diff options
| author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-04-04 21:36:45 +0000 | 
|---|---|---|
| committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-04-04 21:36:45 +0000 | 
| commit | 1826edb5d4e3998ba026d2d0436bbbae9047ed3a (patch) | |
| tree | 82ef88b91371176d49ca4ccb6bf5744f54582837 | |
| parent | e6f25afcdd988e0d40add0363592d78c3685dd00 (diff) | |
input: Added authorization support for incomming connections
| -rw-r--r-- | input/main.c | 5 | ||||
| -rw-r--r-- | input/manager.c | 5 | ||||
| -rw-r--r-- | input/server.c | 81 | ||||
| -rw-r--r-- | input/server.h | 2 | 
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); | 
