diff options
Diffstat (limited to 'src/components/protocol_handler/src/protocol_handler_impl.cc')
-rw-r--r-- | src/components/protocol_handler/src/protocol_handler_impl.cc | 206 |
1 files changed, 165 insertions, 41 deletions
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index 222ca635d0..7769696a76 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -104,6 +104,8 @@ ProtocolHandlerImpl::ProtocolHandlerImpl( get_settings().maximum_audio_payload_size()); protocol_header_validator_.set_max_video_payload_size( get_settings().maximum_video_payload_size()); + protocol_header_validator_.set_max_protocol_version_supported( + get_settings().max_supported_protocol_version()); incoming_data_handler_.set_validator(&protocol_header_validator_); const size_t& message_frequency_count = @@ -493,8 +495,9 @@ void ProtocolHandlerImpl::SendStartSessionNAck( BsonArray rejectedParamsArr; bson_array_initialize(&rejectedParamsArr, rejectedParams.size()); for (std::string param : rejectedParams) { - char paramPtr[255]; - strncpy(paramPtr, param.c_str(), 255); + char paramPtr[256]; + strncpy(paramPtr, param.c_str(), sizeof(paramPtr)); + paramPtr[sizeof(paramPtr) - 1] = '\0'; bson_array_add_string(&rejectedParamsArr, paramPtr); } bson_object_put_array( @@ -555,8 +558,9 @@ void ProtocolHandlerImpl::SendEndSessionNAck( BsonArray rejectedParamsArr; bson_array_initialize(&rejectedParamsArr, rejectedParams.size()); for (std::string param : rejectedParams) { - char paramPtr[255]; - strncpy(paramPtr, param.c_str(), 255); + char paramPtr[256]; + strncpy(paramPtr, param.c_str(), sizeof(paramPtr)); + paramPtr[sizeof(paramPtr) - 1] = '\0'; bson_array_add_string(&rejectedParamsArr, paramPtr); } bson_object_put_array( @@ -850,6 +854,7 @@ void ProtocolHandlerImpl::SendHeartBeat(int32_t connection_id, } void ProtocolHandlerImpl::SendMessageToMobileApp(const RawMessagePtr message, + bool needs_encryption, bool final_message) { #ifdef TELEMETRY_MONITOR const date_time::TimeDuration start_time = date_time::getCurrentTime(); @@ -917,6 +922,7 @@ void ProtocolHandlerImpl::SendMessageToMobileApp(const RawMessagePtr message, message->service_type(), message->data_size(), message->data(), + needs_encryption, final_message); if (result != RESULT_OK) { LOG4CXX_ERROR(logger_, @@ -934,6 +940,7 @@ void ProtocolHandlerImpl::SendMessageToMobileApp(const RawMessagePtr message, message->data_size(), message->data(), frame_size, + needs_encryption, final_message); if (result != RESULT_OK) { LOG4CXX_ERROR(logger_, @@ -971,17 +978,17 @@ void ProtocolHandlerImpl::OnTMMessageReceived(const RawMessagePtr tm_message) { size_t malformed_occurs = 0u; const ProtocolFramePtrList protocol_frames = incoming_data_handler_.ProcessData( - *tm_message, &result, &malformed_occurs); - LOG4CXX_DEBUG(logger_, "Proccessed " << protocol_frames.size() << " frames"); + *tm_message, result, &malformed_occurs); + LOG4CXX_DEBUG(logger_, "Processed " << protocol_frames.size() << " frames"); if (result != RESULT_OK) { if (result == RESULT_MALFORMED_OCCURS) { LOG4CXX_WARN( logger_, "Malformed message occurs, connection id " << connection_key); if (!get_settings().malformed_message_filtering()) { - LOG4CXX_DEBUG(logger_, "Malformed message filterign disabled"); + LOG4CXX_DEBUG(logger_, "Malformed message filtering disabled"); session_observer_.OnMalformedMessageCallback(connection_key); - // For tracking only malformed occurrence check outpute + // For tracking only malformed occurrence check output } else { if (malformed_occurs > 0) { TrackMalformedMessage(connection_key, malformed_occurs); @@ -1126,13 +1133,27 @@ void ProtocolHandlerImpl::OnUnexpectedDisconnect( OnConnectionClosed(connection_id); } -void ProtocolHandlerImpl::NotifyOnFailedHandshake() { +void ProtocolHandlerImpl::NotifyOnGetSystemTimeFailed() { LOG4CXX_AUTO_TRACE(logger_); #ifdef ENABLE_SECURITY - security_manager_->NotifyListenersOnHandshakeFailed(); + security_manager_->ResetPendingSystemTimeRequests(); + security_manager_->NotifyListenersOnGetSystemTimeFailed(); #endif // ENABLE_SECURITY } +void ProtocolHandlerImpl::ProcessFailedPTU() { +#ifdef ENABLE_SECURITY + security_manager_->ProcessFailedPTU(); +#endif // ENABLE_SECURITY +} + +#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_); @@ -1210,6 +1231,19 @@ void ProtocolHandlerImpl::OnAuthTokenUpdated(const std::string& policy_app_id, } } +bool ProtocolHandlerImpl::IsRPCServiceSecure( + const uint32_t connection_key) const { + LOG4CXX_AUTO_TRACE(logger_); +#ifdef ENABLE_SECURITY + + security_manager::SSLContext* context = + session_observer_.GetSSLContext(connection_key, ServiceType::kRpc); + return (context && context->IsInitCompleted()); +#else + return false; +#endif // ENABLE_SECURITY +} + RESULT_CODE ProtocolHandlerImpl::SendFrame(const ProtocolFramePtr packet) { LOG4CXX_AUTO_TRACE(logger_); if (!packet) { @@ -1254,13 +1288,18 @@ RESULT_CODE ProtocolHandlerImpl::SendSingleFrameMessage( const uint8_t service_type, const size_t data_size, const uint8_t* data, + const bool needs_encryption, const bool is_final_message) { LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG( + logger_, + "Packet needs encryption: " << std::boolalpha << needs_encryption); + ProtocolFramePtr ptr( new protocol_handler::ProtocolPacket(connection_id, protocol_version, - PROTECTION_OFF, + needs_encryption, FRAME_TYPE_SINGLE, service_type, FRAME_DATA_SINGLE, @@ -1282,6 +1321,7 @@ RESULT_CODE ProtocolHandlerImpl::SendMultiFrameMessage( const size_t data_size, const uint8_t* data, const size_t max_frame_size, + const bool needs_encryption, const bool is_final_message) { LOG4CXX_AUTO_TRACE(logger_); @@ -1322,7 +1362,7 @@ RESULT_CODE ProtocolHandlerImpl::SendMultiFrameMessage( const ProtocolFramePtr firstPacket( new protocol_handler::ProtocolPacket(connection_id, protocol_version, - PROTECTION_OFF, + needs_encryption, FRAME_TYPE_FIRST, service_type, FRAME_DATA_FIRST, @@ -1346,7 +1386,7 @@ RESULT_CODE ProtocolHandlerImpl::SendMultiFrameMessage( const ProtocolFramePtr ptr( new protocol_handler::ProtocolPacket(connection_id, protocol_version, - PROTECTION_OFF, + needs_encryption, FRAME_TYPE_CONSECUTIVE, service_type, data_type, @@ -1408,6 +1448,7 @@ RESULT_CODE ProtocolHandlerImpl::HandleSingleFrameMessage( packet->protocol_version(), packet->data(), packet->total_data_bytes(), + packet->protection_flag(), packet->service_type(), packet->payload_size())); if (!rawMessage) { @@ -1547,7 +1588,8 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageEndSession( << " type."); if (packet.protocol_version() >= PROTOCOL_VERSION_5) { std::vector<std::string> rejectedParams; - if (hash_id == protocol_handler::HASH_ID_WRONG) { + if (hash_id == protocol_handler::HASH_ID_WRONG && + packet.service_type() == kRpc) { rejectedParams.push_back(std::string(strings::hash_id)); } SendEndSessionNAck(connection_id, @@ -1565,6 +1607,59 @@ 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(); + +#ifdef ENABLE_SECURITY + 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 (is_force_protected && !can_start_protected) { + return ServiceStatus::PROTECTION_ENFORCED; + } + + if (is_force_unprotected && !can_start_unprotected) { + return ServiceStatus::UNSECURE_START_FAILED; + } +#endif // ENABLE_SECURITY + + if ((ServiceType::kMobileNav == service_type && !is_video_allowed) || + (ServiceType::kAudio == service_type && !is_audio_allowed)) { + return ServiceStatus::SERVICE_START_FAILED; + } + + return ServiceStatus::INVALID_ENUM; +} + RESULT_CODE ProtocolHandlerImpl::HandleControlMessageEndServiceACK( const ProtocolPacket& packet) { LOG4CXX_AUTO_TRACE(logger_); @@ -1605,27 +1700,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; @@ -1723,14 +1812,22 @@ void ProtocolHandlerImpl::NotifySessionStarted( start_session_frame_map_.erase(it); } + const ServiceType service_type = ServiceTypeFromByte(packet->service_type()); const uint8_t protocol_version = packet->protocol_version(); if (0 == context.new_session_id_) { LOG4CXX_WARN(logger_, "Refused by session_observer to create service " - << packet->service_type() << " type."); + << static_cast<int32_t>(service_type) << " type."); + const auto session_id = packet->session_id(); + const auto connection_key = + session_observer_.KeyFromPair(context.connection_id_, session_id); + service_status_update_handler_->OnServiceUpdate( + connection_key, + context.service_type_, + ServiceStatus::SERVICE_START_FAILED); SendStartSessionNAck(context.connection_id_, - packet->session_id(), + session_id, protocol_version, packet->service_type(), rejected_params); @@ -1738,7 +1835,10 @@ void ProtocolHandlerImpl::NotifySessionStarted( } std::shared_ptr<BsonObject> start_session_ack_params( - new BsonObject(), [](BsonObject* obj) { bson_object_deinitialize(obj); }); + new BsonObject(), [](BsonObject* obj) { + bson_object_deinitialize(obj); + delete obj; + }); bson_object_initialize_default(start_session_ack_params.get()); // when video service is successfully started, copy input parameters // ("width", "height", "videoProtocol", "videoCodec") to the ACK packet @@ -1810,19 +1910,20 @@ void ProtocolHandlerImpl::NotifySessionStarted( } #ifdef ENABLE_SECURITY - const ServiceType service_type = ServiceTypeFromByte(packet->service_type()); // for packet is encrypted and security plugin is enable if (context.is_protected_ && security_manager_) { const uint32_t connection_key = session_observer_.KeyFromPair( 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( @@ -1853,6 +1954,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(), @@ -1889,7 +1994,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(), @@ -1899,6 +2008,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, @@ -1955,6 +2068,7 @@ void ProtocolHandlerImpl::PopValideAndExpirateMultiframes() { frame->protocol_version(), frame->data(), frame->total_data_bytes(), + frame->protection_flag(), frame->service_type(), frame->payload_size())); DCHECK(rawMessage); @@ -2079,6 +2193,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) { @@ -2106,7 +2225,12 @@ RESULT_CODE ProtocolHandlerImpl::EncryptFrame(ProtocolFramePtr packet) { packet->connection_id(), packet->session_id()); security_manager::SSLContext* context = session_observer_.GetSSLContext( connection_key, ServiceTypeFromByte(packet->service_type())); - if (!context || !context->IsInitCompleted()) { + + LOG4CXX_DEBUG( + logger_, + "Protection flag is: " << packet->protection_flag() << std::boolalpha); + if ((!context || !context->IsInitCompleted()) || !packet->protection_flag()) { + LOG4CXX_DEBUG(logger_, "Ecryption is skipped!"); return RESULT_OK; } const uint8_t* out_data; |