diff options
author | Kozlov Dmitry <dima@server> | 2010-09-09 11:01:43 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-09-09 11:01:43 +0400 |
commit | 29b03dcfbd3b4783b0192e5f8c9bb6281acf44d5 (patch) | |
tree | 7e530a420c4c303706e39cc917f0ad8ea5d657e2 /accel-pptpd/radius/auth.c | |
parent | 4dcca9422c5c001789b17c3266f3db8e0590568d (diff) | |
download | accel-ppp-xebd-29b03dcfbd3b4783b0192e5f8c9bb6281acf44d5.tar.gz accel-ppp-xebd-29b03dcfbd3b4783b0192e5f8c9bb6281acf44d5.zip |
radius: implemented accounting (start/stop/interim-update)
Diffstat (limited to 'accel-pptpd/radius/auth.c')
-rw-r--r-- | accel-pptpd/radius/auth.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/accel-pptpd/radius/auth.c b/accel-pptpd/radius/auth.c new file mode 100644 index 0000000..98c7aa8 --- /dev/null +++ b/accel-pptpd/radius/auth.c @@ -0,0 +1,173 @@ +#include <stdlib.h> +#include <string.h> +#include <openssl/md5.h> + +#include "log.h" +#include "pwdb.h" + +#include "radius.h" + + +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; +} + +int rad_auth_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; + + 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) { + if (req->reply->id != req->pack->id) { + rad_packet_free(req->reply); + req->reply = NULL; + } else + break; + } + } + + if (req->reply && req->reply->code == CODE_ACCESS_ACCEPT) { + rad_proc_attrs(req); + r = PWDB_SUCCESS; + } + +out: + rad_req_free(req); + + return r; +} + +int rad_auth_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; + + 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) { + if (req->reply->id != req->pack->id) { + rad_packet_free(req->reply); + req->reply = NULL; + } else + break; + } + } + + if (!req->reply) + log_warn("radius:auth: no response\n"); + else if (req->reply->code == CODE_ACCESS_ACCEPT) { + rad_proc_attrs(req); + r = PWDB_SUCCESS; + } + +out: + rad_req_free(req); + + return r; +} + +int rad_auth_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_NO_IMPL; +} + +int rad_auth_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_NO_IMPL; +} + + |