summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pptpd/auth_pap.c104
-rw-r--r--accel-pptpd/ppp.c46
-rw-r--r--accel-pptpd/ppp.h14
-rw-r--r--accel-pptpd/ppp_auth.c72
-rw-r--r--accel-pptpd/ppp_auth.h6
-rw-r--r--accel-pptpd/ppp_fsm.h1
-rw-r--r--accel-pptpd/ppp_lcp.c16
7 files changed, 213 insertions, 46 deletions
diff --git a/accel-pptpd/auth_pap.c b/accel-pptpd/auth_pap.c
index 42a70f5..ed0f6bf 100644
--- a/accel-pptpd/auth_pap.c
+++ b/accel-pptpd/auth_pap.c
@@ -1,31 +1,46 @@
#include "log.h"
+#include "ppp.h"
#include "ppp_auth.h"
-static int lcp_get_conf_req(struct auth_driver_t*, struct ppp_layer_t*, struct lcp_opt32_t*);
-static int lcp_recv_conf_req(struct auth_driver_t*, struct ppp_layer_t*, struct lcp_opt32_t*);
-static int lcp_conf_established(struct auth_driver_t*, struct ppp_layer_t*);
+#define MSG_FAILED "Authentication failed"
+#define MSG_SUCCESSED "Authentication successed"
+
+#define HDR_LEN (sizeof(struct pap_hdr_t)-2)
+
+static int lcp_get_conf_req(struct auth_driver_t*, struct ppp_t*, struct lcp_opt32_t*);
+static int lcp_recv_conf_req(struct auth_driver_t*, struct ppp_t*, struct lcp_opt32_t*);
+static int begin(struct auth_driver_t*, struct ppp_t*);
+static int terminate(struct auth_driver_t*, struct ppp_t*);
static void pap_recv(struct ppp_handler_t*h);
struct pap_proto_t
{
struct ppp_handler_t h;
struct ppp_t *ppp;
- struct ppp_layer_t *lcp;
};
struct pap_hdr_t
{
+ uint16_t proto;
uint8_t code;
uint8_t id;
uint16_t len;
} __attribute__((packed));
+struct pap_ack_t
+{
+ struct pap_hdr_t hdr;
+ uint8_t msg_len;
+ char msg[0];
+} __attribute__((packed));
+
static struct auth_driver_t pap=
{
.type=PPP_PAP,
.get_conf_req=lcp_get_conf_req,
.recv_conf_req=lcp_recv_conf_req,
- .established=lcp_established,
+ .start=pap_start,
+ .finish=pap_finish,
};
@@ -40,30 +55,67 @@ int plugin_init(void)
return 0;
}
-static int lcp_established(struct auth_driver_t*d, struct ppp_layer_t*lcp)
+static int pap_start(struct auth_driver_t *d, struct ppp_t *ppp)
{
- struct pap_proto_t *p=malloc(sizeof(*l));
+ struct pap_proto_t *p=malloc(sizeof(*p));
- memset(&p,0,sizeof(*l));
+ memset(&p,0,sizeof(*p));
p->h.proto=PPP_PAP;
p->h.recv=pap_recv;
- p->ppp=lcp->ppp;
- p->lcp=lcp;
+ p->ppp=ppp;
+ ppp->auth_pd=p;
ppp_register_handler(p->ppp,p->h);
+
+ return 0;
}
+static int pap_finish(struct auth_driver_t *d, struct ppp_t *ppp)
+{
+ struct pap_proto_t *p=(struct pap_proto_t*)ppp->auth_pd;
+
+ ppp_unregister_handler(p->ppp,p->h);
-static int lcp_get_conf_req(struct auth_driver_t*, struct ppp_layer_t*, struct lcp_opt32_t*)
+ free(p);
+
+ return 0;
+}
+
+static int lcp_get_conf_req(struct auth_driver_t *d, struct ppp_t *ppp, struct lcp_opt32_t *opt)
{
+ return 0;
}
-static int lcp_recv_conf_req(struct auth_driver_t*, struct ppp_layer_t*, struct lcp_opt32_t*)
+static int lcp_recv_conf_req(struct auth_driver_t *d, struct ppp_t *ppp, struct lcp_opt32_t *opt)
{
+ return 0;
}
-static void pap_send_nack(struct pap_proto_t *p,struct pap_hdr_t *hdr)
+static void pap_send_ack(struct pap_proto_t *p, int id)
{
+ uint8_t buf[128];
+ struct pap_ack_t *msg=(struct pap_ack_t*)buf;
+ msg->hdr.proto=PPP_PAP;
+ msg->hdr.code=PAP_ACK;
+ msg->hdr.id=id;
+ msg->hdr.len=HDR_LEN+1+sizeof(MSG_SUCCESSED);
+ msg->len=sizeof(MSG_SUCCESSED);
+ memcpy(msg->msg,MSG_SUCCESSED,sizeof(MSG_SUCCESSED));
+
+ ppp_send(p->ppp,msg,msg->hdr.len+2);
+}
+static void pap_send_nack(struct pap_proto_t *p,int id)
+{
+ uint8_t buf[128];
+ struct pap_ack_t *msg=(struct pap_ack_t*)buf;
+ msg->hdr.proto=PPP_PAP;
+ msg->hdr.code=PAP_NACK;
+ msg->hdr.id=id;
+ msg->hdr.len=HDR_LEN+1+sizeof(MSG_FAILED);
+ msg->len=sizeof(MSG_FAILED);
+ memcpy(msg->msg,MSG_FAILED,sizeof(MSG_FAILED));
+
+ ppp_send(p->ppp,msg,msg->hdr.len+2);
}
static int pap_recv_req(struct pap_proto_t *p,struct pap_hdr_t *hdr)
@@ -96,30 +148,28 @@ static int pap_recv_req(struct pap_proto_t *p,struct pap_hdr_t *hdr)
if (pwdb_check(peer_id,passwd))
{
log_warn("PAP: authentication error\n");
- pap_send_nack(p,hdr);
+ pap_send_nack(p,hdr->id);
+ auth_failed(p->ppp);
ret=-1;
- }else ret=0;
+ }else
+ {
+ pap_send_ack(p,hdr->id);
+ auth_successed(p->ppp);
+ ret=0;
+ }
free(peer_id);
free(passwd);
- pap_send_ack(p,hdr);
- return 0;
+ return ret;
}
-static void pap_recv(struct ppp_handler_t*h)
+static void pap_recv(struct ppp_handler_t *h)
{
struct pap_proto_t *p=container_of(h,typeof(*p),h);
- struct pap_hdr_t *hdr;
-
- if (p->ppp->in_buf_size<sizeof(*hdr)+2 || htons(hdr->len)<sizeof(*hdr) || htons(hdr->len)<p->ppp->in_buf_size-2)
- {
- log_warn("PAP: short packet received\n");
- return;
- }
+ struct pap_hdr_t *hdr=(struct pap_hdr_t *)p->ppp->in_buf;
- hdr=(struct pap_hdr_t *)p->ppp->in_buf;
- if (ntohs(hdr->len)<sizeof(*hdr) ||)
+ if (p->ppp->in_buf_size<sizeof(*hdr) || htons(hdr->len)<HDR_LEN || htons(hdr->len)<p->ppp->in_buf_size-2)
{
log_warn("PAP: short packet received\n");
return;
diff --git a/accel-pptpd/ppp.c b/accel-pptpd/ppp.c
index 2c9c47d..f8a1be5 100644
--- a/accel-pptpd/ppp.c
+++ b/accel-pptpd/ppp.c
@@ -89,9 +89,11 @@ int establish_ppp(struct ppp_t *ppp)
INIT_LIST_HEAD(&ppp->layers);
ppp->lcp_layer=ppp_lcp_init(ppp);
- list_add_tail(&ppp->lcp_layer->entry,&ppp->layers);
+ /*list_add_tail(&ppp->lcp_layer->entry,&ppp->layers);
ppp_fsm_open(ppp->lcp_layer);
- ppp_fsm_lower_up(ppp->lcp_layer);
+ ppp_fsm_lower_up(ppp->lcp_layer);*/
+ ppp->cur_layer=PPP_LAYER_LCP;
+ lcp_start(ppp);
return 0;
@@ -162,3 +164,43 @@ static void ppp_timeout(struct triton_md_handler_t*h)
}
+void ppp_layer_started(struct ppp_t *ppp)
+{
+ int i;
+ switch(ppp->cur_layer)
+ {
+ case PPP_LAYER_LCP:
+ ppp->cur_layer++;
+ if (auth_start(ppp))
+ break;
+ case PPP_LAYER_AUTH:
+ ppp->cur_layer++;
+ if (ccp_start(ppp))
+ break;
+ case PPP_LAYER_CCP:
+ ppp->cur_layer++;
+ if (ipcp_start(ppp))
+ break;
+ case PPP_LAYER_IPCP:
+ break;
+ }
+}
+void ppp_terminate(struct ppp_t *ppp)
+{
+ switch(ppp->cur_layer)
+ {
+ case PPP_LAYER_IPCP:
+ ppp->cur_layer--;
+ ipcp_finish(ppp);
+ case PPP_LAYER_CCP:
+ ppp->cur_layer--;
+ ccp_finish(ppp);
+ case PPP_LAYER_AUTH:
+ ppp->cur_layer--;
+ auth_finish(ppp);
+ case PPP_LAYER_LCP:
+ ppp->cur_layer--;
+ lcp_finish(ppp);
+ }
+}
+
diff --git a/accel-pptpd/ppp.h b/accel-pptpd/ppp.h
index a48f00d..4a4c70e 100644
--- a/accel-pptpd/ppp.h
+++ b/accel-pptpd/ppp.h
@@ -41,6 +41,11 @@
#define PPP_CBCP 0xc029 /* Callback Control Protocol */
#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */
+#define PPP_LAYER_LCP 1
+#define PPP_LAYER_AUTH 2
+#define PPP_LAYER_CCP 3
+#define PPP_LAYER_IPCP 4
+
struct ppp_t
{
struct triton_md_handler_t *h;
@@ -57,6 +62,7 @@ struct ppp_t
int mtu,mru;
int accomp; // 0 - disabled, 1 - enable, 2 - allow, disabled, 3 - allow,enabled
int pcomp; // 0 - disabled, 1 - enable, 2 - allow, disabled, 3 - allow,enabled
+ int auth[AUTH_MAX];
//
int log:1;
@@ -68,8 +74,11 @@ struct ppp_t
void *in_buf;
int in_buf_size;
+ struct list_head handlers;
+
+ int cur_layer;
struct ppp_layer_t *lcp_layer;
- struct list_head layers;
+ void *auth_pd;
};
struct ppp_handler_t
@@ -86,7 +95,8 @@ int ppp_send(struct ppp_t *ppp, void *data, int size);
void ppp_init(void);
struct ppp_layer_t* ppp_lcp_init(struct ppp_t *ppp);
-
+void ppp_layer_started(struct ppp_t *ppp);
+void ppp_terminate(struct ppp_t *ppp);
#undef offsetof
#ifdef __compiler_offsetof
diff --git a/accel-pptpd/ppp_auth.c b/accel-pptpd/ppp_auth.c
index b66727b..1117c21 100644
--- a/accel-pptpd/ppp_auth.c
+++ b/accel-pptpd/ppp_auth.c
@@ -27,12 +27,12 @@ int auth_get_conf_req(struct ppp_layer_t *l, struct lcp_opt32_t *opt)
for(i=0; i<AUTH_MAX; i++)
{
- if (l->auth[i] && l->options.lcp.neg_auth[i]>0)
+ if (l->ppp->auth[i] && l->options.lcp.neg_auth[i]>0)
goto cont;
}
for(i=0; i<AUTH_MAX; i++)
{
- if (l->auth[i] && l->options.lcp.neg_auth[i]==0)
+ if (l->ppp->auth[i] && l->options.lcp.neg_auth[i]==0)
goto cont;
}
return -1;
@@ -40,7 +40,7 @@ int auth_get_conf_req(struct ppp_layer_t *l, struct lcp_opt32_t *opt)
cont:
list_for_each_entry(drv,&drv_list,entry)
{
- if (drv->type==l->auth[i])
+ if (drv->type==l->ppp->auth[i])
break;
}
n=drv->get_conf_req(drv,l,opt);
@@ -56,13 +56,13 @@ int auth_recv_conf_req(struct ppp_layer_t *l, struct lcp_opt_hdr_t *hdr)
for(i=0; i<AUTH_MAX; i++)
{
- if (l->auth[i]==opt->val)
+ if (l->ppp->auth[i]==opt->val)
{
list_for_each_entry(drv,&drv_list,entry)
{
- if (drv->type==l->auth[i])
+ if (drv->type==l->ppp->auth[i])
{
- if (drv->recv_conf_req(drv,l,opt))
+ if (drv->recv_conf_req(drv,l->ppp,opt))
return -1;
l->options.lcp.neg_auth[i]=1;
return 0;
@@ -80,15 +80,15 @@ int auth_recv_conf_rej(struct ppp_layer_t *l, struct lcp_opt_hdr_t *hdr)
for(i=0; i<AUTH_MAX; i++)
{
- if (l->auth[i]==opt->val)
+ if (l->ppp->auth[i]==opt->val)
{
l->options.lcp.neg_auth[i]=-1;
break;
}
}
- for(i=0; i<3; i++)
+ for(i=0; i<AUTH_MAX; i++)
{
- if (l->auth[i] && l->options.lcp.neg_auth[i]!=-1)
+ if (l->ppp->auth[i] && l->options.lcp.neg_auth[i]!=-1)
return 0;
}
return -1;
@@ -100,7 +100,7 @@ int auth_recv_conf_nak(struct ppp_layer_t *l, struct lcp_opt_hdr_t *hdr)
for(i=0; i<AUTH_MAX; i++)
{
- if (l->auth[i]==opt->val)
+ if (l->ppp->auth[i]==opt->val)
{
l->options.lcp.neg_auth[i]=2;
return 0;
@@ -109,3 +109,55 @@ int auth_recv_conf_nak(struct ppp_layer_t *l, struct lcp_opt_hdr_t *hdr)
return -1;
}
+int auth_start(struct ppp_t *ppp)
+{
+ int i;
+ struct auth_driver_t *drv;
+
+ for(i=0; i<AUTH_MAX; i++)
+ {
+ if (ppp->lcp_layer->options.lcp.neg_auth[i]==1)
+ {
+ list_for_each_entry(drv,&drv_list,entry)
+ {
+ if (drv->type==ppp->auth[i])
+ return drv->start(ppp);
+ }
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+void auth_finish(struct ppp_t *ppp)
+{
+ int i;
+ struct auth_driver_t *drv;
+
+ for(i=0; i<AUTH_MAX; i++)
+ {
+ if (ppp->lcp_layer->options.lcp.neg_auth[i]==1)
+ {
+ list_for_each_entry(drv,&drv_list,entry)
+ {
+ if (drv->type==ppp->auth[i])
+ {
+ drv->finish(ppp);
+ return;
+ }
+ }
+ }
+ }
+}
+
+void auth_successed(struct ppp_t *ppp)
+{
+ ppp_layer_started(ppp);
+}
+
+void auth_failed(struct ppp_t *ppp)
+{
+ ppp_terminate(ppp);
+}
+
diff --git a/accel-pptpd/ppp_auth.h b/accel-pptpd/ppp_auth.h
index 79ceb64..064bf24 100644
--- a/accel-pptpd/ppp_auth.h
+++ b/accel-pptpd/ppp_auth.h
@@ -11,8 +11,10 @@ struct auth_driver_t
{
struct list_head entry;
int type;
- int (*get_conf_req)(struct auth_driver_t*, struct ppp_layer_t*, struct lcp_opt32_t*);
- int (*recv_conf_req)(struct auth_driver_t*, struct ppp_layer_t*, struct lcp_opt32_t*);
+ int (*get_conf_req)(struct auth_driver_t*, struct ppp_t*, struct lcp_opt32_t*);
+ int (*recv_conf_req)(struct auth_driver_t*, struct ppp_t*, struct lcp_opt32_t*);
+ int (*begin)(struct auth_driver_t*, struct ppp_t*);
+ int (*terminate)(struct auth_driver_t*, struct ppp_t*);
};
int auth_get_conf_req(struct ppp_layer_t *l, struct lcp_opt32_t *);
diff --git a/accel-pptpd/ppp_fsm.h b/accel-pptpd/ppp_fsm.h
index 3e1eded..3ed6284 100644
--- a/accel-pptpd/ppp_fsm.h
+++ b/accel-pptpd/ppp_fsm.h
@@ -55,7 +55,6 @@ struct ppp_layer_t
int id;
int recv_id;
- int auth[AUTH_MAX];
int opt_restart:1;
int opt_passive:1;
diff --git a/accel-pptpd/ppp_lcp.c b/accel-pptpd/ppp_lcp.c
index 50ad444..2d1dee0 100644
--- a/accel-pptpd/ppp_lcp.c
+++ b/accel-pptpd/ppp_lcp.c
@@ -20,13 +20,15 @@ char* auth="pap,eap,mschap-v2";
char* mppe="allow,disabled";
char* pwdb="radius";
+static void lcp_layer_up(struct ppp_layer_t*);
+static void lcp_layer_down(struct ppp_layer_t*);
static void send_conf_req(struct ppp_layer_t*);
static void send_conf_ack(struct ppp_layer_t*);
static void send_conf_nak(struct ppp_layer_t*);
static void send_conf_rej(struct ppp_layer_t*);
static void lcp_recv(struct ppp_layer_t*);
-struct ppp_layer_t* ppp_lcp_init(struct ppp_t *ppp)
+void lcp_start(struct ppp_t *ppp)
{
struct ppp_layer_t *layer=malloc(sizeof(*layer));
memset(layer,0,sizeof(*layer));
@@ -37,16 +39,26 @@ struct ppp_layer_t* ppp_lcp_init(struct ppp_t *ppp)
layer->ppp=ppp;
ppp_fsm_init(layer);
+ layer->layer_started=lcp_layer_started;
layer->send_conf_req=send_conf_req;
layer->send_conf_ack=send_conf_ack;
layer->send_conf_nak=send_conf_nak;
layer->send_conf_rej=send_conf_rej;
ppp_fsm_init(layer);
+ ppp_fsm_lower_up(layer);
+ ppp_fsm_open(layer);
ppp_register_handler(&layer->h);
+}
- return layer;
+static void lcp_layer_up(struct ppp_layer_t *l)
+{
+ ppp_layer_started(l->ppp);
+}
+static void lcp_layer_down(struct ppp_layer_t *l)
+{
+ ppp_terminate(l->ppp);
}
static void send_conf_req(struct ppp_layer_t*l)