EAP-PEAP server: Support vendor EAP types in Phase 2
This was already allowed with EAP-PEAP, but EAP-TEAP was hardcoded to use only the non-expanded EAP types. Extend that to allow vendor EAP types to be used. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
		
							parent
							
								
									357c1062dc
								
							
						
					
					
						commit
						aba8dc82fc
					
				
					 1 changed files with 28 additions and 13 deletions
				
			
		|  | @ -938,15 +938,14 @@ static Boolean eap_teap_check(struct eap_sm *sm, void *priv, | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data, | static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data, | ||||||
| 				enum eap_type eap_type) | 				int vendor, enum eap_type eap_type) | ||||||
| { | { | ||||||
| 	if (data->phase2_priv && data->phase2_method) { | 	if (data->phase2_priv && data->phase2_method) { | ||||||
| 		data->phase2_method->reset(sm, data->phase2_priv); | 		data->phase2_method->reset(sm, data->phase2_priv); | ||||||
| 		data->phase2_method = NULL; | 		data->phase2_method = NULL; | ||||||
| 		data->phase2_priv = NULL; | 		data->phase2_priv = NULL; | ||||||
| 	} | 	} | ||||||
| 	data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF, | 	data->phase2_method = eap_server_get_eap_method(vendor, eap_type); | ||||||
| 							eap_type); |  | ||||||
| 	if (!data->phase2_method) | 	if (!data->phase2_method) | ||||||
| 		return -1; | 		return -1; | ||||||
| 
 | 
 | ||||||
|  | @ -962,7 +961,8 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, | ||||||
| 					     struct eap_teap_data *data, | 					     struct eap_teap_data *data, | ||||||
| 					     u8 *in_data, size_t in_len) | 					     u8 *in_data, size_t in_len) | ||||||
| { | { | ||||||
| 	u8 next_type = EAP_TYPE_NONE; | 	int next_vendor = EAP_VENDOR_IETF; | ||||||
|  | 	enum eap_type next_type = EAP_TYPE_NONE; | ||||||
| 	struct eap_hdr *hdr; | 	struct eap_hdr *hdr; | ||||||
| 	u8 *pos; | 	u8 *pos; | ||||||
| 	size_t left; | 	size_t left; | ||||||
|  | @ -990,8 +990,9 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, | ||||||
| 		    m->method == EAP_TYPE_TNC) { | 		    m->method == EAP_TYPE_TNC) { | ||||||
| 			wpa_printf(MSG_DEBUG, | 			wpa_printf(MSG_DEBUG, | ||||||
| 				   "EAP-TEAP: Peer Nak'ed required TNC negotiation"); | 				   "EAP-TEAP: Peer Nak'ed required TNC negotiation"); | ||||||
|  | 			next_vendor = EAP_VENDOR_IETF; | ||||||
| 			next_type = eap_teap_req_failure(data, 0); | 			next_type = eap_teap_req_failure(data, 0); | ||||||
| 			eap_teap_phase2_init(sm, data, next_type); | 			eap_teap_phase2_init(sm, data, next_vendor, next_type); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| #endif /* EAP_SERVER_TNC */ | #endif /* EAP_SERVER_TNC */ | ||||||
|  | @ -999,14 +1000,17 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, | ||||||
| 		if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && | 		if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && | ||||||
| 		    sm->user->methods[sm->user_eap_method_index].method != | 		    sm->user->methods[sm->user_eap_method_index].method != | ||||||
| 		    EAP_TYPE_NONE) { | 		    EAP_TYPE_NONE) { | ||||||
|  | 			next_vendor = sm->user->methods[ | ||||||
|  | 				sm->user_eap_method_index].vendor; | ||||||
| 			next_type = sm->user->methods[ | 			next_type = sm->user->methods[ | ||||||
| 				sm->user_eap_method_index++].method; | 				sm->user_eap_method_index++].method; | ||||||
| 			wpa_printf(MSG_DEBUG, "EAP-TEAP: try EAP type %d", | 			wpa_printf(MSG_DEBUG, "EAP-TEAP: try EAP type %u:%u", | ||||||
| 				   next_type); | 				   next_vendor, next_type); | ||||||
| 		} else { | 		} else { | ||||||
|  | 			next_vendor = EAP_VENDOR_IETF; | ||||||
| 			next_type = eap_teap_req_failure(data, 0); | 			next_type = eap_teap_req_failure(data, 0); | ||||||
| 		} | 		} | ||||||
| 		eap_teap_phase2_init(sm, data, next_type); | 		eap_teap_phase2_init(sm, data, next_vendor, next_type); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -1026,8 +1030,9 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, | ||||||
| 
 | 
 | ||||||
| 	if (!m->isSuccess(sm, priv)) { | 	if (!m->isSuccess(sm, priv)) { | ||||||
| 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 method failed"); | 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 method failed"); | ||||||
|  | 		next_vendor = EAP_VENDOR_IETF; | ||||||
| 		next_type = eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD); | 		next_type = eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD); | ||||||
| 		eap_teap_phase2_init(sm, data, next_type); | 		eap_teap_phase2_init(sm, data, next_vendor, next_type); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -1037,6 +1042,7 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, | ||||||
| 			wpa_hexdump_ascii(MSG_DEBUG, | 			wpa_hexdump_ascii(MSG_DEBUG, | ||||||
| 					  "EAP-TEAP: Phase 2 Identity not found in the user database", | 					  "EAP-TEAP: Phase 2 Identity not found in the user database", | ||||||
| 					  sm->identity, sm->identity_len); | 					  sm->identity, sm->identity_len); | ||||||
|  | 			next_vendor = EAP_VENDOR_IETF; | ||||||
| 			next_type = eap_teap_req_failure( | 			next_type = eap_teap_req_failure( | ||||||
| 				data, TEAP_ERROR_INNER_METHOD); | 				data, TEAP_ERROR_INNER_METHOD); | ||||||
| 			break; | 			break; | ||||||
|  | @ -1047,23 +1053,28 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, | ||||||
| 			/* TODO: Allow any inner EAP method that provides
 | 			/* TODO: Allow any inner EAP method that provides
 | ||||||
| 			 * mutual authentication and EMSK derivation (i.e., | 			 * mutual authentication and EMSK derivation (i.e., | ||||||
| 			 * EAP-pwd or EAP-EKE). */ | 			 * EAP-pwd or EAP-EKE). */ | ||||||
|  | 			next_vendor = EAP_VENDOR_IETF; | ||||||
| 			next_type = EAP_TYPE_PWD; | 			next_type = EAP_TYPE_PWD; | ||||||
| 			sm->user_eap_method_index = 0; | 			sm->user_eap_method_index = 0; | ||||||
| 		} else { | 		} else { | ||||||
|  | 			next_vendor = sm->user->methods[0].vendor; | ||||||
| 			next_type = sm->user->methods[0].method; | 			next_type = sm->user->methods[0].method; | ||||||
| 			sm->user_eap_method_index = 1; | 			sm->user_eap_method_index = 1; | ||||||
| 		} | 		} | ||||||
| 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Try EAP type %d", next_type); | 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Try EAP type %u:%u", | ||||||
|  | 			   next_vendor, next_type); | ||||||
| 		break; | 		break; | ||||||
| 	case PHASE2_METHOD: | 	case PHASE2_METHOD: | ||||||
| 	case CRYPTO_BINDING: | 	case CRYPTO_BINDING: | ||||||
| 		eap_teap_update_icmk(sm, data); | 		eap_teap_update_icmk(sm, data); | ||||||
| 		eap_teap_state(data, CRYPTO_BINDING); | 		eap_teap_state(data, CRYPTO_BINDING); | ||||||
| 		data->eap_seq++; | 		data->eap_seq++; | ||||||
|  | 		next_vendor = EAP_VENDOR_IETF; | ||||||
| 		next_type = EAP_TYPE_NONE; | 		next_type = EAP_TYPE_NONE; | ||||||
| #ifdef EAP_SERVER_TNC | #ifdef EAP_SERVER_TNC | ||||||
| 		if (sm->tnc && !data->tnc_started) { | 		if (sm->tnc && !data->tnc_started) { | ||||||
| 			wpa_printf(MSG_DEBUG, "EAP-TEAP: Initialize TNC"); | 			wpa_printf(MSG_DEBUG, "EAP-TEAP: Initialize TNC"); | ||||||
|  | 			next_vendor = EAP_VENDOR_IETF; | ||||||
| 			next_type = EAP_TYPE_TNC; | 			next_type = EAP_TYPE_TNC; | ||||||
| 			data->tnc_started = 1; | 			data->tnc_started = 1; | ||||||
| 		} | 		} | ||||||
|  | @ -1077,7 +1088,7 @@ static void eap_teap_process_phase2_response(struct eap_sm *sm, | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	eap_teap_phase2_init(sm, data, next_type); | 	eap_teap_phase2_init(sm, data, next_vendor, next_type); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -1640,7 +1651,8 @@ static int eap_teap_process_phase1(struct eap_sm *sm, | ||||||
| static int eap_teap_process_phase2_start(struct eap_sm *sm, | static int eap_teap_process_phase2_start(struct eap_sm *sm, | ||||||
| 					 struct eap_teap_data *data) | 					 struct eap_teap_data *data) | ||||||
| { | { | ||||||
| 	u8 next_type; | 	int next_vendor; | ||||||
|  | 	enum eap_type next_type; | ||||||
| 
 | 
 | ||||||
| 	if (data->identity) { | 	if (data->identity) { | ||||||
| 		/* Used PAC and identity is from PAC-Opaque */ | 		/* Used PAC and identity is from PAC-Opaque */ | ||||||
|  | @ -1653,6 +1665,7 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm, | ||||||
| 			wpa_hexdump_ascii(MSG_DEBUG, | 			wpa_hexdump_ascii(MSG_DEBUG, | ||||||
| 					  "EAP-TEAP: Phase 2 Identity not found in the user database", | 					  "EAP-TEAP: Phase 2 Identity not found in the user database", | ||||||
| 					  sm->identity, sm->identity_len); | 					  sm->identity, sm->identity_len); | ||||||
|  | 			next_vendor = EAP_VENDOR_IETF; | ||||||
| 			next_type = EAP_TYPE_NONE; | 			next_type = EAP_TYPE_NONE; | ||||||
| 			eap_teap_state(data, PHASE2_METHOD); | 			eap_teap_state(data, PHASE2_METHOD); | ||||||
| 		} else if (sm->eap_teap_pac_no_inner) { | 		} else if (sm->eap_teap_pac_no_inner) { | ||||||
|  | @ -1672,6 +1685,7 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm, | ||||||
| 		} else { | 		} else { | ||||||
| 			wpa_printf(MSG_DEBUG, | 			wpa_printf(MSG_DEBUG, | ||||||
| 				   "EAP-TEAP: Identity already known - skip Phase 2 Identity Request"); | 				   "EAP-TEAP: Identity already known - skip Phase 2 Identity Request"); | ||||||
|  | 			next_vendor = sm->user->methods[0].vendor; | ||||||
| 			next_type = sm->user->methods[0].method; | 			next_type = sm->user->methods[0].method; | ||||||
| 			sm->user_eap_method_index = 1; | 			sm->user_eap_method_index = 1; | ||||||
| 			eap_teap_state(data, PHASE2_METHOD); | 			eap_teap_state(data, PHASE2_METHOD); | ||||||
|  | @ -1682,10 +1696,11 @@ static int eap_teap_process_phase2_start(struct eap_sm *sm, | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} else { | 	} else { | ||||||
| 		eap_teap_state(data, PHASE2_ID); | 		eap_teap_state(data, PHASE2_ID); | ||||||
|  | 		next_vendor = EAP_VENDOR_IETF; | ||||||
| 		next_type = EAP_TYPE_IDENTITY; | 		next_type = EAP_TYPE_IDENTITY; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return eap_teap_phase2_init(sm, data, next_type); | 	return eap_teap_phase2_init(sm, data, next_vendor, next_type); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jouni Malinen
						Jouni Malinen