diff options
| -rw-r--r-- | hcid/dbus-security.c | 132 | ||||
| -rw-r--r-- | hcid/dbus.c | 123 | ||||
| -rw-r--r-- | hcid/dbus.h | 3 | 
3 files changed, 139 insertions, 119 deletions
| diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c index a00ecad9..a0230f77 100644 --- a/hcid/dbus-security.c +++ b/hcid/dbus-security.c @@ -28,11 +28,23 @@  #include <stdio.h>  #include <errno.h> +#include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> +#include <bluetooth/hci_lib.h> +  #include <dbus/dbus.h>  #include "dbus.h"  #include "hcid.h" +#define TIMEOUT				(30 * 1000)		/* 30 seconds */ + +struct pin_request { +	int dev; +	bdaddr_t sba; +	bdaddr_t bda; +}; +  static struct passkey_agent *default_agent = NULL;  static void default_agent_exited(const char *name, void *data) @@ -154,6 +166,121 @@ static struct service_data sec_services[] = {  	{ NULL, NULL }  }; +static void passkey_agent_reply(DBusPendingCall *call, void *user_data) +{ +	struct pin_request *req = (struct pin_request *) user_data; +	pin_code_reply_cp pr; +	DBusMessage *message; +	DBusMessageIter iter; +	int arg_type; +	int msg_type; +	size_t len; +	char *pin; +	const char *error_msg; + +	message = dbus_pending_call_steal_reply(call); + +	if (!message) +		goto done; + +	msg_type = dbus_message_get_type(message); +	dbus_message_iter_init(message, &iter); + +	if (msg_type == DBUS_MESSAGE_TYPE_ERROR) { +		dbus_message_iter_get_basic(&iter, &error_msg); + +		/* handling WRONG_ARGS_ERROR, DBUS_ERROR_NO_REPLY, DBUS_ERROR_SERVICE_UNKNOWN */ +		error("%s: %s", dbus_message_get_error_name(message), error_msg); +		hci_send_cmd(req->dev, OGF_LINK_CTL, +					OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); + +		goto done; +	} + +	/* check signature */ +	arg_type = dbus_message_iter_get_arg_type(&iter); +	if (arg_type != DBUS_TYPE_STRING) { +		error("Wrong reply signature: expected PIN"); +		hci_send_cmd(req->dev, OGF_LINK_CTL, +					OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); +	} else { +		dbus_message_iter_get_basic(&iter, &pin); +		len = strlen(pin); + +		set_pin_length(&req->sba, len); + +		memset(&pr, 0, sizeof(pr)); +		bacpy(&pr.bdaddr, &req->bda); +		memcpy(pr.pin_code, pin, len); +		pr.pin_len = len; +		hci_send_cmd(req->dev, OGF_LINK_CTL, +			OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); +	} + +done: +	if (message) +		dbus_message_unref(message); + +	dbus_pending_call_unref(call); +} + +static int call_passkey_agent(struct passkey_agent *agent, int dev, const char *path, +				bdaddr_t *sba, bdaddr_t *dba) +{ +	DBusMessage *message = NULL; +	DBusPendingCall *pending = NULL; +	DBusConnection *connection; +	struct pin_request *req; +	char bda[18]; +	char *ptr = bda; + +	ba2str(sba, bda); + +	debug("Creating method call: name=%s, path=%s", agent->name, +			agent->path); + +	message = dbus_message_new_method_call(agent->name, agent->path, +			"org.bluez.PasskeyAgent", "Request"); +	if (message == NULL) { +		error("Couldn't allocate D-Bus message"); +		goto failed; +	} + +	req = malloc(sizeof(*req)); +	if (!req) +		goto failed; +	req->dev = dev; +	bacpy(&req->sba, sba); +	bacpy(&req->bda, dba); + +	connection = get_dbus_connection(); + +	dbus_message_append_args(message, +					DBUS_TYPE_STRING, &path, +					DBUS_TYPE_STRING, &ptr, +					DBUS_TYPE_INVALID); + +	if (dbus_connection_send_with_reply(connection, message, +				&pending, TIMEOUT) == FALSE) { +		error("D-Bus send failed"); +		goto failed; +	} + +	dbus_pending_call_set_notify(pending, passkey_agent_reply, req, free); + +	dbus_message_unref(message); + +	return 0; + +failed: +	if (message) +		dbus_message_unref(message); + +	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); + +	return -1; +} +  DBusHandlerResult handle_security_method(DBusConnection *conn, DBusMessage *msg, void *data)  {  	service_handler_func_t handler; @@ -166,3 +293,8 @@ DBusHandlerResult handle_security_method(DBusConnection *conn, DBusMessage *msg,  	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;  } +int call_default_passkey_agent(int dev, const char *path, bdaddr_t *sba, bdaddr_t *dba) +{ +	return call_passkey_agent(default_agent, dev, path, sba, dba); +} + diff --git a/hcid/dbus.c b/hcid/dbus.c index ea33a5e8..988aa56c 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -55,14 +55,8 @@ static DBusConnection *connection;  static int default_dev = -1;  static volatile sig_atomic_t __timeout_active = 0; -#define TIMEOUT				(30 * 1000)		/* 30 seconds */  #define MAX_CONN_NUMBER			10 -#define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent" -#define PINAGENT_INTERFACE PINAGENT_SERVICE_NAME -#define PIN_REQUEST "PinRequest" -#define PINAGENT_PATH BASE_PATH "/PinAgent" -  static const char *services_cls[] = {  	"positioning",  	"networking", @@ -106,12 +100,6 @@ static const char *phone_minor_cls[] = {  	"isdn"  }; -struct pin_request { -	int dev; -	bdaddr_t sba; -	bdaddr_t bda; -}; -  /*   * Timeout functions Protypes   */ @@ -194,69 +182,6 @@ static const DBusObjectPathVTable obj_mgr_vtable = {   */  static DBusHandlerResult hci_dbus_signal_filter(DBusConnection *conn, DBusMessage *msg, void *data); -static void reply_handler_function(DBusPendingCall *call, void *user_data) -{ -	struct pin_request *req = (struct pin_request *) user_data; -	pin_code_reply_cp pr; -	DBusMessage *message; -	DBusMessageIter iter; -	int arg_type; -	int msg_type; -	size_t len; -	char *pin; -	const char *error_msg; - -	message = dbus_pending_call_steal_reply(call); - -	if (!message) -		goto done; - -	msg_type = dbus_message_get_type(message); -	dbus_message_iter_init(message, &iter); - -	if (msg_type == DBUS_MESSAGE_TYPE_ERROR) { -		dbus_message_iter_get_basic(&iter, &error_msg); - -		/* handling WRONG_ARGS_ERROR, DBUS_ERROR_NO_REPLY, DBUS_ERROR_SERVICE_UNKNOWN */ -		error("%s: %s", dbus_message_get_error_name(message), error_msg); -		hci_send_cmd(req->dev, OGF_LINK_CTL, -					OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); - -		goto done; -	} - -	/* check signature */ -	arg_type = dbus_message_iter_get_arg_type(&iter); -	if (arg_type != DBUS_TYPE_STRING) { -		error("Wrong reply signature: expected PIN"); -		hci_send_cmd(req->dev, OGF_LINK_CTL, -					OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); -	} else { -		dbus_message_iter_get_basic(&iter, &pin); -		len = strlen(pin); - -		set_pin_length(&req->sba, len); - -		memset(&pr, 0, sizeof(pr)); -		bacpy(&pr.bdaddr, &req->bda); -		memcpy(pr.pin_code, pin, len); -		pr.pin_len = len; -		hci_send_cmd(req->dev, OGF_LINK_CTL, -			OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); -	} - -done: -	if (message) -		dbus_message_unref(message); - -	dbus_pending_call_unref(call); -} - -static void free_pin_req(void *req) -{ -	free(req); -} -  static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t dev_id,  				const DBusObjectPathVTable *pvtable, gboolean fallback)  { @@ -449,53 +374,13 @@ failed:  void hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci)  { -	DBusMessage *message = NULL; -	DBusPendingCall *pending = NULL; -	struct pin_request *req; -	uint8_t *addr = (uint8_t *) &ci->bdaddr; -	dbus_bool_t out = ci->out; - -	if (!dbus_connection_get_is_connected(connection)) { -		if (!hcid_dbus_init()) -			goto failed; -	} - -	message = dbus_message_new_method_call(PINAGENT_SERVICE_NAME, PINAGENT_PATH, -						PINAGENT_INTERFACE, PIN_REQUEST); -	if (message == NULL) { -		error("Couldn't allocate D-Bus message"); -		goto failed; -	} - -	req = malloc(sizeof(*req)); -	req->dev = dev; -	bacpy(&req->sba, sba); -	bacpy(&req->bda, &ci->bdaddr); +	char path[MAX_PATH_LENGTH], addr[18]; -	dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &out, -			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, -			&addr, sizeof(bdaddr_t), DBUS_TYPE_INVALID); +	ba2str(sba, addr); -	if (dbus_connection_send_with_reply(connection, message, -						&pending, TIMEOUT) == FALSE) { -		error("D-Bus send failed"); -		goto failed; -	} - -	dbus_pending_call_set_notify(pending, reply_handler_function, -							req, free_pin_req); - -	dbus_connection_flush(connection); - -	dbus_message_unref(message); - -	return; - -failed: -	if (message) -		dbus_message_unref(message); +	snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, hci_devid(addr)); -	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); +	call_default_passkey_agent(dev, path, sba, &ci->bdaddr);  }  void hcid_dbus_bonding_created_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status) diff --git a/hcid/dbus.h b/hcid/dbus.h index 6c32f2da..86008489 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -26,6 +26,7 @@  #include <stdint.h>  #include <dbus/dbus.h> +#include <bluetooth/bluetooth.h>  #define BASE_PATH		"/org/bluez"  #define BASE_INTERFACE		"org.bluez" @@ -127,6 +128,8 @@ DBusHandlerResult handle_security_method(DBusConnection *conn, DBusMessage *msg,  service_handler_func_t find_service_handler(struct service_data *services, DBusMessage *msg); +int call_default_passkey_agent(int dev, const char *path, bdaddr_t *sba, bdaddr_t *dba); +  static inline DBusHandlerResult send_reply_and_unref(DBusConnection *conn, DBusMessage *reply)  {  	if (reply) { | 
