From 4dcca9422c5c001789b17c3266f3db8e0590568d Mon Sep 17 00:00:00 2001 From: Kozlov Dmitry Date: Wed, 8 Sep 2010 16:23:51 +0400 Subject: radius: implemented CHAP (md5) authorization --- accel-pptpd/accel-pptpd.conf | 1 + accel-pptpd/auth/auth_chap_md5.c | 58 +++++++++++++++++++++++--------------- accel-pptpd/radius/radius.c | 61 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 92 insertions(+), 28 deletions(-) (limited to 'accel-pptpd') diff --git a/accel-pptpd/accel-pptpd.conf b/accel-pptpd/accel-pptpd.conf index ece04f2..1e3bc92 100644 --- a/accel-pptpd/accel-pptpd.conf +++ b/accel-pptpd/accel-pptpd.conf @@ -1,6 +1,7 @@ [modules] ./libpptp.so ./libauth_pap.so +./libauth_chap_md5.so ./libradius.so [core] diff --git a/accel-pptpd/auth/auth_chap_md5.c b/accel-pptpd/auth/auth_chap_md5.c index de2f471..0bcec37 100644 --- a/accel-pptpd/auth/auth_chap_md5.c +++ b/accel-pptpd/auth/auth_chap_md5.c @@ -20,6 +20,8 @@ #define CHAP_SUCCESS 3 #define CHAP_FAILURE 4 +#define CHAP_MD5 5 + #define VALUE_SIZE 16 #define MSG_FAILURE "Authentication failed" @@ -128,13 +130,13 @@ static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth) static int lcp_send_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *ptr) { - *ptr=5; + *ptr = CHAP_MD5; return 1; } static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *ptr) { - if (*ptr==5) + if (*ptr == CHAP_MD5) return LCP_OPT_ACK; return LCP_OPT_NAK; } @@ -198,6 +200,7 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h uint8_t md5[MD5_DIGEST_LENGTH]; char *passwd; char *name; + int r; struct chap_challenge_t *msg=(struct chap_challenge_t*)hdr; log_debug("recv [CHAP Response id=%x <", msg->hdr.id); @@ -221,34 +224,45 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h } name = strndup(msg->name,ntohs(msg->hdr.len)-sizeof(*msg)+2); - passwd = pwdb_get_passwd(ad->ppp,name); - if (!passwd) - { - free(name); - log_debug("chap-md5: user not found\n"); - chap_send_failure(ad); - return; - } - MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx,&msg->hdr.id,1); - MD5_Update(&md5_ctx,passwd,strlen(passwd)); - MD5_Update(&md5_ctx,ad->val,VALUE_SIZE); - MD5_Final(md5,&md5_ctx); - - if (memcmp(md5,msg->val,sizeof(md5))) - { - log_debug("chap-md5: challenge response mismatch\n"); + r = pwdb_check(ad->ppp, name, PPP_CHAP, CHAP_MD5, ad->id, ad->val, VALUE_SIZE, msg->val); + + if (r == PWDB_NO_IMPL) { + passwd = pwdb_get_passwd(ad->ppp,name); + if (!passwd) + { + free(name); + log_debug("chap-md5: user not found\n"); + chap_send_failure(ad); + return; + } + + MD5_Init(&md5_ctx); + MD5_Update(&md5_ctx,&msg->hdr.id,1); + MD5_Update(&md5_ctx,passwd,strlen(passwd)); + MD5_Update(&md5_ctx,ad->val,VALUE_SIZE); + MD5_Final(md5,&md5_ctx); + + if (memcmp(md5,msg->val,sizeof(md5))) + { + log_debug("chap-md5: challenge response mismatch\n"); + chap_send_failure(ad); + auth_failed(ad->ppp); + }else + { + chap_send_success(ad); + auth_successed(ad->ppp); + } + free(passwd); + } else if (r == PWDB_DENIED) { chap_send_failure(ad); auth_failed(ad->ppp); - }else - { + } else { chap_send_success(ad); auth_successed(ad->ppp); } free(name); - free(passwd); } static struct ppp_auth_handler_t chap= diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c index a786dea..89eb9fe 100644 --- a/accel-pptpd/radius/radius.c +++ b/accel-pptpd/radius/radius.c @@ -14,6 +14,10 @@ #include "radius.h" +#define CHAP_MD5 5 +#define MSCHAP_V1 0x80 +#define MSCHAP_V2 0x81 + int conf_max_try = 3; int conf_timeout = 3; char *conf_nas_identifier = "accel-pptpd"; @@ -129,9 +133,54 @@ out: static int check_chap_md5(struct radius_pd_t *rpd, const char *username, va_list args) { - /*int id = va_arg(args, int); - const uint8_t *challenge = va_arg(args, const uint8_t *);*/ - return PWDB_DENIED; + struct rad_req_t *req; + int i, r = PWDB_DENIED; + char chap_password[17]; + + int id = va_arg(args, int); + const uint8_t *challenge = va_arg(args, const uint8_t *); + int challenge_len = va_arg(args, int); + const uint8_t *response = va_arg(args, const uint8_t *); + + chap_password[0] = id; + memcpy(chap_password + 1, response, 16); + + req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username); + if (!req) + return PWDB_DENIED; + + req->server_name = conf_auth_server; + req->server_port = conf_auth_server_port; + + if (challenge_len == 16) + memcpy(req->RA, challenge, 16); + else { + if (rad_req_add_str(req, "CHAP-Challenge", (char*)challenge, challenge_len, 0)) + goto out; + } + + if (rad_req_add_str(req, "CHAP-Password", chap_password, 17, 0)) + goto out; + + for(i = 0; i < conf_max_try; i++) { + if (rad_req_send(req)) + goto out; + + rad_req_wait(req, conf_timeout); + + if (req->reply) + break; + } + + if (req->reply && req->reply->code == CODE_ACCESS_ACCEPT) { + proc_attrs(req); + r = PWDB_SUCCESS; + } + +out: + rad_req_free(req); + + return r; } static int check_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list args) @@ -171,13 +220,13 @@ static int check(struct pwdb_t *pwdb, struct ppp_t *ppp, const char *username, i case PPP_CHAP: chap_type = va_arg(args, int); switch(chap_type) { - case 0x05: + case CHAP_MD5: r = check_chap_md5(rpd, username, args); break; - case 0x80: + case MSCHAP_V1: r = check_mschap_v1(rpd, username, args); break; - case 0x81: + case MSCHAP_V2: r = check_mschap_v2(rpd, username, args); break; } -- cgit v1.2.3