From 7206898657c84b6131103d127751e030513a1abc Mon Sep 17 00:00:00 2001 From: Kozlov Dmitry Date: Wed, 29 Dec 2010 17:18:56 +0300 Subject: [PATCH] radius: changed api --- accel-pptpd/radius/acct.c | 40 +++--- accel-pptpd/radius/auth.c | 54 ++++---- accel-pptpd/radius/dict/dictionary | 1 + accel-pptpd/radius/dm_coa.c | 2 +- accel-pptpd/radius/packet.c | 208 +++++++++++++---------------- accel-pptpd/radius/radius.c | 12 ++ accel-pptpd/radius/radius.h | 32 +++-- accel-pptpd/radius/radius_p.h | 2 + accel-pptpd/radius/req.c | 58 +++++--- accel-pptpd/triton/loader.c | 2 +- 10 files changed, 211 insertions(+), 200 deletions(-) diff --git a/accel-pptpd/radius/acct.c b/accel-pptpd/radius/acct.c index 86dd0cd..f2c0ebb 100644 --- a/accel-pptpd/radius/acct.c +++ b/accel-pptpd/radius/acct.c @@ -58,13 +58,13 @@ static void req_set_stat(struct rad_req_t *req, struct ppp_t *ppp) req->rpd->acct_output_gigawords++; req->rpd->acct_output_octets = ifreq.stats.p.ppp_obytes; - rad_packet_change_int(req->pack, "Acct-Input-Octets", ifreq.stats.p.ppp_ibytes); - rad_packet_change_int(req->pack, "Acct-Output-Octets", ifreq.stats.p.ppp_obytes); - rad_packet_change_int(req->pack, "Acct-Input-Packets", ifreq.stats.p.ppp_ipackets); - rad_packet_change_int(req->pack, "Acct-Output-Packets", ifreq.stats.p.ppp_opackets); - rad_packet_change_int(req->pack, "Acct-Input-Gigawords", req->rpd->acct_input_gigawords); - rad_packet_change_int(req->pack, "Acct-Output-Gigawords", req->rpd->acct_output_gigawords); - rad_packet_change_int(req->pack, "Acct-Session-Time", stop_time - ppp->start_time); + rad_packet_change_int(req->pack, NULL, "Acct-Input-Octets", ifreq.stats.p.ppp_ibytes); + rad_packet_change_int(req->pack, NULL, "Acct-Output-Octets", ifreq.stats.p.ppp_obytes); + rad_packet_change_int(req->pack, NULL, "Acct-Input-Packets", ifreq.stats.p.ppp_ipackets); + rad_packet_change_int(req->pack, NULL, "Acct-Output-Packets", ifreq.stats.p.ppp_opackets); + rad_packet_change_int(req->pack, NULL, "Acct-Input-Gigawords", req->rpd->acct_input_gigawords); + rad_packet_change_int(req->pack, NULL, "Acct-Output-Gigawords", req->rpd->acct_output_gigawords); + rad_packet_change_int(req->pack, NULL, "Acct-Session-Time", stop_time - ppp->start_time); } static int rad_acct_read(struct triton_md_handler_t *h) @@ -135,7 +135,7 @@ static void rad_acct_timeout(struct triton_timer_t *t) req->pack->id++; - rad_packet_change_int(req->pack, "Acct-Delay-Time", dt); + rad_packet_change_int(req->pack, NULL, "Acct-Delay-Time", dt); req_set_RA(req, conf_acct_secret); rad_req_send(req, conf_interim_verbose); } @@ -154,8 +154,8 @@ static void rad_acct_interim_update(struct triton_timer_t *t) time(&rpd->acct_timestamp); rpd->acct_req->pack->id++; - rad_packet_change_val(rpd->acct_req->pack, "Acct-Status-Type", "Interim-Update"); - rad_packet_change_int(rpd->acct_req->pack, "Acct-Delay-Time", 0); + rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Interim-Update"); + rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", 0); req_set_RA(rpd->acct_req, conf_acct_secret); rad_req_send(rpd->acct_req, conf_interim_verbose); if (conf_acct_timeout) { @@ -194,7 +194,7 @@ int rad_acct_start(struct radius_pd_t *rpd) for (i = 0; i < conf_max_try; i++) { time(&ts); - rad_packet_change_int(rpd->acct_req->pack, "Acct-Delay-Time", ts - rpd->acct_timestamp); + rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp); if (req_set_RA(rpd->acct_req, conf_acct_secret)) goto out_err; if (rad_req_send(rpd->acct_req, conf_verbose)) @@ -256,29 +256,29 @@ void rad_acct_stop(struct radius_pd_t *rpd) switch (rpd->ppp->terminate_cause) { case TERM_USER_REQUEST: - rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "User-Request"); + rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "User-Request"); break; case TERM_SESSION_TIMEOUT: - rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "Session-Timeout"); + rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Session-Timeout"); break; case TERM_ADMIN_RESET: - rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "Admin-Reset"); + rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Admin-Reset"); break; case TERM_USER_ERROR: case TERM_AUTH_ERROR: - rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "User-Error"); + rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "User-Error"); break; case TERM_NAS_ERROR: - rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "NAS-Error"); + rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Error"); break; case TERM_NAS_REQUEST: - rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "NAS-Request"); + rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Request"); break; case TERM_NAS_REBOOT: - rad_packet_add_val(rpd->acct_req->pack, "Acct-Terminate-Cause", "NAS-Reboot"); + rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Reboot"); break; } - rad_packet_change_val(rpd->acct_req->pack, "Acct-Status-Type", "Stop"); + rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Stop"); req_set_stat(rpd->acct_req, rpd->ppp); req_set_RA(rpd->acct_req, conf_acct_secret); /// !!! rad_req_add_val(rpd->acct_req, "Acct-Terminate-Cause", ""); @@ -292,7 +292,7 @@ void rad_acct_stop(struct radius_pd_t *rpd) for(i = 0; i < conf_max_try; i++) { time(&ts); - rad_packet_change_int(rpd->acct_req->pack, "Acct-Delay-Time", ts - rpd->acct_timestamp); + rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp); rpd->acct_req->pack->id++; if (req_set_RA(rpd->acct_req, conf_acct_secret)) break; diff --git a/accel-pptpd/radius/auth.c b/accel-pptpd/radius/auth.c index 94a8269..244cb6e 100644 --- a/accel-pptpd/radius/auth.c +++ b/accel-pptpd/radius/auth.c @@ -190,7 +190,7 @@ int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args) if (!epasswd) goto out; - if (rad_packet_add_octets(req->pack, "User-Password", epasswd, epasswd_len)) { + if (rad_packet_add_octets(req->pack, NULL, "User-Password", epasswd, epasswd_len)) { if (epasswd_len) _free(epasswd); goto out; @@ -200,7 +200,7 @@ int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args) _free(epasswd); if (conf_sid_in_auth) - if (rad_packet_add_str(req->pack, "Acct-Session-Id", rpd->ppp->sessionid, PPP_SESSIONID_LEN)) + if (rad_packet_add_str(req->pack, NULL, "Acct-Session-Id", rpd->ppp->sessionid)) return -1; r = rad_auth_send(req); @@ -240,29 +240,29 @@ 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, "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, "CHAP-Password", chap_password, 17)) + 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, "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, "CHAP-Password", chap_password, 17)) + 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, "State")) { - if (rad_packet_change_octets(rpd->auth_req->pack, "State", rpd->attr_state, rpd->attr_state_len)) + 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, "State", rpd->attr_state, rpd->attr_state_len)) + if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len)) goto out; } } @@ -272,7 +272,7 @@ int rad_auth_chap_md5(struct radius_pd_t *rpd, const char *username, va_list arg } if (conf_sid_in_auth) - if (rad_packet_add_str(rpd->auth_req->pack, "Acct-Session-Id", rpd->ppp->sessionid, PPP_SESSIONID_LEN)) + 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); @@ -358,24 +358,24 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar if (!rpd->auth_req) return PWDB_DENIED; - if (rad_packet_add_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len)) + if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len)) goto out; - if (rad_packet_add_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response))) + if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response))) goto out; } else { - if (rad_packet_change_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len)) + if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len)) goto out; - if (rad_packet_change_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response))) + 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, "State")) { - if (rad_packet_change_octets(rpd->auth_req->pack, "State", rpd->attr_state, rpd->attr_state_len)) + 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, "State", rpd->attr_state, rpd->attr_state_len)) + if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len)) goto out; } } @@ -385,7 +385,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar } if (conf_sid_in_auth) - if (rad_packet_add_str(rpd->auth_req->pack, "Acct-Session-Id", rpd->ppp->sessionid, PPP_SESSIONID_LEN)) + 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); @@ -433,24 +433,24 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar if (!rpd->auth_req) return PWDB_DENIED; - if (rad_packet_add_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16)) + if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16)) goto out; - if (rad_packet_add_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response))) + 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_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16)) + if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16)) goto out; - if (rad_packet_change_vendor_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response))) + 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, "State")) { - if (rad_packet_change_octets(rpd->auth_req->pack, "State", rpd->attr_state, rpd->attr_state_len)) + 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, "State", rpd->attr_state, rpd->attr_state_len)) + if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len)) goto out; } } @@ -460,12 +460,12 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar } if (conf_sid_in_auth) - if (rad_packet_add_str(rpd->auth_req->pack, "Acct-Session-Id", rpd->ppp->sessionid, PPP_SESSIONID_LEN)) + 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_vendor_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP2-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; diff --git a/accel-pptpd/radius/dict/dictionary b/accel-pptpd/radius/dict/dictionary index 02006a6..2797310 100644 --- a/accel-pptpd/radius/dict/dictionary +++ b/accel-pptpd/radius/dict/dictionary @@ -70,6 +70,7 @@ $INCLUDE dictionary.rfc3576 $INCLUDE dictionary.rfc3580 $INCLUDE dictionary.rfc4072 $INCLUDE dictionary.rfc4372 +$INCLUDE dictionary.rfc4679 $INCLUDE dictionary.rfc5176 $INCLUDE dictionary.microsoft diff --git a/accel-pptpd/radius/dm_coa.c b/accel-pptpd/radius/dm_coa.c index baf51b5..366bb41 100644 --- a/accel-pptpd/radius/dm_coa.c +++ b/accel-pptpd/radius/dm_coa.c @@ -102,7 +102,7 @@ static int dm_coa_send_nak(int fd, struct rad_packet_t *req, struct sockaddr_in reply->id = req->id; if (err_code) - rad_packet_add_int(reply, "Error-Cause", err_code); + rad_packet_add_int(reply, NULL, "Error-Cause", err_code); if (rad_packet_build(reply, RA)) { rad_packet_free(reply); diff --git a/accel-pptpd/radius/packet.c b/accel-pptpd/radius/packet.c index 08991dd..4e24ded 100644 --- a/accel-pptpd/radius/packet.c +++ b/accel-pptpd/radius/packet.c @@ -324,15 +324,25 @@ void rad_packet_print(struct rad_packet_t *pack, void (*print)(const char *fmt, print("]\n"); } -int rad_packet_add_int(struct rad_packet_t *pack, const char *name, int val) +int __export rad_packet_add_int(struct rad_packet_t *pack, const char *vendor_name, const char *name, int val) { struct rad_attr_t *ra; struct rad_dict_attr_t *attr; + struct rad_dict_vendor_t *vendor; - if (pack->len + 2 + 4 >= REQ_LENGTH_MAX) + if (pack->len + (vendor_name ? 8 : 2) + 4 >= REQ_LENGTH_MAX) return -1; - attr = rad_dict_find_attr(name); + if (vendor_name) { + vendor = rad_dict_find_vendor_name(vendor_name); + if (!vendor) + return -1; + attr = rad_dict_find_vendor_attr(vendor, name); + } else { + vendor = NULL; + attr = rad_dict_find_attr(name); + } + if (!attr) return -1; @@ -341,20 +351,21 @@ int rad_packet_add_int(struct rad_packet_t *pack, const char *name, int val) return -1; memset(ra, 0, sizeof(*ra)); + ra->vendor = vendor; ra->attr = attr; ra->len = 4; ra->val.integer = val; list_add_tail(&ra->entry, &pack->attrs); - pack->len += 2 + 4; + pack->len += (vendor_name ? 8 : 2) + 4; return 0; } -int rad_packet_change_int(struct rad_packet_t *pack, const char *name, int val) +int __export rad_packet_change_int(struct rad_packet_t *pack, const char *vendor_name, const char *name, int val) { struct rad_attr_t *ra; - ra = rad_packet_find_attr(pack, name); + ra = rad_packet_find_attr(pack, vendor_name, name); if (!ra) return -1; @@ -363,15 +374,25 @@ int rad_packet_change_int(struct rad_packet_t *pack, const char *name, int val) return 0; } -int rad_packet_add_octets(struct rad_packet_t *pack, const char *name, const uint8_t *val, int len) +int __export rad_packet_add_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len) { struct rad_attr_t *ra; struct rad_dict_attr_t *attr; + struct rad_dict_vendor_t *vendor; - if (pack->len + 2 + len >= REQ_LENGTH_MAX) + if (pack->len + (vendor_name ? 8 : 2) + len >= REQ_LENGTH_MAX) return -1; - attr = rad_dict_find_attr(name); + if (vendor_name) { + vendor = rad_dict_find_vendor_name(vendor_name); + if (!vendor) + return -1; + attr = rad_dict_find_vendor_attr(vendor, name); + } else { + vendor = NULL; + attr = rad_dict_find_attr(name); + } + if (!attr) return -1; @@ -382,6 +403,7 @@ int rad_packet_add_octets(struct rad_packet_t *pack, const char *name, const uin } memset(ra, 0, sizeof(*ra)); + ra->vendor = vendor; ra->attr = attr; ra->len = len; ra->val.octets = _malloc(len); @@ -392,16 +414,16 @@ int rad_packet_add_octets(struct rad_packet_t *pack, const char *name, const uin } memcpy(ra->val.octets, val, len); list_add_tail(&ra->entry, &pack->attrs); - pack->len += 2 + len; + pack->len += (vendor_name ? 8 : 2) + len; return 0; } -int rad_packet_change_octets(struct rad_packet_t *pack, const char *name, const uint8_t *val, int len) +int __export rad_packet_change_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len) { struct rad_attr_t *ra; - ra = rad_packet_find_attr(pack, name); + ra = rad_packet_find_attr(pack, vendor_name, name); if (!ra) return -1; @@ -425,15 +447,26 @@ int rad_packet_change_octets(struct rad_packet_t *pack, const char *name, const } -int rad_packet_add_str(struct rad_packet_t *pack, const char *name, const char *val, int len) +int __export rad_packet_add_str(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val) { struct rad_attr_t *ra; struct rad_dict_attr_t *attr; + struct rad_dict_vendor_t *vendor; + int len = strlen(val); - if (pack->len + 2 + len >= REQ_LENGTH_MAX) + if (pack->len + (vendor_name ? 8 : 2) + len >= REQ_LENGTH_MAX) return -1; - attr = rad_dict_find_attr(name); + if (vendor_name) { + vendor = rad_dict_find_vendor_name(vendor_name); + if (!vendor) + return -1; + attr = rad_dict_find_vendor_attr(vendor, name); + } else { + vendor = NULL; + attr = rad_dict_find_attr(name); + } + if (!attr) return -1; @@ -444,9 +477,10 @@ int rad_packet_add_str(struct rad_packet_t *pack, const char *name, const char * } memset(ra, 0, sizeof(*ra)); + ra->vendor = vendor; ra->attr = attr; ra->len = len; - ra->val.string = _malloc(len+1); + ra->val.string = _malloc(len + 1); if (!ra->val.string) { log_emerg("radius: out of memory\n"); _free(ra); @@ -455,16 +489,16 @@ int rad_packet_add_str(struct rad_packet_t *pack, const char *name, const char * memcpy(ra->val.string, val, len); ra->val.string[len] = 0; list_add_tail(&ra->entry, &pack->attrs); - pack->len += 2 + len; + pack->len += (vendor_name ? 8 : 2) + len; return 0; } -int rad_packet_change_str(struct rad_packet_t *pack, const char *name, const char *val, int len) +int __export rad_packet_change_str(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val, int len) { struct rad_attr_t *ra; - ra = rad_packet_find_attr(pack, name); + ra = rad_packet_find_attr(pack, vendor_name, name); if (!ra) return -1; @@ -488,19 +522,29 @@ int rad_packet_change_str(struct rad_packet_t *pack, const char *name, const cha return 0; } -int rad_packet_add_val(struct rad_packet_t *pack, const char *name, const char *val) +int __export rad_packet_add_val(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val) { struct rad_attr_t *ra; struct rad_dict_attr_t *attr; struct rad_dict_value_t *v; + struct rad_dict_vendor_t *vendor; - if (pack->len + 2 + 4 >= REQ_LENGTH_MAX) + if (pack->len + (vendor_name ? 8 : 2) + 4 >= REQ_LENGTH_MAX) return -1; - attr = rad_dict_find_attr(name); + if (vendor_name) { + vendor = rad_dict_find_vendor_name(vendor_name); + if (!vendor) + return -1; + attr = rad_dict_find_vendor_attr(vendor, name); + } else { + vendor = NULL; + attr = rad_dict_find_attr(name); + } + if (!attr) return -1; - + v = rad_dict_find_val_name(attr, val); if (!v) return -1; @@ -510,21 +554,22 @@ int rad_packet_add_val(struct rad_packet_t *pack, const char *name, const char * return -1; memset(ra, 0, sizeof(*ra)); + ra->vendor = vendor; ra->attr = attr; ra->len = 4; ra->val = v->val; list_add_tail(&ra->entry, &pack->attrs); - pack->len += 2 + 4; + pack->len += (vendor_name ? 8 : 2) + 4; return 0; } -int rad_packet_change_val(struct rad_packet_t *pack, const char *name, const char *val) +int __export rad_packet_change_val(struct rad_packet_t *pack, const char *vendor_name, const char *name, const char *val) { struct rad_attr_t *ra; struct rad_dict_value_t *v; - ra = rad_packet_find_attr(pack, name); + ra = rad_packet_find_attr(pack, vendor_name, name); if (!ra) return -1; @@ -537,19 +582,33 @@ int rad_packet_change_val(struct rad_packet_t *pack, const char *name, const cha return 0; } -int rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *name, in_addr_t ipaddr) +int __export rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *vendor_name, const char *name, in_addr_t ipaddr) { - return rad_packet_add_int(pack, name, ipaddr); + return rad_packet_add_int(pack, vendor_name, name, ipaddr); } -struct rad_attr_t *rad_packet_find_attr(struct rad_packet_t *pack, const char *name) +struct rad_attr_t __export *rad_packet_find_attr(struct rad_packet_t *pack, const char *vendor_name, const char *name) { struct rad_attr_t *ra; + struct rad_dict_vendor_t *vendor; - list_for_each_entry(ra, &pack->attrs, entry) - if (!strcmp(ra->attr->name, name)) - return ra; + if (vendor_name) { + vendor = rad_dict_find_vendor_name(vendor_name); + if (!vendor) + return NULL; + } else + vendor = NULL; + + list_for_each_entry(ra, &pack->attrs, entry) { + if (vendor && vendor != ra->vendor) + continue; + + if (strcmp(ra->attr->name, name)) + continue; + + return ra; + } return NULL; } @@ -578,91 +637,6 @@ int rad_packet_send(struct rad_packet_t *pack, int fd, struct sockaddr_in *addr) return 0; } -int rad_packet_add_vendor_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len) -{ - struct rad_attr_t *ra; - struct rad_dict_attr_t *attr; - struct rad_dict_vendor_t *vendor; - - if (pack->len + 6 + 2 + len >= REQ_LENGTH_MAX) - return -1; - - vendor = rad_dict_find_vendor_name(vendor_name); - if (!vendor) - return -1; - - attr = rad_dict_find_vendor_attr(vendor, name); - if (!attr) - return -1; - - ra = mempool_alloc(attr_pool); - if (!ra) { - log_emerg("radius: out of memory\n"); - return -1; - } - - memset(ra, 0, sizeof(*ra)); - ra->vendor = vendor; - ra->attr = attr; - ra->len = len; - ra->val.octets = _malloc(len); - if (!ra->val.octets) { - log_emerg("radius: out of memory\n"); - _free(ra); - return -1; - } - memcpy(ra->val.octets, val, len); - list_add_tail(&ra->entry, &pack->attrs); - pack->len += 6 + 2 + len; - - return 0; -} - -int rad_packet_change_vendor_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len) -{ - struct rad_attr_t *ra; - - ra = rad_packet_find_vendor_attr(pack, vendor_name, name); - if (!ra) - return -1; - - if (ra->len != len) { - if (pack->len - ra->len + len >= REQ_LENGTH_MAX) - return -1; - - ra->val.octets = _realloc(ra->val.octets, len); - if (!ra->val.octets) { - log_emerg("radius: out of memory\n"); - return -1; - } - - pack->len += len - ra->len; - ra->len = len; - } - - memcpy(ra->val.octets, val, len); - - return 0; -} - -struct rad_attr_t *rad_packet_find_vendor_attr(struct rad_packet_t *pack, const char *vendor_name, const char *name) -{ - struct rad_attr_t *ra; - - list_for_each_entry(ra, &pack->attrs, entry) { - if (!ra->vendor) - continue; - if (strcmp(ra->vendor->name, vendor_name)) - continue; - if (strcmp(ra->attr->name, name)) - continue; - - return ra; - } - - return NULL; -} - static void __init init(void) { attr_pool = mempool_create(sizeof(struct rad_attr_t)); diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c index 8d0c887..f081cf4 100644 --- a/accel-pptpd/radius/radius.c +++ b/accel-pptpd/radius/radius.c @@ -173,6 +173,7 @@ static void ppp_starting(struct ppp_t *ppp) rpd->pd.key = &pd_key; rpd->ppp = ppp; pthread_mutex_init(&rpd->lock, NULL); + INIT_LIST_HEAD(&rpd->plugin_list); list_add_tail(&rpd->pd.entry, &ppp->pd_list); pthread_rwlock_wrlock(&sessions_lock); @@ -331,12 +332,23 @@ int rad_check_nas_pack(struct rad_packet_t *pack) if (conf_nas_identifier && ident && strcmp(conf_nas_identifier, ident)) return -1; + if (conf_nas_ip_address && ipaddr && conf_nas_ip_address != ipaddr) return -1; return 0; } +void __export rad_register_plugin(struct ppp_t *ppp, struct rad_plugin_t *plugin) +{ + struct radius_pd_t *rpd = find_pd(ppp); + + if (!rpd) + return; + + list_add_tail(&plugin->entry, &rpd->plugin_list); +} + static struct ipdb_t ipdb = { .get = get_ip, }; diff --git a/accel-pptpd/radius/radius.h b/accel-pptpd/radius/radius.h index c42989e..ad229d2 100644 --- a/accel-pptpd/radius/radius.h +++ b/accel-pptpd/radius/radius.h @@ -84,6 +84,17 @@ struct rad_packet_t void *buf; }; +struct rad_plugin_t +{ + struct list_head entry; + int (*send_access_request)(struct rad_plugin_t *, struct rad_packet_t *pack); + int (*send_accounting_request)(struct rad_plugin_t *, struct rad_packet_t *pack); +}; + +struct ppp_t; + +void rad_register_plugin(struct ppp_t *, struct rad_plugin_t *); + struct rad_dict_attr_t *rad_dict_find_attr(const char *name); struct rad_dict_attr_t *rad_dict_find_attr_id(struct rad_dict_vendor_t *vendor, int type); struct rad_dict_value_t *rad_dict_find_val_name(struct rad_dict_attr_t *, const char *name); @@ -92,18 +103,15 @@ struct rad_dict_vendor_t *rad_dict_find_vendor_name(const char *name); struct rad_dict_vendor_t *rad_dict_find_vendor_id(int id); struct rad_dict_attr_t *rad_dict_find_vendor_attr(struct rad_dict_vendor_t *vendor, const char *name); -struct rad_attr_t *rad_packet_find_attr(struct rad_packet_t *pack, const char *name); -int rad_packet_add_int(struct rad_packet_t *pack, const char *name, int val); -int rad_packet_add_val(struct rad_packet_t *pack, const char *name, const char *val); -int rad_packet_add_str(struct rad_packet_t *pack, const char *name, const char *val, int len); -int rad_packet_add_octets(struct rad_packet_t *pack, const char *name, const uint8_t *val, int len); -int rad_packet_change_int(struct rad_packet_t *pack, const char *name, int val); -int rad_packet_change_val(struct rad_packet_t *pack, const char *name, const char *val); -int rad_packet_change_octets(struct rad_packet_t *pack, const char *name, const uint8_t *val, int len); -int rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *name, in_addr_t ipaddr); -int rad_packet_add_vendor_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len); -int rad_packet_change_vendor_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len); -struct rad_attr_t *rad_packet_find_vendor_attr(struct rad_packet_t *pack, const char *vendor_name, const char *name); +struct rad_attr_t *rad_packet_find_attr(struct rad_packet_t *pack, const char *vendor, const char *name); +int rad_packet_add_int(struct rad_packet_t *pack, const char *vendor, const char *name, int val); +int rad_packet_add_val(struct rad_packet_t *pack, const char *vendor, const char *name, const char *val); +int rad_packet_add_str(struct rad_packet_t *pack, const char *vendor, const char *name, const char *val); +int rad_packet_add_octets(struct rad_packet_t *pack, const char *vendor, const char *name, const uint8_t *val, int len); +int rad_packet_change_int(struct rad_packet_t *pack, const char *vendor, const char *name, int val); +int rad_packet_change_val(struct rad_packet_t *pack, const char *vendor, const char *name, const char *val); +int rad_packet_change_octets(struct rad_packet_t *pack, const char *vendor, const char *name, const uint8_t *val, int len); +int rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *vendor, const char *name, in_addr_t ipaddr); #endif diff --git a/accel-pptpd/radius/radius_p.h b/accel-pptpd/radius/radius_p.h index 2bd3ff8..9fd0b74 100644 --- a/accel-pptpd/radius/radius_p.h +++ b/accel-pptpd/radius/radius_p.h @@ -38,6 +38,8 @@ struct radius_pd_t uint8_t *attr_state; int attr_state_len; int termination_action; + + struct list_head plugin_list; }; struct rad_req_t diff --git a/accel-pptpd/radius/req.c b/accel-pptpd/radius/req.c index 94c10c3..a384f23 100644 --- a/accel-pptpd/radius/req.c +++ b/accel-pptpd/radius/req.c @@ -21,6 +21,7 @@ static void rad_req_timeout(struct triton_timer_t *t); struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *username) { + struct rad_plugin_t *plugin; struct rad_req_t *req = _malloc(sizeof(*req)); if (!req) @@ -48,32 +49,45 @@ struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *u if (!req->pack) goto out_err; - if (rad_packet_add_str(req->pack, "User-Name", username, strlen(username))) + if (rad_packet_add_str(req->pack, NULL, "User-Name", username)) goto out_err; if (conf_nas_identifier) - if (rad_packet_add_str(req->pack, "NAS-Identifier", conf_nas_identifier, strlen(conf_nas_identifier))) + if (rad_packet_add_str(req->pack, NULL, "NAS-Identifier", conf_nas_identifier)) goto out_err; if (conf_nas_ip_address) - if (rad_packet_add_ipaddr(req->pack, "NAS-IP-Address", conf_nas_ip_address)) + if (rad_packet_add_ipaddr(req->pack, NULL, "NAS-IP-Address", conf_nas_ip_address)) goto out_err; - if (rad_packet_add_int(req->pack, "NAS-Port", rpd->ppp->unit_idx)) + if (rad_packet_add_int(req->pack, NULL, "NAS-Port", rpd->ppp->unit_idx)) goto out_err; - if (rad_packet_add_val(req->pack, "NAS-Port-Type", "Virtual")) + if (rad_packet_add_val(req->pack, NULL, "NAS-Port-Type", "Virtual")) goto out_err; - if (rad_packet_add_val(req->pack, "Service-Type", "Framed-User")) + if (rad_packet_add_val(req->pack, NULL, "Service-Type", "Framed-User")) goto out_err; - if (rad_packet_add_val(req->pack, "Framed-Protocol", "PPP")) + if (rad_packet_add_val(req->pack, NULL, "Framed-Protocol", "PPP")) goto out_err; if (rpd->ppp->ctrl->calling_station_id) - if (rad_packet_add_str(req->pack, "Calling-Station-Id", rpd->ppp->ctrl->calling_station_id, strlen(rpd->ppp->ctrl->calling_station_id))) + if (rad_packet_add_str(req->pack, NULL, "Calling-Station-Id", rpd->ppp->ctrl->calling_station_id)) goto out_err; if (rpd->ppp->ctrl->called_station_id) - if (rad_packet_add_str(req->pack, "Called-Station-Id", rpd->ppp->ctrl->called_station_id, strlen(rpd->ppp->ctrl->called_station_id))) + if (rad_packet_add_str(req->pack, NULL, "Called-Station-Id", rpd->ppp->ctrl->called_station_id)) goto out_err; if (rpd->attr_class) - if (rad_packet_add_octets(req->pack, "Class", rpd->attr_class, rpd->attr_class_len)) + if (rad_packet_add_octets(req->pack, NULL, "Class", rpd->attr_class, rpd->attr_class_len)) goto out_err; + list_for_each_entry(plugin, &req->rpd->plugin_list, entry) { + switch (code) { + case CODE_ACCESS_REQUEST: + if (plugin->send_access_request && plugin->send_access_request(plugin, req->pack)) + goto out_err; + break; + case CODE_ACCOUNTING_REQUEST: + if (plugin->send_accounting_request && plugin->send_accounting_request(plugin, req->pack)) + goto out_err; + break; + } + } + return req; out_err: @@ -88,29 +102,29 @@ int rad_req_acct_fill(struct rad_req_t *req) memset(req->RA, 0, sizeof(req->RA)); - if (rad_packet_add_val(req->pack, "Acct-Status-Type", "Start")) + if (rad_packet_add_val(req->pack, NULL, "Acct-Status-Type", "Start")) return -1; - if (rad_packet_add_val(req->pack, "Acct-Authentic", "RADIUS")) + if (rad_packet_add_val(req->pack, NULL, "Acct-Authentic", "RADIUS")) return -1; - if (rad_packet_add_str(req->pack, "Acct-Session-Id", req->rpd->ppp->sessionid, PPP_SESSIONID_LEN)) + if (rad_packet_add_str(req->pack, NULL, "Acct-Session-Id", req->rpd->ppp->sessionid)) return -1; - if (rad_packet_add_int(req->pack, "Acct-Session-Time", 0)) + if (rad_packet_add_int(req->pack, NULL, "Acct-Session-Time", 0)) return -1; - if (rad_packet_add_int(req->pack, "Acct-Input-Octets", 0)) + if (rad_packet_add_int(req->pack, NULL, "Acct-Input-Octets", 0)) return -1; - if (rad_packet_add_int(req->pack, "Acct-Output-Octets", 0)) + if (rad_packet_add_int(req->pack, NULL, "Acct-Output-Octets", 0)) return -1; - if (rad_packet_add_int(req->pack, "Acct-Input-Packets", 0)) + if (rad_packet_add_int(req->pack, NULL, "Acct-Input-Packets", 0)) return -1; - if (rad_packet_add_int(req->pack, "Acct-Output-Packets", 0)) + if (rad_packet_add_int(req->pack, NULL, "Acct-Output-Packets", 0)) return -1; - if (rad_packet_add_int(req->pack, "Acct-Input-Gigawords", 0)) + if (rad_packet_add_int(req->pack, NULL, "Acct-Input-Gigawords", 0)) return -1; - if (rad_packet_add_int(req->pack, "Acct-Output-Gigawords", 0)) + if (rad_packet_add_int(req->pack, NULL, "Acct-Output-Gigawords", 0)) return -1; - if (rad_packet_add_int(req->pack, "Acct-Delay-Time", 0)) + if (rad_packet_add_int(req->pack, NULL, "Acct-Delay-Time", 0)) return -1; - if (rad_packet_add_ipaddr(req->pack, "Framed-IP-Address", req->rpd->ppp->peer_ipaddr)) + if (rad_packet_add_ipaddr(req->pack, NULL, "Framed-IP-Address", req->rpd->ppp->peer_ipaddr)) return -1; return 0; diff --git a/accel-pptpd/triton/loader.c b/accel-pptpd/triton/loader.c index b6c1914..2a2a2e2 100644 --- a/accel-pptpd/triton/loader.c +++ b/accel-pptpd/triton/loader.c @@ -48,7 +48,7 @@ int load_modules(const char *name) } } - if (!dlopen(fname, RTLD_NOW | RTLD_GLOBAL)) { + if (!dlopen(fname, RTLD_LAZY | RTLD_GLOBAL)) { triton_log_error("loader: failed to load '%s': %s\n", opt->name, dlerror()); _free(fname); return -1; -- GitLab