summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-10-29 14:59:22 +0400
committerKozlov Dmitry <dima@server>2010-10-29 14:59:22 +0400
commit01da9860b5637448208cbe8f88bf7a9a290a4f3f (patch)
treef2e132fcf4365611d7a1ad84172e99c86de8d5c6
parent4e1a10190d4afba6a960666fa540a8983023b595 (diff)
downloadaccel-ppp-01da9860b5637448208cbe8f88bf7a9a290a4f3f.tar.gz
accel-ppp-01da9860b5637448208cbe8f88bf7a9a290a4f3f.zip
ppp: improved mppe handling
radius: bind parameter to bind to ip other then nas-ip-address
-rw-r--r--accel-pptpd/ppp/ccp_mppe.c42
-rw-r--r--accel-pptpd/radius/radius.c7
-rw-r--r--accel-pptpd/radius/radius_p.h1
-rw-r--r--accel-pptpd/radius/req.c4
4 files changed, 51 insertions, 3 deletions
diff --git a/accel-pptpd/ppp/ccp_mppe.c b/accel-pptpd/ppp/ccp_mppe.c
index 2302c027..9235d851 100644
--- a/accel-pptpd/ppp/ccp_mppe.c
+++ b/accel-pptpd/ppp/ccp_mppe.c
@@ -25,6 +25,8 @@ static struct ccp_option_t *mppe_init(struct ppp_ccp_t *ccp);
static void mppe_free(struct ppp_ccp_t *ccp, struct ccp_option_t *opt);
static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr);
static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr);
+static int mppe_recv_conf_nak(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr);
+static int mppe_recv_conf_rej(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr);
static void mppe_print(void (*print)(const char *fmt,...),struct ccp_option_t*, uint8_t *ptr);
struct mppe_option_t
@@ -41,6 +43,8 @@ static struct ccp_option_handler_t mppe_opt_hnd = {
.send_conf_req = mppe_send_conf_req,
.send_conf_nak = mppe_send_conf_req,
.recv_conf_req = mppe_recv_conf_req,
+ .recv_conf_nak = mppe_recv_conf_nak,
+ .recv_conf_rej = mppe_recv_conf_rej,
.free = mppe_free,
.print = mppe_print,
};
@@ -114,7 +118,7 @@ static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u
struct mppe_option_t *mppe_opt = container_of(opt,typeof(*mppe_opt),opt);
struct ccp_opt32_t *opt32 = (struct ccp_opt32_t*)ptr;
- if (mppe_opt->policy == 2 || mppe_opt->mppe != -1) {
+ if (mppe_opt->mppe != -1) {
opt32->hdr.id = CI_MPPE;
opt32->hdr.len = 6;
opt32->val = mppe_opt->mppe ? htonl(MPPE_S | MPPE_H) : 0;
@@ -170,6 +174,42 @@ static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u
return CCP_OPT_ACK;
}
+static int mppe_recv_conf_rej(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr)
+{
+ struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt);
+
+ if (mppe_opt->mppe != 2) {
+ mppe_opt->mppe = -1;
+ return 0;
+ }
+
+ return -1;
+}
+
+static int mppe_recv_conf_nak(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr)
+{
+ struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt);
+ struct ccp_opt32_t *opt32 = (struct ccp_opt32_t *)ptr;
+
+ if (opt32->hdr.len != 6)
+ return -1;
+
+ if (mppe_opt->policy == 2) {
+ if (ntohl(opt32->val) == (MPPE_S | MPPE_H))
+ return -1;
+ } else if (mppe_opt->policy == 1) {
+ if (ntohl(opt32->val) & (MPPE_S | MPPE_H) == (MPPE_S | MPPE_H))
+ mppe_opt->mppe = 0;
+ else
+ mppe_opt->mppe = 1;
+ } else {
+ if (opt32->val == 0)
+ return -1;
+ }
+
+ return 0;
+}
+
static void mppe_print(void (*print)(const char *fmt,...),struct ccp_option_t *opt, uint8_t *ptr)
{
struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt);
diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c
index a07df9a6..e6a13e90 100644
--- a/accel-pptpd/radius/radius.c
+++ b/accel-pptpd/radius/radius.c
@@ -27,6 +27,7 @@ int conf_timeout = 3;
char *conf_nas_identifier = "accel-pptpd";
char *conf_nas_ip_address;
char *conf_gw_ip_address;
+in_addr_t conf_bind = 0;
int conf_verbose = 0;
char *conf_auth_server;
@@ -378,6 +379,12 @@ static void __init radius_init(void)
if (opt)
conf_gw_ip_address = opt;
+ opt = conf_get_opt("radius", "bind");
+ if (opt)
+ conf_bind = inet_addr(opt);
+ else if (conf_nas_ip_address)
+ conf_bind = inet_addr(conf_nas_ip_address);
+
opt = conf_get_opt("radius", "auth_server");
if (!opt) {
log_emerg("radius: auth_server not specified\n");
diff --git a/accel-pptpd/radius/radius_p.h b/accel-pptpd/radius/radius_p.h
index a24d6877..efcd9b82 100644
--- a/accel-pptpd/radius/radius_p.h
+++ b/accel-pptpd/radius/radius_p.h
@@ -59,6 +59,7 @@ extern int conf_timeout;
extern int conf_verbose;
extern char *conf_nas_identifier;
extern char *conf_nas_ip_address;
+extern in_addr_t conf_bind;
extern char *conf_gw_ip_address;
extern char *conf_auth_server;
extern char *conf_auth_secret;
diff --git a/accel-pptpd/radius/req.c b/accel-pptpd/radius/req.c
index f92d1224..7526a920 100644
--- a/accel-pptpd/radius/req.c
+++ b/accel-pptpd/radius/req.c
@@ -140,8 +140,8 @@ static int make_socket(struct rad_req_t *req)
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
- if (conf_nas_ip_address) {
- addr.sin_addr.s_addr = inet_addr(conf_nas_ip_address);
+ if (conf_bind) {
+ addr.sin_addr.s_addr = conf_bind;
if (bind(req->hnd.fd, (struct sockaddr *) &addr, sizeof(addr))) {
log_ppp_error("radius:bind: %s\n", strerror(errno));
goto out_err;