diff options
| author | Johan Hedberg <johan.hedberg@nokia.com> | 2008-06-06 11:28:57 +0000 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2008-06-06 11:28:57 +0000 | 
| commit | 833b95efc8bda83851624b203991db196282335c (patch) | |
| tree | 91a36d9f9ab649b504685a018e88bc73ae0d4502 | |
| parent | 30877999b61e655ff7f4e804240098c4cd31831e (diff) | |
Further cleanup of authentication logic
| -rw-r--r-- | hcid/adapter.c | 4 | ||||
| -rw-r--r-- | hcid/adapter.h | 9 | ||||
| -rw-r--r-- | hcid/dbus-hci.c | 35 | ||||
| -rw-r--r-- | hcid/dbus-hci.h | 3 | ||||
| -rw-r--r-- | hcid/dbus-security.c | 170 | ||||
| -rw-r--r-- | hcid/security.c | 46 | 
6 files changed, 43 insertions, 224 deletions
| diff --git a/hcid/adapter.c b/hcid/adapter.c index d958a04b..8d71b3bd 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -2628,7 +2628,7 @@ static void create_bond_req_exit(void *user_data)  	l = g_slist_find_custom(adapter->pin_reqs, &adapter->bonding->bdaddr,  			pin_req_cmp);  	if (l) { -		struct pending_pin_info *p = l->data; +		struct pending_auth_info *p = l->data;  		if (!p->replied) {  			int dd; @@ -2773,7 +2773,7 @@ static DBusMessage *adapter_cancel_bonding(DBusConnection *conn,  	l = g_slist_find_custom(adapter->pin_reqs, &bdaddr, pin_req_cmp);  	if (l) { -		struct pending_pin_info *pin_req = l->data; +		struct pending_auth_info *pin_req = l->data;  		if (pin_req->replied) {  			/* diff --git a/hcid/adapter.h b/hcid/adapter.h index 7808609a..ec2c3f81 100644 --- a/hcid/adapter.h +++ b/hcid/adapter.h @@ -46,6 +46,12 @@ typedef enum {  	NAME_SENT          /* D-Bus signal RemoteNameUpdated sent */  } name_status_t; +typedef enum { +	AUTH_TYPE_PINCODE, +	AUTH_TYPE_PASSKEY, +	AUTH_TYPE_CONFIRM, +} auth_type_t; +  struct remote_dev_info {  	bdaddr_t bdaddr;  	int8_t rssi; @@ -65,7 +71,8 @@ struct bonding_request_info {  	int auth_active;  }; -struct pending_pin_info { +struct pending_auth_info { +	auth_type_t type;  	bdaddr_t bdaddr;  	int replied;	/* If we've already replied to the request */  }; diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index 61bd1cd1..8c93a883 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -929,16 +929,16 @@ int hcid_dbus_stop_device(uint16_t id)  int pin_req_cmp(const void *p1, const void *p2)  { -	const struct pending_pin_info *pb1 = p1; -	const struct pending_pin_info *pb2 = p2; +	const struct pending_auth_info *pb1 = p1; +	const struct pending_auth_info *pb2 = p2;  	return p2 ? bacmp(&pb1->bdaddr, &pb2->bdaddr) : -1;  } -void hcid_dbus_pending_pin_req_add(bdaddr_t *sba, bdaddr_t *dba) +void hcid_dbus_new_auth_request(bdaddr_t *sba, bdaddr_t *dba, auth_type_t type)  {  	struct adapter *adapter; -	struct pending_pin_info *info; +	struct pending_auth_info *info;  	adapter = find_adapter(sba);  	if (!adapter) { @@ -946,9 +946,10 @@ void hcid_dbus_pending_pin_req_add(bdaddr_t *sba, bdaddr_t *dba)  		return;  	} -	info = g_new0(struct pending_pin_info, 1); +	info = g_new0(struct pending_auth_info, 1);  	bacpy(&info->bdaddr, dba); +	info->type = type;  	adapter->pin_reqs = g_slist_append(adapter->pin_reqs, info);  	if (adapter->bonding && !bacmp(dba, &adapter->bonding->bdaddr)) @@ -1159,20 +1160,6 @@ int hcid_dbus_user_passkey(bdaddr_t *sba, bdaddr_t *dba)  	return 0;  } -int hcid_dbus_confirm_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci, char *pin) -{ -	struct adapter *adapter; - -	adapter = find_adapter(sba); -	if (!adapter) { -		error("No matching adapter found"); -		return -1; -	} - -	return handle_confirm_request_old(connection, dev, adapter, -						sba, &ci->bdaddr, pin); -} -  void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,  					uint8_t status)  { @@ -1186,6 +1173,8 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,  	void *d;  	gboolean paired = TRUE; +	debug("hcid_dbus_bonding_process_complete: status=%02x", status); +  	ba2str(peer, peer_addr);  	adapter = find_adapter(local); @@ -1216,6 +1205,8 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,  	if (device) {  		char *ptr = adapter->path + ADAPTER_PATH_INDEX; +		debug("hcid_dbus_bonding_process_complete: removing temporary flag"); +  		device->temporary = FALSE;  		dbus_connection_emit_signal(connection, ptr, @@ -2097,8 +2088,10 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,  					device->path, DEVICE_INTERFACE,  					"Connected", DBUS_TYPE_BOOLEAN,  					&connected); -		if (device->temporary) +		if (device->temporary) { +			debug("Removing temporary device %s", device->address);  			adapter_remove_device(connection, adapter, device); +		}  	}  } @@ -2396,7 +2389,7 @@ void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr)  	l = g_slist_find_custom(adapter->pin_reqs, &ret->bdaddr, pin_req_cmp);  	if (l) { -		struct pending_pin_info *p = l->data; +		struct pending_auth_info *p = l->data;  		p->replied = 1;  	}  } diff --git a/hcid/dbus-hci.h b/hcid/dbus-hci.h index 167780b4..31c13199 100644 --- a/hcid/dbus-hci.h +++ b/hcid/dbus-hci.h @@ -28,9 +28,8 @@ int hcid_dbus_register_device(uint16_t id);  int hcid_dbus_unregister_device(uint16_t id);  int hcid_dbus_start_device(uint16_t id);  int hcid_dbus_stop_device(uint16_t id); -void hcid_dbus_pending_pin_req_add(bdaddr_t *sba, bdaddr_t *dba); +void hcid_dbus_new_auth_request(bdaddr_t *sba, bdaddr_t *dba, auth_type_t type);  int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci); -int hcid_dbus_confirm_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci, char *pin);  void hcid_dbus_inquiry_start(bdaddr_t *local);  void hcid_dbus_inquiry_complete(bdaddr_t *local); diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c index dfa2c711..840efca6 100644 --- a/hcid/dbus-security.c +++ b/hcid/dbus-security.c @@ -1022,176 +1022,6 @@ int handle_passkey_request_old(DBusConnection *conn, int dev,  	return call_passkey_agent(conn, agent, dev, adapter->path, sba, dba);  } -static DBusPendingCall *agent_confirm(const char *path, bdaddr_t *bda, -					struct passkey_agent *agent, -					const char *value) -{ -	DBusMessage *message; -	DBusPendingCall *call; -	char bda_str[18], *ptr = bda_str; - -	message = dbus_message_new_method_call(agent->name, agent->path, -					"org.bluez.PasskeyAgent", "Confirm"); -	if (message == NULL) { -		error("Couldn't allocate D-Bus message"); -		return NULL; -	} - -	ba2str(bda, bda_str); - -	dbus_message_append_args(message, -				DBUS_TYPE_STRING, &path, -				DBUS_TYPE_STRING, &ptr, -				DBUS_TYPE_STRING, &value, -				DBUS_TYPE_INVALID); - -	if (dbus_connection_send_with_reply(agent->conn, message, -					&call, REQUEST_TIMEOUT) == FALSE) { -		error("D-Bus send failed"); -		dbus_message_unref(message); -		return NULL; -	} - -	dbus_message_unref(message); -	return call; -} - -static void confirm_agent_reply(DBusPendingCall *call, void *user_data) -{ -	struct pending_agent_request *req = user_data; -	struct passkey_agent *agent = req->agent; -	pin_code_reply_cp pr; -	DBusMessage *message; -	DBusError err; -	int len; - -	/* steal_reply will always return non-NULL since the callback -	 * is only called after a reply has been received */ -	message = dbus_pending_call_steal_reply(call); - -	dbus_error_init(&err); -	if (dbus_set_error_from_message(&err, message)) { - -		error("Passkey agent replied with an error: %s, %s", -				err.name, err.message); - -		dbus_error_free(&err); -		goto fail; -	} - -	dbus_error_init(&err); -	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) { -		error("Wrong confirm reply signature: %s", err.message); -		dbus_error_free(&err); -		goto fail; -	} - -	len = strlen(req->pin); - -	set_pin_length(&req->sba, len); - -	memset(&pr, 0, sizeof(pr)); -	bacpy(&pr.bdaddr, &req->bda); -	memcpy(pr.pin_code, req->pin, len); -	pr.pin_len = len; -	hci_send_cmd(req->dev, OGF_LINK_CTL, -			OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); - -	goto done; - -fail: -	hci_send_cmd(req->dev, OGF_LINK_CTL, -			OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); - -done: -	if (message) -		dbus_message_unref(message); - -	agent->pending_requests = g_slist_remove(agent->pending_requests, req); -	dbus_pending_call_cancel(req->call); -	if (req->call) -		dbus_pending_call_unref(req->call); -	g_free(req->pin); -	g_free(req->path); -	g_free(req); - -	if (agent != default_agent) { -		agent->adapter->passkey_agents = g_slist_remove(agent->adapter->passkey_agents, -								agent); -		passkey_agent_free(agent); -	} -} - -static int call_confirm_agent(DBusConnection *conn, -				struct passkey_agent *agent, int dev, -				const char *path, bdaddr_t *sba, -				bdaddr_t *dba, const char *pin) -{ -	struct pending_agent_request *req; - -	if (!agent) { -		debug("call_passkey_agent(): no agent available"); -		goto send; -	} - -	debug("Calling PasskeyAgent.Confirm: name=%s, path=%s", -						agent->name, agent->path); - -	req = g_new0(struct pending_agent_request, 1); -	req->dev = dev; -	bacpy(&req->sba, sba); -	bacpy(&req->bda, dba); -	req->agent = agent; -	req->path = g_strdup(path); -	req->pin = g_strdup(pin); - -	req->call = agent_confirm(path, dba, agent, pin); -	if (!req->call) -		goto failed; - -	dbus_pending_call_set_notify(req->call, confirm_agent_reply, req, NULL); - -	agent->pending_requests = g_slist_append(agent->pending_requests, req); - -	return 0; - -failed: -	g_free(req->pin); -	g_free(req->path); -	g_free(req); - -send: -	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); - -	return -1; -} - -int handle_confirm_request_old(DBusConnection *conn, int dev, -						struct adapter *adapter, -						bdaddr_t *sba, bdaddr_t *dba, -							const char *pin) -{ -	struct passkey_agent *agent = default_agent; -	GSList *l; -	char addr[18]; - -	ba2str(dba, addr); - -	for (l = adapter->passkey_agents; l != NULL; l = l->next) { -		struct passkey_agent *a = l->data; -		if (a != default_agent && -				g_slist_length(a->pending_requests) >= 1) -			continue; -		if (!strcmp(a->addr, addr)) { -			agent = a; -			break; -		} -	} - -	return call_confirm_agent(conn, agent, dev, adapter->path, -							sba, dba, pin); -} -  static void send_cancel_request(struct pending_agent_request *req)  {  	DBusMessage *message; diff --git a/hcid/security.c b/hcid/security.c index 0df255ab..1a711e18 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -365,6 +365,8 @@ static void user_confirm_request(int dev, bdaddr_t *sba, void *ptr)  	if (hcid_dbus_user_confirm(sba, &req->bdaddr, req->passkey) < 0)  		hci_send_cmd(dev, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY,  				6, ptr); +	else +		hcid_dbus_new_auth_request(sba, &req->bdaddr, AUTH_TYPE_CONFIRM);  }  static void user_passkey_request(int dev, bdaddr_t *sba, void *ptr) @@ -374,6 +376,8 @@ static void user_passkey_request(int dev, bdaddr_t *sba, void *ptr)  	if (hcid_dbus_user_passkey(sba, &req->bdaddr) < 0)  		hci_send_cmd(dev, OGF_LINK_CTL, OCF_USER_PASSKEY_NEG_REPLY,  				6, ptr); +	else +		hcid_dbus_new_auth_request(sba, &req->bdaddr, AUTH_TYPE_PASSKEY);  }  static void remote_oob_data_request(int dev, bdaddr_t *sba, void *ptr) @@ -459,39 +463,27 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba)  	} else if (pairing == HCID_PAIRING_NONE)  		goto reject; -	if (hcid.security == HCID_SEC_AUTO) { -		if (!ci->out) { -			/* Incomming connection */ -			set_pin_length(sba, hcid.pin_len); -			memcpy(pr.pin_code, hcid.pin_code, hcid.pin_len); -			pr.pin_len = hcid.pin_len; -			hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, +	if (hcid.security == HCID_SEC_AUTO && !ci->out) { +		set_pin_length(sba, hcid.pin_len); +		memcpy(pr.pin_code, hcid.pin_code, hcid.pin_len); +		pr.pin_len = hcid.pin_len; +		hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY,  				PIN_CODE_REPLY_CP_SIZE, &pr); -		} else { -			/* Outgoing connection */ -			if (pinlen > 0) { -				set_pin_length(sba, pinlen); -				memcpy(pr.pin_code, pin, pinlen); -				pr.pin_len = pinlen; -				hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, -					PIN_CODE_REPLY_CP_SIZE, &pr); -			} else { -				/* Request PIN from passkey agent */ -				hcid_dbus_request_pin(dev, sba, ci); -			} -		}  	} else {  		if (pinlen > 0) { -			/* Confirm PIN by passkey agent */ -			hcid_dbus_confirm_pin(dev, sba, ci, pin); +			set_pin_length(sba, pinlen); +			memcpy(pr.pin_code, pin, pinlen); +			pr.pin_len = pinlen; +			hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, +					PIN_CODE_REPLY_CP_SIZE, &pr);  		} else { -			/* Request PIN from passkey agent */  -			hcid_dbus_request_pin(dev, sba, ci); +			/* Request PIN from passkey agent */ +			if (hcid_dbus_request_pin(dev, sba, ci) < 0) +				goto reject; +			hcid_dbus_new_auth_request(sba, dba, AUTH_TYPE_PINCODE);  		}  	} -	hcid_dbus_pending_pin_req_add(sba, &ci->bdaddr); -  	g_free(cr);  	return; @@ -500,8 +492,6 @@ reject:  	g_free(cr);  	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); - -	return;  }  static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr) | 
