diff options
Diffstat (limited to 'accel-pptpd/radius/radius.c')
-rw-r--r-- | accel-pptpd/radius/radius.c | 194 |
1 files changed, 25 insertions, 169 deletions
diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c index 89eb9fe..89491b3 100644 --- a/accel-pptpd/radius/radius.c +++ b/accel-pptpd/radius/radius.c @@ -5,8 +5,6 @@ #include <unistd.h> #include <arpa/inet.h> -#include <openssl/md5.h> - #include "log.h" #include "ppp.h" #include "pwdb.h" @@ -35,173 +33,16 @@ char *conf_acct_server_secret; static struct ppp_notified_t notified; -static struct radius_pd_t *find_pd(struct ppp_t *ppp); - -static void proc_attrs(struct rad_req_t *req) +void rad_proc_attrs(struct rad_req_t *req) { struct rad_req_attr_t *attr; list_for_each_entry(attr, &req->reply->attrs, entry) { - if (!strcmp(attr->attr->name, "Framed-IP-Address")) { + if (!strcmp(attr->attr->name, "Framed-IP-Address")) req->rpd->ipaddr = attr->val.ipaddr; - } - } -} - -static uint8_t* encrypt_password(const char *passwd, const char *secret, const uint8_t *RA, int *epasswd_len) -{ - uint8_t *epasswd; - int i, j, chunk_cnt; - uint8_t b[16], c[16]; - MD5_CTX ctx; - - chunk_cnt = (strlen(passwd) - 1) / 16 + 1; - - epasswd = malloc(chunk_cnt * 16); - if (!epasswd) { - log_error("radius: out of memory\n"); - return NULL; - } - - memset(epasswd, 0, chunk_cnt * 16); - memcpy(epasswd, passwd, strlen(passwd)); - memcpy(c, RA, 16); - - for (i = 0; i < chunk_cnt; i++) { - MD5_Init(&ctx); - MD5_Update(&ctx, secret, strlen(secret)); - MD5_Update(&ctx, c, 16); - MD5_Final(b, &ctx); - - for(j = 0; j < 16; j++) - epasswd[i * 16 + j] ^= b[j]; - - memcpy(c, epasswd + i * 16, 16); - } - - *epasswd_len = chunk_cnt * 16; - return epasswd; -} - -static int check_pap(struct radius_pd_t *rpd, const char *username, va_list args) -{ - struct rad_req_t *req; - int i, r = PWDB_DENIED; - //int id = va_arg(args, int); - const char *passwd = va_arg(args, const char *); - uint8_t *epasswd; - int epasswd_len; - - 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; - - epasswd = encrypt_password(passwd, conf_auth_server_secret, req->RA, &epasswd_len); - if (!epasswd) - goto out; - - if (rad_req_add_str(req, "Password", (char*)epasswd, epasswd_len, 0)) { - free(epasswd); - goto out; - } - - free(epasswd); - - 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_chap_md5(struct radius_pd_t *rpd, const char *username, va_list args) -{ - 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; + else if (!strcmp(attr->attr->name, "Acct-Interim-Interval")) + req->rpd->acct_interim_interval = attr->val.integer; } - - 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) -{ - /*int id = va_arg(args, int); - const uint8_t *challenge = va_arg(args, const uint8_t *); - 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);*/ - return PWDB_DENIED; -} - -static int check_mschap_v2(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 *); - const uint8_t *peer_challenge = va_arg(args, const uint8_t *); - const uint8_t *response = va_arg(args, const uint8_t *); - int flags = va_arg(args, int); - uint8_t *authenticator = va_arg(args, uint8_t *);*/ - return PWDB_DENIED; } static int check(struct pwdb_t *pwdb, struct ppp_t *ppp, const char *username, int type, va_list _args) @@ -215,19 +56,19 @@ static int check(struct pwdb_t *pwdb, struct ppp_t *ppp, const char *username, i switch(type) { case PPP_PAP: - r = check_pap(rpd, username, args); + r = rad_auth_pap(rpd, username, args); break; case PPP_CHAP: chap_type = va_arg(args, int); switch(chap_type) { case CHAP_MD5: - r = check_chap_md5(rpd, username, args); + r = rad_auth_chap_md5(rpd, username, args); break; case MSCHAP_V1: - r = check_mschap_v1(rpd, username, args); + r = rad_auth_mschap_v1(rpd, username, args); break; case MSCHAP_V2: - r = check_mschap_v2(rpd, username, args); + r = rad_auth_mschap_v2(rpd, username, args); break; } break; @@ -254,7 +95,7 @@ static int get_ip(struct ppp_t *ppp, in_addr_t *addr, in_addr_t *peer_addr) return -1; } -static void ppp_started(struct ppp_notified_t *n, struct ppp_t *ppp) +static void ppp_starting(struct ppp_notified_t *n, struct ppp_t *ppp) { struct radius_pd_t *pd = malloc(sizeof(*pd)); @@ -264,6 +105,19 @@ static void ppp_started(struct ppp_notified_t *n, struct ppp_t *ppp) list_add_tail(&pd->pd.entry, &ppp->pd_list); } +static void ppp_started(struct ppp_notified_t *n, struct ppp_t *ppp) +{ + struct radius_pd_t *rpd = find_pd(ppp); + + if (rad_acct_start(rpd)) + ppp_terminate(rpd->ppp, 0); +} +static void ppp_finishing(struct ppp_notified_t *n, struct ppp_t *ppp) +{ + struct radius_pd_t *rpd = find_pd(ppp); + + rad_acct_stop(rpd); +} static void ppp_finished(struct ppp_notified_t *n, struct ppp_t *ppp) { struct radius_pd_t *rpd = find_pd(ppp); @@ -272,7 +126,7 @@ static void ppp_finished(struct ppp_notified_t *n, struct ppp_t *ppp) free(rpd); } -static struct radius_pd_t *find_pd(struct ppp_t *ppp) +struct radius_pd_t *find_pd(struct ppp_t *ppp) { struct ppp_pd_t *pd; struct radius_pd_t *rpd; @@ -297,7 +151,9 @@ static struct pwdb_t pwdb = { }; static struct ppp_notified_t notified = { + .starting = ppp_starting, .started = ppp_started, + .finishing = ppp_finishing, .finished = ppp_finished, }; |