Skip to content

Commit 16e03fc

Browse files
committed
teap: improve debugging when supplicant returns failure
1 parent d71a2d3 commit 16e03fc

1 file changed

Lines changed: 51 additions & 29 deletions

File tree

src/modules/rlm_eap/types/rlm_eap_teap/eap_teap.c

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,15 @@ static void eap_teap_append_crypto_binding(REQUEST *request, tls_session_t *tls_
325325
eap_teap_tlv_append(request, tls_session, EAP_TEAP_TLV_CRYPTO_BINDING, true, sizeof(cbb->binding), (uint8_t *)&cbb->binding);
326326
}
327327

328+
/*
329+
* We have to be _very_ careful here as it is useful to still decode for debugging
330+
* responses but of course there could be _really_ bad data in here so we try to
331+
* work through all the errors but for wholely invalid packets we just bail early
332+
* with RLM_MODULE_INVALID to indicate "do not decode!"
333+
* - RLM_MODULE_OK: all well
334+
* - RLM_MODULE_REJECT: bad, but safe to call eap_teap_teap2vp
335+
* - RLM_MODULE_INVALID: its terrible, do not touch this packet!
336+
*/
328337
static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t const *data, unsigned int data_len)
329338
{
330339
uint16_t attr;
@@ -339,10 +348,14 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
339348

340349
rad_assert(sizeof(present) * 8 > EAP_TEAP_TLV_MAX);
341350

351+
/*
352+
* we compromise on debugging by making everything in this
353+
* section return RLM_MODULE_INVALID but it is a *lot* safer
354+
*/
342355
while (remaining > 0) {
343356
if (remaining < 4) {
344357
REDEBUG("Phase 2: Data is too small (%u) to contain a TLV header", remaining);
345-
return 0;
358+
return RLM_MODULE_INVALID;
346359
}
347360

348361
memcpy(&attr, data, sizeof(attr));
@@ -376,7 +389,7 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
376389
}
377390
}
378391
eap_teap_send_error(request, tls_session, EAP_TEAP_ERR_UNEXPECTED_TLV);
379-
return 0;
392+
return RLM_MODULE_INVALID;
380393
}
381394

382395
if (num[EAP_TEAP_TLV_INTERMED_RESULT] > 1) {
@@ -404,7 +417,7 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
404417
if (length > remaining) {
405418
REDEBUG2("Phase 2: TLV %u is longer than room remaining in the packet (%u > %u).", attr,
406419
length, remaining);
407-
return 0;
420+
return RLM_MODULE_INVALID;
408421
}
409422

410423
if (attr == EAP_TEAP_TLV_ERROR) {
@@ -421,7 +434,7 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
421434
if (length != 2) {
422435
fail_length:
423436
REDEBUG("Phase 2: TLV %u is too short. Expected 2, got %d.", attr, length);
424-
return 0;
437+
return RLM_MODULE_INVALID;
425438
}
426439

427440
status = (data[0] << 8) | data[1];
@@ -438,27 +451,27 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
438451

439452
if (vlen <= 2) {
440453
REDEBUG("Phase 2: Basic-Password-Auth-Resp TLV is too short. Expected >2, got %d.", vlen);
441-
return 0;
454+
return RLM_MODULE_INVALID;
442455
}
443456

444457
/*
445458
* Can't be zero. We must have MORE than "1 octet length + User-Name"
446459
*/
447460
if (!p[0] || ((p[0] + 1) >= vlen)) {
448461
REDEBUG("Phase 2: Basic-Password-Auth-Resp TLV is invalid. User-Name field has bad lenth %u", p[0]);
449-
return 0;
462+
return RLM_MODULE_INVALID;
450463
}
451464

452465
vlen -= p[0] + 1;
453466
if (!vlen) {
454467
REDEBUG("Phase 2: Basic-Password-Auth-Resp TLV is invalid. Password field is missing");
455-
return 0;
468+
return RLM_MODULE_INVALID;
456469
}
457470

458471
p += p[0] + 1;
459472
if (!p[0] || (p[0] >= vlen)) {
460473
REDEBUG("Phase 2: Basic-Password-Auth-Resp TLV is invalid. Password field has bad lenth %u", p[0]);
461-
return 0;
474+
return RLM_MODULE_INVALID;
462475
}
463476
}
464477

@@ -468,7 +481,7 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
468481
if ((data[0] != 0) || (data[1] == 0) || (data[1] > 2)) {
469482
REDEBUG("Phase 2: Identity-Type TLV contains invalid value %02x%02x",
470483
data[0], data[1]);
471-
return 0;
484+
return RLM_MODULE_INVALID;
472485
}
473486
}
474487

@@ -478,12 +491,12 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
478491
if (attr == EAP_TEAP_TLV_CRYPTO_BINDING) {
479492
if (length != sizeof(eap_tlv_crypto_binding_tlv_t)) {
480493
REDEBUG("Phase 2: Crypto-Binding TLV has incorrect length %u", length);
481-
return 0;
494+
return RLM_MODULE_INVALID;
482495
}
483496

484497
if (data[1] != EAP_TEAP_VERSION) {
485498
REDEBUG("Phase 2: Crypto-Binding TLV has incorrect version %u", data[1]);
486-
return 0;
499+
return RLM_MODULE_INVALID;
487500
}
488501
}
489502

@@ -494,6 +507,10 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
494507
data += length;
495508
}
496509

510+
/*
511+
* Safe to return RLM_MODULE_REJECT now that calling eap_teap_teap2vp is safe
512+
*/
513+
497514
/*
498515
* Check status if we have it.
499516
*/
@@ -504,13 +521,13 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
504521
} else {
505522
REDEBUG("Phase 2: Received Result TLV from peer which indicates failure. Rejecting request.");
506523
}
507-
return 0;
524+
return RLM_MODULE_REJECT;
508525
}
509526

510527
if (status != EAP_TEAP_TLV_RESULT_SUCCESS) {
511528
unknown_value:
512529
REDEBUG("Phase 2: Received Result TLV from peer with unknown value %u. Rejecting request.", status);
513-
goto unexpected;
530+
return RLM_MODULE_REJECT;
514531
}
515532
}
516533

@@ -523,15 +540,15 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
523540
if ((error >= 2000) && (error <= 2999)) {
524541
REDEBUG("Phase 2: Received Error TLV from peer which indicates fatal error %u. Rejecting request.",
525542
error);
526-
return 0;
543+
return RLM_MODULE_REJECT;
527544
}
528545

529546
/*
530547
* Check if the peer mixed & matched TLVs.
531548
*/
532549
if ((num[EAP_TEAP_TLV_NAK] > 0) && (num[EAP_TEAP_TLV_NAK] != total)) {
533550
REDEBUG("Phase 2: NAK TLV was sent along with non-NAK TLVs. Rejecting request.");
534-
goto unexpected;
551+
return RLM_MODULE_REJECT;
535552
}
536553

537554
/*
@@ -545,21 +562,21 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
545562
case TLS_SESSION_HANDSHAKE:
546563
if (present) {
547564
REDEBUG("Phase 2: Unexpected TLVs in TLS Session Handshake stage");
548-
goto unexpected;
565+
return RLM_MODULE_REJECT;
549566
}
550567
break;
551568
case AUTHENTICATION:
552569
if (present & ~((1 << EAP_TEAP_TLV_EAP_PAYLOAD) | (1 << EAP_TEAP_TLV_CRYPTO_BINDING) | (1 << EAP_TEAP_TLV_INTERMED_RESULT) | (1 << EAP_TEAP_TLV_RESULT) | (1 << EAP_TEAP_TLV_BASIC_PASSWORD_AUTH_RESP))) {
553570
REDEBUG("Phase 2: Unexpected TLVs in authentication stage");
554-
goto unexpected;
571+
return RLM_MODULE_REJECT;
555572
}
556573

557574
/*
558575
* A password request must yield a password response.
559576
*/
560577
if (t->sent_basic_password && ((present & (1 << EAP_TEAP_TLV_BASIC_PASSWORD_AUTH_RESP)) == 0)) {
561578
REDEBUG("Phase 2: Sent Basic-Password-Auth-Req but reply does not contain Basic-Password-Auth-Resp");
562-
goto unexpected;
579+
return RLM_MODULE_REJECT;
563580
}
564581

565582
/*
@@ -571,14 +588,14 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
571588
((present & (1 << EAP_TEAP_TLV_EAP_PAYLOAD)) == 0) &&
572589
((present & (1 << EAP_TEAP_TLV_BASIC_PASSWORD_AUTH_RESP)) == 0)) {
573590
REDEBUG("Phase 2: Received Identity-Type without EAP-Payload or Basic-Password-Auth-Resp");
574-
goto unexpected;
591+
return RLM_MODULE_REJECT;
575592
}
576593

577594
break;
578595
case PROVISIONING:
579596
if (present & ~((1 << EAP_TEAP_TLV_RESULT) | (1 << EAP_TEAP_TLV_CRYPTO_BINDING) | (1 << EAP_TEAP_TLV_INTERMED_RESULT))) {
580597
REDEBUG("Phase 2: Unexpected TLVs in provisioning stage");
581-
goto unexpected;
598+
return RLM_MODULE_REJECT;
582599
}
583600
break;
584601
case COMPLETE:
@@ -589,18 +606,18 @@ static int eap_teap_verify(REQUEST *request, tls_session_t *tls_session, uint8_t
589606
(1 << EAP_TEAP_TLV_RESULT) | (1 << EAP_TEAP_TLV_ERROR));
590607
if (present) {
591608
REDEBUG("Phase 2: Unexpected TLVs in complete stage");
592-
goto unexpected;
609+
return RLM_MODULE_REJECT;
593610
}
594611
break;
595612
default:
596613
REDEBUG("Phase 2: Internal error, invalid stage %d", t->stage);
597-
return 0;
614+
return RLM_MODULE_REJECT;
598615
}
599616

600617
/*
601618
* We got this far. It looks OK.
602619
*/
603-
return 1;
620+
return RLM_MODULE_OK;
604621
}
605622

606623
static ssize_t eap_teap_decode_vp(TALLOC_CTX *request, DICT_ATTR const *parent,
@@ -1816,6 +1833,7 @@ static void print_tunneled_data(uint8_t const *data, size_t data_len)
18161833
PW_CODE eap_teap_process(eap_handler_t *eap_session, tls_session_t *tls_session)
18171834
{
18181835
PW_CODE code;
1836+
int verify;
18191837
VALUE_PAIR *teap_vps, *vp;
18201838
uint8_t const *data;
18211839
size_t data_len;
@@ -1836,8 +1854,17 @@ PW_CODE eap_teap_process(eap_handler_t *eap_session, tls_session_t *tls_session)
18361854

18371855
/*
18381856
* See if the tunneled data is well formed.
1857+
* - RLM_MODULE_INVALID means the TLVs are bad so do not decode them and immediately bail
18391858
*/
1840-
if (!eap_teap_verify(request, tls_session, data, data_len)) return PW_CODE_ACCESS_REJECT;
1859+
verify = eap_teap_verify(request, tls_session, data, data_len);
1860+
if (verify == RLM_MODULE_INVALID) return PW_CODE_ACCESS_REJECT;
1861+
1862+
teap_vps = eap_teap_teap2vp(request, tls_session->ssl, data, data_len, NULL, NULL);
1863+
1864+
RDEBUG("Phase 2: Got Tunneled TEAP TLVs");
1865+
rdebug_pair_list(L_DBG_LVL_1, request, teap_vps, NULL);
1866+
1867+
if (verify != RLM_MODULE_OK) return PW_CODE_ACCESS_REJECT;
18411868

18421869
if (t->stage == TLS_SESSION_HANDSHAKE) {
18431870
char buf[256];
@@ -1900,11 +1927,6 @@ PW_CODE eap_teap_process(eap_handler_t *eap_session, tls_session_t *tls_session)
19001927
return PW_CODE_ACCESS_CHALLENGE;
19011928
}
19021929

1903-
teap_vps = eap_teap_teap2vp(request, tls_session->ssl, data, data_len, NULL, NULL);
1904-
1905-
RDEBUG("Phase 2: Got Tunneled TEAP TLVs");
1906-
rdebug_pair_list(L_DBG_LVL_1, request, teap_vps, NULL);
1907-
19081930
code = eap_teap_process_tlvs(request, eap_session, tls_session, teap_vps);
19091931

19101932
fr_pair_list_free(&teap_vps);

0 commit comments

Comments
 (0)