Diff between 4e3ad171df3ea75b4efede0ca0c90ade703e352f and 968be4037ca1b38b1a8bd1acc4007b1aa9fd4bb0

Changed Files

File Additions Deletions Status
android/hal-msg.h +3 -0 modified
android/socket.c +19 -10 modified

Full Patch

diff --git a/android/hal-msg.h b/android/hal-msg.h
index aba98ed..6ef00f9 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -235,6 +235,9 @@ struct hal_cmd_le_test_mode {
 #define HAL_SOCK_SCO		0x02
 #define HAL_SOCK_L2CAP		0x03
 
+#define HAL_SOCK_FLAG_ENCRYPT	0x01
+#define HAL_SOCK_FLAG_AUTH	0x02
+
 #define HAL_OP_SOCK_LISTEN		0x01
 struct hal_cmd_sock_listen {
 	uint8_t type;
diff --git a/android/socket.c b/android/socket.c
index 92b021c..c62ca61 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -70,6 +70,7 @@ GList *connections = NULL;
 
 struct rfcomm_sock {
 	int channel;	/* RFCOMM channel */
+	BtIOSecLevel sec_level;
 
 	/* for socket to BT */
 	int bt_sock;
@@ -84,8 +85,6 @@ struct rfcomm_sock {
 
 	uint8_t *buf;
 	int buf_size;
-
-	const struct profile_info *profile;
 };
 
 struct rfcomm_channel {
@@ -721,6 +720,19 @@ static int find_free_channel(void)
 	return 0;
 }
 
+static BtIOSecLevel get_sec_level(uint8_t flags)
+{
+	/* HAL_SOCK_FLAG_AUTH should require MITM but in our case setting
+	 * security to BT_IO_SEC_HIGH would also require 16-digits PIN code
+	 * for pre-2.1 devices which is not what Android expects. For this
+	 * reason we ignore this flag to not break apps which use "secure"
+	 * sockets (have both auth and encrypt flags set, there is no public
+	 * API in Android which should provide proper high security socket).
+	 */
+	return flags & HAL_SOCK_FLAG_ENCRYPT ? BT_IO_SEC_MEDIUM :
+							BT_IO_SEC_LOW;
+}
+
 static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
 						uint8_t flags, int *hal_sock)
 {
@@ -748,7 +760,7 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
 
 	profile = get_profile_by_uuid(uuid);
 	if (!profile) {
-		sec_level = BT_IO_SEC_MEDIUM;
+		sec_level = get_sec_level(flags);
 	} else {
 		if (!profile->create_record)
 			return HAL_STATUS_INVALID;
@@ -931,20 +943,16 @@ fail:
 
 static bool do_rfcomm_connect(struct rfcomm_sock *rfsock, int chan)
 {
-	BtIOSecLevel sec_level = BT_IO_SEC_MEDIUM;
 	GIOChannel *io;
 	GError *gerr = NULL;
 
-	if (rfsock->profile)
-		sec_level = rfsock->profile->sec_level;
-
-	DBG("rfsock %p sec_level %d chan %d", rfsock, sec_level, chan);
+	DBG("rfsock %p sec_level %d chan %d", rfsock, rfsock->sec_level, chan);
 
 	io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
 				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
 				BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
 				BT_IO_OPT_CHANNEL, chan,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
+				BT_IO_OPT_SEC_LEVEL, rfsock->sec_level,
 				BT_IO_OPT_INVALID);
 	if (!io) {
 		error("Failed connect: %s", gerr->message);
@@ -1047,13 +1055,14 @@ static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan,
 	DBG("rfsock %p jv_sock %d hal_sock %d", rfsock, rfsock->jv_sock,
 							*hal_sock);
 
+	rfsock->sec_level = get_sec_level(flags);
+
 	bacpy(&rfsock->dst, addr);
 
 	if (!memcmp(uuid, zero_uuid, sizeof(zero_uuid))) {
 		if (!do_rfcomm_connect(rfsock, chan))
 			goto failed;
 	} else {
-		rfsock->profile = get_profile_by_uuid(uuid);
 
 		if (bt_search_service(&adapter_addr, &rfsock->dst, &uu,
 					sdp_search_cb, rfsock, NULL, 0) < 0) {