diff options
Diffstat (limited to 'accel-pptpd/auth/auth_mschap_v1.c')
-rw-r--r-- | accel-pptpd/auth/auth_mschap_v1.c | 100 |
1 files changed, 90 insertions, 10 deletions
diff --git a/accel-pptpd/auth/auth_mschap_v1.c b/accel-pptpd/auth/auth_mschap_v1.c index 818d60d..ac8edd7 100644 --- a/accel-pptpd/auth/auth_mschap_v1.c +++ b/accel-pptpd/auth/auth_mschap_v1.c @@ -34,6 +34,10 @@ #define HDR_LEN (sizeof(struct chap_hdr_t)-2) +static int conf_timeout = 3; +static int conf_interval = 0; +static int conf_max_failure = 2; + static int urandom_fd; struct chap_hdr_t @@ -82,11 +86,17 @@ struct chap_auth_data_t struct ppp_t *ppp; int id; uint8_t val[VALUE_SIZE]; + struct triton_timer_t timeout; + struct triton_timer_t interval; + int failure; + int started:1; }; static void chap_send_challenge(struct chap_auth_data_t *ad); static void chap_recv(struct ppp_handler_t *h); static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response_t *res, const char *name); +static void chap_timeout(struct triton_timer_t *t); +static void chap_restart(struct triton_timer_t *t); static void print_buf(const uint8_t *buf,int size) { @@ -125,6 +135,10 @@ static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth) d->h.proto=PPP_CHAP; d->h.recv=chap_recv; + d->timeout.expire = chap_timeout; + d->timeout.expire_tv.tv_sec = conf_timeout; + d->interval.expire = chap_restart; + d->interval.expire_tv.tv_sec = conf_interval; ppp_register_chan_handler(ppp,&d->h); @@ -137,11 +151,41 @@ static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth) { struct chap_auth_data_t *d=container_of(auth,typeof(*d),auth); + if (d->timeout.tpd) + triton_timer_del(&d->timeout); + + if (d->interval.tpd) + triton_timer_del(&d->interval); + ppp_unregister_handler(ppp,&d->h); return 0; } +static void chap_timeout(struct triton_timer_t *t) +{ + struct chap_auth_data_t *d = container_of(t, typeof(*d), timeout); + + log_ppp_warn("mschap-v1: timeout\n"); + + if (++d->failure == conf_max_failure) { + if (d->started) + ppp_terminate(d->ppp, 0); + else + auth_failed(d->ppp); + } else { + --d->id; + chap_send_challenge(d); + } +} + +static void chap_restart(struct triton_timer_t *t) +{ + struct chap_auth_data_t *d = container_of(t, typeof(*d), interval); + + chap_send_challenge(d); +} + static int lcp_send_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *ptr) { *ptr=MSCHAP_V1; @@ -206,6 +250,9 @@ static void chap_send_challenge(struct chap_auth_data_t *ad) log_ppp_debug(">]\n"); ppp_chan_send(ad->ppp,&msg,ntohs(msg.hdr.len)+2); + + if (conf_timeout && !ad->timeout.tpd) + triton_timer_add(ad->ppp->ctrl->ctx, &ad->timeout, 0); } static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *hdr) @@ -214,6 +261,9 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h char *name; int r; + if (ad->timeout.tpd) + triton_timer_del(&ad->timeout); + log_ppp_debug("recv [MSCHAP-v1 Response id=%x <", msg->hdr.id); print_buf(msg->lm_hash,24); log_ppp_debug(">, <"); @@ -226,20 +276,29 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h { log_ppp_error("mschap-v1: id mismatch\n"); chap_send_failure(ad); - auth_failed(ad->ppp); + if (ad->started) + ppp_terminate(ad->ppp, 0); + else + auth_failed(ad->ppp); } if (msg->val_size!=RESPONSE_VALUE_SIZE) { log_ppp_error("mschap-v1: value-size should be %i, expected %i\n",RESPONSE_VALUE_SIZE,msg->val_size); chap_send_failure(ad); - auth_failed(ad->ppp); + if (ad->started) + ppp_terminate(ad->ppp, 0); + else + auth_failed(ad->ppp); } name = _strndup(msg->name,ntohs(msg->hdr.len)-sizeof(*msg)+2); if (!name) { log_emerg("mschap-v2: out of memory\n"); - auth_failed(ad->ppp); + if (ad->started) + ppp_terminate(ad->ppp, 0); + else + auth_failed(ad->ppp); return; } @@ -249,11 +308,19 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h if (r == PWDB_DENIED) { chap_send_failure(ad); - auth_failed(ad->ppp); + if (ad->started) + ppp_terminate(ad->ppp, 0); + else + auth_failed(ad->ppp); _free(name); } else { chap_send_success(ad); - auth_successed(ad->ppp, name); + if (!ad->started) { + ad->started = 1; + if (conf_interval) + triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0); + auth_successed(ad->ppp, name); + } } } @@ -356,13 +423,26 @@ static void chap_recv(struct ppp_handler_t *h) static void __init auth_mschap_v1_init() { - urandom_fd=open("/dev/urandom",O_RDONLY); - if (urandom_fd<0) - { - log_error("mschap-v1: failed to open /dev/urandom: %s\n",strerror(errno)); + char *opt; + + opt = conf_get_opt("auth", "timeout"); + if (opt && atoi(opt) > 0) + conf_timeout = atoi(opt); + + opt = conf_get_opt("auth", "interval"); + if (opt && atoi(opt) > 0) + conf_interval = atoi(opt); + + opt = conf_get_opt("auth", "max-failure"); + if (opt && atoi(opt) > 0) + conf_max_failure = atoi(opt); + + urandom_fd = open("/dev/urandom", O_RDONLY); + if (urandom_fd < 0) { + log_emerg("mschap-v1: failed to open /dev/urandom: %s\n", strerror(errno)); return; } if (ppp_auth_register_handler(&chap)) - log_error("mschap-v1: failed to register handler\n"); + log_emerg("mschap-v1: failed to register handler\n"); } |