aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:45 -0400
committerMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:45 -0400
commit77db1980565626471a980f0d2d17299e4bd5e7a5 (patch)
tree93b71744c82fd3479d3c91033b871032de03049b
parent79d554a6976a295aa9212172b218f29ca71c3b3d (diff)
[Bluetooth] Enforce security for outgoing RFCOMM connections
Recent tests with various Bluetooth headsets have shown that some of them don't enforce authentication and encryption when connecting. All of them leave it up to the host stack to enforce it. Non of them should allow unencrypted connections, but that is how it is. So in case the link mode settings require authentication and/or encryption it will now also be enforced on outgoing RFCOMM connections. Previously this was only done for incoming connections. This support has a small drawback from a protocol level point of view since the host stack can't really tell with 100% certainty if a remote side is already authenticated or not. So if both sides are configured to enforce authentication it will be requested twice. Most Bluetooth chips are caching this information and thus no extra authentication procedure has to be triggered over-the-air, but it can happen. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/rfcomm.h1
-rw-r--r--net/bluetooth/rfcomm/core.c77
-rw-r--r--net/bluetooth/rfcomm/sock.c8
3 files changed, 52 insertions, 34 deletions
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 98ec7a320689..8c54ff37ad4f 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -181,6 +181,7 @@ struct rfcomm_dlc {
181 u8 priority; 181 u8 priority;
182 u8 v24_sig; 182 u8 v24_sig;
183 u8 mscex; 183 u8 mscex;
184 u8 out;
184 185
185 u32 link_mode; 186 u32 link_mode;
186 187
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 0c2c93735e93..1f92f9ab4959 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -53,7 +53,7 @@
53#define BT_DBG(D...) 53#define BT_DBG(D...)
54#endif 54#endif
55 55
56#define VERSION "1.8" 56#define VERSION "1.9"
57 57
58static int disable_cfc = 0; 58static int disable_cfc = 0;
59static int channel_mtu = -1; 59static int channel_mtu = -1;
@@ -230,6 +230,21 @@ static int rfcomm_l2sock_create(struct socket **sock)
230 return err; 230 return err;
231} 231}
232 232
233static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d)
234{
235 struct sock *sk = d->session->sock->sk;
236
237 if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) {
238 if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon))
239 return 1;
240 } else if (d->link_mode & RFCOMM_LM_AUTH) {
241 if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon))
242 return 1;
243 }
244
245 return 0;
246}
247
233/* ---- RFCOMM DLCs ---- */ 248/* ---- RFCOMM DLCs ---- */
234static void rfcomm_dlc_timeout(unsigned long arg) 249static void rfcomm_dlc_timeout(unsigned long arg)
235{ 250{
@@ -371,15 +386,23 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
371 d->addr = __addr(s->initiator, dlci); 386 d->addr = __addr(s->initiator, dlci);
372 d->priority = 7; 387 d->priority = 7;
373 388
374 d->state = BT_CONFIG; 389 d->state = BT_CONFIG;
375 rfcomm_dlc_link(s, d); 390 rfcomm_dlc_link(s, d);
376 391
392 d->out = 1;
393
377 d->mtu = s->mtu; 394 d->mtu = s->mtu;
378 d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc; 395 d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
379 396
380 if (s->state == BT_CONNECTED) 397 if (s->state == BT_CONNECTED) {
381 rfcomm_send_pn(s, 1, d); 398 if (rfcomm_check_link_mode(d))
399 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
400 else
401 rfcomm_send_pn(s, 1, d);
402 }
403
382 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); 404 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
405
383 return 0; 406 return 0;
384} 407}
385 408
@@ -1146,21 +1169,6 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
1146 return 0; 1169 return 0;
1147} 1170}
1148 1171
1149static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d)
1150{
1151 struct sock *sk = d->session->sock->sk;
1152
1153 if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) {
1154 if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon))
1155 return 1;
1156 } else if (d->link_mode & RFCOMM_LM_AUTH) {
1157 if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon))
1158 return 1;
1159 }
1160
1161 return 0;
1162}
1163
1164static void rfcomm_dlc_accept(struct rfcomm_dlc *d) 1172static void rfcomm_dlc_accept(struct rfcomm_dlc *d)
1165{ 1173{
1166 struct sock *sk = d->session->sock->sk; 1174 struct sock *sk = d->session->sock->sk;
@@ -1205,10 +1213,8 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
1205 if (rfcomm_check_link_mode(d)) { 1213 if (rfcomm_check_link_mode(d)) {
1206 set_bit(RFCOMM_AUTH_PENDING, &d->flags); 1214 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1207 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); 1215 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
1208 return 0; 1216 } else
1209 } 1217 rfcomm_dlc_accept(d);
1210
1211 rfcomm_dlc_accept(d);
1212 } 1218 }
1213 return 0; 1219 return 0;
1214 } 1220 }
@@ -1223,10 +1229,8 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
1223 if (rfcomm_check_link_mode(d)) { 1229 if (rfcomm_check_link_mode(d)) {
1224 set_bit(RFCOMM_AUTH_PENDING, &d->flags); 1230 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1225 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); 1231 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
1226 return 0; 1232 } else
1227 } 1233 rfcomm_dlc_accept(d);
1228
1229 rfcomm_dlc_accept(d);
1230 } else { 1234 } else {
1231 rfcomm_send_dm(s, dlci); 1235 rfcomm_send_dm(s, dlci);
1232 } 1236 }
@@ -1636,7 +1640,11 @@ static void rfcomm_process_connect(struct rfcomm_session *s)
1636 d = list_entry(p, struct rfcomm_dlc, list); 1640 d = list_entry(p, struct rfcomm_dlc, list);
1637 if (d->state == BT_CONFIG) { 1641 if (d->state == BT_CONFIG) {
1638 d->mtu = s->mtu; 1642 d->mtu = s->mtu;
1639 rfcomm_send_pn(s, 1, d); 1643 if (rfcomm_check_link_mode(d)) {
1644 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
1645 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
1646 } else
1647 rfcomm_send_pn(s, 1, d);
1640 } 1648 }
1641 } 1649 }
1642} 1650}
@@ -1709,7 +1717,11 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
1709 1717
1710 if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) { 1718 if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
1711 rfcomm_dlc_clear_timer(d); 1719 rfcomm_dlc_clear_timer(d);
1712 rfcomm_dlc_accept(d); 1720 if (d->out) {
1721 rfcomm_send_pn(s, 1, d);
1722 rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
1723 } else
1724 rfcomm_dlc_accept(d);
1713 if (d->link_mode & RFCOMM_LM_SECURE) { 1725 if (d->link_mode & RFCOMM_LM_SECURE) {
1714 struct sock *sk = s->sock->sk; 1726 struct sock *sk = s->sock->sk;
1715 hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon); 1727 hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon);
@@ -1717,7 +1729,10 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
1717 continue; 1729 continue;
1718 } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) { 1730 } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
1719 rfcomm_dlc_clear_timer(d); 1731 rfcomm_dlc_clear_timer(d);
1720 rfcomm_send_dm(s, d->dlci); 1732 if (!d->out)
1733 rfcomm_send_dm(s, d->dlci);
1734 else
1735 d->state = BT_CLOSED;
1721 __rfcomm_dlc_close(d, ECONNREFUSED); 1736 __rfcomm_dlc_close(d, ECONNREFUSED);
1722 continue; 1737 continue;
1723 } 1738 }
@@ -1726,7 +1741,7 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
1726 continue; 1741 continue;
1727 1742
1728 if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) && 1743 if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
1729 d->mscex == RFCOMM_MSCEX_OK) 1744 d->mscex == RFCOMM_MSCEX_OK)
1730 rfcomm_process_tx(d); 1745 rfcomm_process_tx(d);
1731 } 1746 }
1732} 1747}
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 5083adcbfae5..cacb1ab51f99 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -309,13 +309,13 @@ static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int
309 sk->sk_destruct = rfcomm_sock_destruct; 309 sk->sk_destruct = rfcomm_sock_destruct;
310 sk->sk_sndtimeo = RFCOMM_CONN_TIMEOUT; 310 sk->sk_sndtimeo = RFCOMM_CONN_TIMEOUT;
311 311
312 sk->sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; 312 sk->sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
313 sk->sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; 313 sk->sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
314 314
315 sock_reset_flag(sk, SOCK_ZAPPED); 315 sock_reset_flag(sk, SOCK_ZAPPED);
316 316
317 sk->sk_protocol = proto; 317 sk->sk_protocol = proto;
318 sk->sk_state = BT_OPEN; 318 sk->sk_state = BT_OPEN;
319 319
320 bt_sock_link(&rfcomm_sk_list, sk); 320 bt_sock_link(&rfcomm_sk_list, sk);
321 321
@@ -413,6 +413,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
413 bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); 413 bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
414 rfcomm_pi(sk)->channel = sa->rc_channel; 414 rfcomm_pi(sk)->channel = sa->rc_channel;
415 415
416 d->link_mode = rfcomm_pi(sk)->link_mode;
417
416 err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); 418 err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
417 if (!err) 419 if (!err)
418 err = bt_sock_wait_state(sk, BT_CONNECTED, 420 err = bt_sock_wait_state(sk, BT_CONNECTED,