diff options
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/accel-ppp.conf | 4 | ||||
-rw-r--r-- | accel-pppd/accel-ppp.conf.5 | 46 | ||||
-rw-r--r-- | accel-pppd/auth/auth_chap_md5.c | 44 | ||||
-rw-r--r-- | accel-pppd/auth/auth_pap.c | 23 | ||||
-rw-r--r-- | accel-pppd/ctrl/l2tp/l2tp.c | 10 | ||||
-rw-r--r-- | accel-pppd/ctrl/pppoe/pppoe.c | 8 | ||||
-rw-r--r-- | accel-pppd/ctrl/pptp/pptp.c | 9 | ||||
-rw-r--r-- | accel-pppd/ctrl/sstp/sstp.c | 13 | ||||
-rw-r--r-- | accel-pppd/ipv6/dhcpv6.c | 5 | ||||
-rw-r--r-- | accel-pppd/ipv6/nd.c | 2 | ||||
-rw-r--r-- | accel-pppd/session.c | 10 |
11 files changed, 149 insertions, 25 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf index abc82469..d5c69bf8 100644 --- a/accel-pppd/accel-ppp.conf +++ b/accel-pppd/accel-ppp.conf @@ -67,8 +67,12 @@ unit-cache=1 #unit-preallocate=1 [auth] +#timeout=5 +#interval=0 +#max-failure=3 #any-login=0 #noauth=0 +#challenge-name=accel-ppp [pptp] verbose=1 diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5 index 6eca3582..f951325c 100644 --- a/accel-pppd/accel-ppp.conf.5 +++ b/accel-pppd/accel-ppp.conf.5 @@ -137,6 +137,11 @@ Specifies netlink maximum send buffer size (SO_SNDBUF option) (default 32768). .TP .BI "nl-rcv-buffer=" n Specifies netlink maximum receive buffer size (SO_RCVBUF option) (default 1048576). +.TP +.BI "session-timeout=" n +Specifies max sessions time in seconds, after this time session will be terminated. +.br +This timeout can be redefined with radius attribute Session-Timeout. 0 value means infinite timeout. .SH [ppp] .br PPP module configuration. @@ -239,6 +244,27 @@ This should reduce kernel-level interface creation/deletion rate lack. .TP .BI "unit-preallocate=" 0|1 If set to 1 then allocate ppp unit (interface) before authorization, so Nas-Port and Nas-Port-Id would be defined in Access-Request phase. +.SH [auth] +.br +Contains authentication params +.TP +.BI "timeout=" n +If n is not zero specifies timeout in seconds to wait for PAP, CHAP, Microsoft CHAP v1/v2 authentication. +.TP +.BI "interval=" n +If n is not zero specifies timeout in seconds to restart CHAP and Microsoft CHAP v1/v2 authentication. +.TP +.BI "max-failure=" n +If n is not zero specifies maximum number of CHAP and Microsoft CHAP v1/v2 authentication failures. +.TP +.BI "any-login=" 0|1 +If set to 1 allows pass PAP, CHAP and Microsoft CHAP v1 authentication with any login. +.TP +.BI "noauth=" 0|1 +If set to 1 skips any PPP and IPOE authentication. +.TP +.BI "challenge-name=" name +Specifies challenge name for CHAP authentication. .SH [ipoe] .TP .BI "verbose=" n @@ -538,6 +564,11 @@ as a template, i.e pptp%d => pptp0. .BI "ppp-max-mtu=" n Set the maximum MTU value that can be negotiated for PPP over PPTP sessions. Default value is 1436. +.TP +.BI "session-timeout=" n +Specifies max sessions time in seconds, after this time session will be terminated. +.br +This timeout can be redefined with radius attribute Session-Timeout. 0 value means infinite timeout. .SH [pppoe] .br Configuration of PPPoE module. @@ -607,6 +638,11 @@ Specifies overall limit of PADI packets to reply in 1 second period (default 0 - If this option is given ppp interface will be renamed using .B ifname as a template, i.e pppoe%d => pppoe0. +.TP +.BI "session-timeout=" n +Specifies max sessions time in seconds, after this time session will be terminated. +.br +This timeout can be redefined with radius attribute Session-Timeout. 0 value means infinite timeout. .SH [l2tp] .br Configuration of L2TP module. @@ -698,6 +734,11 @@ sessions. Default value is 1420. If this option is given ppp interface will be renamed using .B ifname as a template, i.e l2tp%d => l2tp0. +.TP +.BI "session-timeout=" n +Specifies max sessions time in seconds, after this time session will be terminated. +.br +This timeout can be redefined with radius attribute Session-Timeout. 0 value means infinite timeout. .SH [sstp] .br Configuration of SSTP module. @@ -804,6 +845,11 @@ as a template, i.e sstp%d => sstp0. .BI "ppp-max-mtu=" n Set the maximum MTU value that can be negotiated for PPP over SSTP sessions. Default value is 1452, maximum is 4087. +.TP +.BI "session-timeout=" n +Specifies max sessions time in seconds, after this time session will be terminated. +.br +This timeout can be redefined with radius attribute Session-Timeout. 0 value means infinite timeout. .SH [radius] .br Configuration of RADIUS module. diff --git a/accel-pppd/auth/auth_chap_md5.c b/accel-pppd/auth/auth_chap_md5.c index d3982334..3ff685e6 100644 --- a/accel-pppd/auth/auth_chap_md5.c +++ b/accel-pppd/auth/auth_chap_md5.c @@ -36,6 +36,7 @@ static int conf_timeout = 5; static int conf_interval = 0; static int conf_max_failure = 3; static int conf_any_login = 0; +static const char *conf_challenge_name = "accel-ppp"; struct chap_hdr { uint16_t proto; @@ -220,31 +221,36 @@ static void chap_send_success(struct chap_auth_data *ad, int id) static void chap_send_challenge(struct chap_auth_data *ad, int new) { -#define CHAP_CHALLENGE_NAME "accel-ppp" - struct { - struct chap_challenge m; - char name[sizeof(CHAP_CHALLENGE_NAME)]; - } __attribute__((packed)) msg = { - .m.hdr.proto = htons(PPP_CHAP), - .m.hdr.code = CHAP_CHALLENGE, - .m.hdr.id = ad->id, - .m.hdr.len = htons(sizeof(struct chap_challenge) - 2 + strlen(CHAP_CHALLENGE_NAME)), - .m.val_size = VALUE_SIZE, - .name = CHAP_CHALLENGE_NAME, - }; + struct chap_challenge *msg; + int name_len; + + name_len = conf_challenge_name ? strlen(conf_challenge_name) : 0; + msg = alloca(sizeof(*msg) + name_len); + memset(msg, 0, sizeof(*msg) + name_len); + + msg->hdr.proto = htons(PPP_CHAP); + msg->hdr.code = CHAP_CHALLENGE; + msg->hdr.id = ad->id; + msg->hdr.len = htons(sizeof(*msg) + name_len - 2); if (new) read(urandom_fd, ad->val, VALUE_SIZE); - memcpy(msg.m.val, ad->val, VALUE_SIZE); + memcpy(msg->val, ad->val, VALUE_SIZE); + msg->val_size = VALUE_SIZE; + + if (name_len) + memcpy(msg->name, conf_challenge_name, name_len); if (conf_ppp_verbose) { - log_ppp_info2("send [CHAP Challenge id=%x <", msg.m.hdr.id); - print_buf(msg.m.val, VALUE_SIZE); - log_ppp_info2(">]\n"); + log_ppp_info2("send [CHAP Challenge id=%x <", msg->hdr.id); + print_buf(msg->val, VALUE_SIZE); + log_ppp_info2("> name=\""); + print_str(msg->name, ntohs(msg->hdr.len) - sizeof(*msg) + 2); + log_ppp_info2("\"]\n"); } - ppp_chan_send(ad->ppp, &msg, ntohs(msg.m.hdr.len) + 2); + ppp_chan_send(ad->ppp, msg, ntohs(msg->hdr.len) + 2); if (conf_timeout && !ad->timeout.tpd) triton_timer_add(ad->ppp->ses.ctrl->ctx, &ad->timeout, 0); @@ -481,6 +487,10 @@ static void load_config(void) opt = conf_get_opt("auth", "any-login"); if (opt) conf_any_login = atoi(opt); + + opt = conf_get_opt("auth", "challenge-name"); + if (opt) + conf_challenge_name = opt; } static void auth_chap_md5_init() diff --git a/accel-pppd/auth/auth_pap.c b/accel-pppd/auth/auth_pap.c index 40921019..f31be8b4 100644 --- a/accel-pppd/auth/auth_pap.c +++ b/accel-pppd/auth/auth_pap.c @@ -43,6 +43,7 @@ struct pap_auth_data { char *peer_id; int req_id; unsigned int started:1; + unsigned int active:1; }; struct pap_hdr { @@ -76,6 +77,10 @@ static struct auth_data_t* auth_data_init(struct ppp_t *ppp) d->auth.len = 0; d->ppp = ppp; + d->h.proto = PPP_PAP; + d->h.recv = pap_recv; + ppp_register_chan_handler(ppp, &d->h); + return &d->auth; } @@ -83,6 +88,11 @@ static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth) { struct pap_auth_data *d = container_of(auth, typeof(*d), auth); + if (d->timeout.tpd) + triton_timer_del(&d->timeout); + + ppp_unregister_handler(ppp, &d->h); + _free(d); } @@ -90,14 +100,12 @@ static int pap_start(struct ppp_t *ppp, struct auth_data_t *auth) { struct pap_auth_data *d = container_of(auth, typeof(*d), auth); - d->h.proto = PPP_PAP; - d->h.recv = pap_recv; d->timeout.expire = pap_timeout; d->timeout.period = conf_timeout * 1000; triton_timer_add(ppp->ses.ctrl->ctx, &d->timeout, 0); - ppp_register_chan_handler(ppp, &d->h); + d->active = 1; return 0; } @@ -105,14 +113,14 @@ static int pap_finish(struct ppp_t *ppp, struct auth_data_t *auth) { struct pap_auth_data *d = container_of(auth, typeof(*d), auth); + d->active = 0; + if (d->timeout.tpd) triton_timer_del(&d->timeout); if (d->peer_id) _free(d->peer_id); - ppp_unregister_handler(ppp, &d->h); - return 0; } @@ -200,6 +208,11 @@ static int pap_recv_req(struct pap_auth_data *p, struct pap_hdr *hdr) int passwd_len; uint8_t *ptr = (uint8_t*)(hdr + 1); + if (!p->active) { + log_ppp_debug("PAP: unexpected packet received\n"); + return 0; + } + if (p->timeout.tpd) triton_timer_del(&p->timeout); diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c index 8567027d..027d7100 100644 --- a/accel-pppd/ctrl/l2tp/l2tp.c +++ b/accel-pppd/ctrl/l2tp/l2tp.c @@ -93,6 +93,7 @@ static size_t conf_secret_len = 0; static int conf_mppe = MPPE_UNSET; static int conf_dataseq = L2TP_DATASEQ_ALLOW; static int conf_reorder_timeout = 0; +static int conf_session_timeout; static const char *conf_ip_pool; static const char *conf_ipv6_pool; static const char *conf_dpv6_pool; @@ -1813,6 +1814,9 @@ static int l2tp_session_start_data_channel(struct l2tp_sess_t *sess) if (conf_ifname) sess->ppp.ses.ifname_rename = _strdup(conf_ifname); + if (conf_session_timeout) + sess->ppp.ses.session_timeout = conf_session_timeout; + sess->ppp.ses.ctrl = &sess->ctrl; sess->apses_state = APSTATE_INIT; @@ -4972,6 +4976,12 @@ static void load_config(void) conf_dpv6_pool = conf_get_opt("l2tp", "ipv6-pool-delegate"); conf_ifname = conf_get_opt("l2tp", "ifname"); + opt = conf_get_opt("l2tp", "session-timeout"); + if (opt) + conf_session_timeout = atoi(opt); + else + conf_session_timeout = 0; + switch (iprange_check_activation()) { case IPRANGE_DISABLED: log_warn("l2tp: iprange module disabled, improper IP configuration of PPP interfaces may cause kernel soft lockup\n"); diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c index 415dd7c0..43163f16 100644 --- a/accel-pppd/ctrl/pppoe/pppoe.c +++ b/accel-pppd/ctrl/pppoe/pppoe.c @@ -127,6 +127,7 @@ unsigned long stat_filtered; pthread_rwlock_t serv_lock = PTHREAD_RWLOCK_INITIALIZER; LIST_HEAD(serv_list); static int connlimit_loaded; +static int conf_session_timeout; static pthread_mutex_t sid_lock = PTHREAD_MUTEX_INITIALIZER; static unsigned long *sid_map; @@ -417,6 +418,8 @@ static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const ui conn->ppp.ses.dpv6_pool_name = _strdup(conf_dpv6_pool); if (conf_ifname) conn->ppp.ses.ifname_rename = _strdup(conf_ifname); + if (conf_session_timeout) + conn->ppp.ses.session_timeout = conf_session_timeout; triton_context_register(&conn->ctx, conn); @@ -2027,6 +2030,11 @@ static void load_config(void) else conf_cookie_timeout = 5; + opt = conf_get_opt("pppoe", "session-timeout"); + if (opt) + conf_session_timeout = atoi(opt); + else + conf_session_timeout = 0; conf_mppe = MPPE_UNSET; opt = conf_get_opt("pppoe", "mppe"); diff --git a/accel-pppd/ctrl/pptp/pptp.c b/accel-pppd/ctrl/pptp/pptp.c index a5bcaca8..a95fe8ae 100644 --- a/accel-pppd/ctrl/pptp/pptp.c +++ b/accel-pppd/ctrl/pptp/pptp.c @@ -60,6 +60,7 @@ static int conf_timeout = 5; static int conf_echo_interval = 0; static int conf_echo_failure = 3; static int conf_verbose = 0; +static int conf_session_timeout; static int conf_mppe = MPPE_UNSET; static const char *conf_ip_pool; static const char *conf_ipv6_pool; @@ -721,6 +722,8 @@ static int pptp_connect(struct triton_md_handler_t *h) conn->ppp.ses.dpv6_pool_name = _strdup(conf_dpv6_pool); if (conf_ifname) conn->ppp.ses.ifname_rename = _strdup(conf_ifname); + if (conf_session_timeout) + conn->ppp.ses.session_timeout = conf_session_timeout; triton_context_register(&conn->ctx, &conn->ppp.ses); triton_md_register_handler(&conn->ctx, &conn->hnd); @@ -807,6 +810,12 @@ static void load_config(void) conf_dpv6_pool = conf_get_opt("pptp", "ipv6-pool-delegate"); conf_ifname = conf_get_opt("pptp", "ifname"); + opt = conf_get_opt("pptp", "session-timeout"); + if (opt) + conf_session_timeout = atoi(opt); + else + conf_session_timeout = 0; + switch (iprange_check_activation()) { case IPRANGE_DISABLED: log_warn("pptp: iprange module disabled, improper IP configuration of PPP interfaces may cause kernel soft lockup\n"); diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c index 4b154005..40c6ad91 100644 --- a/accel-pppd/ctrl/sstp/sstp.c +++ b/accel-pppd/ctrl/sstp/sstp.c @@ -169,6 +169,7 @@ static const char *conf_ifname; static int conf_proxyproto = 0; static int conf_sndbuf = 0; static int conf_rcvbuf = 0; +static int conf_session_timeout; static int conf_hash_protocol = CERT_HASH_PROTOCOL_SHA1 | CERT_HASH_PROTOCOL_SHA256; static struct hash_t conf_hash_sha1 = { .len = 0 }; @@ -2401,6 +2402,8 @@ static int sstp_connect(struct triton_md_handler_t *h) conn->ppp.ses.dpv6_pool_name = _strdup(conf_dpv6_pool); if (conf_ifname) conn->ppp.ses.ifname_rename = _strdup(conf_ifname); + if (conf_session_timeout) + conn->ppp.ses.session_timeout = conf_session_timeout; sockaddr_ntop(&addr, addr_buf, sizeof(addr_buf), FLAG_NOPORT); conn->ctrl.calling_station_id = _strdup(addr_buf); @@ -2412,12 +2415,12 @@ static int sstp_connect(struct triton_md_handler_t *h) triton_context_register(&conn->ctx, &conn->ppp.ses); triton_context_call(&conn->ctx, (triton_event_func)sstp_start, conn); + triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); triton_context_wakeup(&conn->ctx); - __sync_add_and_fetch(&stat_starting, 1); triton_event_fire(EV_CTRL_STARTING, &conn->ppp.ses); - triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); + __sync_add_and_fetch(&stat_starting, 1); } return 0; @@ -2843,6 +2846,12 @@ static void load_config(void) if (opt && atoi(opt) > 0) conf_rcvbuf = atoi(opt); + opt = conf_get_opt("sstp", "session-timeout"); + if (opt) + conf_session_timeout = atoi(opt); + else + conf_session_timeout = 0; + ipmode = (serv.addr.u.sa.sa_family == AF_INET && !conf_proxyproto) ? iprange_check_activation() : -1; switch (ipmode) { diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c index 91b396c3..cefbcfd8 100644 --- a/accel-pppd/ipv6/dhcpv6.c +++ b/accel-pppd/ipv6/dhcpv6.c @@ -76,7 +76,10 @@ static void ev_ses_started(struct ap_session *ses) if (a->prefix_len == 0 || IN6_IS_ADDR_UNSPECIFIED(&a->addr)) return; + net->enter_ns(); sock = net->socket(AF_INET6, SOCK_DGRAM, 0); + net->exit_ns(); + if (!sock) { log_ppp_error("dhcpv6: socket: %s\n", strerror(errno)); return; @@ -85,7 +88,7 @@ static void ev_ses_started(struct ap_session *ses) net->setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &f, sizeof(f)); if (net->setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ses->ifname, strlen(ses->ifname))) { - log_ppp_error("ipv6_nd: setsockopt(SO_BINDTODEVICE): %s\n", strerror(errno)); + log_ppp_error("dhcpv6: setsockopt(SO_BINDTODEVICE): %s\n", strerror(errno)); close(sock); return; } diff --git a/accel-pppd/ipv6/nd.c b/accel-pppd/ipv6/nd.c index 943ed6d3..297e4d63 100644 --- a/accel-pppd/ipv6/nd.c +++ b/accel-pppd/ipv6/nd.c @@ -284,7 +284,9 @@ static int ipv6_nd_start(struct ap_session *ses) int val; struct ipv6_nd_handler_t *h; + net->enter_ns(); sock = net->socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + net->exit_ns(); if (sock < 0) { log_ppp_error("socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6): %s\n", strerror(errno)); diff --git a/accel-pppd/session.c b/accel-pppd/session.c index 63c9c11b..81ac271b 100644 --- a/accel-pppd/session.c +++ b/accel-pppd/session.c @@ -35,6 +35,7 @@ static int conf_single_session = -1; static int conf_single_session_ignore_case; static int conf_sid_source; static int conf_seq_save_timeout = 10; +static int conf_session_timeout; static const char *conf_seq_file; int __export conf_max_sessions; int __export conf_max_starting; @@ -152,6 +153,9 @@ void __export ap_session_activate(struct ap_session *ses) __sync_sub_and_fetch(&ap_session_stat.starting, 1); __sync_add_and_fetch(&ap_session_stat.active, 1); + if (!ses->session_timeout && conf_session_timeout) + ses->session_timeout = conf_session_timeout; + if (ses->idle_timeout) { ses->timer.expire = ap_session_timer; ses->timer.period = 60000; @@ -547,6 +551,12 @@ static void load_config(void) conf_max_starting = atoi(opt); else conf_max_starting = 0; + + opt = conf_get_opt("common", "session-timeout"); + if (opt) + conf_session_timeout = atoi(opt); + else + conf_session_timeout = 0; } static void init(void) |