hostapd: reconfigure wps credentials on reload
This patch fixes a bug that prevents updating Multi-AP credentials after hostapd has started. It was sent to upstream hostapd here: https://patchwork.ozlabs.org/bundle/rmelotte/hostapd:%20update%20WPS%20credentials%20on%20SIGHUP/ Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
This commit is contained in:
		 Raphaël Mélotte
					Raphaël Mélotte
				
			
				
					committed by
					
						 Petr Štetiar
						Petr Štetiar
					
				
			
			
				
	
			
			
			 Petr Štetiar
						Petr Štetiar
					
				
			
						parent
						
							59fa9c28d6
						
					
				
				
					commit
					14b9100f1c
				
			| @@ -0,0 +1,187 @@ | ||||
| From b389a77a0f6dccf495dbce5be9476000f6ec06a2 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> | ||||
| Date: Wed, 9 Dec 2020 19:55:53 +0100 | ||||
| Subject: [PATCH] wps: reconfigure credentials on reload | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| When new credentials are configured and hostapd is reconfigured using | ||||
| SIGHUP (or reload on the ctrl_iface), also update the wps credentials. | ||||
|  | ||||
| Before these changes, when WPS is triggered the registar always serves | ||||
| the credentials that were configured when hostapd started. | ||||
|  | ||||
| Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> | ||||
| --- | ||||
|  src/ap/wps_hostapd.c    | 86 +++++++++++++++++++++++++++++++++++++++-- | ||||
|  src/wps/wps.h           |  6 +++ | ||||
|  src/wps/wps_registrar.c | 29 ++++++++++++++ | ||||
|  3 files changed, 118 insertions(+), 3 deletions(-) | ||||
|  | ||||
| diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c | ||||
| index dc8aa8f65..ff942a67b 100644 | ||||
| --- a/src/ap/wps_hostapd.c | ||||
| +++ b/src/ap/wps_hostapd.c | ||||
| @@ -1375,6 +1375,43 @@ static void hostapd_wps_nfc_clear(struct wps_context *wps) | ||||
|  #endif /* CONFIG_WPS_NFC */ | ||||
|  } | ||||
|   | ||||
| +int hostapd_wps_update_multi_ap(struct hostapd_data *hapd, | ||||
| +				struct wps_registrar *reg) { | ||||
| +	struct hostapd_bss_config *conf = hapd->conf; | ||||
| +	u8 *multi_ap_backhaul_network_key = NULL; | ||||
| +	size_t multi_ap_backhaul_network_key_len = 0; | ||||
| +	int ret = -1; | ||||
| + | ||||
| +	if ((conf->multi_ap & FRONTHAUL_BSS) && | ||||
| +	    conf->multi_ap_backhaul_ssid.ssid_len) { | ||||
| +		if (conf->multi_ap_backhaul_ssid.wpa_passphrase) { | ||||
| +			multi_ap_backhaul_network_key = | ||||
| +				(u8 *) os_strdup(conf->multi_ap_backhaul_ssid.wpa_passphrase); | ||||
| +			if (multi_ap_backhaul_network_key == NULL) | ||||
| +				return -1; | ||||
| +			multi_ap_backhaul_network_key_len = | ||||
| +				os_strlen(conf->multi_ap_backhaul_ssid.wpa_passphrase); | ||||
| +		} else if (conf->multi_ap_backhaul_ssid.wpa_psk) { | ||||
| +			multi_ap_backhaul_network_key = os_malloc(2 * PMK_LEN + 1); | ||||
| +			if (multi_ap_backhaul_network_key == NULL) | ||||
| +				return -1; | ||||
| +			wpa_snprintf_hex((char *) multi_ap_backhaul_network_key, | ||||
| +					 2 * PMK_LEN + 1, | ||||
| +					 conf->multi_ap_backhaul_ssid.wpa_psk->psk, | ||||
| +					 PMK_LEN); | ||||
| +			multi_ap_backhaul_network_key_len = 2 * PMK_LEN; | ||||
| +		} | ||||
| +		ret = wps_registrar_update_multi_ap(reg, | ||||
| +						    conf->multi_ap_backhaul_ssid.ssid, | ||||
| +						    conf->multi_ap_backhaul_ssid.ssid_len, | ||||
| +						    multi_ap_backhaul_network_key, | ||||
| +						    multi_ap_backhaul_network_key_len); | ||||
| +		os_free(multi_ap_backhaul_network_key); | ||||
| +	} | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| + | ||||
|   | ||||
|  void hostapd_deinit_wps(struct hostapd_data *hapd) | ||||
|  { | ||||
| @@ -1409,11 +1446,54 @@ void hostapd_update_wps(struct hostapd_data *hapd) | ||||
|  	hapd->wps->upc = hapd->conf->upc; | ||||
|  #endif /* CONFIG_WPS_UPNP */ | ||||
|   | ||||
| -	hostapd_wps_set_vendor_ext(hapd, hapd->wps); | ||||
| -	hostapd_wps_set_application_ext(hapd, hapd->wps); | ||||
| +	struct wps_context *wps = hapd->wps; | ||||
| +	struct hostapd_bss_config *conf = hapd->conf; | ||||
| + | ||||
| +	os_memcpy(wps->ssid, conf->ssid.ssid, conf->ssid.ssid_len); | ||||
| +	wps->ssid_len = conf->ssid.ssid_len; | ||||
| + | ||||
| +	/* Clear wps settings, then fill them again */ | ||||
| +	os_free(wps->network_key); | ||||
| +	wps->network_key = NULL; | ||||
| +	wps->network_key_len = 0; | ||||
| +	wps->psk_set = 0; | ||||
| +	if (conf->ssid.wpa_psk_file) { | ||||
| +		/* Use per-device PSKs */ | ||||
| +	} else if (conf->ssid.wpa_passphrase) { | ||||
| +		wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase); | ||||
| +		if (wps->network_key == NULL) | ||||
| +			return; | ||||
| +		wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase); | ||||
| +	} else if (conf->ssid.wpa_psk) { | ||||
| +		wps->network_key = os_malloc(2 * PMK_LEN + 1); | ||||
| +		if (wps->network_key == NULL) | ||||
| +			return; | ||||
| +		wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1, | ||||
| +				 conf->ssid.wpa_psk->psk, PMK_LEN); | ||||
| +		wps->network_key_len = 2 * PMK_LEN; | ||||
| +#ifdef CONFIG_WEP | ||||
| +	} else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) { | ||||
| +		wps->network_key = os_malloc(conf->ssid.wep.len[0]); | ||||
| +		if (wps->network_key == NULL) | ||||
| +			return; | ||||
| +		os_memcpy(wps->network_key, conf->ssid.wep.key[0], | ||||
| +			  conf->ssid.wep.len[0]); | ||||
| +		wps->network_key_len = conf->ssid.wep.len[0]; | ||||
| +#endif /* CONFIG_WEP */ | ||||
| +	} | ||||
| + | ||||
| +	if (conf->ssid.wpa_psk) { | ||||
| +		os_memcpy(wps->psk, conf->ssid.wpa_psk->psk, PMK_LEN); | ||||
| +		wps->psk_set = 1; | ||||
| +	} | ||||
| + | ||||
| +	hostapd_wps_update_multi_ap(hapd, wps->registrar); | ||||
| + | ||||
| +	hostapd_wps_set_vendor_ext(hapd, wps); | ||||
| +	hostapd_wps_set_application_ext(hapd, wps); | ||||
|   | ||||
|  	if (hapd->conf->wps_state) | ||||
| -		wps_registrar_update_ie(hapd->wps->registrar); | ||||
| +		wps_registrar_update_ie(wps->registrar); | ||||
|  	else | ||||
|  		hostapd_deinit_wps(hapd); | ||||
|  } | ||||
| diff --git a/src/wps/wps.h b/src/wps/wps.h | ||||
| index 93888b011..110e3ea52 100644 | ||||
| --- a/src/wps/wps.h | ||||
| +++ b/src/wps/wps.h | ||||
| @@ -938,6 +938,12 @@ struct wpabuf * wps_build_nfc_handover_sel_p2p(struct wps_context *ctx, | ||||
|  					       struct wpabuf *nfc_dh_pubkey, | ||||
|  					       struct wpabuf *nfc_dev_pw); | ||||
|   | ||||
| +int wps_registrar_update_multi_ap(struct wps_registrar *reg, | ||||
| +				  const u8 *multi_ap_backhaul_ssid, | ||||
| +				  size_t multi_ap_backhaul_ssid_len, | ||||
| +				  const u8 *multi_ap_backhaul_network_key, | ||||
| +				  size_t multi_ap_backhaul_network_key_len); | ||||
| + | ||||
|  /* ndef.c */ | ||||
|  struct wpabuf * ndef_parse_wifi(const struct wpabuf *buf); | ||||
|  struct wpabuf * ndef_build_wifi(const struct wpabuf *buf); | ||||
| diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c | ||||
| index 9e1ee36da..d6b27be28 100644 | ||||
| --- a/src/wps/wps_registrar.c | ||||
| +++ b/src/wps/wps_registrar.c | ||||
| @@ -3669,6 +3669,35 @@ int wps_registrar_config_ap(struct wps_registrar *reg, | ||||
|  } | ||||
|   | ||||
|   | ||||
| +int wps_registrar_update_multi_ap(struct wps_registrar *reg, | ||||
| +				  const u8 *multi_ap_backhaul_ssid, | ||||
| +				  size_t multi_ap_backhaul_ssid_len, | ||||
| +				  const u8 *multi_ap_backhaul_network_key, | ||||
| +				  size_t multi_ap_backhaul_network_key_len) | ||||
| +{ | ||||
| +	if (multi_ap_backhaul_ssid != NULL) { | ||||
| +		os_memcpy(reg->multi_ap_backhaul_ssid, | ||||
| +			  multi_ap_backhaul_ssid, | ||||
| +			  multi_ap_backhaul_ssid_len); | ||||
| +		reg->multi_ap_backhaul_ssid_len = | ||||
| +			multi_ap_backhaul_ssid_len; | ||||
| +	} | ||||
| +	os_free(reg->multi_ap_backhaul_network_key); | ||||
| +	reg->multi_ap_backhaul_network_key = NULL; | ||||
| +	reg->multi_ap_backhaul_network_key_len = 0; | ||||
| + | ||||
| +	if (multi_ap_backhaul_network_key != NULL) { | ||||
| +		reg->multi_ap_backhaul_network_key = | ||||
| +			os_memdup(multi_ap_backhaul_network_key, | ||||
| +				  multi_ap_backhaul_network_key_len); | ||||
| +		if (reg->multi_ap_backhaul_network_key == NULL) | ||||
| +			return -1; | ||||
| +		reg->multi_ap_backhaul_network_key_len = | ||||
| +			multi_ap_backhaul_network_key_len; | ||||
| +	} | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
|  #ifdef CONFIG_WPS_NFC | ||||
|   | ||||
|  int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg, | ||||
| --  | ||||
| 2.29.2 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user