diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2009-01-15 15:58:40 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-02-27 00:14:26 -0500 |
commit | 9f2c8a03fbb3048cf38b158f87aa0c3c09bca084 (patch) | |
tree | b8e81e5a8e3f0b8b8a15c06f1cf36e8aa02644e2 /net/bluetooth/rfcomm/sock.c | |
parent | 2af6b9d518ddfbc4d6990d5f9c9b1a05341c1cef (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>
Diffstat (limited to 'net/bluetooth/rfcomm/sock.c')
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 75 |
1 files changed, 68 insertions, 7 deletions
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 | ||
274 | static struct proto rfcomm_proto = { | 279 | static 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 | |||
756 | static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | 769 | static 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 | |||
840 | static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) | 891 | static 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; |