On device reboot enable wpa-supplicant for EAPoL. 11/250511/3 submit/tizen/20210126.062930
authorNiraj Kumar Goit <niraj.g@samsung.com>
Mon, 28 Dec 2020 20:07:12 +0000 (01:37 +0530)
committerNiraj Kumar Goit <niraj.g@samsung.com>
Mon, 25 Jan 2021 08:08:01 +0000 (13:38 +0530)
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 <niraj.g@samsung.com>
packaging/connman.spec
plugins/ethernet.c
src/connman.h
src/service.c

index ccba7fb..f1a29fa 100644 (file)
@@ -6,7 +6,7 @@
 
 Name:           connman
 Version:        1.38
-Release:        2
+Release:        3
 License:        GPL-2.0+
 Summary:        Connection Manager
 Url:            http://connman.net
index ad2ab6e..3bf80a5 100644 (file)
@@ -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);
index 4080ece..f4a2f44 100755 (executable)
@@ -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);
index c7088d2..55bb5f6 100755 (executable)
@@ -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