From 255528bec9a5ffdd81ce509f2166a3a405b958d3 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 27 Sep 2006 16:25:11 +0000 Subject: Return correct error reply for CreateBonding when using security mode 3 --- hcid/dbus-adapter.c | 28 +++++++++++++++++++++++----- hcid/dbus-error.c | 7 ------- hcid/dbus.c | 12 +++++++++--- hcid/dbus.h | 6 ++++-- hcid/security.c | 2 +- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c index 53b65144..b7425a1a 100644 --- a/hcid/dbus-adapter.c +++ b/hcid/dbus-adapter.c @@ -1786,6 +1786,19 @@ failed: return -1; } +static void reply_authentication_failure(struct bonding_request_info *bonding) +{ + DBusMessage *reply; + int status; + + status = bonding->hci_status ? + bonding->hci_status : HCI_AUTHENTICATION_FAILURE; + + reply = new_authentication_return(bonding->rq, status); + if (reply) + send_reply_and_unref(bonding->conn, reply); +} + static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, struct hci_dbus_data *pdata) { @@ -1811,10 +1824,12 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, if (cond & (G_IO_HUP | G_IO_ERR)) { debug("Hangup or error on bonding IO channel"); - if (!pdata->bonding->connected) + + if (!pdata->bonding->auth_active) error_connection_attempt_failed(pdata->bonding->conn, pdata->bonding->rq, ENETDOWN); else - error_authentication_failed(pdata->bonding->conn, pdata->bonding->rq); + reply_authentication_failure(pdata->bonding); + goto failed; } @@ -1828,12 +1843,13 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, } if (ret != 0) { - error_connection_attempt_failed(pdata->bonding->conn, pdata->bonding->rq, ret); + if (pdata->bonding->auth_active) + reply_authentication_failure(pdata->bonding); + else + error_connection_attempt_failed(pdata->bonding->conn, pdata->bonding->rq, ret); goto failed; } - pdata->bonding->connected = 1; - len = sizeof(cinfo); if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &cinfo, &len) < 0) { error("Can't get connection info: %s (%d)", strerror(errno), errno); @@ -1879,6 +1895,8 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, hci_close_dev(dd); + pdata->bonding->auth_active = 1; + pdata->bonding->io_id = g_io_add_watch(io, G_IO_NVAL | G_IO_HUP | G_IO_ERR, (GIOFunc) create_bonding_conn_complete, pdata); diff --git a/hcid/dbus-error.c b/hcid/dbus-error.c index aa7ed5ef..82415cef 100644 --- a/hcid/dbus-error.c +++ b/hcid/dbus-error.c @@ -187,13 +187,6 @@ DBusHandlerResult error_authentication_canceled(DBusConnection *conn, DBusMessag "Authentication Canceled")); } -DBusHandlerResult error_authentication_failed(DBusConnection *conn, DBusMessage *msg) -{ - return send_reply_and_unref(conn, - dbus_message_new_error(msg, ERROR_INTERFACE ".AuthenticationFailed", - "Authentication failed")); -} - DBusHandlerResult error_discover_in_progress(DBusConnection *conn, DBusMessage *msg) { return error_in_progress(conn, msg, "Discover in progress"); diff --git a/hcid/dbus.c b/hcid/dbus.c index 06abd9d3..af9859d5 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -225,7 +225,7 @@ static int active_conn_remove(struct slist **list, uint16_t *handle) return ret_val; } -static DBusMessage *dbus_msg_new_authentication_return(DBusMessage *msg, uint8_t status) +DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status) { switch (status) { case 0x00: /* success */ @@ -789,6 +789,9 @@ void hcid_dbus_pending_pin_req_add(bdaddr_t *sba, bdaddr_t *dba) memset(info, 0, sizeof(struct pending_pin_info)); bacpy(&info->bdaddr, dba); pdata->pin_reqs = slist_append(pdata->pin_reqs, info); + + if (pdata->bonding && !bacmp(dba, &pdata->bonding->bdaddr)) + pdata->bonding->auth_active = 1; } int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci) @@ -856,7 +859,7 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t error_authentication_canceled(connection, pdata->bonding->rq); } else { /* reply authentication success or an error */ - message = dbus_msg_new_authentication_return(pdata->bonding->rq, status); + message = new_authentication_return(pdata->bonding->rq, status); send_reply_and_unref(connection, message); } @@ -1552,6 +1555,9 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b pdata->pin_reqs = slist_remove(pdata->pin_reqs, p); free(p); } + + if (pdata->bonding) + pdata->bonding->hci_status = status; } else { /* Sent the remote device connected signal */ message = dbus_message_new_signal(path, ADAPTER_INTERFACE, "RemoteDeviceConnected"); @@ -1634,7 +1640,7 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, uint16_t handle /* reply authentication canceled */ error_authentication_canceled(connection, pdata->bonding->rq); } else { - message = dbus_msg_new_authentication_return(pdata->bonding->rq, HCI_AUTHENTICATION_FAILURE); + message = new_authentication_return(pdata->bonding->rq, HCI_AUTHENTICATION_FAILURE); send_reply_and_unref(connection, message); } diff --git a/hcid/dbus.h b/hcid/dbus.h index e754622e..05edc48b 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -88,8 +88,9 @@ struct bonding_request_info { DBusMessage *rq; GIOChannel *io; guint io_id; + int hci_status; int cancel; - int connected; + int auth_active; }; struct pending_pin_info { @@ -158,6 +159,8 @@ DBusHandlerResult bluez_new_failure_msg(DBusConnection *conn, DBusMessage *msg, DBusMessage *dev_signal_factory(const int devid, const char *prop_name, const int first, ...); +DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status); + int get_default_dev_id(void); DBusHandlerResult error_failed(DBusConnection *conn, DBusMessage *msg, int err); @@ -177,7 +180,6 @@ DBusHandlerResult error_bonding_does_not_exist(DBusConnection *conn, DBusMessage DBusHandlerResult error_bonding_in_progress(DBusConnection *conn, DBusMessage *msg); DBusHandlerResult error_bonding_not_in_progress(DBusConnection *conn, DBusMessage *msg); DBusHandlerResult error_authentication_canceled(DBusConnection *conn, DBusMessage *msg); -DBusHandlerResult error_authentication_failed(DBusConnection *conn, DBusMessage *msg); DBusHandlerResult error_discover_in_progress(DBusConnection *conn, DBusMessage *msg); DBusHandlerResult error_connect_in_progress(DBusConnection *conn, DBusMessage *msg); DBusHandlerResult error_connect_not_in_progress(DBusConnection *conn, DBusMessage *msg); diff --git a/hcid/security.c b/hcid/security.c index 77fb9d41..c82fbc00 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -852,7 +852,7 @@ void start_security_manager(int hdev) chan = g_io_channel_unix_new(dev); g_io_channel_set_close_on_unref(chan, TRUE); - io_data[hdev].watch_id = g_io_add_watch_full(chan, 0, + io_data[hdev].watch_id = g_io_add_watch_full(chan, G_PRIORITY_HIGH, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, io_security_event, di, (GDestroyNotify)free); io_data[hdev].channel = chan; -- cgit