diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 492df6cc8..fcd973287 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -128,6 +128,7 @@ struct hostapd_vlan { }; #define PMK_LEN 32 +#define MIN_PASSPHRASE_LEN 8 #define MAX_PASSPHRASE_LEN 63 struct hostapd_sta_wpa_psk_short { struct hostapd_sta_wpa_psk_short *next; diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c index 1ed8e7f47..96091526b 100644 --- a/src/ap/ieee802_11_auth.c +++ b/src/ap/ieee802_11_auth.c @@ -449,20 +449,40 @@ static void decode_tunnel_passwords(struct hostapd_data *hapd, */ if (passphrase == NULL) break; + + /* + * Passphase should be 8..63 chars (to be hashed with SSID) + * or 64 chars hex string (no separate hashing with SSID). + */ + + if (passphraselen < MIN_PASSPHRASE_LEN || + passphraselen > MAX_PASSPHRASE_LEN + 1) + continue; + /* * passphrase does not contain the NULL termination. * Add it here as pbkdf2_sha1() requires it. */ psk = os_zalloc(sizeof(struct hostapd_sta_wpa_psk_short)); if (psk) { - if (passphraselen > MAX_PASSPHRASE_LEN) - passphraselen = MAX_PASSPHRASE_LEN; - os_memcpy(psk->passphrase, passphrase, passphraselen); - psk->is_passphrase = 1; + if ((passphraselen == MAX_PASSPHRASE_LEN + 1) && + (hexstr2bin(passphrase, psk->psk, PMK_LEN) < 0)) { + hostapd_logger(hapd, cache->addr, + HOSTAPD_MODULE_RADIUS, + HOSTAPD_LEVEL_WARNING, + "invalid hex string (%d chars) in Tunnel-Password", + passphraselen); + goto skip; + } else if (passphraselen <= MAX_PASSPHRASE_LEN) { + os_memcpy(psk->passphrase, passphrase, + passphraselen); + psk->is_passphrase = 1; + } psk->next = cache->psk; cache->psk = psk; psk = NULL; } +skip: os_free(psk); os_free(passphrase); }