X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fagent-connman.c;h=e4850a8f7f0a3c39ab7af3b984bf07aa121e422a;hb=d9c4473ac7a38978f0c8922ddb72849320faab75;hp=9ccba72e0224307013b4902e4dd6d1defb792b36;hpb=2023b90de4066fe2cf28b48bfca58c35c92aab20;p=platform%2Fupstream%2Fconnman.git diff --git a/src/agent-connman.c b/src/agent-connman.c old mode 100644 new mode 100755 index 9ccba72..e4850a8 --- a/src/agent-connman.c +++ b/src/agent-connman.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2012-2013 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -34,7 +34,7 @@ #include "connman.h" -static connman_bool_t check_reply_has_dict(DBusMessage *reply) +static bool check_reply_has_dict(DBusMessage *reply) { const char *signature = DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING @@ -42,8 +42,8 @@ static connman_bool_t check_reply_has_dict(DBusMessage *reply) DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING; - if (dbus_message_has_signature(reply, signature) == TRUE) - return TRUE; + if (dbus_message_has_signature(reply, signature)) + return true; connman_warn("Reply %s to %s from %s has wrong signature %s", signature, @@ -51,20 +51,25 @@ static connman_bool_t check_reply_has_dict(DBusMessage *reply) dbus_message_get_sender(reply), dbus_message_get_signature(reply)); - return FALSE; + return false; } struct request_input_reply { struct connman_service *service; - authentication_cb_t callback; + struct connman_peer *peer; + union { + authentication_cb_t service_callback; + peer_wps_cb_t peer_callback; + }; + bool wps_requested; void *user_data; }; static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) { struct request_input_reply *passphrase_reply = user_data; - connman_bool_t values_received = FALSE; - connman_bool_t wps = FALSE; + bool values_received = false; + bool wps = false; const char *error = NULL; char *identity = NULL; char *passphrase = NULL; @@ -74,15 +79,20 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) int name_len = 0; DBusMessageIter iter, dict; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); goto done; } - if (check_reply_has_dict(reply) == FALSE) + if (!check_reply_has_dict(reply)) goto done; - values_received = TRUE; + values_received = true; dbus_message_iter_init(reply, &iter); dbus_message_iter_recurse(&iter, &dict); @@ -90,68 +100,112 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) DBusMessageIter entry, value; dbus_message_iter_recurse(&dict, &entry); - if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; + } dbus_message_iter_get_basic(&entry, &key); if (g_str_equal(key, "Identity")) { dbus_message_iter_next(&entry); if (dbus_message_iter_get_arg_type(&entry) - != DBUS_TYPE_VARIANT) + != DBUS_TYPE_VARIANT) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; + } + dbus_message_iter_recurse(&entry, &value); + if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; + break; + } + 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) + if (dbus_message_iter_get_arg_type(&entry) + != DBUS_TYPE_VARIANT) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; + } + dbus_message_iter_recurse(&entry, &value); + if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; + break; + } + dbus_message_iter_get_basic(&value, &passphrase); } else if (g_str_equal(key, "WPS")) { - wps = TRUE; dbus_message_iter_next(&entry); if (dbus_message_iter_get_arg_type(&entry) - != DBUS_TYPE_VARIANT) + != DBUS_TYPE_VARIANT) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; + } + dbus_message_iter_recurse(&entry, &value); + if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; + break; + } + + wps = true; dbus_message_iter_get_basic(&value, &wpspin); break; } else if (g_str_equal(key, "Name")) { dbus_message_iter_next(&entry); if (dbus_message_iter_get_arg_type(&entry) - != DBUS_TYPE_VARIANT) + != DBUS_TYPE_VARIANT) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; + } + dbus_message_iter_recurse(&entry, &value); + if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; + break; + } + dbus_message_iter_get_basic(&value, &name); name_len = strlen(name); } else if (g_str_equal(key, "SSID")) { + DBusMessageIter array_iter; + dbus_message_iter_next(&entry); if (dbus_message_iter_get_arg_type(&entry) - != DBUS_TYPE_VARIANT) + != DBUS_TYPE_VARIANT) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; + } dbus_message_iter_recurse(&entry, &value); if (dbus_message_iter_get_arg_type(&value) - != DBUS_TYPE_VARIANT) + != DBUS_TYPE_ARRAY) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; - if (dbus_message_iter_get_element_type(&value) - != DBUS_TYPE_VARIANT) + } + dbus_message_iter_recurse(&value, &array_iter); + if (dbus_message_iter_get_arg_type(&array_iter) + != DBUS_TYPE_BYTE) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; - dbus_message_iter_get_fixed_array(&value, &name, + } + dbus_message_iter_get_fixed_array(&array_iter, &name, &name_len); } dbus_message_iter_next(&dict); } done: - passphrase_reply->callback(passphrase_reply->service, values_received, - name, name_len, - identity, passphrase, - wps, wpspin, error, - passphrase_reply->user_data); + passphrase_reply->service_callback(passphrase_reply->service, + values_received, name, name_len, + identity, passphrase, wps, wpspin, + error, passphrase_reply->user_data); + g_free(passphrase_reply); } @@ -161,14 +215,14 @@ static void request_input_append_alternates(DBusMessageIter *iter, const char *str = user_data; char **alternates, **alternative; - if (str == NULL) + if (!str) return; alternates = g_strsplit(str, ",", 0); - if (alternates == NULL) + if (!alternates) return; - for (alternative = alternates; *alternative != NULL; alternative++) + for (alternative = alternates; *alternative; alternative++) dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, alternative); @@ -199,14 +253,17 @@ static void request_input_append_passphrase(DBusMessageIter *iter, value = "wep"; break; case CONNMAN_SERVICE_SECURITY_PSK: +#if defined TIZEN_EXT + case CONNMAN_SERVICE_SECURITY_RSN: +#endif 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)) + if (phase2 && ( + g_str_has_suffix(phase2, "GTC") || + g_str_has_suffix(phase2, "OTP"))) value = "response"; else value = "passphrase"; @@ -222,7 +279,7 @@ static void request_input_append_passphrase(DBusMessageIter *iter, connman_dbus_dict_append_basic(iter, "Requirement", DBUS_TYPE_STRING, &value); - if (__connman_service_wps_enabled(service) == TRUE) { + if (__connman_service_wps_enabled(service)) { connman_dbus_dict_append_array(iter, "Alternates", DBUS_TYPE_STRING, request_input_append_alternates, @@ -230,13 +287,21 @@ static void request_input_append_passphrase(DBusMessageIter *iter, } } +struct request_wps_data { + bool peer; +}; + static void request_input_append_wps(DBusMessageIter *iter, void *user_data) { + struct request_wps_data *wps = user_data; const char *str = "wpspin"; connman_dbus_dict_append_basic(iter, "Type", DBUS_TYPE_STRING, &str); - str = "alternate"; + if (wps && wps->peer) + str = "mandatory"; + else + str = "alternate"; connman_dbus_dict_append_basic(iter, "Requirement", DBUS_TYPE_STRING, &str); } @@ -310,12 +375,12 @@ static void previous_passphrase_handler(DBusMessageIter *iter, network = __connman_service_get_network(service); data.passphrase = connman_network_get_string(network, "WiFi.PinWPS"); - if (connman_network_get_bool(network, "WiFi.UseWPS") == TRUE && - data.passphrase != NULL) { + if (connman_network_get_bool(network, "WiFi.UseWPS") && + data.passphrase) { data.type = "wpspin"; } else { data.passphrase = __connman_service_get_passphrase(service); - if (data.passphrase == NULL) + if (!data.passphrase) return; security = __connman_service_get_security(service); @@ -324,6 +389,9 @@ static void previous_passphrase_handler(DBusMessageIter *iter, data.type = "wep"; break; case CONNMAN_SERVICE_SECURITY_PSK: +#if defined TIZEN_EXT + case CONNMAN_SERVICE_SECURITY_RSN: +#endif data.type = "psk"; break; /* @@ -342,21 +410,26 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data) { struct request_input_reply *username_password_reply = user_data; const char *error = NULL; - connman_bool_t values_received = FALSE; + bool values_received = false; char *username = NULL; char *password = NULL; char *key; DBusMessageIter iter, dict; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); goto done; } - if (check_reply_has_dict(reply) == FALSE) + if (!check_reply_has_dict(reply)) goto done; - values_received = TRUE; + values_received = true; dbus_message_iter_init(reply, &iter); dbus_message_iter_recurse(&iter, &dict); @@ -372,17 +445,33 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data) if (g_str_equal(key, "Username")) { dbus_message_iter_next(&entry); if (dbus_message_iter_get_arg_type(&entry) - != DBUS_TYPE_VARIANT) + != DBUS_TYPE_VARIANT) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; + } + dbus_message_iter_recurse(&entry, &value); + if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; + break; + } + dbus_message_iter_get_basic(&value, &username); } else if (g_str_equal(key, "Password")) { dbus_message_iter_next(&entry); if (dbus_message_iter_get_arg_type(&entry) != - DBUS_TYPE_VARIANT) + DBUS_TYPE_VARIANT) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; break; + } + dbus_message_iter_recurse(&entry, &value); + if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; + break; + } + dbus_message_iter_get_basic(&value, &password); } @@ -390,16 +479,17 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data) } done: - username_password_reply->callback(username_password_reply->service, - values_received, NULL, 0, - username, password, - FALSE, NULL, error, - username_password_reply->user_data); + username_password_reply->service_callback( + username_password_reply->service, values_received, + NULL, 0, username, password, FALSE, NULL, error, + username_password_reply->user_data); + g_free(username_password_reply); } int __connman_agent_request_passphrase_input(struct connman_service *service, - authentication_cb_t callback, void *user_data) + authentication_cb_t callback, + const char *dbus_sender, void *user_data) { DBusMessage *message; const char *path, *agent_sender, *agent_path; @@ -407,16 +497,20 @@ int __connman_agent_request_passphrase_input(struct connman_service *service, DBusMessageIter dict; struct request_input_reply *passphrase_reply; int err; + void *agent; - connman_agent_get_info(&agent_sender, &agent_path); + agent = connman_agent_get_info(dbus_sender, &agent_sender, + &agent_path); - if (service == NULL || agent_path == NULL || callback == NULL) + DBG("agent %p service %p path %s", agent, service, agent_path); + + if (!service || !agent || !agent_path || !callback) return -ESRCH; message = dbus_message_new_method_call(agent_sender, agent_path, CONNMAN_AGENT_INTERFACE, "RequestInput"); - if (message == NULL) + if (!message) return -ENOMEM; dbus_message_iter_init_append(message, &iter); @@ -443,32 +537,31 @@ int __connman_agent_request_passphrase_input(struct connman_service *service, if (__connman_service_get_security(service) != CONNMAN_SERVICE_SECURITY_NONE) { connman_dbus_dict_append_dict(&dict, "Passphrase", - request_input_append_passphrase, service); + request_input_append_passphrase, service); previous_passphrase_handler(&dict, service); } - if (__connman_service_wps_enabled(service) == TRUE) { - connman_dbus_dict_append_dict(&dict, "WPS", + if (__connman_service_wps_enabled(service)) + connman_dbus_dict_append_dict(&dict, "WPS", request_input_append_wps, NULL); - } connman_dbus_dict_close(&iter, &dict); passphrase_reply = g_try_new0(struct request_input_reply, 1); - if (passphrase_reply == NULL) { + if (!passphrase_reply) { dbus_message_unref(message); return -ENOMEM; } passphrase_reply->service = service; - passphrase_reply->callback = callback; + passphrase_reply->service_callback = callback; passphrase_reply->user_data = user_data; err = connman_agent_queue_message(service, message, connman_timeout_input_request(), request_input_passphrase_reply, - passphrase_reply); + passphrase_reply, agent); if (err < 0 && err != -EBUSY) { DBG("error %d sending agent message", err); @@ -491,16 +584,17 @@ int __connman_agent_request_login_input(struct connman_service *service, DBusMessageIter dict; struct request_input_reply *username_password_reply; int err; + void *agent; - connman_agent_get_info(&agent_sender, &agent_path); + agent = connman_agent_get_info(NULL, &agent_sender, &agent_path); - if (service == NULL || agent_path == NULL || callback == NULL) + if (!service || !agent || !agent_path || !callback) return -ESRCH; message = dbus_message_new_method_call(agent_sender, agent_path, CONNMAN_AGENT_INTERFACE, "RequestInput"); - if (message == NULL) + if (!message) return -ENOMEM; dbus_message_iter_init_append(message, &iter); @@ -520,18 +614,19 @@ int __connman_agent_request_login_input(struct connman_service *service, connman_dbus_dict_close(&iter, &dict); username_password_reply = g_try_new0(struct request_input_reply, 1); - if (username_password_reply == NULL) { + if (!username_password_reply) { dbus_message_unref(message); return -ENOMEM; } username_password_reply->service = service; - username_password_reply->callback = callback; + username_password_reply->service_callback = callback; username_password_reply->user_data = user_data; err = connman_agent_queue_message(service, message, connman_timeout_input_request(), - request_input_login_reply, username_password_reply); + request_input_login_reply, username_password_reply, + agent); if (err < 0 && err != -EBUSY) { DBG("error %d sending agent request", err); dbus_message_unref(message); @@ -553,15 +648,20 @@ struct request_browser_reply_data { static void request_browser_reply(DBusMessage *reply, void *user_data) { struct request_browser_reply_data *browser_reply_data = user_data; - connman_bool_t result = FALSE; + bool result = false; const char *error = NULL; + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { error = dbus_message_get_error_name(reply); goto done; } - result = TRUE; + result = true; done: browser_reply_data->callback(browser_reply_data->service, result, @@ -578,19 +678,20 @@ int __connman_agent_request_browser(struct connman_service *service, DBusMessageIter iter; const char *path, *agent_sender, *agent_path; int err; + void *agent; - connman_agent_get_info(&agent_sender, &agent_path); + agent = connman_agent_get_info(NULL, &agent_sender, &agent_path); - if (service == NULL || agent_path == NULL || callback == NULL) + if (!service || !agent || !agent_path || !callback) return -ESRCH; - if (url == NULL) + if (!url) url = ""; message = dbus_message_new_method_call(agent_sender, agent_path, CONNMAN_AGENT_INTERFACE, "RequestBrowser"); - if (message == NULL) + if (!message) return -ENOMEM; dbus_message_iter_init_append(message, &iter); @@ -601,7 +702,7 @@ int __connman_agent_request_browser(struct connman_service *service, dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &url); browser_reply_data = g_try_new0(struct request_browser_reply_data, 1); - if (browser_reply_data == NULL) { + if (!browser_reply_data) { dbus_message_unref(message); return -ENOMEM; } @@ -612,7 +713,8 @@ int __connman_agent_request_browser(struct connman_service *service, err = connman_agent_queue_message(service, message, connman_timeout_browser_launch(), - request_browser_reply, browser_reply_data); + request_browser_reply, browser_reply_data, + agent); if (err < 0 && err != -EBUSY) { DBG("error %d sending browser request", err); @@ -625,3 +727,147 @@ int __connman_agent_request_browser(struct connman_service *service, return -EINPROGRESS; } + +int __connman_agent_report_peer_error(struct connman_peer *peer, + const char *path, const char *error, + report_error_cb_t callback, + const char *dbus_sender, + void *user_data) +{ + return connman_agent_report_error_full(peer, path, "ReportPeerError", + error, callback, dbus_sender, user_data); +} + +static void request_peer_authorization_reply(DBusMessage *reply, + void *user_data) +{ + struct request_input_reply *auth_reply = user_data; + DBusMessageIter iter, dict; + const char *error = NULL; + bool choice_done = false; + char *wpspin = NULL; + char *key; + + if (!reply) { + error = CONNMAN_ERROR_INTERFACE ".OperationAborted"; + goto done; + } + + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + error = dbus_message_get_error_name(reply); + goto done; + } + + if (!check_reply_has_dict(reply)) + goto done; + + dbus_message_iter_init(reply, &iter); + dbus_message_iter_recurse(&iter, &dict); + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry, value; + + dbus_message_iter_recurse(&dict, &entry); + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; + break; + } + + dbus_message_iter_get_basic(&entry, &key); + + if (g_str_equal(key, "WPS")) { + choice_done = true; + + dbus_message_iter_next(&entry); + if (dbus_message_iter_get_arg_type(&entry) + != DBUS_TYPE_VARIANT) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; + break; + } + + dbus_message_iter_recurse(&entry, &value); + if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) { + error = CONNMAN_ERROR_INTERFACE ".InvalidArguments"; + break; + } + + dbus_message_iter_get_basic(&value, &wpspin); + break; + } + dbus_message_iter_next(&dict); + } + + if (!auth_reply->wps_requested) + choice_done = true; + +done: + auth_reply->peer_callback(auth_reply->peer, choice_done, wpspin, + error, auth_reply->user_data); + + g_free(auth_reply); +} + +int __connman_agent_request_peer_authorization(struct connman_peer *peer, + peer_wps_cb_t callback, + bool wps_requested, + const char *dbus_sender, + void *user_data) +{ + struct request_wps_data wps = { .peer = true }; + const char *path, *agent_sender, *agent_path; + struct request_input_reply *auth_reply; + DBusMessageIter dict, iter; + DBusMessage *message; + void *agent; + int err; + + agent = connman_agent_get_info(dbus_sender, &agent_sender, + &agent_path); + DBG("agent %p peer %p path %s", agent, peer, agent_path); + + if (!peer || !agent || !agent_path || !callback) + return -ESRCH; + + message = dbus_message_new_method_call(agent_sender, agent_path, + CONNMAN_AGENT_INTERFACE, "RequestPeerAuthorization"); + if (!message) + return -ENOMEM; + + dbus_message_iter_init_append(message, &iter); + + path = __connman_peer_get_path(peer); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path); + + connman_dbus_dict_open(&iter, &dict); + + if (wps_requested) + connman_dbus_dict_append_dict(&dict, "WPS", + request_input_append_wps, &wps); + + connman_dbus_dict_close(&iter, &dict); + + auth_reply = g_try_new0(struct request_input_reply, 1); + if (!auth_reply) { + dbus_message_unref(message); + return -ENOMEM; + } + + auth_reply->peer = peer; + auth_reply->peer_callback = callback; + auth_reply->wps_requested = wps_requested; + auth_reply->user_data = user_data; + + err = connman_agent_queue_message(peer, message, + connman_timeout_input_request(), + request_peer_authorization_reply, + auth_reply, agent); + if (err < 0 && err != -EBUSY) { + DBG("error %d sending agent message", err); + dbus_message_unref(message); + g_free(auth_reply); + return err; + } + + dbus_message_unref(message); + + return -EINPROGRESS; +}