diff options
Diffstat (limited to 'accel-pptpd/radius/auth.c')
-rw-r--r-- | accel-pptpd/radius/auth.c | 497 |
1 files changed, 0 insertions, 497 deletions
diff --git a/accel-pptpd/radius/auth.c b/accel-pptpd/radius/auth.c deleted file mode 100644 index 692830ed..00000000 --- a/accel-pptpd/radius/auth.c +++ /dev/null @@ -1,497 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include <openssl/md5.h> -#include <openssl/sha.h> - -#include "triton.h" -#include "events.h" -#include "log.h" -#include "pwdb.h" - -#include "radius_p.h" -#include "attr_defs.h" - -#include "memdebug.h" - -static int decrypt_chap_mppe_keys(struct rad_req_t *req, struct rad_attr_t *attr, const uint8_t *challenge, uint8_t *key) -{ - MD5_CTX md5_ctx; - SHA_CTX sha1_ctx; - uint8_t md5[MD5_DIGEST_LENGTH]; - uint8_t sha1[SHA_DIGEST_LENGTH]; - uint8_t plain[32]; - int i; - - if (attr->len != 32) { - log_ppp_warn("radius: %s: incorrect attribute length (%i)\n", attr->attr->name, attr->len); - return -1; - } - - 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->pack->buf + 4, 16); - MD5_Final(md5, &md5_ctx); - - for (i = 0; i < 16; i++) - plain[i] ^= md5[i]; - - MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret)); - MD5_Update(&md5_ctx, attr->val.octets, 16); - MD5_Final(md5, &md5_ctx); - - for (i = 0; i < 16; i++) - plain[i + 16] ^= md5[i]; - - SHA1_Init(&sha1_ctx); - SHA1_Update(&sha1_ctx, plain + 8, 16); - SHA1_Update(&sha1_ctx, plain + 8, 16); - SHA1_Update(&sha1_ctx, challenge, 8); - SHA1_Final(sha1, &sha1_ctx); - - memcpy(key, sha1, 16); - - return 0; -} - -static int decrypt_mppe_key(struct rad_req_t *req, struct rad_attr_t *attr, uint8_t *key) -{ - MD5_CTX md5_ctx; - uint8_t md5[16]; - uint8_t plain[32]; - int i; - - if (attr->len != 34) { - log_ppp_warn("radius: %s: incorrect attribute length (%i)\n", attr->attr->name, attr->len); - return -1; - } - - if ((attr->val.octets[0] & 0x80) == 0) { - log_ppp_warn("radius: %s: incorrect salt value (%x)\n", attr->attr->name, attr->len); - return -1; - } - - MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret)); - MD5_Update(&md5_ctx, req->pack->buf + 4, 16); - MD5_Update(&md5_ctx, attr->val.octets, 2); - MD5_Final(md5, &md5_ctx); - - memcpy(plain, attr->val.octets + 2, 32); - - for (i = 0; i < 16; i++) - plain[i] ^= md5[i]; - - if (plain[0] != 16) { - log_ppp_warn("radius: %s: incorrect key length (%i)\n", attr->attr->name, plain[0]); - return -1; - } - - MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, conf_auth_secret, strlen(conf_auth_secret)); - MD5_Update(&md5_ctx, attr->val.octets + 2, 16); - MD5_Final(md5, &md5_ctx); - - plain[16] ^= md5[0]; - - memcpy(key, plain + 1, 16); - - return 0; -} - - -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; - - if (strlen(passwd)) - chunk_cnt = (strlen(passwd) - 1) / 16 + 1; - else { - *epasswd_len = 0; - return (uint8_t *)1; - } - - epasswd = _malloc(chunk_cnt * 16); - if (!epasswd) { - log_emerg("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 rad_auth_send(struct rad_req_t *req) -{ - int i; - - for(i = 0; i < conf_max_try; i++) { - __sync_add_and_fetch(&stat_auth_sent, 1); - if (rad_req_send(req, conf_verbose)) - goto out; - - rad_req_wait(req, conf_timeout); - - if (req->reply) { - if (req->reply->id != req->pack->id) { - __sync_add_and_fetch(&stat_auth_lost, 1); - rad_packet_free(req->reply); - req->reply = NULL; - } else - break; - } else - __sync_add_and_fetch(&stat_auth_lost, 1); - } - - 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; - } - -out: - return PWDB_DENIED; -} - -int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args) -{ - struct rad_req_t *req; - int 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_secret, req->RA, &epasswd_len); - if (!epasswd) - goto out; - - if (rad_packet_add_octets(req->pack, NULL, "User-Password", epasswd, epasswd_len)) { - if (epasswd_len) - _free(epasswd); - goto out; - } - - if (epasswd_len) - _free(epasswd); - - if (conf_sid_in_auth) - if (rad_packet_add_str(req->pack, NULL, "Acct-Session-Id", rpd->ppp->sessionid)) - return -1; - - r = rad_auth_send(req); - if (r == PWDB_SUCCESS) { - struct ev_radius_t ev = { - .ppp = rpd->ppp, - .request = req->pack, - .reply = req->reply, - }; - triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev); - } - -out: - rad_req_free(req); - - return r; -} - -int rad_auth_chap_md5(struct radius_pd_t *rpd, const char *username, va_list args) -{ - int r = PWDB_DENIED; - uint8_t chap_password[17]; - - int id = va_arg(args, int); - uint8_t *challenge = va_arg(args, uint8_t *); - int challenge_len = va_arg(args, int); - uint8_t *response = va_arg(args, uint8_t *); - - chap_password[0] = id; - memcpy(chap_password + 1, response, 16); - - if (!rpd->auth_req) { - rpd->auth_req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username); - if (!rpd->auth_req) - return PWDB_DENIED; - - 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)) - 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)) - goto out; - } - - if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Password", chap_password, 17)) - goto out; - - if (rpd->attr_state) { - if (rad_packet_find_attr(rpd->auth_req->pack, NULL, "State")) { - if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len)) - goto out; - } else { - if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len)) - goto out; - } - } - - if (rad_packet_build(rpd->auth_req->pack, rpd->auth_req->RA)) - return -1; - } - - if (conf_sid_in_auth) - 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 = { - .ppp = rpd->ppp, - .request = rpd->auth_req->pack, - .reply = rpd->auth_req->reply, - }; - triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev); - rpd->auth_req->pack->id++; - } - - return r; -out: - rad_req_free(rpd->auth_req); - rpd->auth_req = NULL; - - return r; -} - -static void setup_mppe(struct rad_req_t *req, const uint8_t *challenge) -{ - struct rad_attr_t *attr; - uint8_t mppe_recv_key[16]; - uint8_t mppe_send_key[16]; - struct ev_mppe_keys_t ev_mppe = { - .ppp = req->rpd->ppp, - }; - - list_for_each_entry(attr, &req->reply->attrs, entry) { - if (attr->vendor && attr->vendor->id == Vendor_Microsoft) { - switch (attr->attr->id) { - case MS_CHAP_MPPE_Keys: - if (decrypt_chap_mppe_keys(req, attr, challenge, mppe_recv_key)) - continue; - ev_mppe.recv_key = mppe_recv_key; - ev_mppe.send_key = mppe_recv_key; - break; - case MS_MPPE_Recv_Key: - if (decrypt_mppe_key(req, attr, mppe_recv_key)) - continue; - ev_mppe.recv_key = mppe_recv_key; - break; - case MS_MPPE_Send_Key: - if (decrypt_mppe_key(req, attr, mppe_send_key)) - continue; - ev_mppe.send_key = mppe_send_key; - break; - case MS_MPPE_Encryption_Policy: - ev_mppe.policy = attr->val.integer; - break; - case MS_MPPE_Encryption_Type: - ev_mppe.type = attr->val.integer; - break; - } - } - } - - if (ev_mppe.recv_key && ev_mppe.send_key) - triton_event_fire(EV_MPPE_KEYS, &ev_mppe); -} - -int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list args) -{ - int r = PWDB_DENIED; - uint8_t response[50]; - - 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 *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); - - response[0] = id; - response[1] = flags; - memcpy(response + 2, lm_response, 24); - memcpy(response + 2 + 24, nt_response, 24); - - if (!rpd->auth_req) { - rpd->auth_req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username); - if (!rpd->auth_req) - return PWDB_DENIED; - - if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len)) - goto out; - - if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response))) - goto out; - } else { - if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len)) - goto out; - - if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response))) - goto out; - - if (rpd->attr_state) { - if (rad_packet_find_attr(rpd->auth_req->pack, NULL, "State")) { - if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len)) - goto out; - } else { - if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len)) - goto out; - } - } - - if (rad_packet_build(rpd->auth_req->pack, rpd->auth_req->RA)) - return -1; - } - - if (conf_sid_in_auth) - 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 = { - .ppp = rpd->ppp, - .request = rpd->auth_req->pack, - .reply = rpd->auth_req->reply, - }; - triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev); - setup_mppe(rpd->auth_req, challenge); - rpd->auth_req->pack->id++; - } - - return r; -out: - rad_req_free(rpd->auth_req); - rpd->auth_req = NULL; - - return r; -} - -int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list args) -{ - int r = PWDB_DENIED; - struct rad_attr_t *ra; - uint8_t mschap_response[50]; - - 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 *reserved = 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 *); - - mschap_response[0] = id; - mschap_response[1] = flags; - memcpy(mschap_response + 2, peer_challenge, 16); - memcpy(mschap_response + 2 + 16, reserved, 8); - memcpy(mschap_response + 2 + 16 + 8, response, 24); - - if (!rpd->auth_req) { - rpd->auth_req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username); - if (!rpd->auth_req) - return PWDB_DENIED; - - if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16)) - goto out; - - if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response))) - goto out; - } else { - if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16)) - goto out; - - if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response))) - goto out; - - if (rpd->attr_state) { - if (rad_packet_find_attr(rpd->auth_req->pack, NULL, "State")) { - if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len)) - goto out; - } else { - if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len)) - goto out; - } - } - - if (rad_packet_build(rpd->auth_req->pack, rpd->auth_req->RA)) - return -1; - } - - if (conf_sid_in_auth) - 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) { - ra = rad_packet_find_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP2-Success"); - if (!ra) { - log_error("radius:auth:mschap-v2: 'MS-CHAP-Success' not found in radius response\n"); - r = PWDB_DENIED; - } else - memcpy(authenticator, ra->val.octets + 3, 40); - } - if (r == PWDB_SUCCESS) { - struct ev_radius_t ev = { - .ppp = rpd->ppp, - .request = rpd->auth_req->pack, - .reply = rpd->auth_req->reply, - }; - triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev); - setup_mppe(rpd->auth_req, NULL); - rpd->auth_req->pack->id++; - } - - return r; -out: - rad_req_free(rpd->auth_req); - rpd->auth_req = NULL; - - return r; -} - - |