From 4de3c3c4a9a978dcfec233275719dbc328aef241 Mon Sep 17 00:00:00 2001 From: Niraj Kumar Goit Date: Tue, 29 Dec 2020 01:37:12 +0530 Subject: [PATCH] On device reboot enable wpa-supplicant for EAPoL. In case of device reboot enable wpa-supplicant for eapol connection if last connection was EAP over ethernet. Change-Id: Ia264accac74ecffdba6c2b116807e45f675ef3db Signed-off-by: Niraj Kumar Goit --- packaging/connman.spec | 2 +- plugins/ethernet.c | 177 +++++++++++++++++++++++++++++++++++++++---------- src/connman.h | 1 + src/service.c | 11 +++ 4 files changed, 155 insertions(+), 36 deletions(-) diff --git a/packaging/connman.spec b/packaging/connman.spec index ccba7fb..f1a29fa 100644 --- a/packaging/connman.spec +++ b/packaging/connman.spec @@ -6,7 +6,7 @@ Name: connman Version: 1.38 -Release: 2 +Release: 3 License: GPL-2.0+ Summary: Connection Manager Url: http://connman.net diff --git a/plugins/ethernet.c b/plugins/ethernet.c index ad2ab6e..3bf80a5 100644 --- a/plugins/ethernet.c +++ b/plugins/ethernet.c @@ -151,19 +151,28 @@ static void eth_network_remove(struct connman_network *network) } #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET -static struct connman_network *g_network = NULL; +#define NETCONFIG_SERVICE "net.netconfig" +#define NETCONFIG_ETHERNET_INTERFACE NETCONFIG_SERVICE ".ethernet" +#define NETCONFIG_ETHERNET_PATH "/net/netconfig/ethernet" + +struct eapol_method_call_data { + DBusConnection *connection; + struct connman_network *network; +}; + +static struct eapol_method_call_data enable_eapol_data; void handle_eap_signal(GSupplicantInterface *interface, bool status) { DBG("captured EAP signal"); - if (!g_network) + if (!enable_eapol_data.network) return; if (g_strcmp0("wired", g_supplicant_interface_get_driver(interface))) return; - if (!connman_network_check_validity(g_network)) + if (!connman_network_check_validity(enable_eapol_data.network)) return; DBG("network is valid"); @@ -179,13 +188,13 @@ void handle_eap_signal(GSupplicantInterface *interface, bool status) ethernet->interface = NULL; } - connman_network_set_error(g_network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - g_network = NULL; + connman_network_set_error(enable_eapol_data.network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); + enable_eapol_data.network = NULL; return; } - connman_network_set_connected(g_network, status); - g_network = NULL; + connman_network_set_connected(enable_eapol_data.network, status); + enable_eapol_data.network = NULL; } static void interface_create_callback(int result, @@ -204,43 +213,141 @@ static void interface_create_callback(int result, g_supplicant_interface_set_data(interface, ethernet); } -static int eth_network_connect(struct connman_network *network) +static int eapol_interface_create(void) { - DBG("network %p", network); - + struct connman_network *network = enable_eapol_data.network; struct connman_service *service = connman_service_lookup_from_network(network); - if (service && __connman_service_get_use_eapol(service)) { - struct connman_device *device = connman_network_get_device(network); - struct ethernet_data *ethernet = connman_device_get_data(device); - const char *driver = "wired"; - int index = connman_network_get_index(network); - char *ifname = connman_inet_ifname(index);; - char *config_file = NULL; + if (!service) { + DBG("service not found"); + return -1; + } - g_supplicant_register_eap_callback(handle_eap_signal); - g_network = network; + struct connman_device *device = connman_network_get_device(network); + struct ethernet_data *ethernet = connman_device_get_data(device); + const char *driver = "wired"; + int index = connman_network_get_index(network); + char *ifname = connman_inet_ifname(index);; + char *config_file = NULL; - if (asprintf(&config_file, "/var/lib/connman/%s-eapol.conf", ifname) < 0) { - g_free(ifname); - return -ENOMEM; - } + g_supplicant_register_eap_callback(handle_eap_signal); + + if (asprintf(&config_file, "/var/lib/connman/%s-eapol.conf", ifname) < 0) { + g_free(ifname); + return -ENOMEM; + } - DBG("config_file %s", config_file); + DBG("config_file %s", config_file); - g_supplicant_replace_config_file(ifname, config_file); - free(config_file); + g_supplicant_replace_config_file(ifname, config_file); + free(config_file); - /* - * TODO: RemoveInterface if already present because - * already created interface will not start EAP handshake. - */ - g_supplicant_interface_create(ifname, driver, NULL, - interface_create_callback, ethernet); + /* + * TODO: RemoveInterface if already present because + * already created interface will not start EAP handshake. + */ + return g_supplicant_interface_create(ifname, driver, NULL, + interface_create_callback, ethernet); +} - g_free(ifname); +static void enable_eapol_reply(DBusPendingCall *call, void *user_data) +{ + DBusMessage *reply; + DBusError error; + DBusMessageIter args; - return 0; + DBG(""); + + reply = dbus_pending_call_steal_reply(call); + + dbus_error_init(&error); + if (dbus_set_error_from_message(&error, reply)) { + DBG("enable_eapol_request() %s %s", error.name, error.message); + dbus_error_free(&error); + dbus_message_unref(reply); + dbus_pending_call_unref(call); + dbus_connection_unref(enable_eapol_data.connection); + + enable_eapol_data.connection = NULL; + return; + } + + if (eapol_interface_create() < 0) + DBG("Failed to create eapol interface"); +} + +static int eth_network_enable_eapol(struct connman_service *service, struct connman_network *network) +{ + DBusMessage *msg = NULL; + DBusPendingCall *call; + + DBusConnection *connection = connman_dbus_get_connection(); + if (!connection) { + DBG("dbus connection does not exist"); + return -EINVAL; + } + + msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_ETHERNET_PATH, + NETCONFIG_ETHERNET_INTERFACE, "EnableEap"); + if (!msg) { + dbus_connection_unref(connection); + return -EINVAL; + } + + const char *path = __connman_service_get_path(service); + dbus_bool_t enable = true; + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &enable, + DBUS_TYPE_INVALID); + + if (!dbus_connection_send_with_reply(connection, msg, + &call, DBUS_TIMEOUT_USE_DEFAULT)) { + dbus_message_unref(msg); + dbus_connection_unref(connection); + return -EIO; + } + + if (!call) { + dbus_message_unref(msg); + dbus_connection_unref(connection); + return -EIO; + } + + enable_eapol_data.connection = connection; + enable_eapol_data.network = network; + + dbus_pending_call_set_notify(call, enable_eapol_reply, NULL, NULL); + dbus_message_unref(msg); + + return 0; +} + +static int eth_network_connect(struct connman_network *network) +{ + DBG("network %p", network); + + int err = 0; + struct connman_service *service = connman_service_lookup_from_network(network); + + if (service && __connman_service_get_use_eapol(service)) { + /** Enable eapol on device reboot **/ + if (__connman_service_get_connect_reason(service) != CONNMAN_SERVICE_CONNECT_REASON_USER) { + err = eth_network_enable_eapol(service, network); + if (err < 0) { + DBG("Failed to enable eapol"); + return err; + } + } else { + err = eapol_interface_create(); + if (err < 0) { + DBG("Failed to create eapol interface"); + return err; + } + + return 0; + } } connman_network_set_connected(network, true); @@ -258,7 +365,7 @@ static int eth_network_disconnect(struct connman_network *network) struct connman_device *device = connman_network_get_device(network); struct ethernet_data *ethernet = connman_device_get_data(device); - g_network = NULL; + enable_eapol_data.network = NULL; g_supplicant_unregister_eap_callback(); if (ethernet && ethernet->interface) { g_supplicant_interface_remove(ethernet->interface, NULL, NULL); diff --git a/src/connman.h b/src/connman.h index 4080ece..f4a2f44 100755 --- a/src/connman.h +++ b/src/connman.h @@ -828,6 +828,7 @@ void __connman_service_set_auto_connect_mode(bool enable); #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET int __connman_service_get_use_eapol(struct connman_service *service); +int __connman_service_get_connect_reason(struct connman_service *service); #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ bool __connman_service_remove(struct connman_service *service); diff --git a/src/service.c b/src/service.c index c7088d2..55bb5f6 100755 --- a/src/service.c +++ b/src/service.c @@ -5414,6 +5414,16 @@ int __connman_service_get_use_eapol(struct connman_service *service) return service->use_eapol; } + +int __connman_service_get_connect_reason(struct connman_service *service) +{ + if (!service) { + DBG("Service is NULL"); + return -1; + } + + return service->connect_reason; +} #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ static DBusMessage *get_properties(DBusConnection *conn, @@ -6164,6 +6174,7 @@ static DBusMessage *set_property(DBusConnection *conn, if (err < 0) return __connman_error_failed(msg, -err); + service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER; service_save(service); #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ } else -- 2.7.4