diff options
author | jacobkeeler <jacob.keeler@livioradio.com> | 2019-04-08 14:33:45 -0400 |
---|---|---|
committer | jacobkeeler <jacob.keeler@livioradio.com> | 2019-04-08 14:33:45 -0400 |
commit | 18cac0a4ede64efd7ea1ac33c55a137638507352 (patch) | |
tree | 215171e33acc33aebd3459befa1e4a1d2821596e | |
parent | 6897d49d165e6a40450c6f662fec218ed6628f60 (diff) | |
download | sdl_core-18cac0a4ede64efd7ea1ac33c55a137638507352.tar.gz |
Add policy check for passthrough messages
3 files changed, 74 insertions, 9 deletions
diff --git a/src/components/application_manager/include/application_manager/rpc_passing_handler.h b/src/components/application_manager/include/application_manager/rpc_passing_handler.h index 675d567820..f8a1519d86 100644 --- a/src/components/application_manager/include/application_manager/rpc_passing_handler.h +++ b/src/components/application_manager/include/application_manager/rpc_passing_handler.h @@ -77,6 +77,13 @@ class RPCPassingHandler { bool IsPassThroughMessage(uint32_t correlation_id, commands::Command::CommandSource source, int32_t message_type); + /** + * @brief Check if passthrough is allowed by policies for a given message + * @param rpc_message RPC message SmartObject + * @return true if the request is allowed to be passed through, false + * otherwise + */ + bool IsPassThroughAllowed(smart_objects::SmartObject rpc_message); /** * @brief Function to handle sending and receiving RPC Passing diff --git a/src/components/application_manager/src/rpc_handler_impl.cc b/src/components/application_manager/src/rpc_handler_impl.cc index 156abfbed8..40aeb03223 100644 --- a/src/components/application_manager/src/rpc_handler_impl.cc +++ b/src/components/application_manager/src/rpc_handler_impl.cc @@ -118,16 +118,17 @@ void RPCHandlerImpl::ProcessMessageFromMobile( (*so_from_mobile)[strings::params][strings::correlation_id].asUInt(); int32_t message_type = (*so_from_mobile)[strings::params][strings::message_type].asInt(); - if (app_manager_.GetAppServiceManager() - .GetRPCPassingHandler() - .RPCPassThrough(*so_from_mobile)) { + RPCPassingHandler& handler = + app_manager_.GetAppServiceManager().GetRPCPassingHandler(); + // Check permissions for requests, otherwise attempt passthrough + if ((application_manager::MessageType::kRequest != message_type || + handler.IsPassThroughAllowed(*so_from_mobile)) && + handler.RPCPassThrough(*so_from_mobile)) { // RPC was forwarded. Skip handling by Core return; - } else if (!app_manager_.GetAppServiceManager() - .GetRPCPassingHandler() - .IsPassThroughMessage(correlation_id, - commands::Command::SOURCE_MOBILE, - message_type)) { + } else if (!handler.IsPassThroughMessage(correlation_id, + commands::Command::SOURCE_MOBILE, + message_type)) { // Since PassThrough failed, refiltering the message if (!ConvertMessageToSO(*message, *so_from_mobile)) { LOG4CXX_ERROR(logger_, "Cannot create smart object from message"); diff --git a/src/components/application_manager/src/rpc_passing_handler.cc b/src/components/application_manager/src/rpc_passing_handler.cc index 04d66ed207..ef1ba3c093 100644 --- a/src/components/application_manager/src/rpc_passing_handler.cc +++ b/src/components/application_manager/src/rpc_passing_handler.cc @@ -93,6 +93,63 @@ bool RPCPassingHandler::CanHandleFunctionID(int32_t function_id) { return false; } +bool RPCPassingHandler::IsPassThroughAllowed( + smart_objects::SmartObject rpc_message) { + LOG4CXX_AUTO_TRACE(logger_); + mobile_api::FunctionID::eType function_id = + static_cast<mobile_api::FunctionID::eType>( + rpc_message[strings::params][strings::function_id].asInt()); + uint32_t connection_key = + rpc_message[strings::params][strings::connection_key].asUInt(); + std::string function_id_str = + MessageHelper::StringifiedFunctionID(function_id); + ApplicationSharedPtr app = app_manager_.application(connection_key); + PolicyHandlerInterface& policy_handler = app_manager_.GetPolicyHandler(); + if (!app) { + return false; + } else if (function_id_str.empty()) { + // Unknown RPC, just do basic revoked and user consent checks + std::string device_mac; + app_manager_.connection_handler().get_session_observer().GetDataOnDeviceID( + app->device(), NULL, NULL, &device_mac, NULL); + return policy_handler.UnknownRPCPassthroughAllowed(app->policy_app_id()) && + !policy_handler.IsApplicationRevoked(app->policy_app_id()) && + policy::kDeviceAllowed == + app_manager_.GetUserConsentForDevice(device_mac); + } + + RPCParams params; + + const smart_objects::SmartObject& s_map = rpc_message[strings::msg_params]; + if (smart_objects::SmartType_Map == s_map.getType()) { + smart_objects::SmartMap::const_iterator iter = s_map.map_begin(); + smart_objects::SmartMap::const_iterator iter_end = s_map.map_end(); + + for (; iter != iter_end; ++iter) { + LOG4CXX_DEBUG(logger_, "Request's param: " << iter->first); + params.insert(iter->first); + } + } + + CommandParametersPermissions parameters_permissions; + + mobile_apis::Result::eType check_result = app_manager_.CheckPolicyPermissions( + app, function_id_str, params, ¶meters_permissions); + + // Check, if RPC is allowed by policy (since we are allowing unknown params, + // check should pass if only undefined parameters exist) + if (mobile_apis::Result::DISALLOWED == check_result && + !parameters_permissions.undefined_params.empty() && + parameters_permissions.disallowed_params.empty() && + parameters_permissions.allowed_params.empty()) { + return true; + } else if (mobile_apis::Result::SUCCESS != check_result) { + return false; + } + + return true; +} + bool RPCPassingHandler::RPCPassThrough(smart_objects::SmartObject rpc_message) { LOG4CXX_AUTO_TRACE(logger_); @@ -121,7 +178,7 @@ bool RPCPassingHandler::RPCPassThrough(smart_objects::SmartObject rpc_message) { LOG4CXX_DEBUG(logger_, "Correlation id DOES exist in map. Returning"); std::shared_ptr<smart_objects::SmartObject> response( MessageHelper::CreateNegativeResponse( - rpc_message[strings::params][strings::connection_key].asInt(), + rpc_message[strings::params][strings::connection_key].asUInt(), rpc_message[strings::params][strings::function_id].asInt(), correlation_id, mobile_apis::Result::INVALID_ID)); |