From beedfc022282b2e13c4a5ca334b3fea1ada97d73 Mon Sep 17 00:00:00 2001 From: "matthias.ringwald@gmail.com" Date: Mon, 6 Jan 2014 18:37:25 +0000 Subject: [PATCH] try to authorize an authenticated connection if required to access attribute --- ble/att_server.c | 16 ++++++++++++++++ ble/sm.c | 21 ++++++++++----------- ble/sm.h | 12 ++++++++++-- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/ble/att_server.c b/ble/att_server.c index 3f2bf13d4..2a0a5a780 100644 --- a/ble/att_server.c +++ b/ble/att_server.c @@ -218,6 +218,22 @@ static void att_run(void){ uint8_t att_response_buffer[28]; uint16_t att_response_size = att_handle_request(&att_connection, att_request_buffer, att_request_size, att_response_buffer); + + // intercept "insufficient authorization" for authenticated connections to allow for user authorization + if (att_response_buffer[0] == ATT_ERROR_RESPONSE + && att_response_buffer[4] == ATT_ERROR_INSUFFICIENT_AUTHORIZATION + && att_connection.authenticated){ + switch (sm_authorization_state(att_client_addr_type, att_client_address)){ + case AUTHORIZATION_UNKNOWN: + sm_request_authorization(att_client_addr_type, att_client_address); + return; + case AUTHORIZATION_PENDING: + return; + default: + break; + } + } + att_server_state = ATT_SERVER_IDLE; if (att_response_size == 0) return; diff --git a/ble/sm.c b/ble/sm.c index 00c3c5e29..777b9cd2c 100644 --- a/ble/sm.c +++ b/ble/sm.c @@ -204,7 +204,7 @@ static bd_addr_t sm_s_address; static uint8_t sm_actual_encryption_key_size; static uint8_t sm_connection_encrypted; static uint8_t sm_connection_authenticated; // [0..1] -static uint8_t sm_connection_authorized; +static uint8_t sm_connection_authorization_state; // PER INSTANCE DATA @@ -518,7 +518,7 @@ static void sm_notify_client_authorization(uint8_t type, uint8_t addr_type, bd_a BD_ADDR_COPY(event.address, address); event.authorization_result = result; - log_info("sm_notify_client_authorization %02x, addres_type %u, address (), result %u, index %u", event.type, event.addr_type, event.authorization_result); + log_info("sm_notify_client_authorization %02x, address_type %u, address (), result %u", event.type, event.addr_type, event.authorization_result); if (!sm_client_packet_handler) return; sm_client_packet_handler(HCI_EVENT_PACKET, 0, (uint8_t*) &event, sizeof(event)); @@ -1285,7 +1285,7 @@ static void sm_event_packet_handler (void * connection, uint8_t packet_type, uin // reset security properties sm_connection_encrypted = 0; sm_connection_authenticated = 0; - sm_connection_authorized = 0; + sm_connection_authorization_state = AUTHORIZATION_UNKNOWN; // request security if (sm_s_request_security){ @@ -1692,31 +1692,30 @@ int sm_authenticated(uint8_t addr_type, bd_addr_t address){ return sm_connection_authenticated; } -int sm_authorized(uint8_t addr_type, bd_addr_t address){ +authorization_state_t sm_authorization_state(uint8_t addr_type, bd_addr_t address){ if (!sm_get_connection(addr_type, address)) return 0; // wrong connection if (!sm_connection_encrypted) return 0; // unencrypted connection cannot be authorized if (!sm_connection_authenticated) return 0; // unauthenticatd connection cannot be authorized - return sm_connection_authorized; + return sm_connection_authorization_state; } // request authorization void sm_request_authorization(uint8_t addr_type, bd_addr_t address){ + sm_connection_authorization_state = AUTHORIZATION_PENDING; sm_notify_client(SM_AUTHORIZATION_REQUEST, sm_m_addr_type, sm_m_address, 0, 0); } // called by client app on authorization request void sm_authorization_decline(uint8_t addr_type, bd_addr_t address){ if (!sm_get_connection(addr_type, address)) return; // wrong connection - sm_connection_authorized = 0; - // post event - sm_notify_client_authorization(SM_AUTHORIZATION_RESULT, sm_m_addr_type, sm_m_address, sm_connection_authorized); + sm_connection_authorization_state = AUTHORIZATION_DECLINED; + sm_notify_client_authorization(SM_AUTHORIZATION_RESULT, sm_m_addr_type, sm_m_address, 0); } void sm_authorization_grant(uint8_t addr_type, bd_addr_t address){ if (!sm_get_connection(addr_type, address)) return; // wrong connection - sm_connection_authorized = 1; - // post event - sm_notify_client_authorization(SM_AUTHORIZATION_RESULT, sm_m_addr_type, sm_m_address, sm_connection_authorized); + sm_connection_authorization_state = AUTHORIZATION_GRANTED; + sm_notify_client_authorization(SM_AUTHORIZATION_RESULT, sm_m_addr_type, sm_m_address, 1); } // GAP Bonding API diff --git a/ble/sm.h b/ble/sm.h index 920af38a2..19eb93166 100644 --- a/ble/sm.h +++ b/ble/sm.h @@ -70,6 +70,14 @@ typedef enum { IO_CAPABILITY_UNKNOWN = 0xff } io_capability_t; +// Authorization state +typedef enum { + AUTHORIZATION_UNKNOWN, + AUTHORIZATION_PENDING, + AUTHORIZATION_DECLINED, + AUTHORIZATION_GRANTED +} authorization_state_t; + // Authentication requirement flags #define SM_AUTHREQ_NO_BONDING 0x00 #define SM_AUTHREQ_BONDING 0x01 @@ -142,8 +150,8 @@ int sm_encryption_key_size(uint8_t addr_type, bd_addr_t address); // @returns 1 if bonded with OOB/Passkey (AND MITM protection) int sm_authenticated(uint8_t addr_type, bd_addr_t address); -// @returns 1 if connection was authorized by client app (for this session) -int sm_authorized(uint8_t addr_type, bd_addr_t address); +// @returns authorization_state for the current session +authorization_state_t sm_authorization_state(uint8_t addr_type, bd_addr_t address); // request authorization void sm_request_authorization(uint8_t addr_type, bd_addr_t address);