*
* Connection Manager
*
- * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2012 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
#include "connman.h"
+#define REQUEST_TIMEOUT (120 * 1000) /* 120 seconds */
+
static DBusConnection *connection = NULL;
static guint agent_watch = 0;
static gchar *agent_path = NULL;
return 0;
}
+static connman_bool_t check_reply_has_dict(DBusMessage *reply)
+{
+ const char *signature = DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
+
+ if (dbus_message_has_signature(reply, signature) == TRUE)
+ return TRUE;
+
+ connman_warn("Reply %s to %s from %s has wrong signature %s",
+ signature,
+ dbus_message_get_interface(reply),
+ dbus_message_get_sender(reply),
+ dbus_message_get_signature(reply));
+
+ return FALSE;
+}
+
struct request_input_reply {
struct connman_service *service;
authentication_cb_t callback;
struct request_input_reply *passphrase_reply = user_data;
connman_bool_t values_received = FALSE;
connman_bool_t wps = FALSE;
+ const char *error = NULL;
char *identity = NULL;
char *passphrase = NULL;
char *wpspin = NULL;
DBusMessageIter iter, dict;
DBusMessage *reply = dbus_pending_call_steal_reply(call);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+ 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)
goto done;
values_received = TRUE;
passphrase_reply->callback(passphrase_reply->service, values_received,
name, name_len,
identity, passphrase,
- wps, wpspin,
+ wps, wpspin, error,
passphrase_reply->user_data);
connman_service_unref(passphrase_reply->service);
dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
g_free(passphrase_reply);
}
static void request_input_login_reply(DBusPendingCall *call, void *user_data)
{
struct request_input_reply *username_password_reply = user_data;
+ const char *error = NULL;
+ connman_bool_t values_received = FALSE;
char *username = NULL;
char *password = NULL;
char *key;
DBusMessageIter iter, dict;
DBusMessage *reply = dbus_pending_call_steal_reply(call);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+ 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)
+ goto done;
+
+ values_received = TRUE;
dbus_message_iter_init(reply, &iter);
dbus_message_iter_recurse(&iter, &dict);
done:
username_password_reply->callback(username_password_reply->service,
- TRUE, NULL, 0,
+ values_received, NULL, 0,
username, password,
- FALSE, NULL,
+ FALSE, NULL, error,
username_password_reply->user_data);
connman_service_unref(username_password_reply->service);
dbus_message_unref(reply);
request_input_append_identity, service);
}
- connman_dbus_dict_append_dict(&dict, "Passphrase",
- request_input_append_passphrase, service);
+ if (__connman_service_get_security(service) !=
+ CONNMAN_SERVICE_SECURITY_NONE) {
+ connman_dbus_dict_append_dict(&dict, "Passphrase",
+ request_input_append_passphrase, service);
+ }
if (__connman_service_wps_enabled(service) == TRUE) {
connman_dbus_dict_append_dict(&dict, "WPS",
return -ENOMEM;
}
- if (dbus_connection_send_with_reply(connection, message,
- &call, -1) == FALSE) {
+ if (dbus_connection_send_with_reply(connection, message, &call,
+ REQUEST_TIMEOUT) == FALSE) {
dbus_message_unref(message);
g_free(passphrase_reply);
return -ESRCH;
dbus_message_unref(message);
- return -EIO;
+ return -EINPROGRESS;
}
int __connman_agent_request_login_input(struct connman_service *service,
return -ENOMEM;
}
- if (dbus_connection_send_with_reply(connection, message,
- &call, -1) == FALSE) {
+ if (dbus_connection_send_with_reply(connection, message, &call,
+ REQUEST_TIMEOUT) == FALSE) {
dbus_message_unref(message);
g_free(username_password_reply);
return -ESRCH;
dbus_message_unref(message);
- return -EIO;
+ return -EINPROGRESS;
}
struct request_browser_reply_data {
struct request_browser_reply_data *browser_reply_data = user_data;
DBusMessage *reply = dbus_pending_call_steal_reply(call);
connman_bool_t result = FALSE;
+ const char *error = NULL;
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+ if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+ error = dbus_message_get_error_name(reply);
goto done;
+ }
result = TRUE;
done:
- browser_reply_data->callback(browser_reply_data->service,
- result, browser_reply_data->user_data);
+ browser_reply_data->callback(browser_reply_data->service, result,
+ error, browser_reply_data->user_data);
connman_service_unref(browser_reply_data->service);
dbus_message_unref(reply);
g_free(browser_reply_data);
return -ENOMEM;
}
- if (dbus_connection_send_with_reply(connection, message,
- &call, -1) == FALSE) {
+ if (dbus_connection_send_with_reply(connection, message, &call,
+ REQUEST_TIMEOUT) == FALSE) {
dbus_message_unref(message);
g_free(browser_reply_data);
return -ESRCH;
dbus_message_unref(message);
- return -EIO;
+ return -EINPROGRESS;
}
struct report_error_data {
connman_service_unref(report_error->service);
g_free(report_error);
dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
}
int __connman_agent_report_error(struct connman_service *service,
return -ENOMEM;
}
- if (dbus_connection_send_with_reply(connection, message,
- &call, -1) == FALSE) {
+ if (dbus_connection_send_with_reply(connection, message, &call,
+ REQUEST_TIMEOUT) == FALSE) {
dbus_message_unref(message);
g_free(report_error);
return -ESRCH;
report_error, NULL);
dbus_message_unref(message);
- return -EIO;
+ return -EINPROGRESS;
}
int __connman_agent_init(void)