@@ -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+ */
328337static 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
606623static 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)
18161833PW_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