summaryrefslogtreecommitdiff
path: root/accel-pptpd
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2010-09-28 01:07:28 +0400
committerDmitry Kozlov <xeb@mail.ru>2010-09-28 01:07:28 +0400
commitc654e2d286a10a5bca2c07f3e427f52d600717ac (patch)
treeb811ab8c326d12668e7efd933644cb86695c5c6a /accel-pptpd
parent2902ea733331c1a083487666dbdd847518a0f117 (diff)
downloadaccel-ppp-c654e2d286a10a5bca2c07f3e427f52d600717ac.tar.gz
accel-ppp-c654e2d286a10a5bca2c07f3e427f52d600717ac.zip
auth: implemented timeouts
Diffstat (limited to 'accel-pptpd')
-rw-r--r--accel-pptpd/auth/auth_chap_md5.c100
-rw-r--r--accel-pptpd/auth/auth_mschap_v1.c100
-rw-r--r--accel-pptpd/auth/auth_mschap_v2.c78
-rw-r--r--accel-pptpd/auth/auth_pap.c43
4 files changed, 291 insertions, 30 deletions
diff --git a/accel-pptpd/auth/auth_chap_md5.c b/accel-pptpd/auth/auth_chap_md5.c
index 7681fb5..ba12295 100644
--- a/accel-pptpd/auth/auth_chap_md5.c
+++ b/accel-pptpd/auth/auth_chap_md5.c
@@ -31,6 +31,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
@@ -69,10 +73,16 @@ 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 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)
{
@@ -87,8 +97,6 @@ static void print_str(const char *buf,int size)
log_ppp_debug("%c",buf[i]);
}
-
-
static struct auth_data_t* auth_data_init(struct ppp_t *ppp)
{
struct chap_auth_data_t *d=_malloc(sizeof(*d));
@@ -113,6 +121,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);
@@ -125,11 +137,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("chap-md5: 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 = CHAP_MD5;
@@ -194,6 +236,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)
@@ -205,6 +250,9 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
int r;
struct chap_challenge_t *msg=(struct chap_challenge_t*)hdr;
+ if (ad->timeout.tpd)
+ triton_timer_del(&ad->timeout);
+
log_ppp_debug("recv [CHAP Response id=%x <", msg->hdr.id);
print_buf(msg->val,msg->val_size);
log_ppp_debug(">, name=\"");
@@ -249,20 +297,37 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
{
log_ppp_debug("chap-md5: challenge response mismatch\n");
chap_send_failure(ad);
- auth_failed(ad->ppp);
+ if (ad->started)
+ ppp_terminate(ad->ppp, 0);
+ else
+ auth_failed(ad->ppp);
}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);
+ }
}
+ _free(name);
_free(passwd);
} else if (r == PWDB_DENIED) {
chap_send_failure(ad);
- auth_failed(ad->ppp);
_free(name);
+ if (ad->started)
+ ppp_terminate(ad->ppp, 0);
+ else
+ auth_failed(ad->ppp);
} 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);
+ }
}
}
@@ -297,12 +362,27 @@ static void chap_recv(struct ppp_handler_t *h)
static void __init auth_chap_md5_init()
{
- urandom_fd=open("/dev/urandom",O_RDONLY);
- if (urandom_fd<0)
- {
- log_error("chap-md5: 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("chap-md5: failed to open /dev/urandom: %s\n", strerror(errno));
return;
}
+
if (ppp_auth_register_handler(&chap))
log_error("chap-md5: failed to register handler\n");
}
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");
}
diff --git a/accel-pptpd/auth/auth_mschap_v2.c b/accel-pptpd/auth/auth_mschap_v2.c
index 8e50775..4b5e9a0 100644
--- a/accel-pptpd/auth/auth_mschap_v2.c
+++ b/accel-pptpd/auth/auth_mschap_v2.c
@@ -35,7 +35,12 @@
#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;
+
static uint8_t magic1[39] =
{0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
@@ -95,11 +100,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 *msg, 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)
{
@@ -140,6 +151,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);
@@ -152,11 +167,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-v2: 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_V2;
@@ -280,6 +325,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)
@@ -289,6 +337,9 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
char authenticator[40];
int r;
+ if (ad->timeout.tpd)
+ triton_timer_del(&ad->timeout);
+
log_ppp_debug("recv [MSCHAP-v2 Response id=%x <", msg->hdr.id);
print_buf(msg->peer_challenge,16);
log_ppp_debug(">, <");
@@ -301,20 +352,29 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
{
log_ppp_error("mschap-v2: id mismatch\n");
chap_send_failure(ad);
- ppp_terminate(ad->ppp, 0);
+ if (ad->started)
+ ppp_terminate(ad->ppp, 0);
+ else
+ auth_failed(ad->ppp);
}
if (msg->val_size!=RESPONSE_VALUE_SIZE)
{
log_ppp_error("mschap-v2: value-size should be %i, expected %i\n",RESPONSE_VALUE_SIZE,msg->val_size);
chap_send_failure(ad);
- ppp_terminate(ad->ppp, 0);
+ 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;
}
@@ -328,11 +388,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, msg, authenticator);
- 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);
+ }
}
}
diff --git a/accel-pptpd/auth/auth_pap.c b/accel-pptpd/auth/auth_pap.c
index 2abf572..42ef66b 100644
--- a/accel-pptpd/auth/auth_pap.c
+++ b/accel-pptpd/auth/auth_pap.c
@@ -20,7 +20,7 @@
#define PAP_ACK 2
#define PAP_NAK 3
-char *strndup(const char *s, size_t n);
+static int conf_timeout = 3;
static struct auth_data_t* auth_data_init(struct ppp_t *ppp);
static void auth_data_free(struct ppp_t*, struct auth_data_t*);
@@ -29,12 +29,15 @@ static int lcp_recv_conf_req(struct ppp_t*, struct auth_data_t*, uint8_t*);
static int pap_start(struct ppp_t*, struct auth_data_t*);
static int pap_finish(struct ppp_t*, struct auth_data_t*);
static void pap_recv(struct ppp_handler_t*h);
+static void pap_timeout(struct triton_timer_t *t);
struct pap_auth_data_t
{
struct auth_data_t auth;
struct ppp_handler_t h;
struct ppp_t *ppp;
+ int started:1;
+ struct triton_timer_t timeout;
};
struct pap_hdr_t
@@ -85,8 +88,12 @@ static int pap_start(struct ppp_t *ppp, struct auth_data_t *auth)
{
struct pap_auth_data_t *d=container_of(auth,typeof(*d),auth);
- d->h.proto=PPP_PAP;
- d->h.recv=pap_recv;
+ d->h.proto = PPP_PAP;
+ d->h.recv = pap_recv;
+ d->timeout.expire = pap_timeout;
+ d->timeout.expire_tv.tv_sec = conf_timeout;
+
+ triton_timer_add(ppp->ctrl->ctx, &d->timeout, 0);
ppp_register_chan_handler(ppp,&d->h);
@@ -95,12 +102,23 @@ static int pap_start(struct ppp_t *ppp, struct auth_data_t *auth)
static int pap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
{
struct pap_auth_data_t *d=container_of(auth,typeof(*d),auth);
+
+ if (d->timeout.tpd)
+ triton_timer_del(&d->timeout);
ppp_unregister_handler(ppp,&d->h);
return 0;
}
+static void pap_timeout(struct triton_timer_t *t)
+{
+ struct pap_auth_data_t *d = container_of(t, typeof(*d), timeout);
+
+ log_ppp_warn("pap: timeout\n");
+ auth_failed(d->ppp);
+}
+
static int lcp_send_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *ptr)
{
return 0;
@@ -153,6 +171,9 @@ static int pap_recv_req(struct pap_auth_data_t *p,struct pap_hdr_t *hdr)
int passwd_len;
uint8_t *ptr=(uint8_t*)(hdr+1);
+ if (p->timeout.tpd)
+ triton_timer_del(&p->timeout);
+
log_ppp_debug("recv [PAP AuthReq id=%x]\n",hdr->id);
peer_id_len=*(uint8_t*)ptr; ptr++;
@@ -184,12 +205,18 @@ static int pap_recv_req(struct pap_auth_data_t *p,struct pap_hdr_t *hdr)
if (r == PWDB_DENIED) {
log_ppp_warn("PAP: authentication error\n");
pap_send_nak(p, hdr->id);
- auth_failed(p->ppp);
+ if (p->started)
+ ppp_terminate(p->ppp, 0);
+ else
+ auth_failed(p->ppp);
ret=-1;
_free(peer_id);
} else {
pap_send_ack(p, hdr->id);
- auth_successed(p->ppp, peer_id);
+ if (!p->started) {
+ p->started = 1;
+ auth_successed(p->ppp, peer_id);
+ }
ret = 0;
}
@@ -218,6 +245,12 @@ static void pap_recv(struct ppp_handler_t *h)
static void __init auth_pap_init()
{
+ char *opt;
+
+ opt = conf_get_opt("auth", "timeout");
+ if (opt && atoi(opt) > 0)
+ conf_timeout = atoi(opt);
+
ppp_auth_register_handler(&pap);
}