aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-01-15 15:58:40 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:26 -0500
commit9f2c8a03fbb3048cf38b158f87aa0c3c09bca084 (patch)
treeb8e81e5a8e3f0b8b8a15c06f1cf36e8aa02644e2
parent2af6b9d518ddfbc4d6990d5f9c9b1a05341c1cef (diff)
Bluetooth: Replace RFCOMM link mode with security level
Change the RFCOMM internals to use the new security levels and remove the link mode details. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/rfcomm.h7
-rw-r--r--net/bluetooth/rfcomm/core.c28
-rw-r--r--net/bluetooth/rfcomm/sock.c75
3 files changed, 79 insertions, 31 deletions
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 71b45f459687..bda68d833ddd 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -183,8 +183,8 @@ struct rfcomm_dlc {
183 u8 remote_v24_sig; 183 u8 remote_v24_sig;
184 u8 mscex; 184 u8 mscex;
185 u8 out; 185 u8 out;
186 186 u8 sec_level;
187 u32 link_mode; 187 u8 role_switch;
188 u32 defer_setup; 188 u32 defer_setup;
189 189
190 uint mtu; 190 uint mtu;
@@ -307,7 +307,8 @@ struct rfcomm_pinfo {
307 struct bt_sock bt; 307 struct bt_sock bt;
308 struct rfcomm_dlc *dlc; 308 struct rfcomm_dlc *dlc;
309 u8 channel; 309 u8 channel;
310 u32 link_mode; 310 u8 sec_level;
311 u8 role_switch;
311}; 312};
312 313
313int rfcomm_init_sockets(void); 314int rfcomm_init_sockets(void);
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 68f70c5270c6..db83f92d274c 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -223,21 +223,11 @@ static int rfcomm_l2sock_create(struct socket **sock)
223 return err; 223 return err;
224} 224}
225 225
226static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) 226static inline int rfcomm_check_security(struct rfcomm_dlc *d)
227{ 227{
228 struct sock *sk = d->session->sock->sk; 228 struct sock *sk = d->session->sock->sk;
229 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
230 229
231 if (d->link_mode & RFCOMM_LM_SECURE) 230 return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level);
232 return hci_conn_security(conn->hcon, BT_SECURITY_HIGH);
233
234 if (d->link_mode & RFCOMM_LM_ENCRYPT)
235 return hci_conn_security(conn->hcon, BT_SECURITY_MEDIUM);
236
237 if (d->link_mode & RFCOMM_LM_AUTH)
238 return hci_conn_security(conn->hcon, BT_SECURITY_LOW);
239
240 return 1;
241} 231}
242 232
243/* ---- RFCOMM DLCs ---- */ 233/* ---- RFCOMM DLCs ---- */
@@ -390,7 +380,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
390 d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc; 380 d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
391 381
392 if (s->state == BT_CONNECTED) { 382 if (s->state == BT_CONNECTED) {
393 if (rfcomm_check_link_mode(d)) 383 if (rfcomm_check_security(d))
394 rfcomm_send_pn(s, 1, d); 384 rfcomm_send_pn(s, 1, d);
395 else 385 else
396 set_bit(RFCOMM_AUTH_PENDING, &d->flags); 386 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
@@ -1192,7 +1182,7 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d)
1192 d->state_change(d, 0); 1182 d->state_change(d, 0);
1193 rfcomm_dlc_unlock(d); 1183 rfcomm_dlc_unlock(d);
1194 1184
1195 if (d->link_mode & RFCOMM_LM_MASTER) 1185 if (d->role_switch)
1196 hci_conn_switch_role(l2cap_pi(sk)->conn->hcon, 0x00); 1186 hci_conn_switch_role(l2cap_pi(sk)->conn->hcon, 0x00);
1197 1187
1198 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig); 1188 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
@@ -1200,7 +1190,7 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d)
1200 1190
1201static void rfcomm_check_accept(struct rfcomm_dlc *d) 1191static void rfcomm_check_accept(struct rfcomm_dlc *d)
1202{ 1192{
1203 if (rfcomm_check_link_mode(d)) { 1193 if (rfcomm_check_security(d)) {
1204 if (d->defer_setup) { 1194 if (d->defer_setup) {
1205 set_bit(RFCOMM_DEFER_SETUP, &d->flags); 1195 set_bit(RFCOMM_DEFER_SETUP, &d->flags);
1206 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); 1196 rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
@@ -1660,7 +1650,7 @@ static void rfcomm_process_connect(struct rfcomm_session *s)
1660 d = list_entry(p, struct rfcomm_dlc, list); 1650 d = list_entry(p, struct rfcomm_dlc, list);
1661 if (d->state == BT_CONFIG) { 1651 if (d->state == BT_CONFIG) {
1662 d->mtu = s->mtu; 1652 d->mtu = s->mtu;
1663 if (rfcomm_check_link_mode(d)) { 1653 if (rfcomm_check_security(d)) {
1664 rfcomm_send_pn(s, 1, d); 1654 rfcomm_send_pn(s, 1, d);
1665 } else { 1655 } else {
1666 set_bit(RFCOMM_AUTH_PENDING, &d->flags); 1656 set_bit(RFCOMM_AUTH_PENDING, &d->flags);
@@ -1748,10 +1738,6 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
1748 } else 1738 } else
1749 rfcomm_dlc_accept(d); 1739 rfcomm_dlc_accept(d);
1750 } 1740 }
1751 if (d->link_mode & RFCOMM_LM_SECURE) {
1752 struct sock *sk = s->sock->sk;
1753 hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon);
1754 }
1755 continue; 1741 continue;
1756 } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) { 1742 } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
1757 rfcomm_dlc_clear_timer(d); 1743 rfcomm_dlc_clear_timer(d);
@@ -1994,7 +1980,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
1994 d = list_entry(p, struct rfcomm_dlc, list); 1980 d = list_entry(p, struct rfcomm_dlc, list);
1995 1981
1996 if (!status && encrypt == 0x00 && 1982 if (!status && encrypt == 0x00 &&
1997 (d->link_mode & RFCOMM_LM_ENCRYPT) && 1983 d->sec_level == BT_SECURITY_HIGH &&
1998 (d->state == BT_CONNECTED || 1984 (d->state == BT_CONNECTED ||
1999 d->state == BT_CONFIG)) { 1985 d->state == BT_CONFIG)) {
2000 __rfcomm_dlc_close(d, ECONNREFUSED); 1986 __rfcomm_dlc_close(d, ECONNREFUSED);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index d37a829a81e4..9986ef35c890 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -261,14 +261,19 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
261 261
262 if (parent) { 262 if (parent) {
263 sk->sk_type = parent->sk_type; 263 sk->sk_type = parent->sk_type;
264 pi->link_mode = rfcomm_pi(parent)->link_mode;
265 pi->dlc->defer_setup = bt_sk(parent)->defer_setup; 264 pi->dlc->defer_setup = bt_sk(parent)->defer_setup;
265
266 pi->sec_level = rfcomm_pi(parent)->sec_level;
267 pi->role_switch = rfcomm_pi(parent)->role_switch;
266 } else { 268 } else {
267 pi->link_mode = 0;
268 pi->dlc->defer_setup = 0; 269 pi->dlc->defer_setup = 0;
270
271 pi->sec_level = BT_SECURITY_LOW;
272 pi->role_switch = 0;
269 } 273 }
270 274
271 pi->dlc->link_mode = pi->link_mode; 275 pi->dlc->sec_level = pi->sec_level;
276 pi->dlc->role_switch = pi->role_switch;
272} 277}
273 278
274static struct proto rfcomm_proto = { 279static struct proto rfcomm_proto = {
@@ -408,7 +413,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
408 bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); 413 bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
409 rfcomm_pi(sk)->channel = sa->rc_channel; 414 rfcomm_pi(sk)->channel = sa->rc_channel;
410 415
411 d->link_mode = rfcomm_pi(sk)->link_mode; 416 d->sec_level = rfcomm_pi(sk)->sec_level;
417 d->role_switch = rfcomm_pi(sk)->role_switch;
412 418
413 err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); 419 err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
414 if (!err) 420 if (!err)
@@ -741,7 +747,14 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
741 break; 747 break;
742 } 748 }
743 749
744 rfcomm_pi(sk)->link_mode = opt; 750 if (opt & RFCOMM_LM_AUTH)
751 rfcomm_pi(sk)->sec_level = BT_SECURITY_LOW;
752 if (opt & RFCOMM_LM_ENCRYPT)
753 rfcomm_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
754 if (opt & RFCOMM_LM_SECURE)
755 rfcomm_pi(sk)->sec_level = BT_SECURITY_HIGH;
756
757 rfcomm_pi(sk)->role_switch = (opt & RFCOMM_LM_MASTER);
745 break; 758 break;
746 759
747 default: 760 default:
@@ -756,7 +769,8 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
756static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) 769static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
757{ 770{
758 struct sock *sk = sock->sk; 771 struct sock *sk = sock->sk;
759 int err = 0; 772 struct bt_security sec;
773 int len, err = 0;
760 u32 opt; 774 u32 opt;
761 775
762 BT_DBG("sk %p", sk); 776 BT_DBG("sk %p", sk);
@@ -767,6 +781,23 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
767 lock_sock(sk); 781 lock_sock(sk);
768 782
769 switch (optname) { 783 switch (optname) {
784 case BT_SECURITY:
785 sec.level = BT_SECURITY_LOW;
786
787 len = min_t(unsigned int, sizeof(sec), optlen);
788 if (copy_from_user((char *) &sec, optval, len)) {
789 err = -EFAULT;
790 break;
791 }
792
793 if (sec.level > BT_SECURITY_HIGH) {
794 err = -EINVAL;
795 break;
796 }
797
798 rfcomm_pi(sk)->sec_level = sec.level;
799 break;
800
770 case BT_DEFER_SETUP: 801 case BT_DEFER_SETUP:
771 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { 802 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
772 err = -EINVAL; 803 err = -EINVAL;
@@ -796,6 +827,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
796 struct sock *l2cap_sk; 827 struct sock *l2cap_sk;
797 struct rfcomm_conninfo cinfo; 828 struct rfcomm_conninfo cinfo;
798 int len, err = 0; 829 int len, err = 0;
830 u32 opt;
799 831
800 BT_DBG("sk %p", sk); 832 BT_DBG("sk %p", sk);
801 833
@@ -806,7 +838,26 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
806 838
807 switch (optname) { 839 switch (optname) {
808 case RFCOMM_LM: 840 case RFCOMM_LM:
809 if (put_user(rfcomm_pi(sk)->link_mode, (u32 __user *) optval)) 841 switch (rfcomm_pi(sk)->sec_level) {
842 case BT_SECURITY_LOW:
843 opt = RFCOMM_LM_AUTH;
844 break;
845 case BT_SECURITY_MEDIUM:
846 opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
847 break;
848 case BT_SECURITY_HIGH:
849 opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
850 RFCOMM_LM_SECURE;
851 break;
852 default:
853 opt = 0;
854 break;
855 }
856
857 if (rfcomm_pi(sk)->role_switch)
858 opt |= RFCOMM_LM_MASTER;
859
860 if (put_user(opt, (u32 __user *) optval))
810 err = -EFAULT; 861 err = -EFAULT;
811 break; 862 break;
812 863
@@ -840,6 +891,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
840static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) 891static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
841{ 892{
842 struct sock *sk = sock->sk; 893 struct sock *sk = sock->sk;
894 struct bt_security sec;
843 int len, err = 0; 895 int len, err = 0;
844 896
845 BT_DBG("sk %p", sk); 897 BT_DBG("sk %p", sk);
@@ -853,6 +905,15 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
853 lock_sock(sk); 905 lock_sock(sk);
854 906
855 switch (optname) { 907 switch (optname) {
908 case BT_SECURITY:
909 sec.level = rfcomm_pi(sk)->sec_level;
910
911 len = min_t(unsigned int, len, sizeof(sec));
912 if (copy_to_user(optval, (char *) &sec, len))
913 err = -EFAULT;
914
915 break;
916
856 case BT_DEFER_SETUP: 917 case BT_DEFER_SETUP:
857 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { 918 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
858 err = -EINVAL; 919 err = -EINVAL;