}
#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");
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,
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,
+ 0, 0, 60, 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);
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);