network: Rework autoconnect logic
This commit is contained in:
parent
786365e2c7
commit
c25499a118
121
src/network.c
121
src/network.c
|
@ -410,6 +410,29 @@ static bool network_set_8021x_secrets(struct network *network)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int network_load_psk(struct network *network)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
const char *psk = l_settings_get_value(network->settings,
|
||||||
|
"Security", "PreSharedKey");
|
||||||
|
|
||||||
|
if (!psk)
|
||||||
|
return -ENOKEY;
|
||||||
|
|
||||||
|
l_free(network->psk);
|
||||||
|
network->psk = l_util_from_hexstring(psk, &len);
|
||||||
|
if (!network->psk)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (len != 32) {
|
||||||
|
l_free(network->psk);
|
||||||
|
network->psk = NULL;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void network_sync_psk(struct network *network)
|
void network_sync_psk(struct network *network)
|
||||||
{
|
{
|
||||||
char *hex;
|
char *hex;
|
||||||
|
@ -429,16 +452,27 @@ int network_autoconnect(struct network *network, struct scan_bss *bss)
|
||||||
{
|
{
|
||||||
struct wiphy *wiphy = device_get_wiphy(network->device);
|
struct wiphy *wiphy = device_get_wiphy(network->device);
|
||||||
bool is_autoconnectable;
|
bool is_autoconnectable;
|
||||||
|
bool is_rsn;
|
||||||
|
int ret;
|
||||||
|
|
||||||
switch (network_get_security(network)) {
|
switch (network_get_security(network)) {
|
||||||
case SECURITY_NONE:
|
case SECURITY_NONE:
|
||||||
network_settings_load(network);
|
is_rsn = false;
|
||||||
break;
|
break;
|
||||||
case SECURITY_PSK:
|
case SECURITY_PSK:
|
||||||
{
|
if (network->ask_psk)
|
||||||
|
return -ENOKEY;
|
||||||
|
|
||||||
|
/* Fall through */
|
||||||
|
case SECURITY_8021X:
|
||||||
|
is_rsn = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_rsn) {
|
||||||
struct ie_rsn_info rsn;
|
struct ie_rsn_info rsn;
|
||||||
const char *psk;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
memset(&rsn, 0, sizeof(rsn));
|
memset(&rsn, 0, sizeof(rsn));
|
||||||
scan_bss_get_rsn_info(bss, &rsn);
|
scan_bss_get_rsn_info(bss, &rsn);
|
||||||
|
@ -448,65 +482,48 @@ int network_autoconnect(struct network *network, struct scan_bss *bss)
|
||||||
l_debug("Cipher mis-match");
|
l_debug("Cipher mis-match");
|
||||||
return -ENETUNREACH;
|
return -ENETUNREACH;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (network->ask_psk)
|
|
||||||
return -ENOKEY;
|
|
||||||
|
|
||||||
if (!network_settings_load(network))
|
if (!network_settings_load(network))
|
||||||
return -ENOKEY;
|
return -ENOKEY;
|
||||||
|
|
||||||
psk = l_settings_get_value(network->settings, "Security",
|
/* If no entry, default to Autoconnectable=True */
|
||||||
"PreSharedKey");
|
|
||||||
|
|
||||||
if (!psk) {
|
|
||||||
network_settings_close(network);
|
|
||||||
return -ENOKEY;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_free(network->psk);
|
|
||||||
network->psk = l_util_from_hexstring(psk, &len);
|
|
||||||
|
|
||||||
if (network->psk && len != 32) {
|
|
||||||
network_settings_close(network);
|
|
||||||
return -ENOKEY;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SECURITY_8021X:
|
|
||||||
{
|
|
||||||
struct l_queue *missing_secrets = NULL;
|
|
||||||
|
|
||||||
if (!network_settings_load(network))
|
|
||||||
return -ENOKEY;
|
|
||||||
|
|
||||||
if (eap_check_settings(network->settings, network->secrets,
|
|
||||||
"EAP-", true, &missing_secrets) ||
|
|
||||||
!l_queue_isempty(missing_secrets) ||
|
|
||||||
!network_set_8021x_secrets(network)) {
|
|
||||||
l_queue_destroy(missing_secrets, eap_secret_info_free);
|
|
||||||
network_settings_close(network);
|
|
||||||
return -ENOKEY;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!l_settings_get_bool(network->settings, "Settings",
|
if (!l_settings_get_bool(network->settings, "Settings",
|
||||||
"Autoconnect", &is_autoconnectable))
|
"Autoconnect", &is_autoconnectable))
|
||||||
goto connect;
|
is_autoconnectable = true;
|
||||||
|
|
||||||
if (!is_autoconnectable) {
|
ret = -EPERM;
|
||||||
network_settings_close(network);
|
if (!is_autoconnectable)
|
||||||
return -EPERM;
|
goto close_settings;
|
||||||
|
|
||||||
|
if (network_get_security(network) == SECURITY_PSK) {
|
||||||
|
ret = network_load_psk(network);
|
||||||
|
if (ret < 0)
|
||||||
|
goto close_settings;
|
||||||
|
} else if (network_get_security(network) == SECURITY_8021X) {
|
||||||
|
struct l_queue *missing_secrets = NULL;
|
||||||
|
|
||||||
|
ret = eap_check_settings(network->settings, network->secrets,
|
||||||
|
"EAP-", true, &missing_secrets);
|
||||||
|
if (ret < 0)
|
||||||
|
goto close_settings;
|
||||||
|
|
||||||
|
ret = -ENOKEY;
|
||||||
|
if (!l_queue_isempty(missing_secrets)) {
|
||||||
|
l_queue_destroy(missing_secrets, eap_secret_info_free);
|
||||||
|
goto close_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!network_set_8021x_secrets(network))
|
||||||
|
goto close_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect:
|
|
||||||
device_connect_network(network->device, network, bss, NULL);
|
device_connect_network(network->device, network, bss, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
close_settings:
|
||||||
|
network_settings_close(network);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_connect_failed(struct network *network)
|
void network_connect_failed(struct network *network)
|
||||||
|
|
Loading…
Reference in New Issue