From ba8f0c64622661f6055b9a78141d0acc8d35e657 Mon Sep 17 00:00:00 2001 From: Henri Bragge Date: Thu, 31 Mar 2011 15:49:32 +0300 Subject: [PATCH] agent: Implement EAP identity and passphrase query EAP credentials will be queried whenever connecting to an 802.1X network unless EAP-TLS is used OR if service is provisioned via .config file. Besides adding Identity field into the API, this patch also removes the restriction to receive value for only one field per response. Now both Identity and Passphrase can be received in one call. --- src/agent.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- src/connman.h | 3 ++- src/service.c | 21 +++++++++++++++++++-- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/agent.c b/src/agent.c index 9d42ad1..3a8674e 100644 --- a/src/agent.c +++ b/src/agent.c @@ -95,6 +95,7 @@ static void request_input_passphrase_reply(DBusPendingCall *call, void *user_dat { struct request_input_reply *passphrase_reply = user_data; connman_bool_t wps = FALSE; + char *identity = NULL; char *passphrase = NULL; char *wpspin = NULL; char *key; @@ -114,13 +115,22 @@ static void request_input_passphrase_reply(DBusPendingCall *call, void *user_dat break; dbus_message_iter_get_basic(&entry, &key); - if (g_str_equal(key, "Passphrase")) { + + if (g_str_equal(key, "Identity")) { + dbus_message_iter_next(&entry); + if (dbus_message_iter_get_arg_type(&entry) + != DBUS_TYPE_VARIANT) + break; + dbus_message_iter_recurse(&entry, &value); + dbus_message_iter_get_basic(&value, &identity); + + } else if (g_str_equal(key, "Passphrase")) { dbus_message_iter_next(&entry); if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) break; dbus_message_iter_recurse(&entry, &value); dbus_message_iter_get_basic(&value, &passphrase); - break; + } else if (g_str_equal(key, "WPS")) { wps = TRUE; @@ -154,7 +164,7 @@ static void request_input_passphrase_reply(DBusPendingCall *call, void *user_dat } done: - passphrase_reply->callback(passphrase_reply->service, + passphrase_reply->callback(passphrase_reply->service, identity, passphrase, passphrase_reply->user_data); connman_service_unref(passphrase_reply->service); dbus_message_unref(reply); @@ -181,11 +191,24 @@ static void request_input_append_alternates(DBusMessageIter *iter, g_strfreev(alternates); } +static void request_input_append_identity(DBusMessageIter *iter, + void *user_data) +{ + char *str = "string"; + + connman_dbus_dict_append_basic(iter, "Type", + DBUS_TYPE_STRING, &str); + str = "Mandatory"; + connman_dbus_dict_append_basic(iter, "Requirement", + DBUS_TYPE_STRING, &str); +} + static void request_input_append_passphrase(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; char *value; + const char *phase2; switch (__connman_service_get_security(service)) { case CONNMAN_SERVICE_SECURITY_WEP: @@ -194,6 +217,17 @@ static void request_input_append_passphrase(DBusMessageIter *iter, case CONNMAN_SERVICE_SECURITY_PSK: value = "psk"; break; + case CONNMAN_SERVICE_SECURITY_8021X: + phase2 = __connman_service_get_phase2(service); + + if (phase2 != NULL && ( + g_str_has_suffix(phase2, "GTC") == TRUE || + g_str_has_suffix(phase2, "OTP") == TRUE)) + value = "response"; + else + value = "passphrase"; + + break; default: value = "string"; break; @@ -249,6 +283,13 @@ int __connman_agent_request_input(struct connman_service *service, DBUS_TYPE_OBJECT_PATH, &path); connman_dbus_dict_open(&iter, &dict); + + if (__connman_service_get_security(service) == + CONNMAN_SERVICE_SECURITY_8021X) { + connman_dbus_dict_append_dict(&dict, "Identity", + request_input_append_identity, service); + } + connman_dbus_dict_append_dict(&dict, "Passphrase", request_input_append_passphrase, service); diff --git a/src/connman.h b/src/connman.h index 6143558..2d152a4 100644 --- a/src/connman.h +++ b/src/connman.h @@ -72,7 +72,8 @@ void __connman_counter_cleanup(void); struct connman_service *service; typedef void (* passphrase_cb_t) (struct connman_service *service, - const char *passphrase, void *user_data); + const char *identity, const char *passphrase, + void *user_data); typedef void (* report_error_cb_t) (struct connman_service *service, gboolean retry, void *user_data); int __connman_agent_request_input(struct connman_service *service, diff --git a/src/service.c b/src/service.c index f00166e..960a58a 100644 --- a/src/service.c +++ b/src/service.c @@ -2748,13 +2748,17 @@ static connman_bool_t get_reconnect_state(struct connman_service *service) } static void request_input_cb (struct connman_service *service, - const char *passphrase, void *user_data) + const char *identity, const char *passphrase, + void *user_data) { DBG ("RequestInput return, %p", service); - if (passphrase == NULL && service->wps == FALSE) + if (identity == NULL && passphrase == NULL && service->wps == FALSE) return; + if (identity != NULL) + __connman_service_set_identity(service, identity); + if (passphrase != NULL) __connman_service_set_passphrase(service, passphrase); @@ -3831,6 +3835,19 @@ static int service_connect(struct connman_service *service) } break; case CONNMAN_SERVICE_SECURITY_8021X: + if (service->eap == NULL) + return -EINVAL; + + /* + * never request credentials if using EAP-TLS + * (EAP-TLS networks need to be fully provisioned) + */ + if (g_str_equal(service->eap, "tls") == TRUE) + break; + + if (service->immutable != TRUE) + return -ENOKEY; + break; } break; -- 2.7.4