summaryrefslogtreecommitdiff
path: root/accel-pptpd/auth/auth_mschap_v1.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pptpd/auth/auth_mschap_v1.c')
-rw-r--r--accel-pptpd/auth/auth_mschap_v1.c100
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");
}