From: Alan T. DeKok Date: Wed, 29 Mar 2017 15:30:48 +0000 (-0400) Subject: start of peapv1 X-Git-Tag: release_3_0_14~65 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=freeradius.git;a=commitdiff_plain;h=77f85a69878a0a334ce8130cd1177476c7f6631e start of peapv1 --- diff --git a/src/modules/rlm_eap/types/rlm_eap_peap/peap.c b/src/modules/rlm_eap/types/rlm_eap_peap/peap.c index cc0927e..801bd7c 100644 --- a/src/modules/rlm_eap/types/rlm_eap_peap/peap.c +++ b/src/modules/rlm_eap/types/rlm_eap_peap/peap.c @@ -207,12 +207,17 @@ static void eapsoh_verify(REQUEST *request, RADIUS_PACKET *packet, * Verify the tunneled EAP message. */ static int eapmessage_verify(REQUEST *request, - uint8_t const *data, unsigned int data_len) + uint8_t const *data, unsigned int data_len, int peap_version) { eap_packet_raw_t const *eap_packet = (eap_packet_raw_t const *) data; eap_type_t eap_method; /* + * Hack for now. + */ + if (peap_version == 1) return 1; + + /* * No data, OR only 1 byte of EAP type. */ if (!data || (data_len == 0) || @@ -241,7 +246,7 @@ static int eapmessage_verify(REQUEST *request, RDEBUG2("Received EAP-TLV response"); return 1; } - RDEBUG2("Got something weird"); + RDEBUG2("Received unexpected EAP-Response, rejecting the session."); break; @@ -264,7 +269,7 @@ static int eapmessage_verify(REQUEST *request, */ static VALUE_PAIR *eap2vp(UNUSED REQUEST *request, RADIUS_PACKET *packet, EAP_DS *eap_ds, - uint8_t const *data, size_t data_len) + uint8_t const *data, size_t data_len, int peap_version) { size_t total; uint8_t *p; @@ -281,18 +286,25 @@ static VALUE_PAIR *eap2vp(UNUSED REQUEST *request, RADIUS_PACKET *packet, total = data_len; if (total > 249) total = 249; - /* - * Hand-build an EAP packet from the crap in PEAP version 0. - */ - vp->vp_length = EAP_HEADER_LEN + total; - vp->vp_octets = p = talloc_array(vp, uint8_t, vp->vp_length); + if (peap_version == 0) { + /* + * Hand-build an EAP packet from the crap in PEAP version 0. + */ + vp->vp_length = EAP_HEADER_LEN + total; + vp->vp_octets = p = talloc_array(vp, uint8_t, vp->vp_length); + + p[0] = PW_EAP_RESPONSE; + p[1] = eap_ds->response->id; + p[2] = (data_len + EAP_HEADER_LEN) >> 8; + p[3] = (data_len + EAP_HEADER_LEN) & 0xff; - p[0] = PW_EAP_RESPONSE; - p[1] = eap_ds->response->id; - p[2] = (data_len + EAP_HEADER_LEN) >> 8; - p[3] = (data_len + EAP_HEADER_LEN) & 0xff; + memcpy(p + EAP_HEADER_LEN, data, total); - memcpy(p + EAP_HEADER_LEN, data, total); + } else { /* peapv1 */ + vp->vp_length = total; + vp->vp_octets = p = talloc_array(vp, uint8_t, vp->vp_length); + memcpy(p, data, total); + } fr_cursor_init(&cursor, &head); fr_cursor_insert(&cursor, vp); @@ -323,6 +335,9 @@ static int vp2eap(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR *vp) rad_assert(vp != NULL); VALUE_PAIR *this; vp_cursor_t cursor; + size_t header = EAP_HEADER_LEN; + + if (tls_session->peap_flag > 0) header = 0; /* * Skip the id, code, and length. Just write the EAP @@ -330,7 +345,7 @@ static int vp2eap(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR *vp) */ #ifndef NDEBUG if ((rad_debug_lvl > 2) && fr_log_fp) { - size_t i, total, start = EAP_HEADER_LEN; + size_t i, total, start = header; total = 0; for (this = fr_cursor_init(&cursor, &vp); this; this = fr_cursor_next(&cursor)) { @@ -360,7 +375,7 @@ static int vp2eap(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR *vp) * Send the EAP data in the first attribute, WITHOUT the * header. */ - (tls_session->record_plus)(&tls_session->clean_in, vp->vp_octets + EAP_HEADER_LEN, vp->vp_length - EAP_HEADER_LEN); + (tls_session->record_plus)(&tls_session->clean_in, vp->vp_octets + header, vp->vp_length - header); /* * Send the rest of the EAP data, but skipping the first VP. @@ -730,6 +745,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session, rlm_rcode_t rcode = RLM_MODULE_REJECT; uint8_t const *data; unsigned int data_len; + size_t header = 0; REQUEST *request = handler->request; EAP_DS *eap_ds = handler->eap_ds; @@ -745,12 +761,14 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session, RDEBUG2("PEAP state %s", peap_state(t)); if ((t->status != PEAP_STATUS_TUNNEL_ESTABLISHED) && - !eapmessage_verify(request, data, data_len)) { + !eapmessage_verify(request, data, data_len, tls_session->peap_flag)) { REDEBUG("Tunneled data is invalid"); if (rad_debug_lvl > 2) print_tunneled_data(data, data_len); return RLM_MODULE_REJECT; } + if (tls_session->peap_flag > 0) header = EAP_HEADER_LEN; + switch (t->status) { case PEAP_STATUS_TUNNEL_ESTABLISHED: /* FIXME: should be no data in the buffer here, check & assert? */ @@ -778,7 +796,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session, case PEAP_STATUS_INNER_IDENTITY_REQ_SENT: /* we're expecting an identity response */ - if (data[0] != PW_EAP_IDENTITY) { + if (data[header] != PW_EAP_IDENTITY) { REDEBUG("Expected EAP-Identity, got something else"); return RLM_MODULE_REJECT; } @@ -789,7 +807,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session, t->username = fr_pair_make(t, NULL, "User-Name", NULL, T_OP_EQ); rad_assert(t->username != NULL); - fr_pair_value_bstrncpy(t->username, data + 1, data_len - 1); + fr_pair_value_bstrncpy(t->username, data + header + 1, data_len - header - 1); RDEBUG("Got inner identity '%s'", t->username->vp_strvalue); if (t->soh) { @@ -804,7 +822,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session, case PEAP_STATUS_WAIT_FOR_SOH_RESPONSE: fake = request_alloc_fake(request); rad_assert(!fake->packet->vps); - eapsoh_verify(fake, fake->packet, data, data_len); + eapsoh_verify(fake, fake->packet, data + header, data_len - header); setup_fake_request(request, fake, t); if (t->soh_virtual_server) { @@ -842,7 +860,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session, * If we authenticated the user, then it's OK. */ case PEAP_STATUS_SENT_TLV_SUCCESS: - if (eappeap_check_tlv(request, data, data_len)) { + if (eappeap_check_tlv(request, data + header, data_len - header)) { RDEBUG2("Success"); return RLM_MODULE_OK; } @@ -937,7 +955,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session, case PEAP_STATUS_PHASE2: fake->packet->vps = eap2vp(request, fake->packet, - eap_ds, data, data_len); + eap_ds, data, data_len, tls_session->peap_flag); if (!fake->packet->vps) { talloc_free(fake); RDEBUG2("Unable to convert tunneled EAP packet to internal server data structures"); @@ -962,11 +980,11 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session, * so we add one here, by pulling it out of the * EAP-Identity packet. */ - if ((data[0] == PW_EAP_IDENTITY) && (data_len > 1)) { + if ((data[header] == PW_EAP_IDENTITY) && (data_len > (1 + header))) { t->username = fr_pair_make(t, NULL, "User-Name", NULL, T_OP_EQ); rad_assert(t->username != NULL); - fr_pair_value_bstrncpy(t->username, data + 1, data_len - 1); + fr_pair_value_bstrncpy(t->username, data + header + 1, data_len - header - 1); RDEBUG2("Got tunneled identity of %s", t->username->vp_strvalue); diff --git a/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c b/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c index e43c9c7..5bf7c96 100644 --- a/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c +++ b/src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c @@ -262,6 +262,13 @@ static int mod_process(void *arg, eap_handler_t *handler) peap = tls_session->opaque = peap_alloc(tls_session, inst); } + /* + * Negotiate PEAP versions down. + */ + if ((handler->eap_ds->response->type.data[0] & 0x03) < tls_session->peap_flag) { + tls_session->peap_flag = handler->eap_ds->response->type.data[0] & 0x03; + } + status = eaptls_process(handler); if ((status == FR_TLS_INVALID) || (status == FR_TLS_FAIL)) { REDEBUG("[eaptls process] = %s", fr_int2str(fr_tls_status_table, status, ""));