summaryrefslogtreecommitdiff
path: root/accel-pppd/radius/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/radius/auth.c')
-rw-r--r--accel-pppd/radius/auth.c117
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);