summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/accel-ppp.conf1
-rw-r--r--accel-pppd/accel-ppp.conf.511
-rw-r--r--accel-pppd/auth/auth_chap_md5.c41
-rw-r--r--accel-pppd/auth/auth_mschap_v1.c26
-rw-r--r--accel-pppd/auth/auth_mschap_v2.c19
-rw-r--r--accel-pppd/auth/auth_pap.c21
-rw-r--r--accel-pppd/ppp/ppp.c12
-rw-r--r--accel-pppd/ppp/ppp.h1
-rw-r--r--accel-pppd/ppp/ppp_auth.c32
-rw-r--r--accel-pppd/ppp/ppp_auth.h2
10 files changed, 131 insertions, 35 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf
index 31ad4e0f..a549a557 100644
--- a/accel-pppd/accel-ppp.conf
+++ b/accel-pppd/accel-ppp.conf
@@ -29,6 +29,7 @@ mru=1400
#ccp=0
#sid-case=upper
#check-ip=0
+#single-session=replace
[lcp]
echo-interval=30
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index d9aaadb3..0180f5ec 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -104,6 +104,17 @@ Specifies in which case generate session identifier (default lower).
.BI "check-ip=" 0|1
Specifies whether accel-ppp should check if IP already assigned to other ppp interface (default 0).
.TP
+.BI "single-session=" replace|deny
+Specifies whether accel-ppp should control sessions count.
+.br
+If this option is absent session count control is turned off.
+If this option is
+.B replace
+then accel-ppp will terminate first session when second is authorized.
+If this option is
+.B deny
+then accel-ppp will deny second session authorization.
+.TP
.SH [lcp]
.br
PPP LCP module configuration
diff --git a/accel-pppd/auth/auth_chap_md5.c b/accel-pppd/auth/auth_chap_md5.c
index 2ea60ba7..a9a5572a 100644
--- a/accel-pppd/auth/auth_chap_md5.c
+++ b/accel-pppd/auth/auth_chap_md5.c
@@ -289,9 +289,14 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
name = _strndup(msg->name,ntohs(msg->hdr.len) - sizeof(*msg) + 2);
if (conf_any_login) {
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ return;
+ }
chap_send_success(ad);
ad->started = 1;
- ppp_auth_successed(ad->ppp, name);
return;
}
@@ -325,12 +330,17 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
ppp_auth_failed(ad->ppp, name);
_free(name);
} else {
- chap_send_success(ad);
if (!ad->started) {
- ad->started = 1;
- if (conf_interval)
- triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
- ppp_auth_successed(ad->ppp, name);
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ } else {
+ chap_send_success(ad);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
+ }
} else
_free(name);
}
@@ -343,14 +353,21 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
ppp_auth_failed(ad->ppp, name);
_free(name);
} else {
- chap_send_success(ad);
if (!ad->started) {
- ad->started = 1;
- if (conf_interval)
- triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
- ppp_auth_successed(ad->ppp, name);
- } else
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ } else {
+ chap_send_success(ad);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
+ }
+ } else {
+ chap_send_success(ad);
_free(name);
+ }
}
}
diff --git a/accel-pppd/auth/auth_mschap_v1.c b/accel-pppd/auth/auth_mschap_v1.c
index 4308300a..237e3aa2 100644
--- a/accel-pppd/auth/auth_mschap_v1.c
+++ b/accel-pppd/auth/auth_mschap_v1.c
@@ -312,9 +312,14 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
}
if (conf_any_login) {
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ return;
+ }
chap_send_success(ad);
ad->started = 1;
- ppp_auth_successed(ad->ppp, name);
return;
}
@@ -331,14 +336,21 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
ppp_auth_failed(ad->ppp, name);
_free(name);
} else {
- chap_send_success(ad);
if (!ad->started) {
- ad->started = 1;
- if (conf_interval)
- triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
- ppp_auth_successed(ad->ppp, name);
- } else
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ } else {
+ chap_send_success(ad);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
+ }
+ } else {
+ chap_send_success(ad);
_free(name);
+ }
}
}
diff --git a/accel-pppd/auth/auth_mschap_v2.c b/accel-pppd/auth/auth_mschap_v2.c
index 644f70b2..c14e44f3 100644
--- a/accel-pppd/auth/auth_mschap_v2.c
+++ b/accel-pppd/auth/auth_mschap_v2.c
@@ -404,14 +404,21 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
ppp_auth_failed(ad->ppp, name);
_free(name);
} else {
- chap_send_success(ad, msg, authenticator);
if (!ad->started) {
- ad->started = 1;
- if (conf_interval)
- triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
- ppp_auth_successed(ad->ppp, name);
- } else
+ if (ppp_auth_successed(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
+ _free(name);
+ } else {
+ chap_send_success(ad, msg, authenticator);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
+ }
+ } else {
+ chap_send_success(ad, msg, authenticator);
_free(name);
+ }
}
}
diff --git a/accel-pppd/auth/auth_pap.c b/accel-pppd/auth/auth_pap.c
index 70e80819..c03a9a10 100644
--- a/accel-pppd/auth/auth_pap.c
+++ b/accel-pppd/auth/auth_pap.c
@@ -198,9 +198,14 @@ static int pap_recv_req(struct pap_auth_data_t *p, struct pap_hdr_t *hdr)
peer_id = _strndup((const char*)peer_id, peer_id_len);
if (conf_any_login) {
+ if (ppp_auth_successed(p->ppp, peer_id)) {
+ pap_send_nak(p, hdr->id);
+ ppp_terminate(p->ppp, TERM_AUTH_ERROR, 0);
+ _free(peer_id);
+ return -1;
+ }
pap_send_ack(p, hdr->id);
p->started = 1;
- ppp_auth_successed(p->ppp, peer_id);
return 0;
}
@@ -223,15 +228,19 @@ static int pap_recv_req(struct pap_auth_data_t *p, struct pap_hdr_t *hdr)
ppp_terminate(p->ppp, TERM_AUTH_ERROR, 0);
else
ppp_auth_failed(p->ppp, peer_id);
- ret=-1;
+ ret = -1;
_free(peer_id);
} else {
- pap_send_ack(p, hdr->id);
- if (!p->started) {
+ if (ppp_auth_successed(p->ppp, peer_id)) {
+ pap_send_nak(p, hdr->id);
+ ppp_terminate(p->ppp, TERM_AUTH_ERROR, 0);
+ _free(peer_id);
+ ret = -1;
+ } else {
+ pap_send_ack(p, hdr->id);
p->started = 1;
- ppp_auth_successed(p->ppp, peer_id);
+ ret = 0;
}
- ret = 0;
}
_free(passwd);
diff --git a/accel-pppd/ppp/ppp.c b/accel-pppd/ppp/ppp.c
index a044d9a6..5a4006cf 100644
--- a/accel-pppd/ppp/ppp.c
+++ b/accel-pppd/ppp/ppp.c
@@ -25,7 +25,8 @@
#include "memdebug.h"
int __export conf_ppp_verbose;
-static int conf_sid_ucase;
+int conf_sid_ucase;
+int conf_single_session = -1;
pthread_rwlock_t __export ppp_lock = PTHREAD_RWLOCK_INITIALIZER;
__export LIST_HEAD(ppp_list);
@@ -640,6 +641,15 @@ static void load_config(void)
else if (strcmp(opt, "lower"))
log_emerg("ppp: sid-case: invalid format\n");
}
+
+ opt = conf_get_opt("ppp", "single-session");
+ if (opt) {
+ if (!strcmp(opt, "deny"))
+ conf_single_session = 0;
+ else if (!strcmp(opt, "replace"))
+ conf_single_session = 1;
+ } else
+ conf_single_session = -1;
}
static void __init init(void)
diff --git a/accel-pppd/ppp/ppp.h b/accel-pppd/ppp/ppp.h
index 8556b2c2..9d2409ed 100644
--- a/accel-pppd/ppp/ppp.h
+++ b/accel-pppd/ppp/ppp.h
@@ -178,6 +178,7 @@ extern int ppp_shutdown;
void ppp_shutdown_soft(void);
extern int conf_ppp_verbose;
+extern int conf_single_session;
extern pthread_rwlock_t ppp_lock;
extern struct list_head ppp_list;
diff --git a/accel-pppd/ppp/ppp_auth.c b/accel-pppd/ppp/ppp_auth.c
index 32413c6b..e58b9a59 100644
--- a/accel-pppd/ppp/ppp_auth.c
+++ b/accel-pppd/ppp/ppp_auth.c
@@ -299,14 +299,42 @@ static void auth_layer_free(struct ppp_layer_data_t *ld)
_free(ad);
}
-void __export ppp_auth_successed(struct ppp_t *ppp, char *username)
+static void ppp_terminate_sec(struct ppp_t *ppp)
{
+ ppp_terminate(ppp, TERM_NAS_REQUEST, 0);
+}
+
+int __export ppp_auth_successed(struct ppp_t *ppp, char *username)
+{
+ struct ppp_t *p;
struct auth_layer_data_t *ad = container_of(ppp_find_layer_data(ppp, &auth_layer), typeof(*ad), ld);
- log_ppp_debug("auth_layer_started\n");
+
+ pthread_rwlock_rdlock(&ppp_lock);
+ list_for_each_entry(p, &ppp_list, entry) {
+ if (p->username && !strcmp(p->username, username)) {
+ if (conf_single_session == 0) {
+ pthread_rwlock_unlock(&ppp_lock);
+ log_ppp_info1("%s: second session denied\n", username);
+ return -1;
+ } else {
+ if (conf_single_session == 1)
+ triton_context_call(p->ctrl->ctx, (triton_event_func)ppp_terminate_sec, p);
+ break;
+ }
+ }
+ }
+ pthread_rwlock_unlock(&ppp_lock);
+
+ pthread_rwlock_wrlock(&ppp_lock);
ppp->username = username;
+ pthread_rwlock_unlock(&ppp_lock);
+
+ log_ppp_debug("auth_layer_started\n");
ppp_layer_started(ppp, &ad->ld);
log_ppp_info1("%s: authentication successed\n", username);
triton_event_fire(EV_PPP_AUTHORIZED, ppp);
+
+ return 0;
}
void __export ppp_auth_failed(struct ppp_t *ppp, const char *username)
diff --git a/accel-pppd/ppp/ppp_auth.h b/accel-pppd/ppp/ppp_auth.h
index 87cc7420..c84f5f99 100644
--- a/accel-pppd/ppp/ppp_auth.h
+++ b/accel-pppd/ppp/ppp_auth.h
@@ -29,7 +29,7 @@ struct ppp_auth_handler_t
int ppp_auth_register_handler(struct ppp_auth_handler_t*);
-void ppp_auth_successed(struct ppp_t *ppp, char *username);
+int ppp_auth_successed(struct ppp_t *ppp, char *username);
void ppp_auth_failed(struct ppp_t *ppp, const char *username);
int ppp_auth_restart(struct ppp_t *ppp);