diff options
author | Jacob Keeler <jacob.keeler@livioradio.com> | 2018-06-18 08:22:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-18 08:22:27 -0700 |
commit | 7f4db1878dc618e3d8454d9b70b665bf79fea5ed (patch) | |
tree | 9e3aa46ba0691d1f830a0208f585573cb9bd4993 /src/components/protocol_handler | |
parent | 1527db9a68a54e07891ccfad0c2532f0813704d7 (diff) | |
parent | d99d7f2fa71205a5f1a69d07b1abb75ef2c1fc7f (diff) | |
download | sdl_core-7f4db1878dc618e3d8454d9b70b665bf79fea5ed.tar.gz |
Merge pull request #2105 from smartdevicelink/feature/get_system_time
Feature/get system time
Diffstat (limited to 'src/components/protocol_handler')
5 files changed, 93 insertions, 26 deletions
diff --git a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h index 0ef40290f2..2d7d5c148c 100644 --- a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h +++ b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h @@ -90,6 +90,12 @@ class HandshakeHandler : public security_manager::SecurityManagerListener { security_manager::SSLContext::HandshakeResult result) OVERRIDE; /** + * @brief Notification about handshake failure + * @return true on success notification handling or false otherwise + */ + bool OnHandshakeFailed() OVERRIDE; + + /** * @brief Notification that certificate update is required. */ void OnCertificateUpdateRequired() OVERRIDE; diff --git a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h index 0efb81cdd7..4d86a78688 100644 --- a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h +++ b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h @@ -235,6 +235,8 @@ class ProtocolHandlerImpl uint8_t session_id, uint8_t service_type); + void NotifyOnFailedHandshake() OVERRIDE; + // TODO(Ezamakhov): move Ack/Nack as interface for StartSessionHandler /** * \brief Sends acknowledgement of starting session to mobile application @@ -686,7 +688,9 @@ class ProtocolHandlerImpl bool is_ptu_triggered_; std::list<std::shared_ptr<HandshakeHandler> > ptu_pending_handlers_; + std::list<std::shared_ptr<HandshakeHandler> > handshake_handlers_; sync_primitives::Lock ptu_handlers_lock_; + sync_primitives::Lock handshake_handlers_lock_; #endif // ENABLE_SECURITY // Thread that pumps non-parsed messages coming from mobile side. diff --git a/src/components/protocol_handler/src/handshake_handler.cc b/src/components/protocol_handler/src/handshake_handler.cc index 055ff2cf45..24c3127743 100644 --- a/src/components/protocol_handler/src/handshake_handler.cc +++ b/src/components/protocol_handler/src/handshake_handler.cc @@ -92,6 +92,18 @@ bool HandshakeHandler::GetPolicyCertificateData(std::string& data) const { void HandshakeHandler::OnCertificateUpdateRequired() {} +bool HandshakeHandler::OnHandshakeFailed() { + BsonObject params; + if (payload_) { + params = bson_object_from_bytes(payload_.get()); + } else { + bson_object_initialize_default(¶ms); + } + ProcessFailedHandshake(params); + bson_object_deinitialize(¶ms); + return true; +} + bool HandshakeHandler::OnHandshakeDone( uint32_t connection_key, security_manager::SSLContext::HandshakeResult result) { diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index 762b986782..e5bacdbf6f 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -149,6 +149,7 @@ ProtocolHandlerImpl::~ProtocolHandlerImpl() { "Not all observers have unsubscribed" " from ProtocolHandlerImpl"); } + handshake_handlers_.clear(); } void ProtocolHandlerImpl::AddProtocolObserver(ProtocolObserver* observer) { @@ -839,6 +840,11 @@ void ProtocolHandlerImpl::OnConnectionClosed( multiframe_builder_.RemoveConnection(connection_id); } +void ProtocolHandlerImpl::NotifyOnFailedHandshake() { + LOG4CXX_AUTO_TRACE(logger_); + security_manager_->NotifyListenersOnHandshakeFailed(); +} + void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) { LOG4CXX_AUTO_TRACE(logger_); @@ -851,12 +857,14 @@ void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) { return; } - const bool is_cert_expired = security_manager_->IsCertificateUpdateRequired(); for (auto handler : ptu_pending_handlers_) { + const bool is_cert_expired = security_manager_->IsCertificateUpdateRequired( + handler->connection_key()); security_manager::SSLContext* ssl_context = - is_cert_expired - ? NULL - : security_manager_->CreateSSLContext(handler->connection_key()); + is_cert_expired ? NULL + : security_manager_->CreateSSLContext( + handler->connection_key(), + security_manager::SecurityManager::kUseExisting); if (!ssl_context) { const std::string error("CreateSSLContext failed"); @@ -1286,7 +1294,8 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( session_observer_.KeyFromPair(connection_id, session_id); security_manager::SSLContext* ssl_context = - security_manager_->CreateSSLContext(connection_key); + security_manager_->CreateSSLContext( + connection_key, security_manager::SecurityManager::kUseExisting); if (!ssl_context) { const std::string error("CreateSSLContext failed"); LOG4CXX_ERROR(logger_, error); @@ -1563,14 +1572,11 @@ void ProtocolHandlerImpl::NotifySessionStarted( context, packet->protocol_version(), bson_object_bytes); + handshake_handlers_.push_back(handler); const bool is_certificate_empty = security_manager_->IsPolicyCertificateDataEmpty(); - const bool is_certificate_expired = - is_certificate_empty || - security_manager_->IsCertificateUpdateRequired(); - if (context.is_ptu_required_ && is_certificate_empty) { LOG4CXX_DEBUG(logger_, "PTU for StartSessionHandler " @@ -1586,6 +1592,7 @@ void ProtocolHandlerImpl::NotifySessionStarted( ptu_pending_handlers_.push_back(handler); is_ptu_triggered_ = true; security_manager_->NotifyOnCertificateUpdateRequired(); + security_manager_->PostponeHandshake(connection_key); } else { LOG4CXX_DEBUG(logger_, "PTU has been triggered. Added to pending."); ptu_pending_handlers_.push_back(handler); @@ -1594,9 +1601,11 @@ void ProtocolHandlerImpl::NotifySessionStarted( } security_manager::SSLContext* ssl_context = - is_certificate_expired + is_certificate_empty ? NULL - : security_manager_->CreateSSLContext(connection_key); + : security_manager_->CreateSSLContext( + connection_key, + security_manager::SecurityManager::kUseExisting); if (!ssl_context) { const std::string error("CreateSSLContext failed"); LOG4CXX_ERROR(logger_, error); @@ -1630,12 +1639,27 @@ void ProtocolHandlerImpl::NotifySessionStarted( *fullVersion, *start_session_ack_params); } else { - security_manager_->AddListener(new HandshakeHandler(*handler)); + LOG4CXX_DEBUG(logger_, + "Adding Handshake handler to listeners: " << handler.get()); + security_manager::SecurityManagerListener* listener = + new HandshakeHandler(*handler); + security_manager_->AddListener(listener); + if (!ssl_context->IsHandshakePending()) { // Start handshake process security_manager_->StartHandshake(connection_key); + + if (!security_manager_->IsSystemTimeProviderReady()) { + security_manager_->RemoveListener(listener); + SendStartSessionNAck(context.connection_id_, + packet->session_id(), + protocol_version, + packet->service_type(), + rejected_params); + } } } + LOG4CXX_DEBUG(logger_, "Protection establishing for connection " << connection_key << " is in progress"); diff --git a/src/components/protocol_handler/test/protocol_handler_tm_test.cc b/src/components/protocol_handler/test/protocol_handler_tm_test.cc index 8525b1c5b9..075b332345 100644 --- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc +++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc @@ -46,6 +46,7 @@ #include "security_manager/mock_ssl_context.h" #endif // ENABLE_SECURITY #include "transport_manager/mock_transport_manager.h" +#include "utils/mock_system_time_handler.h" #include "utils/make_shared.h" #include "utils/test_async_waiter.h" #include <bson_object.h> @@ -95,8 +96,12 @@ using protocol_handler::kBulk; using protocol_handler::kInvalidServiceType; // For TM states using transport_manager::TransportManagerListener; +using test::components::security_manager_test::MockSystemTimeHandler; using transport_manager::E_SUCCESS; using transport_manager::DeviceInfo; +// For security +using ContextCreationStrategy = + security_manager::SecurityManager::ContextCreationStrategy; // For CH entities using connection_handler::DeviceHandle; // Google Testing Framework Entities @@ -987,7 +992,10 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) { SetProtocolVersion2(); // Expect start protection for unprotected session - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, + CreateSSLContext(connection_key, + security_manager::SecurityManager:: + ContextCreationStrategy::kUseExisting)) . // Return fail protection WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), ReturnNull())); @@ -1042,7 +1050,7 @@ TEST_F(ProtocolHandlerImplTest, SetProtocolVersion2(); // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce( @@ -1119,7 +1127,7 @@ TEST_F(ProtocolHandlerImplTest, .WillOnce(ReturnRefOfCopy(services)); // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce(Return(&ssl_context_mock)); @@ -1198,7 +1206,7 @@ TEST_F(ProtocolHandlerImplTest, times++; // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce( @@ -1296,7 +1304,7 @@ TEST_F( times++; // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce( @@ -1392,7 +1400,10 @@ TEST_F(ProtocolHandlerImplTest, times++; // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, + CreateSSLContext(connection_key, + security_manager::SecurityManager:: + ContextCreationStrategy::kUseExisting)) . // Return new SSLContext WillOnce( @@ -1420,27 +1431,37 @@ TEST_F(ProtocolHandlerImplTest, // Expect add listener for handshake result EXPECT_CALL(security_manager_mock, AddListener(_)) - // Emulate handshake fail - .WillOnce(Invoke(OnHandshakeDoneFunctor( - connection_key, - security_manager::SSLContext::Handshake_Result_Success))); + // Emulate handshake + .WillOnce( + DoAll(NotifyTestAsyncWaiter(&waiter), + Invoke(OnHandshakeDoneFunctor( + connection_key, + security_manager::SSLContext::Handshake_Result_Success)))); + times++; // Listener check SSLContext EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, start_service)) . // Emulate protection for service is not enabled - WillOnce(ReturnNull()); + WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), ReturnNull())); + times++; + + EXPECT_CALL(security_manager_mock, IsSystemTimeProviderReady()) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(true))); + times++; - // Expect service protection enable EXPECT_CALL(session_observer_mock, - SetProtectionFlag(connection_key, start_service)); + SetProtectionFlag(connection_key, start_service)) + .WillOnce(NotifyTestAsyncWaiter(&waiter)); + times++; - // Expect send Ack with PROTECTION_OFF (on fail handshake) + // Expect send Ack with PROTECTION_ON (on successfull handshake) EXPECT_CALL(transport_manager_mock, SendMessageToDevice( ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))) .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; SendControlMessage( |