From 5905717229c512e975ca95715736db795f3105d2 Mon Sep 17 00:00:00 2001 From: "Maksym Ked (GitHub)" <41471947+mked-luxoft@users.noreply.github.com> Date: Thu, 29 Aug 2019 17:18:03 +0300 Subject: Feature/rpc message protection (#2951) * Added encryption required flag to policy table. Also added RPC Encryption Manager Interface for comfortable access to policy table. * Added logic for processing RPC according to the proposal. * The permission change notification has been expanded. * Fixed UTs after implementation feature RPC message protection. * Fix multiframe issue * Fix style * Added storage of encryption required rpcs * Fix CI build * Extended logic adding encryption flag in message helper * Added permission check of encryption required for PROP * Added permission check of encryption required for EXT * Fixes after rebase * Answer PR comments - fixed typos - fixed 3rd party cmake * fixup! Added logic for processing RPC according to the proposal. * fixup! The permission change notification has been expanded. * Answer PR comments - renamed functions - added encryption_required flag to sql_pt_ext* source files - added condition and logging to CacheManager::GetApplicationParams * fixup! Added logic for processing RPC according to the proposal. * fixup! Added encryption required flag to policy table. * fixup! Added permission check of encryption required for EXT * fixup! Added permission check of encryption required for PROP * Fixes after rebase --- .../include/application_manager/message.h | 15 ++ .../include/application_manager/message_helper.h | 5 +- .../application_manager/policies/policy_handler.h | 4 + .../application_manager/rpc_protection_manager.h | 111 +++++++++++ .../rpc_protection_manager_impl.h | 116 +++++++++++ .../include/application_manager/rpc_service_impl.h | 18 +- .../application_manager/smart_object_keys.h | 2 + .../rc_get_interior_vehicle_data_consent_test.cc | 12 +- .../src/application_manager_impl.cc | 7 +- src/components/application_manager/src/message.cc | 16 +- .../src/message_helper/message_helper.cc | 51 ++++- .../src/mobile_message_handler.cc | 5 +- .../src/policies/policy_handler.cc | 26 ++- .../application_manager/src/rpc_handler_impl.cc | 2 + .../src/rpc_protection_manager_impl.cc | 218 +++++++++++++++++++++ .../application_manager/src/rpc_service_impl.cc | 93 ++++++++- .../application_manager/src/smart_object_keys.cc | 2 + .../application_manager/mock_message_helper.h | 5 +- .../mock_rpc_protection_manager.h | 65 ++++++ .../mock_rpc_protection_mediator.h | 22 +++ .../test/mobile_message_handler_test.cc | 1 + .../test/mobile_message_handler_v1_test.cc | 14 +- .../test/mock_message_helper.cc | 5 +- .../test/policy_handler_test.cc | 49 ++++- .../policies/policy_encryption_flag_getter.h | 106 ++++++++++ .../policies/policy_handler_interface.h | 8 +- .../policies/policy_handler_observer.h | 2 + .../policy/policy_external/policy/policy_manager.h | 4 +- .../policy/policy_regular/policy/policy_manager.h | 3 +- src/components/include/protocol/raw_message.h | 4 + .../include/protocol_handler/protocol_handler.h | 5 + .../policies/mock_policy_handler_interface.h | 4 + .../policy_external/policy/mock_cache_manager.h | 14 ++ .../policy_external/policy/mock_policy_manager.h | 17 ++ .../policy_regular/policy/mock_cache_manager.h | 13 ++ .../policy_regular/policy/mock_policy_manager.h | 17 ++ .../test/protocol_handler/mock_protocol_handler.h | 4 +- src/components/interfaces/MOBILE_API.xml | 5 + .../media_manager/test/media_manager_impl_test.cc | 1 + .../policy_external/include/policy/cache_manager.h | 16 ++ .../include/policy/cache_manager_interface.h | 37 ++++ .../policy_external/include/policy/policy_helper.h | 19 +- .../include/policy/policy_manager_impl.h | 40 ++++ .../include/policy/policy_table/types.h | 3 +- .../include/policy/policy_table_interface_ext.xml | 2 + .../policy_external/include/policy/policy_types.h | 7 +- .../policy/policy_external/src/cache_manager.cc | 56 ++++++ .../policy/policy_external/src/policy_helper.cc | 126 +++++++++++- .../policy_external/src/policy_manager_impl.cc | 130 +++++++++--- .../policy_external/src/policy_table/enums.cc | 163 +++++++++++++++ .../policy_external/src/policy_table/types.cc | 29 ++- .../policy_external/src/sql_pt_ext_queries.cc | 8 +- .../src/sql_pt_ext_representation.cc | 6 + .../policy/policy_external/src/sql_pt_queries.cc | 24 ++- .../policy_external/src/sql_pt_representation.cc | 18 +- .../policy_regular/include/policy/cache_manager.h | 16 ++ .../include/policy/cache_manager_interface.h | 36 ++++ .../policy_regular/include/policy/policy_helper.h | 51 +++-- .../include/policy/policy_manager_impl.h | 66 ++++++- .../include/policy/policy_table/types.h | 2 + .../policy_regular/include/policy/policy_types.h | 29 ++- .../policy/policy_regular/src/cache_manager.cc | 56 ++++++ .../policy/policy_regular/src/policy_helper.cc | 193 ++++++++++++++++-- .../policy_regular/src/policy_manager_impl.cc | 181 ++++++++++++++++- .../policy_regular/src/policy_table/types.cc | 32 ++- .../policy/policy_regular/src/sql_pt_queries.cc | 27 +-- .../policy_regular/src/sql_pt_representation.cc | 20 +- 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/multiframe_builder.cc | 5 + .../protocol_handler/src/protocol_handler_impl.cc | 37 +++- .../protocol_handler/src/protocol_packet.cc | 1 + .../test/incoming_data_handler_test.cc | 14 +- .../test/protocol_handler_tm_test.cc | 30 ++- .../security_manager/src/security_manager_impl.cc | 3 +- .../security_manager/test/security_manager_test.cc | 49 +++-- .../test/transport_manager_observer_test.cc | 2 +- .../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 +- .../test/transport_adapter_listener_test.cc | 4 +- .../test/transport_adapter_test.cc | 4 +- .../test/transport_manager_impl_test.cc | 2 +- 85 files changed, 2442 insertions(+), 193 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/application_manager/test/include/application_manager/mock_rpc_protection_mediator.h create mode 100644 src/components/include/application_manager/policies/policy_encryption_flag_getter.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/message_helper.h b/src/components/application_manager/include/application_manager/message_helper.h index 44046be523..8f05b523b3 100644 --- a/src/components/application_manager/include/application_manager/message_helper.h +++ b/src/components/application_manager/include/application_manager/message_helper.h @@ -514,11 +514,14 @@ class MessageHelper { * @brief Send notification to mobile on application permissions update * @param connection_key Id of application to send message to * @param permissions updated permissions for application + * @param app_mngr reference to application manager + * @param require_encryption require encryption flag */ static void SendOnPermissionsChangeNotification( uint32_t connection_key, const policy::Permissions& permissions, - ApplicationManager& app_mngr); + ApplicationManager& app_mngr, + const policy::EncryptionRequired encryprion_required); /* * @brief Send notification to HMI on application permissions update diff --git a/src/components/application_manager/include/application_manager/policies/policy_handler.h b/src/components/application_manager/include/application_manager/policies/policy_handler.h index ccbd466cdd..dddd1b333d 100644 --- a/src/components/application_manager/include/application_manager/policies/policy_handler.h +++ b/src/components/application_manager/include/application_manager/policies/policy_handler.h @@ -77,6 +77,8 @@ class PolicyHandler : public PolicyHandlerInterface, PolicyHandler(const policy::PolicySettings& get_settings, application_manager::ApplicationManager& application_manager); virtual ~PolicyHandler(); + PolicyEncryptionFlagGetterInterfaceSPtr PolicyEncryptionFlagGetter() + const OVERRIDE; bool LoadPolicyLibrary() OVERRIDE; bool PolicyEnabled() const OVERRIDE; bool InitPolicyTable() OVERRIDE; @@ -674,6 +676,8 @@ class PolicyHandler : public PolicyHandlerInterface, virtual void OnPTUFinished(const bool ptu_result) OVERRIDE; + virtual void OnPTInited() OVERRIDE; + /** * @brief OnDeviceSwitching Notifies policy manager on device switch event so * policy permissions should be processed accordingly 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..34188da4e9 --- /dev/null +++ b/src/components/application_manager/include/application_manager/rpc_protection_manager.h @@ -0,0 +1,111 @@ +/* + * 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 "application_manager/policies/policy_handler_observer.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 policy::PolicyHandlerObserver { + 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 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 correlation 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 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 application_manager + +#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..b971ace480 --- /dev/null +++ b/src/components/application_manager/include/application_manager/rpc_protection_manager_impl.h @@ -0,0 +1,116 @@ +/* + * 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 +#include "application_manager/policies/policy_handler.h" +#include "application_manager/rpc_protection_manager.h" + +namespace application_manager { +/* + * @brief RPCProtectionManager implementation + */ +class RPCProtectionManagerImpl : public RPCProtectionManager { + public: + typedef std::pair AppIdCorrIdPair; + typedef std::set FunctionNames; + typedef std::map AppEncryptedRpcMap; + + RPCProtectionManagerImpl(policy::PolicyHandlerInterface& policy_handler); + + ~RPCProtectionManagerImpl() OVERRIDE {} + + bool CheckPolicyEncryptionFlag( + const uint32_t function_id, + const ApplicationSharedPtr app, + const bool is_rpc_service_secure) const OVERRIDE; + + bool IsInEncryptionNeededCache(const uint32_t app_id, + const uint32_t conrrelation_id) const 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; + + // PolicyHandlerObserver interface + void OnPTUFinished(const bool ptu_result) OVERRIDE; + + void OnPTInited() OVERRIDE; + + private: + /* + * @brief check whether given rpc is an exception + * @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 retreives list of rpcs that require encryption by policy + * @param policy_app_id policy application name + * @return container with function names that require encryption by policy + */ + FunctionNames GetEncryptedRPCsForApp(const std::string& policy_app_id); + + /* + * @brief checks whether given function name is in saved encrypted rpc list + * @param policy_app_id policy application name + * @param function_name policy function name + * @return true if function_name for this policy_app_id is saved, otherwise - + * false + */ + bool IsEncryptionRequiredByPolicy(const std::string& policy_app_id, + const std::string& function_name) const; + + /* + * @brief saves rpcs that have encryption_required flag in policy table to + * internal container + */ + void SaveEncryptedRPC(); + + policy::PolicyHandlerInterface& policy_handler_; + + AppEncryptedRpcMap encrypted_rpcs_; + sync_primitives::Lock encrypted_rpcs_lock_; + + std::set encryption_needed_cache_; + sync_primitives::Lock message_needed_encryption_lock_; +}; +} // namespace application_manager + +#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..e32cdf42a2 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 @@ -38,6 +38,7 @@ #include "application_manager/message_helper.h" #include "application_manager/mobile_message_handler.h" #include "application_manager/request_controller.h" +#include "application_manager/rpc_protection_manager.h" #include "application_manager/rpc_service.h" #include "application_manager/usage_statistics.h" @@ -87,6 +88,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 +112,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, @@ -133,6 +143,11 @@ class RPCServiceImpl : public RPCService, bool ConvertSOtoMessage(const smart_objects::SmartObject& message, Message& output, 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 +158,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 1831d8cb4d..1d13417fa1 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* require_encryption; +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..c607721bbd 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 @@ -41,6 +41,7 @@ #include "application_manager/mock_request_controller_settings.h" #include "application_manager/mock_rpc_plugin.h" #include "application_manager/mock_rpc_plugin_manager.h" +#include "application_manager/mock_rpc_protection_manager.h" #include "application_manager/request_controller.h" #include "application_manager/rpc_service_impl.h" #include "hmi_message_handler/mock_hmi_message_handler.h" @@ -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 diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 20a53b9780..3829005047 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -53,6 +53,7 @@ #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" @@ -209,11 +210,15 @@ ApplicationManagerImpl::ApplicationManagerImpl( timer_pool_.push_back(clearing_timer); rpc_handler_.reset(new rpc_handler::RPCHandlerImpl(*this)); commands_holder_.reset(new CommandHolderImpl(*this)); + std::shared_ptr rpc_protection_manager = + std::make_shared(*policy_handler_); + policy_handler_->add_listener(rpc_protection_manager.get()); rpc_service_.reset(new rpc_service::RPCServiceImpl(*this, request_ctrl_, protocol_handler_, hmi_handler_, - *commands_holder_)); + *commands_holder_, + rpc_protection_manager)); } 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/message_helper/message_helper.cc b/src/components/application_manager/src/message_helper/message_helper.cc index 3639953a3a..e2ed3fa820 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -2528,7 +2528,8 @@ void MessageHelper::SendQueryApps(const uint32_t connection_key, void MessageHelper::SendOnPermissionsChangeNotification( uint32_t connection_key, const policy::Permissions& permissions, - ApplicationManager& app_mngr) { + ApplicationManager& app_mngr, + const policy::EncryptionRequired encryprion_required) { LOG4CXX_AUTO_TRACE(logger_); smart_objects::SmartObject content(smart_objects::SmartType_Map); @@ -2545,8 +2546,10 @@ void MessageHelper::SendOnPermissionsChangeNotification( content[strings::msg_params] = smart_objects::SmartObject(smart_objects::SmartType_Map); - // content[strings::msg_params][strings::app_id] = connection_key; - + if (encryprion_required.is_initialized()) { + content[strings::msg_params][strings::require_encryption] = + static_cast(*encryprion_required); + } content[strings::msg_params]["permissionItem"] = smart_objects::SmartObject(smart_objects::SmartType_Array); @@ -2556,6 +2559,41 @@ void MessageHelper::SendOnPermissionsChangeNotification( policy::Permissions::const_iterator it_permissions = permissions.begin(); policy::Permissions::const_iterator it_permissions_end = permissions.end(); + using policy::EncryptionRequired; + auto permission_item_encryption_flag_state = + [](const EncryptionRequired& app_flag, + const EncryptionRequired& groups_flag) -> EncryptionRequired { + enum EncryptionFlagState { TRUE, FALSE, MISSING }; + auto enum_from_optional_bool = [](const EncryptionRequired& flag) { + if (!flag.is_initialized()) { + return MISSING; + } + return *flag ? TRUE : FALSE; + }; + + typedef std::pair + EnctyptionStatePair; + typedef std::map + PermissionItemEncryptionTable; + static PermissionItemEncryptionTable encryption_state_table = { + {{TRUE, TRUE}, EncryptionRequired(true)}, + {{TRUE, FALSE}, EncryptionRequired()}, + {{TRUE, MISSING}, EncryptionRequired()}, + {{FALSE, TRUE}, EncryptionRequired()}, + {{FALSE, FALSE}, EncryptionRequired()}, + {{FALSE, MISSING}, EncryptionRequired()}, + {{MISSING, TRUE}, EncryptionRequired(true)}, + {{MISSING, FALSE}, EncryptionRequired()}, + {{MISSING, MISSING}, EncryptionRequired()}, + }; + const auto app_flag_state = enum_from_optional_bool(app_flag); + const auto groups_flag_state = enum_from_optional_bool(groups_flag); + auto it = encryption_state_table.find( + EnctyptionStatePair(app_flag_state, groups_flag_state)); + DCHECK_OR_RETURN(it != encryption_state_table.end(), EncryptionRequired()); + return it->second; + }; + for (size_t index_pi = 0; it_permissions != it_permissions_end; ++it_permissions, ++index_pi) { permissions_item_array[index_pi] = @@ -2564,9 +2602,14 @@ void MessageHelper::SendOnPermissionsChangeNotification( smart_objects::SmartObject& permission_item = permissions_item_array[index_pi]; - // Filling the rpcName of PermissionItem permission_item["rpcName"] = (*it_permissions).first; const policy::RpcPermissions& rpc_permissions = (*it_permissions).second; + auto item_require_encryption = permission_item_encryption_flag_state( + encryprion_required, rpc_permissions.require_encryption); + if (item_require_encryption.is_initialized()) { + const bool require_encryption = *item_require_encryption; + permission_item[strings::require_encryption] = require_encryption; + } // Creating SO for hmiPermissions permission_item["hmiPermissions"] = 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/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index ab07151b69..1bad50b34f 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -303,6 +303,11 @@ PolicyHandler::PolicyHandler(const PolicySettings& settings, PolicyHandler::~PolicyHandler() {} +PolicyEncryptionFlagGetterInterfaceSPtr +PolicyHandler::PolicyEncryptionFlagGetter() const { + return policy_manager_; +} + bool PolicyHandler::PolicyEnabled() const { return get_settings().enable_policy(); } @@ -364,12 +369,25 @@ bool PolicyHandler::InitPolicyTable() { hmi_apis::FunctionID::BasicCommunication_OnReady); std::string preloaded_file = get_settings().preloaded_pt_file(); if (file_system::FileExists(preloaded_file)) { - return policy_manager_->InitPT(preloaded_file, &get_settings()); + const bool pt_inited = + policy_manager_->InitPT(preloaded_file, &get_settings()); + OnPTInited(); + return pt_inited; } LOG4CXX_FATAL(logger_, "The file which contains preloaded PT is not exist"); return false; } +void PolicyHandler::OnPTInited() { + LOG4CXX_AUTO_TRACE(logger_); + + sync_primitives::AutoLock lock(listeners_lock_); + + std::for_each(listeners_.begin(), + listeners_.end(), + std::mem_fun(&PolicyHandlerObserver::OnPTInited)); +} + bool PolicyHandler::ResetPolicyTable() { LOG4CXX_TRACE(logger_, "Reset policy table."); POLICY_LIB_CHECK(false); @@ -444,6 +462,7 @@ void PolicyHandler::OnAppPermissionConsent( void PolicyHandler::OnDeviceConsentChanged(const std::string& device_id, const bool is_allowed) { + LOG4CXX_AUTO_TRACE(logger_); POLICY_LIB_CHECK_VOID(); connection_handler::DeviceHandle device_handle; if (!application_manager_.connection_handler().GetDeviceID(device_id, @@ -1431,8 +1450,11 @@ void PolicyHandler::OnPermissionsUpdated(const std::string& device_id, return; } + const auto require_encryption = + policy_manager_->GetAppEncryptionRequired(policy_app_id); + MessageHelper::SendOnPermissionsChangeNotification( - app->app_id(), permissions, application_manager_); + app->app_id(), permissions, application_manager_, require_encryption); LOG4CXX_DEBUG(logger_, "Notification sent for application_id: " diff --git a/src/components/application_manager/src/rpc_handler_impl.cc b/src/components/application_manager/src/rpc_handler_impl.cc index 49877ce3ef..e17eaa264e 100644 --- a/src/components/application_manager/src/rpc_handler_impl.cc +++ b/src/components/application_manager/src/rpc_handler_impl.cc @@ -469,6 +469,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; @@ -510,6 +511,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..8ff00eb3c5 --- /dev/null +++ b/src/components/application_manager/src/rpc_protection_manager_impl.cc @@ -0,0 +1,218 @@ +/* + * 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/application.h" +#include "application_manager/message_helper.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::CheckPolicyEncryptionFlag( + const uint32_t function_id, + const ApplicationSharedPtr app, + 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); + + 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(); + + return IsEncryptionRequiredByPolicy(policy_app_id, function_name); +} + +bool RPCProtectionManagerImpl::IsEncryptionRequiredByPolicy( + const std::string& policy_app_id, const std::string& function_name) const { + LOG4CXX_AUTO_TRACE(logger_); + + auto it = encrypted_rpcs_.find(policy_app_id); + + if (encrypted_rpcs_.end() == it) { + LOG4CXX_WARN( + logger_, + "App specific policies for app: " << policy_app_id << " not found"); + it = encrypted_rpcs_.find(policy_table::kDefaultApp); + return encrypted_rpcs_.end() != it + ? (*it).second.find(function_name) != (*it).second.end() + : false; + } + + return (*it).second.find(function_name) != (*it).second.end(); +} + +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)); +} + +void RPCProtectionManagerImpl::OnPTUFinished(const bool ptu_result) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(encrypted_rpcs_lock_); + + if (ptu_result) { + LOG4CXX_TRACE(logger_, + "PTU finished successfully, commencing internal encrypted " + "RPC cache update"); + encrypted_rpcs_.clear(); + SaveEncryptedRPC(); + } else { + LOG4CXX_WARN(logger_, + "PTU was unsuccessful. Keeping internal RPC cache from " + "current snapshot"); + } +} + +void RPCProtectionManagerImpl::SaveEncryptedRPC() { + LOG4CXX_AUTO_TRACE(logger_); + + const auto policy_encryption_flag_getter = + policy_handler_.PolicyEncryptionFlagGetter(); + + const auto policy_policy_app_ids = + policy_encryption_flag_getter->GetApplicationPolicyIDs(); + + for (const auto& app : policy_policy_app_ids) { + LOG4CXX_DEBUG(logger_, "Processing app name: " << app); + + encrypted_rpcs_[app] = GetEncryptedRPCsForApp(app); + } +} + +void RPCProtectionManagerImpl::OnPTInited() { + LOG4CXX_AUTO_TRACE(logger_); + + encrypted_rpcs_.clear(); + + SaveEncryptedRPC(); +} + +RPCProtectionManagerImpl::FunctionNames +RPCProtectionManagerImpl::GetEncryptedRPCsForApp( + const std::string& policy_app_id) { + LOG4CXX_AUTO_TRACE(logger_); + FunctionNames encrypted_rpcs; + + const auto policy_encryption_flag_getter = + policy_handler_.PolicyEncryptionFlagGetter(); + + if (!policy_encryption_flag_getter->AppNeedEncryption(policy_app_id)) { + return encrypted_rpcs; + } + + const auto function_groups = + policy_encryption_flag_getter->GetFunctionalGroupsForApp(policy_app_id); + + auto fill_encrypted_rpcs = [&encrypted_rpcs]( + const std::string& function_name) { + LOG4CXX_DEBUG(logger_, "Adding required encryprion rpc: " << function_name); + encrypted_rpcs.insert(function_name); + }; + + for (const auto& function_group : function_groups) { + if (policy_encryption_flag_getter->FunctionGroupNeedEncryption( + function_group)) { + auto rpcs = policy_encryption_flag_getter->GetRPCsForFunctionGroup( + function_group); + + std::for_each(rpcs.begin(), rpcs.end(), fill_encrypted_rpcs); + } + } + + return encrypted_rpcs; +} + +} // namespace application_manager diff --git a/src/components/application_manager/src/rpc_service_impl.cc b/src/components/application_manager/src/rpc_service_impl.cc index c7d1bde288..cfd5335a42 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, 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) { @@ -119,6 +160,19 @@ bool RPCServiceImpl::ManageMobileCommand( SendMessageToMobile(response); return false; } + if (EncryptionFlagCheckResult::kError_EncryptionNeeded == + IsEncryptionRequired( + *message, + app, + protocol_handler_->IsRPCServiceSecure(connection_key))) { + const auto response = MessageHelper::CreateNegativeResponse( + connection_key, + function_id, + correlation_id, + static_cast(mobile_apis::Result::ENCRYPTION_NEEDED)); + SendMessageToMobile(response); + return false; + } // Message for "CheckPermission" must be with attached schema mobile_so_factory().attachSchema(*message, false); @@ -340,6 +394,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."); @@ -364,7 +419,32 @@ 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), + 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) { @@ -454,6 +534,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].asUInt()); smart_objects::SmartObject& msg_to_mobile = *message; // If correlation_id is not present, it is from-HMI message which should be @@ -485,19 +567,20 @@ 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, window_id, 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 e9adf796af..2efc04a767 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* require_encryption = "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_message_helper.h b/src/components/application_manager/test/include/application_manager/mock_message_helper.h index 6cbe46f9ec..79718983ee 100644 --- a/src/components/application_manager/test/include/application_manager/mock_message_helper.h +++ b/src/components/application_manager/test/include/application_manager/mock_message_helper.h @@ -155,10 +155,11 @@ class MockMessageHelper { uint32_t correlation_id, ApplicationManager& app_mngr)); #endif // #ifdef EXTERNAL_PROPRIETARY_MODE - MOCK_METHOD3(SendOnPermissionsChangeNotification, + MOCK_METHOD4(SendOnPermissionsChangeNotification, void(uint32_t connection_key, const policy::Permissions& permissions, - ApplicationManager& app_mngr)); + ApplicationManager& app_mngr, + const bool require_encryption)); MOCK_METHOD4(SendPolicySnapshotNotification, void(uint32_t connection_key, const std::vector& policy_data, 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..112de0fea5 --- /dev/null +++ b/src/components/application_manager/test/include/application_manager/mock_rpc_protection_manager.h @@ -0,0 +1,65 @@ +/* + * 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 "application_manager/rpc_protection_manager.h" +#include "gmock/gmock.h" + +namespace application_manager { +class MockRPCProtectionManager : public RPCProtectionManager { + public: + MOCK_CONST_METHOD3(CheckPolicyEncryptionFlag, + bool(const uint32_t function_id, + const ApplicationSharedPtr app, + 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)); +}; +} // namespace application_manager + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_RPC_PROTECTION_MANAGER_H_ diff --git a/src/components/application_manager/test/include/application_manager/mock_rpc_protection_mediator.h b/src/components/application_manager/test/include/application_manager/mock_rpc_protection_mediator.h new file mode 100644 index 0000000000..858673e3b3 --- /dev/null +++ b/src/components/application_manager/test/include/application_manager/mock_rpc_protection_mediator.h @@ -0,0 +1,22 @@ +#pragma once + +#include "application_manager/rpc_protection_mediator.h" +#include "gmock/gmock.h" + +namespace application_manager { +class MockRPCProtectionMediator : public RPCProtectionMediator { + public: + MOCK_METHOD4(DoesRPCNeedEncryption, + bool(const uint32_t function_id, + std::shared_ptr app, + const uint32_t conrrelation_id, + const bool is_rpc_service_secure)); + MOCK_METHOD1(DoesRPCNeedEncryption, bool(const uint32_t conrrelation_id)); + MOCK_METHOD1(EncryptResponseByForce, void(const uint32_t conrrelation_id)); + MOCK_METHOD3(CreateNegativeResponse, + std::shared_ptr( + const uint32_t connection_key, + const uint32_t function_id, + const uint32_t conrrelation_id)); +}; +} // namespace application_manager diff --git a/src/components/application_manager/test/mobile_message_handler_test.cc b/src/components/application_manager/test/mobile_message_handler_test.cc index cac04d4508..3ae79ce8ce 100644 --- a/src/components/application_manager/test/mobile_message_handler_test.cc +++ b/src/components/application_manager/test/mobile_message_handler_test.cc @@ -109,6 +109,7 @@ class MobileMessageHandlerTest : public testing::Test { protocol_version, &full_data[0], full_size, + false, ServiceType::kRpc, payload_size); diff --git a/src/components/application_manager/test/mobile_message_handler_v1_test.cc b/src/components/application_manager/test/mobile_message_handler_v1_test.cc index 7801798705..ab37694c28 100644 --- a/src/components/application_manager/test/mobile_message_handler_v1_test.cc +++ b/src/components/application_manager/test/mobile_message_handler_v1_test.cc @@ -69,8 +69,11 @@ const unsigned char* data_v1 = TEST(MobileMessageHandlerTestV1Test, HandleIncomingMessageProtocolV1_SendJSONData_ExpectEqual) { - RawMessagePtr message = std::make_shared( - connection_key_p1, protocol_version_1, data_v1, data_json.length()); + RawMessagePtr message = std::make_shared(connection_key_p1, + protocol_version_1, + data_v1, + data_json.length(), + false); application_manager::Message* ptr = MobileMessageHandler::HandleIncomingMessageProtocol(message); @@ -89,8 +92,11 @@ TEST(MobileMessageHandlerTestV1Test, const unsigned char* data_v1 = reinterpret_cast(full_data.c_str()); - RawMessagePtr message = std::make_shared( - connection_key_p1, protocol_version_1, data_v1, full_data.length()); + RawMessagePtr message = std::make_shared(connection_key_p1, + protocol_version_1, + data_v1, + full_data.length(), + false); application_manager::Message* ptr = MobileMessageHandler::HandleIncomingMessageProtocol(message); diff --git a/src/components/application_manager/test/mock_message_helper.cc b/src/components/application_manager/test/mock_message_helper.cc index cccadc5a9d..7002bb0157 100644 --- a/src/components/application_manager/test/mock_message_helper.cc +++ b/src/components/application_manager/test/mock_message_helper.cc @@ -212,9 +212,10 @@ void MessageHelper::SendGetListOfPermissionsResponse( void MessageHelper::SendOnPermissionsChangeNotification( uint32_t connection_key, const policy::Permissions& permissions, - ApplicationManager& app_mngr) { + ApplicationManager& app_mngr, + const policy::EncryptionRequired require_encryption) { MockMessageHelper::message_helper_mock()->SendOnPermissionsChangeNotification( - connection_key, permissions, app_mngr); + connection_key, permissions, app_mngr, require_encryption); } void MessageHelper::SendPolicySnapshotNotification( diff --git a/src/components/application_manager/test/policy_handler_test.cc b/src/components/application_manager/test/policy_handler_test.cc index 6af4c4f018..94567e893d 100644 --- a/src/components/application_manager/test/policy_handler_test.cc +++ b/src/components/application_manager/test/policy_handler_test.cc @@ -243,8 +243,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; @@ -496,11 +500,15 @@ 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(kDeviceId, 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(kDeviceId, kPolicyAppId_, perms); @@ -510,8 +518,12 @@ TEST_F(PolicyHandlerTest, OnPermissionsUpdated_TwoParams_InvalidApp_UNSUCCESS) { std::shared_ptr invalid_app; EXPECT_CALL(app_manager_, application(kDeviceId, kPolicyAppId_)) .WillOnce(Return(invalid_app)); + ChangePolicyManagerToMock(); + const policy::EncryptionRequired require_encryption; + EXPECT_CALL(*mock_policy_manager_, GetAppEncryptionRequired(kPolicyAppId_)) + .Times(0); EXPECT_CALL(mock_message_helper_, - SendOnPermissionsChangeNotification(_, _, _)) + SendOnPermissionsChangeNotification(_, _, _, _)) .Times(0); Permissions permissions; @@ -524,8 +536,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( @@ -556,8 +572,12 @@ TEST_F(PolicyHandlerTest, EXPECT_CALL(*mock_app_, hmi_level(kDefaultWindowId)) .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)); @@ -585,8 +605,12 @@ TEST_F(PolicyHandlerTest, EXPECT_CALL(*mock_app_, hmi_level(kDefaultWindowId)) .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)); @@ -613,8 +637,12 @@ TEST_F(PolicyHandlerTest, EXPECT_CALL(*mock_app_, hmi_level(kDefaultWindowId)) .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 @@ -645,9 +673,16 @@ TEST_F(PolicyHandlerTest, CheckPermissions) { .WillOnce(Return(hmi_level)); EXPECT_CALL(*mock_app_, device()).WillOnce(Return(device)); EXPECT_CALL(*mock_app_, policy_app_id()).WillOnce(Return(kPolicyAppId_)); +#ifdef EXTERNAL_PROPRIETARY_MODE EXPECT_CALL(*mock_policy_manager_, CheckPermissions( kDeviceId, kPolicyAppId_, kHmiLevel_, kRpc_, kRpc_params, _)); + +#else // EXTERNAL_PROPRIETARY_MODE + EXPECT_CALL(*mock_policy_manager_, + CheckPermissions( + kDeviceId, kPolicyAppId_, kHmiLevel_, kRpc_, kRpc_params, _)); +#endif // EXTERNAL_PROPRIETARY_MODE EXPECT_CALL(mock_message_helper_, StringifiedHMILevel(hmi_level)) .WillOnce(Return(kHmiLevel_)); EXPECT_CALL(mock_message_helper_, GetDeviceMacAddressForHandle(device, _)) diff --git a/src/components/include/application_manager/policies/policy_encryption_flag_getter.h b/src/components/include/application_manager/policies/policy_encryption_flag_getter.h new file mode 100644 index 0000000000..1a004fb926 --- /dev/null +++ b/src/components/include/application_manager/policies/policy_encryption_flag_getter.h @@ -0,0 +1,106 @@ +/* + * 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_POLICY_ENCRYPTION_FLAG_GETTER +#define SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_POLICIES_POLICY_ENCRYPTION_FLAG_GETTER + +#include +#include "policy/policy_table/types.h" + +using rpc::policy_table_interface_base::Strings; + +namespace policy { +/* + * @brief PolicyEncryptionFlagGetterInterface interface + */ +class PolicyEncryptionFlagGetterInterface { + public: + /*! + * @brief virtual destructor PolicyEncryptionFlagGetterInterface + */ + virtual ~PolicyEncryptionFlagGetterInterface() {} + + /* + * @brief retreives flag whether given application needs encryption + * @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; + + /* + * @brief retreives function group for app + * @param policy_app_id policy app id + * @return groups that exist for app + */ + virtual const std::vector GetFunctionalGroupsForApp( + const std::string& policy_app_id) const = 0; + + /* + * @brief retreives flag indicating whether function group needs encryption + * @param policy_group group + * @return true if the group need encryption + */ + virtual bool FunctionGroupNeedEncryption( + const std::string& policy_group) const = 0; + + /* + * @brief retreives rpcs for given function group + * @param policy_group group + * @return RPCs that exists in group + */ + virtual const std::vector GetRPCsForFunctionGroup( + const std::string& group) const = 0; + + /* + * @brief retreives policy function name + * @param function_id function id + * @return policy function name + */ + virtual const std::string GetPolicyFunctionName( + const uint32_t function_id) const = 0; + /* + * @brief retrieves application names from policy table + * @return container with policy application names + */ + virtual const std::vector GetApplicationPolicyIDs() const = 0; +}; + +} // namespace policy +#endif // SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_POLICIES_POLICY_ENCRYPTION_FLAG_GETTER diff --git a/src/components/include/application_manager/policies/policy_handler_interface.h b/src/components/include/application_manager/policies/policy_handler_interface.h index 75655f7f08..8e450edd49 100644 --- a/src/components/include/application_manager/policies/policy_handler_interface.h +++ b/src/components/include/application_manager/policies/policy_handler_interface.h @@ -41,6 +41,7 @@ #include "boost/optional.hpp" #include "application_manager/application.h" +#include "application_manager/policies/policy_encryption_flag_getter.h" #include "application_manager/policies/policy_handler_observer.h" #include "interfaces/MOBILE_API.h" #include "policy/cache_manager_interface.h" @@ -51,17 +52,20 @@ #include "smart_objects/smart_object.h" #include "utils/callable.h" #include "utils/custom_string.h" -#include "utils/optional.h" using namespace ::rpc::policy_table_interface_base; namespace policy { typedef std::shared_ptr StatusNotifier; +typedef std::shared_ptr + PolicyEncryptionFlagGetterInterfaceSPtr; class PolicyHandlerInterface { public: virtual ~PolicyHandlerInterface() {} virtual bool LoadPolicyLibrary() = 0; + virtual PolicyEncryptionFlagGetterInterfaceSPtr PolicyEncryptionFlagGetter() + const = 0; virtual bool PolicyEnabled() const = 0; virtual bool InitPolicyTable() = 0; virtual bool ResetPolicyTable() = 0; @@ -334,6 +338,8 @@ class PolicyHandlerInterface { virtual void OnPTUFinished(const bool ptu_result) = 0; + virtual void OnPTInited() = 0; + #ifdef EXTERNAL_PROPRIETARY_MODE virtual void OnCertificateDecrypted(bool is_succeeded) = 0; #endif // EXTERNAL_PROPRIETARY_MODE diff --git a/src/components/include/application_manager/policies/policy_handler_observer.h b/src/components/include/application_manager/policies/policy_handler_observer.h index 9c1091d0a8..42348e7705 100644 --- a/src/components/include/application_manager/policies/policy_handler_observer.h +++ b/src/components/include/application_manager/policies/policy_handler_observer.h @@ -53,6 +53,8 @@ class PolicyHandlerObserver { virtual void OnPTUFinished(const bool ptu_result) {} + virtual void OnPTInited() {} + virtual ~PolicyHandlerObserver() {} }; } // namespace policy diff --git a/src/components/include/policy/policy_external/policy/policy_manager.h b/src/components/include/policy/policy_external/policy/policy_manager.h index c6f0202d59..1242c7a460 100644 --- a/src/components/include/policy/policy_external/policy/policy_manager.h +++ b/src/components/include/policy/policy_external/policy/policy_manager.h @@ -38,6 +38,7 @@ #include "utils/callable.h" #include "utils/optional.h" +#include "application_manager/policies/policy_encryption_flag_getter.h" #include "policy/access_remote.h" #include "policy/cache_manager_interface.h" #include "policy/policy_listener.h" @@ -49,7 +50,8 @@ namespace policy { class PolicySettings; typedef std::shared_ptr StatusNotifier; -class PolicyManager : public usage_statistics::StatisticsManager { +class PolicyManager : public usage_statistics::StatisticsManager, + public PolicyEncryptionFlagGetterInterface { public: /** * @brief The NotificationMode enum defines whether application will be diff --git a/src/components/include/policy/policy_regular/policy/policy_manager.h b/src/components/include/policy/policy_regular/policy/policy_manager.h index c1547da760..65f4cb69ff 100644 --- a/src/components/include/policy/policy_regular/policy/policy_manager.h +++ b/src/components/include/policy/policy_regular/policy/policy_manager.h @@ -50,7 +50,8 @@ namespace policy { class PolicySettings; typedef std::shared_ptr StatusNotifier; -class PolicyManager : public usage_statistics::StatisticsManager { +class PolicyManager : public usage_statistics::StatisticsManager, + public PolicyEncryptionFlagGetterInterface { public: virtual ~PolicyManager() {} 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..619c47ac34 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; @@ -69,10 +70,12 @@ class ProtocolHandler { /** * \brief Method for sending message to Mobile Application. * \param message RawMessage with params to be sent to Mobile App. + * \param needs_encryption whether message needs to be encrypted by policy * \param final_message tells whether message's * connection must be closed when message is processed */ virtual void SendMessageToMobileApp(const RawMessagePtr message, + bool needs_encryption, bool final_message) = 0; /** @@ -136,6 +139,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 a2ec715dbf..f5b6f28825 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 @@ -34,6 +34,7 @@ #define SRC_COMPONENTS_INCLUDE_TEST_APPLICATION_MANAGER_POLICIES_MOCK_POLICY_HANDLER_INTERFACE_H_ #include "application_manager/application_manager.h" +#include "application_manager/policies/policy_encryption_flag_getter.h" #include "application_manager/policies/policy_handler_interface.h" #include "gmock/gmock.h" #include "policy/policy_types.h" @@ -46,6 +47,8 @@ namespace policy_test { class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface { public: MOCK_METHOD0(LoadPolicyLibrary, bool()); + MOCK_CONST_METHOD0(PolicyEncryptionFlagGetter, + policy::PolicyEncryptionFlagGetterInterfaceSPtr()); MOCK_CONST_METHOD0(PolicyEnabled, bool()); MOCK_METHOD0(InitPolicyTable, bool()); MOCK_METHOD0(ResetPolicyTable, bool()); @@ -184,6 +187,7 @@ class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface { void(std::map app_hmi_types)); MOCK_METHOD1(OnCertificateUpdated, void(const std::string& certificate_data)); MOCK_METHOD1(OnPTUFinished, void(const bool ptu_result)); + MOCK_METHOD0(OnPTInited, void()); MOCK_METHOD1(OnCertificateDecrypted, void(bool is_succeeded)); MOCK_METHOD0(CanUpdate, bool()); MOCK_METHOD2(OnDeviceConsentChanged, diff --git a/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h index 0a6bef45dd..938be4eb85 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h +++ b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h @@ -57,6 +57,7 @@ class MockCacheManagerInterface : public ::policy::CacheManagerInterface { const PTString& hmi_level, const PTString& rpc, CheckPermissionResult& result)); + MOCK_CONST_METHOD0(pt, std::shared_ptr()); MOCK_METHOD0(IsPTPreloaded, bool()); MOCK_METHOD0(IgnitionCyclesBeforeExchange, int()); MOCK_METHOD1(KilometersBeforeExchange, int(int current)); @@ -296,6 +297,19 @@ class MockCacheManagerInterface : public ::policy::CacheManagerInterface { RequestType::State(const std::string& policy_app_id)); MOCK_CONST_METHOD1(GetAppRequestSubTypesState, RequestSubType::State(const std::string& policy_app_id)); + + MOCK_CONST_METHOD1( + GetAppEncryptionRequiredFlag, + rpc::Optional(const std::string& application_policy_name)); + + MOCK_CONST_METHOD1( + GetFunctionalGroupingEncryptionRequiredFlag, + rpc::Optional(const std::string& functional_group)); + + MOCK_CONST_METHOD2(GetApplicationParams, + void(const std::string& application_name, + policy_table::ApplicationParams& application_params)); + MOCK_CONST_METHOD0(GetPolicyAppIDs, const policy_table::Strings()); }; } // namespace policy_test diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h index 5313628890..7c71643044 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h @@ -54,6 +54,23 @@ namespace policy_manager_test { class MockPolicyManager : public PolicyManager { public: + MOCK_CONST_METHOD1(AppNeedEncryption, bool(const std::string& policy_app_id)); + MOCK_CONST_METHOD1( + GetFunctionalGroupsForApp, + const std::vector(const std::string& policy_app_id)); + MOCK_CONST_METHOD0(GetApplicationPolicyIDs, const std::vector()); + MOCK_CONST_METHOD2(FunctionNeedEncryption, + bool(const std::string& policy_group, + const std::string& policy_function_id)); + MOCK_CONST_METHOD1(FunctionGroupNeedEncryption, + bool(const std::string& policy_group)); + MOCK_CONST_METHOD1( + GetAppEncryptionRequired, + const rpc::Optional(const std::string& policy_app_id)); + MOCK_CONST_METHOD1(GetRPCsForFunctionGroup, + const std::vector(const std::string& group)); + MOCK_CONST_METHOD1(GetPolicyFunctionName, + const std::string(const uint32_t function_id)); MOCK_METHOD1(set_listener, void(PolicyListener* listener)); MOCK_METHOD2(InitPT, bool(const std::string& file_name, diff --git a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h index c296701e34..194445b8b6 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h @@ -258,6 +258,19 @@ class MockCacheManagerInterface : public CacheManagerInterface { RequestType::State(const std::string& policy_app_id)); MOCK_CONST_METHOD1(GetAppRequestSubTypesState, RequestSubType::State(const std::string& policy_app_id)); + + MOCK_CONST_METHOD1( + GetAppEncryptionRequiredFlag, + rpc::Optional(const std::string& application_policy_name)); + + MOCK_CONST_METHOD1( + GetFunctionalGroupingEncryptionRequiredFlag, + rpc::Optional(const std::string& functional_group)); + + MOCK_CONST_METHOD2(GetApplicationParams, + void(const std::string& application_name, + policy_table::ApplicationParams& application_params)); + MOCK_CONST_METHOD0(GetPolicyAppIDs, const policy_table::Strings()); }; } // namespace policy_test diff --git a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h index c6e692cf0b..4ddd8cb309 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h @@ -55,6 +55,23 @@ using namespace policy; class MockPolicyManager : public PolicyManager { public: + MOCK_CONST_METHOD1(AppNeedEncryption, bool(const std::string& policy_app_id)); + MOCK_CONST_METHOD1( + GetFunctionalGroupsForApp, + const std::vector(const std::string& policy_app_id)); + MOCK_CONST_METHOD0(GetApplicationPolicyIDs, const std::vector()); + MOCK_CONST_METHOD2(FunctionNeedEncryption, + bool(const std::string& policy_group, + const std::string& policy_function_id)); + MOCK_CONST_METHOD1(FunctionGroupNeedEncryption, + bool(const std::string& policy_group)); + MOCK_CONST_METHOD1( + GetAppEncryptionRequired, + const rpc::Optional(const std::string& policy_app_id)); + MOCK_CONST_METHOD1(GetRPCsForFunctionGroup, + const std::vector(const std::string& group)); + MOCK_CONST_METHOD1(GetPolicyFunctionName, + const std::string(const uint32_t function_id)); MOCK_METHOD1(set_listener, void(PolicyListener* listener)); MOCK_METHOD2(InitPT, bool(const std::string& file_name, diff --git a/src/components/include/test/protocol_handler/mock_protocol_handler.h b/src/components/include/test/protocol_handler/mock_protocol_handler.h index 4468914a26..772b63b582 100644 --- a/src/components/include/test/protocol_handler/mock_protocol_handler.h +++ b/src/components/include/test/protocol_handler/mock_protocol_handler.h @@ -44,8 +44,9 @@ namespace protocol_handler_test { class MockProtocolHandler : public ::protocol_handler::ProtocolHandler { public: - MOCK_METHOD2(SendMessageToMobileApp, + MOCK_METHOD3(SendMessageToMobileApp, void(const ::protocol_handler::RawMessagePtr message, + bool needs_encryption, bool final_message)); MOCK_METHOD1(AddProtocolObserver, void(::protocol_handler::ProtocolObserver* observer)); @@ -67,6 +68,7 @@ class MockProtocolHandler : public ::protocol_handler::ProtocolHandler { void(const ::protocol_handler::SessionContext& context, std::vector& rejected_params)); MOCK_METHOD0(NotifyOnFailedHandshake, void()); + MOCK_CONST_METHOD1(IsRPCServiceSecure, bool(const uint32_t connection_key)); }; } // namespace protocol_handler_test } // namespace components diff --git a/src/components/interfaces/MOBILE_API.xml b/src/components/interfaces/MOBILE_API.xml index a16a4afa53..d4cae5249d 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. + @@ -2235,6 +2238,7 @@ + @@ -8010,6 +8014,7 @@ Change in permissions for a given set of RPCs + diff --git a/src/components/media_manager/test/media_manager_impl_test.cc b/src/components/media_manager/test/media_manager_impl_test.cc index cd299d736c..3c537f2337 100644 --- a/src/components/media_manager/test/media_manager_impl_test.cc +++ b/src/components/media_manager/test/media_manager_impl_test.cc @@ -194,6 +194,7 @@ class MediaManagerImplTest : public ::testing::Test { kProtocolVersion, data_sending, data_sending_size, + false, serviceType)); media_manager_impl_->OnMessageReceived(raw_message_ptr); media_manager_impl_->OnMobileMessageSent(raw_message_ptr); diff --git a/src/components/policy/policy_external/include/policy/cache_manager.h b/src/components/policy/policy_external/include/policy/cache_manager.h index 19a475371d..05d423da83 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager.h +++ b/src/components/policy/policy_external/include/policy/cache_manager.h @@ -413,6 +413,12 @@ class CacheManager : public CacheManagerInterface { */ bool GetFunctionalGroupings(policy_table::FunctionalGroupings& groups); + /** + * @brief Get policy app names from PT + * @return container of strings representing policy application names + */ + const policy_table::Strings GetPolicyAppIDs() const OVERRIDE; + /** * Checks if the application is represented in policy table * @param app_id application id @@ -898,6 +904,16 @@ class CacheManager : public CacheManagerInterface { const std::string& policy_app_id, policy::Permissions& permission); + EncryptionRequired GetAppEncryptionRequiredFlag( + const std::string& application_policy_name) const OVERRIDE; + + EncryptionRequired GetFunctionalGroupingEncryptionRequiredFlag( + const std::string& functional_group) const OVERRIDE; + + void GetApplicationParams( + const std::string& application_name, + policy_table::ApplicationParams& application_policies) const OVERRIDE; + private: std::shared_ptr pt_; std::shared_ptr snapshot_; diff --git a/src/components/policy/policy_external/include/policy/cache_manager_interface.h b/src/components/policy/policy_external/include/policy/cache_manager_interface.h index 0cbbb6df1f..4eb1f2167d 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_external/include/policy/cache_manager_interface.h @@ -435,6 +435,12 @@ class CacheManagerInterface { virtual bool GetFunctionalGroupings( policy_table::FunctionalGroupings& groups) = 0; + /** + * @brief Get policy app names from PT + * @return container of strings representing policy application names + */ + virtual const policy_table::Strings GetPolicyAppIDs() const = 0; + /** * Checks if the application is represented in policy table * @param app_id application id @@ -954,6 +960,37 @@ class CacheManagerInterface { virtual void OnDeviceSwitching(const std::string& device_id_from, const std::string& device_id_to) = 0; + /** + * @brief GetAppEncryptionRequiredFlag retrieves encryption required flag + * for + * given application + * @param application policy application name + * @return optional object containing encryption required flag + */ + virtual rpc::Optional GetAppEncryptionRequiredFlag( + const std::string& application_policy_name) const = 0; + + /** + * @brief GetFunctionalGroupingEncryptionRequiredFlag retrieves encryption + * required flag + * for + * given functional grouping + * @param functional_group policy functional group name + * @return optional object containing encryption required flag + */ + virtual rpc::Optional + GetFunctionalGroupingEncryptionRequiredFlag( + const std::string& functional_group) const = 0; + + /** + * @brief retreives application params + * @param application_name policy applicatoin name + * @param application_params application params + */ + virtual void GetApplicationParams( + const std::string& application_name, + policy_table::ApplicationParams& application_params) const = 0; + #ifdef BUILD_TESTS /** * @brief GetPT allows to obtain std::shared_ptr to PT. diff --git a/src/components/policy/policy_external/include/policy/policy_helper.h b/src/components/policy/policy_external/include/policy/policy_helper.h index bce2559431..0918f9e1c3 100644 --- a/src/components/policy/policy_external/include/policy/policy_helper.h +++ b/src/components/policy/policy_external/include/policy/policy_helper.h @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2013, Ford Motor Company All rights reserved. @@ -201,6 +201,15 @@ struct CheckAppPolicy { */ bool IsRequestSubTypeChanged(const AppPoliciesValueType& app_policy) const; + /** + * @brief IsEncryptionRequiredFlagChanged check if encryption_needed flag was + * changed for application or application groups + * @param app_policy application policies + * @return true if encryption_needed state was changed otherwise - false + */ + bool IsEncryptionRequiredFlagChanged( + const AppPoliciesValueType& app_policy) const; + /** * @brief Helper function that inserts permissions into app_permissions_diff_ * map. @@ -307,6 +316,14 @@ struct ProcessFunctionalGroup { private: GroupConsent GetGroupState(const std::string& group_name); + /* + * @brief Fills encryption required flags for all rpcs in functional group + * @param encryption_required Optional object containing encryption required + * flag + */ + void FillEncryptionFlagForRpcs( + const policy_table::Rpc& rpcs, + const policy::EncryptionRequired encryption_required); const policy_table::FunctionalGroupings& fg_; const std::vector& group_permissions_; Permissions& data_; diff --git a/src/components/policy/policy_external/include/policy/policy_manager_impl.h b/src/components/policy/policy_external/include/policy/policy_manager_impl.h index 261f66a3b2..cb06a65e41 100644 --- a/src/components/policy/policy_external/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_external/include/policy/policy_manager_impl.h @@ -54,7 +54,47 @@ class PolicyManagerImpl : public PolicyManager { public: PolicyManagerImpl(); explicit PolicyManagerImpl(bool in_memory); + /* + * \param policy_app_id policy app id + * \return true if the app need encryption + */ + bool AppNeedEncryption(const std::string& policy_app_id) const OVERRIDE; + + /* + * \param policy_app_id policy app id + * \return Optional app need encryption + */ + const rpc::Optional GetAppEncryptionRequired( + const std::string& policy_app_id) const OVERRIDE; + + /* + * \param policy_app_id policy app id + * \return groups that exist for app + */ + const std::vector GetFunctionalGroupsForApp( + const std::string& policy_app_id) const OVERRIDE; + + const std::vector GetApplicationPolicyIDs() const OVERRIDE; + + /* + * \param policy_group group + * \return true if the group need encryption + */ + bool FunctionGroupNeedEncryption( + const std::string& policy_group) const OVERRIDE; + /* + * \param policy_group group\ + * \return RPCs that exists in group + */ + const std::vector GetRPCsForFunctionGroup( + const std::string& group) const OVERRIDE; + /* + * \param function_id function id + * \return policy function name + */ + const std::string GetPolicyFunctionName( + const uint32_t function_id) const OVERRIDE; /** * @brief set_listener set new policy listener instance * @param listener new policy listener diff --git a/src/components/policy/policy_external/include/policy/policy_table/types.h b/src/components/policy/policy_external/include/policy/policy_table/types.h index 8795e2690f..7f59c17384 100644 --- a/src/components/policy/policy_external/include/policy/policy_table/types.h +++ b/src/components/policy/policy_external/include/policy/policy_table/types.h @@ -116,7 +116,6 @@ typedef Integer FunctionIDInt; typedef Map RemoteRpcs; typedef Map AccessModules; typedef Array, 0, 255> ModuleTypes; - typedef AppHMIType AppHmiType; typedef std::vector AppHmiTypes; @@ -237,6 +236,7 @@ struct ApplicationParams : PolicyBase { // App Service Params Optional app_service_parameters; Optional allow_unknown_rpc_passthrough; + Optional encryption_required; public: ApplicationParams(); @@ -331,6 +331,7 @@ struct Rpcs : CompositeType { disallowed_by_external_consent_entities_on; Optional disallowed_by_external_consent_entities_off; + Optional encryption_required; public: Rpcs(); diff --git a/src/components/policy/policy_external/include/policy/policy_table_interface_ext.xml b/src/components/policy/policy_external/include/policy/policy_table_interface_ext.xml index 46c8f40a01..af7effd97f 100644 --- a/src/components/policy/policy_external/include/policy/policy_table_interface_ext.xml +++ b/src/components/policy/policy_external/include/policy/policy_table_interface_ext.xml @@ -114,6 +114,7 @@ + + diff --git a/src/components/policy/policy_external/include/policy/policy_types.h b/src/components/policy/policy_external/include/policy/policy_types.h index 7247995f48..fcf6c33c1b 100644 --- a/src/components/policy/policy_external/include/policy/policy_types.h +++ b/src/components/policy/policy_external/include/policy/policy_types.h @@ -41,6 +41,7 @@ #include #include +#include "policy/policy_table/types.h" #include "transport_manager/common.h" #include "utils/helpers.h" @@ -87,6 +88,8 @@ typedef std::string Parameter; typedef std::string RpcName; typedef std::set RPCParams; +typedef rpc::Optional EncryptionRequired; + typedef std::map > HMIPermissions; struct ParameterPermissions : std::map > { @@ -102,6 +105,7 @@ struct ParameterPermissions struct RpcPermissions { HMIPermissions hmi_permissions; ParameterPermissions parameter_permissions; + EncryptionRequired require_encryption; }; typedef std::map Permissions; @@ -508,7 +512,8 @@ enum PermissionsCheckResult { RESULT_CONSENT_NOT_REQIURED, RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED, RESULT_REQUEST_TYPE_CHANGED, - RESULT_REQUEST_SUBTYPE_CHANGED + RESULT_REQUEST_SUBTYPE_CHANGED, + RESULT_ENCRYPTION_REQUIRED_FLAG_CHANGED, }; /** diff --git a/src/components/policy/policy_external/src/cache_manager.cc b/src/components/policy/policy_external/src/cache_manager.cc index 4170e7aaa6..965b91c9f4 100644 --- a/src/components/policy/policy_external/src/cache_manager.cc +++ b/src/components/policy/policy_external/src/cache_manager.cc @@ -325,6 +325,20 @@ const policy_table::Strings& CacheManager::GetGroups(const PTString& app_id) { return pt_->policy_table.app_policies_section.apps[app_id].groups; } +const policy_table::Strings CacheManager::GetPolicyAppIDs() const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + + const auto apps = pt_->policy_table.app_policies_section.apps; + + policy_table::Strings policy_app_ids; + for (const auto& app : apps) { + policy_app_ids.push_back(app.first); + } + + return policy_app_ids; +} + bool CacheManager::CanAppKeepContext(const std::string& app_id) const { CACHE_MANAGER_CHECK(false); sync_primitives::AutoLock auto_lock(cache_lock_); @@ -3078,4 +3092,46 @@ void CacheManager::BackgroundBackuper::DoBackup() { backup_notifier_.NotifyOne(); } +EncryptionRequired CacheManager::GetAppEncryptionRequiredFlag( + const std::string& application) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + + return pt_->policy_table.app_policies_section.apps[application] + .encryption_required; +} + +EncryptionRequired CacheManager::GetFunctionalGroupingEncryptionRequiredFlag( + const std::string& functional_group) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + + const auto& functional_groupings = pt_->policy_table.functional_groupings; + + const auto& grouping_itr = functional_groupings.find(functional_group); + if (grouping_itr == functional_groupings.end()) { + LOG4CXX_WARN(logger_, "Group " << functional_group << " not found"); + return rpc::Optional(rpc::Boolean(false)); + } + + return (*grouping_itr).second.encryption_required; +} + +void CacheManager::GetApplicationParams( + const std::string& application_name, + policy_table::ApplicationParams& application_params) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + + const auto apps = pt_->policy_table.app_policies_section.apps; + const auto it = apps.find(application_name); + if (apps.end() == it) { + LOG4CXX_WARN(logger_, + "Application " << application_name << " was not found"); + return; + } + + application_params = (*it).second; +} + } // namespace policy diff --git a/src/components/policy/policy_external/src/policy_helper.cc b/src/components/policy/policy_external/src/policy_helper.cc index e8855bb11a..bb0a36df68 100644 --- a/src/components/policy/policy_external/src/policy_helper.cc +++ b/src/components/policy/policy_external/src/policy_helper.cc @@ -452,6 +452,8 @@ PermissionsCheckResult CheckAppPolicy::CheckPermissionsChanges( bool has_new_groups = HasNewGroups(app_policy); + const bool encryption_required_flag_changed = + IsEncryptionRequiredFlagChanged(app_policy); if (has_revoked_groups && has_consent_needed_groups) { return RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED; } else if (has_revoked_groups) { @@ -460,6 +462,8 @@ PermissionsCheckResult CheckAppPolicy::CheckPermissionsChanges( return RESULT_CONSENT_NEEDED; } else if (has_new_groups) { return RESULT_CONSENT_NOT_REQIURED; + } else if (encryption_required_flag_changed) { + return RESULT_ENCRYPTION_REQUIRED_FLAG_CHANGED; } return RESULT_NO_CHANGES; @@ -540,11 +544,98 @@ bool CheckAppPolicy::IsRequestSubTypeChanged( return diff.size(); } +bool CheckAppPolicy::IsEncryptionRequiredFlagChanged( + const AppPoliciesValueType& app_policy) const { + LOG4CXX_AUTO_TRACE(logger_); + auto get_app_encryption_needed = + [](const std::string& policy_app_id, + policy_table::ApplicationPolicies& policies) + -> rpc::Optional { + auto it = policies.find(policy_app_id); + if (policies.end() == it) { + LOG4CXX_WARN(logger_, "App is not present in policies" << policy_app_id); + return rpc::Optional(false); + } + return it->second.encryption_required; + }; + + auto get_app_groups = + [](const std::string& policy_app_id, + policy_table::ApplicationPolicies& policies) -> policy_table::Strings { + policy_table::Strings result; + auto it = policies.find(policy_app_id); + if (policies.end() == it) { + LOG4CXX_WARN(logger_, "App is not present in policies" << policy_app_id); + return result; + } + auto& groups = it->second.groups; + std::copy(groups.begin(), groups.end(), std::back_inserter(result)); + return result; + }; + + auto get_app_rpcs = [](const std::string group_name, + const FunctionalGroupings& groups) + -> rpc::Optional { + auto it = groups.find(group_name); + if (it == groups.end()) { + return rpc::Optional(); + } + return rpc::Optional(it->second); + }; + + const auto snapshot_groups = get_app_groups( + app_policy.first, snapshot_->policy_table.app_policies_section.apps); + const auto update_groups = get_app_groups( + app_policy.first, update_->policy_table.app_policies_section.apps); + + auto get_resulting_encryption_required_flag_for_app_groups = + [this, &get_app_rpcs]( + const rpc::policy_table_interface_base::Strings& app_groups, + const std::shared_ptr pt) { + for (const auto& group : app_groups) { + const auto rpcs = + get_app_rpcs(group, pt->policy_table.functional_groupings); + if (*rpcs->encryption_required) { + return true; + } + } + + return false; + }; + + auto group_res_en_flag_changed = + [this, &get_resulting_encryption_required_flag_for_app_groups]( + const rpc::policy_table_interface_base::Strings& snapshot_groups, + const rpc::policy_table_interface_base::Strings& update_groups) { + return get_resulting_encryption_required_flag_for_app_groups( + snapshot_groups, snapshot_) != + get_resulting_encryption_required_flag_for_app_groups( + update_groups, update_); + }; + + const auto snapshot_app_encryption_needed = get_app_encryption_needed( + app_policy.first, snapshot_->policy_table.app_policies_section.apps); + const auto update_app_encryption_needed = get_app_encryption_needed( + app_policy.first, update_->policy_table.app_policies_section.apps); + + const bool app_encryption_needed_changed = + (snapshot_app_encryption_needed.is_initialized() != + update_app_encryption_needed.is_initialized()) || + (*snapshot_app_encryption_needed != *update_app_encryption_needed); + + if ((!update_app_encryption_needed.is_initialized() || + *update_app_encryption_needed) && + group_res_en_flag_changed(snapshot_groups, update_groups)) { + return true; + } + + return app_encryption_needed_changed; +} + void FillActionsForAppPolicies::operator()( const policy::CheckAppPolicyResults::value_type& value) { const std::string app_id = value.first; - const policy_table::ApplicationPolicies::const_iterator app_policy = - app_policies_.find(app_id); + const auto app_policy = app_policies_.find(app_id); if (app_policies_.end() == app_policy) { return; @@ -567,6 +658,7 @@ void FillActionsForAppPolicies::operator()( case RESULT_PERMISSIONS_REVOKED: case RESULT_REQUEST_TYPE_CHANGED: case RESULT_REQUEST_SUBTYPE_CHANGED: + case RESULT_ENCRYPTION_REQUIRED_FLAG_CHANGED: break; case RESULT_NO_CHANGES: default: @@ -641,9 +733,11 @@ void FillNotificationData::UpdateParameters( // particular parameters (if applicable), the system shall find all of the // functional groups the RPC is included in. If user consent is needed as // listed within the functional group in the policy table, the system shall - // use a logical AND: backend permissions AND User permissions. If the RPC is + // use a logical AND: backend permissions AND User permissions. If the RPC + // is // listed under more than one group, the system shall perform a logical OR - // amongst all of the possible allowed permissions scenarios for the RPC (and + // among all of the possible allowed permissions scenarios for the RPC + // (and // parameter/or HMI level) defined by each of the functional groups. // Due to requirements SDL must consider cases when 'parameters' section is @@ -734,7 +828,8 @@ void FillNotificationData::ExcludeSame(RpcPermissions& rpc) { } } - // Removing disallowed parameters from allowed and undefined (by user consent) + // Removing disallowed parameters from allowed and undefined (by user + // consent) if (rpc.parameter_permissions.end() != it_parameter_user_disallowed) { if (rpc.parameter_permissions.end() != it_parameter_allowed) { ExcludeSameParameters(rpc.parameter_permissions[kAllowedKey], @@ -841,10 +936,31 @@ bool ProcessFunctionalGroup::operator()(const StringsValueType& group_name) { undefined_group_consent_, does_require_user_consent); std::for_each(rpcs.begin(), rpcs.end(), filler); + const auto encryption_required = (*it).second.encryption_required; + FillEncryptionFlagForRpcs(rpcs, encryption_required); } return true; } +void ProcessFunctionalGroup::FillEncryptionFlagForRpcs( + const policy_table::Rpc& rpcs, + const EncryptionRequired encryption_required) { + auto update_encryption_required = [](EncryptionRequired& current, + const EncryptionRequired& incoming) { + if (!incoming.is_initialized()) { + return; + } + if (current.is_initialized() && *current) { + return; + } + current = incoming; + }; + for (const auto& rpc : rpcs) { + auto& item = data_[rpc.first]; + update_encryption_required(item.require_encryption, encryption_required); + } +} + GroupConsent ProcessFunctionalGroup::GetGroupState( const std::string& group_name) { std::vector::const_iterator it = diff --git a/src/components/policy/policy_external/src/policy_manager_impl.cc b/src/components/policy/policy_external/src/policy_manager_impl.cc index c11bdefb90..255f6050a6 100644 --- a/src/components/policy/policy_external/src/policy_manager_impl.cc +++ b/src/components/policy/policy_external/src/policy_manager_impl.cc @@ -528,7 +528,7 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, CheckAppPolicyResults PolicyManagerImpl::CheckPermissionsChanges( const std::shared_ptr pt_update, const std::shared_ptr snapshot) { - LOG4CXX_INFO(logger_, "Checking incoming permissions."); + LOG4CXX_AUTO_TRACE(logger_); // Replace predefined policies with its actual setting, e.g. "123":"default" // to actual values of default section @@ -832,7 +832,6 @@ void PolicyManagerImpl::CheckPermissions(const PTString& device_id, LOG4CXX_INFO(logger_, "CheckPermissions for " << app_id << " and rpc " << rpc << " for " << hmi_level << " level."); - Permissions rpc_permissions; // Check, if there are calculated permission present in cache @@ -1076,13 +1075,15 @@ bool PolicyManagerImpl::ReactOnUserDevConsentForApp( const transport_manager::DeviceHandle& device_handle, const std::string& app_id, const bool is_device_allowed) { - auto current_request_types = GetAppRequestTypes(device_handle, app_id); + std::vector current_request_types = + GetAppRequestTypes(device_handle, app_id); std::string current_priority, new_priority; GetPriority(app_id, ¤t_priority); bool result = cache_->ReactOnUserDevConsentForApp(app_id, is_device_allowed); - auto new_request_types = GetAppRequestTypes(device_handle, app_id); + std::vector new_request_types = + GetAppRequestTypes(device_handle, app_id); GetPriority(app_id, &new_priority); std::sort(current_request_types.begin(), current_request_types.end()); std::sort(new_request_types.begin(), new_request_types.end()); @@ -1107,7 +1108,7 @@ bool PolicyManagerImpl::ReactOnUserDevConsentForApp( } if (permissions.requestTypeChanged || (!permissions.priority.empty())) { - const auto& device_id = GetCurrentDeviceId(device_handle, app_id); + auto device_id = GetCurrentDeviceId(device_handle, app_id); listener_->SendOnAppPermissionsChanged(permissions, device_id, app_id); } return result; @@ -1394,13 +1395,11 @@ void PolicyManagerImpl::GetPermissionsForApp( } bool allowed_by_default = false; - const auto device_consent = GetUserConsentForDevice(device_id); - if ((policy::kDeviceAllowed == device_consent) && - cache_->IsDefaultPolicy(policy_app_id)) { + if (cache_->IsDefaultPolicy(policy_app_id)) { app_id_to_check = kDefaultId; allowed_by_default = true; } else if (cache_->IsPredataPolicy(policy_app_id) || - policy::kDeviceAllowed != device_consent) { + policy::kDeviceDisallowed == GetUserConsentForDevice(device_id)) { app_id_to_check = kPreDataConsentId; allowed_by_default = true; } @@ -1593,7 +1592,7 @@ void PolicyManagerImpl::UpdateAppConsentWithExternalConsent( void PolicyManagerImpl::NotifySystem( const std::string& device_id, - const PolicyManagerImpl::AppPoliciesValueType& app_policy) const { + const AppPoliciesValueType& app_policy) const { listener()->OnPendingPermissionChange(device_id, app_policy.first); } @@ -1768,14 +1767,12 @@ void PolicyManagerImpl::KmsChanged(int kilometers) { const boost::optional PolicyManagerImpl::LockScreenDismissalEnabledState() const { - LOG4CXX_AUTO_TRACE(logger_); return cache_->LockScreenDismissalEnabledState(); } const boost::optional PolicyManagerImpl::LockScreenDismissalWarningMessage( const std::string& language) const { - LOG4CXX_AUTO_TRACE(logger_); return cache_->LockScreenDismissalWarningMessage(language); } @@ -1888,7 +1885,7 @@ bool PolicyManagerImpl::IsApplicationRevoked(const std::string& app_id) const { bool PolicyManagerImpl::IsConsentNeeded(const std::string& device_id, const std::string& app_id) { LOG4CXX_AUTO_TRACE(logger_); - const int count = cache_->CountUnconsentedGroups(app_id, device_id); + int count = cache_->CountUnconsentedGroups(app_id, device_id); LOG4CXX_DEBUG(logger_, "There are: " << count << " unconsented groups."); return count != 0; } @@ -2032,10 +2029,7 @@ StatusNotifier PolicyManagerImpl::AddApplication( const std::string& application_id, const rpc::policy_table_interface_base::AppHmiTypes& hmi_types) { LOG4CXX_AUTO_TRACE(logger_); - auto device_consent = GetUserConsentForDevice(device_id); - LOG4CXX_DEBUG(logger_, - "check_device_id: " << device_id << " check_device_consent: " - << device_consent); + DeviceConsent device_consent = GetUserConsentForDevice(device_id); sync_primitives::AutoLock lock(apps_registration_lock_); if (IsNewApplication(application_id)) { LOG4CXX_DEBUG(logger_, "Adding new application"); @@ -2073,7 +2067,6 @@ void PolicyManagerImpl::ProcessExternalConsentStatusForApp( CalculateGroupsConsentFromExternalConsent( groups_by_status, allowed_groups, disallowed_groups); - LOG4CXX_DEBUG(logger_, "check device_id: " << device_id); UpdateAppConsentWithExternalConsent(device_id, application_id, allowed_groups, @@ -2113,16 +2106,8 @@ void PolicyManagerImpl::PromoteExistedApplication( DeviceConsent device_consent) { // If device consent changed to allowed during application being // disconnected, app permissions should be changed also - LOG4CXX_DEBUG(logger_, - "kDeviceAllowed == device_consent: " - << (kDeviceAllowed == device_consent) - << " device_consent: " << device_consent); if (kDeviceAllowed == device_consent && cache_->IsPredataPolicy(application_id)) { - LOG4CXX_INFO(logger_, - "Setting " - << policy::kDefaultId - << " permissions for application id: " << application_id); cache_->SetDefaultPolicy(application_id); } ProcessExternalConsentStatusForApp( @@ -2211,7 +2196,8 @@ void PolicyManagerImpl::SetDefaultHmiTypes( const std::string& application_id, const std::vector& hmi_types) { LOG4CXX_INFO(logger_, "SetDefaultHmiTypes"); - const auto device_id = GetCurrentDeviceId(device_handle, application_id); + const std::string device_id = + GetCurrentDeviceId(device_handle, application_id); ApplicationOnDevice who = {device_id, application_id}; access_remote_->SetDefaultHmiTypes(who, hmi_types); } @@ -2324,4 +2310,94 @@ void PolicyManagerImpl::set_access_remote( access_remote_ = access_remote; } +bool PolicyManagerImpl::AppNeedEncryption( + const std::string& policy_app_id) const { + const auto encryption_required = + cache_->GetAppEncryptionRequiredFlag(policy_app_id); + + return encryption_required.is_initialized() ? *encryption_required : true; +} + +const rpc::Optional PolicyManagerImpl::GetAppEncryptionRequired( + const std::string& policy_app_id) const { + return cache_->GetAppEncryptionRequiredFlag(policy_app_id); +} + +const std::vector PolicyManagerImpl::GetFunctionalGroupsForApp( + const std::string& policy_app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + using namespace rpc::policy_table_interface_base; + DCHECK(kDeviceId != policy_app_id); + + std::vector function_groups; + + ApplicationParams app_params; + cache_->GetApplicationParams(policy_app_id, app_params); + + const auto& policy_function_group = app_params.groups; + + for (const auto& group : policy_function_group) { + function_groups.push_back(group); + } + + return function_groups; +} + +const std::vector PolicyManagerImpl::GetApplicationPolicyIDs() + const { + LOG4CXX_AUTO_TRACE(logger_); + std::vector policy_app_ids; + + const auto apps = cache_->GetPolicyAppIDs(); + + for (const auto& app : apps) { + policy_app_ids.push_back(app); + } + + return policy_app_ids; +} + +bool PolicyManagerImpl::FunctionGroupNeedEncryption( + const std::string& policy_group) const { + LOG4CXX_AUTO_TRACE(logger_); + FunctionalGroupings functional_groupings; + cache_->GetFunctionalGroupings(functional_groupings); + + const auto& grouping_itr = functional_groupings.find(policy_group); + + if (grouping_itr == functional_groupings.end()) { + LOG4CXX_WARN(logger_, "Group " << policy_group << " not found"); + return false; + } + + const auto& grouping = (*grouping_itr).second; + + return grouping.encryption_required.is_initialized() + ? *grouping.encryption_required + : false; +} + +const std::string PolicyManagerImpl::GetPolicyFunctionName( + const uint32_t function_id) const { + LOG4CXX_AUTO_TRACE(logger_); + return policy_table::EnumToJsonString( + static_cast(function_id)); +} + +const std::vector PolicyManagerImpl::GetRPCsForFunctionGroup( + const std::string& group) const { + std::vector rpcs_for_group; + + FunctionalGroupings functional_groupings; + cache_->GetFunctionalGroupings(functional_groupings); + + const auto& rpcs = functional_groupings[group].rpcs; + + for (const auto& rpc : rpcs) { + rpcs_for_group.push_back(rpc.first); + } + + return rpcs_for_group; +} + } // namespace policy 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 6f60b43af9..c7dfe98271 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,169 @@ 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/policy/policy_external/src/policy_table/types.cc b/src/components/policy/policy_external/src/policy_table/types.cc index d39b3f7623..cfe5ceed30 100644 --- a/src/components/policy/policy_external/src/policy_table/types.cc +++ b/src/components/policy/policy_external/src/policy_table/types.cc @@ -45,7 +45,6 @@ PolicyBase::PolicyBase(const Json::Value* value__) , default_hmi(impl::ValueMember(value__, "default_hmi")) , keep_context(impl::ValueMember(value__, "keep_context")) , steal_focus(impl::ValueMember(value__, "steal_focus")) {} - Json::Value PolicyBase::ToJsonValue() const { Json::Value result__(Json::objectValue); impl::WriteJsonField("groups", groups, &result__); @@ -355,7 +354,8 @@ ApplicationParams::ApplicationParams(const Json::Value* value__) , icon_url(impl::ValueMember(value__, "icon_url")) , app_service_parameters(impl::ValueMember(value__, "app_services")) , allow_unknown_rpc_passthrough( - impl::ValueMember(value__, "allow_unknown_rpc_passthrough")) {} + impl::ValueMember(value__, "allow_unknown_rpc_passthrough")) + , encryption_required(impl::ValueMember(value__, "encryption_required")) {} Json::Value ApplicationParams::ToJsonValue() const { Json::Value result__(PolicyBase::ToJsonValue()); @@ -379,6 +379,7 @@ Json::Value ApplicationParams::ToJsonValue() const { impl::WriteJsonField("allow_unknown_rpc_passthrough", allow_unknown_rpc_passthrough, &result__); + impl::WriteJsonField("encryption_required", encryption_required, &result__); return result__; } @@ -430,6 +431,9 @@ bool ApplicationParams::is_valid() const { if (!allow_unknown_rpc_passthrough.is_valid()) { return false; } + if (!encryption_required.is_valid()) { + return false; + } return Validate(); } @@ -489,6 +493,9 @@ bool ApplicationParams::struct_empty() const { if (allow_unknown_rpc_passthrough.is_initialized()) { return false; } + if (!encryption_required.is_valid()) { + return false; + } return true; } @@ -567,6 +574,10 @@ void ApplicationParams::ReportErrors(rpc::ValidationReport* report__) const { allow_unknown_rpc_passthrough.ReportErrors( &report__->ReportSubobject("allow_unknown_rpc_passthrough")); } + if (!encryption_required.is_valid()) { + encryption_required.ReportErrors( + &report__->ReportSubobject("encryption_required")); + } } void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { @@ -663,7 +674,8 @@ Rpcs::Rpcs(const Json::Value* value__) , disallowed_by_external_consent_entities_on(impl::ValueMember( value__, "disallowed_by_external_consent_entities_on")) , disallowed_by_external_consent_entities_off(impl::ValueMember( - value__, "disallowed_by_external_consent_entities_off")) {} + value__, "disallowed_by_external_consent_entities_off")) + , encryption_required(impl::ValueMember(value__, "encryption_required")) {} Json::Value Rpcs::ToJsonValue() const { Json::Value result__(Json::objectValue); @@ -675,6 +687,7 @@ Json::Value Rpcs::ToJsonValue() const { impl::WriteJsonField("disallowed_by_external_consent_entities_off", disallowed_by_external_consent_entities_off, &result__); + impl::WriteJsonField("encryption_required", encryption_required, &result__); return result__; } @@ -691,6 +704,9 @@ bool Rpcs::is_valid() const { if (!disallowed_by_external_consent_entities_off.is_valid()) { return false; } + if (!encryption_required.is_valid()) { + return false; + } return Validate(); } @@ -711,6 +727,9 @@ bool Rpcs::struct_empty() const { if (disallowed_by_external_consent_entities_off.is_initialized()) { return false; } + if (encryption_required.is_initialized()) { + return false; + } return true; } @@ -735,6 +754,10 @@ void Rpcs::ReportErrors(rpc::ValidationReport* report__) const { &report__->ReportSubobject( "disallowed_by_external_consent_entities_off")); } + if (!encryption_required.is_valid()) { + encryption_required.ReportErrors( + &report__->ReportSubobject("encryption_required")); + } } void Rpcs::SetPolicyTableType(PolicyTableType pt_type) { diff --git a/src/components/policy/policy_external/src/sql_pt_ext_queries.cc b/src/components/policy/policy_external/src/sql_pt_ext_queries.cc index 2c24bbc522..ea323908c0 100644 --- a/src/components/policy/policy_external/src/sql_pt_ext_queries.cc +++ b/src/components/policy/policy_external/src/sql_pt_ext_queries.cc @@ -207,9 +207,10 @@ const std::string kInsertApplication = " `default_hmi`, `priority_value`, `is_revoked`, `memory_kb`, " " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " " `endpoint`, `enabled`, `auth_token`, " - " `cloud_transport_type`, `icon_url`, `allow_unknown_rpc_passthrough`) " + " `cloud_transport_type`, `icon_url`, `allow_unknown_rpc_passthrough`, " + "`encryption_required`) " "VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; const std::string kCollectFriendlyMsg = "SELECT * FROM `message`"; @@ -238,7 +239,8 @@ const std::string kSelectAppPolicies = "SELECT `id`, `priority_value`, `default_hmi`, `keep_context`, " " `steal_focus`, `memory_kb`, `heart_beat_timeout_ms`, `certificate`, " " `hybrid_app_preference_value`, `endpoint`, `enabled`, `auth_token`, " - " `cloud_transport_type`, `icon_url`, `allow_unknown_rpc_passthrough` " + " `cloud_transport_type`, `icon_url`, `allow_unknown_rpc_passthrough`, " + "`encryption_required`" "FROM `application`"; const std::string kSelectFunctionalGroupNames = diff --git a/src/components/policy/policy_external/src/sql_pt_ext_representation.cc b/src/components/policy/policy_external/src/sql_pt_ext_representation.cc index e4711a3cd2..30eb7b4f38 100644 --- a/src/components/policy/policy_external/src/sql_pt_ext_representation.cc +++ b/src/components/policy/policy_external/src/sql_pt_ext_representation.cc @@ -796,6 +796,9 @@ bool SQLPTExtRepresentation::SaveSpecificAppPolicy( app.second.allow_unknown_rpc_passthrough.is_initialized() ? app_query.Bind(15, *app.second.allow_unknown_rpc_passthrough) : app_query.Bind(15); + app.second.encryption_required.is_initialized() + ? app_query.Bind(16, *app.second.encryption_required) + : app_query.Bind(16); if (!app_query.Exec() || !app_query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into application."); @@ -940,6 +943,9 @@ bool SQLPTExtRepresentation::GatherApplicationPoliciesSection( *params.cloud_transport_type = query.GetString(12); *params.icon_url = query.GetString(13); *params.allow_unknown_rpc_passthrough = query.GetBoolean(14); + if (!query.IsNull(15)) { + *params.encryption_required = query.GetBoolean(15); + } const auto& gather_app_id = ((*policies).apps[app_id].is_string()) ? (*policies).apps[app_id].get_string() : app_id; diff --git a/src/components/policy/policy_external/src/sql_pt_queries.cc b/src/components/policy/policy_external/src/sql_pt_queries.cc index 5592fdecd8..5e89d0b372 100644 --- a/src/components/policy/policy_external/src/sql_pt_queries.cc +++ b/src/components/policy/policy_external/src/sql_pt_queries.cc @@ -82,7 +82,8 @@ const std::string kCreateSchema = "CREATE TABLE IF NOT EXISTS `functional_group`( " " `id` INTEGER PRIMARY KEY NOT NULL, " " `user_consent_prompt` TEXT, " - " `name` VARCHAR(100) NOT NULL " + " `name` VARCHAR(100) NOT NULL, " + " `encryption_required` BOOLEAN " "); " "CREATE TABLE IF NOT EXISTS `external_consent_entities`( " " `group_id` INTEGER NOT NULL, " @@ -160,6 +161,7 @@ const std::string kCreateSchema = " `icon_url` VARCHAR(65535), " " `allow_unknown_rpc_passthrough` BOOLEAN, " " `remote_control_denied` BOOLEAN NOT NULL DEFAULT 0, " + " `encryption_required` BOOLEAN, " " CONSTRAINT `fk_application_hmi_level1` " " FOREIGN KEY(`default_hmi`) " " REFERENCES `hmi_level`(`value`), " @@ -658,8 +660,9 @@ const std::string kSelectLockScreenIcon = "SELECT `url` FROM `endpoint` WHERE `service` = ? AND `application_id` = ?"; const std::string kInsertFunctionalGroup = - "INSERT INTO `functional_group` (`id`, `name`, `user_consent_prompt`) " - " VALUES (?, ?, ?)"; + "INSERT INTO `functional_group` (`id`, `name`, `user_consent_prompt`, " + "`encryption_required`) " + " VALUES (?, ?, ?, ?)"; const std::string kInsertRpc = "INSERT INTO `rpc` (`name`, `hmi_level_value`, `functional_group_id`) " @@ -679,9 +682,10 @@ const std::string kInsertApplication = "INSERT OR IGNORE INTO `application` (`id`, `priority_value`, " "`is_revoked`, `memory_kb`, `heart_beat_timeout_ms`, `certificate`, " "`hybrid_app_preference_value`, `endpoint`, `enabled`, `auth_token`, " - "`cloud_transport_type`, `icon_url`, `allow_unknown_rpc_passthrough`) " + "`cloud_transport_type`, `icon_url`, `allow_unknown_rpc_passthrough`, " + "`encryption_required`) " "VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?)"; + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; const std::string kInsertAppGroup = "INSERT INTO `app_group` (`application_id`, `functional_group_id`)" @@ -804,7 +808,7 @@ const std::string kSelectAppLevels = "SELECT `application_id` FROM `app_level`"; const std::string kSelectDeviceData = "SELECT * FROM `device`"; const std::string kSelectFunctionalGroups = - "SELECT `id`,`name`, `user_consent_prompt` " + "SELECT `id`,`name`, `user_consent_prompt`, `encryption_required` " "FROM `functional_group`"; const std::string kSelectAllRpcs = @@ -822,7 +826,7 @@ const std::string kSelectAppPolicies = "SELECT `id`, `priority_value`, `memory_kb`, " " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type`, `icon_url`, " - " `allow_unknown_rpc_passthrough` " + " `allow_unknown_rpc_passthrough`, `encryption_required` " "FROM " " `application`"; @@ -947,8 +951,8 @@ const std::string kInsertApplicationFull = " `is_predata`, `memory_kb`, `heart_beat_timeout_ms`, " " `certificate`, `hybrid_app_preference_value`, `endpoint`, `enabled`, " " `auth_token`, `cloud_transport_type`, `icon_url`, " - "`allow_unknown_rpc_passthrough`) " - " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + "`allow_unknown_rpc_passthrough`, `encryption_required`) " + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; const std::string kSelectApplicationFull = "SELECT `keep_context`, `steal_focus`, `default_hmi`, `priority_value`, " @@ -956,7 +960,7 @@ const std::string kSelectApplicationFull = " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type`, " "`icon_url`, " - " `allow_unknown_rpc_passthrough` " + " `allow_unknown_rpc_passthrough`, `encryption_required` " "FROM `application` " "WHERE `id` = ?"; diff --git a/src/components/policy/policy_external/src/sql_pt_representation.cc b/src/components/policy/policy_external/src/sql_pt_representation.cc index d5950f9d42..f2a2d34145 100644 --- a/src/components/policy/policy_external/src/sql_pt_representation.cc +++ b/src/components/policy/policy_external/src/sql_pt_representation.cc @@ -648,6 +648,10 @@ bool SQLPTRepresentation::GatherFunctionalGroupings( *rpcs_tbl.user_consent_prompt = func_group.GetString(2); } + if (!func_group.IsNull(3)) { + *rpcs_tbl.encryption_required = func_group.GetBoolean(3); + } + const int group_id = func_group.GetInteger(0); rpcs.Bind(0, group_id); @@ -785,6 +789,10 @@ bool SQLPTRepresentation::GatherApplicationPoliciesSection( const auto& gather_app_id = ((*policies).apps[app_id].is_string()) ? (*policies).apps[app_id].get_string() : app_id; + + if (!query.IsNull(12)) { + *params.encryption_required = query.GetBoolean(12); + } // Data should be gathered from db by "default" key if application has // default policies @@ -903,7 +911,9 @@ bool SQLPTRepresentation::SaveFunctionalGroupings( groups_it->second.user_consent_prompt.is_initialized() ? query.Bind(2, *(groups_it->second.user_consent_prompt)) : query.Bind(2); - + groups_it->second.encryption_required.is_initialized() + ? query.Bind(3, *(groups_it->second.encryption_required)) + : query.Bind(3); if (!query.Exec() || !query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into functional groups"); return false; @@ -1100,6 +1110,10 @@ bool SQLPTRepresentation::SaveSpecificAppPolicy( ? app_query.Bind(12, *app.second.allow_unknown_rpc_passthrough) : app_query.Bind(12); + app.second.encryption_required.is_initialized() + ? app_query.Bind(13, *app.second.encryption_required) + : app_query.Bind(13); + if (!app_query.Exec() || !app_query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into application."); return false; @@ -2355,6 +2369,8 @@ bool SQLPTRepresentation::CopyApplication(const std::string& source, : query.Bind(16, source_app.GetString(15)); source_app.IsNull(16) ? query.Bind(17) : query.Bind(17, source_app.GetBoolean(16)); + source_app.IsNull(17) ? query.Bind(18) + : query.Bind(18, source_app.GetBoolean(17)); if (!query.Exec()) { LOG4CXX_WARN(logger_, "Failed inserting into application."); diff --git a/src/components/policy/policy_regular/include/policy/cache_manager.h b/src/components/policy/policy_regular/include/policy/cache_manager.h index 1c28b596c0..1773347af7 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -395,6 +395,12 @@ class CacheManager : public CacheManagerInterface { */ bool GetFunctionalGroupings(policy_table::FunctionalGroupings& groups); + /** + * @brief Get policy app names from PT + * @return container of strings representing policy application names + */ + const policy_table::Strings GetPolicyAppIDs() const OVERRIDE; + /** * Checks if the application is represented in policy table * @param app_id application id @@ -850,6 +856,16 @@ class CacheManager : public CacheManagerInterface { void OnDeviceSwitching(const std::string& device_id_from, const std::string& device_id_to) OVERRIDE; + EncryptionRequired GetAppEncryptionRequiredFlag( + const std::string& application_policy_name) const OVERRIDE; + + EncryptionRequired GetFunctionalGroupingEncryptionRequiredFlag( + const std::string& functional_group) const OVERRIDE; + + void GetApplicationParams( + const std::string& application_name, + policy_table::ApplicationParams& application_policies) const OVERRIDE; + private: std::string currentDateTime(); struct AppHMITypeToString { diff --git a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h index e8f2644bc5..374db728c7 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h @@ -418,6 +418,12 @@ class CacheManagerInterface { virtual bool GetFunctionalGroupings( policy_table::FunctionalGroupings& groups) = 0; + /** + * @brief Get policy app names from PT + * @return container of strings representing policy application names + */ + virtual const policy_table::Strings GetPolicyAppIDs() const = 0; + /** * Checks if the application is represented in policy table * @param app_id application id @@ -815,6 +821,36 @@ class CacheManagerInterface { */ virtual void OnDeviceSwitching(const std::string& device_id_from, const std::string& device_id_to) = 0; + + /** + * @brief GetAppEncryptionRequiredFlag retrieves encryption required flag for + * given application + * @param application policy application name + * @return optional object containing encryption required flag + */ + virtual rpc::Optional GetAppEncryptionRequiredFlag( + const std::string& application_policy_name) const = 0; + + /** + * @brief GetFunctionalGroupingEncryptionRequiredFlag retrieves encryption + * required flag + * for + * given functional grouping + * @param functional_group policy functional group name + * @return optional object containing encryption required flag + */ + virtual rpc::Optional + GetFunctionalGroupingEncryptionRequiredFlag( + const std::string& functional_group) const = 0; + + /** + * @brief retreives application params + * @param application_name policy applicatoin name + * @param application_params application params + */ + virtual void GetApplicationParams( + const std::string& application_name, + policy_table::ApplicationParams& application_params) const = 0; }; typedef std::shared_ptr CacheManagerInterfaceSPtr; diff --git a/src/components/policy/policy_regular/include/policy/policy_helper.h b/src/components/policy/policy_regular/include/policy/policy_helper.h index 4c697858f5..adedd8786f 100644 --- a/src/components/policy/policy_regular/include/policy/policy_helper.h +++ b/src/components/policy/policy_regular/include/policy/policy_helper.h @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2013, Ford Motor Company All rights reserved. @@ -83,22 +83,11 @@ bool operator!=(const policy_table::ApplicationParams& first, struct CheckAppPolicy { CheckAppPolicy(PolicyManagerImpl* pm, const std::shared_ptr update, - const std::shared_ptr snapshot); + const std::shared_ptr snapshot, + CheckAppPolicyResults& out_results); bool operator()(const AppPoliciesValueType& app_policy); private: - enum PermissionsCheckResult { - RESULT_NO_CHANGES, - RESULT_APP_REVOKED, - RESULT_NICKNAME_MISMATCH, - RESULT_PERMISSIONS_REVOKED, - RESULT_CONSENT_NEEDED, - RESULT_CONSENT_NOT_REQIURED, - RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED, - RESULT_REQUEST_TYPE_CHANGED, - RESULT_REQUEST_SUBTYPE_CHANGED - }; - void SetPendingPermissions(const AppPoliciesValueType& app_policy, PermissionsCheckResult result) const; PermissionsCheckResult CheckPermissionsChanges( @@ -119,6 +108,16 @@ struct CheckAppPolicy { const policy_table::Strings& groups) const; bool IsAppRevoked(const AppPoliciesValueType& app_policy) const; bool NicknamesMatch(const AppPoliciesValueType& app_policy) const; + + /** + * @brief Check of current policy against incoming updated policy is + * performed. + * This function adds result code of this check to container. + * @param app_id Application id + * @param result Result value + */ + void AddResult(const std::string& app_id, PermissionsCheckResult result); + /** * @brief Allows to check if appropriate group requires any consent. * @param group_name the group for which consent will be checked. @@ -129,10 +128,31 @@ struct CheckAppPolicy { bool IsRequestTypeChanged(const AppPoliciesValueType& app_policy) const; bool IsRequestSubTypeChanged(const AppPoliciesValueType& app_policy) const; + bool IsEncryptionRequiredFlagChanged( + const AppPoliciesValueType& app_policy) const; + private: PolicyManagerImpl* pm_; const std::shared_ptr update_; const std::shared_ptr snapshot_; + CheckAppPolicyResults& out_results_; +}; + +/** + * @brief Helper struct for filling actions to be done for processed application + * using CheckAppPolicyResults data as a source + */ +struct FillActionsForAppPolicies { + FillActionsForAppPolicies( + ApplicationsPoliciesActions& actions, + const policy_table::ApplicationPolicies& app_policies) + : actions_(actions), app_policies_(app_policies) {} + + void operator()(const policy::CheckAppPolicyResults::value_type& value); + + private: + ApplicationsPoliciesActions& actions_; + const policy_table::ApplicationPolicies& app_policies_; }; /* @@ -174,6 +194,9 @@ struct ProcessFunctionalGroup { private: GroupConsent GetGroupState(const std::string& group_name); + void FillEncryptionFlagForRpcs( + const policy_table::Rpc& rpcs, + const policy::EncryptionRequired encryption_required); const policy_table::FunctionalGroupings& fg_; const std::vector& group_permissions_; Permissions& data_; diff --git a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h index 903f7820d2..d8ab079cf0 100644 --- a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h @@ -37,6 +37,7 @@ #include #include +#include "application_manager/policies/policy_encryption_flag_getter.h" #include "policy/access_remote.h" #include "policy/access_remote_impl.h" #include "policy/cache_manager_interface.h" @@ -57,6 +58,45 @@ struct CheckAppPolicy; class PolicyManagerImpl : public PolicyManager { public: PolicyManagerImpl(); + /* + * \param policy_app_id policy app id + * \return true if the app need encryption + */ + bool AppNeedEncryption(const std::string& policy_app_id) const OVERRIDE; + + /* + * \param policy_app_id policy app id + * \return Optional app need encryption + */ + const rpc::Optional GetAppEncryptionRequired( + const std::string& policy_app_id) const OVERRIDE; + /* + * \param policy_app_id policy app id + * \return groups that exist for app + */ + const std::vector GetFunctionalGroupsForApp( + const std::string& policy_app_id) const OVERRIDE; + + const std::vector GetApplicationPolicyIDs() const OVERRIDE; + + /* + * \param policy_group group + * \return true if the group need encryption + */ + bool FunctionGroupNeedEncryption( + const std::string& policy_group) const OVERRIDE; + /* + * \param policy_group group + * \return RPCs that exists in group + */ + const std::vector GetRPCsForFunctionGroup( + const std::string& group) const OVERRIDE; + /* + * \param function_id function id + * \return policy function name + */ + const std::string GetPolicyFunctionName( + const uint32_t function_id) const OVERRIDE; /** * @brief set_listener set new policy listener instance @@ -92,6 +132,21 @@ class PolicyManagerImpl : public PolicyManager { bool LoadPT(const std::string& file, const BinaryMessage& pt_content) OVERRIDE; + typedef policy_table::ApplicationPolicies::value_type AppPoliciesValueType; + + /** + * @brief Notifies system by sending OnAppPermissionChanged notification + * @param app_policy Reference to application policy + */ + void NotifySystem(const AppPoliciesValueType& app_policy) const; + + /** + * @brief Sends OnPermissionChange notification to application if its + * currently registered + * @param app_policy Reference to application policy + */ + void SendPermissionsToApp(const AppPoliciesValueType& app_policy); + /** * @brief Resets Policy Table * @param file_name Path to preloaded PT file @@ -836,10 +891,19 @@ class PolicyManagerImpl : public PolicyManager { * @param snapshot Shared pointer to current copy of policy table * @return Collection per-application results */ - void CheckPermissionsChanges( + CheckAppPolicyResults CheckPermissionsChanges( const std::shared_ptr update, const std::shared_ptr snapshot); + void ProcessAppPolicyCheckResults( + const CheckAppPolicyResults& results, + const rpc::policy_table_interface_base::ApplicationPolicies& + app_policies); + + void ProcessActionsForAppPolicies( + const ApplicationsPoliciesActions& actions, + const policy_table::ApplicationPolicies& app_policies); + /** * @brief Compares current policies to the updated one. * Trigger actions in case if certain fields after update were changed. diff --git a/src/components/policy/policy_regular/include/policy/policy_table/types.h b/src/components/policy/policy_regular/include/policy/policy_table/types.h index c2a8f901ad..cb7b689317 100644 --- a/src/components/policy/policy_regular/include/policy/policy_table/types.h +++ b/src/components/policy/policy_regular/include/policy/policy_table/types.h @@ -203,6 +203,7 @@ struct ApplicationParams : PolicyBase { // App Service Params Optional app_service_parameters; Optional allow_unknown_rpc_passthrough; + Optional encryption_required; public: ApplicationParams(); @@ -268,6 +269,7 @@ struct Rpcs : CompositeType { public: Optional > user_consent_prompt; Nullable rpcs; + Optional encryption_required; public: Rpcs(); diff --git a/src/components/policy/policy_regular/include/policy/policy_types.h b/src/components/policy/policy_regular/include/policy/policy_types.h index 0be5919126..2794615cb4 100644 --- a/src/components/policy/policy_regular/include/policy/policy_types.h +++ b/src/components/policy/policy_regular/include/policy/policy_types.h @@ -41,6 +41,7 @@ #include #include +#include "policy/policy_table/types.h" #include "transport_manager/common.h" #include "utils/helpers.h" @@ -77,6 +78,8 @@ enum PolicyTableStatus { StatusUnknown }; +typedef rpc::Optional EncryptionRequired; + // Code generator uses String class name, so this typedef was renamed to PTSring typedef std::string PTString; typedef std::vector BinaryMessage; @@ -102,6 +105,7 @@ struct ParameterPermissions struct RpcPermissions { HMIPermissions hmi_permissions; ParameterPermissions parameter_permissions; + EncryptionRequired require_encryption; }; typedef std::map Permissions; @@ -427,6 +431,28 @@ struct ExternalConsentStatusItemSorter { } }; +/** + * @brief The ApplicationPolicyActions struct contains actions which should be + * done for some application + */ +struct ApplicationPolicyActions { + ApplicationPolicyActions() + : is_notify_system(false) + , is_send_permissions_to_app(false) + , is_consent_needed(false) {} + + bool is_notify_system; + bool is_send_permissions_to_app; + bool is_consent_needed; +}; + +/** + * @brief ApplicationsPoliciesActions map of actions to be done for every + * application + */ +typedef std::map + ApplicationsPoliciesActions; + /** * @brief Customer connectivity settings status */ @@ -476,7 +502,8 @@ enum PermissionsCheckResult { RESULT_CONSENT_NOT_REQIURED, RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED, RESULT_REQUEST_TYPE_CHANGED, - RESULT_REQUEST_SUBTYPE_CHANGED + RESULT_REQUEST_SUBTYPE_CHANGED, + RESULT_ENCRYPTION_REQUIRED_FLAG_CHANGED }; /** diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index d121886765..b13770282f 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -124,6 +124,20 @@ const policy_table::Strings& CacheManager::GetGroups(const PTString& app_id) { return pt_->policy_table.app_policies_section.apps[app_id].groups; } +const policy_table::Strings CacheManager::GetPolicyAppIDs() const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + + const auto apps = pt_->policy_table.app_policies_section.apps; + + policy_table::Strings policy_app_ids; + for (const auto& app : apps) { + policy_app_ids.push_back(app.first); + } + + return policy_app_ids; +} + bool CacheManager::CanAppKeepContext(const std::string& app_id) const { CACHE_MANAGER_CHECK(false); bool result = true; @@ -2052,4 +2066,46 @@ void CacheManager::BackgroundBackuper::DoBackup() { backup_notifier_.NotifyOne(); } +EncryptionRequired CacheManager::GetAppEncryptionRequiredFlag( + const std::string& application) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + + return pt_->policy_table.app_policies_section.apps[application] + .encryption_required; +} + +EncryptionRequired CacheManager::GetFunctionalGroupingEncryptionRequiredFlag( + const std::string& functional_group) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + + const auto& functional_groupings = pt_->policy_table.functional_groupings; + + const auto& grouping_itr = functional_groupings.find(functional_group); + if (grouping_itr == functional_groupings.end()) { + LOG4CXX_WARN(logger_, "Group " << functional_group << " not found"); + return EncryptionRequired(rpc::Boolean(false)); + } + + return (*grouping_itr).second.encryption_required; +} + +void CacheManager::GetApplicationParams( + const std::string& application_name, + policy_table::ApplicationParams& application_params) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + + const auto apps = pt_->policy_table.app_policies_section.apps; + const auto it = apps.find(application_name); + if (apps.end() == it) { + LOG4CXX_WARN(logger_, + "Application " << application_name << " was not found"); + return; + } + + application_params = (*it).second; +} + } // namespace policy diff --git a/src/components/policy/policy_regular/src/policy_helper.cc b/src/components/policy/policy_regular/src/policy_helper.cc index 26e4984e6d..7ebb66bf2b 100644 --- a/src/components/policy/policy_regular/src/policy_helper.cc +++ b/src/components/policy/policy_regular/src/policy_helper.cc @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2013, Ford Motor Company All rights reserved. @@ -122,8 +122,12 @@ bool operator!=(const policy_table::ApplicationParams& first, CheckAppPolicy::CheckAppPolicy( PolicyManagerImpl* pm, const std::shared_ptr update, - const std::shared_ptr snapshot) - : pm_(pm), update_(update), snapshot_(snapshot) {} + const std::shared_ptr snapshot, + CheckAppPolicyResults& out_results) + : pm_(pm) + , update_(update) + , snapshot_(snapshot) + , out_results_(out_results) {} bool policy::CheckAppPolicy::HasRevokedGroups( const policy::AppPoliciesValueType& app_policy, @@ -332,6 +336,13 @@ bool CheckAppPolicy::NicknamesMatch( return true; } +void CheckAppPolicy::AddResult(const std::string& app_id, + PermissionsCheckResult result) { + LOG4CXX_AUTO_TRACE(logger_); + const auto item = std::make_pair(app_id, result); + out_results_.insert(item); +} + bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) { const std::string app_id = app_policy.first; @@ -343,13 +354,13 @@ bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) { if (!IsPredefinedApp(app_policy) && IsAppRevoked(app_policy)) { SetPendingPermissions(app_policy, RESULT_APP_REVOKED); - NotifySystem(app_policy); + AddResult(app_id, RESULT_APP_REVOKED); return true; } if (!IsPredefinedApp(app_policy) && !NicknamesMatch(app_policy)) { SetPendingPermissions(app_policy, RESULT_NICKNAME_MISMATCH); - NotifySystem(app_policy); + AddResult(app_id, RESULT_NICKNAME_MISMATCH); return true; } @@ -360,19 +371,18 @@ bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) { if (is_request_type_changed) { SetPendingPermissions(app_policy, RESULT_REQUEST_TYPE_CHANGED); + AddResult(app_id, RESULT_REQUEST_TYPE_CHANGED); } if (is_request_subtype_changed) { SetPendingPermissions(app_policy, RESULT_REQUEST_SUBTYPE_CHANGED); - } - - if (is_request_type_changed || is_request_subtype_changed) { - NotifySystem(app_policy); + AddResult(app_id, RESULT_REQUEST_SUBTYPE_CHANGED); } } if (RESULT_NO_CHANGES == result) { LOG4CXX_INFO( logger_, "Permissions for application:" << app_id << " wasn't changed."); + AddResult(app_id, RESULT_NO_CHANGES); return true; } @@ -381,27 +391,31 @@ bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) { "Permissions for application:" << app_id << " have been changed."); if (IsPredefinedApp(app_policy)) { + LOG4CXX_DEBUG(logger_, "app id: " << app_id << " is predefined app"); for (const policy_table::ApplicationPolicies::value_type& app : snapshot_->policy_table.app_policies_section.apps) { if (app_policy.first == app.second.get_string()) { if (RESULT_CONSENT_NOT_REQIURED != result) { SetPendingPermissions(app, result); - NotifySystem(app); + AddResult(app_id, RESULT_CONSENT_NEEDED); } - SendPermissionsToApp(app.first, app_policy.second.groups); + LOG4CXX_DEBUG(logger_, "Sending permissions for app: " << app_id); } } return true; } if (!IsPredefinedApp(app_policy) && RESULT_CONSENT_NOT_REQIURED != result) { + LOG4CXX_DEBUG(logger_, "Sending permissions for app: " << app_id); SetPendingPermissions(app_policy, result); - NotifySystem(app_policy); + AddResult(app_id, RESULT_CONSENT_NEEDED); } // Don't sent notification for predefined apps (e.g. default, device etc.) if (!IsPredefinedApp(app_policy)) { - SendPermissionsToApp(app_policy.first, app_policy.second.groups); + LOG4CXX_DEBUG(logger_, "Sending permissions for app: " << app_id); + SetPendingPermissions(app_policy, result); + AddResult(app_id, result); } return true; } @@ -460,8 +474,7 @@ void policy::CheckAppPolicy::SetPendingPermissions( pm_->app_permissions_diff_lock_.Release(); } -policy::CheckAppPolicy::PermissionsCheckResult -policy::CheckAppPolicy::CheckPermissionsChanges( +policy::PermissionsCheckResult policy::CheckAppPolicy::CheckPermissionsChanges( const policy::AppPoliciesValueType& app_policy) const { bool has_revoked_groups = HasRevokedGroups(app_policy); @@ -469,6 +482,9 @@ policy::CheckAppPolicy::CheckPermissionsChanges( bool has_new_groups = HasNewGroups(app_policy); + const bool encryption_required_flag_changed = + IsEncryptionRequiredFlagChanged(app_policy); + if (has_revoked_groups && has_consent_needed_groups) { return RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED; } else if (has_revoked_groups) { @@ -477,6 +493,8 @@ policy::CheckAppPolicy::CheckPermissionsChanges( return RESULT_CONSENT_NEEDED; } else if (has_new_groups) { return RESULT_CONSENT_NOT_REQIURED; + } else if (encryption_required_flag_changed) { + return RESULT_ENCRYPTION_REQUIRED_FLAG_CHANGED; } return RESULT_NO_CHANGES; @@ -545,6 +563,130 @@ bool CheckAppPolicy::IsRequestSubTypeChanged( return diff.size(); } +bool CheckAppPolicy::IsEncryptionRequiredFlagChanged( + const AppPoliciesValueType& app_policy) const { + auto get_app_encryption_needed = + [](const std::string& policy_app_id, + policy_table::ApplicationPolicies& policies) + -> rpc::Optional { + auto it = policies.find(policy_app_id); + if (policies.end() == it) { + LOG4CXX_WARN(logger_, "App is not present in policies" << policy_app_id); + return rpc::Optional(false); + } + return it->second.encryption_required; + }; + + auto get_app_groups = + [](const std::string& policy_app_id, + policy_table::ApplicationPolicies& policies) -> policy_table::Strings { + policy_table::Strings result; + auto it = policies.find(policy_app_id); + if (policies.end() == it) { + LOG4CXX_WARN(logger_, "App is not present in policies" << policy_app_id); + return result; + } + auto& groups = it->second.groups; + std::copy(groups.begin(), groups.end(), std::back_inserter(result)); + return result; + }; + + auto get_app_rpcs = [](const std::string group_name, + const FunctionalGroupings& groups) + -> rpc::Optional { + auto it = groups.find(group_name); + if (it == groups.end()) { + return rpc::Optional(); + } + return rpc::Optional(it->second); + }; + + const auto snapshot_groups = get_app_groups( + app_policy.first, snapshot_->policy_table.app_policies_section.apps); + const auto update_groups = get_app_groups( + app_policy.first, update_->policy_table.app_policies_section.apps); + + auto get_resulting_encryption_required_flag_for_app_groups = + [this, &get_app_rpcs]( + const rpc::policy_table_interface_base::Strings& app_groups, + const std::shared_ptr pt) { + for (const auto& group : app_groups) { + const auto rpcs = + get_app_rpcs(group, pt->policy_table.functional_groupings); + if (*rpcs->encryption_required) { + return true; + } + } + + return false; + }; + + auto group_res_en_flag_changed = + [this, &get_resulting_encryption_required_flag_for_app_groups]( + const rpc::policy_table_interface_base::Strings& snapshot_groups, + const rpc::policy_table_interface_base::Strings& update_groups) { + return get_resulting_encryption_required_flag_for_app_groups( + snapshot_groups, snapshot_) != + get_resulting_encryption_required_flag_for_app_groups( + update_groups, update_); + }; + + const auto snapshot_app_encryption_needed = get_app_encryption_needed( + app_policy.first, snapshot_->policy_table.app_policies_section.apps); + const auto update_app_encryption_needed = get_app_encryption_needed( + app_policy.first, update_->policy_table.app_policies_section.apps); + + const bool app_encryption_needed_changed = + (snapshot_app_encryption_needed.is_initialized() != + update_app_encryption_needed.is_initialized()) || + (*snapshot_app_encryption_needed != *update_app_encryption_needed); + + if ((!update_app_encryption_needed.is_initialized() || + *update_app_encryption_needed) && + group_res_en_flag_changed(snapshot_groups, update_groups)) { + return true; + } + + return app_encryption_needed_changed; +} + +void FillActionsForAppPolicies::operator()( + const policy::CheckAppPolicyResults::value_type& value) { + const std::string app_id = value.first; + const auto app_policy = app_policies_.find(app_id); + + if (app_policies_.end() == app_policy) { + return; + } + + if (IsPredefinedApp(*app_policy)) { + return; + } + + switch (value.second) { + case RESULT_APP_REVOKED: + case RESULT_NICKNAME_MISMATCH: + actions_[app_id].is_notify_system = true; + return; + case RESULT_CONSENT_NEEDED: + case RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED: + actions_[app_id].is_consent_needed = true; + break; + case RESULT_CONSENT_NOT_REQIURED: + case RESULT_PERMISSIONS_REVOKED: + case RESULT_REQUEST_TYPE_CHANGED: + case RESULT_REQUEST_SUBTYPE_CHANGED: + case RESULT_ENCRYPTION_REQUIRED_FLAG_CHANGED: + break; + case RESULT_NO_CHANGES: + default: + return; + } + + actions_[app_id].is_notify_system = true; + actions_[app_id].is_send_permissions_to_app = true; +} + FillNotificationData::FillNotificationData(Permissions& data, GroupConsent group_state, GroupConsent undefined_group_consent) @@ -728,10 +870,31 @@ bool ProcessFunctionalGroup::operator()(const StringsValueType& group_name) { FillNotificationData filler( data_, GetGroupState(group_name_str), undefined_group_consent_); std::for_each(rpcs.begin(), rpcs.end(), filler); + FillEncryptionFlagForRpcs(rpcs, (*it).second.encryption_required); } return true; } +void ProcessFunctionalGroup::FillEncryptionFlagForRpcs( + const policy_table::Rpc& rpcs, + const EncryptionRequired encryption_required) { + auto update_encryption_required = [](EncryptionRequired& current, + const EncryptionRequired& incoming) { + if (!incoming.is_initialized()) { + return; + } + if (current.is_initialized() && *current) { + return; + } + current = incoming; + }; + + for (const auto& rpc : rpcs) { + auto& item = data_[rpc.first]; + update_encryption_required(item.require_encryption, encryption_required); + } +} + GroupConsent ProcessFunctionalGroup::GetGroupState( const std::string& group_name) { std::vector::const_iterator it = diff --git a/src/components/policy/policy_regular/src/policy_manager_impl.cc b/src/components/policy/policy_regular/src/policy_manager_impl.cc index 5a7c822a9b..e3d2c1780c 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -348,7 +348,8 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, // groups, which had been present before are absent in PTU and will be // removed after update. So in case of revoked groups system has to know // names and ids of revoked groups before they will be removed. - CheckPermissionsChanges(pt_update, policy_table_snapshot); + const auto results = + CheckPermissionsChanges(pt_update, policy_table_snapshot); // Replace current data with updated if (!cache_->ApplyUpdate(*pt_update)) { @@ -360,6 +361,9 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, } CheckPermissionsChangesAfterUpdate(*pt_update, *policy_table_snapshot); + ProcessAppPolicyCheckResults( + results, pt_update->policy_table.app_policies_section.apps); + listener_->OnCertificateUpdated( *(pt_update->policy_table.module_config.certificate)); @@ -390,7 +394,82 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, return true; } -void PolicyManagerImpl::CheckPermissionsChanges( +void PolicyManagerImpl::ProcessAppPolicyCheckResults( + const CheckAppPolicyResults& results, + const rpc::policy_table_interface_base::ApplicationPolicies& app_policies) { + LOG4CXX_AUTO_TRACE(logger_); + + ApplicationsPoliciesActions actions_for_apps_policies; + FillActionsForAppPolicies filler(actions_for_apps_policies, app_policies); + + std::for_each(results.begin(), results.end(), filler); + + ProcessActionsForAppPolicies(actions_for_apps_policies, app_policies); +} + +void PolicyManagerImpl::ProcessActionsForAppPolicies( + const ApplicationsPoliciesActions& actions, + const policy_table::ApplicationPolicies& app_policies) { + ApplicationsPoliciesActions::const_iterator it_actions = actions.begin(); + for (; it_actions != actions.end(); ++it_actions) { + auto app_policy = app_policies.find(it_actions->first); + if (app_policies.end() == app_policy) { + continue; + } + + if (it_actions->second.is_consent_needed) { + // Post-check after ExternalConsent consent changes + const std::string& policy_app_id = app_policy->first; + if (!IsConsentNeeded(last_device_id_, policy_app_id)) { + sync_primitives::AutoLock lock(app_permissions_diff_lock_); + + PendingPermissions::iterator app_id_diff = + app_permissions_diff_.find(policy_app_id); + + if (app_permissions_diff_.end() != app_id_diff) { + app_id_diff->second.appPermissionsConsentNeeded = false; + } + } + } + if (it_actions->second.is_notify_system) { + NotifySystem(*app_policy); + } + if (it_actions->second.is_send_permissions_to_app) { + SendPermissionsToApp(*app_policy); + } + } +} + +void PolicyManagerImpl::NotifySystem( + const PolicyManagerImpl::AppPoliciesValueType& app_policy) const { + listener()->OnPendingPermissionChange(last_device_id_, app_policy.first); +} + +void PolicyManagerImpl::SendPermissionsToApp( + const PolicyManagerImpl::AppPoliciesValueType& app_policy) { + const std::string app_id = app_policy.first; + + std::vector group_permissons; + GetPermissionsForApp(last_device_id_, app_id, group_permissons); + + Permissions notification_data; + + // Need to get rid of this call + auto policy_table_snapshot = cache_->GenerateSnapshot(); + + PrepareNotificationData( + policy_table_snapshot->policy_table.functional_groupings, + app_policy.second.groups, + group_permissons, + notification_data); + + std::string default_hmi; + default_hmi = "NONE"; + listener()->OnPermissionsUpdated( + last_device_id_, app_id, notification_data, default_hmi); +} + +CheckAppPolicyResults PolicyManagerImpl::CheckPermissionsChanges( const std::shared_ptr pt_update, const std::shared_ptr snapshot) { LOG4CXX_AUTO_TRACE(logger_); @@ -399,9 +478,13 @@ void PolicyManagerImpl::CheckPermissionsChanges( // to actual values of default section UnwrapAppPolicies(pt_update->policy_table.app_policies_section.apps); + CheckAppPolicyResults out_results; + std::for_each(pt_update->policy_table.app_policies_section.apps.begin(), pt_update->policy_table.app_policies_section.apps.end(), - CheckAppPolicy(this, pt_update, snapshot)); + CheckAppPolicy(this, pt_update, snapshot, out_results)); + + return out_results; } void PolicyManagerImpl::CheckPermissionsChangesAfterUpdate( @@ -420,7 +503,7 @@ void PolicyManagerImpl::PrepareNotificationData( const policy_table::Strings& group_names, const std::vector& group_permission, Permissions& notification_data) { - LOG4CXX_INFO(logger_, "Preparing data for notification."); + LOG4CXX_AUTO_TRACE(logger_); ProcessFunctionalGroup processor(groups, group_permission, notification_data); std::for_each(group_names.begin(), group_names.end(), processor); } @@ -1555,4 +1638,94 @@ void PolicyManagerImpl::set_access_remote( access_remote_ = access_remote; } +bool PolicyManagerImpl::AppNeedEncryption( + const std::string& policy_app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + const auto encryption_required = + cache_->GetAppEncryptionRequiredFlag(policy_app_id); + + return encryption_required.is_initialized() ? *encryption_required : true; +} + +const rpc::Optional PolicyManagerImpl::GetAppEncryptionRequired( + const std::string& policy_app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + return cache_->GetAppEncryptionRequiredFlag(policy_app_id); +} + +const std::vector PolicyManagerImpl::GetFunctionalGroupsForApp( + const std::string& policy_app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + using namespace rpc::policy_table_interface_base; + DCHECK(kDeviceId != policy_app_id); + + std::vector function_groups; + + ApplicationParams app_policies; + cache_->GetApplicationParams(policy_app_id, app_policies); + + const auto& policy_function_group = app_policies.groups; + + for (const auto& group : policy_function_group) { + function_groups.push_back(group); + } + + return function_groups; +} + +const std::vector PolicyManagerImpl::GetApplicationPolicyIDs() + const { + LOG4CXX_AUTO_TRACE(logger_); + std::vector policy_app_ids; + + const auto apps = cache_->GetPolicyAppIDs(); + + for (const auto& app : apps) { + policy_app_ids.push_back(app); + } + + return policy_app_ids; +} + +bool PolicyManagerImpl::FunctionGroupNeedEncryption( + const std::string& policy_group) const { + LOG4CXX_AUTO_TRACE(logger_); + FunctionalGroupings functional_groupings; + cache_->GetFunctionalGroupings(functional_groupings); + + const auto& grouping_itr = functional_groupings.find(policy_group); + if (grouping_itr == functional_groupings.end()) { + LOG4CXX_WARN(logger_, "Group " << policy_group << " not found"); + return false; + } + + const auto& grouping = (*grouping_itr).second; + + return grouping.encryption_required.is_initialized() + ? *grouping.encryption_required + : false; +} + +const std::string PolicyManagerImpl::GetPolicyFunctionName( + const uint32_t function_id) const { + return policy_table::EnumToJsonString( + static_cast(function_id)); +} + +const std::vector PolicyManagerImpl::GetRPCsForFunctionGroup( + const std::string& group) const { + std::vector rpcs_for_group; + + FunctionalGroupings functional_groupings; + cache_->GetFunctionalGroupings(functional_groupings); + + const auto& rpcs = functional_groupings[group].rpcs; + + for (const auto& rpc : rpcs) { + rpcs_for_group.push_back(rpc.first); + } + + return rpcs_for_group; +} + } // namespace policy diff --git a/src/components/policy/policy_regular/src/policy_table/types.cc b/src/components/policy/policy_regular/src/policy_table/types.cc index 7fdfde996c..704cbacf4c 100644 --- a/src/components/policy/policy_regular/src/policy_table/types.cc +++ b/src/components/policy/policy_regular/src/policy_table/types.cc @@ -31,7 +31,6 @@ PolicyBase::~PolicyBase() {} PolicyBase::PolicyBase(const Json::Value* value__) : CompositeType(InitHelper(value__, &Json::Value::isObject)) , priority(impl::ValueMember(value__, "priority")) {} - Json::Value PolicyBase::ToJsonValue() const { Json::Value result__(Json::objectValue); impl::WriteJsonField("priority", priority, &result__); @@ -280,7 +279,8 @@ ApplicationParams::ApplicationParams(const Json::Value* value__) , icon_url(impl::ValueMember(value__, "icon_url")) , app_service_parameters(impl::ValueMember(value__, "app_services")) , allow_unknown_rpc_passthrough( - impl::ValueMember(value__, "allow_unknown_rpc_passthrough")) {} + impl::ValueMember(value__, "allow_unknown_rpc_passthrough")) + , encryption_required(impl::ValueMember(value__, "encryption_required")) {} Json::Value ApplicationParams::ToJsonValue() const { Json::Value result__(PolicyBase::ToJsonValue()); @@ -305,6 +305,8 @@ Json::Value ApplicationParams::ToJsonValue() const { impl::WriteJsonField("allow_unknown_rpc_passthrough", allow_unknown_rpc_passthrough, &result__); + impl::WriteJsonField("encryption_required", encryption_required, &result__); + return result__; } @@ -360,6 +362,9 @@ bool ApplicationParams::is_valid() const { if (!allow_unknown_rpc_passthrough.is_valid()) { return false; } + if (!encryption_required.is_valid()) { + return false; + } return Validate(); } @@ -422,6 +427,9 @@ bool ApplicationParams::struct_empty() const { if (allow_unknown_rpc_passthrough.is_initialized()) { return false; } + if (encryption_required.is_initialized()) { + return false; + } return true; } @@ -487,6 +495,10 @@ void ApplicationParams::ReportErrors(rpc::ValidationReport* report__) const { allow_unknown_rpc_passthrough.ReportErrors( &report__->ReportSubobject("allow_unknown_rpc_passthrough")); } + if (!encryption_required.is_valid()) { + encryption_required.ReportErrors( + &report__->ReportSubobject("encryption_required")); + } } void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { @@ -535,6 +547,7 @@ bool RpcParameters::is_valid() const { if (!parameters.is_valid()) { return false; } + return Validate(); } @@ -581,12 +594,14 @@ Rpcs::~Rpcs() {} Rpcs::Rpcs(const Json::Value* value__) : CompositeType(InitHelper(value__, &Json::Value::isObject)) , user_consent_prompt(impl::ValueMember(value__, "user_consent_prompt")) - , rpcs(impl::ValueMember(value__, "rpcs")) {} + , rpcs(impl::ValueMember(value__, "rpcs")) + , encryption_required(impl::ValueMember(value__, "encryption_required")) {} Json::Value Rpcs::ToJsonValue() const { Json::Value result__(Json::objectValue); impl::WriteJsonField("user_consent_prompt", user_consent_prompt, &result__); impl::WriteJsonField("rpcs", rpcs, &result__); + impl::WriteJsonField("encryption_required", encryption_required, &result__); return result__; } @@ -597,6 +612,9 @@ bool Rpcs::is_valid() const { if (!rpcs.is_valid()) { return false; } + if (!encryption_required.is_valid()) { + return false; + } return Validate(); } @@ -611,7 +629,9 @@ bool Rpcs::struct_empty() const { if (rpcs.is_initialized()) { return false; } - + if (encryption_required.is_initialized()) { + return false; + } return true; } @@ -626,6 +646,10 @@ void Rpcs::ReportErrors(rpc::ValidationReport* report__) const { if (!rpcs.is_valid()) { rpcs.ReportErrors(&report__->ReportSubobject("rpcs")); } + if (!encryption_required.is_valid()) { + encryption_required.ReportErrors( + &report__->ReportSubobject("encryption_required")); + } } void Rpcs::SetPolicyTableType(PolicyTableType pt_type) { diff --git a/src/components/policy/policy_regular/src/sql_pt_queries.cc b/src/components/policy/policy_regular/src/sql_pt_queries.cc index b3816d37f8..760a647853 100644 --- a/src/components/policy/policy_regular/src/sql_pt_queries.cc +++ b/src/components/policy/policy_regular/src/sql_pt_queries.cc @@ -77,7 +77,8 @@ const std::string kCreateSchema = "CREATE TABLE IF NOT EXISTS `functional_group`( " " `id` INTEGER PRIMARY KEY NOT NULL, " " `user_consent_prompt` TEXT, " - " `name` VARCHAR(100) NOT NULL " + " `name` VARCHAR(100) NOT NULL, " + " `encryption_required` BOOLEAN " "); " "CREATE TABLE IF NOT EXISTS `priority`( " " `value` VARCHAR(45) PRIMARY KEY NOT NULL " @@ -146,6 +147,7 @@ const std::string kCreateSchema = " `icon_url` VARCHAR(65535), " " `allow_unknown_rpc_passthrough` BOOLEAN, " " `remote_control_denied` BOOLEAN NOT NULL DEFAULT 0, " + " `encryption_required` BOOLEAN, " " CONSTRAINT `fk_application_hmi_level1` " " FOREIGN KEY(`default_hmi`) " " REFERENCES `hmi_level`(`value`), " @@ -612,8 +614,9 @@ const std::string kSelectLockScreenIcon = "SELECT `url` FROM `endpoint` WHERE `service` = ? AND `application_id` = ?"; const std::string kInsertFunctionalGroup = - "INSERT INTO `functional_group` (`id`, `name`, `user_consent_prompt`) " - " VALUES (?, ?, ?)"; + "INSERT INTO `functional_group` (`id`, `name`, `user_consent_prompt`, " + "`encryption_required`) " + " VALUES (?, ?, ?, ?)"; const std::string kInsertRpc = "INSERT INTO `rpc` (`name`, `hmi_level_value`, `functional_group_id`) " @@ -628,9 +631,10 @@ const std::string kInsertApplication = "INSERT OR IGNORE INTO `application` (`id`, `priority_value`, " "`is_revoked`, `memory_kb`, `heart_beat_timeout_ms`, `certificate`, " "`hybrid_app_preference_value`, `endpoint`, `enabled`, `auth_token`, " - "`cloud_transport_type`, `icon_url`, `allow_unknown_rpc_passthrough`) " + "`cloud_transport_type`, `icon_url`, `allow_unknown_rpc_passthrough` " + ",`encryption_required`) " "VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?)"; + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; const std::string kInsertAppGroup = "INSERT INTO `app_group` (`application_id`, `functional_group_id`)" @@ -744,7 +748,7 @@ const std::string kSelectAppLevels = const std::string kSelectDeviceData = "SELECT * FROM `device`"; const std::string kSelectFunctionalGroups = - "SELECT `id`,`name`, `user_consent_prompt` " + "SELECT `id`,`name`, `user_consent_prompt`, `encryption_required` " "FROM `functional_group`"; const std::string kSelectAllRpcs = @@ -758,7 +762,7 @@ const std::string kSelectAppPolicies = "SELECT `id`, `priority_value`, `memory_kb`, " " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type`, `icon_url`, " - " `allow_unknown_rpc_passthrough` " + " `allow_unknown_rpc_passthrough`, `encryption_required`" "FROM " " `application`"; @@ -883,16 +887,17 @@ const std::string kInsertApplicationFull = " `is_predata`, `memory_kb`, `heart_beat_timeout_ms`, " " `certificate`, `hybrid_app_preference_value`, `endpoint`, `enabled`, " " `auth_token`, `cloud_transport_type`, `icon_url`, " - "`allow_unknown_rpc_passthrough`) " - " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + "`allow_unknown_rpc_passthrough`, `encryption_required`)" + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; const std::string kSelectApplicationFull = - "SELECT `keep_context`, `steal_focus`, `default_hmi`, `priority_value`, " + "SELECT `keep_context`, `steal_focus`, `default_hmi`, " + "`priority_value`, " " `is_revoked`, `is_default`, `is_predata`, `memory_kb`," " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type`, " "`icon_url`, " - " `allow_unknown_rpc_passthrough` " + " `allow_unknown_rpc_passthrough`, `encryption_required`" "FROM `application` " "WHERE `id` = " "?"; diff --git a/src/components/policy/policy_regular/src/sql_pt_representation.cc b/src/components/policy/policy_regular/src/sql_pt_representation.cc index 8ac04ba5f3..50d5e282e1 100644 --- a/src/components/policy/policy_regular/src/sql_pt_representation.cc +++ b/src/components/policy/policy_regular/src/sql_pt_representation.cc @@ -616,6 +616,10 @@ bool SQLPTRepresentation::GatherFunctionalGroupings( *rpcs_structure.user_consent_prompt = functional_group.GetString(2); } + if (!functional_group.IsNull(3)) { + *rpcs_structure.encryption_required = functional_group.GetBoolean(3); + } + const int group_id = functional_group.GetInteger(0); // Collecting RPCs with their HMI levels and parameters (if any) @@ -718,6 +722,7 @@ bool SQLPTRepresentation::GatherApplicationPoliciesSection( params.priority = priority; *params.memory_kb = query.GetInteger(2); + *params.heart_beat_timeout_ms = query.GetUInteger(3); if (!query.IsNull(4)) { *params.certificate = query.GetString(4); @@ -738,6 +743,10 @@ bool SQLPTRepresentation::GatherApplicationPoliciesSection( *params.icon_url = query.GetString(10); *params.allow_unknown_rpc_passthrough = query.GetBoolean(11); + if (!query.IsNull(12)) { + *params.encryption_required = query.GetBoolean(12); + } + const auto& gather_app_id = ((*policies).apps[app_id].is_string()) ? (*policies).apps[app_id].get_string() : app_id; @@ -853,7 +862,9 @@ bool SQLPTRepresentation::SaveFunctionalGroupings( it->second.user_consent_prompt.is_initialized() ? query.Bind(2, *(it->second.user_consent_prompt)) : query.Bind(2); - + it->second.encryption_required.is_initialized() + ? query.Bind(3, *(it->second.encryption_required)) + : query.Bind(3); if (!query.Exec() || !query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into functional groups"); return false; @@ -1042,6 +1053,10 @@ bool SQLPTRepresentation::SaveSpecificAppPolicy( ? app_query.Bind(12, *app.second.allow_unknown_rpc_passthrough) : app_query.Bind(12); + app.second.encryption_required.is_initialized() + ? app_query.Bind(13, *app.second.encryption_required) + : app_query.Bind(13); + if (!app_query.Exec() || !app_query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into application."); return false; @@ -1103,7 +1118,6 @@ bool policy::SQLPTRepresentation::SaveDevicePolicy( app_query.Bind(3, 0); app_query.Bind(4, 0); app_query.Bind(5); - if (!app_query.Exec() || !app_query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into application."); return false; @@ -2326,6 +2340,8 @@ bool SQLPTRepresentation::CopyApplication(const std::string& source, : query.Bind(16, source_app.GetString(15)); source_app.IsNull(16) ? query.Bind(17) : query.Bind(17, source_app.GetBoolean(16)); + source_app.IsNull(17) ? query.Bind(18) + : query.Bind(18, source_app.GetBoolean(17)); if (!query.Exec()) { LOG4CXX_WARN(logger_, "Failed inserting into application."); 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/multiframe_builder.cc b/src/components/protocol_handler/src/multiframe_builder.cc index d7cfc6f90e..fbfc061490 100644 --- a/src/components/protocol_handler/src/multiframe_builder.cc +++ b/src/components/protocol_handler/src/multiframe_builder.cc @@ -261,6 +261,11 @@ RESULT_CODE MultiFrameBuilder::HandleConsecutiveFrame( } } + const bool packet_protection_flag = packet->protection_flag(); + if (!assembling_frame->protection_flag() && packet_protection_flag) { + assembling_frame->set_protection_flag(packet_protection_flag); + } + assembling_frame->set_frame_data(new_frame_data); LOG4CXX_DEBUG(logger_, diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index 222ca635d0..d95c57f0cc 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/protocol_handler/test/incoming_data_handler_test.cc b/src/components/protocol_handler/test/incoming_data_handler_test.cc index fff102dde9..a187fe6cb5 100644 --- a/src/components/protocol_handler/test/incoming_data_handler_test.cc +++ b/src/components/protocol_handler/test/incoming_data_handler_test.cc @@ -68,8 +68,10 @@ class IncomingDataHandlerTest : public ::testing::Test { void ProcessData(transport_manager::ConnectionUID uid, const uint8_t* const data, const uint32_t data_size) { - actual_frames = data_handler.ProcessData( - RawMessage(uid, 0, data, data_size), &result_code, &malformed_occurs); + actual_frames = + data_handler.ProcessData(RawMessage(uid, 0, data, data_size, false), + &result_code, + &malformed_occurs); } void AppendPacketToTMData(const ProtocolPacket& packet) { @@ -117,15 +119,17 @@ TEST_F(IncomingDataHandlerTest, NullData) { TEST_F(IncomingDataHandlerTest, DataForUnknownConnection) { size_t malformed_count = 0; - actual_frames = data_handler.ProcessData( - RawMessage(uid_unknown, 0, NULL, 0), &result_code, &malformed_count); + actual_frames = + data_handler.ProcessData(RawMessage(uid_unknown, 0, NULL, 0, false), + &result_code, + &malformed_count); EXPECT_EQ(RESULT_FAIL, result_code); EXPECT_EQ(malformed_count, 0u); EXPECT_TRUE(actual_frames.empty()); AppendPacketToTMData(ProtocolPacket()); actual_frames = data_handler.ProcessData( - RawMessage(uid_unknown, 0, tm_data.data(), tm_data.size()), + RawMessage(uid_unknown, 0, tm_data.data(), tm_data.size(), false), &result_code, &malformed_count); EXPECT_EQ(RESULT_FAIL, result_code); diff --git a/src/components/protocol_handler/test/protocol_handler_tm_test.cc b/src/components/protocol_handler/test/protocol_handler_tm_test.cc index e23223c2c8..692b1a7134 100644 --- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc +++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc @@ -3662,8 +3662,12 @@ TEST_F(ProtocolHandlerImplTest, const bool is_final = true; const uint32_t total_data_size = 1; UCharDataVector data(total_data_size); - RawMessagePtr message = std::make_shared( - connection_key, PROTOCOL_VERSION_3, &data[0], total_data_size, kControl); + RawMessagePtr message = std::make_shared(connection_key, + PROTOCOL_VERSION_3, + &data[0], + total_data_size, + false, + kControl); // Expect getting pair from key from session observer EXPECT_CALL(session_observer_mock, PairFromKey(message->connection_key(), _, _)) @@ -3684,7 +3688,7 @@ TEST_F(ProtocolHandlerImplTest, times++; // Act - protocol_handler_impl->SendMessageToMobileApp(message, is_final); + protocol_handler_impl->SendMessageToMobileApp(message, false, is_final); EXPECT_TRUE(waiter->WaitFor(times, kAsyncExpectationsTimeout)); } @@ -3700,8 +3704,12 @@ TEST_F(ProtocolHandlerImplTest, const bool is_final = true; const uint32_t total_data_size = 1; UCharDataVector data(total_data_size); - RawMessagePtr message = std::make_shared( - connection_key, PROTOCOL_VERSION_3, &data[0], total_data_size, kRpc); + RawMessagePtr message = std::make_shared(connection_key, + PROTOCOL_VERSION_3, + &data[0], + total_data_size, + false, + kRpc); // Expect getting pair from key from session observer EXPECT_CALL(session_observer_mock, PairFromKey(message->connection_key(), _, _)) @@ -3727,7 +3735,7 @@ TEST_F(ProtocolHandlerImplTest, times++; // Act - protocol_handler_impl->SendMessageToMobileApp(message, is_final); + protocol_handler_impl->SendMessageToMobileApp(message, false, is_final); EXPECT_TRUE(waiter->WaitFor(times, kAsyncExpectationsTimeout)); } @@ -3743,8 +3751,12 @@ TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendMultiframeMessage) { const uint32_t total_data_size = MAXIMUM_FRAME_DATA_V2_SIZE * 2; UCharDataVector data(total_data_size); const uint8_t first_consecutive_frame = 0x01; - RawMessagePtr message = std::make_shared( - connection_key, PROTOCOL_VERSION_3, &data[0], total_data_size, kBulk); + RawMessagePtr message = std::make_shared(connection_key, + PROTOCOL_VERSION_3, + &data[0], + total_data_size, + false, + kBulk); // Expect getting pair from key from session observer EXPECT_CALL(session_observer_mock, PairFromKey(message->connection_key(), _, _)) @@ -3782,7 +3794,7 @@ TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendMultiframeMessage) { times++; // Act - protocol_handler_impl->SendMessageToMobileApp(message, is_final); + protocol_handler_impl->SendMessageToMobileApp(message, false, is_final); EXPECT_TRUE(waiter->WaitFor(times, kAsyncExpectationsTimeout)); } 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/security_manager/test/security_manager_test.cc b/src/components/security_manager/test/security_manager_test.cc index 21af54f67b..7906ae7006 100644 --- a/src/components/security_manager/test/security_manager_test.cc +++ b/src/components/security_manager/test/security_manager_test.cc @@ -122,7 +122,7 @@ class SecurityManagerTest : public ::testing::Test { uint32_t dataSize, const ServiceType serviceType) { const RawMessagePtr rawMessagePtr(std::make_shared( - kKey, kProtocolVersion, data, dataSize, serviceType)); + kKey, kProtocolVersion, data, dataSize, false, serviceType)); security_manager_->OnMessageReceived(rawMessagePtr); } /* @@ -292,6 +292,7 @@ TEST_F(SecurityManagerTest, SecurityManager_NULLCryptoManager) { EXPECT_CALL(mock_protocol_handler, SendMessageToMobileApp( InternalErrorWithErrId(SecurityManager::ERROR_NOT_SUPPORTED), + false, kIsFinal)) .WillOnce(NotifyTestAsyncWaiter(&waiter)); const SecurityQuery::QueryHeader header(SecurityQuery::REQUEST, @@ -307,8 +308,8 @@ TEST_F(SecurityManagerTest, SecurityManager_NULLCryptoManager) { */ TEST_F(SecurityManagerTest, OnMobileMessageSent) { const uint8_t* data_param = NULL; - const RawMessagePtr rawMessagePtr( - std::make_shared(kKey, kProtocolVersion, data_param, 0)); + const RawMessagePtr rawMessagePtr(std::make_shared( + kKey, kProtocolVersion, data_param, 0, false)); security_manager_->OnMobileMessageSent(rawMessagePtr); } /* @@ -338,6 +339,7 @@ TEST_F(SecurityManagerTest, GetEmptyQuery) { mock_protocol_handler, SendMessageToMobileApp( InternalErrorWithErrId(SecurityManager::ERROR_INVALID_QUERY_SIZE), + false, kIsFinal)); // Call with NULL data call_OnMessageReceived(NULL, 0, kSecureServiceType); @@ -359,6 +361,7 @@ TEST_F(SecurityManagerTest, GetWrongJSONSize) { mock_protocol_handler, SendMessageToMobileApp( InternalErrorWithErrId(SecurityManager::ERROR_INVALID_QUERY_SIZE), + false, kIsFinal)); SecurityQuery::QueryHeader header(SecurityQuery::REQUEST, SecurityQuery::INVALID_QUERY_ID); @@ -388,6 +391,7 @@ TEST_F(SecurityManagerTest, GetInvalidQueryId) { mock_protocol_handler, SendMessageToMobileApp( InternalErrorWithErrId(SecurityManager::ERROR_INVALID_QUERY_ID), + false, kIsFinal)) .WillOnce(NotifyTestAsyncWaiter(&waiter)); times++; @@ -427,10 +431,11 @@ TEST_F(SecurityManagerTest, CreateSSLContext_ErrorCreateSSL) { EXPECT_CALL(mock_session_observer, ProtocolVersionUsed(connection_id, session_id, _)) .WillOnce(Return(true)); - EXPECT_CALL( - mock_protocol_handler, - SendMessageToMobileApp( - InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), kIsFinal)); + EXPECT_CALL(mock_protocol_handler, + SendMessageToMobileApp( + InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), + false, + kIsFinal)); // Emulate SessionObserver and CryptoManager result EXPECT_CALL(mock_session_observer, GetSSLContext(kKey, kControl)) @@ -461,6 +466,7 @@ TEST_F(SecurityManagerTest, CreateSSLContext_SetSSLContextError) { mock_protocol_handler, SendMessageToMobileApp( InternalErrorWithErrId(SecurityManager::ERROR_UNKNOWN_INTERNAL_ERROR), + false, kIsFinal)); // Emulate SessionObserver and CryptoManager result @@ -512,10 +518,11 @@ TEST_F(SecurityManagerTest, StartHandshake_ServiceStillUnprotected) { ProtocolVersionUsed(connection_id, session_id, _)) .WillOnce(Return(true)); // Expect InternalError with ERROR_INTERNAL - EXPECT_CALL( - mock_protocol_handler, - SendMessageToMobileApp( - InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), kIsFinal)); + EXPECT_CALL(mock_protocol_handler, + SendMessageToMobileApp( + InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), + false, + kIsFinal)); // Expect notifying listeners (unsuccess) EXPECT_CALL(*mock_sm_listener, OnHandshakeDone(kKey, SSLContext::Handshake_Result_Fail)) @@ -550,10 +557,11 @@ TEST_F(SecurityManagerTest, StartHandshake_SSLInternalError) { EXPECT_CALL(mock_session_observer, GetSSLContext(kKey, kControl)) .WillOnce(ReturnNull()); // Expect InternalError with ERROR_ID - EXPECT_CALL( - mock_protocol_handler, - SendMessageToMobileApp( - InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), kIsFinal)); + EXPECT_CALL(mock_protocol_handler, + SendMessageToMobileApp( + InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), + false, + kIsFinal)); security_manager_->StartHandshake(kKey); mock_sm_listener.release(); @@ -579,6 +587,7 @@ TEST_F(SecurityManagerTest, ProccessHandshakeData_WrongDataSize) { mock_protocol_handler, SendMessageToMobileApp( InternalErrorWithErrId(SecurityManager::ERROR_INVALID_QUERY_SIZE), + false, kIsFinal)) .WillOnce(NotifyTestAsyncWaiter(&waiter)); @@ -611,6 +620,7 @@ TEST_F(SecurityManagerTest, mock_protocol_handler, SendMessageToMobileApp( InternalErrorWithErrId(SecurityManager::ERROR_SERVICE_NOT_PROTECTED), + false, kIsFinal)) .WillOnce(NotifyTestAsyncWaiter(&waiter)); times++; @@ -665,6 +675,7 @@ TEST_F(SecurityManagerTest, ProccessHandshakeData_InvalidData) { mock_protocol_handler, SendMessageToMobileApp( InternalErrorWithErrId(SecurityManager::ERROR_SSL_INVALID_DATA), + false, kIsFinal)) .Times(handshake_emulates) .WillRepeatedly(NotifyTestAsyncWaiter(&waiter)); @@ -743,9 +754,9 @@ TEST_F(SecurityManagerTest, ProccessHandshakeData_Answer) { // Get size of raw message after const size_t raw_message_size = 15; - EXPECT_CALL( - mock_protocol_handler, - SendMessageToMobileApp(RawMessageEqSize(raw_message_size), kIsFinal)) + EXPECT_CALL(mock_protocol_handler, + SendMessageToMobileApp( + RawMessageEqSize(raw_message_size), false, kIsFinal)) .Times(handshake_emulates) .WillRepeatedly(NotifyTestAsyncWaiter(&waiter)); times += handshake_emulates; @@ -872,7 +883,7 @@ TEST_F(SecurityManagerTest, ProccessHandshakeData_HandshakeFinished) { .WillRepeatedly(DoAll(NotifyTestAsyncWaiter(&waiter), Return(true))); times += 2; // matches to the number above - EXPECT_CALL(mock_protocol_handler, SendMessageToMobileApp(_, kIsFinal)) + EXPECT_CALL(mock_protocol_handler, SendMessageToMobileApp(_, false, kIsFinal)) .Times(2) .WillRepeatedly(NotifyTestAsyncWaiter(&waiter)); times += 2; // matches to the number above diff --git a/src/components/telemetry_monitor/test/transport_manager_observer_test.cc b/src/components/telemetry_monitor/test/transport_manager_observer_test.cc index 57834339d6..c0501ac45e 100644 --- a/src/components/telemetry_monitor/test/transport_manager_observer_test.cc +++ b/src/components/telemetry_monitor/test/transport_manager_observer_test.cc @@ -47,7 +47,7 @@ TEST(TransportManagerObserverTest, MessageProcess) { MockTelemetryMonitor mock_telemetry_monitor; TransportManagerObserver tr_observer(&mock_telemetry_monitor); protocol_handler::RawMessage* ptr = - new ::protocol_handler::RawMessage(0, 0, NULL, 0); + new ::protocol_handler::RawMessage(0, 0, NULL, 0, false); tr_observer.StartRawMsg(ptr); EXPECT_CALL(mock_telemetry_monitor, SendMetric(_)); tr_observer.StopRawMsg(ptr); 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); } diff --git a/src/components/transport_manager/test/transport_adapter_listener_test.cc b/src/components/transport_manager/test/transport_adapter_listener_test.cc index 0813448e91..9f18d5bc13 100644 --- a/src/components/transport_manager/test/transport_adapter_listener_test.cc +++ b/src/components/transport_manager/test/transport_adapter_listener_test.cc @@ -130,7 +130,7 @@ TEST_F(TransportAdapterListenerTest, OnDataReceiveFailed) { TEST_F(TransportAdapterListenerTest, OnDataSendDone) { unsigned char data[3] = {0x20, 0x07, 0x01}; ::protocol_handler::RawMessagePtr data_container = - std::make_shared< ::protocol_handler::RawMessage>(1, 1, data, 3); + std::make_shared< ::protocol_handler::RawMessage>(1, 1, data, 3, false); EXPECT_CALL(tr_mock, ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_SEND_DONE, @@ -146,7 +146,7 @@ TEST_F(TransportAdapterListenerTest, OnDataSendDone) { TEST_F(TransportAdapterListenerTest, OnDataSendFailed) { unsigned char data[3] = {0x20, 0x07, 0x01}; ::protocol_handler::RawMessagePtr data_container = - std::make_shared< ::protocol_handler::RawMessage>(1, 1, data, 3); + std::make_shared< ::protocol_handler::RawMessage>(1, 1, data, 3, false); DataSendError err; EXPECT_CALL(tr_mock, diff --git a/src/components/transport_manager/test/transport_adapter_test.cc b/src/components/transport_manager/test/transport_adapter_test.cc index 56386db201..aa41c0bc6d 100644 --- a/src/components/transport_manager/test/transport_adapter_test.cc +++ b/src/components/transport_manager/test/transport_adapter_test.cc @@ -969,7 +969,7 @@ TEST_F(TransportAdapterTest, SendData) { const unsigned int kSize = 3; unsigned char data[kSize] = {0x20, 0x07, 0x01}; const RawMessagePtr kMessage = - std::make_shared(1, 1, data, kSize); + std::make_shared(1, 1, data, kSize, false); EXPECT_CALL(*mock_connection, SendData(kMessage)) .WillOnce(Return(TransportAdapter::OK)); @@ -1009,7 +1009,7 @@ TEST_F(TransportAdapterTest, SendData_ConnectionNotEstablished) { const unsigned int kSize = 3; unsigned char data[kSize] = {0x20, 0x07, 0x01}; const RawMessagePtr kMessage = - std::make_shared(1, 1, data, kSize); + std::make_shared(1, 1, data, kSize, false); EXPECT_CALL(*mock_connection, SendData(kMessage)).Times(0); res = transport_adapter.SendData(dev_id, app_handle, kMessage); diff --git a/src/components/transport_manager/test/transport_manager_impl_test.cc b/src/components/transport_manager/test/transport_manager_impl_test.cc index 3c3e336d0a..6411352ac9 100644 --- a/src/components/transport_manager/test/transport_manager_impl_test.cc +++ b/src/components/transport_manager/test/transport_manager_impl_test.cc @@ -101,7 +101,7 @@ class TransportManagerImplTest : public ::testing::Test { unsigned char data[kSize] = { 0x20, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; test_message_ = std::make_shared( - connection_key_, version_protocol_, data, kSize); + connection_key_, version_protocol_, data, kSize, false); } DeviceInfo ConstructDeviceInfo(const std::string& mac_address, -- cgit v1.2.1