diff options
Diffstat (limited to 'accel-pppd/auth/auth_chap_md5.c')
-rw-r--r-- | accel-pppd/auth/auth_chap_md5.c | 101 |
1 files changed, 73 insertions, 28 deletions
diff --git a/accel-pppd/auth/auth_chap_md5.c b/accel-pppd/auth/auth_chap_md5.c index 9a52581c..5be8b875 100644 --- a/accel-pppd/auth/auth_chap_md5.c +++ b/accel-pppd/auth/auth_chap_md5.c @@ -30,39 +30,39 @@ #define MSG_FAILURE "Authentication failed" #define MSG_SUCCESS "Authentication succeeded" -#define HDR_LEN (sizeof(struct chap_hdr_t)-2) +#define HDR_LEN (sizeof(struct chap_hdr)-2) static int conf_timeout = 5; static int conf_interval = 0; static int conf_max_failure = 3; static int conf_any_login = 0; -struct chap_hdr_t { +struct chap_hdr { uint16_t proto; uint8_t code; uint8_t id; uint16_t len; } __attribute__((packed)); -struct chap_challenge_t { - struct chap_hdr_t hdr; +struct chap_challenge { + struct chap_hdr hdr; uint8_t val_size; uint8_t val[VALUE_SIZE]; char name[0]; } __attribute__((packed)); -struct chap_failure_t { - struct chap_hdr_t hdr; +struct chap_failure { + struct chap_hdr hdr; char message[sizeof(MSG_FAILURE)]; } __attribute__((packed)); -struct chap_success_t { - struct chap_hdr_t hdr; +struct chap_success { + struct chap_hdr hdr; char message[sizeof(MSG_SUCCESS)]; } __attribute__((packed)); -struct chap_auth_data_t { +struct chap_auth_data { struct auth_data_t auth; struct ppp_handler_t h; struct ppp_t *ppp; @@ -71,10 +71,12 @@ struct chap_auth_data_t { struct triton_timer_t timeout; struct triton_timer_t interval; int failure; + char *name; + char *mschap_error; int started:1; }; -static void chap_send_challenge(struct chap_auth_data_t *ad, int new); +static void chap_send_challenge(struct chap_auth_data *ad, int new); static void chap_recv(struct ppp_handler_t *h); static void chap_timeout_timer(struct triton_timer_t *t); static void chap_restart_timer(struct triton_timer_t *t); @@ -94,7 +96,7 @@ static void print_str(const char *buf, int size) static struct auth_data_t* auth_data_init(struct ppp_t *ppp) { - struct chap_auth_data_t *d = _malloc(sizeof(*d)); + struct chap_auth_data *d = _malloc(sizeof(*d)); memset(d, 0, sizeof(*d)); d->auth.proto = PPP_CHAP; @@ -105,7 +107,7 @@ static struct auth_data_t* auth_data_init(struct ppp_t *ppp) static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth) { - struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth); + struct chap_auth_data *d = container_of(auth, typeof(*d), auth); if (d->timeout.tpd) triton_timer_del(&d->timeout); @@ -118,7 +120,7 @@ static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth) static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth) { - struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth); + struct chap_auth_data *d = container_of(auth, typeof(*d), auth); d->h.proto = PPP_CHAP; d->h.recv = chap_recv; @@ -127,6 +129,7 @@ static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth) d->interval.expire = chap_restart_timer; d->interval.period = conf_interval * 1000; d->id = 1; + d->name = NULL; ppp_register_chan_handler(ppp, &d->h); @@ -137,13 +140,16 @@ static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth) static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth) { - struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth); + struct chap_auth_data *d = container_of(auth, typeof(*d), auth); if (d->timeout.tpd) triton_timer_del(&d->timeout); if (d->interval.tpd) triton_timer_del(&d->interval); + + if (d->name) + _free(d->name); ppp_unregister_handler(ppp, &d->h); @@ -152,7 +158,7 @@ static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth) static void chap_timeout_timer(struct triton_timer_t *t) { - struct chap_auth_data_t *d = container_of(t, typeof(*d), timeout); + struct chap_auth_data *d = container_of(t, typeof(*d), timeout); if (conf_ppp_verbose) log_ppp_warn("chap-md5: timeout\n"); @@ -168,7 +174,7 @@ static void chap_timeout_timer(struct triton_timer_t *t) static void chap_restart_timer(struct triton_timer_t *t) { - struct chap_auth_data_t *d = container_of(t, typeof(*d), interval); + struct chap_auth_data *d = container_of(t, typeof(*d), interval); chap_send_challenge(d, 1); } @@ -186,9 +192,9 @@ static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t * return LCP_OPT_NAK; } -static void chap_send_failure(struct chap_auth_data_t *ad) +static void chap_send_failure(struct chap_auth_data *ad) { - struct chap_failure_t msg = { + struct chap_failure msg = { .hdr.proto = htons(PPP_CHAP), .hdr.code = CHAP_FAILURE, .hdr.id = ad->id, @@ -202,9 +208,9 @@ static void chap_send_failure(struct chap_auth_data_t *ad) ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2); } -static void chap_send_success(struct chap_auth_data_t *ad, int id) +static void chap_send_success(struct chap_auth_data *ad, int id) { - struct chap_success_t msg = { + struct chap_success msg = { .hdr.proto = htons(PPP_CHAP), .hdr.code = CHAP_SUCCESS, .hdr.id = id, @@ -218,9 +224,9 @@ static void chap_send_success(struct chap_auth_data_t *ad, int id) ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2); } -static void chap_send_challenge(struct chap_auth_data_t *ad, int new) +static void chap_send_challenge(struct chap_auth_data *ad, int new) { - struct chap_challenge_t msg = { + struct chap_challenge msg = { .hdr.proto = htons(PPP_CHAP), .hdr.code = CHAP_CHALLENGE, .hdr.id = ad->id, @@ -245,14 +251,45 @@ static void chap_send_challenge(struct chap_auth_data_t *ad, int new) triton_timer_add(ad->ppp->ses.ctrl->ctx, &ad->timeout, 0); } -static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *hdr) +static void auth_result(struct chap_auth_data *ad, int res) +{ + char *name = ad->name; + + ad->name = NULL; + + if (res == PWDB_DENIED) { + chap_send_failure(ad); + if (ad->started) + ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0); + else + ppp_auth_failed(ad->ppp, name); + } else { + if (ppp_auth_succeeded(ad->ppp, name)) { + chap_send_failure(ad); + ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0); + } else { + chap_send_success(ad, ad->id); + ad->started = 1; + if (conf_interval) + triton_timer_add(ad->ppp->ses.ctrl->ctx, &ad->interval, 0); + name = NULL; + } + } + + ad->id++; + + if (name) + _free(name); +} + +static void chap_recv_response(struct chap_auth_data *ad, struct chap_hdr *hdr) { MD5_CTX md5_ctx; uint8_t md5[MD5_DIGEST_LENGTH]; char *passwd; char *name; int r; - struct chap_challenge_t *msg = (struct chap_challenge_t*)hdr; + struct chap_challenge *msg = (struct chap_challenge*)hdr; if (ad->timeout.tpd) triton_timer_del(&ad->timeout); @@ -270,6 +307,9 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h return; } + if (ad->name) + return; + if (msg->hdr.id != ad->id) { if (conf_ppp_verbose) log_ppp_warn("chap-md5: id mismatch\n"); @@ -301,7 +341,12 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h return; } - r = pwdb_check(&ad->ppp->ses, name, PPP_CHAP, CHAP_MD5, ad->id, ad->val, VALUE_SIZE, msg->val); + r = pwdb_check(&ad->ppp->ses, (pwdb_callback)auth_result, ad, name, PPP_CHAP, CHAP_MD5, ad->id, ad->val, VALUE_SIZE, msg->val); + + if (r == PWDB_WAIT) { + ad->name = name; + return; + } if (r == PWDB_NO_IMPL) { passwd = pwdb_get_passwd(&ad->ppp->ses, name); @@ -383,7 +428,7 @@ static int chap_check(uint8_t *ptr) static int chap_restart(struct ppp_t *ppp, struct auth_data_t *auth) { - struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth); + struct chap_auth_data *d = container_of(auth, typeof(*d), auth); chap_send_challenge(d, 1); @@ -405,8 +450,8 @@ static struct ppp_auth_handler_t chap= static void chap_recv(struct ppp_handler_t *h) { - struct chap_auth_data_t *d = container_of(h, typeof(*d), h); - struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf; + struct chap_auth_data *d = container_of(h, typeof(*d), h); + struct chap_hdr *hdr = (struct chap_hdr *)d->ppp->buf; if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) > d->ppp->buf_size - 2) { log_ppp_warn("chap-md5: short packet received\n"); |