From 3b56ac9a03fcb37fc6c8784bc1e9fecb9311fb71 Mon Sep 17 00:00:00 2001 From: bsolonenko Date: Tue, 26 Mar 2019 14:26:26 +0200 Subject: Added logic for processing RPC according to the proposal. --- .../include/application_manager/message.h | 15 ++ .../application_manager/rpc_protection_manager.h | 123 ++++++++++++++ .../rpc_protection_manager_impl.h | 97 +++++++++++ .../include/application_manager/rpc_service_impl.h | 19 ++- .../application_manager/smart_object_keys.h | 2 + .../rc_get_interior_vehicle_data_consent_test.cc | 13 +- .../src/application_manager_impl.cc | 15 +- src/components/application_manager/src/message.cc | 16 +- .../src/mobile_message_handler.cc | 5 +- .../application_manager/src/rpc_handler_impl.cc | 2 + .../src/rpc_protection_manager_impl.cc | 187 +++++++++++++++++++++ .../application_manager/src/rpc_service_impl.cc | 95 ++++++++++- .../application_manager/src/smart_object_keys.cc | 2 + .../mock_rpc_protection_manager.h | 66 ++++++++ .../test/policy_handler_test.cc | 53 ++++-- .../rpc_encryption_data_accessor_interface.h | 95 +++++++++++ src/components/include/protocol/raw_message.h | 4 + .../include/protocol_handler/protocol_handler.h | 4 + .../policies/mock_policy_handler_interface.h | 3 + src/components/interfaces/MOBILE_API.xml | 5 + .../policy_external/src/policy_table/enums.cc | 164 ++++++++++++++++++ src/components/protocol/src/raw_message.cc | 6 + src/components/protocol_handler/CMakeLists.txt | 1 + .../protocol_handler/protocol_handler_impl.h | 5 + .../protocol_handler/src/protocol_handler_impl.cc | 37 +++- .../protocol_handler/src/protocol_packet.cc | 1 + .../security_manager/src/security_manager_impl.cc | 3 +- .../src/cloud/websocket_client_connection.cc | 2 +- .../threaded_socket_connection.cc | 2 +- .../src/usb/libusb/usb_connection.cc | 2 +- .../src/usb/qnx/usb_connection.cc | 2 +- 31 files changed, 999 insertions(+), 47 deletions(-) create mode 100644 src/components/application_manager/include/application_manager/rpc_protection_manager.h create mode 100644 src/components/application_manager/include/application_manager/rpc_protection_manager_impl.h create mode 100644 src/components/application_manager/src/rpc_protection_manager_impl.cc create mode 100644 src/components/application_manager/test/include/application_manager/mock_rpc_protection_manager.h create mode 100644 src/components/include/application_manager/policies/rpc_encryption_data_accessor_interface.h diff --git a/src/components/application_manager/include/application_manager/message.h b/src/components/application_manager/include/application_manager/message.h index 7525ff1aa3..1ce7596bf2 100644 --- a/src/components/application_manager/include/application_manager/message.h +++ b/src/components/application_manager/include/application_manager/message.h @@ -71,6 +71,12 @@ class Message { int32_t correlation_id() const; int32_t connection_key() const; + /** + * @brief retreives message's protection flag + * @return true if message is encrypted, otherwise returns false + */ + bool is_message_encrypted() const; + MessageType type() const; protocol_handler::MajorProtocolVersion protocol_version() const; @@ -95,6 +101,13 @@ class Message { void set_data_size(size_t data_size); void set_payload_size(size_t payload_size); + /** + * @brief sets message's protection flag + * @param protection - bool value, if message is encrypted - true, otherwise + * - false + */ + void set_message_encryption(const bool protection); + static bool is_sufficient_version( protocol_handler::MajorProtocolVersion minVersion, protocol_handler::MajorProtocolVersion version); @@ -122,6 +135,8 @@ class Message { size_t data_size_; size_t payload_size_; protocol_handler::MajorProtocolVersion version_; + + bool is_message_encrypted_; }; typedef std::shared_ptr MobileMessage; diff --git a/src/components/application_manager/include/application_manager/rpc_protection_manager.h b/src/components/application_manager/include/application_manager/rpc_protection_manager.h new file mode 100644 index 0000000000..0a272117ea --- /dev/null +++ b/src/components/application_manager/include/application_manager/rpc_protection_manager.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_PROTOCOL_HANDLER_RPC_PROTECTION_MANAGER_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_PROTOCOL_HANDLER_RPC_PROTECTION_MANAGER_H_ + +#include +#include + +#include "application_manager/application.h" +#include "smart_objects/smart_object.h" + +namespace ns_smart_device_link { +namespace ns_smart_objects { +class SmartObject; +} // namespace ns_smart_objects +} // namespace ns_smart_device_link +namespace smart_objects = ns_smart_device_link::ns_smart_objects; + +namespace application_manager { +class Application; +} // namespace application_manager + +namespace application_manager { +/** + * @brief RPCProtectionManager interface + * This entity exists to get info from policy table regarding encryption on + * application and function group level, as well as make decisions whether + * certain RPC should be encrypted or not. + * It mediates communication between PRCService and + * PolicyEncryptionFlagGetterInterface which is implemented by PolicyManager, + * providing adequate level of abstraction. + */ +class RPCProtectionManager { + public: + /* + * @brief virtual destructor RPCProtectionManager + */ + virtual ~RPCProtectionManager() {} + + /* + * @brief checks whether given rpc requires encryption by policy + * @param function_id function id + * @param app ref to Application + * @param is_rpc_service_secure the flag the secure service started + * @return true if function need encryption for current app, else false + */ + virtual bool CheckPolicyEncryptionFlag( + const uint32_t function_id, + const ApplicationSharedPtr app, + const uint32_t conrrelation_id, + const bool is_rpc_service_secure) const = 0; + /* + * @brief check whether given rpc is saved to internal cache and needs to be + * encrypted before sending to mobile + * @param app_id application id + * @param correlation_id conrrelation id + * @return true if the message with correlation id correlation_id needed e + * ncryption else false + */ + virtual bool IsInEncryptionNeededCache( + const uint32_t app_id, const uint32_t conrrelation_id) const = 0; + /* + * @brief create encryption needed response in case when received unencrypted + * rpc that requires encryption + * @param connection_key connection key + * @param function_id function id + * @param conrrelation_id conrrelation id + * @return response with error code ENCRYPTION_NEEDED + */ + virtual smart_objects::SmartObjectSPtr CreateEncryptionNeededResponse( + const uint32_t connection_key, + const uint32_t function_id, + const uint32_t conrrelation_id) = 0; + + /* + * @brief Adds app id and correlation id of a message to internal cache + * @param app_id application if + * @param correlation_id correlation id + */ + virtual void AddToEncryptionNeededCache(const uint32_t app_id, + const uint32_t correlation_id) = 0; + + /* + * @brief Removes app id and correlation id of a message from internal cache + * @param app_id application if + * @param correlation_id correlation id + */ + virtual void RemoveFromEncryptionNeededCache( + const uint32_t app_id, const uint32_t correlation_id) = 0; +}; +} // namespace policy + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_PROTOCOL_HANDLER_RPC_PROTECTION_MANAGER_H_ diff --git a/src/components/application_manager/include/application_manager/rpc_protection_manager_impl.h b/src/components/application_manager/include/application_manager/rpc_protection_manager_impl.h new file mode 100644 index 0000000000..35217f1591 --- /dev/null +++ b/src/components/application_manager/include/application_manager/rpc_protection_manager_impl.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_PROTOCOL_HANDLER_RPC_PROTECTION_MANAGER_IMPL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_PROTOCOL_HANDLER_RPC_PROTECTION_MANAGER_IMPL_H_ + +#include +#include "application_manager/rpc_protection_manager.h" +#include "application_manager/policies/policy_handler.h" + +namespace application_manager { +/* +* @brief RPCProtectionManager implementation +*/ +class RPCProtectionManagerImpl : public RPCProtectionManager { + public: + RPCProtectionManagerImpl(policy::PolicyHandlerInterface& policy_handler); + + ~RPCProtectionManagerImpl() OVERRIDE {} + + bool CheckPolicyEncryptionFlag( + const uint32_t function_id, + const ApplicationSharedPtr app, + const uint32_t conrrelation_id, + const bool is_rpc_service_secure) const OVERRIDE; + + bool IsInEncryptionNeededCache(const uint32_t app_id, + const uint32_t conrrelation_id) const OVERRIDE; + + smart_objects::SmartObjectSPtr CreateEncryptionNeededResponse( + const uint32_t connection_key, + const uint32_t function_id, + const uint32_t conrrelation_id) OVERRIDE; + + void AddToEncryptionNeededCache(const uint32_t app_id, + const uint32_t correlation_id) OVERRIDE; + + void RemoveFromEncryptionNeededCache(const uint32_t app_id, + const uint32_t correlation_id) OVERRIDE; + + private: + /* + * @brief check whether given rpc is an exeption + * @param function_id function id + * @return true if function_id is an exception (rpc that can be sent before + * app is registered, hence before secure rpc service is established) + */ + bool IsExceptionRPC(const uint32_t function_id) const; + + /* + * @brief checks whether given function is in functional group + * @param function_name function name + * @param group group name + * @return true if the function exists in group else return false + */ + bool IsFunctionInGroup(const std::string& function_name, + const std::string& group) const; + + policy::PolicyHandlerInterface& policy_handler_; + + typedef std::pair AppIdCorrIdPair; + + std::set encryption_needed_cache_; + sync_primitives::Lock message_needed_encryption_lock_; +}; +} // namespace policy + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_PROTOCOL_HANDLER_RPC_PROTECTION_MANAGER_IMPL_H_ diff --git a/src/components/application_manager/include/application_manager/rpc_service_impl.h b/src/components/application_manager/include/application_manager/rpc_service_impl.h index ab71729b3f..a33570e180 100644 --- a/src/components/application_manager/include/application_manager/rpc_service_impl.h +++ b/src/components/application_manager/include/application_manager/rpc_service_impl.h @@ -87,6 +87,14 @@ typedef threads::MessageLoopThread > ToHmiQueue; } // namespace impl +typedef std::shared_ptr RPCProtectionManagerSPtr; + +enum class EncryptionFlagCheckResult { + kSuccess_Protected, + kSuccess_NotProtected, + kError_EncryptionNeeded +}; + class RPCServiceImpl : public RPCService, public impl::ToMobileQueue::Handler, public impl::ToHmiQueue::Handler { @@ -103,7 +111,8 @@ class RPCServiceImpl : public RPCService, request_controller::RequestController& request_ctrl, protocol_handler::ProtocolHandler* protocol_handler, hmi_message_handler::HMIMessageHandler* hmi_handler, - CommandHolder& commands_holder); + CommandHolder& commands_holder, + RPCProtectionManagerSPtr rpc_protection_manager); ~RPCServiceImpl(); bool ManageMobileCommand(const commands::MessageSharedPtr message, @@ -132,7 +141,12 @@ class RPCServiceImpl : public RPCService, private: bool ConvertSOtoMessage(const smart_objects::SmartObject& message, Message& output, - const bool allow_unknown_parameters = false); + const bool allow_unknown_parameters = false); + + EncryptionFlagCheckResult IsEncryptionRequired( + const smart_objects::SmartObject& message, + ApplicationSharedPtr app, + const bool is_rpc_service_secure) const; hmi_apis::HMI_API& hmi_so_factory(); mobile_apis::MOBILE_API& mobile_so_factory(); void CheckSourceForUnsupportedRequest( @@ -143,6 +157,7 @@ class RPCServiceImpl : public RPCService, request_controller::RequestController& request_ctrl_; protocol_handler::ProtocolHandler* protocol_handler_; hmi_message_handler::HMIMessageHandler* hmi_handler_; + RPCProtectionManagerSPtr rpc_protection_manager_; CommandHolder& commands_holder_; // Thread that pumps messages being passed to mobile side. impl::ToMobileQueue messages_to_mobile_; diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h index fc124f7558..0ed900c653 100644 --- a/src/components/application_manager/include/application_manager/smart_object_keys.h +++ b/src/components/application_manager/include/application_manager/smart_object_keys.h @@ -38,6 +38,8 @@ namespace application_manager { namespace strings { extern const char* params; +extern const char* requireEncryption; +extern const char* protection; extern const char* message_type; extern const char* correlation_id; extern const char* function_id; diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/rc_get_interior_vehicle_data_consent_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/rc_get_interior_vehicle_data_consent_test.cc index b28f2c972a..4a5a0fb977 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/rc_get_interior_vehicle_data_consent_test.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/rc_get_interior_vehicle_data_consent_test.cc @@ -55,6 +55,7 @@ #include "rc_rpc_plugin/rc_module_constants.h" #include "rc_rpc_plugin/rc_rpc_plugin.h" #include "test/application_manager/mock_application_manager_settings.h" +#include "application_manager/mock_rpc_protection_manager.h" using ::testing::_; using ::testing::Mock; @@ -101,11 +102,14 @@ class RCGetInteriorVehicleDataConsentTest : mock_app_(std::make_shared >()) , command_holder(app_mngr_) , request_controller(mock_request_controler) + , rpc_protection_manager_( + std::make_shared()) , rpc_service_(app_mngr_, request_controller, &mock_protocol_handler, &mock_hmi_handler, - command_holder) + command_holder, + rpc_protection_manager_) , rc_app_extention_(std::make_shared(kPluginID)) , mock_rpc_plugin_manager( std::make_shared >()) @@ -144,6 +148,10 @@ class RCGetInteriorVehicleDataConsentTest .WillByDefault(Return(true)); ON_CALL(mock_allocation_manager_, is_rc_enabled()) .WillByDefault(Return(true)); + ON_CALL(mock_protocol_handler, IsRPCServiceSecure(_)) + .WillByDefault(Return(false)); + ON_CALL(*rpc_protection_manager_, CheckPolicyEncryptionFlag(_, _, _, _)) + .WillByDefault(Return(false)); } template @@ -187,6 +195,8 @@ class RCGetInteriorVehicleDataConsentTest MockRPCPlugin mock_rpc_plugin; MockCommandFactory mock_command_factory; am::request_controller::RequestController request_controller; + std::shared_ptr + rpc_protection_manager_; am::rpc_service::RPCServiceImpl rpc_service_; std::shared_ptr rc_app_extention_; std::shared_ptr @@ -238,7 +248,6 @@ TEST_F(RCGetInteriorVehicleDataConsentTest, EXPECT_CALL(mock_command_factory, CreateCommand(_, _)) .WillOnce(Return(rc_consent_response)); auto command = CreateRCCommand(mobile_message); - // Act ASSERT_TRUE(command->Init()); command->Run(); diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 3a92009d4f..30e1d84fd1 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -48,11 +48,14 @@ #include "application_manager/helpers/application_helper.h" #include "application_manager/hmi_capabilities_impl.h" #include "application_manager/message_helper.h" +#include "application_manager/rpc_service_impl.h" +#include "application_manager/rpc_handler_impl.h" #include "application_manager/mobile_message_handler.h" #include "application_manager/plugin_manager/rpc_plugin_manager_impl.h" #include "application_manager/policies/policy_handler.h" #include "application_manager/resumption/resume_ctrl_impl.h" #include "application_manager/rpc_handler_impl.h" +#include "application_manager/rpc_protection_manager_impl.h" #include "application_manager/rpc_service_impl.h" #include "connection_handler/connection_handler_impl.h" #include "formatters/CFormatterJsonSDLRPCv1.h" @@ -200,11 +203,13 @@ ApplicationManagerImpl::ApplicationManagerImpl( timer_pool_.push_back(clearing_timer); rpc_handler_.reset(new rpc_handler::RPCHandlerImpl(*this)); commands_holder_.reset(new CommandHolderImpl(*this)); - rpc_service_.reset(new rpc_service::RPCServiceImpl(*this, - request_ctrl_, - protocol_handler_, - hmi_handler_, - *commands_holder_)); + rpc_service_.reset(new rpc_service::RPCServiceImpl( + *this, + request_ctrl_, + protocol_handler_, + hmi_handler_, + *commands_holder_, + std::make_shared(*policy_handler_))); } ApplicationManagerImpl::~ApplicationManagerImpl() { diff --git a/src/components/application_manager/src/message.cc b/src/components/application_manager/src/message.cc index 2ec5891ae3..b75428780d 100644 --- a/src/components/application_manager/src/message.cc +++ b/src/components/application_manager/src/message.cc @@ -64,8 +64,8 @@ Message::Message(protocol_handler::MessagePriority priority) , binary_data_(NULL) , data_size_(0) , payload_size_(0) - , version_( - protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_UNKNOWN) {} + , version_(protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_UNKNOWN) + , is_message_encrypted_(false) {} Message::Message(const Message& message) : function_id_(0) @@ -76,8 +76,8 @@ Message::Message(const Message& message) , binary_data_(NULL) , data_size_(0) , payload_size_(0) - , version_( - protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_UNKNOWN) { + , version_(protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_UNKNOWN) + , is_message_encrypted_(false) { *this = message; } @@ -142,6 +142,10 @@ int32_t Message::connection_key() const { return connection_key_; } +bool Message::is_message_encrypted() const { + return is_message_encrypted_; +} + MessageType Message::type() const { return type_; } @@ -228,6 +232,10 @@ void Message::set_payload_size(size_t payload_size) { payload_size_ = payload_size; } +void Message::set_message_encryption(const bool protection) { + is_message_encrypted_ = protection; +} + bool Message::is_sufficient_version( protocol_handler::MajorProtocolVersion minVersion, protocol_handler::MajorProtocolVersion version) { diff --git a/src/components/application_manager/src/mobile_message_handler.cc b/src/components/application_manager/src/mobile_message_handler.cc index 4c4cb251fc..d3e7c782f7 100644 --- a/src/components/application_manager/src/mobile_message_handler.cc +++ b/src/components/application_manager/src/mobile_message_handler.cc @@ -195,6 +195,7 @@ MobileMessageHandler::HandleIncomingMessageProtocolV2( message->protocol_version())); outgoing_message->set_data_size(message->data_size()); outgoing_message->set_payload_size(message->payload_size()); + outgoing_message->set_message_encryption(message->protection_flag()); if (!payload.data.empty()) { const BinaryData binary_payload_data(payload.data); @@ -220,7 +221,8 @@ MobileMessageHandler::HandleOutgoingMessageProtocolV1( new protocol_handler::RawMessage(message->connection_key(), 1, &raw_message[0], - message_string.length() + 1); + message_string.length() + 1, + false); return result; } @@ -298,6 +300,7 @@ MobileMessageHandler::HandleOutgoingMessageProtocolV2( message->protocol_version(), &data_for_sending[0], data_for_sending_size, + false, type); return msg_to_protocol_handler; diff --git a/src/components/application_manager/src/rpc_handler_impl.cc b/src/components/application_manager/src/rpc_handler_impl.cc index 3fceaf573c..8fb2296edb 100644 --- a/src/components/application_manager/src/rpc_handler_impl.cc +++ b/src/components/application_manager/src/rpc_handler_impl.cc @@ -472,6 +472,7 @@ bool RPCHandlerImpl::ConvertMessageToSO( << message.protocol_version() << "."); return false; } + output[strings::params][strings::protection] = message.is_message_encrypted(); LOG4CXX_DEBUG(logger_, "Successfully parsed message into smart object"); return true; @@ -513,6 +514,7 @@ std::shared_ptr RPCHandlerImpl::ConvertRawMsgToMessage( } else { LOG4CXX_ERROR(logger_, "Received invalid message"); } + return outgoing_message; } diff --git a/src/components/application_manager/src/rpc_protection_manager_impl.cc b/src/components/application_manager/src/rpc_protection_manager_impl.cc new file mode 100644 index 0000000000..d784d9c2c9 --- /dev/null +++ b/src/components/application_manager/src/rpc_protection_manager_impl.cc @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "application_manager/rpc_protection_manager_impl.h" +#include "application_manager/message_helper.h" +#include "application_manager/application.h" +#include "utils/helpers.h" + +CREATE_LOGGERPTR_LOCAL(logger_, "RPCProtectionManagerImpl"); + +namespace application_manager { + +namespace rpc_encryption_exceptions { +std::vector kExceptionRPCs = {"RegisterAppInterface", + "SystemRequest", + "OnPermissionsChange", + "OnSystemRequest", + "PutFile", + "OnHMIStatus"}; +} + +RPCProtectionManagerImpl::RPCProtectionManagerImpl( + policy::PolicyHandlerInterface& policy_handler) + : policy_handler_(policy_handler) { + LOG4CXX_AUTO_TRACE(logger_); +} + +bool RPCProtectionManagerImpl::IsFunctionInGroup( + const std::string& function_name, const std::string& group) const { + const auto policy_encryption_flag_getter = + policy_handler_.PolicyEncryptionFlagGetter(); + + const auto group_rpcs = + policy_encryption_flag_getter->GetRPCsForFunctionGroup(group); + + const auto it = + std::find(group_rpcs.begin(), group_rpcs.end(), function_name); + + const bool is_function_in_group = it != group_rpcs.end(); + + LOG4CXX_DEBUG(logger_, + "Function is in group " << std::boolalpha + << is_function_in_group); + + return is_function_in_group; +} + +bool RPCProtectionManagerImpl::CheckPolicyEncryptionFlag( + const uint32_t function_id, + const ApplicationSharedPtr app, + const uint32_t correlation_id, + const bool is_rpc_service_secure) const { + LOG4CXX_AUTO_TRACE(logger_); + const auto& policy_encryption_flag_getter = + policy_handler_.PolicyEncryptionFlagGetter(); + const std::string function_name = + policy_encryption_flag_getter->GetPolicyFunctionName(function_id); + LOG4CXX_DEBUG(logger_, + "Function for check is " << function_name + << " conrrelation_id is " + << correlation_id); + + if (!is_rpc_service_secure && IsExceptionRPC(function_id)) { + LOG4CXX_WARN(logger_, + "Exception RPC can be sent in an non secure service despite " + "encryption required flag"); + return false; + } + + if (!app) { + LOG4CXX_WARN(logger_, "Received app nullptr"); + return false; + } + + const auto policy_app_id = app->policy_app_id(); + if (!policy_encryption_flag_getter->AppNeedEncryption(policy_app_id)) { + LOG4CXX_TRACE(logger_, "Application does not require encryption"); + return false; + } + + const auto app_rpc_groups = + policy_encryption_flag_getter->GetFunctionGroupsForApp(policy_app_id); + + for (const auto& group : app_rpc_groups) { + const bool is_function_in_group = IsFunctionInGroup(function_name, group); + + if (is_function_in_group && + policy_encryption_flag_getter->FunctionGroupNeedEncryption(group)) { + LOG4CXX_DEBUG(logger_, + "Message needs encryption. Function name is " + << function_name); + return true; + } + } + + return false; +} + +bool RPCProtectionManagerImpl::IsInEncryptionNeededCache( + const uint32_t app_id, const uint32_t correlation_id) const { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, "correlation_id is " << correlation_id); + + return encryption_needed_cache_.find(std::make_pair( + app_id, correlation_id)) != encryption_needed_cache_.end(); +} + +bool RPCProtectionManagerImpl::IsExceptionRPC( + const uint32_t function_id) const { + using namespace rpc_encryption_exceptions; + const std::string policy_fucntion_id = policy_table::EnumToJsonString( + static_cast(function_id)); + return helpers::in_range(kExceptionRPCs, policy_fucntion_id); +} + +void RPCProtectionManagerImpl::AddToEncryptionNeededCache( + const uint32_t app_id, const uint32_t correlation_id) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(message_needed_encryption_lock_); + + LOG4CXX_DEBUG(logger_, "Adding rpc with correlation id: " << correlation_id); + + encryption_needed_cache_.insert(std::make_pair(app_id, correlation_id)); +} + +void RPCProtectionManagerImpl::RemoveFromEncryptionNeededCache( + const uint32_t app_id, const uint32_t correlation_id) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(message_needed_encryption_lock_); + + LOG4CXX_DEBUG(logger_, + "Removing rpc with correlation id: " << correlation_id); + + encryption_needed_cache_.erase(std::make_pair(app_id, correlation_id)); +} + +smart_objects::SmartObjectSPtr +RPCProtectionManagerImpl::CreateEncryptionNeededResponse( + const uint32_t connection_key, + const uint32_t function_id, + const uint32_t correlation_id) { + LOG4CXX_AUTO_TRACE(logger_); + auto it = encryption_needed_cache_.find( + std::make_pair(connection_key, correlation_id)); + if (it != encryption_needed_cache_.end()) { + encryption_needed_cache_.erase(it); + } else { + LOG4CXX_WARN(logger_, + "RPC for correlation id: " << correlation_id << " and app id: " + << connection_key << " not found"); + } + return MessageHelper::CreateNegativeResponse( + connection_key, + function_id, + correlation_id, + static_cast(mobile_apis::Result::ENCRYPTION_NEEDED)); +} +} // namespace protocol_handler diff --git a/src/components/application_manager/src/rpc_service_impl.cc b/src/components/application_manager/src/rpc_service_impl.cc index b5cae1c126..7830fdcd78 100644 --- a/src/components/application_manager/src/rpc_service_impl.cc +++ b/src/components/application_manager/src/rpc_service_impl.cc @@ -31,6 +31,7 @@ */ #include "application_manager/rpc_service_impl.h" +#include "application_manager/rpc_protection_manager_impl.h" #include "application_manager/app_service_manager.h" #include "application_manager/plugin_manager/plugin_keys.h" @@ -48,11 +49,13 @@ RPCServiceImpl::RPCServiceImpl( request_controller::RequestController& request_ctrl, protocol_handler::ProtocolHandler* protocol_handler, hmi_message_handler::HMIMessageHandler* hmi_handler, - CommandHolder& commands_holder) + CommandHolder& commands_holder, + RPCProtectionManagerSPtr rpc_protection_manager) : app_manager_(app_manager) , request_ctrl_(request_ctrl) , protocol_handler_(protocol_handler) , hmi_handler_(hmi_handler) + , rpc_protection_manager_(rpc_protection_manager) , commands_holder_(commands_holder) , messages_to_mobile_("AM ToMobile", this) , messages_to_hmi_("AM ToHMI", this) @@ -61,6 +64,44 @@ RPCServiceImpl::RPCServiceImpl( RPCServiceImpl::~RPCServiceImpl() {} +EncryptionFlagCheckResult RPCServiceImpl::IsEncryptionRequired( + const smart_objects::SmartObject& message, + std::shared_ptr app, + const bool is_rpc_service_secure) const { + LOG4CXX_AUTO_TRACE(logger_); + const auto function_id = + message[strings::params][strings::function_id].asUInt(); + const auto correlation_id = + message[strings::params][strings::correlation_id].asUInt(); + + const auto message_type = + message[strings::params][strings::message_type].asUInt(); + const bool policy_encryption_flag = + rpc_protection_manager_->CheckPolicyEncryptionFlag( + function_id, app, correlation_id, is_rpc_service_secure); + if (MessageType::kRequest == message_type) { + const bool message_protected = + message[strings::params][strings::protection].asBool(); + + if (!message_protected) { + return policy_encryption_flag + ? EncryptionFlagCheckResult::kError_EncryptionNeeded + : EncryptionFlagCheckResult::kSuccess_NotProtected; + } + + // request is encrypted, so we need to encrypt response regardless of + // policy flag + const auto connection_key = + message[strings::params][strings::connection_key].asUInt(); + rpc_protection_manager_->AddToEncryptionNeededCache(connection_key, + correlation_id); + return EncryptionFlagCheckResult::kSuccess_Protected; + } + return policy_encryption_flag + ? EncryptionFlagCheckResult::kSuccess_Protected + : EncryptionFlagCheckResult::kSuccess_NotProtected; +} + bool RPCServiceImpl::ManageMobileCommand( const commands::MessageSharedPtr message, commands::Command::CommandSource source) { @@ -118,6 +159,17 @@ bool RPCServiceImpl::ManageMobileCommand( SendMessageToMobile(response); return false; } + if (EncryptionFlagCheckResult::kError_EncryptionNeeded == + IsEncryptionRequired( + *message, + app, + protocol_handler_->IsRPCServiceSecure(connection_key))) { + const auto response = + rpc_protection_manager_->CreateEncryptionNeededResponse( + connection_key, function_id, correlation_id); + SendMessageToMobile(response); + return false; + } // Message for "CheckPermission" must be with attached schema mobile_so_factory().attachSchema(*message, false); @@ -337,6 +389,7 @@ void RPCServiceImpl::Handle(const impl::MessageToHmi message) { } void RPCServiceImpl::Handle(const impl::MessageToMobile message) { + LOG4CXX_AUTO_TRACE(logger_); if (!protocol_handler_) { LOG4CXX_WARN(logger_, "Protocol Handler is not set; cannot send message to mobile."); @@ -361,7 +414,33 @@ void RPCServiceImpl::Handle(const impl::MessageToMobile message) { } } - protocol_handler_->SendMessageToMobileApp(rawMessage, is_final); + const auto correlation_id = message->correlation_id(); + const auto app_id = message->connection_key(); + + const bool is_service_secure = + protocol_handler_->IsRPCServiceSecure(message->connection_key()); + + const bool needs_encryption = + MessageType::kNotification == message->type() + ? rpc_protection_manager_->CheckPolicyEncryptionFlag( + message->function_id(), + app_manager_.application(app_id), + correlation_id, + is_service_secure) + : rpc_protection_manager_->IsInEncryptionNeededCache(app_id, + correlation_id); + + if (needs_encryption && !is_service_secure) { + LOG4CXX_WARN(logger_, + "Unable to send rpc that requires encryption without secure " + "rpc service"); + return; + }; + + protocol_handler_->SendMessageToMobileApp( + rawMessage, needs_encryption, is_final); + rpc_protection_manager_->RemoveFromEncryptionNeededCache(app_id, + correlation_id); LOG4CXX_INFO(logger_, "Message for mobile given away"); if (close_session) { @@ -451,6 +530,8 @@ void RPCServiceImpl::SendMessageToMobile( LOG4CXX_WARN(logger_, "Can't send msg to Mobile: failed to create string"); return; } + const auto api_function_id = static_cast( + (*message)[strings::params][strings::function_id].asInt()); smart_objects::SmartObject& msg_to_mobile = *message; // If correlation_id is not present, it is from-HMI message which should be @@ -461,9 +542,6 @@ void RPCServiceImpl::SendMessageToMobile( msg_to_mobile[strings::params][strings::connection_key].asUInt(), msg_to_mobile[strings::params][strings::function_id].asInt()); } else if (app) { - mobile_apis::FunctionID::eType function_id = - static_cast( - (*message)[strings::params][strings::function_id].asUInt()); RPCParams params; const smart_objects::SmartObject& s_map = (*message)[strings::msg_params]; @@ -479,18 +557,19 @@ void RPCServiceImpl::SendMessageToMobile( } } const std::string string_functionID = - MessageHelper::StringifiedFunctionID(function_id); + MessageHelper::StringifiedFunctionID(api_function_id); const mobile_apis::Result::eType check_result = app_manager_.CheckPolicyPermissions(app, string_functionID, params); if (mobile_apis::Result::SUCCESS != check_result) { LOG4CXX_WARN(logger_, - "Function \"" << string_functionID << "\" (#" << function_id + "Function \"" << string_functionID << "\" (#" + << api_function_id << ") not allowed by policy"); return; } #ifdef EXTERNAL_PROPRIETARY_MODE - if (function_id == mobile_apis::FunctionID::OnSystemRequestID) { + if (api_function_id == mobile_apis::FunctionID::OnSystemRequestID) { mobile_apis::RequestType::eType request_type = static_cast( (*message)[strings::msg_params][strings::request_type].asUInt()); diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index 872103929f..35f09b5244 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -5,6 +5,8 @@ namespace application_manager { namespace strings { const char* params = "params"; +const char* requireEncryption = "requireEncryption"; +const char* protection = "protection"; const char* message_type = "message_type"; const char* correlation_id = "correlation_id"; const char* function_id = "function_id"; diff --git a/src/components/application_manager/test/include/application_manager/mock_rpc_protection_manager.h b/src/components/application_manager/test/include/application_manager/mock_rpc_protection_manager.h new file mode 100644 index 0000000000..0060ea9ed3 --- /dev/null +++ b/src/components/application_manager/test/include/application_manager/mock_rpc_protection_manager.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_RPC_PROTECTION_MANAGER_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_RPC_PROTECTION_MANAGER_H_ + +#include "gmock/gmock.h" +#include "application_manager/rpc_protection_manager.h" + +namespace application_manager { +class MockRPCProtectionManager : public RPCProtectionManager { + public: + MOCK_CONST_METHOD4(CheckPolicyEncryptionFlag, + bool(const uint32_t function_id, + const ApplicationSharedPtr app, + const uint32_t conrrelation_id, + const bool is_rpc_service_secure)); + + MOCK_METHOD3(CreateEncryptionNeededResponse, + std::shared_ptr( + const uint32_t connection_key, + const uint32_t function_id, + const uint32_t conrrelation_id)); + + MOCK_CONST_METHOD2(IsInEncryptionNeededCache, + bool(const uint32_t app_id, + const uint32_t conrrelation_id)); + + MOCK_METHOD2(AddToEncryptionNeededCache, + void(const uint32_t app_id, const uint32_t correlation_id)); + + MOCK_METHOD2(RemoveFromEncryptionNeededCache, + void(const uint32_t app_id, const uint32_t correlation_id)); +}; +} + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_RPC_PROTECTION_MANAGER_H_ diff --git a/src/components/application_manager/test/policy_handler_test.cc b/src/components/application_manager/test/policy_handler_test.cc index 458b065cdd..671c39f32d 100644 --- a/src/components/application_manager/test/policy_handler_test.cc +++ b/src/components/application_manager/test/policy_handler_test.cc @@ -241,8 +241,12 @@ class PolicyHandlerTest : public ::testing::Test { EXPECT_CALL(mock_message_helper_, StringToHMILevel(default_hmi_level)) .WillOnce(Return(hmi_level)); + ChangePolicyManagerToMock(); + const policy::EncryptionRequired require_encryption; + EXPECT_CALL(*mock_policy_manager_, GetAppEncryptionRequired(kPolicyAppId_)) + .WillOnce(Return(require_encryption)); EXPECT_CALL(mock_message_helper_, - SendOnPermissionsChangeNotification(kAppId1_, _, _)); + SendOnPermissionsChangeNotification(kAppId1_, _, _, _)); EXPECT_CALL(app_manager_, state_controller()).Times(0); Permissions permissions; @@ -494,11 +498,16 @@ TEST_F(PolicyHandlerTest, UnloadPolicyLibrary_method_ExpectLibraryUnloaded) { TEST_F(PolicyHandlerTest, OnPermissionsUpdated_method_With2Parameters) { // Check expectations + ChangePolicyManagerToMock(); + const policy::EncryptionRequired require_encryption; + EXPECT_CALL(*mock_policy_manager_, GetAppEncryptionRequired(kPolicyAppId_)) + .WillOnce(Return(require_encryption)); + EXPECT_CALL(app_manager_, application_by_policy_id(kPolicyAppId_)) .WillOnce(Return(mock_app_)); EXPECT_CALL(*mock_app_, app_id()).WillOnce(Return(kAppId1_)); EXPECT_CALL(mock_message_helper_, - SendOnPermissionsChangeNotification(kAppId1_, _, _)); + SendOnPermissionsChangeNotification(kAppId1_, _, _, _)); // Act Permissions perms; policy_handler_.OnPermissionsUpdated(kPolicyAppId_, perms); @@ -508,9 +517,12 @@ TEST_F(PolicyHandlerTest, OnPermissionsUpdated_TwoParams_InvalidApp_UNSUCCESS) { std::shared_ptr invalid_app; EXPECT_CALL(app_manager_, application_by_policy_id(kPolicyAppId_)) .WillOnce(Return(invalid_app)); + ChangePolicyManagerToMock(); + const policy::EncryptionRequired require_encryption; + EXPECT_CALL(*mock_policy_manager_, GetAppEncryptionRequired(kPolicyAppId_)) + .WillOnce(ReturnRef(require_encryption)); EXPECT_CALL(mock_message_helper_, - SendOnPermissionsChangeNotification(_, _, _)) - .Times(0); + SendOnPermissionsChangeNotification(_, _, _, _)).Times(0); Permissions permissions; policy_handler_.OnPermissionsUpdated(kPolicyAppId_, permissions); @@ -522,8 +534,12 @@ TEST_F(PolicyHandlerTest, OnPermissionsUpdated_InvalidApp_UNSUCCESS) { .WillOnce(Return(mock_app_)) .WillOnce(Return(invalid_app)); EXPECT_CALL(*mock_app_, app_id()).WillOnce(Return(kAppId1_)); + ChangePolicyManagerToMock(); + const policy::EncryptionRequired require_encryption; + EXPECT_CALL(*mock_policy_manager_, GetAppEncryptionRequired(kPolicyAppId_)) + .WillOnce(Return(require_encryption)); EXPECT_CALL(mock_message_helper_, - SendOnPermissionsChangeNotification(kAppId1_, _, _)); + SendOnPermissionsChangeNotification(kAppId1_, _, _, _)); Permissions permissions; policy_handler_.OnPermissionsUpdated(kPolicyAppId_, permissions, "HMI_FULL"); @@ -553,8 +569,12 @@ TEST_F(PolicyHandlerTest, EXPECT_CALL(*mock_app_, hmi_level()) .WillOnce(Return(mobile_apis::HMILevel::HMI_NONE)); + ChangePolicyManagerToMock(); + const policy::EncryptionRequired require_encryption; + EXPECT_CALL(*mock_policy_manager_, GetAppEncryptionRequired(kPolicyAppId_)) + .WillOnce(Return(require_encryption)); EXPECT_CALL(mock_message_helper_, - SendOnPermissionsChangeNotification(kAppId1_, _, _)); + SendOnPermissionsChangeNotification(kAppId1_, _, _, _)); EXPECT_CALL(app_manager_, state_controller()) .WillRepeatedly(ReturnRef(mock_state_controller)); @@ -581,8 +601,12 @@ TEST_F(PolicyHandlerTest, EXPECT_CALL(*mock_app_, hmi_level()) .WillOnce(Return(mobile_apis::HMILevel::HMI_NONE)); + ChangePolicyManagerToMock(); + const policy::EncryptionRequired require_encryption; + EXPECT_CALL(*mock_policy_manager_, GetAppEncryptionRequired(kPolicyAppId_)) + .WillOnce(Return(require_encryption)); EXPECT_CALL(mock_message_helper_, - SendOnPermissionsChangeNotification(kAppId1_, _, _)); + SendOnPermissionsChangeNotification(kAppId1_, _, _, _)); EXPECT_CALL(app_manager_, state_controller()) .WillRepeatedly(ReturnRef(mock_state_controller)); @@ -608,8 +632,12 @@ TEST_F(PolicyHandlerTest, EXPECT_CALL(*mock_app_, hmi_level()) .WillOnce(Return(mobile_apis::HMILevel::HMI_LIMITED)); + ChangePolicyManagerToMock(); + const policy::EncryptionRequired require_encryption; + EXPECT_CALL(*mock_policy_manager_, GetAppEncryptionRequired(kPolicyAppId_)) + .WillOnce(Return(require_encryption)); EXPECT_CALL(mock_message_helper_, - SendOnPermissionsChangeNotification(kAppId1_, _, _)); + SendOnPermissionsChangeNotification(kAppId1_, _, _, _)); EXPECT_CALL(app_manager_, state_controller()).Times(0); // Act @@ -978,8 +1006,7 @@ TEST_F(PolicyHandlerTest, AppPermissions permissions(kPolicyAppId_); permissions.appPermissionsConsentNeeded = false; EXPECT_CALL(mock_message_helper_, - SendOnAppPermissionsChangedNotification(kAppId1_, _, _)) - .Times(0); + SendOnAppPermissionsChangedNotification(kAppId1_, _, _)).Times(0); EXPECT_CALL(*mock_policy_manager_, GetAppPermissionsChanges(_)) .WillOnce(Return(permissions)); @@ -1118,8 +1145,7 @@ TEST_F(PolicyHandlerTest, // Check expectations // Notification won't be sent EXPECT_CALL(mock_message_helper_, - SendOnAppPermissionsChangedNotification(kAppId1_, _, _)) - .Times(0); + SendOnAppPermissionsChangedNotification(kAppId1_, _, _)).Times(0); EXPECT_CALL(*mock_policy_manager_, GetAppPermissionsChanges(_)) .WillOnce(Return(permissions)); @@ -2244,8 +2270,7 @@ TEST_F(PolicyHandlerTest, _, NULL, _, - _)) - .WillOnce(Return(1u)); + _)).WillOnce(Return(1u)); EXPECT_CALL(app_manager_, application(kConnectionKey_)) .WillOnce(Return(mock_app_)); diff --git a/src/components/include/application_manager/policies/rpc_encryption_data_accessor_interface.h b/src/components/include/application_manager/policies/rpc_encryption_data_accessor_interface.h new file mode 100644 index 0000000000..84bcc1ea57 --- /dev/null +++ b/src/components/include/application_manager/policies/rpc_encryption_data_accessor_interface.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_POLICIES_RPC_ENCRYPTION_MANAGER +#define SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_POLICIES_RPC_ENCRYPTION_MANAGER + +#include +#include "policy/policy_table/types.h" + +using rpc::policy_table_interface_base::Strings; + +namespace policy { +/* +* @brief RPCEncryptionDataAccessorInterface interface +*/ +class RPCEncryptionDataAccessorInterface { + public: + /*! + * @brief virtual destructor RPCEncryptionDataAccessorInterface + */ + virtual ~RPCEncryptionDataAccessorInterface() {} + + /* + * @param policy_app_id policy app id + * @return true if the app need encryption + */ + virtual bool AppNeedEncryption(const std::string& policy_app_id) const = 0; + + /* + * @brief Retrieves encryption required flag on the application level + * @param policy_app_id policy app id + * @return true if the app need encryption + */ + virtual const rpc::Optional GetAppEncryptionRequired( + const std::string& policy_app_id) const = 0; + + /* + * @param policy_app_id policy app id + * @return groups that exist for app + */ + virtual const Strings GetGroupsForApp( + const std::string& policy_app_id) const = 0; + + /* + * @param policy_group group + * @return true if the group need encryption + */ + virtual bool GroupNeedEncryption(const std::string& policy_group) const = 0; + + /* + * @param policy_group group + * @return RPCs that exists in group + */ + virtual const std::vector GetRPCsForGroup( + const std::string& group) const = 0; + + /* + * @param function_id function id + * @return policy function name + */ + virtual const std::string GetPolicyFunctionName( + const uint32_t function_id) const = 0; +}; + +} // policy +#endif // SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_POLICIES_RPC_ENCRYPTION_MANAGER diff --git a/src/components/include/protocol/raw_message.h b/src/components/include/protocol/raw_message.h index 21b324417c..3de0d783cb 100644 --- a/src/components/include/protocol/raw_message.h +++ b/src/components/include/protocol/raw_message.h @@ -58,6 +58,7 @@ class RawMessage { uint32_t protocol_version, const uint8_t* const data_param, uint32_t data_size, + bool protection, uint8_t type = ServiceType::kRpc, uint32_t payload_size = 0); /** @@ -96,6 +97,8 @@ class RawMessage { ServiceType service_type() const { return service_type_; } + + bool protection_flag() const; /** * \brief Specifies current state of message in queue. * if false message is "ready to be processed" @@ -109,6 +112,7 @@ class RawMessage { uint8_t* data_; size_t data_size_; uint32_t protocol_version_; + bool protection_; ServiceType service_type_; size_t payload_size_; bool waiting_; diff --git a/src/components/include/protocol_handler/protocol_handler.h b/src/components/include/protocol_handler/protocol_handler.h index 5e65fc69d4..4eefc43b22 100644 --- a/src/components/include/protocol_handler/protocol_handler.h +++ b/src/components/include/protocol_handler/protocol_handler.h @@ -39,6 +39,7 @@ *\namespace protocol_handlerHandler *\brief Namespace for SmartDeviceLink ProtocolHandler related functionality. */ + namespace protocol_handler { class ProtocolObserver; @@ -73,6 +74,7 @@ class ProtocolHandler { * connection must be closed when message is processed */ virtual void SendMessageToMobileApp(const RawMessagePtr message, + bool needs_encryption, bool final_message) = 0; /** @@ -136,6 +138,8 @@ class ProtocolHandler { const SessionContext& context, std::vector& rejected_params) = 0; + virtual bool IsRPCServiceSecure(const uint32_t connection_key) const = 0; + protected: /** * \brief Destructor diff --git a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h index 059442f424..6dfeea7212 100644 --- a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h +++ b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h @@ -38,6 +38,7 @@ #include "gmock/gmock.h" #include "policy/policy_types.h" #include "smart_objects/smart_object.h" +#include "application_manager/policies/rpc_encryption_data_accessor_interface.h" namespace test { namespace components { @@ -46,6 +47,8 @@ namespace policy_test { class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface { public: MOCK_METHOD0(LoadPolicyLibrary, bool()); + MOCK_CONST_METHOD0(RPCEncryptionDataAccessor, + policy::RPCEncryptionDataAccessorInterface&()); MOCK_CONST_METHOD0(PolicyEnabled, bool()); MOCK_METHOD0(InitPolicyTable, bool()); MOCK_METHOD0(ResetPolicyTable, bool()); diff --git a/src/components/interfaces/MOBILE_API.xml b/src/components/interfaces/MOBILE_API.xml index a2cdb88b4d..c0df090b92 100644 --- a/src/components/interfaces/MOBILE_API.xml +++ b/src/components/interfaces/MOBILE_API.xml @@ -138,6 +138,9 @@ The data sent failed to pass CRC check in receiver end + + SDL receives an un-encrypted PRC request that needs protection. + @@ -2172,6 +2175,7 @@ + @@ -7489,6 +7493,7 @@ Change in permissions for a given set of RPCs + diff --git a/src/components/policy/policy_external/src/policy_table/enums.cc b/src/components/policy/policy_external/src/policy_table/enums.cc index bb25623b35..1d3a27ea82 100644 --- a/src/components/policy/policy_external/src/policy_table/enums.cc +++ b/src/components/policy/policy_external/src/policy_table/enums.cc @@ -888,6 +888,170 @@ bool EnumFromJsonString(const std::string& literal, return false; } +const char* EnumToJsonString(FunctionID val) { + switch (val) { + case RegisterAppInterfaceID: + return "RegisterAppInterface"; + case UnregisterAppInterfaceID: + return "UnregisterAppInterface"; + case SetGlobalPropertiesID: + return "SetGlobalProperties"; + case ResetGlobalPropertiesID: + return "ResetGlobalProperties"; + case AddCommandID: + return "AddCommand"; + case DeleteCommandID: + return "DeleteCommand"; + case AddSubMenuID: + return "AddSubMenu"; + case DeleteSubMenuID: + return "DeleteSubMenu"; + case CreateInteractionChoiceSetID: + return "CreateInteractionChoiceSet"; + case PerformInteractionID: + return "PerformInteraction"; + case DeleteInteractionChoiceSetID: + return "DeleteInteractionChoiceSet"; + case AlertID: + return "Alert"; + case ShowID: + return "Show"; + case SpeakID: + return "Speak"; + case SetMediaClockTimerID: + return "SetMediaClockTimer"; + case PerformAudioPassThruID: + return "PerformAudioPassThru"; + case EndAudioPassThruID: + return "EndAudioPassThru"; + case SubscribeButtonID: + return "SubscribeButton"; + case UnsubscribeButtonID: + return "UnsubscribeButton"; + case SubscribeVehicleDataID: + return "SubscribeVehicleData"; + case UnsubscribeVehicleDataID: + return "UnsubscribeVehicleData"; + case GetVehicleDataID: + return "GetVehicleData"; + case ReadDIDID: + return "ReadDID"; + case GetDTCsID: + return "GetDTCs"; + case ScrollableMessageID: + return "ScrollableMessage"; + case SliderID: + return "Slider"; + case ShowConstantTBTID: + return "ShowConstantTBT"; + case AlertManeuverID: + return "AlertManeuver"; + case UpdateTurnListID: + return "UpdateTurnList"; + case ChangeRegistrationID: + return "ChangeRegistration"; + case GenericResponseID: + return "GenericResponse"; + case PutFileID: + return "PutFile"; + case DeleteFileID: + return "DeleteFile"; + case ListFilesID: + return "ListFiles"; + case SetAppIconID: + return "SetAppIcon"; + case SetDisplayLayoutID: + return "SetDisplayLayout"; + case DiagnosticMessageID: + return "DiagnosticMessage"; + case SystemRequestID: + return "SystemRequest"; + case SendLocationID: + return "SendLocation"; + case DialNumberID: + return "DialNumber"; + case ButtonPressID: + return "ButtonPress"; + case GetInteriorVehicleDataID: + return "GetInteriorVehicleData"; + case SetInteriorVehicleDataID: + return "SetInteriorVehicleData"; + case GetWayPointsID: + return "GetWayPoints"; + case SubscribeWayPointsID: + return "SubscribeWayPoints"; + case UnsubscribeWayPointsID: + return "UnsubscribeWayPoints"; + case GetSystemCapabilityID: + return "GetSystemCapability"; + case SendHapticDataID: + return "SendHapticData"; + case SetCloudAppPropertiesID: + return "SetCloudAppProperties"; + case GetCloudAppPropertiesID: + return "GetCloudAppProperties"; + case PublishAppServiceID: + return "PublishAppService"; + case GetFileID: + return "GetFile"; + case GetAppServiceDataID: + return "GetAppServiceData"; + case PerformAppServiceInteractionID: + return "PerformAppServiceInteraction"; + case OnHMIStatusID: + return "OnHMIStatus"; + case OnAppInterfaceUnregisteredID: + return "OnAppInterfaceUnregistered"; + case OnButtonEventID: + return "OnButtonEvent"; + case OnButtonPressID: + return "OnButtonPress"; + case OnVehicleDataID: + return "OnVehicleData"; + case OnCommandID: + return "OnCommand"; + case OnTBTClientStateID: + return "OnTBTClientState"; + case OnDriverDistractionID: + return "OnDriverDistraction"; + case OnPermissionsChangeID: + return "OnPermissionsChange"; + case OnAudioPassThruID: + return "OnAudioPassThru"; + case OnLanguageChangeID: + return "OnLanguageChange"; + case OnKeyboardInputID: + return "OnKeyboardInput"; + case OnTouchEventID: + return "OnTouchEvent"; + case OnSystemRequestID: + return "OnSystemRequest"; + case OnHashChangeID: + return "OnHashChange"; + case OnInteriorVehicleDataID: + return "OnInteriorVehicleData"; + case OnWayPointChangeID: + return "OnWayPointChange"; + case OnRCStatusID: + return "OnRCStatus"; + case OnAppServiceDataID: + return "OnAppServiceData"; + case EncodedSyncPDataID: + return "EncodedSyncPData"; + case SyncPDataID: + return "SyncPData"; + case OnEncodedSyncPDataID: + return "OnEncodedSyncPData"; + case OnSyncPDataID: + return "OnSyncPData"; + case OnSystemCapabilityUpdatedID: + return "OnSystemCapabilityUpdated"; + default: + return ""; + } +}; + + bool EnumFromJsonString(const std::string& literal, FunctionID* result) { if ("RegisterAppInterface" == literal) { *result = RegisterAppInterfaceID; diff --git a/src/components/protocol/src/raw_message.cc b/src/components/protocol/src/raw_message.cc index daffd0f2bd..72eb82394b 100644 --- a/src/components/protocol/src/raw_message.cc +++ b/src/components/protocol/src/raw_message.cc @@ -40,12 +40,14 @@ RawMessage::RawMessage(uint32_t connection_key, uint32_t protocol_version, const uint8_t* const data_param, uint32_t data_sz, + bool protection, uint8_t type, uint32_t payload_size) : connection_key_(connection_key) , data_(NULL) , data_size_(data_sz) , protocol_version_(protocol_version) + , protection_(protection) , service_type_(ServiceTypeFromByte(type)) , payload_size_(payload_size) , waiting_(false) { @@ -87,6 +89,10 @@ bool RawMessage::IsWaiting() const { return waiting_; } +bool RawMessage::protection_flag() const { + return protection_; +} + void RawMessage::set_waiting(bool v) { waiting_ = v; } diff --git a/src/components/protocol_handler/CMakeLists.txt b/src/components/protocol_handler/CMakeLists.txt index ed3aaaf24c..d18c13337c 100644 --- a/src/components/protocol_handler/CMakeLists.txt +++ b/src/components/protocol_handler/CMakeLists.txt @@ -34,6 +34,7 @@ include_directories( ${COMPONENTS_DIR}/utils/include/ ${COMPONENTS_DIR}/protocol_handler/include/ ${COMPONENTS_DIR}/connection_handler/include/ + ${COMPONENTS_DIR}/application_manager/include ${LOG4CXX_INCLUDE_DIRECTORY} ${BSON_INCLUDE_DIRECTORY} ) 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 15996bb4e2..9d6243e274 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 @@ -230,8 +230,11 @@ class ProtocolHandlerImpl * \param message Message with params to be sent to Mobile App */ void SendMessageToMobileApp(const RawMessagePtr message, + bool needs_encryption, bool final_message) OVERRIDE; + bool IsRPCServiceSecure(const uint32_t connection_key) const OVERRIDE; + /** * \brief Sends number of processed frames in case of binary nav streaming * \param connection_key Unique key used by other components as session @@ -569,6 +572,7 @@ class ProtocolHandlerImpl const uint8_t service_type, const size_t data_size, const uint8_t* data, + const bool needs_encryption, const bool is_final_message); /** @@ -591,6 +595,7 @@ class ProtocolHandlerImpl const size_t data_size, const uint8_t* data, const size_t max_frame_size, + const bool needs_encryption, const bool is_final_message); /** diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index 222ca635d0..1f1243056d 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -850,6 +850,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 +918,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 +936,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_, @@ -1210,6 +1213,15 @@ void ProtocolHandlerImpl::OnAuthTokenUpdated(const std::string& policy_app_id, } } +bool ProtocolHandlerImpl::IsRPCServiceSecure( + const uint32_t connection_key) const { + LOG4CXX_AUTO_TRACE(logger_); + + security_manager::SSLContext* context = + session_observer_.GetSSLContext(connection_key, ServiceType::kRpc); + return (context && context->IsInitCompleted()); +} + RESULT_CODE ProtocolHandlerImpl::SendFrame(const ProtocolFramePtr packet) { LOG4CXX_AUTO_TRACE(logger_); if (!packet) { @@ -1254,13 +1266,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 +1299,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 +1340,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 +1364,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 +1426,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) { @@ -1723,12 +1742,13 @@ 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(service_type) << " type."); SendStartSessionNAck(context.connection_id_, packet->session_id(), protocol_version, @@ -1810,7 +1830,6 @@ 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( @@ -1955,6 +1974,7 @@ void ProtocolHandlerImpl::PopValideAndExpirateMultiframes() { frame->protocol_version(), frame->data(), frame->total_data_bytes(), + frame->protection_flag(), frame->service_type(), frame->payload_size())); DCHECK(rawMessage); @@ -2106,7 +2126,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; diff --git a/src/components/protocol_handler/src/protocol_packet.cc b/src/components/protocol_handler/src/protocol_packet.cc index 3473b8e5c5..4b4e988f89 100644 --- a/src/components/protocol_handler/src/protocol_packet.cc +++ b/src/components/protocol_handler/src/protocol_packet.cc @@ -433,6 +433,7 @@ RawMessagePtr ProtocolPacket::serializePacket() const { packet_header_.version, packet, total_packet_size, + false, packet_header_.serviceType)); delete[] packet; diff --git a/src/components/security_manager/src/security_manager_impl.cc b/src/components/security_manager/src/security_manager_impl.cc index dd71828d73..19c2ee2b11 100644 --- a/src/components/security_manager/src/security_manager_impl.cc +++ b/src/components/security_manager/src/security_manager_impl.cc @@ -582,10 +582,11 @@ void SecurityManagerImpl::SendQuery(const SecurityQuery& query, protocol_version, &data_sending[0], data_sending.size(), + false, protocol_handler::kControl)); DCHECK(protocol_handler_); // Add RawMessage to ProtocolHandler message query - protocol_handler_->SendMessageToMobileApp(rawMessagePtr, false); + protocol_handler_->SendMessageToMobileApp(rawMessagePtr, false, false); } } diff --git a/src/components/transport_manager/src/cloud/websocket_client_connection.cc b/src/components/transport_manager/src/cloud/websocket_client_connection.cc index ec2fb0bcfb..794cf57208 100644 --- a/src/components/transport_manager/src/cloud/websocket_client_connection.cc +++ b/src/components/transport_manager/src/cloud/websocket_client_connection.cc @@ -261,7 +261,7 @@ void WebsocketClientConnection::OnRead(boost::system::error_code ec, boost::beast::buffers_front(buffer_.data())); ::protocol_handler::RawMessagePtr frame( - new protocol_handler::RawMessage(0, 0, data, size)); + new protocol_handler::RawMessage(0, 0, data, size, false)); controller_->DataReceiveDone(device_uid_, app_handle_, frame); diff --git a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc index 8f8c004594..96c4c2c370 100644 --- a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc +++ b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc @@ -304,7 +304,7 @@ bool ThreadedSocketConnection::Receive() { logger_, "Received " << bytes_read << " bytes for connection " << this); ::protocol_handler::RawMessagePtr frame( - new protocol_handler::RawMessage(0, 0, buffer, bytes_read)); + new protocol_handler::RawMessage(0, 0, buffer, bytes_read, false)); controller_->DataReceiveDone( device_handle(), application_handle(), frame); } else if (bytes_read < 0) { diff --git a/src/components/transport_manager/src/usb/libusb/usb_connection.cc b/src/components/transport_manager/src/usb/libusb/usb_connection.cc index d60c409a96..9f57df499e 100644 --- a/src/components/transport_manager/src/usb/libusb/usb_connection.cc +++ b/src/components/transport_manager/src/usb/libusb/usb_connection.cc @@ -137,7 +137,7 @@ void UsbConnection::OnInTransfer(libusb_transfer* transfer) { << transfer->actual_length << ", data:" << hex_data(transfer->buffer, transfer->actual_length)); ::protocol_handler::RawMessagePtr data(new protocol_handler::RawMessage( - 0, 0, in_buffer_, transfer->actual_length)); + 0, 0, in_buffer_, transfer->actual_length, false)); controller_->DataReceiveDone(device_uid_, app_handle_, data); } else { LOG4CXX_ERROR(logger_, diff --git a/src/components/transport_manager/src/usb/qnx/usb_connection.cc b/src/components/transport_manager/src/usb/qnx/usb_connection.cc index c514162eb0..2945639ce9 100644 --- a/src/components/transport_manager/src/usb/qnx/usb_connection.cc +++ b/src/components/transport_manager/src/usb/qnx/usb_connection.cc @@ -144,7 +144,7 @@ void UsbConnection::OnInTransfer(usbd_urb* urb) { device_uid_, app_handle_, DataReceiveError()); } else { ::protocol_handler::RawMessagePtr msg( - new protocol_handler::RawMessage(0, 0, in_buffer_, len)); + new protocol_handler::RawMessage(0, 0, in_buffer_, len, false)); controller_->DataReceiveDone(device_uid_, app_handle_, msg); } -- cgit v1.2.1