Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01b30f00 authored by Martin Brabham's avatar Martin Brabham
Browse files

SecurityModule: Add hooks to ISecurityManagerListener for Dialog notification

Bug: 144375377
Test: atest --host -t bluetooth_test_gd:ClassicPairingHandlerTest
Change-Id: I92a462880cb5cd8ab78c624d7a63085118b90218
parent 0101aa06
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -14,11 +14,13 @@
 * limitations under the License.
 */
#include "security/facade.h"

#include "hci/hci_layer.h"
#include "l2cap/classic/l2cap_classic_module.h"
#include "l2cap/le/l2cap_le_module.h"
#include "os/handler.h"
#include "security/facade.grpc.pb.h"
#include "security/security_manager_listener.h"
#include "security/security_module.h"

namespace bluetooth {
@@ -61,10 +63,13 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public
    return ::grpc::Status::OK;
  }

  void OnDisplayYesNoDialogWithValue(const bluetooth::hci::AddressWithType& address, uint32_t numeric_value) {}
  void OnDisplayYesNoDialog(const bluetooth::hci::AddressWithType& address) {}
  void OnDisplayPasskeyDialog(const bluetooth::hci::AddressWithType& address, uint32_t passkey) {}
  void OnDisplayPasskeyInputDialog(const bluetooth::hci::AddressWithType& address){};
  void OnDisplayCancelDialog(const bluetooth::hci::AddressWithType& address) {}
  void OnDeviceBonded(hci::AddressWithType device) {}

  void OnDeviceUnbonded(hci::AddressWithType device) {}

  void OnDeviceBondFailed(hci::AddressWithType device) {}

 private:
+1 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ void SecurityManagerImpl::DispatchPairingHandler(std::shared_ptr<security::recor
    case hci::AddressType::PUBLIC_DEVICE_ADDRESS:
      pairing_handler = std::make_shared<security::pairing::ClassicPairingHandler>(
          l2cap_classic_module_->GetFixedChannelManager(), security_manager_channel_, record, security_handler_,
          std::move(callback));
          std::move(callback), listeners_);
      break;
    default:
      ASSERT_LOG(false, "Pairing type %hhu not implemented!", record->GetPseudoAddress().GetAddressType());
+52 −16
Original line number Diff line number Diff line
@@ -21,6 +21,41 @@ namespace bluetooth {
namespace security {
namespace pairing {

void ClassicPairingHandler::NotifyUiDisplayYesNo(uint32_t numeric_value) {
  for (auto& iter : client_listeners_) {
    iter.second->Post(common::Bind(&ISecurityManagerListener::OnDisplayYesNoDialogWithValue,
                                   common::Unretained(iter.first), GetRecord()->GetPseudoAddress(), numeric_value));
  }
}

void ClassicPairingHandler::NotifyUiDisplayYesNo() {
  for (auto& iter : client_listeners_) {
    iter.second->Post(common::Bind(&ISecurityManagerListener::OnDisplayYesNoDialog, common::Unretained(iter.first),
                                   GetRecord()->GetPseudoAddress()));
  }
}

void ClassicPairingHandler::NotifyUiDisplayPasskey(uint32_t passkey) {
  for (auto& iter : client_listeners_) {
    iter.second->Post(common::Bind(&ISecurityManagerListener::OnDisplayPasskeyDialog, common::Unretained(iter.first),
                                   GetRecord()->GetPseudoAddress(), passkey));
  }
}

void ClassicPairingHandler::NotifyUiDisplayPasskeyInput() {
  for (auto& iter : client_listeners_) {
    iter.second->Post(common::Bind(&ISecurityManagerListener::OnDisplayPasskeyInputDialog,
                                   common::Unretained(iter.first), GetRecord()->GetPseudoAddress()));
  }
}

void ClassicPairingHandler::NotifyUiDisplayCancel() {
  for (auto& iter : client_listeners_) {
    iter.second->Post(common::Bind(&ISecurityManagerListener::OnDisplayCancelDialog, common::Unretained(iter.first),
                                   GetRecord()->GetPseudoAddress()));
  }
}

void ClassicPairingHandler::OnRegistrationComplete(
    l2cap::classic::FixedChannelManager::RegistrationResult result,
    std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service) {
@@ -54,6 +89,7 @@ void ClassicPairingHandler::OnConnectionOpen(std::unique_ptr<l2cap::classic::Fix
void ClassicPairingHandler::OnConnectionFail(l2cap::classic::FixedChannelManager::ConnectionResult result) {
  Cancel();
}

void ClassicPairingHandler::OnConnectionClose(hci::ErrorCode error_code) {
  // Called when the connection gets closed
  LOG_ERROR("Connection closed due to: %s", hci::ErrorCodeText(error_code).c_str());
@@ -238,8 +274,8 @@ void ClassicPairingHandler::OnReceive(hci::UserConfirmationRequestView packet) {
          break;
        case hci::IoCapability::KEYBOARD_ONLY:
          // PassKey Entry, Initiator display, Responder input
          // TODO(optedoblivion): Notify UI
          LOG_INFO("Notify UI");
          NotifyUiDisplayPasskey(packet.GetNumericValue());
          LOG_INFO("Passkey Entry: A display, B input");
          // Authenticated
          break;
        case hci::IoCapability::NO_INPUT_NO_OUTPUT:
@@ -255,26 +291,26 @@ void ClassicPairingHandler::OnReceive(hci::UserConfirmationRequestView packet) {
      switch (responder_io_capability) {
        case hci::IoCapability::DISPLAY_ONLY:
          // NumericComparison, Initiator display, Responder auto confirm
          // TODO(optedoblivion): Notify UI
          LOG_INFO("Notify UI");
          LOG_INFO("Numeric Comparison: A DisplayYesNo, B auto confirm");
          NotifyUiDisplayYesNo(packet.GetNumericValue());
          // Unauthenticated
          break;
        case hci::IoCapability::DISPLAY_YES_NO:
          // NumericComparison Both Display, Both confirm
          // TODO(optedoblivion): Notify UI
          LOG_INFO("Notify UI");
          LOG_INFO("Numeric Comparison: A and B DisplayYesNo");
          NotifyUiDisplayYesNo(packet.GetNumericValue());
          // Authenticated
          break;
        case hci::IoCapability::KEYBOARD_ONLY:
          // PassKey Entry, Initiator display, Responder input
          // TODO(optedoblivion): Notify UI
          LOG_INFO("Notify UI");
          NotifyUiDisplayPasskey(packet.GetNumericValue());
          LOG_INFO("Passkey Entry: A display, B input");
          // Authenticated
          break;
        case hci::IoCapability::NO_INPUT_NO_OUTPUT:
          // NumericComparison, auto confirm Responder, Yes/No confirm Initiator. Don't show confirmation value
          // TODO(optedoblivion): Notify UI
          LOG_INFO("Notify UI");
          NotifyUiDisplayYesNo();
          LOG_INFO("Numeric Comparison: A DisplayYesNo, B auto confirm, no show value");
          // Unauthenticated
          break;
      }
@@ -283,20 +319,20 @@ void ClassicPairingHandler::OnReceive(hci::UserConfirmationRequestView packet) {
      switch (responder_io_capability) {
        case hci::IoCapability::DISPLAY_ONLY:
          // PassKey Entry, Responder display, Initiator input
          // TODO(optedoblivion): Notify UI
          LOG_INFO("Notify UI");
          NotifyUiDisplayPasskeyInput();
          LOG_INFO("Passkey Entry: A input, B display");
          // Authenticated
          break;
        case hci::IoCapability::DISPLAY_YES_NO:
          // PassKey Entry, Responder display, Initiator input
          // TODO(optedoblivion): Notify UI
          LOG_INFO("Notify UI");
          NotifyUiDisplayPasskeyInput();
          LOG_INFO("Passkey Entry: A input, B display");
          // Authenticated
          break;
        case hci::IoCapability::KEYBOARD_ONLY:
          // PassKey Entry, both input
          // TODO(optedoblivion): Notify UI
          LOG_INFO("Notify UI");
          NotifyUiDisplayPasskeyInput();
          LOG_INFO("Passkey Entry: A input, B input");
          // Authenticated
          break;
        case hci::IoCapability::NO_INPUT_NO_OUTPUT:
+13 −2
Original line number Diff line number Diff line
@@ -23,9 +23,13 @@

#include "l2cap/classic/l2cap_classic_module.h"
#include "security/initial_informations.h"
#include "security/security_manager_listener.h"

namespace bluetooth {
namespace security {

class ISecurityManagerListener;

namespace pairing {

static constexpr hci::IoCapability kDefaultIoCapability = hci::IoCapability::DISPLAY_YES_NO;
@@ -38,13 +42,14 @@ class ClassicPairingHandler : public PairingHandler {
  ClassicPairingHandler(std::shared_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager,
                        channel::SecurityManagerChannel* security_manager_channel,
                        std::shared_ptr<record::SecurityRecord> record, os::Handler* security_handler,
                        common::OnceCallback<void(hci::Address, PairingResultOrFailure)> complete_callback)
                        common::OnceCallback<void(hci::Address, PairingResultOrFailure)> complete_callback,
                        std::vector<std::pair<ISecurityManagerListener*, os::Handler*>>& client_listeners)
      : PairingHandler(security_manager_channel, std::move(record)),
        fixed_channel_manager_(std::move(fixed_channel_manager)), security_policy_(),
        security_handler_(security_handler), remote_io_capability_(kDefaultIoCapability),
        local_io_capability_(kDefaultIoCapability), local_oob_present_(kDefaultOobDataPresent),
        local_authentication_requirements_(kDefaultAuthenticationRequirements),
        complete_callback_(std::move(complete_callback)) {}
        complete_callback_(std::move(complete_callback)), client_listeners_(client_listeners) {}

  ~ClassicPairingHandler() override = default;

@@ -76,6 +81,11 @@ class ClassicPairingHandler : public PairingHandler {
  void OnConnectionOpen(std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel);
  void OnConnectionFail(l2cap::classic::FixedChannelManager::ConnectionResult result);
  void OnConnectionClose(hci::ErrorCode error_code);
  void NotifyUiDisplayYesNo(uint32_t numeric_value);
  void NotifyUiDisplayYesNo();
  void NotifyUiDisplayPasskey(uint32_t passkey);
  void NotifyUiDisplayPasskeyInput();
  void NotifyUiDisplayCancel();

  std::shared_ptr<l2cap::classic::FixedChannelManager> fixed_channel_manager_;
  std::unique_ptr<l2cap::classic::FixedChannelService> fixed_channel_service_{nullptr};
@@ -87,6 +97,7 @@ class ClassicPairingHandler : public PairingHandler {
  hci::AuthenticationRequirements local_authentication_requirements_ __attribute__((unused));
  std::unique_ptr<l2cap::classic::FixedChannel> fixed_channel_{nullptr};
  common::OnceCallback<void(hci::Address, PairingResultOrFailure)> complete_callback_;
  std::vector<std::pair<ISecurityManagerListener*, os::Handler*>>& client_listeners_;
  hci::ErrorCode last_status_;
  bool locally_initiated_ = false;
};
+19 −3
Original line number Diff line number Diff line
@@ -101,6 +101,8 @@ class SecurityManagerChannelCallback : public ISecurityManagerChannelListener {
};

static void pairing_complete_callback(bluetooth::hci::Address address, PairingResultOrFailure status) {
  ASSERT(std::holds_alternative<PairingResult>(status));
  // auto result = std::get<PairingResult>(status);
  //  if (std::holds_alternative<PairingResult>(status)) {
  //    auto result = status::get<PairingResult>(status);
  //  }
@@ -124,7 +126,7 @@ class ClassicPairingHandlerTest : public ::testing::Test {
    EXPECT_CALL(*sptr, RegisterService(::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_))
        .Times(::testing::AnyNumber());
    pairing_handler_ = new pairing::ClassicPairingHandler(sptr, channel_, security_record_, handler_,
                                                          common::Bind(&pairing_complete_callback));
                                                          common::Bind(&pairing_complete_callback), client_listeners_);
    channel_callback_ = new SecurityManagerChannelCallback(pairing_handler_);
    channel_->SetChannelListener(channel_callback_);
  }
@@ -149,6 +151,7 @@ class ClassicPairingHandlerTest : public ::testing::Test {
  channel::SecurityManagerChannel* channel_ = nullptr;
  pairing::ClassicPairingHandler* pairing_handler_ = nullptr;
  std::shared_ptr<record::SecurityRecord> security_record_ = nullptr;
  std::vector<std::pair<ISecurityManagerListener*, os::Handler*>> client_listeners_;
};

// Security Manager Boot Sequence (Required for SSP, these are already set at boot time)
@@ -159,8 +162,8 @@ class ClassicPairingHandlerTest : public ::testing::Test {
/*** Locally initiated ***/
// Security Pairing Sequence (JustWorks)
//  -> *Establish L2CAP connection*
//  -> AuthenticationRequested (should L2CAP request secure service which causes this?)
//  <- LinkKeyRequest
//  -> AuthenticationRequested (L2CAP handles this)
//  <- LinkKeyRequest   // This is entry point for remote initiated
//  -> LinkKeyRequestNegativeReply
//  <- IoCapabilityRequest
//  -> IoCapabilityRequestReply
@@ -213,6 +216,7 @@ hci::SecurityCommandView GetLastCommand(FakeHciLayer* hci_layer) {

TEST_F(ClassicPairingHandlerTest, setup_teardown) {}

/*** JustWorks (Numeric Comparison w/ no UI) ***/
// display_only + display_only is JustWorks no confirmation
// Needs dialog as per security a bug unless pairing is temporary
TEST_F(ClassicPairingHandlerTest, locally_initiatied_display_only_display_only_temp) {
@@ -501,6 +505,18 @@ TEST_F(ClassicPairingHandlerTest, locally_initiatied_no_input_no_output_no_input
  ASSERT_EQ(key_type, security_record_->GetKeyType());
}

/*** Numeric Comparison ***/
// display_yes_no + display_only

// display_yes_no + display_yes_no
// display_yes_no + keyboard_only
// display_yes_no + no_input_no_output

// keyboard_only + display_only
// keyboard_only + display_yes_no

// keyboard_only + keyboard_only  (a just works I missed)

// Remotely initiated

// Collisions
Loading