mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +01:00
network: Store Transition Disable info
This indication can come in via EAPoL message 3 or during FILS Association. It carries information as to whether certain transition mode options should be disabled. See WPA3 Specification, version 3 for more details.
This commit is contained in:
parent
8cfe038d67
commit
47ba837e98
@ -54,6 +54,7 @@ enum handshake_event {
|
|||||||
HANDSHAKE_EVENT_FAILED,
|
HANDSHAKE_EVENT_FAILED,
|
||||||
HANDSHAKE_EVENT_REKEY_FAILED,
|
HANDSHAKE_EVENT_REKEY_FAILED,
|
||||||
HANDSHAKE_EVENT_EAP_NOTIFY,
|
HANDSHAKE_EVENT_EAP_NOTIFY,
|
||||||
|
HANDSHAKE_EVENT_TRANSITION_DISABLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*handshake_event_func_t)(struct handshake_state *hs,
|
typedef void (*handshake_event_func_t)(struct handshake_state *hs,
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#define NET_AUTOCONNECT SETTINGS, "AutoConnect"
|
#define NET_AUTOCONNECT SETTINGS, "AutoConnect"
|
||||||
#define NET_ALWAYS_RANDOMIZE_ADDRESS SETTINGS, "AlwaysRandomizeAddress"
|
#define NET_ALWAYS_RANDOMIZE_ADDRESS SETTINGS, "AlwaysRandomizeAddress"
|
||||||
#define NET_ADDRESS_OVERRIDE SETTINGS, "AddressOverride"
|
#define NET_ADDRESS_OVERRIDE SETTINGS, "AddressOverride"
|
||||||
|
#define NET_TRANSITION_DISABLE SETTINGS, "TransitionDisable"
|
||||||
|
#define NET_TRANSITION_DISABLE_MODES SETTINGS, "DisabledTransitionModes"
|
||||||
|
|
||||||
enum security;
|
enum security;
|
||||||
struct scan_freq_set;
|
struct scan_freq_set;
|
||||||
@ -67,6 +69,8 @@ struct network_config {
|
|||||||
bool override_addr:1;
|
bool override_addr:1;
|
||||||
bool always_random_addr:1;
|
bool always_random_addr:1;
|
||||||
uint8_t sta_addr[6];
|
uint8_t sta_addr[6];
|
||||||
|
bool have_transition_disable : 1;
|
||||||
|
uint8_t transition_disable;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct network_info {
|
struct network_info {
|
||||||
|
@ -83,6 +83,8 @@ struct network {
|
|||||||
bool ask_passphrase:1; /* Whether we should force-ask agent */
|
bool ask_passphrase:1; /* Whether we should force-ask agent */
|
||||||
bool is_hs20:1;
|
bool is_hs20:1;
|
||||||
bool anqp_pending:1; /* Set if there is a pending ANQP request */
|
bool anqp_pending:1; /* Set if there is a pending ANQP request */
|
||||||
|
uint8_t transition_disable; /* Temporary cache until info is set */
|
||||||
|
bool have_transition_disable:1;
|
||||||
int rank;
|
int rank;
|
||||||
/* Holds DBus Connect() message if it comes in before ANQP finishes */
|
/* Holds DBus Connect() message if it comes in before ANQP finishes */
|
||||||
struct l_dbus_message *connect_after_anqp;
|
struct l_dbus_message *connect_after_anqp;
|
||||||
@ -353,6 +355,29 @@ bool network_set_psk(struct network *network, const uint8_t *psk)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int network_set_transition_disable(struct network *network,
|
||||||
|
const uint8_t *td, size_t len)
|
||||||
|
{
|
||||||
|
struct network_info *info = network->info;
|
||||||
|
/* We only recognize bits 0, 2, 3 */
|
||||||
|
uint8_t supported_bitmask = 0x0d;
|
||||||
|
|
||||||
|
if (len < 1)
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
network->have_transition_disable = true;
|
||||||
|
network->transition_disable = td[0] & supported_bitmask;
|
||||||
|
|
||||||
|
if (info && info->config.have_transition_disable &&
|
||||||
|
info->config.transition_disable ==
|
||||||
|
network->transition_disable)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
network->sync_settings = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int network_get_signal_strength(const struct network *network)
|
int network_get_signal_strength(const struct network *network)
|
||||||
{
|
{
|
||||||
struct scan_bss *best_bss = l_queue_peek_head(network->bss_list);
|
struct scan_bss *best_bss = l_queue_peek_head(network->bss_list);
|
||||||
@ -608,26 +633,35 @@ static void network_settings_save_sae_pt_ecc(struct l_settings *settings,
|
|||||||
l_settings_set_bytes(settings, "Security", key, buf, len);
|
l_settings_set_bytes(settings, "Security", key, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_sync_settings(struct network *network)
|
static void network_settings_save(struct network *network,
|
||||||
|
struct l_settings *settings)
|
||||||
{
|
{
|
||||||
struct l_settings *settings = network->settings;
|
if (network->have_transition_disable) {
|
||||||
struct l_settings *fs_settings;
|
char *modes[4];
|
||||||
const char *ssid = network_get_ssid(network);
|
unsigned int i = 0;
|
||||||
|
|
||||||
if (!network->sync_settings)
|
l_settings_set_bool(settings, NET_TRANSITION_DISABLE, true);
|
||||||
|
|
||||||
|
if (test_bit(&network->transition_disable, 0))
|
||||||
|
modes[i++] = "personal";
|
||||||
|
|
||||||
|
if (test_bit(&network->transition_disable, 2))
|
||||||
|
modes[i++] = "enterprise";
|
||||||
|
|
||||||
|
if (test_bit(&network->transition_disable, 3))
|
||||||
|
modes[i++] = "open";
|
||||||
|
|
||||||
|
modes[i] = NULL;
|
||||||
|
|
||||||
|
l_settings_set_string_list(settings,
|
||||||
|
NET_TRANSITION_DISABLE_MODES,
|
||||||
|
modes, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (network->security != SECURITY_PSK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
network->sync_settings = false;
|
/* We only update the [Security] bits here, wipe the group first */
|
||||||
|
|
||||||
/*
|
|
||||||
* Re-open the settings from Disk, in case they were updated
|
|
||||||
* since we last opened them. We only update the [Security]
|
|
||||||
* bits here
|
|
||||||
*/
|
|
||||||
fs_settings = storage_network_open(SECURITY_PSK, ssid);
|
|
||||||
if (fs_settings)
|
|
||||||
settings = fs_settings;
|
|
||||||
|
|
||||||
l_settings_remove_group(settings, "Security");
|
l_settings_remove_group(settings, "Security");
|
||||||
|
|
||||||
if (network->psk)
|
if (network->psk)
|
||||||
@ -643,11 +677,38 @@ void network_sync_settings(struct network *network)
|
|||||||
|
|
||||||
if (network->sae_pt_20)
|
if (network->sae_pt_20)
|
||||||
network_settings_save_sae_pt_ecc(settings, network->sae_pt_20);
|
network_settings_save_sae_pt_ecc(settings, network->sae_pt_20);
|
||||||
|
}
|
||||||
|
|
||||||
storage_network_sync(SECURITY_PSK, ssid, settings);
|
void network_sync_settings(struct network *network)
|
||||||
|
{
|
||||||
|
struct network_info *info = network->info;
|
||||||
|
|
||||||
if (fs_settings)
|
if (!network->sync_settings)
|
||||||
|
return;
|
||||||
|
|
||||||
|
l_debug("");
|
||||||
|
|
||||||
|
network->sync_settings = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Re-open the settings from Disk, in case they were updated
|
||||||
|
* since we last opened them.
|
||||||
|
*/
|
||||||
|
if (network->info) {
|
||||||
|
struct l_settings *fs_settings = info->ops->open(info);
|
||||||
|
|
||||||
|
if (L_WARN_ON(!fs_settings))
|
||||||
|
return;
|
||||||
|
|
||||||
|
network_settings_save(network, fs_settings);
|
||||||
|
info->ops->sync(info, fs_settings);
|
||||||
l_settings_free(fs_settings);
|
l_settings_free(fs_settings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
network_settings_save(network, network->settings);
|
||||||
|
storage_network_sync(network->security, network->ssid,
|
||||||
|
network->settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct network_info *network_get_info(const struct network *network)
|
const struct network_info *network_get_info(const struct network *network)
|
||||||
|
@ -46,6 +46,9 @@ struct l_settings *network_get_settings(const struct network *network);
|
|||||||
|
|
||||||
bool network_set_psk(struct network *network, const uint8_t *psk);
|
bool network_set_psk(struct network *network, const uint8_t *psk);
|
||||||
|
|
||||||
|
int network_set_transition_disable(struct network *network,
|
||||||
|
const uint8_t *td, size_t len);
|
||||||
|
|
||||||
int network_handshake_setup(struct network *network,
|
int network_handshake_setup(struct network *network,
|
||||||
struct handshake_state *hs);
|
struct handshake_state *hs);
|
||||||
|
|
||||||
|
@ -714,6 +714,14 @@ static void station_handshake_event(struct handshake_state *hs,
|
|||||||
l_warn("Unable to securely rekey on this hw/kernel...");
|
l_warn("Unable to securely rekey on this hw/kernel...");
|
||||||
station_reconnect(station);
|
station_reconnect(station);
|
||||||
break;
|
break;
|
||||||
|
case HANDSHAKE_EVENT_TRANSITION_DISABLE:
|
||||||
|
{
|
||||||
|
const uint8_t *td = va_arg(args, const uint8_t *);
|
||||||
|
size_t len = va_arg(args, size_t);
|
||||||
|
|
||||||
|
network_set_transition_disable(network, td, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case HANDSHAKE_EVENT_COMPLETE:
|
case HANDSHAKE_EVENT_COMPLETE:
|
||||||
case HANDSHAKE_EVENT_SETTING_KEYS_FAILED:
|
case HANDSHAKE_EVENT_SETTING_KEYS_FAILED:
|
||||||
case HANDSHAKE_EVENT_EAP_NOTIFY:
|
case HANDSHAKE_EVENT_EAP_NOTIFY:
|
||||||
|
Loading…
Reference in New Issue
Block a user