diff options
author | Kozlov Dmitry <dima@server> | 2010-09-03 18:58:53 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-09-03 18:58:53 +0400 |
commit | e8aa3a1457295f70f8ccc9cd7f2f9073f01a5e2e (patch) | |
tree | 17a99610798630e83fc1032c82ee51c404ce19fe /accel-pptpd/auth/auth_pap.c | |
parent | a22573e91dac7971aa4c9b1d874d6751e8502d16 (diff) | |
download | accel-ppp-e8aa3a1457295f70f8ccc9cd7f2f9073f01a5e2e.tar.gz accel-ppp-e8aa3a1457295f70f8ccc9cd7f2f9073f01a5e2e.zip |
project restructured
Diffstat (limited to 'accel-pptpd/auth/auth_pap.c')
-rw-r--r-- | accel-pptpd/auth/auth_pap.c | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/accel-pptpd/auth/auth_pap.c b/accel-pptpd/auth/auth_pap.c new file mode 100644 index 00000000..92ddef52 --- /dev/null +++ b/accel-pptpd/auth/auth_pap.c @@ -0,0 +1,214 @@ +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <arpa/inet.h> + +#include "log.h" +#include "ppp.h" +#include "ppp_auth.h" +#include "ppp_lcp.h" +#include "pwdb.h" + +#define MSG_FAILED "Authentication failed" +#define MSG_SUCCESSED "Authentication successed" + +#define HDR_LEN (sizeof(struct pap_hdr_t)-2) + +#define PAP_REQ 1 +#define PAP_ACK 2 +#define PAP_NAK 3 + +char *strndup(const char *s, size_t n); + +static struct auth_data_t* auth_data_init(struct ppp_t *ppp); +static void auth_data_free(struct ppp_t*, struct auth_data_t*); +static int lcp_send_conf_req(struct ppp_t*, struct auth_data_t*, uint8_t*); +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); + +struct pap_auth_data_t +{ + struct auth_data_t auth; + struct ppp_handler_t h; + struct ppp_t *ppp; +}; + +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 ppp_auth_handler_t pap= +{ + .name="PAP", + .init=auth_data_init, + .free=auth_data_free, + .send_conf_req=lcp_send_conf_req, + .recv_conf_req=lcp_recv_conf_req, + .start=pap_start, + .finish=pap_finish, +}; + +static struct auth_data_t* auth_data_init(struct ppp_t *ppp) +{ + struct pap_auth_data_t *d=malloc(sizeof(*d)); + + memset(d,0,sizeof(*d)); + d->auth.proto=PPP_PAP; + d->ppp=ppp; + + return &d->auth; +} + +static void auth_data_free(struct ppp_t *ppp,struct auth_data_t *auth) +{ + struct pap_auth_data_t *d=container_of(auth,typeof(*d),auth); + + free(d); +} + +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; + + ppp_register_chan_handler(ppp,&d->h); + + return 0; +} +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); + + ppp_unregister_handler(ppp,&d->h); + + return 0; +} + +static int lcp_send_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *ptr) +{ + return 0; +} + +static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *ptr) +{ + return LCP_OPT_ACK; +} + +static void pap_send_ack(struct pap_auth_data_t *p, int id) +{ + uint8_t buf[128]; + struct pap_ack_t *msg=(struct pap_ack_t*)buf; + msg->hdr.proto=htons(PPP_PAP); + msg->hdr.code=PAP_ACK; + msg->hdr.id=id; + msg->hdr.len=htons(HDR_LEN+1+sizeof(MSG_SUCCESSED)-1); + msg->msg_len=sizeof(MSG_SUCCESSED)-1; + memcpy(msg->msg,MSG_SUCCESSED,sizeof(MSG_SUCCESSED)); + + log_debug("send [PAP AuthAck id=%x \"%s\"]\n",id,MSG_SUCCESSED); + + ppp_chan_send(p->ppp,msg,ntohs(msg->hdr.len)+2); +} + +static void pap_send_nak(struct pap_auth_data_t *p,int id) +{ + uint8_t buf[128]; + struct pap_ack_t *msg=(struct pap_ack_t*)buf; + msg->hdr.proto=htons(PPP_PAP); + msg->hdr.code=PAP_NAK; + msg->hdr.id=id; + msg->hdr.len=htons(HDR_LEN+1+sizeof(MSG_FAILED)-1); + msg->msg_len=sizeof(MSG_FAILED)-1; + memcpy(msg->msg,MSG_FAILED,sizeof(MSG_FAILED)); + + log_debug("send [PAP AuthNak id=%x \"%s\"]\n",id,MSG_FAILED); + + ppp_chan_send(p->ppp,msg,ntohs(msg->hdr.len)+2); +} + +static int pap_recv_req(struct pap_auth_data_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); + + log_debug("recv [PAP AuthReq id=%x]\n",hdr->id); + + peer_id_len=*(uint8_t*)ptr; ptr++; + if (peer_id_len>ntohs(hdr->len)-sizeof(*hdr)+2-1) + { + log_warn("PAP: short packet received\n"); + return -1; + } + peer_id=(char*)ptr; ptr+=peer_id_len; + + passwd_len=*(uint8_t*)ptr; ptr++; + if (passwd_len>ntohs(hdr->len)-sizeof(*hdr)+2-2-peer_id_len) + { + log_warn("PAP: short packet received\n"); + return -1; + } + + peer_id=strndup((const char*)peer_id,peer_id_len); + passwd=strndup((const char*)ptr,passwd_len); + + if (pwdb_check(p->ppp,peer_id,passwd)) + { + log_warn("PAP: authentication error\n"); + pap_send_nak(p,hdr->id); + auth_failed(p->ppp); + ret=-1; + }else + { + pap_send_ack(p,hdr->id); + auth_successed(p->ppp); + ret=0; + } + + free(peer_id); + free(passwd); + + return ret; +} + +static void pap_recv(struct ppp_handler_t *h) +{ + struct pap_auth_data_t *d=container_of(h,typeof(*d),h); + struct pap_hdr_t *hdr=(struct pap_hdr_t *)d->ppp->chan_buf; + + if (d->ppp->chan_buf_size<sizeof(*hdr) || ntohs(hdr->len)<HDR_LEN || ntohs(hdr->len)<d->ppp->chan_buf_size-2) + { + log_warn("PAP: short packet received\n"); + return; + } + + if (hdr->code==PAP_REQ) pap_recv_req(d,hdr); + else + { + log_warn("PAP: unknown code received %x\n",hdr->code); + } +} + +static void __init auth_pap_init() +{ + ppp_auth_register_handler(&pap); +} + |