Example #1
0
int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba)
{
	struct btd_adapter *adapter;
	struct btd_device *device;
	char pin[17];
	int pinlen;

	if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
		return -ENODEV;

	memset(pin, 0, sizeof(pin));
	pinlen = read_pin_code(sba, dba, pin);
	if (pinlen > 0) {
		btd_adapter_pincode_reply(adapter, dba, pin);
		return 0;
	}

	return device_request_authentication(device, AUTH_TYPE_PINCODE, 0,
								pincode_cb);
}
Example #2
0
int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
{
	struct btd_adapter *adapter;
	struct btd_device *device;
	struct agent *agent;
	uint8_t rem_cap, rem_auth, loc_cap, loc_auth;
	gboolean bonding_initiator;

	if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
		return -ENODEV;

	if (btd_adapter_get_auth_info(adapter, dba, &loc_auth) < 0) {
		error("Unable to get local authentication requirements");
		goto fail;
	}

	agent = device_get_agent(device);
	if (agent == NULL) {
		error("No agent available for user confirmation");
		goto fail;
	}

	loc_cap = agent_get_io_capability(agent);

	DBG("confirm IO capabilities are 0x%02x", loc_cap);
	DBG("confirm authentication requirement is 0x%02x", loc_auth);

	rem_cap = device_get_cap(device);
	rem_auth = device_get_auth(device);

	DBG("remote IO capabilities are 0x%02x", rem_cap);
	DBG("remote authentication requirement is 0x%02x", rem_auth);

	/* If we require MITM but the remote device can't provide that
	 * (it has NoInputNoOutput) then reject the confirmation
	 * request. The only exception is when we're dedicated bonding
	 * initiators since then we always have the MITM bit set. */
	bonding_initiator = device_is_bonding(device, NULL);
	if (!bonding_initiator && (loc_auth & 0x01) && rem_cap == 0x03) {
		error("Rejecting request: remote device can't provide MITM");
		goto fail;
	}

	/* If no side requires MITM protection; auto-accept */
	if ((loc_auth == 0xff || !(loc_auth & 0x01) || rem_cap == 0x03) &&
				(!(rem_auth & 0x01) || loc_cap == 0x03)) {
		DBG("auto accept of confirmation");

		/* Wait 5 milliseconds before doing auto-accept */
		usleep(5000);

		if (confirm_reply(adapter, device, TRUE) < 0)
			return -EIO;

		return device_request_authentication(device, AUTH_TYPE_AUTO,
								0, NULL);
	}

	return device_request_authentication(device, AUTH_TYPE_CONFIRM,
							passkey, confirm_cb);

fail:
	return confirm_reply(adapter, device, FALSE);
}