aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:54 -0400
committerMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:54 -0400
commitb1235d79611e78a07629b4cbe53291c9cffd1834 (patch)
treeb12b694d991e62a761d48ee4bb12b6eade753f78 /net/bluetooth/l2cap.c
parent7cb127d5b0e7af7a0afd23785722ca3edab4ceff (diff)
[Bluetooth] Allow security for outgoing L2CAP connections
When requested the L2CAP layer will now enforce authentication and encryption on outgoing connections. The usefulness of this feature is kinda limited since it will not allow proper connection ownership tracking until the authentication procedure has been finished. This is a limitation of Bluetooth 2.0 and before and can only be fixed by using Simple Pairing. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r--net/bluetooth/l2cap.c172
1 files changed, 108 insertions, 64 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 4fcf24af7590..c1239852834a 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -76,11 +76,21 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
76static void l2cap_sock_timeout(unsigned long arg) 76static void l2cap_sock_timeout(unsigned long arg)
77{ 77{
78 struct sock *sk = (struct sock *) arg; 78 struct sock *sk = (struct sock *) arg;
79 int reason;
79 80
80 BT_DBG("sock %p state %d", sk, sk->sk_state); 81 BT_DBG("sock %p state %d", sk, sk->sk_state);
81 82
82 bh_lock_sock(sk); 83 bh_lock_sock(sk);
83 __l2cap_sock_close(sk, ETIMEDOUT); 84
85 if (sk->sk_state == BT_CONNECT &&
86 (l2cap_pi(sk)->link_mode & (L2CAP_LM_AUTH |
87 L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)))
88 reason = ECONNREFUSED;
89 else
90 reason = ETIMEDOUT;
91
92 __l2cap_sock_close(sk, reason);
93
84 bh_unlock_sock(sk); 94 bh_unlock_sock(sk);
85 95
86 l2cap_sock_kill(sk); 96 l2cap_sock_kill(sk);
@@ -240,7 +250,7 @@ static void l2cap_chan_del(struct sock *sk, int err)
240 hci_conn_put(conn->hcon); 250 hci_conn_put(conn->hcon);
241 } 251 }
242 252
243 sk->sk_state = BT_CLOSED; 253 sk->sk_state = BT_CLOSED;
244 sock_set_flag(sk, SOCK_ZAPPED); 254 sock_set_flag(sk, SOCK_ZAPPED);
245 255
246 if (err) 256 if (err)
@@ -307,14 +317,16 @@ static void l2cap_do_start(struct sock *sk)
307 struct l2cap_conn *conn = l2cap_pi(sk)->conn; 317 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
308 318
309 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { 319 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
310 struct l2cap_conn_req req; 320 if (l2cap_check_link_mode(sk)) {
311 req.scid = cpu_to_le16(l2cap_pi(sk)->scid); 321 struct l2cap_conn_req req;
312 req.psm = l2cap_pi(sk)->psm; 322 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
323 req.psm = l2cap_pi(sk)->psm;
313 324
314 l2cap_pi(sk)->ident = l2cap_get_ident(conn); 325 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
315 326
316 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 327 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
317 L2CAP_CONN_REQ, sizeof(req), &req); 328 L2CAP_CONN_REQ, sizeof(req), &req);
329 }
318 } else { 330 } else {
319 struct l2cap_info_req req; 331 struct l2cap_info_req req;
320 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); 332 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
@@ -349,14 +361,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
349 } 361 }
350 362
351 if (sk->sk_state == BT_CONNECT) { 363 if (sk->sk_state == BT_CONNECT) {
352 struct l2cap_conn_req req; 364 if (l2cap_check_link_mode(sk)) {
353 req.scid = cpu_to_le16(l2cap_pi(sk)->scid); 365 struct l2cap_conn_req req;
354 req.psm = l2cap_pi(sk)->psm; 366 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
367 req.psm = l2cap_pi(sk)->psm;
355 368
356 l2cap_pi(sk)->ident = l2cap_get_ident(conn); 369 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
357 370
358 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 371 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
359 L2CAP_CONN_REQ, sizeof(req), &req); 372 L2CAP_CONN_REQ, sizeof(req), &req);
373 }
360 } else if (sk->sk_state == BT_CONNECT2) { 374 } else if (sk->sk_state == BT_CONNECT2) {
361 struct l2cap_conn_rsp rsp; 375 struct l2cap_conn_rsp rsp;
362 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 376 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
@@ -455,7 +469,8 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
455 469
456 conn->feat_mask = 0; 470 conn->feat_mask = 0;
457 471
458 setup_timer(&conn->info_timer, l2cap_info_timeout, (unsigned long)conn); 472 setup_timer(&conn->info_timer, l2cap_info_timeout,
473 (unsigned long) conn);
459 474
460 spin_lock_init(&conn->lock); 475 spin_lock_init(&conn->lock);
461 rwlock_init(&conn->chan_list.lock); 476 rwlock_init(&conn->chan_list.lock);
@@ -567,7 +582,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
567 while ((sk = bt_accept_dequeue(parent, NULL))) 582 while ((sk = bt_accept_dequeue(parent, NULL)))
568 l2cap_sock_close(sk); 583 l2cap_sock_close(sk);
569 584
570 parent->sk_state = BT_CLOSED; 585 parent->sk_state = BT_CLOSED;
571 sock_set_flag(parent, SOCK_ZAPPED); 586 sock_set_flag(parent, SOCK_ZAPPED);
572} 587}
573 588
@@ -610,9 +625,8 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
610 req.scid = cpu_to_le16(l2cap_pi(sk)->scid); 625 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
611 l2cap_send_cmd(conn, l2cap_get_ident(conn), 626 l2cap_send_cmd(conn, l2cap_get_ident(conn),
612 L2CAP_DISCONN_REQ, sizeof(req), &req); 627 L2CAP_DISCONN_REQ, sizeof(req), &req);
613 } else { 628 } else
614 l2cap_chan_del(sk, reason); 629 l2cap_chan_del(sk, reason);
615 }
616 break; 630 break;
617 631
618 case BT_CONNECT: 632 case BT_CONNECT:
@@ -681,9 +695,9 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
681 sock_reset_flag(sk, SOCK_ZAPPED); 695 sock_reset_flag(sk, SOCK_ZAPPED);
682 696
683 sk->sk_protocol = proto; 697 sk->sk_protocol = proto;
684 sk->sk_state = BT_OPEN; 698 sk->sk_state = BT_OPEN;
685 699
686 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long)sk); 700 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
687 701
688 bt_sock_link(&l2cap_sk_list, sk); 702 bt_sock_link(&l2cap_sk_list, sk);
689 return sk; 703 return sk;
@@ -1201,7 +1215,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
1201 __l2cap_sock_close(sk, 0); 1215 __l2cap_sock_close(sk, 0);
1202 1216
1203 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) 1217 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
1204 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); 1218 err = bt_sock_wait_state(sk, BT_CLOSED,
1219 sk->sk_lingertime);
1205 } 1220 }
1206 release_sock(sk); 1221 release_sock(sk);
1207 return err; 1222 return err;
@@ -1245,6 +1260,11 @@ static void l2cap_chan_ready(struct sock *sk)
1245 */ 1260 */
1246 parent->sk_data_ready(parent, 0); 1261 parent->sk_data_ready(parent, 0);
1247 } 1262 }
1263
1264 if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) {
1265 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
1266 hci_conn_change_link_key(conn->hcon);
1267 }
1248} 1268}
1249 1269
1250/* Copy frame to all raw sockets on that connection */ 1270/* Copy frame to all raw sockets on that connection */
@@ -1778,7 +1798,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
1778 1798
1779 default: 1799 default:
1780 sk->sk_state = BT_DISCONN; 1800 sk->sk_state = BT_DISCONN;
1781 sk->sk_err = ECONNRESET; 1801 sk->sk_err = ECONNRESET;
1782 l2cap_sock_set_timer(sk, HZ * 5); 1802 l2cap_sock_set_timer(sk, HZ * 5);
1783 { 1803 {
1784 struct l2cap_disconn_req req; 1804 struct l2cap_disconn_req req;
@@ -2151,9 +2171,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status)
2151{ 2171{
2152 struct l2cap_chan_list *l; 2172 struct l2cap_chan_list *l;
2153 struct l2cap_conn *conn = hcon->l2cap_data; 2173 struct l2cap_conn *conn = hcon->l2cap_data;
2154 struct l2cap_conn_rsp rsp;
2155 struct sock *sk; 2174 struct sock *sk;
2156 int result;
2157 2175
2158 if (!conn) 2176 if (!conn)
2159 return 0; 2177 return 0;
@@ -2169,37 +2187,53 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status)
2169 2187
2170 bh_lock_sock(sk); 2188 bh_lock_sock(sk);
2171 2189
2172 if (sk->sk_state != BT_CONNECT2) {
2173 bh_unlock_sock(sk);
2174 continue;
2175 }
2176
2177 if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) && 2190 if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) &&
2178 !(hcon->link_mode & HCI_LM_ENCRYPT)) { 2191 !(hcon->link_mode & HCI_LM_ENCRYPT) &&
2192 !status) {
2179 bh_unlock_sock(sk); 2193 bh_unlock_sock(sk);
2180 continue; 2194 continue;
2181 } 2195 }
2182 2196
2183 if (!status) { 2197 if (sk->sk_state == BT_CONNECT) {
2184 sk->sk_state = BT_CONFIG; 2198 if (!status) {
2185 result = 0; 2199 struct l2cap_conn_req req;
2186 } else { 2200 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
2187 sk->sk_state = BT_DISCONN; 2201 req.psm = l2cap_pi(sk)->psm;
2188 l2cap_sock_set_timer(sk, HZ/10); 2202
2189 result = L2CAP_CR_SEC_BLOCK; 2203 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
2190 } 2204
2205 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2206 L2CAP_CONN_REQ, sizeof(req), &req);
2207 } else {
2208 l2cap_sock_clear_timer(sk);
2209 l2cap_sock_set_timer(sk, HZ / 10);
2210 }
2211 } else if (sk->sk_state == BT_CONNECT2) {
2212 struct l2cap_conn_rsp rsp;
2213 __u16 result;
2214
2215 if (!status) {
2216 sk->sk_state = BT_CONFIG;
2217 result = L2CAP_CR_SUCCESS;
2218 } else {
2219 sk->sk_state = BT_DISCONN;
2220 l2cap_sock_set_timer(sk, HZ / 10);
2221 result = L2CAP_CR_SEC_BLOCK;
2222 }
2191 2223
2192 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 2224 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
2193 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 2225 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2194 rsp.result = cpu_to_le16(result); 2226 rsp.result = cpu_to_le16(result);
2195 rsp.status = cpu_to_le16(0); 2227 rsp.status = cpu_to_le16(0);
2196 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 2228 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2197 L2CAP_CONN_RSP, sizeof(rsp), &rsp); 2229 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
2230 }
2198 2231
2199 bh_unlock_sock(sk); 2232 bh_unlock_sock(sk);
2200 } 2233 }
2201 2234
2202 read_unlock(&l->lock); 2235 read_unlock(&l->lock);
2236
2203 return 0; 2237 return 0;
2204} 2238}
2205 2239
@@ -2207,9 +2241,7 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
2207{ 2241{
2208 struct l2cap_chan_list *l; 2242 struct l2cap_chan_list *l;
2209 struct l2cap_conn *conn = hcon->l2cap_data; 2243 struct l2cap_conn *conn = hcon->l2cap_data;
2210 struct l2cap_conn_rsp rsp;
2211 struct sock *sk; 2244 struct sock *sk;
2212 int result;
2213 2245
2214 if (!conn) 2246 if (!conn)
2215 return 0; 2247 return 0;
@@ -2234,34 +2266,46 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
2234 continue; 2266 continue;
2235 } 2267 }
2236 2268
2237 if (sk->sk_state != BT_CONNECT2) { 2269 if (sk->sk_state == BT_CONNECT) {
2238 bh_unlock_sock(sk); 2270 if (!status) {
2239 continue; 2271 struct l2cap_conn_req req;
2240 } 2272 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
2273 req.psm = l2cap_pi(sk)->psm;
2241 2274
2242 if (!status) { 2275 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
2243 sk->sk_state = BT_CONFIG;
2244 result = 0;
2245 } else {
2246 sk->sk_state = BT_DISCONN;
2247 l2cap_sock_set_timer(sk, HZ/10);
2248 result = L2CAP_CR_SEC_BLOCK;
2249 }
2250 2276
2251 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 2277 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2252 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 2278 L2CAP_CONN_REQ, sizeof(req), &req);
2253 rsp.result = cpu_to_le16(result); 2279 } else {
2254 rsp.status = cpu_to_le16(0); 2280 l2cap_sock_clear_timer(sk);
2255 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 2281 l2cap_sock_set_timer(sk, HZ / 10);
2256 L2CAP_CONN_RSP, sizeof(rsp), &rsp); 2282 }
2283 } else if (sk->sk_state == BT_CONNECT2) {
2284 struct l2cap_conn_rsp rsp;
2285 __u16 result;
2257 2286
2258 if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) 2287 if (!status) {
2259 hci_conn_change_link_key(hcon); 2288 sk->sk_state = BT_CONFIG;
2289 result = L2CAP_CR_SUCCESS;
2290 } else {
2291 sk->sk_state = BT_DISCONN;
2292 l2cap_sock_set_timer(sk, HZ / 10);
2293 result = L2CAP_CR_SEC_BLOCK;
2294 }
2295
2296 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
2297 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2298 rsp.result = cpu_to_le16(result);
2299 rsp.status = cpu_to_le16(0);
2300 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2301 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
2302 }
2260 2303
2261 bh_unlock_sock(sk); 2304 bh_unlock_sock(sk);
2262 } 2305 }
2263 2306
2264 read_unlock(&l->lock); 2307 read_unlock(&l->lock);
2308
2265 return 0; 2309 return 0;
2266} 2310}
2267 2311