diff options
Diffstat (limited to 'accel-pptpd/auth_pap.c')
-rw-r--r-- | accel-pptpd/auth_pap.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/accel-pptpd/auth_pap.c b/accel-pptpd/auth_pap.c new file mode 100644 index 00000000..42a70f50 --- /dev/null +++ b/accel-pptpd/auth_pap.c @@ -0,0 +1,134 @@ +#include "log.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*); +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 +{ + uint8_t code; + uint8_t id; + uint16_t len; +} __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, +}; + + +int plugin_init(void) +{ + if (auth_register(&pap)) + { + log_error("pap: failed to register driver\n"); + return -1; + } + + return 0; +} + +static int lcp_established(struct auth_driver_t*d, struct ppp_layer_t*lcp) +{ + struct pap_proto_t *p=malloc(sizeof(*l)); + + memset(&p,0,sizeof(*l)); + p->h.proto=PPP_PAP; + p->h.recv=pap_recv; + p->ppp=lcp->ppp; + p->lcp=lcp; + + ppp_register_handler(p->ppp,p->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 void pap_send_nack(struct pap_proto_t *p,struct pap_hdr_t *hdr) +{ + +} + +static int pap_recv_req(struct pap_proto_t *p,struct pap_hdr_t *hdr) +{ + int ret; + char *peer_id; + char *passwd; + int peer_id_len; + int passwd_len; + uint8_t *ptr=(uint8_t*)(hdr+1); + + peer_id_len=*(uint8_t*)ptr; ptr++; + if (peer_id_len>htons(hdr->len)-sizeof(*hdr)-1) + { + log_warn("PAP: short packet received\n"); + return -1; + } + peer_id=ptr; ptr+=peer_id_len; + + passwd_len=*(uint8_t*)ptr; ptr++; + if (passwd_len>htons(hdr->len)-sizeof(*hdr)-2-peer_id_len) + { + log_warn("PAP: short packet received\n"); + return -1; + } + + peer_id=stdndup(peer_id,peer_id_len); + passwd=stdndup(ptr,passwd_len); + + if (pwdb_check(peer_id,passwd)) + { + log_warn("PAP: authentication error\n"); + pap_send_nack(p,hdr); + ret=-1; + }else ret=0; + + free(peer_id); + free(passwd); + + pap_send_ack(p,hdr); + return 0; +} + +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; + } + + hdr=(struct pap_hdr_t *)p->ppp->in_buf; + if (ntohs(hdr->len)<sizeof(*hdr) ||) + { + log_warn("PAP: short packet received\n"); + return; + } + + if (hdr->code==PAP_REQ) pap_recv_req(p,hdr); + else + { + log_warn("PAP: unknown code received %x\n",hdr->code); + } +} + |