diff options
Diffstat (limited to 'accel-pppd/radius/auth.c')
-rw-r--r-- | accel-pppd/radius/auth.c | 117 |
1 files changed, 80 insertions, 37 deletions
diff --git a/accel-pppd/radius/auth.c b/accel-pppd/radius/auth.c index 70ecbbe..e4810fa 100644 --- a/accel-pppd/radius/auth.c +++ b/accel-pppd/radius/auth.c @@ -30,7 +30,7 @@ static int decrypt_chap_mppe_keys(struct rad_req_t *req, struct rad_attr_t *attr memcpy(plain, attr->val.octets, 32); MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret)); + MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret)); MD5_Update(&md5_ctx, req->pack->buf + 4, 16); MD5_Final(md5, &md5_ctx); @@ -38,7 +38,7 @@ static int decrypt_chap_mppe_keys(struct rad_req_t *req, struct rad_attr_t *attr plain[i] ^= md5[i]; MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret)); + MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret)); MD5_Update(&md5_ctx, attr->val.octets, 16); MD5_Final(md5, &md5_ctx); @@ -74,7 +74,7 @@ static int decrypt_mppe_key(struct rad_req_t *req, struct rad_attr_t *attr, uint } MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret)); + MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret)); MD5_Update(&md5_ctx, req->pack->buf + 4, 16); MD5_Update(&md5_ctx, attr->val.octets, 2); MD5_Final(md5, &md5_ctx); @@ -90,7 +90,7 @@ static int decrypt_mppe_key(struct rad_req_t *req, struct rad_attr_t *attr, uint } MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret)); + MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret)); MD5_Update(&md5_ctx, attr->val.octets + 2, 16); MD5_Final(md5, &md5_ctx); @@ -145,42 +145,71 @@ static uint8_t* encrypt_password(const char *passwd, const char *secret, const u static int rad_auth_send(struct rad_req_t *req) { int i; - struct timeval tv; + struct timeval tv, tv2; unsigned int dt; + int timeout; - for(i = 0; i < conf_max_try; i++) { - __sync_add_and_fetch(&stat_auth_sent, 1); - gettimeofday(&tv, NULL); - if (rad_req_send(req, conf_verbose)) - goto out; + while (1) { + if (rad_server_req_enter(req)) { + if (rad_server_realloc(req, 0)) { + log_ppp_warn("radius: no available servers\n"); + break; + } + continue; + } - rad_req_wait(req, conf_timeout); + for(i = 0; i < conf_max_try; i++) { + __sync_add_and_fetch(&stat_auth_sent, 1); + gettimeofday(&tv, NULL); + if (rad_req_send(req, conf_verbose)) + goto out; - if (req->reply) { - if (req->reply->id != req->pack->id) { - __sync_add_and_fetch(&stat_auth_lost, 1); - stat_accm_add(stat_auth_lost_1m, 1); - stat_accm_add(stat_auth_lost_5m, 1); - rad_packet_free(req->reply); - req->reply = NULL; - } else { + timeout = conf_timeout; + + while (timeout > 0) { + + rad_req_wait(req, timeout); + + if (req->reply) { + if (req->reply->id != req->pack->id) { + rad_packet_free(req->reply); + req->reply = NULL; + gettimeofday(&tv2, NULL); + timeout = conf_timeout - ((tv2.tv_sec - tv.tv_sec) * 1000 + (tv2.tv_usec - tv.tv_usec) / 1000); + } else + break; + } else + break; + } + + if (req->reply) { dt = (req->reply->tv.tv_sec - tv.tv_sec) * 1000 + (req->reply->tv.tv_usec - tv.tv_usec) / 1000; stat_accm_add(stat_auth_query_1m, dt); stat_accm_add(stat_auth_query_5m, dt); break; + } else { + __sync_add_and_fetch(&stat_auth_lost, 1); + stat_accm_add(stat_auth_lost_1m, 1); + stat_accm_add(stat_auth_lost_5m, 1); } - } else - __sync_add_and_fetch(&stat_auth_lost, 1); - stat_accm_add(stat_auth_lost_1m, 1); - stat_accm_add(stat_auth_lost_5m, 1); - } + } + + rad_server_req_exit(req); - if (!req->reply) - log_ppp_warn("radius:auth: no response\n"); - else if (req->reply->code == CODE_ACCESS_ACCEPT) { - if (rad_proc_attrs(req)) - return PWDB_DENIED; - return PWDB_SUCCESS; + if (!req->reply) { + rad_server_fail(req->serv); + if (rad_server_realloc(req, 0)) { + log_ppp_warn("radius: no available servers\n"); + break; + } + } else { + if (req->reply->code == CODE_ACCESS_ACCEPT) { + if (rad_proc_attrs(req)) + return PWDB_DENIED; + return PWDB_SUCCESS; + } else + break; + } } out: @@ -200,7 +229,7 @@ int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args) if (!req) return PWDB_DENIED; - epasswd = encrypt_password(passwd, conf_auth_secret, req->RA, &epasswd_len); + epasswd = encrypt_password(passwd, req->serv->auth_secret, req->RA, &epasswd_len); if (!epasswd) goto out; @@ -253,20 +282,16 @@ int rad_auth_chap_md5(struct radius_pd_t *rpd, const char *username, va_list arg if (challenge_len == 16) memcpy(rpd->auth_req->RA, challenge, 16); - else { - if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len)) + if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len)) goto out; - } if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Password", chap_password, 17)) goto out; } else { if (challenge_len == 16) memcpy(rpd->auth_req->RA, challenge, 16); - else { - if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len)) + if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len)) goto out; - } if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Password", chap_password, 17)) goto out; @@ -354,6 +379,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar { int r = PWDB_DENIED; uint8_t response[50]; + struct rad_attr_t *ra; int id = va_arg(args, int); const uint8_t *challenge = va_arg(args, const uint8_t *); @@ -361,6 +387,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar const uint8_t *lm_response = va_arg(args, const uint8_t *); const uint8_t *nt_response = va_arg(args, const uint8_t *); int flags = va_arg(args, int); + char **mschap_error = va_arg(args, char **); response[0] = id; response[1] = flags; @@ -402,6 +429,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar if (rad_packet_add_str(rpd->auth_req->pack, NULL, "Acct-Session-Id", rpd->ppp->sessionid)) goto out; + r = rad_auth_send(rpd->auth_req); if (r == PWDB_SUCCESS) { struct ev_radius_t ev = { @@ -412,6 +440,10 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev); setup_mppe(rpd->auth_req, challenge); rpd->auth_req->pack->id++; + } else if (rpd->auth_req->reply) { + ra = rad_packet_find_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP-Error"); + if (ra) + *mschap_error = ra->val.string; } return r; @@ -435,6 +467,8 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar const uint8_t *response = va_arg(args, const uint8_t *); int flags = va_arg(args, int); uint8_t *authenticator = va_arg(args, uint8_t *); + char **mschap_error = va_arg(args, char **); + char **reply_msg = va_arg(args, char **); mschap_response[0] = id; mschap_response[1] = flags; @@ -495,8 +529,17 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev); setup_mppe(rpd->auth_req, NULL); rpd->auth_req->pack->id++; + } else if (rpd->auth_req->reply) { + ra = rad_packet_find_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP-Error"); + if (ra) + *mschap_error = ra->val.string; + ra = rad_packet_find_attr(rpd->auth_req->reply, NULL, "Reply-Message"); + if (ra) + *reply_msg = ra->val.string; } + + return r; out: rad_req_free(rpd->auth_req); |