diff options
Diffstat (limited to 'src/components/protocol_handler/src')
3 files changed, 291 insertions, 47 deletions
diff --git a/src/components/protocol_handler/src/handshake_handler.cc b/src/components/protocol_handler/src/handshake_handler.cc index fa0b375018..669b73c18b 100644 --- a/src/components/protocol_handler/src/handshake_handler.cc +++ b/src/components/protocol_handler/src/handshake_handler.cc @@ -38,23 +38,27 @@ #include "protocol_handler/protocol_packet.h" #include "protocol_handler/session_observer.h" #include "security_manager/security_manager.h" +#include "utils/helpers.h" namespace protocol_handler { CREATE_LOGGERPTR_GLOBAL(logger_, "ProtocolHandler") -HandshakeHandler::HandshakeHandler(ProtocolHandlerImpl& protocol_handler, - SessionObserver& session_observer, - utils::SemanticVersion& full_version, - const SessionContext& context, - const uint8_t protocol_version, - std::shared_ptr<BsonObject> payload) +HandshakeHandler::HandshakeHandler( + ProtocolHandlerImpl& protocol_handler, + SessionObserver& session_observer, + utils::SemanticVersion& full_version, + const SessionContext& context, + const uint8_t protocol_version, + std::shared_ptr<BsonObject> payload, + ServiceStatusUpdateHandler& service_status_update_handler) : protocol_handler_(protocol_handler) , session_observer_(session_observer) , context_(context) , full_version_(full_version) , protocol_version_(protocol_version) - , payload_(payload) {} + , payload_(payload) + , service_status_update_handler_(service_status_update_handler) {} HandshakeHandler::~HandshakeHandler() { LOG4CXX_DEBUG(logger_, "Destroying of HandshakeHandler: " << this); @@ -69,26 +73,53 @@ bool HandshakeHandler::GetPolicyCertificateData(std::string& data) const { return false; } -void HandshakeHandler::OnCertificateUpdateRequired() {} +void HandshakeHandler::OnCertificateUpdateRequired() { + LOG4CXX_AUTO_TRACE(logger_); +} + +#if defined(EXTERNAL_PROPRIETARY_MODE) && defined(ENABLE_SECURITY) +bool HandshakeHandler::OnCertDecryptFailed() { + LOG4CXX_AUTO_TRACE(logger_); + if (payload_) { + ProcessFailedHandshake(*payload_, ServiceStatus::CERT_INVALID); + } + + return true; +} +#endif + +bool HandshakeHandler::OnGetSystemTimeFailed() { + LOG4CXX_AUTO_TRACE(logger_); -bool HandshakeHandler::OnHandshakeFailed() { if (payload_) { - ProcessFailedHandshake(*payload_); + ProcessFailedHandshake(*payload_, ServiceStatus::INVALID_TIME); } else { BsonObject params; bson_object_initialize_default(¶ms); - ProcessFailedHandshake(params); + ProcessFailedHandshake(params, ServiceStatus::INVALID_TIME); bson_object_deinitialize(¶ms); } return true; } +bool HandshakeHandler::OnPTUFailed() { + LOG4CXX_AUTO_TRACE(logger_); + if (payload_) { + ProcessFailedHandshake(*payload_, ServiceStatus::PTU_FAILED); + } + + return true; +} + bool HandshakeHandler::OnHandshakeDone( uint32_t connection_key, security_manager::SSLContext::HandshakeResult result) { LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, + "OnHandshakeDone for service : " << context_.service_type_); + if (connection_key != this->connection_key()) { LOG4CXX_DEBUG(logger_, "Listener " << this @@ -106,7 +137,7 @@ bool HandshakeHandler::OnHandshakeDone( if (success) { ProcessSuccessfulHandshake(connection_key, *payload_); } else { - ProcessFailedHandshake(*payload_); + ProcessFailedHandshake(*payload_, ServiceStatus::CERT_INVALID); } } else { BsonObject params; @@ -114,7 +145,7 @@ bool HandshakeHandler::OnHandshakeDone( if (success) { ProcessSuccessfulHandshake(connection_key, params); } else { - ProcessFailedHandshake(params); + ProcessFailedHandshake(params, ServiceStatus::CERT_INVALID); } bson_object_deinitialize(¶ms); } @@ -122,20 +153,25 @@ bool HandshakeHandler::OnHandshakeDone( return true; } +bool HandshakeHandler::CanBeProtected() const { + const auto& force_unprotected = + protocol_handler_.get_settings().force_unprotected_service(); + + return !(helpers::in_range(force_unprotected, context_.service_type_)); +} + +bool HandshakeHandler::IsAlreadyProtected() const { + return (session_observer_.GetSSLContext(this->connection_key(), + context_.service_type_) != NULL); +} + void HandshakeHandler::ProcessSuccessfulHandshake(const uint32_t connection_key, BsonObject& params) { LOG4CXX_AUTO_TRACE(logger_); - const std::vector<int>& force_unprotected = - protocol_handler_.get_settings().force_unprotected_service(); - const bool can_be_protected = - std::find(force_unprotected.begin(), - force_unprotected.end(), - context_.service_type_) == force_unprotected.end(); + const bool is_service_already_protected = IsAlreadyProtected(); - const bool is_service_already_protected = - session_observer_.GetSSLContext(connection_key, context_.service_type_) != - NULL; + const bool can_be_protected = CanBeProtected(); LOG4CXX_DEBUG(logger_, "Service can be protected: " << can_be_protected @@ -144,6 +180,10 @@ void HandshakeHandler::ProcessSuccessfulHandshake(const uint32_t connection_key, if (can_be_protected && !is_service_already_protected) { session_observer_.SetProtectionFlag(connection_key, context_.service_type_); + service_status_update_handler_.OnServiceUpdate( + this->connection_key(), + context_.service_type_, + ServiceStatus::SERVICE_ACCEPTED); protocol_handler_.SendStartSessionAck(context_.connection_id_, context_.new_session_id_, protocol_version_, @@ -153,6 +193,10 @@ void HandshakeHandler::ProcessSuccessfulHandshake(const uint32_t connection_key, full_version_, params); } else { + service_status_update_handler_.OnServiceUpdate( + this->connection_key(), + context_.service_type_, + ServiceStatus::SERVICE_START_FAILED); protocol_handler_.SendStartSessionNAck(context_.connection_id_, context_.new_session_id_, protocol_version_, @@ -160,7 +204,8 @@ void HandshakeHandler::ProcessSuccessfulHandshake(const uint32_t connection_key, } } -void HandshakeHandler::ProcessFailedHandshake(BsonObject& params) { +void HandshakeHandler::ProcessFailedHandshake(BsonObject& params, + ServiceStatus service_status) { LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, "Handshake failed"); const std::vector<int>& force_protected = @@ -177,6 +222,10 @@ void HandshakeHandler::ProcessFailedHandshake(BsonObject& params) { << context_.is_new_service_); if (can_be_unprotected && context_.is_new_service_) { + service_status_update_handler_.OnServiceUpdate( + this->connection_key(), + context_.service_type_, + ServiceStatus::PROTECTION_DISABLED); protocol_handler_.SendStartSessionAck(context_.connection_id_, context_.new_session_id_, protocol_version_, @@ -186,6 +235,8 @@ void HandshakeHandler::ProcessFailedHandshake(BsonObject& params) { full_version_, params); } else { + service_status_update_handler_.OnServiceUpdate( + this->connection_key(), context_.service_type_, service_status); protocol_handler_.SendStartSessionNAck(context_.connection_id_, context_.new_session_id_, protocol_version_, diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index d95c57f0cc..268af48fdc 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -1129,13 +1129,25 @@ void ProtocolHandlerImpl::OnUnexpectedDisconnect( OnConnectionClosed(connection_id); } -void ProtocolHandlerImpl::NotifyOnFailedHandshake() { +void ProtocolHandlerImpl::NotifyOnGetSystemTimeFailed() { LOG4CXX_AUTO_TRACE(logger_); + security_manager_->ResetPendingSystemTimeRequests(); #ifdef ENABLE_SECURITY - security_manager_->NotifyListenersOnHandshakeFailed(); + security_manager_->NotifyListenersOnGetSystemTimeFailed(); #endif // ENABLE_SECURITY } +void ProtocolHandlerImpl::ProcessFailedPTU() { + security_manager_->ProcessFailedPTU(); +} + +#ifdef EXTERNAL_PROPRIETARY_MODE +void ProtocolHandlerImpl::ProcessFailedCertDecrypt() { + LOG4CXX_AUTO_TRACE(logger_); + security_manager_->ProcessFailedCertDecrypt(); +} +#endif + void ProtocolHandlerImpl::OnTransportConfigUpdated( const transport_manager::transport_adapter::TransportConfig& configs) { LOG4CXX_AUTO_TRACE(logger_); @@ -1584,6 +1596,57 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageEndSession( return RESULT_OK; } +const ServiceStatus ProtocolHandlerImpl::ServiceDisallowedBySettings( + const ServiceType service_type, + const ConnectionID connection_id, + const uint8_t session_id, + const bool protection) const { + LOG4CXX_AUTO_TRACE(logger_); + const std::string& transport = + session_observer_.TransportTypeProfileStringFromConnHandle(connection_id); + + const auto video_transports = settings_.video_service_transports(); + const bool is_video_allowed = + video_transports.empty() || + std::find(video_transports.begin(), video_transports.end(), transport) != + video_transports.end(); + + const auto audio_transports = settings_.audio_service_transports(); + const bool is_audio_allowed = + audio_transports.empty() || + std::find(audio_transports.begin(), audio_transports.end(), transport) != + audio_transports.end(); + + const auto& force_protected = get_settings().force_protected_service(); + + const auto& force_unprotected = get_settings().force_unprotected_service(); + + const bool is_force_protected = + (helpers::in_range(force_protected, service_type)); + + const bool is_force_unprotected = + (helpers::in_range(force_unprotected, service_type)); + + const bool can_start_protected = is_force_protected && protection; + + const bool can_start_unprotected = is_force_unprotected && !protection; + + if ((ServiceType::kMobileNav == service_type && !is_video_allowed) || + (ServiceType::kAudio == service_type && !is_audio_allowed)) { + return ServiceStatus::SERVICE_START_FAILED; + } + + if (is_force_protected && !can_start_protected) { + return ServiceStatus::PROTECTION_ENFORCED; + } + + if (is_force_unprotected && !can_start_unprotected) { + return ServiceStatus::UNSECURE_START_FAILED; + } + + return ServiceStatus::INVALID_ENUM; +} + RESULT_CODE ProtocolHandlerImpl::HandleControlMessageEndServiceACK( const ProtocolPacket& packet) { LOG4CXX_AUTO_TRACE(logger_); @@ -1624,27 +1687,21 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( const ConnectionID connection_id = packet->connection_id(); const uint8_t session_id = packet->session_id(); - const std::string& transport = - session_observer_.TransportTypeProfileStringFromConnHandle(connection_id); + const uint32_t connection_key = + session_observer_.KeyFromPair(connection_id, session_id); - const auto video_transports = settings_.video_service_transports(); - const bool is_video_allowed = - video_transports.empty() || - std::find(video_transports.begin(), video_transports.end(), transport) != - video_transports.end(); + service_status_update_handler_->OnServiceUpdate( + connection_key, service_type, ServiceStatus::SERVICE_RECEIVED); - const auto audio_transports = settings_.audio_service_transports(); - const bool is_audio_allowed = - audio_transports.empty() || - std::find(audio_transports.begin(), audio_transports.end(), transport) != - audio_transports.end(); + const auto settings_check = ServiceDisallowedBySettings( + service_type, connection_id, session_id, protection); - if ((ServiceType::kMobileNav == service_type && !is_video_allowed) || - (ServiceType::kAudio == service_type && !is_audio_allowed)) { + if (ServiceStatus::INVALID_ENUM != settings_check) { LOG4CXX_DEBUG(logger_, "Rejecting StartService for service:" - << service_type << ", over transport: " << transport - << ", disallowed by settings."); + << service_type << ", disallowed by settings."); + service_status_update_handler_->OnServiceUpdate( + connection_key, service_type, settings_check); SendStartSessionNAck( connection_id, session_id, protocol_version, service_type); return RESULT_OK; @@ -1836,12 +1893,14 @@ void ProtocolHandlerImpl::NotifySessionStarted( context.connection_id_, context.new_session_id_); std::shared_ptr<HandshakeHandler> handler = - std::make_shared<HandshakeHandler>(*this, - session_observer_, - *fullVersion, - context, - packet->protocol_version(), - start_session_ack_params); + std::make_shared<HandshakeHandler>( + *this, + session_observer_, + *fullVersion, + context, + packet->protocol_version(), + start_session_ack_params, + *(service_status_update_handler_.get())); security_manager::SSLContext* ssl_context = security_manager_->CreateSSLContext( @@ -1872,6 +1931,10 @@ void ProtocolHandlerImpl::NotifySessionStarted( // mark service as protected session_observer_.SetProtectionFlag(connection_key, service_type); // Start service as protected with current SSLContext + service_status_update_handler_->OnServiceUpdate( + connection_key, + context.service_type_, + ServiceStatus::SERVICE_ACCEPTED); SendStartSessionAck(context.connection_id_, context.new_session_id_, packet->protocol_version(), @@ -1908,7 +1971,11 @@ void ProtocolHandlerImpl::NotifySessionStarted( return; } #endif // ENABLE_SECURITY + const uint32_t connection_key = session_observer_.KeyFromPair( + context.connection_id_, context.new_session_id_); if (rejected_params.empty()) { + service_status_update_handler_->OnServiceUpdate( + connection_key, context.service_type_, ServiceStatus::SERVICE_ACCEPTED); SendStartSessionAck(context.connection_id_, context.new_session_id_, packet->protocol_version(), @@ -1918,6 +1985,10 @@ void ProtocolHandlerImpl::NotifySessionStarted( *fullVersion, *start_session_ack_params); } else { + service_status_update_handler_->OnServiceUpdate( + connection_key, + context.service_type_, + ServiceStatus::SERVICE_START_FAILED); SendStartSessionNAck(context.connection_id_, packet->session_id(), protocol_version, @@ -2099,6 +2170,11 @@ void ProtocolHandlerImpl::Stop() { start_session_frame_map_.clear(); } +void ProtocolHandlerImpl::set_service_status_update_handler( + std::unique_ptr<ServiceStatusUpdateHandler> handler) { + service_status_update_handler_ = std::move(handler); +} + #ifdef ENABLE_SECURITY void ProtocolHandlerImpl::set_security_manager( security_manager::SecurityManager* security_manager) { diff --git a/src/components/protocol_handler/src/service_status_update_handler.cc b/src/components/protocol_handler/src/service_status_update_handler.cc new file mode 100644 index 0000000000..7b2c67ea23 --- /dev/null +++ b/src/components/protocol_handler/src/service_status_update_handler.cc @@ -0,0 +1,117 @@ +#include "protocol_handler/service_status_update_handler.h" +#include "interfaces/HMI_API.h" + +namespace protocol_handler { + +CREATE_LOGGERPTR_GLOBAL(logger_, "ServiceStatusUpdateHandler") + +hmi_apis::Common_ServiceType::eType GetHMIServiceType( + protocol_handler::ServiceType service_type) { + using namespace hmi_apis; + using namespace protocol_handler; + switch (service_type) { + case SERVICE_TYPE_RPC: { + return Common_ServiceType::RPC; + } + case SERVICE_TYPE_AUDIO: { + return Common_ServiceType::AUDIO; + } + case SERVICE_TYPE_NAVI: { + return Common_ServiceType::VIDEO; + } + default: { return Common_ServiceType::INVALID_ENUM; } + } +} + +void ServiceStatusUpdateHandler::OnServiceUpdate( + const uint32_t connection_key, + const protocol_handler::ServiceType service_type, + ServiceStatus service_status) { + using namespace hmi_apis; + typedef utils::Optional<Common_ServiceStatusUpdateReason::eType> + UpdateReasonOptional; + LOG4CXX_AUTO_TRACE(logger_); + auto hmi_service_type = GetHMIServiceType(service_type); + + switch (service_status) { + case ServiceStatus::SERVICE_RECEIVED: { + return listener_->ProcessServiceStatusUpdate( + connection_key, + hmi_service_type, + Common_ServiceEvent::REQUEST_RECEIVED, + UpdateReasonOptional(UpdateReasonOptional::EMPTY)); + } + case ServiceStatus::SERVICE_ACCEPTED: { + return listener_->ProcessServiceStatusUpdate( + connection_key, + hmi_service_type, + Common_ServiceEvent::REQUEST_ACCEPTED, + UpdateReasonOptional(UpdateReasonOptional::EMPTY)); + } + case ServiceStatus::SERVICE_START_FAILED: { + return listener_->ProcessServiceStatusUpdate( + connection_key, + hmi_service_type, + Common_ServiceEvent::REQUEST_REJECTED, + UpdateReasonOptional(UpdateReasonOptional::EMPTY)); + } + case ServiceStatus::PTU_FAILED: { + auto update_reason = Common_ServiceStatusUpdateReason::PTU_FAILED; + return listener_->ProcessServiceStatusUpdate( + connection_key, + hmi_service_type, + Common_ServiceEvent::REQUEST_REJECTED, + update_reason); + } + case ServiceStatus::CERT_INVALID: { + auto update_reason = Common_ServiceStatusUpdateReason::INVALID_CERT; + return listener_->ProcessServiceStatusUpdate( + connection_key, + hmi_service_type, + Common_ServiceEvent::REQUEST_REJECTED, + update_reason); + } + case ServiceStatus::INVALID_TIME: { + auto update_reason = Common_ServiceStatusUpdateReason::INVALID_TIME; + return listener_->ProcessServiceStatusUpdate( + connection_key, + hmi_service_type, + Common_ServiceEvent::REQUEST_REJECTED, + update_reason); + } + case ServiceStatus::PROTECTION_ENFORCED: { + auto update_reason = + Common_ServiceStatusUpdateReason::PROTECTION_ENFORCED; + return listener_->ProcessServiceStatusUpdate( + connection_key, + hmi_service_type, + Common_ServiceEvent::REQUEST_REJECTED, + update_reason); + } + case ServiceStatus::PROTECTION_DISABLED: { + auto update_reason = + Common_ServiceStatusUpdateReason::PROTECTION_DISABLED; + return listener_->ProcessServiceStatusUpdate( + connection_key, + hmi_service_type, + Common_ServiceEvent::REQUEST_ACCEPTED, + update_reason); + } + case ServiceStatus::UNSECURE_START_FAILED: { + auto update_reason = + Common_ServiceStatusUpdateReason::PROTECTION_DISABLED; + return listener_->ProcessServiceStatusUpdate( + connection_key, + hmi_service_type, + Common_ServiceEvent::REQUEST_REJECTED, + update_reason); + } + default: { + LOG4CXX_WARN(logger_, + "Received unknown ServiceStatus: " + << static_cast<int32_t>(service_status)); + return; + } + } +} +} // namespace protocol_handler |