Deleting a WiFi PSK passphrase in response to an invalid key error
causes the passphrase disappear from the save file. This results in
a discovered WiFi network with identical SSID and security method
to remove the saved passphrase of the actual network.
Instead of always removing the passphrase, use service error to keep
track of the passphrase validity. Do this by unsetting service error
only when the service enters ready or disconnect states or when the
passphrase is supplied by the agent. In all other states the service
error is not modified and the error is used to detect and invalid key
upon service connection.
Reported by Pasi Sjöholm.
---
src/service.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/src/service.c b/src/service.c
index 3ed98ed..fdec83e 100644
--- a/src/service.c
+++ b/src/service.c
@@ -5308,6 +5308,8 @@ static int service_indicate_state(struct connman_service
*service)
break;
case CONNMAN_SERVICE_STATE_READY:
+ set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
+
if (service->new_service &&
__connman_stats_service_register(service) == 0)
{
/*
@@ -5374,6 +5376,7 @@ static int service_indicate_state(struct connman_service
*service)
break;
case CONNMAN_SERVICE_STATE_DISCONNECT:
+ set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
reply_pending(service, ECONNABORTED);
@@ -5418,9 +5421,6 @@ static int service_indicate_state(struct connman_service
*service)
break;
}
- if (new_state != CONNMAN_SERVICE_STATE_FAILURE)
- set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
-
service_list_sort();
__connman_connection_update_gateway();
@@ -5448,14 +5448,16 @@ int __connman_service_indicate_error(struct
connman_service *service,
if (!service)
return -EINVAL;
+ if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
+ return -EALREADY;
+
set_error(service, error);
/*
* Supplicant does not always return invalid key error for
* WPA-EAP so clear the credentials always.
*/
- if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY ||
- service->security == CONNMAN_SERVICE_SECURITY_8021X)
+ if (service->security == CONNMAN_SERVICE_SECURITY_8021X)
clear_passphrase(service);
__connman_service_set_agent_identity(service, NULL);
@@ -5852,6 +5854,9 @@ static int service_connect(struct connman_service
*service)
case CONNMAN_SERVICE_SECURITY_PSK:
case CONNMAN_SERVICE_SECURITY_WPA:
case CONNMAN_SERVICE_SECURITY_RSN:
+ if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
+ return -ENOKEY;
+
if (!service->passphrase) {
if (!service->network)
return -EOPNOTSUPP;
@@ -5878,9 +5883,10 @@ static int service_connect(struct connman_service
*service)
* missing. Agent provided credentials can be used as
* fallback if needed.
*/
- if ((!service->identity &&
+ if (((!service->identity &&
!service->agent_identity) ||
- !service->passphrase)
+ !service->passphrase) ||
+ service->error ==
CONNMAN_SERVICE_ERROR_INVALID_KEY)
return -ENOKEY;
break;
@@ -5975,16 +5981,15 @@ int __connman_service_connect(struct connman_service
*service,
err = service_connect(service);
service->connect_reason = reason;
- if (err >= 0) {
- set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
+
+ if (err >= 0)
return 0;
- }
if (err == -EINPROGRESS) {
if (service->timeout == 0)
service->timeout = g_timeout_add_seconds(
CONNECT_TIMEOUT, connect_timeout, service);
- set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
+
return -EINPROGRESS;
}
--
2.1.4
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman