Bluetooth: RFCOMM: Handle security for outgoing DLCs
Security needs to be elevated based on dlc required sec_level before creating dlc. If L2CAP connection is not created then setting dlc required sec_level to chan would do the job. Change-Id: I21debd3559c9ccfb79011160d676932bc2a54604 Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
This commit is contained in:
parent
b1d02621fc
commit
dd94c3b3eb
1 changed files with 34 additions and 9 deletions
|
@ -718,29 +718,46 @@ static int rfcomm_send_credit(struct bt_rfcomm_dlc *dlc, uint8_t credits)
|
||||||
return bt_l2cap_chan_send(&dlc->session->br_chan.chan, buf);
|
return bt_l2cap_chan_send(&dlc->session->br_chan.chan, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rfcomm_dlc_start(struct bt_rfcomm_dlc *dlc)
|
static int rfcomm_dlc_start(struct bt_rfcomm_dlc *dlc)
|
||||||
{
|
{
|
||||||
|
enum security_result result;
|
||||||
|
|
||||||
BT_DBG("dlc %p", dlc);
|
BT_DBG("dlc %p", dlc);
|
||||||
|
|
||||||
/* TODO: Need to check Security */
|
result = rfcomm_dlc_security(dlc);
|
||||||
dlc->mtu = min(dlc->mtu, dlc->session->mtu);
|
switch (result) {
|
||||||
dlc->state = BT_RFCOMM_STATE_CONFIG;
|
case RFCOMM_SECURITY_PASSED:
|
||||||
rfcomm_send_pn(dlc, BT_RFCOMM_MSG_CMD_CR);
|
dlc->mtu = min(dlc->mtu, dlc->session->mtu);
|
||||||
|
dlc->state = BT_RFCOMM_STATE_CONFIG;
|
||||||
|
rfcomm_send_pn(dlc, BT_RFCOMM_MSG_CMD_CR);
|
||||||
|
break;
|
||||||
|
case RFCOMM_SECURITY_PENDING:
|
||||||
|
dlc->state = BT_RFCOMM_STATE_SECURITY_PENDING;
|
||||||
|
break;
|
||||||
|
case RFCOMM_SECURITY_REJECT:
|
||||||
|
default:
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rfcomm_handle_ua(struct bt_rfcomm_session *session, uint8_t dlci)
|
static void rfcomm_handle_ua(struct bt_rfcomm_session *session, uint8_t dlci)
|
||||||
{
|
{
|
||||||
struct bt_rfcomm_dlc *dlc;
|
struct bt_rfcomm_dlc *dlc, *tmp;
|
||||||
|
|
||||||
if (!dlci) {
|
if (!dlci) {
|
||||||
if (session->state != BT_RFCOMM_STATE_CONNECTING) {
|
if (session->state != BT_RFCOMM_STATE_CONNECTING) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
session->state = BT_RFCOMM_STATE_CONNECTED;
|
session->state = BT_RFCOMM_STATE_CONNECTED;
|
||||||
for (dlc = session->dlcs; dlc; dlc = dlc->_next) {
|
for (dlc = session->dlcs; dlc; dlc = tmp) {
|
||||||
|
tmp = dlc->_next;
|
||||||
if (dlc->role == BT_RFCOMM_ROLE_INITIATOR &&
|
if (dlc->role == BT_RFCOMM_ROLE_INITIATOR &&
|
||||||
dlc->state == BT_RFCOMM_STATE_INIT) {
|
dlc->state == BT_RFCOMM_STATE_INIT) {
|
||||||
rfcomm_dlc_start(dlc);
|
if (rfcomm_dlc_start(dlc) < 0) {
|
||||||
|
rfcomm_dlc_drop(dlc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1058,6 +1075,10 @@ static void rfcomm_encrypt_change(struct bt_l2cap_chan *chan,
|
||||||
if (dlc->role == BT_RFCOMM_ROLE_ACCEPTOR) {
|
if (dlc->role == BT_RFCOMM_ROLE_ACCEPTOR) {
|
||||||
rfcomm_send_ua(session, dlc->dlci);
|
rfcomm_send_ua(session, dlc->dlci);
|
||||||
rfcomm_dlc_connected(dlc);
|
rfcomm_dlc_connected(dlc);
|
||||||
|
} else {
|
||||||
|
dlc->mtu = min(dlc->mtu, session->mtu);
|
||||||
|
dlc->state = BT_RFCOMM_STATE_CONFIG;
|
||||||
|
rfcomm_send_pn(dlc, BT_RFCOMM_MSG_CMD_CR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1141,6 +1162,7 @@ int bt_rfcomm_dlc_connect(struct bt_conn *conn, struct bt_rfcomm_dlc *dlc,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
chan = &session->br_chan.chan;
|
chan = &session->br_chan.chan;
|
||||||
|
chan->required_sec_level = dlc->required_sec_level;
|
||||||
ret = bt_l2cap_chan_connect(conn, chan, BT_L2CAP_PSM_RFCOMM);
|
ret = bt_l2cap_chan_connect(conn, chan, BT_L2CAP_PSM_RFCOMM);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
session->state = BT_RFCOMM_STATE_IDLE;
|
session->state = BT_RFCOMM_STATE_IDLE;
|
||||||
|
@ -1151,7 +1173,10 @@ int bt_rfcomm_dlc_connect(struct bt_conn *conn, struct bt_rfcomm_dlc *dlc,
|
||||||
case BT_RFCOMM_STATE_CONNECTING:
|
case BT_RFCOMM_STATE_CONNECTING:
|
||||||
break;
|
break;
|
||||||
case BT_RFCOMM_STATE_CONNECTED:
|
case BT_RFCOMM_STATE_CONNECTED:
|
||||||
rfcomm_dlc_start(dlc);
|
ret = rfcomm_dlc_start(dlc);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BT_ERR("Invalid session state %d", session->state);
|
BT_ERR("Invalid session state %d", session->state);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue