mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-28 10:18:21 -05:00
Allow PSK/passphrase to be set only when needed
The new network profile parameter mem_only_psk=1 can be used to specify that the PSK/passphrase for that network is requested over the control interface (ctrl_iface or D-Bus) similarly to the EAP network parameter requests. The PSK/passphrase can then be configured temporarily in a way that prevents it from getting stored to the configuration file. For example: Event: CTRL-REQ-PSK_PASSPHRASE-0:PSK or passphrase needed for SSID test-wpa2-psk Response: CTRL-RSP-PSK_PASSPHRASE-0:"qwertyuiop" Note: The response value uses the same encoding as the psk network profile parameter, i.e., passphrase is within double quotation marks. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
b898a6ee72
commit
a52410c29f
@ -310,6 +310,7 @@ enum wpa_ctrl_req_type {
|
|||||||
WPA_CTRL_REQ_EAP_OTP,
|
WPA_CTRL_REQ_EAP_OTP,
|
||||||
WPA_CTRL_REQ_EAP_PASSPHRASE,
|
WPA_CTRL_REQ_EAP_PASSPHRASE,
|
||||||
WPA_CTRL_REQ_SIM,
|
WPA_CTRL_REQ_SIM,
|
||||||
|
WPA_CTRL_REQ_PSK_PASSPHRASE,
|
||||||
NUM_WPA_CTRL_REQS
|
NUM_WPA_CTRL_REQS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1816,6 +1816,7 @@ static const struct parse_data ssid_fields[] = {
|
|||||||
{ FUNC(bssid_blacklist) },
|
{ FUNC(bssid_blacklist) },
|
||||||
{ FUNC(bssid_whitelist) },
|
{ FUNC(bssid_whitelist) },
|
||||||
{ FUNC_KEY(psk) },
|
{ FUNC_KEY(psk) },
|
||||||
|
{ INT(mem_only_psk) },
|
||||||
{ FUNC(proto) },
|
{ FUNC(proto) },
|
||||||
{ FUNC(key_mgmt) },
|
{ FUNC(key_mgmt) },
|
||||||
{ INT(bg_scan_period) },
|
{ INT(bg_scan_period) },
|
||||||
|
@ -501,7 +501,12 @@ static void write_bssid(FILE *f, struct wpa_ssid *ssid)
|
|||||||
|
|
||||||
static void write_psk(FILE *f, struct wpa_ssid *ssid)
|
static void write_psk(FILE *f, struct wpa_ssid *ssid)
|
||||||
{
|
{
|
||||||
char *value = wpa_config_get(ssid, "psk");
|
char *value;
|
||||||
|
|
||||||
|
if (ssid->mem_only_psk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
value = wpa_config_get(ssid, "psk");
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
return;
|
return;
|
||||||
fprintf(f, "\tpsk=%s\n", value);
|
fprintf(f, "\tpsk=%s\n", value);
|
||||||
@ -673,6 +678,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
|
|||||||
write_str(f, "bssid_blacklist", ssid);
|
write_str(f, "bssid_blacklist", ssid);
|
||||||
write_str(f, "bssid_whitelist", ssid);
|
write_str(f, "bssid_whitelist", ssid);
|
||||||
write_psk(f, ssid);
|
write_psk(f, ssid);
|
||||||
|
INT(mem_only_psk);
|
||||||
write_proto(f, ssid);
|
write_proto(f, ssid);
|
||||||
write_key_mgmt(f, ssid);
|
write_key_mgmt(f, ssid);
|
||||||
INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD);
|
INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD);
|
||||||
|
@ -180,6 +180,14 @@ struct wpa_ssid {
|
|||||||
*/
|
*/
|
||||||
char *ext_psk;
|
char *ext_psk;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mem_only_psk - Whether to keep PSK/passphrase only in memory
|
||||||
|
*
|
||||||
|
* 0 = allow psk/passphrase to be stored to the configuration file
|
||||||
|
* 1 = do not store psk/passphrase to the configuration file
|
||||||
|
*/
|
||||||
|
int mem_only_psk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pairwise_cipher - Bitfield of allowed pairwise ciphers, WPA_CIPHER_*
|
* pairwise_cipher - Bitfield of allowed pairwise ciphers, WPA_CIPHER_*
|
||||||
*/
|
*/
|
||||||
|
@ -1085,14 +1085,13 @@ struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
|
|||||||
struct wpa_bss *selected = NULL;
|
struct wpa_bss *selected = NULL;
|
||||||
int prio;
|
int prio;
|
||||||
struct wpa_ssid *next_ssid = NULL;
|
struct wpa_ssid *next_ssid = NULL;
|
||||||
|
struct wpa_ssid *ssid;
|
||||||
|
|
||||||
if (wpa_s->last_scan_res == NULL ||
|
if (wpa_s->last_scan_res == NULL ||
|
||||||
wpa_s->last_scan_res_used == 0)
|
wpa_s->last_scan_res_used == 0)
|
||||||
return NULL; /* no scan results from last update */
|
return NULL; /* no scan results from last update */
|
||||||
|
|
||||||
if (wpa_s->next_ssid) {
|
if (wpa_s->next_ssid) {
|
||||||
struct wpa_ssid *ssid;
|
|
||||||
|
|
||||||
/* check that next_ssid is still valid */
|
/* check that next_ssid is still valid */
|
||||||
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
|
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
|
||||||
if (ssid == wpa_s->next_ssid)
|
if (ssid == wpa_s->next_ssid)
|
||||||
@ -1128,6 +1127,27 @@ struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssid = *selected_ssid;
|
||||||
|
if (selected && ssid && ssid->mem_only_psk && !ssid->psk_set &&
|
||||||
|
!ssid->passphrase && !ssid->ext_psk) {
|
||||||
|
const char *field_name, *txt = NULL;
|
||||||
|
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||||
|
"PSK/passphrase not yet available for the selected network");
|
||||||
|
|
||||||
|
wpas_notify_network_request(wpa_s, ssid,
|
||||||
|
WPA_CTRL_REQ_PSK_PASSPHRASE, NULL);
|
||||||
|
|
||||||
|
field_name = wpa_supplicant_ctrl_req_to_string(
|
||||||
|
WPA_CTRL_REQ_PSK_PASSPHRASE, NULL, &txt);
|
||||||
|
if (field_name == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
wpas_send_ctrl_req(wpa_s, ssid, field_name, txt);
|
||||||
|
|
||||||
|
selected = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1239,7 +1239,12 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
|
if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
|
||||||
|
int psk_set = 0;
|
||||||
|
|
||||||
|
if (ssid->psk_set) {
|
||||||
wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL);
|
wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL);
|
||||||
|
psk_set = 1;
|
||||||
|
}
|
||||||
#ifndef CONFIG_NO_PBKDF2
|
#ifndef CONFIG_NO_PBKDF2
|
||||||
if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
|
if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
|
||||||
ssid->passphrase) {
|
ssid->passphrase) {
|
||||||
@ -1249,6 +1254,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
|
|||||||
wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
|
wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
|
||||||
psk, PMK_LEN);
|
psk, PMK_LEN);
|
||||||
wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
|
wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
|
||||||
|
psk_set = 1;
|
||||||
os_memset(psk, 0, sizeof(psk));
|
os_memset(psk, 0, sizeof(psk));
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NO_PBKDF2 */
|
#endif /* CONFIG_NO_PBKDF2 */
|
||||||
@ -1286,6 +1292,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
|
|||||||
"external passphrase)",
|
"external passphrase)",
|
||||||
psk, PMK_LEN);
|
psk, PMK_LEN);
|
||||||
wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
|
wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
|
||||||
|
psk_set = 1;
|
||||||
os_memset(psk, 0, sizeof(psk));
|
os_memset(psk, 0, sizeof(psk));
|
||||||
} else
|
} else
|
||||||
#endif /* CONFIG_NO_PBKDF2 */
|
#endif /* CONFIG_NO_PBKDF2 */
|
||||||
@ -1298,6 +1305,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
|
wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
|
||||||
|
psk_set = 1;
|
||||||
os_memset(psk, 0, sizeof(psk));
|
os_memset(psk, 0, sizeof(psk));
|
||||||
} else {
|
} else {
|
||||||
wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
|
wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
|
||||||
@ -1311,6 +1319,12 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
|
|||||||
ext_password_free(pw);
|
ext_password_free(pw);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_EXT_PASSWORD */
|
#endif /* CONFIG_EXT_PASSWORD */
|
||||||
|
|
||||||
|
if (!psk_set) {
|
||||||
|
wpa_msg(wpa_s, MSG_INFO,
|
||||||
|
"No PSK available for association");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
|
wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
|
||||||
|
|
||||||
@ -4967,6 +4981,15 @@ int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
|
|||||||
str_clear_free(eap->external_sim_resp);
|
str_clear_free(eap->external_sim_resp);
|
||||||
eap->external_sim_resp = os_strdup(value);
|
eap->external_sim_resp = os_strdup(value);
|
||||||
break;
|
break;
|
||||||
|
case WPA_CTRL_REQ_PSK_PASSPHRASE:
|
||||||
|
if (wpa_config_set(ssid, "psk", value, 0) < 0)
|
||||||
|
return -1;
|
||||||
|
ssid->mem_only_psk = 1;
|
||||||
|
if (ssid->passphrase)
|
||||||
|
wpa_config_update_psk(ssid);
|
||||||
|
if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning)
|
||||||
|
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
|
||||||
return -1;
|
return -1;
|
||||||
@ -5014,7 +5037,8 @@ int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
|
if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
|
||||||
(!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk)
|
(!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk &&
|
||||||
|
!ssid->mem_only_psk)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -740,6 +740,11 @@ fast_reauth=1
|
|||||||
# startup and reconfiguration time can be optimized by generating the PSK only
|
# startup and reconfiguration time can be optimized by generating the PSK only
|
||||||
# only when the passphrase or SSID has actually changed.
|
# only when the passphrase or SSID has actually changed.
|
||||||
#
|
#
|
||||||
|
# mem_only_psk: Whether to keep PSK/passphrase only in memory
|
||||||
|
# 0 = allow psk/passphrase to be stored to the configuration file
|
||||||
|
# 1 = do not store psk/passphrase to the configuration file
|
||||||
|
#mem_only_psk=0
|
||||||
|
#
|
||||||
# eapol_flags: IEEE 802.1X/EAPOL options (bit field)
|
# eapol_flags: IEEE 802.1X/EAPOL options (bit field)
|
||||||
# Dynamic WEP key required for non-WPA mode
|
# Dynamic WEP key required for non-WPA mode
|
||||||
# bit0 (1): require dynamically generated unicast WEP key
|
# bit0 (1): require dynamically generated unicast WEP key
|
||||||
|
@ -737,6 +737,8 @@ enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
|
|||||||
return WPA_CTRL_REQ_EAP_PASSPHRASE;
|
return WPA_CTRL_REQ_EAP_PASSPHRASE;
|
||||||
else if (os_strcmp(field, "SIM") == 0)
|
else if (os_strcmp(field, "SIM") == 0)
|
||||||
return WPA_CTRL_REQ_SIM;
|
return WPA_CTRL_REQ_SIM;
|
||||||
|
else if (os_strcmp(field, "PSK_PASSPHRASE") == 0)
|
||||||
|
return WPA_CTRL_REQ_PSK_PASSPHRASE;
|
||||||
return WPA_CTRL_REQ_UNKNOWN;
|
return WPA_CTRL_REQ_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,6 +778,10 @@ const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
|
|||||||
case WPA_CTRL_REQ_SIM:
|
case WPA_CTRL_REQ_SIM:
|
||||||
ret = "SIM";
|
ret = "SIM";
|
||||||
break;
|
break;
|
||||||
|
case WPA_CTRL_REQ_PSK_PASSPHRASE:
|
||||||
|
*txt = "PSK or passphrase";
|
||||||
|
ret = "PSK_PASSPHRASE";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -789,6 +795,35 @@ const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wpas_send_ctrl_req(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
|
||||||
|
const char *field_name, const char *txt)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
size_t buflen;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
buflen = 100 + os_strlen(txt) + ssid->ssid_len;
|
||||||
|
buf = os_malloc(buflen);
|
||||||
|
if (buf == NULL)
|
||||||
|
return;
|
||||||
|
len = os_snprintf(buf, buflen, "%s-%d:%s needed for SSID ",
|
||||||
|
field_name, ssid->id, txt);
|
||||||
|
if (os_snprintf_error(buflen, len)) {
|
||||||
|
os_free(buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ssid->ssid && buflen > len + ssid->ssid_len) {
|
||||||
|
os_memcpy(buf + len, ssid->ssid, ssid->ssid_len);
|
||||||
|
len += ssid->ssid_len;
|
||||||
|
buf[len] = '\0';
|
||||||
|
}
|
||||||
|
buf[buflen - 1] = '\0';
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, WPA_CTRL_REQ "%s", buf);
|
||||||
|
os_free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef IEEE8021X_EAPOL
|
#ifdef IEEE8021X_EAPOL
|
||||||
#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
|
#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
|
||||||
static void wpa_supplicant_eap_param_needed(void *ctx,
|
static void wpa_supplicant_eap_param_needed(void *ctx,
|
||||||
@ -798,9 +833,6 @@ static void wpa_supplicant_eap_param_needed(void *ctx,
|
|||||||
struct wpa_supplicant *wpa_s = ctx;
|
struct wpa_supplicant *wpa_s = ctx;
|
||||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||||
const char *field_name, *txt = NULL;
|
const char *field_name, *txt = NULL;
|
||||||
char *buf;
|
|
||||||
size_t buflen;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if (ssid == NULL)
|
if (ssid == NULL)
|
||||||
return;
|
return;
|
||||||
@ -817,25 +849,7 @@ static void wpa_supplicant_eap_param_needed(void *ctx,
|
|||||||
|
|
||||||
wpas_notify_eap_status(wpa_s, "eap parameter needed", field_name);
|
wpas_notify_eap_status(wpa_s, "eap parameter needed", field_name);
|
||||||
|
|
||||||
buflen = 100 + os_strlen(txt) + ssid->ssid_len;
|
wpas_send_ctrl_req(wpa_s, ssid, field_name, txt);
|
||||||
buf = os_malloc(buflen);
|
|
||||||
if (buf == NULL)
|
|
||||||
return;
|
|
||||||
len = os_snprintf(buf, buflen,
|
|
||||||
WPA_CTRL_REQ "%s-%d:%s needed for SSID ",
|
|
||||||
field_name, ssid->id, txt);
|
|
||||||
if (os_snprintf_error(buflen, len)) {
|
|
||||||
os_free(buf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (ssid->ssid && buflen > len + ssid->ssid_len) {
|
|
||||||
os_memcpy(buf + len, ssid->ssid, ssid->ssid_len);
|
|
||||||
len += ssid->ssid_len;
|
|
||||||
buf[len] = '\0';
|
|
||||||
}
|
|
||||||
buf[buflen - 1] = '\0';
|
|
||||||
wpa_msg(wpa_s, MSG_INFO, "%s", buf);
|
|
||||||
os_free(buf);
|
|
||||||
}
|
}
|
||||||
#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
|
#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
|
||||||
#define wpa_supplicant_eap_param_needed NULL
|
#define wpa_supplicant_eap_param_needed NULL
|
||||||
|
@ -22,4 +22,7 @@ const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
|
|||||||
|
|
||||||
enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field);
|
enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field);
|
||||||
|
|
||||||
|
void wpas_send_ctrl_req(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
|
||||||
|
const char *field_name, const char *txt);
|
||||||
|
|
||||||
#endif /* WPAS_GLUE_H */
|
#endif /* WPAS_GLUE_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user