From a337b4af82fe30d568547aabc61df7bc67a8a835 Mon Sep 17 00:00:00 2001 From: Kozlov Dmitry Date: Mon, 4 Oct 2010 15:12:41 +0400 Subject: ppp: implemented mppe radius: implemented mppe support various improvements and bug fixes --- accel-pptpd/CMakeLists.txt | 1 + accel-pptpd/accel-pptpd.conf | 6 +- accel-pptpd/include/events.h | 2 + accel-pptpd/ppp/ccp_mppe.c | 214 ++++++++++++++++++++ accel-pptpd/ppp/ipcp_opt_dns.c | 3 + accel-pptpd/ppp/ipcp_opt_ipaddr.c | 3 + accel-pptpd/ppp/lcp_opt_accomp.c | 8 +- accel-pptpd/ppp/lcp_opt_magic.c | 7 +- accel-pptpd/ppp/lcp_opt_mru.c | 7 +- accel-pptpd/ppp/lcp_opt_pcomp.c | 8 +- accel-pptpd/ppp/ppp.c | 2 +- accel-pptpd/ppp/ppp_ccp.c | 168 +++++++++++----- accel-pptpd/ppp/ppp_ccp.h | 9 +- accel-pptpd/radius/attr_defs.h | 287 +++++++++++++++++++++++++++ accel-pptpd/radius/auth.c | 132 ++++++++++++ accel-pptpd/radius/dict/dictionary.microsoft | 6 +- accel-pptpd/radius/dict2c.py | 20 ++ accel-pptpd/radius/radius.c | 30 +-- 18 files changed, 828 insertions(+), 85 deletions(-) create mode 100644 accel-pptpd/ppp/ccp_mppe.c create mode 100644 accel-pptpd/radius/attr_defs.h create mode 100644 accel-pptpd/radius/dict2c.py diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt index 9254e7e9..a2c645fa 100644 --- a/accel-pptpd/CMakeLists.txt +++ b/accel-pptpd/CMakeLists.txt @@ -25,6 +25,7 @@ ADD_EXECUTABLE(accel-pptpd ppp/ipcp_opt_ipaddr.c ppp/ipcp_opt_dns.c ppp/ppp_ccp.c + ppp/ccp_mppe.c pwdb.c ipdb.c diff --git a/accel-pptpd/accel-pptpd.conf b/accel-pptpd/accel-pptpd.conf index 7a48802a..22be345f 100644 --- a/accel-pptpd/accel-pptpd.conf +++ b/accel-pptpd/accel-pptpd.conf @@ -19,11 +19,11 @@ min-mtu=1000 mtu=1200 [lcp] -echo-interval=10 +echo-interval=30 echo-failure=3 [pptp] -echo-interval=3 +echo-interval=30 verbose=1 [radius] @@ -39,7 +39,7 @@ verbose=1 [client-ip-range] 192.168.10.20-30 192.168.10.6/32 -192.168.10.1/32 +192.168.10.1/24 192.168.11.0/24 192.168.0.0/24 diff --git a/accel-pptpd/include/events.h b/accel-pptpd/include/events.h index f3278cb2..2f4c4e5c 100644 --- a/accel-pptpd/include/events.h +++ b/accel-pptpd/include/events.h @@ -30,6 +30,8 @@ struct ev_mppe_keys_t struct ppp_t *ppp; uint8_t *recv_key; uint8_t *send_key; + int policy; + int type; }; #endif diff --git a/accel-pptpd/ppp/ccp_mppe.c b/accel-pptpd/ppp/ccp_mppe.c new file mode 100644 index 00000000..8958b520 --- /dev/null +++ b/accel-pptpd/ppp/ccp_mppe.c @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include +#include + +#include "ppp.h" +#include "ppp_ccp.h" +#include "log.h" +#include "events.h" + +#include "memdebug.h" + +#define MPPE_H (1 << 24) +#define MPPE_M (1 << 7) +#define MPPE_S (1 << 6) +#define MPPE_L (1 << 5) +#define MPPE_D (1 << 4) +#define MPPE_C (1 << 0) + +#define MPPE_PAD 4 + +static struct ccp_option_t *mppe_init(struct ppp_ccp_t *ccp); +static void mppe_free(struct ppp_ccp_t *ccp, struct ccp_option_t *opt); +static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr); +static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr); +static void mppe_print(void (*print)(const char *fmt,...),struct ccp_option_t*, uint8_t *ptr); + +struct mppe_option_t +{ + struct ccp_option_t opt; + int mppe; + uint8_t recv_key[16]; + uint8_t send_key[16]; + int policy; // 1 - allowed, 2 - required +}; + +static struct ccp_option_handler_t mppe_opt_hnd = { + .init = mppe_init, + .send_conf_req = mppe_send_conf_req, + .send_conf_nak = mppe_send_conf_req, + .recv_conf_req = mppe_recv_conf_req, + .free = mppe_free, + .print = mppe_print, +}; + +static struct ccp_option_t *mppe_init(struct ppp_ccp_t *ccp) +{ + struct mppe_option_t *mppe_opt = _malloc(sizeof(*mppe_opt)); + memset(mppe_opt, 0, sizeof(*mppe_opt)); + mppe_opt->mppe = -1; + mppe_opt->opt.id = CI_MPPE; + mppe_opt->opt.len = 6; + + return &mppe_opt->opt; +} + +static void mppe_free(struct ppp_ccp_t *ccp, struct ccp_option_t *opt) +{ + struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt); + + _free(mppe_opt); +} + +static int setup_mppe_key(int fd, int transmit, uint8_t *key) +{ + struct ppp_option_data data; + uint8_t buf[6 + 16]; + + memset(buf, 0, sizeof(buf)); + buf[0] = CI_MPPE; + buf[1] = 6; + *(uint32_t*)(buf + 2) = htonl(MPPE_S | MPPE_H); + if (key) + memcpy(buf + 6, key, 16); + + memset(&data, 0, sizeof(data)); + data.ptr = buf; + data.length = sizeof(buf); + data.transmit = transmit; + + if (ioctl(fd, PPPIOCSCOMPRESS, &data)) { + log_ppp_warn("mppe: MPPE requested but not supported by kernel\n"); + return -1; + } + + return 0; +} + +static int decrease_mtu(struct ppp_t *ppp) +{ + struct ifreq ifr; + + strcpy(ifr.ifr_name, ppp->ifname); + + if (ioctl(sock_fd, SIOCGIFMTU, &ifr)) { + log_ppp_error("mppe: failed to get MTU: %s\n", strerror(errno)); + return -1; + } + + ifr.ifr_mtu -= MPPE_PAD; + + if (ioctl(sock_fd, SIOCSIFMTU, &ifr)) { + log_ppp_error("mppe: failed to set MTU: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr) +{ + struct mppe_option_t *mppe_opt = container_of(opt,typeof(*mppe_opt),opt); + struct ccp_opt32_t *opt32 = (struct ccp_opt32_t*)ptr; + + if (mppe_opt->policy == 2 || mppe_opt->mppe != -1) { + opt32->hdr.id = CI_MPPE; + opt32->hdr.len = 6; + opt32->val = mppe_opt->mppe ? htonl(MPPE_S | MPPE_H) : 0; + + if (mppe_opt->mppe && setup_mppe_key(ccp->ppp->unit_fd, 0, mppe_opt->recv_key)) + return 0; + + return 6; + } + return 0; +} + +static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr) +{ + struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt); + struct ccp_opt32_t *opt32 = (struct ccp_opt32_t *)ptr; + + /*if (!ptr) { + if (mppe_opt->policy == 2) + return CCP_OPT_NAK; + return CCP_OPT_ACK; + }*/ + + if (opt32->hdr.len != 6) + return CCP_OPT_REJ; + + if (mppe_opt->policy == 2) { + if (ntohl(opt32->val) != (MPPE_S | MPPE_H)) + return CCP_OPT_NAK; + } else if (mppe_opt->policy == 1) { + if (ntohl(opt32->val) == (MPPE_S | MPPE_H)) + mppe_opt->mppe = 1; + else if ((ntohl(opt32->val) & (MPPE_S | MPPE_H)) == (MPPE_S | MPPE_H)) { + mppe_opt->mppe = 1; + return CCP_OPT_NAK; + } else if (opt32->val) { + mppe_opt->mppe = 0; + return CCP_OPT_NAK; + } else + mppe_opt->mppe = 0; + } + + if (setup_mppe_key(ccp->ppp->unit_fd, 1, mppe_opt->send_key)) + return CCP_OPT_REJ; + + decrease_mtu(ccp->ppp); + + return CCP_OPT_ACK; +} + +static void mppe_print(void (*print)(const char *fmt,...),struct ccp_option_t *opt, uint8_t *ptr) +{ + struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt); + struct ccp_opt32_t *opt32 = (struct ccp_opt32_t *)ptr; + uint32_t bits; + + if (ptr) + bits = ntohl(opt32->val); + else + if (mppe_opt->mppe) + bits = MPPE_S | MPPE_H; + else + bits = 0; + + print("", + bits & MPPE_H ? "+" : "-", + bits & MPPE_M ? "+" : "-", + bits & MPPE_S ? "+" : "-", + bits & MPPE_L ? "+" : "-", + bits & MPPE_D ? "+" : "-", + bits & MPPE_C ? "+" : "-" + ); +} + +static void ev_mppe_keys(struct ev_mppe_keys_t *ev) +{ + struct mppe_option_t *mppe_opt = container_of(ccp_find_option(ev->ppp, &mppe_opt_hnd), typeof(*mppe_opt), opt); + + if ((ev->type & 0x02) == 0) { + log_ppp_warn("mppe: 128-bit session keys not allowed, disabling mppe ...\n"); + return; + } + + memcpy(mppe_opt->recv_key, ev->recv_key, 16); + memcpy(mppe_opt->send_key, ev->send_key, 16); + mppe_opt->policy = ev->policy; + + if (ev->policy == 2) + mppe_opt->mppe = 1; +} + +static void __init mppe_opt_init() +{ + ccp_option_register(&mppe_opt_hnd); + triton_event_register_handler(EV_MPPE_KEYS, (triton_event_func)ev_mppe_keys); +} + diff --git a/accel-pptpd/ppp/ipcp_opt_dns.c b/accel-pptpd/ppp/ipcp_opt_dns.c index b0365da2..4c48fd4c 100644 --- a/accel-pptpd/ppp/ipcp_opt_dns.c +++ b/accel-pptpd/ppp/ipcp_opt_dns.c @@ -101,6 +101,9 @@ static int dns_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, struct dns_option_t *dns_opt=container_of(opt,typeof(*dns_opt),opt); struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; + if (opt32->hdr.len != 6) + return IPCP_OPT_REJ; + if (!dns_opt->addr) { if (dns_opt->opt.id == CI_DNS1 && conf_dns1) dns_opt->addr=conf_dns1; diff --git a/accel-pptpd/ppp/ipcp_opt_ipaddr.c b/accel-pptpd/ppp/ipcp_opt_ipaddr.c index 963d4736..108e350c 100644 --- a/accel-pptpd/ppp/ipcp_opt_ipaddr.c +++ b/accel-pptpd/ppp/ipcp_opt_ipaddr.c @@ -104,6 +104,9 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o struct sockaddr_in addr; struct npioctl np; + if (opt32->hdr.len != 6) + return IPCP_OPT_REJ; + if (ipaddr_opt->ip->peer_addr == opt32->val) goto ack; diff --git a/accel-pptpd/ppp/lcp_opt_accomp.c b/accel-pptpd/ppp/lcp_opt_accomp.c index 94fa1281..241b0e06 100644 --- a/accel-pptpd/ppp/lcp_opt_accomp.c +++ b/accel-pptpd/ppp/lcp_opt_accomp.c @@ -75,13 +75,17 @@ static int accomp_send_conf_nak(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, static int accomp_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr) { struct accomp_option_t *accomp_opt=container_of(opt,typeof(*accomp_opt),opt); + struct lcp_opt_hdr_t *opt0=(struct lcp_opt_hdr_t*)ptr; - if (!ptr) { + /*if (!ptr) { if (accomp_opt->require) return LCP_OPT_NAK; accomp_opt->accomp=0; return LCP_OPT_ACK; - } + }*/ + + if (opt0->len != 2) + return LCP_OPT_REJ; if (accomp_opt->accomp>0) { diff --git a/accel-pptpd/ppp/lcp_opt_magic.c b/accel-pptpd/ppp/lcp_opt_magic.c index 166c85c4..4a61ef91 100644 --- a/accel-pptpd/ppp/lcp_opt_magic.c +++ b/accel-pptpd/ppp/lcp_opt_magic.c @@ -64,8 +64,11 @@ static int magic_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, struct magic_option_t *magic_opt=container_of(opt,typeof(*magic_opt),opt); struct lcp_opt32_t *opt32=(struct lcp_opt32_t*)ptr; - if (!ptr) - return LCP_OPT_NAK; + /*if (!ptr) + return LCP_OPT_NAK;*/ + + if (opt32->hdr.len != 6) + return LCP_OPT_REJ; if (magic_opt->magic==ntohl(opt32->val)) { diff --git a/accel-pptpd/ppp/lcp_opt_mru.c b/accel-pptpd/ppp/lcp_opt_mru.c index 096c0d58..9bf7af67 100644 --- a/accel-pptpd/ppp/lcp_opt_mru.c +++ b/accel-pptpd/ppp/lcp_opt_mru.c @@ -86,8 +86,11 @@ static int mru_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, ui struct mru_option_t *mru_opt = container_of(opt,typeof(*mru_opt),opt); struct lcp_opt16_t *opt16 = (struct lcp_opt16_t*)ptr; - if (!ptr) - return LCP_OPT_NAK; + /*if (!ptr) + return LCP_OPT_NAK;*/ + + if (opt16->hdr.len != 4) + return LCP_OPT_REJ; if (ntohs(opt16->val) < conf_min_mtu || ntohs(opt16->val) > lcp->ppp->ctrl->max_mtu) return LCP_OPT_NAK; diff --git a/accel-pptpd/ppp/lcp_opt_pcomp.c b/accel-pptpd/ppp/lcp_opt_pcomp.c index a1ceb8e8..1f8532bb 100644 --- a/accel-pptpd/ppp/lcp_opt_pcomp.c +++ b/accel-pptpd/ppp/lcp_opt_pcomp.c @@ -75,13 +75,17 @@ static int pcomp_send_conf_nak(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, static int pcomp_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr) { struct pcomp_option_t *pcomp_opt=container_of(opt,typeof(*pcomp_opt),opt); + struct lcp_opt_hdr_t *opt0=(struct lcp_opt_hdr_t*)ptr; - if (!ptr) { + /*if (!ptr) { if (pcomp_opt->require) return LCP_OPT_NAK; pcomp_opt->pcomp=0; return LCP_OPT_ACK; - } + }*/ + + if (opt0->len != 2) + return LCP_OPT_REJ; if (pcomp_opt->pcomp>0) { diff --git a/accel-pptpd/ppp/ppp.c b/accel-pptpd/ppp/ppp.c index 94919779..ee7e13cc 100644 --- a/accel-pptpd/ppp/ppp.c +++ b/accel-pptpd/ppp/ppp.c @@ -424,8 +424,8 @@ static int get_layer_order(const char *name) { if (!strcmp(name,"lcp")) return 0; if (!strcmp(name,"auth")) return 1; - if (!strcmp(name,"ipcp")) return 2; if (!strcmp(name,"ccp")) return 2; + if (!strcmp(name,"ipcp")) return 3; return -1; } diff --git a/accel-pptpd/ppp/ppp_ccp.c b/accel-pptpd/ppp/ppp_ccp.c index 6deaeb18..36db6f9a 100644 --- a/accel-pptpd/ppp/ppp_ccp.c +++ b/accel-pptpd/ppp/ppp_ccp.c @@ -1,8 +1,9 @@ #include #include +#include #include #include -#include +#include #include "triton.h" @@ -22,6 +23,7 @@ struct recv_opt_t struct ccp_option_t *lopt; }; +static struct ppp_layer_t ccp_layer; static LIST_HEAD(option_handlers); static void ccp_layer_up(struct ppp_fsm_t*); @@ -65,6 +67,26 @@ static void ccp_options_free(struct ppp_ccp_t *ccp) } } +static int ccp_set_flags(int fd, int isopen, int isup) +{ + int flags; + + if (ioctl(fd, PPPIOCGFLAGS, &flags)) { + log_ppp_error("ccp: failed to get flags: %s\n", strerror(errno)); + return -1; + } + + flags &= ~(SC_CCP_OPEN | SC_CCP_UP); + flags |= (isopen ? SC_CCP_OPEN : 0) | (isup ? SC_CCP_UP : 0); + + if (ioctl(fd, PPPIOCSFLAGS, &flags)) { + log_ppp_error("ccp: failed to set flags: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp) { struct ppp_ccp_t *ccp=_malloc(sizeof(*ccp)); @@ -80,6 +102,11 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp) ppp_register_unit_handler(ppp,&ccp->hnd); + INIT_LIST_HEAD(&ccp->options); + ccp_options_init(ccp); + + ccp->passive = 1; + ccp->fsm.proto = PPP_CCP; ppp_fsm_init(&ccp->fsm); @@ -92,7 +119,6 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp) ccp->fsm.send_term_req=send_term_req; ccp->fsm.send_term_ack=send_term_ack; - INIT_LIST_HEAD(&ccp->options); INIT_LIST_HEAD(&ccp->ropt_list); return &ccp->ld; @@ -104,8 +130,6 @@ int ccp_layer_start(struct ppp_layer_data_t *ld) log_ppp_debug("ccp_layer_start\n"); - ccp_options_init(ccp); - if (list_empty(&ccp->options)) { ppp_layer_started(ccp->ppp, &ccp->ld); return 0; @@ -115,6 +139,11 @@ int ccp_layer_start(struct ppp_layer_data_t *ld) if (ppp_fsm_open(&ccp->fsm)) return -1; + if (ccp_set_flags(ccp->ppp->unit_fd, 1, 0)) { + ppp_fsm_close(&ccp->fsm); + return -1; + } + return 0; } @@ -123,6 +152,8 @@ void ccp_layer_finish(struct ppp_layer_data_t *ld) struct ppp_ccp_t *ccp=container_of(ld,typeof(*ccp),ld); log_ppp_debug("ccp_layer_finish\n"); + + ccp_set_flags(ccp->ppp->unit_fd, 0, 0); ccp->fsm.fsm_state = FSM_Closed; ppp_layer_finished(ccp->ppp,&ccp->ld); @@ -146,6 +177,10 @@ static void ccp_layer_up(struct ppp_fsm_t *fsm) struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm); log_ppp_debug("ccp_layer_started\n"); ccp->started = 1; + if (ccp_set_flags(ccp->ppp->unit_fd, 1, 1)) { + ppp_terminate(ccp->ppp, 0); + return; + } ppp_layer_started(ccp->ppp,&ccp->ld); } @@ -174,38 +209,45 @@ static void print_ropt(struct recv_opt_t *ropt) static int send_conf_req(struct ppp_fsm_t *fsm) { - struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm); - uint8_t *buf=_malloc(ccp->conf_req_len), *ptr=buf; - struct ccp_hdr_t *ccp_hdr=(struct ccp_hdr_t*)ptr; + struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm); + uint8_t *buf, *ptr; + struct ccp_hdr_t *ccp_hdr; struct ccp_option_t *lopt; int n; - log_ppp_debug("send [CCP ConfReq"); - ccp_hdr->proto=htons(PPP_CCP); - ccp_hdr->code=CONFREQ; - ccp_hdr->id=++ccp->fsm.id; - ccp_hdr->len=0; - log_ppp_debug(" id=%x",ccp_hdr->id); + ccp->need_req = 0; + + if (ccp->passive) + return 0; + + buf = _malloc(ccp->conf_req_len); + ccp_hdr = (struct ccp_hdr_t*)buf; + + ccp_hdr->proto = htons(PPP_CCP); + ccp_hdr->code = CONFREQ; + ccp_hdr->id = ++ccp->fsm.id; + ccp_hdr->len = 0; - ptr+=sizeof(*ccp_hdr); + ptr = (uint8_t*)(ccp_hdr + 1); - list_for_each_entry(lopt,&ccp->options,entry) - { - n=lopt->h->send_conf_req(ccp,lopt,ptr); + log_ppp_debug("send [CCP ConfReq id=%x", ccp_hdr->id); + + list_for_each_entry(lopt,&ccp->options,entry) { + n = lopt->h->send_conf_req(ccp,lopt,ptr); if (n < 0) return -1; - if (n) - { + if (n) { log_ppp_debug(" "); - lopt->h->print(log_ppp_debug,lopt,NULL); - ptr+=n; + lopt->h->print(log_ppp_debug, lopt, NULL); + lopt->state = CCP_OPT_ACK; } + ptr += n; } log_ppp_debug("]\n"); - - ccp_hdr->len=htons((ptr-buf)-2); - ppp_unit_send(ccp->ppp,ccp_hdr,ptr-buf); + + ccp_hdr->len = htons((ptr-buf)-2); + ppp_unit_send(ccp->ppp, ccp_hdr, ptr-buf); _free(buf); @@ -298,9 +340,10 @@ static int ccp_recv_conf_req(struct ppp_ccp_t *ccp,uint8_t *data,int size) struct ccp_opt_hdr_t *hdr; struct recv_opt_t *ropt; struct ccp_option_t *lopt; - int r,ret=1,ack=0; + int r, ret = 1, ack = 0; - ccp->ropt_len=size; + ccp->need_req = 0; + ccp->ropt_len = size; while(size>0) { @@ -318,41 +361,37 @@ static int ccp_recv_conf_req(struct ppp_ccp_t *ccp,uint8_t *data,int size) size-=ropt->len; } - list_for_each_entry(lopt,&ccp->options,entry) - lopt->state=CCP_OPT_NONE; - - log_ppp_debug("recv [CCP ConfReq id=%x",ccp->fsm.recv_id); - list_for_each_entry(ropt,&ccp->ropt_list,entry) + log_ppp_debug("recv [CCP ConfReq id=%x", ccp->fsm.recv_id); + list_for_each_entry(ropt, &ccp->ropt_list, entry) { - list_for_each_entry(lopt,&ccp->options,entry) + list_for_each_entry(lopt, &ccp->options, entry) { - if (lopt->id==ropt->hdr->id) - { + if (lopt->id == ropt->hdr->id) { log_ppp_debug(" "); - lopt->h->print(log_ppp_debug,lopt,(uint8_t*)ropt->hdr); - r=lopt->h->recv_conf_req(ccp,lopt,(uint8_t*)ropt->hdr); - if (ack) - { - lopt->state=CCP_OPT_REJ; - ropt->state=CCP_OPT_REJ; - }else - { - lopt->state=r; - ropt->state=r; + lopt->h->print(log_ppp_debug, lopt, (uint8_t*)ropt->hdr); + r = lopt->h->recv_conf_req(ccp, lopt, (uint8_t*)ropt->hdr); + if (ack) { + lopt->state = CCP_OPT_REJ; + ropt->state = CCP_OPT_REJ; + } else { + if (lopt->state == CCP_OPT_NAK && r == CCP_OPT_ACK) + ccp->need_req = 1; + lopt->state = r; + ropt->state = r; } - ropt->lopt=lopt; - if (rlopt = lopt; + if (r < ret) + ret = r; break; } } - if (ropt->state==CCP_OPT_ACK || ropt->state==CCP_OPT_NAK) - ack=1; - else if (!ropt->lopt) - { + if (ropt->state == CCP_OPT_ACK || ropt->state == CCP_OPT_NAK) + ack = 1; + else if (!ropt->lopt) { log_ppp_debug(" "); print_ropt(ropt); - ropt->state=CCP_OPT_REJ; - ret=CCP_OPT_REJ; + ropt->state = CCP_OPT_REJ; + ret = CCP_OPT_REJ; } } log_ppp_debug("]\n"); @@ -570,14 +609,22 @@ static void ccp_recv(struct ppp_handler_t*h) break; } ccp_free_conf_req(ccp); - if (r==CCP_OPT_FAIL) + + if (r == CCP_OPT_ACK && ccp->passive) { + ccp->passive = 0; + send_conf_req(&ccp->fsm); + } + if (r == CCP_OPT_FAIL) ppp_terminate(ccp->ppp, 0); break; case CONFACK: if (ccp_recv_conf_ack(ccp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) ppp_terminate(ccp->ppp, 0); - else + else { ppp_fsm_recv_conf_ack(&ccp->fsm); + if (ccp->need_req) + send_conf_req(&ccp->fsm); + } break; case CONFNAK: ccp_recv_conf_nak(ccp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN); @@ -625,6 +672,19 @@ int ccp_option_register(struct ccp_option_handler_t *h) return 0; } +struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handler_t *h) +{ + struct ppp_ccp_t *ccp = container_of(ppp_find_layer_data(ppp, &ccp_layer), typeof(*ccp), ld); + struct ccp_option_t *opt; + + list_for_each_entry(opt, &ccp->options, entry) + if (opt->h == h) + return opt; + + log_emerg("ccp: BUG: option not found\n"); + abort(); +} + static struct ppp_layer_t ccp_layer= { .init=ccp_layer_init, diff --git a/accel-pptpd/ppp/ppp_ccp.h b/accel-pptpd/ppp/ppp_ccp.h index 23f44f0f..27b303e6 100644 --- a/accel-pptpd/ppp/ppp_ccp.h +++ b/accel-pptpd/ppp/ppp_ccp.h @@ -8,10 +8,8 @@ /* * Options. */ -#define CI_COMP 2 /* IP-Compress-Protocol */ -#define CI_ADDR 3 /* IP-Address */ -#define CI_DNS1 129 /* Primary-DNS-Address */ -#define CI_DNS2 131 /* Secondary-DNS-Address */ + +#define CI_MPPE 18 /* MPPE */ struct ccp_hdr_t { @@ -87,9 +85,12 @@ struct ppp_ccp_t int conf_req_len; int started:1; + int passive:1; + int need_req:1; }; int ccp_option_register(struct ccp_option_handler_t *h); +struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handler_t *h); #endif diff --git a/accel-pptpd/radius/attr_defs.h b/accel-pptpd/radius/attr_defs.h new file mode 100644 index 00000000..e9b617e4 --- /dev/null +++ b/accel-pptpd/radius/attr_defs.h @@ -0,0 +1,287 @@ +#define User_Name 1 +#define User_Password 2 +#define CHAP_Password 3 +#define NAS_IP_Address 4 +#define NAS_Port 5 +#define Service_Type 6 +#define Framed_Protocol 7 +#define Framed_IP_Address 8 +#define Framed_IP_Netmask 9 +#define Framed_Routing 10 +#define Filter_Id 11 +#define Framed_MTU 12 +#define Framed_Compression 13 +#define Login_IP_Host 14 +#define Login_Service 15 +#define Login_TCP_Port 16 +#define Reply_Message 18 +#define Callback_Number 19 +#define Callback_Id 20 +#define Framed_Route 22 +#define Framed_IPX_Network 23 +#define State 24 +#define Class 25 +#define Vendor_Specific 26 +#define Session_Timeout 27 +#define Idle_Timeout 28 +#define Termination_Action 29 +#define Called_Station_Id 30 +#define Calling_Station_Id 31 +#define NAS_Identifier 32 +#define Proxy_State 33 +#define Login_LAT_Service 34 +#define Login_LAT_Node 35 +#define Login_LAT_Group 36 +#define Framed_AppleTalk_Link 37 +#define Framed_AppleTalk_Network 38 +#define Framed_AppleTalk_Zone 39 +#define CHAP_Challenge 60 +#define NAS_Port_Type 61 +#define Port_Limit 62 +#define Login_LAT_Port 63 +#define Service_Type_Login_User 1 +#define Service_Type_Framed_User 2 +#define Service_Type_Callback_Login_User 3 +#define Service_Type_Callback_Framed_User 4 +#define Service_Type_Outbound_User 5 +#define Service_Type_Administrative_User 6 +#define Service_Type_NAS_Prompt_User 7 +#define Service_Type_Authenticate_Only 8 +#define Service_Type_Callback_NAS_Prompt 9 +#define Service_Type_Call_Check 10 +#define Service_Type_Callback_Administrative 11 +#define Framed_Protocol_PPP 1 +#define Framed_Protocol_SLIP 2 +#define Framed_Protocol_ARAP 3 +#define Framed_Protocol_Gandalf_SLML 4 +#define Framed_Protocol_Xylogics_IPX_SLIP 5 +#define Framed_Protocol_X_75_Synchronous 6 +#define Framed_Routing_None 0 +#define Framed_Routing_Broadcast 1 +#define Framed_Routing_Listen 2 +#define Framed_Routing_Broadcast_Listen 3 +#define Framed_Compression_None 0 +#define Framed_Compression_Van_Jacobson_TCP_IP 1 +#define Framed_Compression_IPX_Header_Compression 2 +#define Framed_Compression_Stac_LZS 3 +#define Login_Service_Telnet 0 +#define Login_Service_Rlogin 1 +#define Login_Service_TCP_Clear 2 +#define Login_Service_PortMaster 3 +#define Login_Service_LAT 4 +#define Login_Service_X25_PAD 5 +#define Login_Service_X25_T3POS 6 +#define Login_Service_TCP_Clear_Quiet 8 +#define Login_TCP_Port_Telnet 23 +#define Login_TCP_Port_Rlogin 513 +#define Login_TCP_Port_Rsh 514 +#define Termination_Action_Default 0 +#define Termination_Action_RADIUS_Request 1 +#define NAS_Port_Type_Async 0 +#define NAS_Port_Type_Sync 1 +#define NAS_Port_Type_ISDN 2 +#define NAS_Port_Type_ISDN_V120 3 +#define NAS_Port_Type_ISDN_V110 4 +#define NAS_Port_Type_Virtual 5 +#define NAS_Port_Type_PIAFS 6 +#define NAS_Port_Type_HDLC_Clear_Channel 7 +#define NAS_Port_Type_X_25 8 +#define NAS_Port_Type_X_75 9 +#define NAS_Port_Type_G_3_Fax 10 +#define NAS_Port_Type_SDSL 11 +#define NAS_Port_Type_ADSL_CAP 12 +#define NAS_Port_Type_ADSL_DMT 13 +#define NAS_Port_Type_IDSL 14 +#define NAS_Port_Type_Ethernet 15 +#define NAS_Port_Type_xDSL 16 +#define NAS_Port_Type_Cable 17 +#define NAS_Port_Type_Wireless_Other 18 +#define NAS_Port_Type_Wireless_802_11 19 +#define Acct_Status_Type 40 +#define Acct_Delay_Time 41 +#define Acct_Input_Octets 42 +#define Acct_Output_Octets 43 +#define Acct_Session_Id 44 +#define Acct_Authentic 45 +#define Acct_Session_Time 46 +#define Acct_Input_Packets 47 +#define Acct_Output_Packets 48 +#define Acct_Terminate_Cause 49 +#define Acct_Multi_Session_Id 50 +#define Acct_Link_Count 51 +#define Acct_Status_Type_Start 1 +#define Acct_Status_Type_Stop 2 +#define Acct_Status_Type_Alive 3 +#define Acct_Status_Type_Interim_Update 3 +#define Acct_Status_Type_Accounting_On 7 +#define Acct_Status_Type_Accounting_Off 8 +#define Acct_Status_Type_Failed 15 +#define Acct_Authentic_RADIUS 1 +#define Acct_Authentic_Local 2 +#define Acct_Authentic_Remote 3 +#define Acct_Authentic_Diameter 4 +#define Acct_Terminate_Cause_User_Request 1 +#define Acct_Terminate_Cause_Lost_Carrier 2 +#define Acct_Terminate_Cause_Lost_Service 3 +#define Acct_Terminate_Cause_Idle_Timeout 4 +#define Acct_Terminate_Cause_Session_Timeout 5 +#define Acct_Terminate_Cause_Admin_Reset 6 +#define Acct_Terminate_Cause_Admin_Reboot 7 +#define Acct_Terminate_Cause_Port_Error 8 +#define Acct_Terminate_Cause_NAS_Error 9 +#define Acct_Terminate_Cause_NAS_Request 10 +#define Acct_Terminate_Cause_NAS_Reboot 11 +#define Acct_Terminate_Cause_Port_Unneeded 12 +#define Acct_Terminate_Cause_Port_Preempted 13 +#define Acct_Terminate_Cause_Port_Suspended 14 +#define Acct_Terminate_Cause_Service_Unavailable 15 +#define Acct_Terminate_Cause_Callback 16 +#define Acct_Terminate_Cause_User_Error 17 +#define Acct_Terminate_Cause_Host_Request 18 +#define Acct_Tunnel_Connection 68 +#define Acct_Tunnel_Packets_Lost 86 +#define Acct_Status_Type_Tunnel_Start 9 +#define Acct_Status_Type_Tunnel_Stop 10 +#define Acct_Status_Type_Tunnel_Reject 11 +#define Acct_Status_Type_Tunnel_Link_Start 12 +#define Acct_Status_Type_Tunnel_Link_Stop 13 +#define Acct_Status_Type_Tunnel_Link_Reject 14 +#define Tunnel_Type 64 +#define Tunnel_Medium_Type 65 +#define Tunnel_Client_Endpoint 66 +#define Tunnel_Server_Endpoint 67 +#define Tunnel_Password 69 +#define Tunnel_Private_Group_Id 81 +#define Tunnel_Assignment_Id 82 +#define Tunnel_Preference 83 +#define Tunnel_Client_Auth_Id 90 +#define Tunnel_Server_Auth_Id 91 +#define Tunnel_Type_PPTP 1 +#define Tunnel_Type_L2F 2 +#define Tunnel_Type_L2TP 3 +#define Tunnel_Type_ATMP 4 +#define Tunnel_Type_VTP 5 +#define Tunnel_Type_AH 6 +#define Tunnel_Type_IP 7 +#define Tunnel_Type_MIN_IP 8 +#define Tunnel_Type_ESP 9 +#define Tunnel_Type_GRE 10 +#define Tunnel_Type_DVS 11 +#define Tunnel_Type_IP_in_IP 12 +#define Tunnel_Medium_Type_IP 1 +#define Tunnel_Medium_Type_IPv4 1 +#define Tunnel_Medium_Type_IPv6 2 +#define Tunnel_Medium_Type_NSAP 3 +#define Tunnel_Medium_Type_HDLC 4 +#define Tunnel_Medium_Type_BBN_1822 5 +#define Tunnel_Medium_Type_IEEE_802 6 +#define Tunnel_Medium_Type_E_163 7 +#define Tunnel_Medium_Type_E_164 8 +#define Tunnel_Medium_Type_F_69 9 +#define Tunnel_Medium_Type_X_121 10 +#define Tunnel_Medium_Type_IPX 11 +#define Tunnel_Medium_Type_Appletalk 12 +#define Tunnel_Medium_Type_DecNet_IV 13 +#define Tunnel_Medium_Type_Banyan_Vines 14 +#define Tunnel_Medium_Type_E_164_NSAP 15 +#define Acct_Input_Gigawords 52 +#define Acct_Output_Gigawords 53 +#define Event_Timestamp 55 +#define ARAP_Password 70 +#define ARAP_Features 71 +#define ARAP_Zone_Access 72 +#define ARAP_Security 73 +#define ARAP_Security_Data 74 +#define Password_Retry 75 +#define Prompt 76 +#define Connect_Info 77 +#define Configuration_Token 78 +#define EAP_Message 79 +#define Message_Authenticator 80 +#define ARAP_Challenge_Response 84 +#define Acct_Interim_Interval 85 +#define NAS_Port_Id 87 +#define Framed_Pool 88 +#define ARAP_Zone_Access_Default_Zone 1 +#define ARAP_Zone_Access_Zone_Filter_Inclusive 2 +#define ARAP_Zone_Access_Zone_Filter_Exclusive 4 +#define Prompt_No_Echo 0 +#define Prompt_Echo 1 +#define Error_Cause 101 +#define Service_Type_Authorize_Only 17 +#define Error_Cause_Residual_Context_Removed 201 +#define Error_Cause_Invalid_EAP_Packet 202 +#define Error_Cause_Unsupported_Attribute 401 +#define Error_Cause_Missing_Attribute 402 +#define Error_Cause_NAS_Identification_Mismatch 403 +#define Error_Cause_Invalid_Request 404 +#define Error_Cause_Unsupported_Service 405 +#define Error_Cause_Unsupported_Extension 406 +#define Error_Cause_Administratively_Prohibited 501 +#define Error_Cause_Proxy_Request_Not_Routable 502 +#define Error_Cause_Session_Context_Not_Found 503 +#define Error_Cause_Session_Context_Not_Removable 504 +#define Error_Cause_Proxy_Processing_Error 505 +#define Error_Cause_Resources_Unavailable 506 +#define Error_Cause_Request_Initiated 507 +#define Acct_Terminate_Cause_Supplicant_Restart 19 +#define Acct_Terminate_Cause_Reauthentication_Failure 20 +#define Acct_Terminate_Cause_Port_Reinit 21 +#define Acct_Terminate_Cause_Port_Disabled 22 +#define NAS_Port_Type_Token_Ring 20 +#define NAS_Port_Type_FDDI 21 +#define Tunnel_Type_VLAN 13 +#define EAP_Key_Name 102 +#define Chargeable_User_Identity 89 +#define Error_Cause_Invalid_Attribute_Value 407 +#define Error_Cause_Multiple_Session_Selection_Unsupported 508 +#define Vendor_Microsoft 311 +#define MS_CHAP_Response 1 +#define MS_CHAP_Error 2 +#define MS_CHAP_CPW_1 3 +#define MS_CHAP_CPW_2 4 +#define MS_CHAP_LM_Enc_PW 5 +#define MS_CHAP_NT_Enc_PW 6 +#define MS_MPPE_Encryption_Policy 7 +#define MS_MPPE_Encryption_Type 8 +#define MS_MPPE_Encryption_Types 8 +#define MS_RAS_Vendor 9 +#define MS_CHAP_Domain 10 +#define MS_CHAP_Challenge 11 +#define MS_CHAP_MPPE_Keys 12 +#define MS_BAP_Usage 13 +#define MS_Link_Utilization_Threshold 14 +#define MS_Link_Drop_Time_Limit 15 +#define MS_MPPE_Send_Key 16 +#define MS_MPPE_Recv_Key 17 +#define MS_RAS_Version 18 +#define MS_Old_ARAP_Password 19 +#define MS_New_ARAP_Password 20 +#define MS_ARAP_PW_Change_Reason 21 +#define MS_Filter 22 +#define MS_Acct_Auth_Type 23 +#define MS_Acct_EAP_Type 24 +#define MS_CHAP2_Response 25 +#define MS_CHAP2_Success 26 +#define MS_CHAP2_CPW 27 +#define MS_Primary_DNS_Server 28 +#define MS_Secondary_DNS_Server 29 +#define MS_Primary_NBNS_Server 30 +#define MS_Secondary_NBNS_Server 31 +#define MS_BAP_Usage_Not_Allowed 0 +#define MS_BAP_Usage_Allowed 1 +#define MS_BAP_Usage_Required 2 +#define MS_ARAP_PW_Change_Reason_Just_Change_Password 1 +#define MS_ARAP_PW_Change_Reason_Expired_Password 2 +#define MS_ARAP_PW_Change_Reason_Admin_Requires_Password_Change 3 +#define MS_ARAP_PW_Change_Reason_Password_Too_Short 4 +#define MS_Acct_Auth_Type_PAP 1 +#define MS_Acct_Auth_Type_CHAP 2 +#define MS_Acct_Auth_Type_MS_CHAP_1 3 +#define MS_Acct_Auth_Type_MS_CHAP_2 4 +#define MS_Acct_Auth_Type_EAP 5 +#define MS_Acct_EAP_Type_MD5 4 +#define MS_Acct_EAP_Type_OTP 5 +#define MS_Acct_EAP_Type_Generic_Token_Card 6 +#define MS_Acct_EAP_Type_TLS 13 +#define Traffic_Shape_in 231 diff --git a/accel-pptpd/radius/auth.c b/accel-pptpd/radius/auth.c index 9b61ecc6..10fdd458 100644 --- a/accel-pptpd/radius/auth.c +++ b/accel-pptpd/radius/auth.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "triton.h" #include "events.h" @@ -8,9 +9,96 @@ #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[16]; + 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(key, &sha1_ctx); + + 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; @@ -160,6 +248,48 @@ out: 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; @@ -196,6 +326,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar .reply = req->reply, }; triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev); + setup_mppe(req, challenge); } out: @@ -251,6 +382,7 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar .reply = req->reply, }; triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev); + setup_mppe(req, NULL); } out: diff --git a/accel-pptpd/radius/dict/dictionary.microsoft b/accel-pptpd/radius/dict/dictionary.microsoft index 6d6e71ae..9ca6b8e9 100644 --- a/accel-pptpd/radius/dict/dictionary.microsoft +++ b/accel-pptpd/radius/dict/dictionary.microsoft @@ -14,11 +14,11 @@ ATTRIBUTE MS-CHAP-CPW-1 3 octets ATTRIBUTE MS-CHAP-CPW-2 4 octets ATTRIBUTE MS-CHAP-LM-Enc-PW 5 octets ATTRIBUTE MS-CHAP-NT-Enc-PW 6 octets -ATTRIBUTE MS-MPPE-Encryption-Policy 7 octets +ATTRIBUTE MS-MPPE-Encryption-Policy 7 integer # This is referred to as both singular and plural in the RFC. # Plural seems to make more sense. -ATTRIBUTE MS-MPPE-Encryption-Type 8 octets -ATTRIBUTE MS-MPPE-Encryption-Types 8 octets +ATTRIBUTE MS-MPPE-Encryption-Type 8 integer +ATTRIBUTE MS-MPPE-Encryption-Types 8 integer ATTRIBUTE MS-RAS-Vendor 9 integer # content is Vendor-ID ATTRIBUTE MS-CHAP-Domain 10 string ATTRIBUTE MS-CHAP-Challenge 11 octets diff --git a/accel-pptpd/radius/dict2c.py b/accel-pptpd/radius/dict2c.py new file mode 100644 index 00000000..ff0961e7 --- /dev/null +++ b/accel-pptpd/radius/dict2c.py @@ -0,0 +1,20 @@ +import sys,re + +hdr = file(sys.argv[2],'w') + +def process(fname, hdr): + for line in file(fname): + if line[:-1].strip() == '': + continue + if line[0] == '#': + continue + f = re.compile('[$.a-zA-Z0-9\-]+').findall(line) + if f[0] == 'ATTRIBUTE' or f[0] == 'VENDOR': + hdr.write('#define {0} {1}\n'.format(f[1].replace('-','_').replace('.','_'), f[2])) + elif f[0] == 'VALUE': + hdr.write('#define {0}_{1} {2}\n'.format(f[1].replace('-','_').replace('.','_'), f[2].replace('-','_'),f[3])) + elif f[0] == '$INCLUDE': + process(f[1], hdr) + +if __name__ == '__main__': + process(sys.argv[1], hdr) diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c index 42b39a5d..fb5a2ca0 100644 --- a/accel-pptpd/radius/radius.c +++ b/accel-pptpd/radius/radius.c @@ -13,6 +13,7 @@ #include "ipdb.h" #include "radius_p.h" +#include "attr_defs.h" #include "memdebug.h" @@ -49,18 +50,23 @@ void rad_proc_attrs(struct rad_req_t *req) struct rad_attr_t *attr; list_for_each_entry(attr, &req->reply->attrs, entry) { - if (!strcmp(attr->attr->name, "Framed-IP-Address")) { - if (!conf_gw_ip_address) - log_ppp_warn("radius: gw-ip-address not specified, cann't assign IP address...\n"); - else { - req->rpd->ipaddr.owner = &ipdb; - req->rpd->ipaddr.peer_addr = attr->val.ipaddr; - req->rpd->ipaddr.addr = inet_addr(conf_gw_ip_address); - } - } else if (!strcmp(attr->attr->name, "Acct-Interim-Interval")) - req->rpd->acct_interim_interval = attr->val.integer; - else if (!strcmp(attr->attr->name, "Session-Timeout")) - req->rpd->session_timeout.expire_tv.tv_sec = attr->val.integer; + switch(attr->attr->id) { + case Framed_IP_Address: + if (!conf_gw_ip_address) + log_ppp_warn("radius: gw-ip-address not specified, cann't assign IP address...\n"); + else { + req->rpd->ipaddr.owner = &ipdb; + req->rpd->ipaddr.peer_addr = attr->val.ipaddr; + req->rpd->ipaddr.addr = inet_addr(conf_gw_ip_address); + } + break; + case Acct_Interim_Interval: + req->rpd->acct_interim_interval = attr->val.integer; + break; + case Session_Timeout: + req->rpd->session_timeout.expire_tv.tv_sec = attr->val.integer; + break; + } } } -- cgit v1.2.3