summaryrefslogtreecommitdiffstats
path: root/input
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2007-04-04 21:36:45 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2007-04-04 21:36:45 +0000
commit1826edb5d4e3998ba026d2d0436bbbae9047ed3a (patch)
tree82ef88b91371176d49ca4ccb6bf5744f54582837 /input
parente6f25afcdd988e0d40add0363592d78c3685dd00 (diff)
input: Added authorization support for incomming connections
Diffstat (limited to 'input')
-rw-r--r--input/main.c5
-rw-r--r--input/manager.c5
-rw-r--r--input/server.c81
-rw-r--r--input/server.h2
4 files changed, 85 insertions, 8 deletions
diff --git a/input/main.c b/input/main.c
index 057ee0db..cfe31b56 100644
--- a/input/main.c
+++ b/input/main.c
@@ -40,7 +40,6 @@
#include "logging.h"
#include "manager.h"
-#include "server.h"
static GMainLoop *main_loop;
@@ -85,12 +84,8 @@ int main(int argc, char *argv[])
if (argc > 1 && !strcmp(argv[1], "-s"))
register_external_service(conn, "input", "Input service", "");
- server_start();
-
g_main_loop_run(main_loop);
- server_stop();
-
input_exit();
dbus_connection_unref(conn);
diff --git a/input/manager.c b/input/manager.c
index 7a8ce746..567ea6ee 100644
--- a/input/manager.c
+++ b/input/manager.c
@@ -43,6 +43,7 @@
#include "textfile.h"
#include "device.h"
+#include "server.h"
#include "error.h"
#include "manager.h"
#include "storage.h"
@@ -872,6 +873,8 @@ int input_init(DBusConnection *conn)
/* Register well known HID devices */
register_stored_inputs(mgr);
+ server_start(connection);
+
return 0;
fail:
@@ -884,6 +887,8 @@ void input_exit(void)
{
dbus_connection_unregister_object_path(connection, INPUT_PATH);
+ server_stop();
+
dbus_connection_unref(connection);
connection = NULL;
diff --git a/input/server.c b/input/server.c
index 911fc8e7..e08bee22 100644
--- a/input/server.c
+++ b/input/server.c
@@ -40,6 +40,7 @@
#include <glib.h>
#include "logging.h"
+#include "dbus.h"
#include "server.h"
#include "storage.h"
@@ -52,6 +53,7 @@ struct session_data {
};
static GSList *sessions = NULL;
+static DBusConnection *connection = NULL;
static struct session_data *find_session(bdaddr_t *src, bdaddr_t *dst)
{
@@ -126,6 +128,68 @@ cleanup:
g_free(session);
}
+static void authorization_callback(DBusPendingCall *pcall, void *data)
+{
+ struct session_data *session = data;
+ DBusMessage *reply = dbus_pending_call_steal_reply(pcall);
+ DBusError derr;
+
+ dbus_error_init(&derr);
+ if (dbus_set_error_from_message(&derr, reply)) {
+ error("Access denied: %s", derr.message);
+ if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) {
+ debug("FIXME: Cancel authorization request");
+ }
+ dbus_error_free(&derr);
+
+ sessions = g_slist_remove(sessions, session);
+
+ close(session->intr_sk);
+ close(session->ctrl_sk);
+
+ g_free(session);
+
+ goto failed;
+ }
+
+ create_device(session);
+failed:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(pcall);
+}
+
+static int authorize_device(struct session_data *session)
+{
+ DBusMessage *msg;
+ DBusPendingCall *pending;
+ char addr[18];
+ const char *paddr = addr;
+ const char *uuid = ""; /* FIXME: */
+
+ msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+ "org.bluez.Database", "RequestAuthorization");
+ if (!msg) {
+ error("Unable to allocat new RequestAuthorization method call");
+ return -ENOMEM;
+ }
+
+ memset(addr, 0, sizeof(addr));
+ ba2str(&session->dst, addr);
+ dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &paddr,
+ DBUS_TYPE_STRING, &uuid,
+ DBUS_TYPE_INVALID);
+
+ if (dbus_connection_send_with_reply(connection,
+ msg, &pending, -1) == FALSE)
+ return -EACCES;
+
+ dbus_pending_call_set_notify(pending, authorization_callback, session, NULL);
+ dbus_message_unref(msg);
+
+ return 0;
+}
+
static void create_watch(int sk, struct session_data *session)
{
GIOChannel *io;
@@ -176,7 +240,18 @@ static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data
if (session) {
if (psm == 19) {
session->intr_sk = nsk;
- create_device(session);
+ if (authorize_device(session) < 0) {
+ error("Authorization request failed");
+ sessions = g_slist_remove(sessions, session);
+
+ close(session->intr_sk);
+ close(session->ctrl_sk);
+
+ g_free(session);
+
+ return TRUE;
+ }
+ debug("Waiting authorization ...");
} else {
error("Control channel already established");
close(nsk);
@@ -238,7 +313,7 @@ static GIOChannel *setup_l2cap(unsigned int psm)
static GIOChannel *ctrl_io = NULL;
static GIOChannel *intr_io = NULL;
-int server_start(void)
+int server_start(DBusConnection *conn)
{
ctrl_io = setup_l2cap(17);
if (!ctrl_io) {
@@ -253,6 +328,8 @@ int server_start(void)
ctrl_io = NULL;
}
+ connection = conn;
+
return 0;
}
diff --git a/input/server.h b/input/server.h
index f0237d4f..ac2a073e 100644
--- a/input/server.h
+++ b/input/server.h
@@ -21,5 +21,5 @@
*
*/
-int server_start(void);
+int server_start(DBusConnection *conn);
void server_stop(void);