From 546cd986780759dd5eee64998f99bc66099a3b32 Mon Sep 17 00:00:00 2001 From: Andriy Byzhynar Date: Fri, 23 Feb 2018 17:54:43 +0200 Subject: Implement fully functional GetSystemTime feature Implemented fully working GetSystemTime feature Fixed UT in the security manager due to code changes Disable randomly failed test --- src/appMain/CMakeLists.txt | 2 + src/appMain/life_cycle.cc | 9 +- src/appMain/life_cycle.h | 7 +- src/components/application_manager/CMakeLists.txt | 11 ++ .../application_manager/application_manager_impl.h | 7 + .../basic_communication_get_system_time_request.h | 69 ++++++++ .../basic_communication_get_system_time_response.h | 72 +++++++++ .../hmi/on_system_time_ready_notification.h | 75 +++++++++ .../include/application_manager/message_helper.h | 9 ++ .../application_manager/smart_object_keys.h | 16 +- .../system_time/system_time_handler_impl.h | 157 ++++++++++++++++++ .../src/application_manager_impl.cc | 4 + .../basic_communication_get_system_time_request.cc | 49 ++++++ ...basic_communication_get_system_time_response.cc | 57 +++++++ .../hmi/on_system_time_ready_notification.cc | 56 +++++++ .../src/commands/hmi/request_to_hmi.cc | 4 +- .../application_manager/src/hmi_command_factory.cc | 18 +++ .../src/message_helper/message_helper.cc | 14 ++ .../src/policies/policy_handler.cc | 10 +- .../application_manager/src/smart_object_keys.cc | 17 +- .../src/system_time/system_time_handler_impl.cc | 169 ++++++++++++++++++++ .../src/connection_handler_impl.cc | 1 + .../policy/policy_regular/policy/policy_manager.h | 6 + .../include/protocol_handler/protocol_handler.h | 6 + .../include/security_manager/crypto_manager.h | 13 +- .../include/security_manager/security_manager.h | 46 +++++- .../security_manager/security_manager_listener.h | 6 + .../include/security_manager/ssl_context.h | 11 +- .../policy_regular/policy/mock_cache_manager.h | 2 +- .../test/protocol_handler/mock_protocol_handler.h | 1 + .../test/security_manager/mock_crypto_manager.h | 4 +- .../test/security_manager/mock_security_manager.h | 10 +- .../mock_security_manager_listener.h | 1 + .../test/security_manager/mock_ssl_context.h | 2 + .../include/test/utils/mock_system_time_handler.h | 69 ++++++++ src/components/interfaces/HMI_API.xml | 10 ++ .../policy_regular/include/policy/cache_manager.h | 6 + .../include/policy/cache_manager_interface.h | 7 + .../include/policy/policy_manager_impl.h | 2 + .../policy/policy_regular/src/cache_manager.cc | 7 + .../policy_regular/src/policy_manager_impl.cc | 7 + .../include/protocol_handler/handshake_handler.h | 7 + .../protocol_handler/protocol_handler_impl.h | 4 + .../protocol_handler/src/handshake_handler.cc | 11 ++ .../protocol_handler/src/protocol_handler_impl.cc | 46 ++++-- .../test/protocol_handler_tm_test.cc | 49 ++++-- .../include/security_manager/crypto_manager_impl.h | 24 ++- .../security_manager/security_manager_impl.h | 80 +++++++++- .../security_manager/src/crypto_manager_impl.cc | 67 ++------ .../security_manager/src/security_manager_impl.cc | 175 +++++++++++++++++++-- .../security_manager/src/ssl_context_impl.cc | 96 +++++++++++ .../test/crypto_manager_impl_test.cc | 9 +- .../security_manager/test/security_manager_test.cc | 129 ++++----------- .../test/ssl_certificate_handshake_test.cc | 3 + src/components/utils/CMakeLists.txt | 1 + .../utils/include/utils/system_time_handler.h | 151 ++++++++++++++++++ src/components/utils/src/system_time_handler.cc | 63 ++++++++ 57 files changed, 1737 insertions(+), 227 deletions(-) create mode 100644 src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h create mode 100644 src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h create mode 100644 src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h create mode 100644 src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h create mode 100644 src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_request.cc create mode 100644 src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_response.cc create mode 100644 src/components/application_manager/src/commands/hmi/on_system_time_ready_notification.cc create mode 100644 src/components/application_manager/src/system_time/system_time_handler_impl.cc create mode 100644 src/components/include/test/utils/mock_system_time_handler.h create mode 100644 src/components/utils/include/utils/system_time_handler.h create mode 100644 src/components/utils/src/system_time_handler.cc (limited to 'src') diff --git a/src/appMain/CMakeLists.txt b/src/appMain/CMakeLists.txt index 514867624a..f59f21e5c3 100644 --- a/src/appMain/CMakeLists.txt +++ b/src/appMain/CMakeLists.txt @@ -109,7 +109,9 @@ set(LIBRARIES jsoncpp ConfigProfile Resumption + SystemTimeLibrary ) + if(REMOTE_CONTROL) SET (LIBRARIES ${LIBRARIES} diff --git a/src/appMain/life_cycle.cc b/src/appMain/life_cycle.cc index fc8441f28c..90a23465be 100644 --- a/src/appMain/life_cycle.cc +++ b/src/appMain/life_cycle.cc @@ -34,6 +34,7 @@ #include "utils/signals.h" #include "utils/make_shared.h" #include "config_profile/profile.h" +#include "application_manager/system_time/system_time_handler_impl.h" #include "resumption/last_state_impl.h" #ifdef ENABLE_SECURITY @@ -119,7 +120,11 @@ bool LifeCycle::StartComponents() { } #ifdef ENABLE_SECURITY - security_manager_ = new security_manager::SecurityManagerImpl(); + auto system_time_handler = + std::unique_ptr( + new application_manager::SystemTimeHandlerImpl(*app_manager_)); + security_manager_ = + new security_manager::SecurityManagerImpl(std::move(system_time_handler)); crypto_manager_ = new security_manager::CryptoManagerImpl( utils::MakeShared( profile_, app_manager_->GetPolicyHandler().RetrieveCertificate())); @@ -131,7 +136,7 @@ bool LifeCycle::StartComponents() { security_manager_->set_crypto_manager(crypto_manager_); security_manager_->AddListener(app_manager_); - app_manager_->AddPolicyObserver(crypto_manager_); + app_manager_->AddPolicyObserver(security_manager_); app_manager_->AddPolicyObserver(protocol_handler_); if (!crypto_manager_->Init()) { LOG4CXX_ERROR(logger_, "CryptoManager initialization fail."); diff --git a/src/appMain/life_cycle.h b/src/appMain/life_cycle.h index db18892cd3..e37da3fa1d 100644 --- a/src/appMain/life_cycle.h +++ b/src/appMain/life_cycle.h @@ -33,8 +33,9 @@ #ifndef SRC_APPMAIN_LIFE_CYCLE_H_ #define SRC_APPMAIN_LIFE_CYCLE_H_ #include +#include #include "utils/macro.h" -#include "unistd.h" +#include "utils/shared_ptr.h" #include "config_profile/profile.h" #include "hmi_message_handler/hmi_message_handler_impl.h" @@ -65,6 +66,10 @@ class SecurityManagerImpl; } // namespace security_manager #endif // ENABLE_SECURITY +namespace utils { +class SystemTimeHandler; +} // namespace utils + namespace main_namespace { class LifeCycle { public: diff --git a/src/components/application_manager/CMakeLists.txt b/src/components/application_manager/CMakeLists.txt index e9f2f8ec7b..966dbee353 100644 --- a/src/components/application_manager/CMakeLists.txt +++ b/src/components/application_manager/CMakeLists.txt @@ -52,6 +52,7 @@ include_directories ( ${COMPONENTS_DIR}/config_profile/include ${COMPONENTS_DIR}/request_watchdog/include ${COMPONENTS_DIR}/resumption/include + ${COMPONENTS_DIR}/system_time/ ${COMPONENTS_DIR}/rpc_base/include ${COMPONENTS_DIR}/interfaces ${POLICY_PATH}/include/ @@ -85,6 +86,9 @@ set (MESSAGE_HELPER_PATHS ) collect_sources(MESSAGE_HELPER_SOURCES "${MESSAGE_HELPER_PATHS}") +set (SYSTEM_TIME_SOURCES + ${AM_SOURCE_DIR}/src/system_time/system_time_handler_impl.cc +) set (POLICIES_SOURCE_DIR ${AM_SOURCE_DIR}/src/policies @@ -146,6 +150,9 @@ set (HMI_COMMANDS_SOURCES ${COMMANDS_SOURCE_DIR}/hmi/activate_app_response.cc ${COMMANDS_SOURCE_DIR}/hmi/get_system_info_request.cc ${COMMANDS_SOURCE_DIR}/hmi/get_system_info_response.cc + ${COMMANDS_SOURCE_DIR}/hmi/basic_communication_get_system_time_request.cc + ${COMMANDS_SOURCE_DIR}/hmi/basic_communication_get_system_time_response.cc + ${COMMANDS_SOURCE_DIR}/hmi/on_system_time_ready_notification.cc ${COMMANDS_SOURCE_DIR}/hmi/sdl_get_list_of_permissions_request.cc ${COMMANDS_SOURCE_DIR}/hmi/sdl_get_list_of_permissions_response.cc ${COMMANDS_SOURCE_DIR}/hmi/sdl_get_user_friendly_message_request.cc @@ -447,6 +454,10 @@ target_link_libraries("AMHMICommandsLibrary" ${LIBRARIES} AMEventEngine) add_library("MessageHelper" ${MESSAGE_HELPER_SOURCES}) target_link_libraries("MessageHelper" ${LIBRARIES}) +add_library("SystemTimeLibrary" ${SYSTEM_TIME_SOURCES}) +target_link_libraries("SystemTimeLibrary" ${LIBRARIES} AMEventEngine) +add_dependencies("MessageHelper" HMI_API MOBILE_API) + add_library("AMMobileCommandsLibrary" ${MOBILE_COMMANDS_SOURCES} ) target_link_libraries("AMMobileCommandsLibrary" ${LIBRARIES} AMEventEngine) diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index 286ad87018..d3fe69efcb 100644 --- a/src/components/application_manager/include/application_manager/application_manager_impl.h +++ b/src/components/application_manager/include/application_manager/application_manager_impl.h @@ -957,6 +957,13 @@ class ApplicationManagerImpl uint32_t connection_key, security_manager::SSLContext::HandshakeResult result) OVERRIDE; + /** + * @brief OnHandshakeFailed currently does nothing. + * This method is declared as pure virtual in common base class + * therefore it has to be present and should be implemented + * to allow creation of current class instances + */ + void OnHandshakeFailed() OVERRIDE; /** * @brief Notification that certificate update is required. */ diff --git a/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h new file mode 100644 index 0000000000..1638b2f51b --- /dev/null +++ b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, 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_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_REQUEST_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_REQUEST_H_ + +#include "application_manager/commands/hmi/request_to_hmi.h" +#include "utils/macro.h" + +namespace application_manager { +namespace commands { + +/** + * @brief The BasicCommunicationGetSystemTimeRequest class sends the request + * to the HMI in order to receive current system time. + */ +class BasicCommunicationGetSystemTimeRequest : public RequestToHMI { + public: + /** + * @brief BasicCommunicationGetSystemTimeRequest does nothing except of + * initializing base class with the passed parameters. + * @param message the message to send to HMI + * @param application_manager application manager. Location service which + * is provides neccessary api to send the request. + */ + BasicCommunicationGetSystemTimeRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager); + + private: + /** + * @brief onTimeOut allows to handle case when + * system does not respond for certain request in + * appropriate time window. + */ + void onTimeOut() FINAL; +}; + +} // namespace commands +} // namespace application_manager +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_REQUEST_H_ diff --git a/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h new file mode 100644 index 0000000000..1bf7447c7d --- /dev/null +++ b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018, 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_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_RESPONSE_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_RESPONSE_H_ + +#include "application_manager/commands/hmi/response_from_hmi.h" + +#include "utils/macro.h" +#include "application_manager/application_manager_impl.h" + +namespace application_manager { + +namespace commands { + +/** + * @brief The BasicCommunicationGetSystemTimeResponse class represents the + * HMI response which is contains data obtained from HMI. + */ +class BasicCommunicationGetSystemTimeResponse : public ResponseFromHMI { + public: + /** + * @brief BasicCommunicationGetSystemTimeResponse does nothing except of + * initializing base class with the passed parameters. + * @param message the message to send to HMI + * @param application_manager Location service which which is provides + * neccessary api to send the request. + */ + BasicCommunicationGetSystemTimeResponse( + const MessageSharedPtr& message, ApplicationManager& application_manager); + + private: + /** + * @brief Run takes the message obtained from the HMI and + * sends this data to the subscribed on certain event class + */ + void Run() FINAL; +}; + +} // namespace commands +} // namespace application_manager + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_RESPONSE_H_ diff --git a/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h b/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h new file mode 100644 index 0000000000..9b8763da42 --- /dev/null +++ b/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018, 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_APPLICATION_MANAGER_COMMANDS_HMI_ON_SYSTEM_TIME_READY_NOTIFICATION_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_ON_SYSTEM_TIME_READY_NOTIFICATION_H_ + +#include "application_manager/commands/hmi/notification_from_hmi.h" +#include "application_manager/application_manager_impl.h" + +namespace application_manager { + +namespace commands { + +/** + * @brief OnSystemTimeReadyNotification command class. + * Notifies SDL whenever system time module is ready. + * It could be GPS or any other module which is allows + * to obtain system time. Once SDL receive this notification + * it is allowed to use GetSystemTimeRequest to rerieve system time. + */ +class OnSystemTimeReadyNotification : public NotificationFromHMI { + public: + /** + * @brief OnSystemTimeReadyNotification create the command. + * @param message content of the command. Passed directy to base class. + */ + OnSystemTimeReadyNotification(const MessageSharedPtr& message, + ApplicationManager& application_manager); + + /** + * @brief ~OnSystemTimeReadyNotification destroys the command object. + */ + ~OnSystemTimeReadyNotification(); + + private: + /** + * @brief Run creates SystemTimeReady event + * and notifies all the subscribers. + */ + void Run() FINAL; +}; + +} // namespace commands +} // namespace application_manager + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_ON_SYSTEM_TIME_READY_NOTIFICATION_H_ 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 b94609c01b..0a476712d6 100644 --- a/src/components/application_manager/include/application_manager/message_helper.h +++ b/src/components/application_manager/include/application_manager/message_helper.h @@ -107,6 +107,15 @@ class MessageHelper { static void SendDecryptCertificateToHMI(const std::string& file_name, ApplicationManager& app_mngr); + /** + * @brief SendGetSystemTimeRequest sends mentioned request to HMI. + * @param correlation_id the message correlation id, required for proper + * response processing. + * @param app_mngr + */ + static void SendGetSystemTimeRequest(const uint32_t correlation_id, + ApplicationManager& app_mngr); + /* * @brief Retrieve vehicle data map for param name in mobile request * to VehicleDataType 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 32a2315f23..e79b34c55f 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 @@ -406,7 +406,19 @@ extern const char* kFull; extern const char* kLimited; extern const char* kBackground; extern const char* kNone; -} +} // namespace hmi_levels + +namespace time_keys { +extern const char* millisecond; +extern const char* second; +extern const char* minute; +extern const char* hour; +extern const char* day; +extern const char* month; +extern const char* year; +extern const char* tz_hour; +extern const char* tz_minute; +} // namespace time_keys namespace hmi_request { extern const char* parent_id; @@ -478,7 +490,7 @@ extern const char* num_custom_presets_available; extern const char* urls; extern const char* policy_app_id; extern const char* enabled; - +extern const char* system_time; } // namespace hmi_response namespace hmi_notification { diff --git a/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h b/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h new file mode 100644 index 0000000000..28ba629e19 --- /dev/null +++ b/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2018, 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_APPLICATION_MANAGER_SYSTEM_TIME_SYSTEM_TIME_HANDLER_IMPL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_SYSTEM_TIME_SYSTEM_TIME_HANDLER_IMPL_H_ + +#include +#include + +#include "utils/lock.h" +#include "utils/macro.h" +#include "utils/system_time_handler.h" +#include "application_manager/application_manager_impl.h" +#include "application_manager/event_engine/event_observer.h" + +namespace application_manager { + +/** + * @brief The SystemTimeHandlerImpl class. + * Responsible for the system time notification. It keeps the list + * of system time listeners, sends appropriate request to the system + * and notifies the listeners with new time right after response has appeared. + */ +class SystemTimeHandlerImpl : public utils::SystemTimeHandler, + public event_engine::EventObserver { + public: + /** + * @brief SystemTimeHandlerImpl creates the instance of the class. + */ + explicit SystemTimeHandlerImpl(ApplicationManager& application_manager); + + /** + * @brief ~SystemTimeHandlerImpl + */ + ~SystemTimeHandlerImpl(); + + private: + /** + * @brief on_event allows to process certain events from the system. + * Event which are handles within this methods are: OnSystemTimeReady + * in order to send system time query and GetSystemTimeResponse in order + * to retrieve utc time and notify all the listeners with new time value. + */ + void on_event(const application_manager::event_engine::Event& event) FINAL; + + /** + * @brief DoSystemTimeQuery sends the appropriate request to the system + * and subscribes the class to the response. This is asynchronous request + * thus it won't block until the system respond and returns immediately. + */ + void DoSystemTimeQuery() FINAL; + + /** + * @brief DoSubscribe allows to subscribe certain listener for + * SystemTime. This certain implementation does not maintain + * listeners collection instead it save the pointer to listener. + * @note the class is not reponsible for the pointer's lifecycle. + * So consider to explicitly unsibsscribe from event when listener + * is going to be destroyed. + * @param listener the listener which will be notified + * in case of SystemTime appeared. + */ + void DoSubscribe(utils::SystemTimeListener* listener) FINAL; + + /** + * @brief DoUnsubscribe assigns the pointer to listener to NULL. + * This certain implementation ignores passed parameter. + * @param listener pointer to the object which should be + * unsubscribed from events. + */ + void DoUnsubscribe(utils::SystemTimeListener* listener) FINAL; + + /** + * @brief FetchSystemTime this method allows to obtain + * recently received utc time. + * @note it is up to user to check whether the returned + * argument is valid + * @return the time value returned by system. + */ + time_t FetchSystemTime() FINAL; + + /** + * @brief SendTimeRequest sends the request to the system + * and subscribes for response. + */ + void SendTimeRequest(); + + /** + * @brief ProcessSystemTimeResponse allows to process GetSystemTimeResponse + * @param event contains response parameters aka "systemTime". + */ + void ProcessSystemTimeResponse( + const application_manager::event_engine::Event& event); + + /** + * @brief ProcessSystemTimeReadyNotification allows to process + * OnSystemTimeready notification + * from HMI. It unsubscribes from the mentioned notification and sends + * GetSystemTimeRequest to HMI in order to obtain system time + */ + void ProcessSystemTimeReadyNotification(); + + /** + * @brief Checks if UTC time is ready to provided by HMI + * and can be requested by GetSystemTime request + * @return True if HMI is ready to provide UTC time + * otherwise False + */ + bool utc_time_can_be_received() const FINAL; + + mutable sync_primitives::Lock state_lock_; + // Variable means HMI readiness to provide system time by request + volatile bool utc_time_can_be_received_; + // Varible used to schedule next GetSystemTime request + // if at the moment of sending first GetSystemTime request + // HMI is not ready to provide system time + volatile bool schedule_request_; + // Varible used to store result for GetSystemTime request + time_t last_time_; + + sync_primitives::Lock system_time_listener_lock_; + utils::SystemTimeListener* system_time_listener_; + ApplicationManager& app_manager_; +}; + +} // namespace application_manager + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_SYSTEM_TIME_SYSTEM_TIME_HANDLER_IMPL_H_ diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 248b54fee5..5aa72d77e5 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -1691,6 +1691,10 @@ bool ApplicationManagerImpl::OnHandshakeDone( return false; } +void ApplicationManagerImpl::OnHandshakeFailed() { + LOG4CXX_AUTO_TRACE(logger_); +} + void ApplicationManagerImpl::OnCertificateUpdateRequired() { LOG4CXX_AUTO_TRACE(logger_); GetPolicyHandler().OnPTExchangeNeeded(); diff --git a/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_request.cc b/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_request.cc new file mode 100644 index 0000000000..215b0404a7 --- /dev/null +++ b/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_request.cc @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018, 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 + * distribut wiion. + * + * 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/commands/hmi/basic_communication_get_system_time_request.h" + +namespace application_manager { + +namespace commands { + +BasicCommunicationGetSystemTimeRequest::BasicCommunicationGetSystemTimeRequest( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : RequestToHMI(message, application_manager) {} + +void BasicCommunicationGetSystemTimeRequest::onTimeOut() { + LOG4CXX_AUTO_TRACE(logger_); + application_manager_.protocol_handler().NotifyOnFailedHandshake(); +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_response.cc b/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_response.cc new file mode 100644 index 0000000000..26dd115d1a --- /dev/null +++ b/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_response.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018, 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/commands/hmi/basic_communication_get_system_time_response.h" +#include "utils/logger.h" + +CREATE_LOGGERPTR_GLOBAL(logger_, "Commands") + +namespace application_manager { +namespace commands { + +BasicCommunicationGetSystemTimeResponse:: + BasicCommunicationGetSystemTimeResponse( + const MessageSharedPtr& message, + ApplicationManager& application_manager) + : ResponseFromHMI(message, application_manager) {} + +void BasicCommunicationGetSystemTimeResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + event_engine::Event event( + hmi_apis::FunctionID::BasicCommunication_GetSystemTime); + event.set_smart_object(*message_); + event.raise(application_manager_.event_dispatcher()); +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/src/commands/hmi/on_system_time_ready_notification.cc b/src/components/application_manager/src/commands/hmi/on_system_time_ready_notification.cc new file mode 100644 index 0000000000..d2376e6dfe --- /dev/null +++ b/src/components/application_manager/src/commands/hmi/on_system_time_ready_notification.cc @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, 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/commands/hmi/on_system_time_ready_notification.h" + +#include "application_manager/event_engine/event.h" +#include "interfaces/HMI_API.h" + +namespace application_manager { + +namespace commands { + +OnSystemTimeReadyNotification::OnSystemTimeReadyNotification( + const MessageSharedPtr& message, ApplicationManager& application_manager) + : NotificationFromHMI(message, application_manager) {} + +OnSystemTimeReadyNotification::~OnSystemTimeReadyNotification() {} + +void OnSystemTimeReadyNotification::Run() { + event_engine::Event event( + hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady); + event.set_smart_object(*message_); + event.raise(application_manager_.event_dispatcher()); +} + +} // namespace commands +} // namespace application_manager diff --git a/src/components/application_manager/src/commands/hmi/request_to_hmi.cc b/src/components/application_manager/src/commands/hmi/request_to_hmi.cc index 6905e7cdef..23c020bca2 100644 --- a/src/components/application_manager/src/commands/hmi/request_to_hmi.cc +++ b/src/components/application_manager/src/commands/hmi/request_to_hmi.cc @@ -74,7 +74,9 @@ bool RequestToHMI::CleanUp() { return true; } -void RequestToHMI::Run() {} +void RequestToHMI::Run() { + SendRequest(); +} void RequestToHMI::SendRequest() { (*message_)[strings::params][strings::protocol_type] = hmi_protocol_type_; diff --git a/src/components/application_manager/src/hmi_command_factory.cc b/src/components/application_manager/src/hmi_command_factory.cc index a7f3ce7e6b..5ef8605999 100644 --- a/src/components/application_manager/src/hmi_command_factory.cc +++ b/src/components/application_manager/src/hmi_command_factory.cc @@ -224,6 +224,7 @@ #include "application_manager/commands/hmi/navi_get_way_points_request.h" #include "application_manager/commands/hmi/navi_get_way_points_response.h" #include "application_manager/commands/hmi/on_ready_notification.h" +#include "application_manager/commands/hmi/on_system_time_ready_notification.h" #include "application_manager/commands/hmi/on_device_chosen_notification.h" #include "application_manager/commands/hmi/on_file_removed_notification.h" #include "application_manager/commands/hmi/on_system_context_notification.h" @@ -269,6 +270,8 @@ #include "application_manager/commands/hmi/on_system_error_notification.h" #include "application_manager/commands/hmi/basic_communication_system_request.h" #include "application_manager/commands/hmi/basic_communication_system_response.h" +#include "application_manager/commands/hmi/basic_communication_get_system_time_request.h" +#include "application_manager/commands/hmi/basic_communication_get_system_time_response.h" #include "application_manager/commands/hmi/basic_communication_on_awake_sdl.h" #include "application_manager/commands/hmi/sdl_policy_update.h" #include "application_manager/commands/hmi/sdl_policy_update_response.h" @@ -1285,6 +1288,11 @@ CommandSharedPtr HMICommandFactory::CreateCommand( new commands::OnReadyNotification(message, application_manager)); break; } + case hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady: { + command.reset(new commands::OnSystemTimeReadyNotification( + message, application_manager)); + break; + } case hmi_apis::FunctionID::BasicCommunication_OnDeviceChosen: { command.reset(new commands::OnDeviceChosenNotification( message, application_manager)); @@ -2221,6 +2229,16 @@ CommandSharedPtr HMICommandFactory::CreateCommand( } break; } + case hmi_apis::FunctionID::BasicCommunication_GetSystemTime: { + if (is_response) { + command.reset(new commands::BasicCommunicationGetSystemTimeResponse( + message, application_manager)); + } else { + command.reset(new commands::BasicCommunicationGetSystemTimeRequest( + message, application_manager)); + } + break; + } case hmi_apis::FunctionID::Navigation_SendLocation: { if (is_response) { command.reset(new commands::NaviSendLocationResponse( 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 6a908c4ebc..9a10c908f1 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -365,6 +365,20 @@ void MessageHelper::SendDecryptCertificateToHMI(const std::string& file_name, app_mngr.ManageHMICommand(message); } +void MessageHelper::SendGetSystemTimeRequest(const uint32_t correlation_id, + ApplicationManager& app_mngr) { + using namespace smart_objects; + SmartObjectSPtr message = + CreateMessageForHMI(hmi_apis::messageType::request, correlation_id); + + DCHECK(message); + + (*message)[strings::params][strings::function_id] = + hmi_apis::FunctionID::BasicCommunication_GetSystemTime; + + app_mngr.ManageHMICommand(message); +} + void MessageHelper::SendHashUpdateNotification(const uint32_t app_id, ApplicationManager& app_mngr) { LOG4CXX_AUTO_TRACE(logger_); diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index bbf391a9f1..98fb6bae65 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -1765,11 +1765,11 @@ void PolicyHandler::OnCertificateDecrypted(bool is_succeeded) { void PolicyHandler::OnCertificateUpdated(const std::string& certificate_data) { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock lock(listeners_lock_); - HandlersCollection::const_iterator it = listeners_.begin(); - for (; it != listeners_.end(); ++it) { - PolicyHandlerObserver* observer = *it; - observer->OnCertificateUpdated(certificate_data); - } + std::for_each( + listeners_.begin(), + listeners_.end(), + std::bind2nd(std::mem_fun(&PolicyHandlerObserver::OnCertificateUpdated), + certificate_data)); } #endif // EXTERNAL_PROPRIETARY_MODE diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index c3aba90dd5..888943d4d6 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -351,7 +351,7 @@ const char* instance_follow_redirect = "InstanceFollowRedirect"; const char* charset = "charset"; const char* content_lenght = "Content_Lenght"; const char* GET = "GET"; -} // http_request +} // namespace http_request namespace mobile_notification { const char* state = "state"; @@ -364,7 +364,17 @@ const char* kFull = "FULL"; const char* kLimited = "LIMITED"; const char* kBackground = "BACKGROUND"; const char* kNone = "NONE"; -} +} // namespace hmi_levels + +namespace time_keys { +const char* millisecond = "millisecond"; +const char* second = "second"; +const char* minute = "minute"; +const char* hour = "hour"; +const char* day = "day"; +const char* month = "month"; +const char* year = "year"; +} // namespace time_keys namespace hmi_request { const char* parent_id = "parentID"; @@ -436,7 +446,7 @@ const char* num_custom_presets_available = "numCustomPresetsAvailable"; const char* urls = "urls"; const char* policy_app_id = "policyAppID"; const char* enabled = "enabled"; - +const char* system_time = "systemTime"; } // namespace hmi_response namespace hmi_notification { @@ -451,7 +461,6 @@ const char* policyfile = "policyfile"; const char* is_active = "isActive"; const char* is_deactivated = "isDeactivated"; const char* event_name = "eventName"; - } // namespace hmi_notification } // namespace application_manager diff --git a/src/components/application_manager/src/system_time/system_time_handler_impl.cc b/src/components/application_manager/src/system_time/system_time_handler_impl.cc new file mode 100644 index 0000000000..a91fb16197 --- /dev/null +++ b/src/components/application_manager/src/system_time/system_time_handler_impl.cc @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2018, 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/system_time/system_time_handler_impl.h" + +#include + +#include "application_manager/message_helper.h" +#include "application_manager/smart_object_keys.h" +#include "interfaces/HMI_API.h" +#include "utils/logger.h" + +namespace application_manager { + +SystemTimeHandlerImpl::SystemTimeHandlerImpl( + ApplicationManager& application_manager) + : event_engine::EventObserver(application_manager.event_dispatcher()) + , utc_time_can_be_received_(false) + , schedule_request_(false) + , system_time_listener_(NULL) + , app_manager_(application_manager) { + LOG4CXX_AUTO_TRACE(logger_); + subscribe_on_event( + hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady); +} + +SystemTimeHandlerImpl::~SystemTimeHandlerImpl() { + LOG4CXX_AUTO_TRACE(logger_); + unsubscribe_from_all_events(); +} + +void SystemTimeHandlerImpl::DoSystemTimeQuery() { + LOG4CXX_AUTO_TRACE(logger_); + using namespace application_manager; + + sync_primitives::AutoLock lock(state_lock_); + if (!utc_time_can_be_received_) { + LOG4CXX_INFO(logger_, + "Navi module is not yet ready." + << "Will process request once it became ready."); + schedule_request_ = true; + return; + } + SendTimeRequest(); +} + +void SystemTimeHandlerImpl::DoSubscribe(utils::SystemTimeListener* listener) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(listener); + sync_primitives::AutoLock lock(system_time_listener_lock_); + system_time_listener_ = listener; +} + +void SystemTimeHandlerImpl::DoUnsubscribe(utils::SystemTimeListener* listener) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(system_time_listener_lock_); + system_time_listener_ = NULL; +} + +time_t SystemTimeHandlerImpl::FetchSystemTime() { + LOG4CXX_AUTO_TRACE(logger_); + return last_time_; +} + +bool SystemTimeHandlerImpl::utc_time_can_be_received() const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(state_lock_); + return utc_time_can_be_received_; +} + +void SystemTimeHandlerImpl::SendTimeRequest() { + LOG4CXX_AUTO_TRACE(logger_); + using namespace application_manager; + uint32_t correlation_id = app_manager_.GetNextHMICorrelationID(); + subscribe_on_event(hmi_apis::FunctionID::BasicCommunication_GetSystemTime, + correlation_id); + MessageHelper::SendGetSystemTimeRequest(correlation_id, app_manager_); +} + +void SystemTimeHandlerImpl::on_event( + const application_manager::event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace application_manager; + using namespace hmi_apis::FunctionID; + switch (event.id()) { + case BasicCommunication_OnSystemTimeReady: + ProcessSystemTimeReadyNotification(); + break; + case BasicCommunication_GetSystemTime: + ProcessSystemTimeResponse(event); + break; + default: + LOG4CXX_ERROR(logger_, "Unknown Event received"); + break; + } +} + +void SystemTimeHandlerImpl::ProcessSystemTimeReadyNotification() { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(state_lock_); + utc_time_can_be_received_ = true; + if (schedule_request_) { + SendTimeRequest(); + schedule_request_ = false; + } + unsubscribe_from_event( + hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady); +} + +void SystemTimeHandlerImpl::ProcessSystemTimeResponse( + const application_manager::event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& message = event.smart_object(); + const smart_objects::SmartObject& system_time_so = + message[strings::msg_params][hmi_response::system_time]; + + struct tm system_time; + memset(&system_time, 0, sizeof(struct tm)); + + system_time.tm_sec = system_time_so[time_keys::second].asInt(); + system_time.tm_min = system_time_so[time_keys::minute].asInt(); + // According to tm specification of tm type hour should be decreased by 1 + system_time.tm_hour = system_time_so[time_keys::hour].asInt() - 1; + system_time.tm_mday = system_time_so[time_keys::day].asInt(); + // According to tm specification of tm type mon should be decreased by 1 + system_time.tm_mon = system_time_so[time_keys::month].asInt() - 1; + // According to tm specification of tm type + // tm_year - number of years since 1900 + system_time.tm_year = system_time_so[time_keys::year].asInt() - 1900; + + // Normalize and convert time from 'tm' format to 'time_t' + last_time_ = mktime(&system_time); + + sync_primitives::AutoLock lock(system_time_listener_lock_); + if (system_time_listener_) { + system_time_listener_->OnSystemTimeArrived(last_time_); + } +} + +} // namespace application_manager diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index 5b26304302..b97c6eacd4 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -316,6 +316,7 @@ void ConnectionHandlerImpl::RemoveConnection( bool AllowProtection(const ConnectionHandlerSettings& settings, const protocol_handler::ServiceType& service_type, const bool is_protected) { + LOG4CXX_AUTO_TRACE(logger_); const std::vector& force_unprotected_list = is_protected ? settings.force_unprotected_service() : settings.force_protected_service(); 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 3e90cfc094..f14cce6c4f 100644 --- a/src/components/include/policy/policy_regular/policy/policy_manager.h +++ b/src/components/include/policy/policy_regular/policy/policy_manager.h @@ -504,6 +504,12 @@ class PolicyManager : public usage_statistics::StatisticsManager { */ virtual bool HasCertificate() const = 0; + /** + * @brief Sets decrypted certificate in policy table + * @param certificate content of certificate + */ + virtual void SetDecryptedCertificate(const std::string& certificate) = 0; + /** * @brief Getter for policy settings * @return policy settings instance diff --git a/src/components/include/protocol_handler/protocol_handler.h b/src/components/include/protocol_handler/protocol_handler.h index 6aafd7d53f..1da8d61e52 100644 --- a/src/components/include/protocol_handler/protocol_handler.h +++ b/src/components/include/protocol_handler/protocol_handler.h @@ -103,6 +103,12 @@ class ProtocolHandler { virtual void SendEndService(int32_t connection_id, uint8_t session_id, uint8_t service_type) = 0; + + /** + * \brief Called to notify all handsheke handlers about handshake failure. + */ + virtual void NotifyOnFailedHandshake() = 0; + /** * \brief Protocol handler settings getter * \return pointer to protocol handler settings class diff --git a/src/components/include/security_manager/crypto_manager.h b/src/components/include/security_manager/crypto_manager.h index 18c06ffe06..486b6da64f 100644 --- a/src/components/include/security_manager/crypto_manager.h +++ b/src/components/include/security_manager/crypto_manager.h @@ -33,6 +33,7 @@ #ifndef SRC_COMPONENTS_INCLUDE_SECURITY_MANAGER_CRYPTO_MANAGER_H_ #define SRC_COMPONENTS_INCLUDE_SECURITY_MANAGER_CRYPTO_MANAGER_H_ +#include #include "application_manager/policies/policy_handler_observer.h" #include "security_manager/security_manager_settings.h" @@ -65,8 +66,16 @@ class CryptoManager : public policy::PolicyHandlerObserver { virtual bool OnCertificateUpdated(const std::string& data) = 0; virtual void ReleaseSSLContext(SSLContext* context) = 0; virtual std::string LastError() const = 0; - - virtual bool IsCertificateUpdateRequired() const = 0; + /** + * @brief IsCertificateUpdateRequired checks if certificate update is needed + * @param system_time - time with which certificate expiration time + * should be compared + * @param certificates_time - certificate expiration time + * @return True if certificate expired and need to be updated + * otherwise False + */ + virtual bool IsCertificateUpdateRequired( + const time_t system_time, const time_t certificates_time) const = 0; /** * \brief Crypto manager settings getter * \return pointer to crypto manager settings class diff --git a/src/components/include/security_manager/security_manager.h b/src/components/include/security_manager/security_manager.h index 8f772f6a13..6ad5e96989 100644 --- a/src/components/include/security_manager/security_manager.h +++ b/src/components/include/security_manager/security_manager.h @@ -41,6 +41,7 @@ #include "protocol_handler/session_observer.h" #include "security_manager/security_manager_listener.h" +#include "application_manager/policies/policy_handler_observer.h" namespace security_manager { @@ -50,7 +51,8 @@ class CryptoManager; * protocol_handler::ProtocolObserver * and provide interface for handling Security queries from mobile side */ -class SecurityManager : public protocol_handler::ProtocolObserver { +class SecurityManager : public protocol_handler::ProtocolObserver, + public policy::PolicyHandlerObserver { public: /** * \brief InternalErrors is 1 byte identifier of internal error @@ -70,6 +72,10 @@ class SecurityManager : public protocol_handler::ProtocolObserver { ERROR_INTERNAL = 0xFF, ERROR_UNKNOWN_INTERNAL_ERROR = 0xFE // error value for testing }; + + // SSL context creation strategy + enum ContextCreationStrategy { kUseExisting = 0, kForceRecreation }; + /** * \brief Sets pointer for Connection Handler layer for managing sessions * \param session_observer pointer to object of the class implementing @@ -114,24 +120,42 @@ class SecurityManager : public protocol_handler::ProtocolObserver { } /** - * \brief Create new SSLContext for connection or return exists + * @brief Create new SSLContext for connection or return exists * Do not notify listeners, send security error on occure - * \param connection_key Unique key used by other components as session + * @param connection_key Unique key used by other components as session * identifier + * @param cc_strategy - SSL context creation strategy * @return new \c SSLContext or \c NULL on any error */ - virtual SSLContext* CreateSSLContext(const uint32_t& connection_key) = 0; + virtual SSLContext* CreateSSLContext(const uint32_t& connection_key, + ContextCreationStrategy cc_strategy) = 0; /** * \brief Start handshake as SSL client */ virtual void StartHandshake(uint32_t connection_key) = 0; + /** + * @brief PostponeHandshake allows to postpone handshake. It notifies + * cryptomanager that certificate should be updated and adds specified + * connection key to the list of the certificate awaiting connections. + * @param connection_key the identifier for connection to postpone handshake. + */ + virtual void PostponeHandshake(const uint32_t connection_key) = 0; + /** * @brief Check whether certificate should be updated + * @param connection_key the connection identifier to check certificate for. * @return true if certificate should be updated otherwise false */ - virtual bool IsCertificateUpdateRequired() = 0; + virtual bool IsCertificateUpdateRequired(const uint32_t connection_key) = 0; + + /** + * @brief Checks whether system time ready notification + * was received from hmi + * @return true if received otherwise false + */ + virtual bool IsSystemTimeProviderReady() const = 0; /** * @brief Notify all listeners that certificate update required @@ -150,6 +174,18 @@ class SecurityManager : public protocol_handler::ProtocolObserver { */ virtual void AddListener(SecurityManagerListener* const listener) = 0; virtual void RemoveListener(SecurityManagerListener* const listener) = 0; + + /** + * @brief OnCertificateUpdated allows to obtain notification when certificate + * has been updated with policy table update. Pass this certificate to crypto + * manager for further processing. Also process postopnes handshake for the + * certain connection key. + * + * @param data the certificates content. + * + * @return always true. + */ + virtual bool OnCertificateUpdated(const std::string& data) = 0; }; } // namespace security_manager #endif // SRC_COMPONENTS_INCLUDE_SECURITY_MANAGER_SECURITY_MANAGER_H_ diff --git a/src/components/include/security_manager/security_manager_listener.h b/src/components/include/security_manager/security_manager_listener.h index aeb3334a56..5942839b58 100644 --- a/src/components/include/security_manager/security_manager_listener.h +++ b/src/components/include/security_manager/security_manager_listener.h @@ -47,6 +47,12 @@ class SecurityManagerListener { */ virtual bool OnHandshakeDone(uint32_t connection_key, SSLContext::HandshakeResult result) = 0; + + /** + * @brief Notification about handshake failure + */ + virtual void OnHandshakeFailed() = 0; + /** * @brief Notify listeners that certificate update is required. */ diff --git a/src/components/include/security_manager/ssl_context.h b/src/components/include/security_manager/ssl_context.h index 86997edbd9..9d66e1af2f 100644 --- a/src/components/include/security_manager/ssl_context.h +++ b/src/components/include/security_manager/ssl_context.h @@ -81,10 +81,11 @@ class SSLContext { HandshakeContext(const custom_str::CustomString& exp_sn, const custom_str::CustomString& exp_cn) - : expected_sn(exp_sn), expected_cn(exp_cn) {} + : expected_sn(exp_sn), expected_cn(exp_cn), system_time(time(NULL)) {} custom_str::CustomString expected_sn; custom_str::CustomString expected_cn; + time_t system_time; }; virtual HandshakeResult StartHandshake(const uint8_t** const out_data, @@ -103,6 +104,14 @@ class SSLContext { size_t* out_data_size) = 0; virtual bool IsInitCompleted() const = 0; virtual bool IsHandshakePending() const = 0; + /** + * @brief GetCertificateDueDate gets certificate expiration date + * @param due_date - certificate expiration time to be received + * @return True if certificate expiration date received + * otherwise False + */ + virtual bool GetCertificateDueDate(time_t& due_date) const = 0; + virtual bool HasCertificate() const = 0; virtual size_t get_max_block_size(size_t mtu) const = 0; virtual std::string LastError() const = 0; 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 ed3a5088c1..c9f53b8606 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 @@ -206,7 +206,7 @@ class MockCacheManagerInterface : public CacheManagerInterface { MOCK_METHOD1(GetHMITypes, const policy_table::AppHMITypes*(const std::string& app_id)); MOCK_CONST_METHOD0(GetCertificate, std::string()); - MOCK_METHOD1(SetDecryptedCertificate, void(const std::string&)); + MOCK_CONST_METHOD1(SetDecryptedCertificate, void(const std::string&)); MOCK_METHOD1(GetGroups, const policy_table::Strings&(const PTString& app_id)); MOCK_CONST_METHOD2(AppHasHMIType, bool(const std::string& application_id, 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 79c2188cdf..e667911944 100644 --- a/src/components/include/test/protocol_handler/mock_protocol_handler.h +++ b/src/components/include/test/protocol_handler/mock_protocol_handler.h @@ -72,6 +72,7 @@ class MockProtocolHandler : public ::protocol_handler::ProtocolHandler { MOCK_METHOD2(NotifySessionStarted, void(const ::protocol_handler::SessionContext& context, std::vector& rejected_params)); + MOCK_METHOD0(NotifyOnFailedHandshake, void()); }; } // namespace protocol_handler_test } // namespace components diff --git a/src/components/include/test/security_manager/mock_crypto_manager.h b/src/components/include/test/security_manager/mock_crypto_manager.h index 55c364bd89..61ec5183e4 100644 --- a/src/components/include/test/security_manager/mock_crypto_manager.h +++ b/src/components/include/test/security_manager/mock_crypto_manager.h @@ -52,7 +52,9 @@ class MockCryptoManager : public ::security_manager::CryptoManager { MOCK_METHOD0(CreateSSLContext, ::security_manager::SSLContext*()); MOCK_METHOD1(ReleaseSSLContext, void(::security_manager::SSLContext*)); MOCK_CONST_METHOD0(LastError, std::string()); - MOCK_CONST_METHOD0(IsCertificateUpdateRequired, bool()); + MOCK_CONST_METHOD2(IsCertificateUpdateRequired, + bool(const time_t system_time, + const time_t certificates_time)); }; } // namespace security_manager_test } // namespace components diff --git a/src/components/include/test/security_manager/mock_security_manager.h b/src/components/include/test/security_manager/mock_security_manager.h index 11890cb071..153ce85422 100644 --- a/src/components/include/test/security_manager/mock_security_manager.h +++ b/src/components/include/test/security_manager/mock_security_manager.h @@ -54,8 +54,9 @@ class MockSecurityManager : public ::security_manager::SecurityManager { MOCK_METHOD4( SendInternalError, void(const uint32_t, const uint8_t&, const std::string&, const uint32_t)); - MOCK_METHOD1(CreateSSLContext, - ::security_manager::SSLContext*(const uint32_t&)); + MOCK_METHOD2(CreateSSLContext, + ::security_manager::SSLContext*(const uint32_t&, + ContextCreationStrategy)); MOCK_METHOD1(StartHandshake, void(uint32_t)); MOCK_METHOD1(AddListener, void(::security_manager::SecurityManagerListener*)); MOCK_METHOD1(RemoveListener, @@ -65,9 +66,12 @@ class MockSecurityManager : public ::security_manager::SecurityManager { void(const ::protocol_handler::RawMessagePtr)); MOCK_METHOD1(OnMobileMessageSent, void(const ::protocol_handler::RawMessagePtr)); - MOCK_METHOD0(IsCertificateUpdateRequired, bool()); + MOCK_METHOD1(IsCertificateUpdateRequired, bool(const uint32_t)); MOCK_METHOD0(NotifyOnCertificateUpdateRequired, void()); MOCK_METHOD0(IsPolicyCertificateDataEmpty, bool()); + MOCK_METHOD1(OnCertificateUpdated, bool(const std::string&)); + MOCK_METHOD1(PostponeHandshake, void(const uint32_t)); + MOCK_CONST_METHOD0(IsSystemTimeProviderReady, bool()); }; /* diff --git a/src/components/include/test/security_manager/mock_security_manager_listener.h b/src/components/include/test/security_manager/mock_security_manager_listener.h index a06762a09d..76273b244d 100644 --- a/src/components/include/test/security_manager/mock_security_manager_listener.h +++ b/src/components/include/test/security_manager/mock_security_manager_listener.h @@ -49,6 +49,7 @@ class MockSecurityManagerListener ::security_manager::SSLContext::HandshakeResult result)); MOCK_METHOD0(OnCertificateUpdateRequired, void()); MOCK_CONST_METHOD1(GetPolicyCertificateData, bool(std::string& data)); + MOCK_METHOD0(OnHandshakeFailed, void()); }; } // namespace security_manager_test } // namespace components diff --git a/src/components/include/test/security_manager/mock_ssl_context.h b/src/components/include/test/security_manager/mock_ssl_context.h index 6b6a26a226..02198d1d22 100644 --- a/src/components/include/test/security_manager/mock_ssl_context.h +++ b/src/components/include/test/security_manager/mock_ssl_context.h @@ -68,6 +68,8 @@ class MockSSLContext : public ::security_manager::SSLContext { MOCK_CONST_METHOD0(LastError, std::string()); MOCK_METHOD0(ResetConnection, void()); MOCK_METHOD1(SetHandshakeContext, void(const HandshakeContext& hsh_ctx)); + MOCK_CONST_METHOD0(HasCertificate, bool()); + MOCK_CONST_METHOD1(GetCertificateDueDate, bool(time_t& due_date)); }; } // namespace security_manager_test } // namespace components diff --git a/src/components/include/test/utils/mock_system_time_handler.h b/src/components/include/test/utils/mock_system_time_handler.h new file mode 100644 index 0000000000..ef80e698f5 --- /dev/null +++ b/src/components/include/test/utils/mock_system_time_handler.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, 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_TEST_SECURITY_MANAGER_MOCK_SYSTEM_TIME_HANDLER_H +#define SRC_COMPONENTS_INCLUDE_TEST_SECURITY_MANAGER_MOCK_SYSTEM_TIME_HANDLER_H + +#include "gmock/gmock.h" +#include "utils/system_time_handler.h" + +namespace test { +namespace components { +namespace security_manager_test { + +class MockSystemTimeHandler : public ::utils::SystemTimeHandler { + public: + MockSystemTimeHandler() {} + MOCK_METHOD0(QuerySystemTime, void()); + MOCK_METHOD1(SubscribeOnSystemTime, + void(utils::SystemTimeListener* listener)); + MOCK_METHOD1(UnSubscribeFromSystemTime, + void(utils::SystemTimeListener* listener)); + MOCK_METHOD0(GetUTCTime, time_t()); + MOCK_CONST_METHOD0(system_time_can_be_received, bool()); + ~MockSystemTimeHandler() {} + + private: + void DoSubscribe(utils::SystemTimeListener*) {} + void DoSystemTimeQuery() {} + void DoUnsubscribe(utils::SystemTimeListener* listener) {} + bool utc_time_can_be_received() const { + return true; + } + time_t FetchSystemTime() { + return 0; + } +}; +} // namespace security_manager_test +} // namespace components +} // namespace test +#endif // SRC_COMPONENTS_INCLUDE_TEST_SECURITY_MANAGER_MOCK_SYSTEM_TIME_HANDLER_H diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml index ab3933fc0f..5d46fce942 100644 --- a/src/components/interfaces/HMI_API.xml +++ b/src/components/interfaces/HMI_API.xml @@ -2747,6 +2747,16 @@ + + Allows to obtain current sytem time + + + + + + + HMI notifies SDL with this notification that NAVI module is ready to provide system time. + HMI must notify SDL about its readiness to start communication. In fact, this has to be the first message between SDL and HMI. 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 8c0acd44d2..f3fcfccd13 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -279,6 +279,12 @@ class CacheManager : public CacheManagerInterface { */ bool IsDefaultPolicy(const std::string& app_id) const OVERRIDE; + /** + * @brief Sets decrypted certificate in policy table + * @param certificate content of certificate + */ + void SetDecryptedCertificate(const std::string& certificate) const OVERRIDE; + /** * @brief SetIsDefault Sets is_default flag for application * @param app_id app specific application 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 9f7c7318db..842d8274eb 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 @@ -276,6 +276,13 @@ class CacheManagerInterface { */ virtual bool IsDefaultPolicy(const std::string& app_id) const = 0; + /** + * @brief Sets decrypted certificate in policy table + * @param certificate content of certificate + */ + virtual void SetDecryptedCertificate( + const std::string& certificate) const = 0; + /** * @brief SetIsDefault Sets is_default flag for application * @param app_id app specific application 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 941db1a67f..6329abbb04 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 @@ -570,6 +570,8 @@ class PolicyManagerImpl : public PolicyManager { */ bool HasCertificate() const OVERRIDE; + void SetDecryptedCertificate(const std::string& certificate) OVERRIDE; + /** * @brief Finds the next URL that must be sent on OnSystemRequest retry * @param urls vector of vectors that contain urls for each application diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index 6a142374d5..8390a232c3 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -1290,6 +1290,13 @@ bool CacheManager::IsDefaultPolicy(const std::string& app_id) const { return result; } +void CacheManager::SetDecryptedCertificate( + const std::string& certificate) const { + CACHE_MANAGER_CHECK_VOID(); + sync_primitives::AutoLock auto_lock(cache_lock_); + *pt_->policy_table.module_config.certificate = certificate; +} + bool CacheManager::SetIsDefault(const std::string& app_id) { CACHE_MANAGER_CHECK(false); sync_primitives::AutoLock auto_lock(cache_lock_); 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 39b303cbb5..305424ba4c 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -1021,6 +1021,13 @@ bool PolicyManagerImpl::HasCertificate() const { return !cache_->GetCertificate().empty(); } +void PolicyManagerImpl::SetDecryptedCertificate( + const std::string& certificate) { + LOG4CXX_AUTO_TRACE(logger_); + cache_->SetDecryptedCertificate(certificate); + cache_->Backup(); +} + class CallStatusChange : public utils::Callable { public: CallStatusChange(UpdateStatusManager& upd_manager, diff --git a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h index 0ef40290f2..5d536eebad 100644 --- a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h +++ b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h @@ -89,6 +89,13 @@ class HandshakeHandler : public security_manager::SecurityManagerListener { uint32_t connection_key, security_manager::SSLContext::HandshakeResult result) OVERRIDE; + /** + * @brief Notification about handshake failure + * Gets parameters from payload and processes + * handshake failure procedure + */ + void OnHandshakeFailed() OVERRIDE; + /** * @brief Notification that certificate update is required. */ 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 0efb81cdd7..4d86a78688 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 @@ -235,6 +235,8 @@ class ProtocolHandlerImpl uint8_t session_id, uint8_t service_type); + void NotifyOnFailedHandshake() OVERRIDE; + // TODO(Ezamakhov): move Ack/Nack as interface for StartSessionHandler /** * \brief Sends acknowledgement of starting session to mobile application @@ -686,7 +688,9 @@ class ProtocolHandlerImpl bool is_ptu_triggered_; std::list > ptu_pending_handlers_; + std::list > handshake_handlers_; sync_primitives::Lock ptu_handlers_lock_; + sync_primitives::Lock handshake_handlers_lock_; #endif // ENABLE_SECURITY // Thread that pumps non-parsed messages coming from mobile side. diff --git a/src/components/protocol_handler/src/handshake_handler.cc b/src/components/protocol_handler/src/handshake_handler.cc index 055ff2cf45..74987ac2bd 100644 --- a/src/components/protocol_handler/src/handshake_handler.cc +++ b/src/components/protocol_handler/src/handshake_handler.cc @@ -92,6 +92,17 @@ bool HandshakeHandler::GetPolicyCertificateData(std::string& data) const { void HandshakeHandler::OnCertificateUpdateRequired() {} +void HandshakeHandler::OnHandshakeFailed() { + BsonObject params; + if (payload_) { + params = bson_object_from_bytes(payload_.get()); + } else { + bson_object_initialize_default(¶ms); + } + ProcessFailedHandshake(params); + bson_object_deinitialize(¶ms); +} + bool HandshakeHandler::OnHandshakeDone( uint32_t connection_key, security_manager::SSLContext::HandshakeResult result) { diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index 762b986782..dcb7999ef9 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -149,6 +149,7 @@ ProtocolHandlerImpl::~ProtocolHandlerImpl() { "Not all observers have unsubscribed" " from ProtocolHandlerImpl"); } + handshake_handlers_.clear(); } void ProtocolHandlerImpl::AddProtocolObserver(ProtocolObserver* observer) { @@ -839,6 +840,18 @@ void ProtocolHandlerImpl::OnConnectionClosed( multiframe_builder_.RemoveConnection(connection_id); } +void ProtocolHandlerImpl::NotifyOnFailedHandshake() { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(handshake_handlers_lock_); + + std::for_each( + handshake_handlers_.begin(), + handshake_handlers_.end(), + std::bind(&HandshakeHandler::OnHandshakeFailed, std::placeholders::_1)); + + handshake_handlers_.clear(); +} + void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) { LOG4CXX_AUTO_TRACE(logger_); @@ -851,12 +864,14 @@ void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) { return; } - const bool is_cert_expired = security_manager_->IsCertificateUpdateRequired(); for (auto handler : ptu_pending_handlers_) { + const bool is_cert_expired = security_manager_->IsCertificateUpdateRequired( + handler->connection_key()); security_manager::SSLContext* ssl_context = - is_cert_expired - ? NULL - : security_manager_->CreateSSLContext(handler->connection_key()); + is_cert_expired ? NULL + : security_manager_->CreateSSLContext( + handler->connection_key(), + security_manager::SecurityManager::kUseExisting); if (!ssl_context) { const std::string error("CreateSSLContext failed"); @@ -1286,7 +1301,8 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( session_observer_.KeyFromPair(connection_id, session_id); security_manager::SSLContext* ssl_context = - security_manager_->CreateSSLContext(connection_key); + security_manager_->CreateSSLContext( + connection_key, security_manager::SecurityManager::kUseExisting); if (!ssl_context) { const std::string error("CreateSSLContext failed"); LOG4CXX_ERROR(logger_, error); @@ -1563,14 +1579,11 @@ void ProtocolHandlerImpl::NotifySessionStarted( context, packet->protocol_version(), bson_object_bytes); + handshake_handlers_.push_back(handler); const bool is_certificate_empty = security_manager_->IsPolicyCertificateDataEmpty(); - const bool is_certificate_expired = - is_certificate_empty || - security_manager_->IsCertificateUpdateRequired(); - if (context.is_ptu_required_ && is_certificate_empty) { LOG4CXX_DEBUG(logger_, "PTU for StartSessionHandler " @@ -1586,6 +1599,7 @@ void ProtocolHandlerImpl::NotifySessionStarted( ptu_pending_handlers_.push_back(handler); is_ptu_triggered_ = true; security_manager_->NotifyOnCertificateUpdateRequired(); + security_manager_->PostponeHandshake(connection_key); } else { LOG4CXX_DEBUG(logger_, "PTU has been triggered. Added to pending."); ptu_pending_handlers_.push_back(handler); @@ -1594,9 +1608,11 @@ void ProtocolHandlerImpl::NotifySessionStarted( } security_manager::SSLContext* ssl_context = - is_certificate_expired + is_certificate_empty ? NULL - : security_manager_->CreateSSLContext(connection_key); + : security_manager_->CreateSSLContext( + connection_key, + security_manager::SecurityManager::kUseExisting); if (!ssl_context) { const std::string error("CreateSSLContext failed"); LOG4CXX_ERROR(logger_, error); @@ -1630,10 +1646,18 @@ void ProtocolHandlerImpl::NotifySessionStarted( *fullVersion, *start_session_ack_params); } else { + LOG4CXX_DEBUG(logger_, "Adding Handshake handler to listenets:"); security_manager_->AddListener(new HandshakeHandler(*handler)); if (!ssl_context->IsHandshakePending()) { // Start handshake process security_manager_->StartHandshake(connection_key); + if (!security_manager_->IsSystemTimeProviderReady()) { + SendStartSessionNAck(context.connection_id_, + packet->session_id(), + protocol_version, + packet->service_type(), + rejected_params); + } } } LOG4CXX_DEBUG(logger_, 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 77de1705da..028c7ee332 100644 --- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc +++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc @@ -46,6 +46,7 @@ #include "security_manager/mock_ssl_context.h" #endif // ENABLE_SECURITY #include "transport_manager/mock_transport_manager.h" +#include "utils/mock_system_time_handler.h" #include "utils/make_shared.h" #include "utils/test_async_waiter.h" #include @@ -95,8 +96,12 @@ using protocol_handler::kBulk; using protocol_handler::kInvalidServiceType; // For TM states using transport_manager::TransportManagerListener; +using test::components::security_manager_test::MockSystemTimeHandler; using transport_manager::E_SUCCESS; using transport_manager::DeviceInfo; +// For security +using ContextCreationStrategy = + security_manager::SecurityManager::ContextCreationStrategy; // For CH entities using connection_handler::DeviceHandle; // Google Testing Framework Entities @@ -987,7 +992,10 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) { SetProtocolVersion2(); // Expect start protection for unprotected session - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, + CreateSSLContext(connection_key, + security_manager::SecurityManager:: + ContextCreationStrategy::kUseExisting)) . // Return fail protection WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), ReturnNull())); @@ -1042,7 +1050,7 @@ TEST_F(ProtocolHandlerImplTest, SetProtocolVersion2(); // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce( @@ -1119,7 +1127,7 @@ TEST_F(ProtocolHandlerImplTest, .WillOnce(ReturnRefOfCopy(services)); // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce(Return(&ssl_context_mock)); @@ -1198,7 +1206,7 @@ TEST_F(ProtocolHandlerImplTest, times++; // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce( @@ -1296,7 +1304,7 @@ TEST_F( times++; // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _)) . // Return new SSLContext WillOnce( @@ -1392,7 +1400,10 @@ TEST_F(ProtocolHandlerImplTest, times++; // call new SSLContext creation - EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key)) + EXPECT_CALL(security_manager_mock, + CreateSSLContext(connection_key, + security_manager::SecurityManager:: + ContextCreationStrategy::kUseExisting)) . // Return new SSLContext WillOnce( @@ -1420,27 +1431,37 @@ TEST_F(ProtocolHandlerImplTest, // Expect add listener for handshake result EXPECT_CALL(security_manager_mock, AddListener(_)) - // Emulate handshake fail - .WillOnce(Invoke(OnHandshakeDoneFunctor( - connection_key, - security_manager::SSLContext::Handshake_Result_Success))); + // Emulate handshake + .WillOnce( + DoAll(NotifyTestAsyncWaiter(&waiter), + Invoke(OnHandshakeDoneFunctor( + connection_key, + security_manager::SSLContext::Handshake_Result_Success)))); + times++; // Listener check SSLContext EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, start_service)) . // Emulate protection for service is not enabled - WillOnce(ReturnNull()); + WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), ReturnNull())); + times++; + + EXPECT_CALL(security_manager_mock, IsSystemTimeProviderReady()) + .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(true))); + times++; - // Expect service protection enable EXPECT_CALL(session_observer_mock, - SetProtectionFlag(connection_key, start_service)); + SetProtectionFlag(connection_key, start_service)) + .WillOnce(NotifyTestAsyncWaiter(&waiter)); + times++; - // Expect send Ack with PROTECTION_OFF (on fail handshake) + // Expect send Ack with PROTECTION_ON (on successfull handshake) EXPECT_CALL(transport_manager_mock, SendMessageToDevice( ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON))) .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS))); + times++; SendControlMessage( diff --git a/src/components/security_manager/include/security_manager/crypto_manager_impl.h b/src/components/security_manager/include/security_manager/crypto_manager_impl.h index 4e48858e5c..c31e02cf48 100644 --- a/src/components/security_manager/include/security_manager/crypto_manager_impl.h +++ b/src/components/security_manager/include/security_manager/crypto_manager_impl.h @@ -71,6 +71,8 @@ class CryptoManagerImpl : public CryptoManager { size_t* out_data_size) OVERRIDE; bool IsInitCompleted() const OVERRIDE; bool IsHandshakePending() const OVERRIDE; + bool GetCertificateDueDate(time_t& due_date) const OVERRIDE; + bool HasCertificate() const OVERRIDE; size_t get_max_block_size(size_t mtu) const OVERRIDE; std::string LastError() const OVERRIDE; void ResetConnection() OVERRIDE; @@ -101,6 +103,22 @@ class CryptoManagerImpl : public CryptoManager { std::string GetTextBy(X509_NAME* name, int object) const; + /** + * @brief Pulls number stored in buffer of chars + * and returns it as integer + * @param buf where symbols stored + * @param idx index of required char to be converted + * @return number in integer representation + */ + int get_number_from_char_buf(char* buf, int* idx) const; + /** + * @brief Converts time from ASN1 format (used in OpenSSL) + * to time_t data type + * @param time_to_convert time to be converted + * @return time in time_t format + */ + time_t convert_asn1_time_to_time_t(ASN1_TIME* time_to_convert) const; + SSL* connection_; BIO* bioIn_; BIO* bioOut_; @@ -128,15 +146,13 @@ class CryptoManagerImpl : public CryptoManager { SSLContext* CreateSSLContext() OVERRIDE; void ReleaseSSLContext(SSLContext* context) OVERRIDE; std::string LastError() const OVERRIDE; - virtual bool IsCertificateUpdateRequired() const OVERRIDE; + bool IsCertificateUpdateRequired( + const time_t system_time, const time_t certificates_time) const OVERRIDE; virtual const CryptoManagerSettings& get_settings() const OVERRIDE; private: bool set_certificate(const std::string& cert_data); - int pull_number_from_buf(char* buf, int* idx); - void asn1_time_to_tm(ASN1_TIME* time); - /** * @brief Sets initial certificate datetime */ diff --git a/src/components/security_manager/include/security_manager/security_manager_impl.h b/src/components/security_manager/include/security_manager/security_manager_impl.h index 469b97d1e1..ab093cc576 100644 --- a/src/components/security_manager/include/security_manager/security_manager_impl.h +++ b/src/components/security_manager/include/security_manager/security_manager_impl.h @@ -35,6 +35,8 @@ #include #include +#include +#include #include "utils/macro.h" #include "utils/message_queue.h" @@ -44,6 +46,7 @@ #include "security_manager/security_query.h" #include "protocol_handler/protocol_handler.h" #include "protocol/common.h" +#include "utils/system_time_handler.h" namespace security_manager { /** @@ -67,12 +70,21 @@ typedef threads::MessageLoopThread SecurityMessageLoop; * \brief SecurityManagerImpl class implements SecurityManager interface */ class SecurityManagerImpl : public SecurityManager, - public SecurityMessageLoop::Handler { + public SecurityMessageLoop::Handler, + public utils::SystemTimeListener { public: /** * \brief Constructor + * \param system_time_handler allows to work with system time. */ - SecurityManagerImpl(); + explicit SecurityManagerImpl( + std::unique_ptr&& system_time_handler); + + /** + * \brief Destructor + */ + ~SecurityManagerImpl(); + /** * \brief Add received from Mobile Application message * Overriden ProtocolObserver::OnMessageReceived method @@ -133,24 +145,41 @@ class SecurityManagerImpl : public SecurityManager, * identifier * @return new \c SSLContext or \c NULL on any error */ - SSLContext* CreateSSLContext(const uint32_t& connection_key) OVERRIDE; + SSLContext* CreateSSLContext(const uint32_t& connection_key, + ContextCreationStrategy cc_strategy) OVERRIDE; /** * \brief Start handshake as SSL client */ void StartHandshake(uint32_t connection_key) OVERRIDE; + /** + * @brief PostponeHandshake allows to postpone handshake. It notifies + * cryptomanager that certificate should be updated and adds specified + * connection key to the list of the certificate awaiting connections. + * @param connection_key the identifier for connection to postpone handshake. + */ + void PostponeHandshake(const uint32_t connection_key) OVERRIDE; + /** * @brief Checks whether certificate should be updated * @return true if certificate should be updated otherwise false */ - bool IsCertificateUpdateRequired() OVERRIDE; + bool IsCertificateUpdateRequired(const uint32_t connection_key) OVERRIDE; + + /** + * @brief Checks whether system time ready notification + * was received from hmi + * @return true if received otherwise false + */ + bool IsSystemTimeProviderReady() const OVERRIDE; /** * \brief Add/Remove for SecurityManagerListener */ void AddListener(SecurityManagerListener* const listener) OVERRIDE; void RemoveListener(SecurityManagerListener* const listener) OVERRIDE; + /** * \brief Notifiers for listeners * \param connection_key Unique key used by other components as session @@ -217,6 +246,39 @@ class SecurityManagerImpl : public SecurityManager, */ void SendQuery(const SecurityQuery& query, const uint32_t connection_key); + /** + * @brief OnCertificateUpdated allows to obtain notification when certificate + * has been updated with policy table update. Pass this certificate to crypto + * manager for further processing. Also process postopnes handshake for the + * certain connection key. + * + * @param data the certificates content. + * @return always true. + */ + bool OnCertificateUpdated(const std::string& data) OVERRIDE; + + /** + * @brief ResumeHandshake allows to resume handshake after certificate has + * been updated. + * @param connection_key the connection identifier to start handshake. + */ + void ResumeHandshake(uint32_t connection_key); + + /** + * @brief ProceedHandshake starts the handshake process. + * @param ssl_context ssl context for the handshake. COntains certificate, + * keys, etc. + * @param connection_key the connection identifier to process handshake. + */ + void ProceedHandshake(SSLContext* ssl_context, uint32_t connection_key); + + /** + * @brief OnSystemTimeArrived method which notifies + * crypto manager with updated time in order to check certificate validity + * @param utc_time the current system time. + */ + void OnSystemTimeArrived(const time_t utc_time) OVERRIDE; + // Thread that pumps handshake data SecurityMessageLoop security_messages_; @@ -235,7 +297,17 @@ class SecurityManagerImpl : public SecurityManager, /** *\brief List of listeners for notify handshake done result */ + std::list listeners_; + + std::unique_ptr system_time_handler_; + sync_primitives::Lock connections_lock_; + std::set awaiting_certificate_connections_; + std::set awaiting_time_connections_; + + mutable sync_primitives::Lock waiters_lock_; + volatile bool waiting_for_certificate_; + volatile bool waiting_for_time_; DISALLOW_COPY_AND_ASSIGN(SecurityManagerImpl); }; } // namespace security_manager diff --git a/src/components/security_manager/src/crypto_manager_impl.cc b/src/components/security_manager/src/crypto_manager_impl.cc index 6bee28a976..8db1d633a7 100644 --- a/src/components/security_manager/src/crypto_manager_impl.cc +++ b/src/components/security_manager/src/crypto_manager_impl.cc @@ -63,7 +63,12 @@ namespace { int debug_callback(int preverify_ok, X509_STORE_CTX* ctx) { if (!preverify_ok) { const int error = X509_STORE_CTX_get_error(ctx); - UNUSED(error); + if (error == X509_V_ERR_CERT_NOT_YET_VALID || + error == X509_V_ERR_CERT_HAS_EXPIRED) { + // return success result code instead of error because start + // and expiration cert dates will be checked by SDL + return 1; + } LOG4CXX_WARN(logger_, "Certificate verification failed with error " << error << " \"" << X509_verify_cert_error_string(error) @@ -264,24 +269,17 @@ std::string CryptoManagerImpl::LastError() const { return std::string(reason ? reason : ""); } -bool CryptoManagerImpl::IsCertificateUpdateRequired() const { +bool CryptoManagerImpl::IsCertificateUpdateRequired( + const time_t system_time, const time_t certificates_time) const { LOG4CXX_AUTO_TRACE(logger_); - const time_t cert_date = mktime(&expiration_time_); + const double seconds = difftime(certificates_time, system_time); - if (cert_date == -1) { - LOG4CXX_WARN(logger_, - "The certifiacte expiration time cannot be represented."); - return false; - } - const time_t now = time(NULL); - const double seconds = difftime(cert_date, now); + LOG4CXX_DEBUG( + logger_, "Certificate UTC time: " << asctime(gmtime(&certificates_time))); - LOG4CXX_DEBUG(logger_, - "Certificate expiration time: " << asctime(&expiration_time_)); - LOG4CXX_DEBUG(logger_, - "Host time: " << asctime(localtime(&now)) - << ". Seconds before expiration: " << seconds); + LOG4CXX_DEBUG(logger_, "Host UTC time: " << asctime(gmtime(&system_time))); + LOG4CXX_DEBUG(logger_, "Seconds before expiration: " << seconds); if (seconds < 0) { LOG4CXX_WARN(logger_, "Certificate is already expired."); return true; @@ -331,8 +329,6 @@ bool CryptoManagerImpl::set_certificate(const std::string& cert_data) { return false; } - asn1_time_to_tm(X509_get_notAfter(cert)); - if (!SSL_CTX_use_PrivateKey(context_, pkey)) { LOG4CXX_ERROR(logger_, "Could not use key: " << LastError()); return false; @@ -359,7 +355,8 @@ bool CryptoManagerImpl::set_certificate(const std::string& cert_data) { return true; } -int CryptoManagerImpl::pull_number_from_buf(char* buf, int* idx) { +int CryptoManagerImpl::SSLContextImpl::get_number_from_char_buf( + char* buf, int* idx) const { if (!idx) { return 0; } @@ -368,40 +365,6 @@ int CryptoManagerImpl::pull_number_from_buf(char* buf, int* idx) { return val; } -void CryptoManagerImpl::asn1_time_to_tm(ASN1_TIME* time) { - char* buf = (char*)time->data; - int index = 0; - const int year = pull_number_from_buf(buf, &index); - if (V_ASN1_GENERALIZEDTIME == time->type) { - expiration_time_.tm_year = - (year * 100 - 1900) + pull_number_from_buf(buf, &index); - } else { - expiration_time_.tm_year = year < 50 ? year + 100 : year; - } - - const int mon = pull_number_from_buf(buf, &index); - const int day = pull_number_from_buf(buf, &index); - const int hour = pull_number_from_buf(buf, &index); - const int mn = pull_number_from_buf(buf, &index); - - expiration_time_.tm_mon = mon - 1; - expiration_time_.tm_mday = day; - expiration_time_.tm_hour = hour; - expiration_time_.tm_min = mn; - - if (buf[index] == 'Z') { - expiration_time_.tm_sec = 0; - } - if ((buf[index] == '+') || (buf[index] == '-')) { - const int mn = pull_number_from_buf(buf, &index); - const int mn1 = pull_number_from_buf(buf, &index); - expiration_time_.tm_sec = (mn * 3600) + (mn1 * 60); - } else { - const int sec = pull_number_from_buf(buf, &index); - expiration_time_.tm_sec = sec; - } -} - void CryptoManagerImpl::InitCertExpTime() { strptime("1 Jan 1970 00:00:00", "%d %b %Y %H:%M:%S", &expiration_time_); } diff --git a/src/components/security_manager/src/security_manager_impl.cc b/src/components/security_manager/src/security_manager_impl.cc index 1853b218b4..d68e6b456e 100644 --- a/src/components/security_manager/src/security_manager_impl.cc +++ b/src/components/security_manager/src/security_manager_impl.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ford Motor Company + * Copyright (c) 2018, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,13 @@ */ #include "security_manager/security_manager_impl.h" +#include #include "security_manager/crypto_manager_impl.h" #include "protocol_handler/protocol_packet.h" #include "utils/logger.h" #include "utils/byte_order.h" #include "json/json.h" +#include "utils/helpers.h" namespace security_manager { @@ -44,11 +46,22 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "SecurityManager") static const char* kErrId = "id"; static const char* kErrText = "text"; -SecurityManagerImpl::SecurityManagerImpl() +SecurityManagerImpl::SecurityManagerImpl( + std::unique_ptr&& system_time_handler) : security_messages_("SecurityManager", this) , session_observer_(NULL) , crypto_manager_(NULL) - , protocol_handler_(NULL) {} + , protocol_handler_(NULL) + , system_time_handler_(std::move(system_time_handler)) + , waiting_for_certificate_(false) + , waiting_for_time_(false) { + DCHECK(system_time_handler_); + system_time_handler_->SubscribeOnSystemTime(this); +} + +SecurityManagerImpl::~SecurityManagerImpl() { + system_time_handler_->UnSubscribeFromSystemTime(this); +} void SecurityManagerImpl::OnMessageReceived( const ::protocol_handler::RawMessagePtr message) { @@ -136,16 +149,20 @@ void SecurityManagerImpl::Handle(const SecurityMessage message) { } security_manager::SSLContext* SecurityManagerImpl::CreateSSLContext( - const uint32_t& connection_key) { + const uint32_t& connection_key, ContextCreationStrategy cc_strategy) { LOG4CXX_INFO(logger_, "ProtectService processing"); DCHECK(session_observer_); DCHECK(crypto_manager_); - security_manager::SSLContext* ssl_context = session_observer_->GetSSLContext( - connection_key, protocol_handler::kControl); - // return exists SSLCOntext for current connection/session - if (ssl_context) { - return ssl_context; + security_manager::SSLContext* ssl_context = NULL; + if (kUseExisting == cc_strategy) { + security_manager::SSLContext* ssl_context = + session_observer_->GetSSLContext(connection_key, + protocol_handler::kControl); + // If SSLContext for current connection/session exists - return it + if (ssl_context) { + return ssl_context; + } } ssl_context = crypto_manager_->CreateSSLContext(); @@ -172,6 +189,40 @@ security_manager::SSLContext* SecurityManagerImpl::CreateSSLContext( return ssl_context; } +void SecurityManagerImpl::PostponeHandshake(const uint32_t connection_key) { + LOG4CXX_TRACE(logger_, "Handshake postponed"); + sync_primitives::AutoLock lock(connections_lock_); + if (waiting_for_certificate_) { + awaiting_certificate_connections_.insert(connection_key); + } + if (waiting_for_time_) { + awaiting_time_connections_.insert(connection_key); + } +} + +void SecurityManagerImpl::ResumeHandshake(uint32_t connection_key) { + LOG4CXX_TRACE(logger_, "Handshake resumed"); + + security_manager::SSLContext* ssl_context = + CreateSSLContext(connection_key, kForceRecreation); + + if (!ssl_context) { + LOG4CXX_WARN(logger_, + "Unable to resume handshake. No SSL context for key " + << connection_key); + return; + } + + ssl_context->ResetConnection(); + if (!ssl_context->HasCertificate()) { + NotifyListenersOnHandshakeDone(connection_key, + SSLContext::Handshake_Result_Fail); + return; + } + + ProceedHandshake(ssl_context, connection_key); +} + void SecurityManagerImpl::StartHandshake(uint32_t connection_key) { DCHECK(session_observer_); LOG4CXX_INFO(logger_, "StartHandshake: connection_key " << connection_key); @@ -187,6 +238,35 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) { SSLContext::Handshake_Result_Fail); return; } + if (!ssl_context->HasCertificate()) { + LOG4CXX_ERROR(logger_, "Security certificate is absent"); + sync_primitives::AutoLock lock(waiters_lock_); + waiting_for_certificate_ = true; + NotifyOnCertififcateUpdateRequired(); + } + + { + sync_primitives::AutoLock lock(waiters_lock_); + waiting_for_time_ = true; + } + + PostponeHandshake(connection_key); + system_time_handler_->QuerySystemTime(); +} + +bool SecurityManagerImpl::IsSystemTimeProviderReady() const { + return system_time_handler_->system_time_can_be_received(); +} + +void SecurityManagerImpl::ProceedHandshake( + security_manager::SSLContext* ssl_context, uint32_t connection_key) { + LOG4CXX_AUTO_TRACE(logger_); + if (!ssl_context) { + LOG4CXX_WARN(logger_, + "Unable to process handshake. No SSL context for key " + << connection_key); + return; + } if (ssl_context->IsInitCompleted()) { NotifyListenersOnHandshakeDone(connection_key, @@ -194,8 +274,33 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) { return; } - ssl_context->SetHandshakeContext( - session_observer_->GetHandshakeContext(connection_key)); + time_t cert_due_date; + if (!ssl_context->GetCertificateDueDate(cert_due_date)) { + LOG4CXX_ERROR(logger_, "Failed to get certificate due date!"); + return; + } + + if (crypto_manager_->IsCertificateUpdateRequired( + system_time_handler_->GetUTCTime(), cert_due_date)) { + LOG4CXX_DEBUG(logger_, "Host certificate update required"); + if (helpers::in_range(awaiting_certificate_connections_, connection_key)) { + NotifyListenersOnHandshakeDone(connection_key, + SSLContext::Handshake_Result_CertExpired); + return; + } + { + sync_primitives::AutoLock lock(waiters_lock_); + waiting_for_certificate_ = true; + } + PostponeHandshake(connection_key); + NotifyOnCertififcateUpdateRequired(); + return; + } + + SSLContext::HandshakeContext handshake_context = + session_observer_->GetHandshakeContext(connection_key); + handshake_context.system_time = system_time_handler_->GetUTCTime(); + ssl_context->SetHandshakeContext(handshake_context); size_t data_size = 0; const uint8_t* data = NULL; @@ -216,9 +321,21 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) { } } -bool SecurityManagerImpl::IsCertificateUpdateRequired() { +bool SecurityManagerImpl::IsCertificateUpdateRequired( + const uint32_t connection_key) { LOG4CXX_AUTO_TRACE(logger_); - return crypto_manager_->IsCertificateUpdateRequired(); + security_manager::SSLContext* ssl_context = + CreateSSLContext(connection_key, kUseExisting); + DCHECK_OR_RETURN(ssl_context, true); + LOG4CXX_DEBUG(logger_, + "Set SSL context to connection_key " << connection_key); + time_t cert_due_date; + if (!ssl_context->GetCertificateDueDate(cert_due_date)) { + LOG4CXX_ERROR(logger_, "Failed to get certificate due date!"); + return true; + } + return crypto_manager_->IsCertificateUpdateRequired( + system_time_handler_->GetUTCTime(), cert_due_date); } void SecurityManagerImpl::AddListener(SecurityManagerListener* const listener) { @@ -227,7 +344,6 @@ void SecurityManagerImpl::AddListener(SecurityManagerListener* const listener) { "Invalid (NULL) pointer to SecurityManagerListener."); return; } - LOG4CXX_DEBUG(logger_, "Adding listener " << listener); listeners_.push_back(listener); } @@ -241,6 +357,37 @@ void SecurityManagerImpl::RemoveListener( listeners_.remove(listener); } +bool SecurityManagerImpl::OnCertificateUpdated(const std::string& data) { + LOG4CXX_AUTO_TRACE(logger_); + { + sync_primitives::AutoLock lock(waiters_lock_); + waiting_for_certificate_ = false; + } + crypto_manager_->OnCertificateUpdated(data); + std::for_each( + awaiting_certificate_connections_.begin(), + awaiting_certificate_connections_.end(), + std::bind1st(std::mem_fun(&SecurityManagerImpl::ResumeHandshake), this)); + + std::set().swap(awaiting_certificate_connections_); + return true; +} + +void SecurityManagerImpl::OnSystemTimeArrived(const time_t utc_time) { + LOG4CXX_AUTO_TRACE(logger_); + { + sync_primitives::AutoLock lock(waiters_lock_); + waiting_for_time_ = false; + } + + std::for_each( + awaiting_time_connections_.begin(), + awaiting_time_connections_.end(), + std::bind1st(std::mem_fun(&SecurityManagerImpl::ResumeHandshake), this)); + + std::set().swap(awaiting_time_connections_); +} + void SecurityManagerImpl::NotifyListenersOnHandshakeDone( const uint32_t& connection_key, SSLContext::HandshakeResult error) { LOG4CXX_AUTO_TRACE(logger_); diff --git a/src/components/security_manager/src/ssl_context_impl.cc b/src/components/security_manager/src/ssl_context_impl.cc index 5be5ff8363..69e22dc44e 100644 --- a/src/components/security_manager/src/ssl_context_impl.cc +++ b/src/components/security_manager/src/ssl_context_impl.cc @@ -77,6 +77,7 @@ bool CryptoManagerImpl::SSLContextImpl::IsInitCompleted() const { SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::StartHandshake( const uint8_t** const out_data, size_t* out_data_size) { + LOG4CXX_AUTO_TRACE(logger_); is_handshake_pending_ = true; return DoHandshakeStep(NULL, 0, out_data, out_data_size); } @@ -174,6 +175,7 @@ const std::string CryptoManagerImpl::SSLContextImpl::RemoveDisallowedInfo( void CryptoManagerImpl::SSLContextImpl::PrintCertData( X509* cert, const std::string& cert_owner) { + LOG4CXX_AUTO_TRACE(logger_); if (!cert) { LOG4CXX_DEBUG(logger_, "Empty certificate data"); return; @@ -206,6 +208,7 @@ void CryptoManagerImpl::SSLContextImpl::PrintCertData( } void CryptoManagerImpl::SSLContextImpl::PrintCertInfo() { + LOG4CXX_AUTO_TRACE(logger_); PrintCertData(SSL_get_certificate(connection_), "HU's"); STACK_OF(X509)* peer_certs = SSL_get_peer_cert_chain(connection_); @@ -217,12 +220,42 @@ void CryptoManagerImpl::SSLContextImpl::PrintCertInfo() { SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::CheckCertContext() { + LOG4CXX_AUTO_TRACE(logger_); X509* cert = SSL_get_peer_certificate(connection_); if (!cert) { // According to the openssl documentation the peer certificate // might be ommitted for the SERVER but required for the cient. return CLIENT == mode_ ? Handshake_Result_Fail : Handshake_Result_Success; } + ASN1_TIME* notBefore = X509_get_notBefore(cert); + ASN1_TIME* notAfter = X509_get_notAfter(cert); + + time_t start = convert_asn1_time_to_time_t(notBefore); + time_t end = convert_asn1_time_to_time_t(notAfter); + + const double start_seconds = difftime(hsh_context_.system_time, start); + const double end_seconds = difftime(end, hsh_context_.system_time); + + if (start_seconds < 0) { + LOG4CXX_ERROR(logger_, + "Certificate is not yet valid. Time before validity " + << start_seconds << " seconds"); + return Handshake_Result_NotYetValid; + } else { + LOG4CXX_DEBUG(logger_, + "Time since certificate validity " << start_seconds + << "seconds"); + } + + if (end_seconds < 0) { + LOG4CXX_ERROR(logger_, + "Certificate already expired. Time after expiration " + << end_seconds << " seconds"); + return Handshake_Result_CertExpired; + } else { + LOG4CXX_DEBUG(logger_, + "Time until expiration " << end_seconds << "seconds"); + } X509_NAME* subj_name = X509_get_subject_name(cert); @@ -247,6 +280,47 @@ CryptoManagerImpl::SSLContextImpl::CheckCertContext() { return Handshake_Result_Success; } +time_t CryptoManagerImpl::SSLContextImpl::convert_asn1_time_to_time_t( + ASN1_TIME* time_to_convert) const { + struct tm cert_time; + memset(&cert_time, 0, sizeof(struct tm)); + // the minimum value for day of month is 1, otherwise exception will be thrown + cert_time.tm_mday = 1; + char* buf = reinterpret_cast(time_to_convert->data); + int index = 0; + const int year = get_number_from_char_buf(buf, &index); + if (V_ASN1_GENERALIZEDTIME == time_to_convert->type) { + cert_time.tm_year = + (year * 100 - 1900) + get_number_from_char_buf(buf, &index); + } else { + cert_time.tm_year = year < 50 ? year + 100 : year; + } + + const int mon = get_number_from_char_buf(buf, &index); + const int day = get_number_from_char_buf(buf, &index); + const int hour = get_number_from_char_buf(buf, &index); + const int mn = get_number_from_char_buf(buf, &index); + + cert_time.tm_mon = mon - 1; + cert_time.tm_mday = day; + cert_time.tm_hour = hour; + cert_time.tm_min = mn; + + if (buf[index] == 'Z') { + cert_time.tm_sec = 0; + } + if ((buf[index] == '+') || (buf[index] == '-')) { + const int mn = get_number_from_char_buf(buf, &index); + const int mn1 = get_number_from_char_buf(buf, &index); + cert_time.tm_sec = (mn * 3600) + (mn1 * 60); + } else { + const int sec = get_number_from_char_buf(buf, &index); + cert_time.tm_sec = sec; + } + + return mktime(&cert_time); +} + bool CryptoManagerImpl::SSLContextImpl::ReadHandshakeData( const uint8_t** const out_data, size_t* out_data_size) { LOG4CXX_AUTO_TRACE(logger_); @@ -288,7 +362,9 @@ bool CryptoManagerImpl::SSLContextImpl::WriteHandshakeData( SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::PerformHandshake() { + LOG4CXX_AUTO_TRACE(logger_); const int handshake_result = SSL_do_handshake(connection_); + LOG4CXX_TRACE(logger_, "Handshake result: " << handshake_result); if (handshake_result == 1) { const HandshakeResult result = CheckCertContext(); if (result != Handshake_Result_Success) { @@ -307,6 +383,7 @@ CryptoManagerImpl::SSLContextImpl::PerformHandshake() { is_handshake_pending_ = false; } else if (handshake_result == 0) { + LOG4CXX_DEBUG(logger_, "SSL handshake failed"); SSL_clear(connection_); is_handshake_pending_ = false; return Handshake_Result_Fail; @@ -447,6 +524,25 @@ bool CryptoManagerImpl::SSLContextImpl::IsHandshakePending() const { return is_handshake_pending_; } +bool CryptoManagerImpl::SSLContextImpl::GetCertificateDueDate( + time_t& due_date) const { + LOG4CXX_AUTO_TRACE(logger_); + + X509* cert = SSL_get_certificate(connection_); + if (!cert) { + LOG4CXX_DEBUG(logger_, "Get certificate failed."); + return false; + } + + due_date = convert_asn1_time_to_time_t(X509_get_notAfter(cert)); + + return true; +} + +bool CryptoManagerImpl::SSLContextImpl::HasCertificate() const { + return SSL_get_certificate(connection_) != NULL; +} + CryptoManagerImpl::SSLContextImpl::~SSLContextImpl() { SSL_shutdown(connection_); SSL_free(connection_); diff --git a/src/components/security_manager/test/crypto_manager_impl_test.cc b/src/components/security_manager/test/crypto_manager_impl_test.cc index b30684e5f6..fb645b175d 100644 --- a/src/components/security_manager/test/crypto_manager_impl_test.cc +++ b/src/components/security_manager/test/crypto_manager_impl_test.cc @@ -210,7 +210,10 @@ TEST_F(CryptoManagerTest, OnCertificateUpdated) { } TEST_F(CryptoManagerTest, OnCertificateUpdated_UpdateNotRequired) { + time_t system_time = 0; + time_t certificates_time = 1; size_t updates_before = 0; + SetInitialValues( security_manager::CLIENT, security_manager::TLSv1_2, kAllCiphers); ASSERT_TRUE(crypto_manager_->Init()); @@ -218,7 +221,8 @@ TEST_F(CryptoManagerTest, OnCertificateUpdated_UpdateNotRequired) { EXPECT_CALL(*mock_security_manager_settings_, update_before_hours()) .WillOnce(Return(updates_before)); - EXPECT_FALSE(crypto_manager_->IsCertificateUpdateRequired()); + EXPECT_FALSE(crypto_manager_->IsCertificateUpdateRequired(system_time, + certificates_time)); size_t max_updates_ = std::numeric_limits::max(); SetInitialValues( @@ -227,7 +231,8 @@ TEST_F(CryptoManagerTest, OnCertificateUpdated_UpdateNotRequired) { .WillOnce(Return(max_updates_)); ASSERT_TRUE(crypto_manager_->Init()); - EXPECT_TRUE(crypto_manager_->IsCertificateUpdateRequired()); + EXPECT_TRUE(crypto_manager_->IsCertificateUpdateRequired(system_time, + certificates_time)); } TEST_F(CryptoManagerTest, OnCertificateUpdated_NotInitialized) { diff --git a/src/components/security_manager/test/security_manager_test.cc b/src/components/security_manager/test/security_manager_test.cc index b334e78e19..4fe66498ea 100644 --- a/src/components/security_manager/test/security_manager_test.cc +++ b/src/components/security_manager/test/security_manager_test.cc @@ -44,6 +44,7 @@ #include "security_manager/mock_ssl_context.h" #include "security_manager/mock_crypto_manager.h" #include "security_manager/mock_security_manager_listener.h" +#include "utils/mock_system_time_handler.h" #include "utils/make_shared.h" #include "utils/test_async_waiter.h" @@ -95,8 +96,12 @@ const uint32_t kAsyncExpectationsTimeout = 10000u; class SecurityManagerTest : public ::testing::Test { protected: + SecurityManagerTest() + : mock_system_time_handler( + std::unique_ptr(new MockSystemTimeHandler())) + , security_manager_( + new SecurityManagerImpl(std::move(mock_system_time_handler))) {} void SetUp() OVERRIDE { - security_manager_.reset(new SecurityManagerImpl()); security_manager_->set_session_observer(&mock_session_observer); security_manager_->set_protocol_handler(&mock_protocol_handler); mock_sm_listener.reset(new testing::StrictMock< @@ -105,7 +110,7 @@ class SecurityManagerTest : public ::testing::Test { } void SetMockCryptoManager() { - EXPECT_CALL(mock_crypto_manager, IsCertificateUpdateRequired()) + EXPECT_CALL(mock_crypto_manager, IsCertificateUpdateRequired(_, _)) .WillRepeatedly(Return(false)); security_manager_->set_crypto_manager(&mock_crypto_manager); } @@ -152,8 +157,9 @@ class SecurityManagerTest : public ::testing::Test { EmulateMobileMessage(header, data, data_size); } } - ::utils::SharedPtr security_manager_; + // Strict mocks (same as all methods EXPECT_CALL().Times(0)) + testing::StrictMock mock_session_observer; testing::StrictMock @@ -166,6 +172,8 @@ class SecurityManagerTest : public ::testing::Test { mock_ssl_context_exists; std::unique_ptr > mock_sm_listener; + std::unique_ptr mock_system_time_handler; + std::shared_ptr security_manager_; }; // Test Bodies @@ -174,7 +182,6 @@ class SecurityManagerTest : public ::testing::Test { * and shall not call any methodes */ TEST_F(SecurityManagerTest, SetNULL_Intefaces) { - security_manager_.reset(new SecurityManagerImpl()); security_manager_->set_session_observer(NULL); security_manager_->set_protocol_handler(NULL); security_manager_->set_crypto_manager(NULL); @@ -398,7 +405,9 @@ TEST_F(SecurityManagerTest, CreateSSLContext_ServiceAlreadyProtected) { EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)) .WillOnce(Return(&mock_ssl_context_new)); - const SSLContext* result = security_manager_->CreateSSLContext(key); + const SSLContext* result = security_manager_->CreateSSLContext( + key, + security_manager::SecurityManager::ContextCreationStrategy::kUseExisting); EXPECT_EQ(&mock_ssl_context_new, result); } /* @@ -424,7 +433,9 @@ TEST_F(SecurityManagerTest, CreateSSLContext_ErrorCreateSSL) { .WillOnce(ReturnNull()); EXPECT_CALL(mock_crypto_manager, CreateSSLContext()).WillOnce(ReturnNull()); - const SSLContext* result = security_manager_->CreateSSLContext(key); + const SSLContext* result = security_manager_->CreateSSLContext( + key, + security_manager::SecurityManager::ContextCreationStrategy::kUseExisting); EXPECT_EQ(NULL, result); } /* @@ -457,7 +468,9 @@ TEST_F(SecurityManagerTest, CreateSSLContext_SetSSLContextError) { EXPECT_CALL(mock_session_observer, SetSSLContext(key, &mock_ssl_context_new)) .WillOnce(Return(SecurityManager::ERROR_UNKNOWN_INTERNAL_ERROR)); - const SSLContext* result = security_manager_->CreateSSLContext(key); + const SSLContext* result = security_manager_->CreateSSLContext( + key, + security_manager::SecurityManager::ContextCreationStrategy::kUseExisting); EXPECT_EQ(NULL, result); } /* @@ -470,7 +483,6 @@ TEST_F(SecurityManagerTest, CreateSSLContext_Success) { // Emulate SessionObserver and CryptoManager result EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)) - .WillOnce(ReturnNull()) . // additional check for debug code WillOnce(Return(&mock_ssl_context_exists)); @@ -479,7 +491,10 @@ TEST_F(SecurityManagerTest, CreateSSLContext_Success) { EXPECT_CALL(mock_session_observer, SetSSLContext(key, &mock_ssl_context_new)) .WillOnce(Return(SecurityManager::ERROR_SUCCESS)); - const SSLContext* result = security_manager_->CreateSSLContext(key); + const SSLContext* result = security_manager_->CreateSSLContext( + key, + security_manager::SecurityManager::ContextCreationStrategy:: + kForceRecreation); EXPECT_EQ(&mock_ssl_context_new, result); } /* @@ -521,109 +536,27 @@ TEST_F(SecurityManagerTest, StartHandshake_SSLInternalError) { uint32_t connection_id = 0; uint8_t session_id = 0; - // uint8_t protocol_version = 0; + EXPECT_CALL(mock_session_observer, PairFromKey(key, _, _)); - EXPECT_CALL(mock_session_observer, GetHandshakeContext(key)) - .WillOnce(Return(SSLContext::HandshakeContext())); EXPECT_CALL(mock_session_observer, ProtocolVersionUsed(connection_id, session_id, _)) .WillOnce(Return(true)); - - // Expect InternalError with ERROR_ID - EXPECT_CALL( - mock_protocol_handler, - SendMessageToMobileApp( - InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), is_final)); // Expect notifying listeners (unsuccess) EXPECT_CALL(*mock_sm_listener, OnHandshakeDone(key, SSLContext::Handshake_Result_Fail)) .WillOnce(Return(true)); - - // Emulate SessionObserver result EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)) - .WillOnce(Return(&mock_ssl_context_exists)); - EXPECT_CALL(mock_ssl_context_exists, IsInitCompleted()) - .WillOnce(Return(false)); - EXPECT_CALL(mock_ssl_context_exists, SetHandshakeContext(_)); - EXPECT_CALL(mock_ssl_context_exists, StartHandshake(_, _)) - .WillOnce(DoAll(SetArgPointee<0>(handshake_data_out_pointer), - SetArgPointee<1>(handshake_data_out_size), - Return(SSLContext::Handshake_Result_Fail))); + .WillOnce(ReturnNull()); + // Expect InternalError with ERROR_ID + EXPECT_CALL( + mock_protocol_handler, + SendMessageToMobileApp( + InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), is_final)); security_manager_->StartHandshake(key); - - // Listener was destroyed after OnHandshakeDone call mock_sm_listener.release(); } -/* - * Shall send data on call StartHandshake - */ -TEST_F(SecurityManagerTest, StartHandshake_SSLInitIsNotComplete) { - SetMockCryptoManager(); - uint32_t connection_id = 0; - uint8_t session_id = 0; - // uint8_t protocol_version = 0; - EXPECT_CALL(mock_session_observer, PairFromKey(key, _, _)); - EXPECT_CALL(mock_session_observer, GetHandshakeContext(key)) - .Times(3) - .WillRepeatedly(Return(SSLContext::HandshakeContext())); - EXPECT_CALL(mock_session_observer, - ProtocolVersionUsed(connection_id, session_id, _)) - .WillOnce(Return(true)); - // Expect send one message (with correct pointer and size data) - EXPECT_CALL(mock_protocol_handler, SendMessageToMobileApp(_, is_final)); - - // Return mock SSLContext - EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)) - .Times(3) - .WillRepeatedly(Return(&mock_ssl_context_exists)); - // Expect initialization check on each call StartHandshake - EXPECT_CALL(mock_ssl_context_exists, IsInitCompleted()) - .Times(3) - .WillRepeatedly(Return(false)); - EXPECT_CALL(mock_ssl_context_exists, SetHandshakeContext(_)).Times(3); - - // Emulate SSLContext::StartHandshake with different parameters - // Only on both correct - data and size shall be send message to mobile app - EXPECT_CALL(mock_ssl_context_exists, StartHandshake(_, _)) - .WillOnce(DoAll(SetArgPointee<0>(handshake_data_out_pointer), - SetArgPointee<1>(0), - Return(SSLContext::Handshake_Result_Success))) - .WillOnce(DoAll(SetArgPointee<0>((uint8_t*)NULL), - SetArgPointee<1>(handshake_data_out_size), - Return(SSLContext::Handshake_Result_Success))) - .WillOnce(DoAll(SetArgPointee<0>(handshake_data_out_pointer), - SetArgPointee<1>(handshake_data_out_size), - Return(SSLContext::Handshake_Result_Success))); - - security_manager_->StartHandshake(key); - security_manager_->StartHandshake(key); - security_manager_->StartHandshake(key); -} -/* - * Shall notify listeners on call StartHandshake after SSLContext initialization - * complete - */ -TEST_F(SecurityManagerTest, StartHandshake_SSLInitIsComplete) { - SetMockCryptoManager(); - // Expect no message send - // Expect notifying listeners (success) - EXPECT_CALL(*mock_sm_listener, - OnHandshakeDone(key, SSLContext::Handshake_Result_Success)) - .WillOnce(Return(true)); - - // Emulate SessionObserver result - EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)) - .WillOnce(Return(&mock_ssl_context_exists)); - EXPECT_CALL(mock_ssl_context_exists, IsInitCompleted()) - .WillOnce(Return(true)); - - security_manager_->StartHandshake(key); - - // Listener was destroyed after OnHandshakeDone call - mock_sm_listener.release(); -} /* * Shall send InternallError on * getting SEND_HANDSHAKE_DATA with NULL data diff --git a/src/components/security_manager/test/ssl_certificate_handshake_test.cc b/src/components/security_manager/test/ssl_certificate_handshake_test.cc index dc335c8da2..f6521c253a 100644 --- a/src/components/security_manager/test/ssl_certificate_handshake_test.cc +++ b/src/components/security_manager/test/ssl_certificate_handshake_test.cc @@ -335,6 +335,9 @@ class SSLHandshakeTest : public testing::Test { std::string client_certificate_; std::string client_ciphers_list_; std::string client_ca_certificate_path_; + + std::vector forced_protected_services_; + std::vector forced_unprotected_services_; }; TEST_F(SSLHandshakeTest, NoVerification) { diff --git a/src/components/utils/CMakeLists.txt b/src/components/utils/CMakeLists.txt index 51835c125a..b256a2fadc 100644 --- a/src/components/utils/CMakeLists.txt +++ b/src/components/utils/CMakeLists.txt @@ -38,6 +38,7 @@ include_directories ( ${COMPONENTS_DIR}/config_profile/include ${COMPONENTS_DIR}/media_manager/include ${COMPONENTS_DIR}/protocol_handler/include + ${JSONCPP_INCLUDE_DIRECTORY} ${LOG4CXX_INCLUDE_DIRECTORY} ) diff --git a/src/components/utils/include/utils/system_time_handler.h b/src/components/utils/include/utils/system_time_handler.h new file mode 100644 index 0000000000..99bbfa39e5 --- /dev/null +++ b/src/components/utils/include/utils/system_time_handler.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2018, 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_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_ +#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_ + +#include + +namespace utils { + +/** + * @brief The SystemTimeListener interface. + * This interface allows to get notifications whenever + * system time appears or fails to appear. + */ +class SystemTimeListener { + public: + /** + * @brief OnSystemTimeArrived Notify about system time + * in utc format + * @param utc_time current system time. + */ + virtual void OnSystemTimeArrived(const time_t utc_time) = 0; +}; + +/** + * @brief SystemTimeHandler the interface which provides the necessary + * public API to work with system time. The class does not implement + * any logic it's public api forwards call to the private virtual + * methods which are suppose to be defined within specific implementation. + */ +class SystemTimeHandler { + public: + /** + * @brief SystemTimeHandler creates an instance + * for this class. + */ + SystemTimeHandler(); + + /** + * @brief QuerySystemTime provides the public interface + * to retrieve the system time. Interface uses private implementation + * hence the logic will be defined within descendant class. + */ + void QuerySystemTime(); + + /** + * @brief SubscribeOnSystemTime allows to subscribe listener + * to the certain event. This class does not provide such storage. + * It rather uses private pure virtual function. So the final behaviour + * should be defined within the descendant class + */ + void SubscribeOnSystemTime(SystemTimeListener* listener); + + /** + * @brief UnSubscribeFromSystemTime allows to unsubscribe listener + * from the certain event. This class does not manipulate with storage. + * It rather uses private pure virtual function. So the final behaviour + * should be defined within the descendant class + */ + void UnSubscribeFromSystemTime(SystemTimeListener* listener); + + /** + * @brief GetUTCTime allows to obtain cached result for the + * GetSystemTime request + * @return utc time. + */ + time_t GetUTCTime(); + + /** + * @brief Checks if system time is ready + * and can be requested by GetSystemTime request + * @return True if HMI is ready to provide UTC time + * otherwise False + */ + bool system_time_can_be_received() const; + + /** + * @brief ~SystemTimeHandler destroys the object + */ + virtual ~SystemTimeHandler(); + + private: + /** + * @brief DoSystemTimeQuery responsible for the system time querying. + * It is up to implementator how exactly system is going to receive this time. + */ + virtual void DoSystemTimeQuery() = 0; + + /** + * @brief DoSubscribe implements the logic which allows to handle + * subscription process. The handling logic should be defined within + * descendant class. + */ + virtual void DoSubscribe(SystemTimeListener* listener) = 0; + + /** + * @brief DoUnsubscribe implements the logic which allows to handle + * unsubscription process. The handling logic should be defined within + * descendant class. + */ + virtual void DoUnsubscribe(SystemTimeListener* listener) = 0; + + /** + * @brief FetchSystemTime allows to obtain the cached result + * for the GetSystemTime request. + * @return utc time. + */ + virtual time_t FetchSystemTime() = 0; + + /** + * @brief Checks if UTC time is ready to provided by HMI + * and can be requested by GetSystemTime request + * @return True if HMI is ready to provide UTC time + * otherwise False + */ + virtual bool utc_time_can_be_received() const = 0; +}; + +} // namespace utils + +#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_ diff --git a/src/components/utils/src/system_time_handler.cc b/src/components/utils/src/system_time_handler.cc new file mode 100644 index 0000000000..ea04d1c0b9 --- /dev/null +++ b/src/components/utils/src/system_time_handler.cc @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018, 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 "utils/system_time_handler.h" +//#include + +namespace utils { + +SystemTimeHandler::SystemTimeHandler() {} + +SystemTimeHandler::~SystemTimeHandler() {} + +void SystemTimeHandler::QuerySystemTime() { + DoSystemTimeQuery(); +} + +void SystemTimeHandler::SubscribeOnSystemTime(SystemTimeListener* listener) { + DoSubscribe(listener); +} + +void SystemTimeHandler::UnSubscribeFromSystemTime( + SystemTimeListener* listener) { + DoUnsubscribe(listener); +} + +time_t SystemTimeHandler::GetUTCTime() { + return FetchSystemTime(); +} + +bool SystemTimeHandler::system_time_can_be_received() const { + return utc_time_can_be_received(); +} + +} // namespace utils -- cgit v1.2.1 From 75ce32ae1430ebdbdb0d52bedc2420a4462a3144 Mon Sep 17 00:00:00 2001 From: KVGrygoriev Date: Wed, 4 Apr 2018 17:38:32 +0300 Subject: Add Unit Tests: GetSystemTime Request/Response, OnSystemTimeReady --- .../basic_communication_get_system_time_request.h | 1 - .../basic_communication_get_system_time_response.h | 1 - .../hmi/on_system_time_ready_notification.h | 1 - ...c_communication_get_system_time_request_test.cc | 72 +++++++++++++++++++ ..._communication_get_system_time_response_test.cc | 79 +++++++++++++++++++++ .../hmi/on_system_time_ready_notification_test.cc | 80 ++++++++++++++++++++++ 6 files changed, 231 insertions(+), 3 deletions(-) create mode 100644 src/components/application_manager/test/commands/hmi/basic_communication_get_system_time_request_test.cc create mode 100644 src/components/application_manager/test/commands/hmi/basic_communication_get_system_time_response_test.cc create mode 100644 src/components/application_manager/test/commands/hmi/on_system_time_ready_notification_test.cc (limited to 'src') diff --git a/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h index 1638b2f51b..1dd0d8c6bb 100644 --- a/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h +++ b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h @@ -55,7 +55,6 @@ class BasicCommunicationGetSystemTimeRequest : public RequestToHMI { BasicCommunicationGetSystemTimeRequest( const MessageSharedPtr& message, ApplicationManager& application_manager); - private: /** * @brief onTimeOut allows to handle case when * system does not respond for certain request in diff --git a/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h index 1bf7447c7d..5e9ae4b1bb 100644 --- a/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h +++ b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h @@ -58,7 +58,6 @@ class BasicCommunicationGetSystemTimeResponse : public ResponseFromHMI { BasicCommunicationGetSystemTimeResponse( const MessageSharedPtr& message, ApplicationManager& application_manager); - private: /** * @brief Run takes the message obtained from the HMI and * sends this data to the subscribed on certain event class diff --git a/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h b/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h index 9b8763da42..c3031da809 100644 --- a/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h +++ b/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h @@ -61,7 +61,6 @@ class OnSystemTimeReadyNotification : public NotificationFromHMI { */ ~OnSystemTimeReadyNotification(); - private: /** * @brief Run creates SystemTimeReady event * and notifies all the subscribers. diff --git a/src/components/application_manager/test/commands/hmi/basic_communication_get_system_time_request_test.cc b/src/components/application_manager/test/commands/hmi/basic_communication_get_system_time_request_test.cc new file mode 100644 index 0000000000..e6a6bf0365 --- /dev/null +++ b/src/components/application_manager/test/commands/hmi/basic_communication_get_system_time_request_test.cc @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018 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 names of the copyright holders 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/commands/hmi/basic_communication_get_system_time_request.h" + +#include "gtest/gtest.h" +#include "utils/shared_ptr.h" +#include "application_manager/commands/command_request_test.h" +#include "protocol_handler/mock_protocol_handler.h" + +namespace test { +namespace components { +namespace commands_test { +namespace hmi_commands_test { +namespace basic_communication_get_system_time_request { + +using ::testing::ReturnRef; +namespace am = ::application_manager; +using am::commands::MessageSharedPtr; +using am::commands::BasicCommunicationGetSystemTimeRequest; +using namespace ::protocol_handler; + +class BasicCommunicationGetSystemTimeRequestTest + : public CommandRequestTest {}; + +TEST_F(BasicCommunicationGetSystemTimeRequestTest, OnTimeout) { + MessageSharedPtr msg = CreateMessage(); + protocol_handler_test::MockProtocolHandler mock_protocol_handler; + + auto command = CreateCommand(msg); + + ON_CALL(app_mngr_, protocol_handler()) + .WillByDefault(ReturnRef(mock_protocol_handler)); + EXPECT_CALL(mock_protocol_handler, NotifyOnFailedHandshake()); + + command->onTimeOut(); +} + +} // namespace basic_communication_get_system_time_request +} // namespace hmi_commands_test +} // namespace commands_test +} // namespace components +} // namespace test diff --git a/src/components/application_manager/test/commands/hmi/basic_communication_get_system_time_response_test.cc b/src/components/application_manager/test/commands/hmi/basic_communication_get_system_time_response_test.cc new file mode 100644 index 0000000000..e4d4572bc1 --- /dev/null +++ b/src/components/application_manager/test/commands/hmi/basic_communication_get_system_time_response_test.cc @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018 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 names of the copyright holders 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 "gtest/gtest.h" +#include "application_manager/commands/commands_test.h" +#include "application_manager/commands/hmi/basic_communication_get_system_time_response.h" +#include "application_manager/mock_application_manager.h" +#include "application_manager/mock_event_dispatcher.h" +#include "application_manager/smart_object_keys.h" +#include "interfaces/HMI_API.h" + +namespace test { +namespace components { +namespace commands_test { +namespace hmi_commands_test { +namespace basic_communication_get_system_time_response { + +using application_manager::commands::BasicCommunicationGetSystemTimeResponse; +using test::components::event_engine_test::MockEventDispatcher; +using testing::ReturnRef; + +ACTION_P(GetEventId, event_id) { + *event_id = arg0.id(); +} + +class BasicCommunicationGetSystemTimeResponseTest + : public CommandsTest {}; + +TEST_F(BasicCommunicationGetSystemTimeResponseTest, Run_SUCCESS) { + MessageSharedPtr msg = CreateMessage(); + MockEventDispatcher mock_event_dispatcher; + int32_t event_id = hmi_apis::FunctionID::INVALID_ENUM; + + auto command(CreateCommand(msg)); + + EXPECT_CALL(app_mngr_, event_dispatcher()) + .WillOnce(ReturnRef(mock_event_dispatcher)); + EXPECT_CALL(mock_event_dispatcher, raise_event(_)) + .WillOnce(GetEventId(&event_id)); + + command->Run(); + + EXPECT_EQ(hmi_apis::FunctionID::BasicCommunication_GetSystemTime, event_id); +} + +} // namespace basic_communication_get_system_time_response +} // namespace hmi_commands_test +} // namespace commands_test +} // namespace components +} // namespace test diff --git a/src/components/application_manager/test/commands/hmi/on_system_time_ready_notification_test.cc b/src/components/application_manager/test/commands/hmi/on_system_time_ready_notification_test.cc new file mode 100644 index 0000000000..35750496c8 --- /dev/null +++ b/src/components/application_manager/test/commands/hmi/on_system_time_ready_notification_test.cc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018 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 names of the copyright holders 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 "gtest/gtest.h" +#include "application_manager/commands/commands_test.h" +#include "application_manager/commands/hmi/on_system_time_ready_notification.h" +#include "application_manager/mock_application_manager.h" +#include "application_manager/mock_event_dispatcher.h" +#include "application_manager/smart_object_keys.h" +#include "interfaces/HMI_API.h" + +namespace test { +namespace components { +namespace commands_test { +namespace hmi_commands_test { +namespace on_system_time_ready_notification { + +using application_manager::commands::OnSystemTimeReadyNotification; +using test::components::event_engine_test::MockEventDispatcher; +using testing::ReturnRef; + +class OnSystemTimeReadyNotificationTest + : public CommandsTest {}; + +ACTION_P(GetEventId, event_id) { + *event_id = arg0.id(); +} + +TEST_F(OnSystemTimeReadyNotificationTest, Run_SUCCESS) { + int32_t event_id = hmi_apis::FunctionID::INVALID_ENUM; + MessageSharedPtr msg = CreateMessage(); + MockEventDispatcher mock_event_dispatcher; + + auto command(CreateCommand(msg)); + + EXPECT_CALL(app_mngr_, event_dispatcher()) + .WillOnce(ReturnRef(mock_event_dispatcher)); + EXPECT_CALL(mock_event_dispatcher, raise_event(_)) + .WillOnce(GetEventId(&event_id)); + + command->Run(); + + EXPECT_EQ(hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady, + event_id); +} + +} // namespace on_system_time_ready_notification +} // namespace hmi_commands_test +} // namespace commands_test +} // namespace components +} // namespace test -- cgit v1.2.1 From 2f93ba5c58812ff714f63b0cb219b3dc3017b021 Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Fri, 25 May 2018 20:28:44 +0300 Subject: Additional fixes after ATF testing Fixed OnCertificateUpdated notification callback for empty certificate Fixed GetSystemTime triggering Fixed handshake resuming on system time arrived Fixed wrong logic in case system time is not ready Removed redundant logic for non-navi applications Removed PTU triggerring for navi on empty certificate in DB --- .../application_manager/application_manager_impl.h | 9 +- .../system_time/system_time_handler_impl.h | 11 +- .../src/application_manager_impl.cc | 3 +- .../src/system_time/system_time_handler_impl.cc | 16 +-- .../src/connection_handler_impl.cc | 8 -- .../include/protocol_handler/session_observer.h | 7 +- .../include/security_manager/security_manager.h | 5 + .../security_manager/security_manager_listener.h | 3 +- .../policy_external/src/policy_manager_impl.cc | 16 +-- .../policy_regular/src/policy_manager_impl.cc | 13 +-- .../include/protocol_handler/handshake_handler.h | 5 +- .../protocol_handler/protocol_handler_impl.h | 6 -- .../protocol_handler/src/handshake_handler.cc | 3 +- .../protocol_handler/src/protocol_handler_impl.cc | 111 +++------------------ .../security_manager/security_manager_impl.h | 5 + .../security_manager/src/security_manager_impl.cc | 16 ++- 16 files changed, 76 insertions(+), 161 deletions(-) (limited to 'src') diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index d3fe69efcb..af096aa354 100644 --- a/src/components/application_manager/include/application_manager/application_manager_impl.h +++ b/src/components/application_manager/include/application_manager/application_manager_impl.h @@ -958,12 +958,11 @@ class ApplicationManagerImpl security_manager::SSLContext::HandshakeResult result) OVERRIDE; /** - * @brief OnHandshakeFailed currently does nothing. - * This method is declared as pure virtual in common base class - * therefore it has to be present and should be implemented - * to allow creation of current class instances + * @brief Notification about handshake failure + * @return true on success notification handling or false otherwise */ - void OnHandshakeFailed() OVERRIDE; + bool OnHandshakeFailed() OVERRIDE; + /** * @brief Notification that certificate update is required. */ diff --git a/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h b/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h index 28ba629e19..add440ad80 100644 --- a/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h +++ b/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h @@ -140,10 +140,13 @@ class SystemTimeHandlerImpl : public utils::SystemTimeHandler, mutable sync_primitives::Lock state_lock_; // Variable means HMI readiness to provide system time by request volatile bool utc_time_can_be_received_; - // Varible used to schedule next GetSystemTime request - // if at the moment of sending first GetSystemTime request - // HMI is not ready to provide system time - volatile bool schedule_request_; + + /** + * @brief Flag used to control that only GetSystemTime request at time could + * be sent to HMI + */ + volatile bool awaiting_get_system_time_; + // Varible used to store result for GetSystemTime request time_t last_time_; diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 5aa72d77e5..8d372f4fd2 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -1691,8 +1691,9 @@ bool ApplicationManagerImpl::OnHandshakeDone( return false; } -void ApplicationManagerImpl::OnHandshakeFailed() { +bool ApplicationManagerImpl::OnHandshakeFailed() { LOG4CXX_AUTO_TRACE(logger_); + return false; } void ApplicationManagerImpl::OnCertificateUpdateRequired() { diff --git a/src/components/application_manager/src/system_time/system_time_handler_impl.cc b/src/components/application_manager/src/system_time/system_time_handler_impl.cc index a91fb16197..6ae6d3e901 100644 --- a/src/components/application_manager/src/system_time/system_time_handler_impl.cc +++ b/src/components/application_manager/src/system_time/system_time_handler_impl.cc @@ -45,7 +45,7 @@ SystemTimeHandlerImpl::SystemTimeHandlerImpl( ApplicationManager& application_manager) : event_engine::EventObserver(application_manager.event_dispatcher()) , utc_time_can_be_received_(false) - , schedule_request_(false) + , awaiting_get_system_time_(false) , system_time_listener_(NULL) , app_manager_(application_manager) { LOG4CXX_AUTO_TRACE(logger_); @@ -67,7 +67,6 @@ void SystemTimeHandlerImpl::DoSystemTimeQuery() { LOG4CXX_INFO(logger_, "Navi module is not yet ready." << "Will process request once it became ready."); - schedule_request_ = true; return; } SendTimeRequest(); @@ -99,11 +98,18 @@ bool SystemTimeHandlerImpl::utc_time_can_be_received() const { void SystemTimeHandlerImpl::SendTimeRequest() { LOG4CXX_AUTO_TRACE(logger_); + + if (awaiting_get_system_time_) { + LOG4CXX_WARN(logger_, "Another GetSystemTime request in progress. Skipped"); + return; + } + using namespace application_manager; uint32_t correlation_id = app_manager_.GetNextHMICorrelationID(); subscribe_on_event(hmi_apis::FunctionID::BasicCommunication_GetSystemTime, correlation_id); MessageHelper::SendGetSystemTimeRequest(correlation_id, app_manager_); + awaiting_get_system_time_ = true; } void SystemTimeHandlerImpl::on_event( @@ -128,10 +134,6 @@ void SystemTimeHandlerImpl::ProcessSystemTimeReadyNotification() { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock lock(state_lock_); utc_time_can_be_received_ = true; - if (schedule_request_) { - SendTimeRequest(); - schedule_request_ = false; - } unsubscribe_from_event( hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady); } @@ -164,6 +166,8 @@ void SystemTimeHandlerImpl::ProcessSystemTimeResponse( if (system_time_listener_) { system_time_listener_->OnSystemTimeArrived(last_time_); } + sync_primitives::AutoLock state_lock(state_lock_); + awaiting_get_system_time_ = false; } } // namespace application_manager diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index b97c6eacd4..59865ac4b2 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -467,14 +467,6 @@ void ConnectionHandlerImpl::OnSessionStartedCallback( const uint32_t session_key = KeyFromPair(connection_handle, context.new_session_id_); - uint32_t app_id = 0; - GetDataOnSessionKey( - session_key, &app_id, NULL, static_cast(NULL)); - if (app_id > 0) { - context.is_ptu_required_ = - !connection_handler_observer_->CheckAppIsNavi(app_id); - } - { sync_primitives::AutoLock auto_lock(start_service_context_map_lock_); start_service_context_map_[session_key] = context; diff --git a/src/components/include/protocol_handler/session_observer.h b/src/components/include/protocol_handler/session_observer.h index 3482c6569c..242775bf25 100644 --- a/src/components/include/protocol_handler/session_observer.h +++ b/src/components/include/protocol_handler/session_observer.h @@ -66,7 +66,6 @@ struct SessionContext { uint32_t hash_id_; bool is_protected_; bool is_new_service_; - bool is_ptu_required_; /** * @brief Constructor @@ -78,8 +77,7 @@ struct SessionContext { , service_type_(protocol_handler::kInvalidServiceType) , hash_id_(0) , is_protected_(false) - , is_new_service_(false) - , is_ptu_required_(false) {} + , is_new_service_(false) {} /** * @brief Constructor @@ -105,8 +103,7 @@ struct SessionContext { , service_type_(service_type) , hash_id_(hash_id) , is_protected_(is_protected) - , is_new_service_(false) - , is_ptu_required_(false) {} + , is_new_service_(false) {} }; /** diff --git a/src/components/include/security_manager/security_manager.h b/src/components/include/security_manager/security_manager.h index 6ad5e96989..61ba43c74f 100644 --- a/src/components/include/security_manager/security_manager.h +++ b/src/components/include/security_manager/security_manager.h @@ -163,6 +163,11 @@ class SecurityManager : public protocol_handler::ProtocolObserver, */ virtual void NotifyOnCertificateUpdateRequired() = 0; + /** + * @brief Notify all listeners that handshake was failed + */ + virtual void NotifyListenersOnHandshakeFailed() = 0; + /** * @brief Check if policy certificate data is empty * @return true if policy certificate data is empty otherwise false diff --git a/src/components/include/security_manager/security_manager_listener.h b/src/components/include/security_manager/security_manager_listener.h index 5942839b58..00a4c68134 100644 --- a/src/components/include/security_manager/security_manager_listener.h +++ b/src/components/include/security_manager/security_manager_listener.h @@ -50,8 +50,9 @@ class SecurityManagerListener { /** * @brief Notification about handshake failure + * @return true on success notification handling or false otherwise */ - virtual void OnHandshakeFailed() = 0; + virtual bool OnHandshakeFailed() = 0; /** * @brief Notify listeners that certificate update is required. 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 2cd0d2b23b..f84df92dba 100644 --- a/src/components/policy/policy_external/src/policy_manager_impl.cc +++ b/src/components/policy/policy_external/src/policy_manager_impl.cc @@ -588,8 +588,7 @@ void PolicyManagerImpl::CheckPermissions(const PTString& app_id, policy_table::FunctionalGroupings functional_groupings; cache_->GetFunctionalGroupings(functional_groupings); - policy_table::Strings app_groups = - GetGroupsNames(app_group_permissions); + policy_table::Strings app_groups = GetGroupsNames(app_group_permissions); // Undefined groups (without user consent) disallowed by default, since // OnPermissionsChange notification has no "undefined" section @@ -621,8 +620,7 @@ void PolicyManagerImpl::CheckPermissions(const PTString& app_id, } const bool known_rpc = rpc_permissions.end() != rpc_permissions.find(rpc); - LOG4CXX_DEBUG(logger_, "Is known rpc " << - (known_rpc ? "true" : "false") ); + LOG4CXX_DEBUG(logger_, "Is known rpc " << (known_rpc ? "true" : "false")); if (!known_rpc) { // RPC not found in list == disallowed by backend result.hmi_level_permitted = kRpcDisallowed; @@ -644,7 +642,9 @@ void PolicyManagerImpl::CheckPermissions(const PTString& app_id, rpc_permissions[rpc].hmi_permissions[kUserDisallowedKey].find( hmi_level)) { // RPC found in allowed == allowed by backend, but disallowed by user - LOG4CXX_DEBUG(logger_, "RPC found in allowed == allowed by backend, but disallowed by user"); + LOG4CXX_DEBUG( + logger_, + "RPC found in allowed == allowed by backend, but disallowed by user"); result.hmi_level_permitted = kRpcUserDisallowed; } else { LOG4CXX_DEBUG(logger_, @@ -984,7 +984,6 @@ void PolicyManagerImpl::SetUserConsentForApp( const PermissionConsent& permissions, const NotificationMode mode) { LOG4CXX_AUTO_TRACE(logger_); - cache_->ResetCalculatedPermissions(); PermissionConsent verified_permissions = EnsureCorrectPermissionConsent(permissions); @@ -1767,11 +1766,6 @@ StatusNotifier PolicyManagerImpl::AddApplication( device_consent); } else { PromoteExistedApplication(application_id, device_consent); - if (helpers::in_range(hmi_types, policy_table::AHT_NAVIGATION) && - !HasCertificate()) { - LOG4CXX_DEBUG(logger_, "Certificate does not exist, scheduling update."); - update_status_manager_.ScheduleUpdate(); - } return utils::MakeShared(); } } 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 305424ba4c..4feae19a2a 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -213,10 +213,8 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, return false; } - if (pt_update->policy_table.module_config.certificate.is_initialized()) { - listener_->OnCertificateUpdated( - *(pt_update->policy_table.module_config.certificate)); - } + listener_->OnCertificateUpdated( + *(pt_update->policy_table.module_config.certificate)); std::map app_hmi_types; cache_->GetHMIAppTypeAfterUpdate(app_hmi_types); @@ -1057,13 +1055,6 @@ StatusNotifier PolicyManagerImpl::AddApplication( device_consent); } else { PromoteExistedApplication(application_id, device_consent); - const policy_table::AppHMIType type = policy_table::AHT_NAVIGATION; - if (helpers::in_range(hmi_types, - (rpc::Enum)type) && - !HasCertificate()) { - LOG4CXX_DEBUG(logger_, "Certificate does not exist, scheduling update."); - update_status_manager_.ScheduleUpdate(); - } return utils::MakeShared(); } } diff --git a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h index 5d536eebad..2d7d5c148c 100644 --- a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h +++ b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h @@ -91,10 +91,9 @@ class HandshakeHandler : public security_manager::SecurityManagerListener { /** * @brief Notification about handshake failure - * Gets parameters from payload and processes - * handshake failure procedure + * @return true on success notification handling or false otherwise */ - void OnHandshakeFailed() OVERRIDE; + bool OnHandshakeFailed() OVERRIDE; /** * @brief Notification that certificate update is required. 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 4d86a78688..e03e29d9bc 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 @@ -685,12 +685,6 @@ class ProtocolHandlerImpl #ifdef ENABLE_SECURITY security_manager::SecurityManager* security_manager_; - - bool is_ptu_triggered_; - std::list > ptu_pending_handlers_; - std::list > handshake_handlers_; - sync_primitives::Lock ptu_handlers_lock_; - sync_primitives::Lock handshake_handlers_lock_; #endif // ENABLE_SECURITY // Thread that pumps non-parsed messages coming from mobile side. diff --git a/src/components/protocol_handler/src/handshake_handler.cc b/src/components/protocol_handler/src/handshake_handler.cc index 74987ac2bd..24c3127743 100644 --- a/src/components/protocol_handler/src/handshake_handler.cc +++ b/src/components/protocol_handler/src/handshake_handler.cc @@ -92,7 +92,7 @@ bool HandshakeHandler::GetPolicyCertificateData(std::string& data) const { void HandshakeHandler::OnCertificateUpdateRequired() {} -void HandshakeHandler::OnHandshakeFailed() { +bool HandshakeHandler::OnHandshakeFailed() { BsonObject params; if (payload_) { params = bson_object_from_bytes(payload_.get()); @@ -101,6 +101,7 @@ void HandshakeHandler::OnHandshakeFailed() { } ProcessFailedHandshake(params); bson_object_deinitialize(¶ms); + return true; } bool HandshakeHandler::OnHandshakeDone( diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index dcb7999ef9..4cc4f883f0 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -75,7 +75,6 @@ ProtocolHandlerImpl::ProtocolHandlerImpl( , #ifdef ENABLE_SECURITY security_manager_(NULL) - , is_ptu_triggered_(false) , #endif // ENABLE_SECURITY raw_ford_messages_from_mobile_( @@ -149,7 +148,6 @@ ProtocolHandlerImpl::~ProtocolHandlerImpl() { "Not all observers have unsubscribed" " from ProtocolHandlerImpl"); } - handshake_handlers_.clear(); } void ProtocolHandlerImpl::AddProtocolObserver(ProtocolObserver* observer) { @@ -842,70 +840,10 @@ void ProtocolHandlerImpl::OnConnectionClosed( void ProtocolHandlerImpl::NotifyOnFailedHandshake() { LOG4CXX_AUTO_TRACE(logger_); - sync_primitives::AutoLock lock(handshake_handlers_lock_); - - std::for_each( - handshake_handlers_.begin(), - handshake_handlers_.end(), - std::bind(&HandshakeHandler::OnHandshakeFailed, std::placeholders::_1)); - - handshake_handlers_.clear(); + security_manager_->NotifyListenersOnHandshakeFailed(); } -void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) { - LOG4CXX_AUTO_TRACE(logger_); - -#ifdef ENABLE_SECURITY - sync_primitives::AutoLock lock(ptu_handlers_lock_); - - if (!is_ptu_triggered_) { - LOG4CXX_ERROR(logger_, - "PTU was not triggered by service starting. Ignored"); - return; - } - - for (auto handler : ptu_pending_handlers_) { - const bool is_cert_expired = security_manager_->IsCertificateUpdateRequired( - handler->connection_key()); - security_manager::SSLContext* ssl_context = - is_cert_expired ? NULL - : security_manager_->CreateSSLContext( - handler->connection_key(), - security_manager::SecurityManager::kUseExisting); - - if (!ssl_context) { - const std::string error("CreateSSLContext failed"); - LOG4CXX_ERROR(logger_, error); - security_manager_->SendInternalError( - handler->connection_key(), - security_manager::SecurityManager::ERROR_INTERNAL, - error); - - handler->OnHandshakeDone( - handler->connection_key(), - security_manager::SSLContext::Handshake_Result_Fail); - - continue; - } - - if (ssl_context->IsInitCompleted()) { - handler->OnHandshakeDone( - handler->connection_key(), - security_manager::SSLContext::Handshake_Result_Success); - } else { - security_manager_->AddListener(new HandshakeHandler(*handler)); - if (!ssl_context->IsHandshakePending()) { - // Start handshake process - security_manager_->StartHandshake(handler->connection_key()); - } - } - } - - LOG4CXX_DEBUG(logger_, "Handshake handlers were notified"); - ptu_pending_handlers_.clear(); - is_ptu_triggered_ = false; -#endif // ENABLE_SECURITY -} +void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) {} RESULT_CODE ProtocolHandlerImpl::SendFrame(const ProtocolFramePtr packet) { LOG4CXX_AUTO_TRACE(logger_); @@ -1579,40 +1517,10 @@ void ProtocolHandlerImpl::NotifySessionStarted( context, packet->protocol_version(), bson_object_bytes); - handshake_handlers_.push_back(handler); - - const bool is_certificate_empty = - security_manager_->IsPolicyCertificateDataEmpty(); - - if (context.is_ptu_required_ && is_certificate_empty) { - LOG4CXX_DEBUG(logger_, - "PTU for StartSessionHandler " - << handler.get() - << " is required and certificate data is empty"); - - sync_primitives::AutoLock lock(ptu_handlers_lock_); - if (!is_ptu_triggered_) { - LOG4CXX_DEBUG(logger_, - "PTU is not triggered yet. " - << "Starting PTU and postponing SSL handshake"); - - ptu_pending_handlers_.push_back(handler); - is_ptu_triggered_ = true; - security_manager_->NotifyOnCertificateUpdateRequired(); - security_manager_->PostponeHandshake(connection_key); - } else { - LOG4CXX_DEBUG(logger_, "PTU has been triggered. Added to pending."); - ptu_pending_handlers_.push_back(handler); - } - return; - } security_manager::SSLContext* ssl_context = - is_certificate_empty - ? NULL - : security_manager_->CreateSSLContext( - connection_key, - security_manager::SecurityManager::kUseExisting); + security_manager_->CreateSSLContext( + connection_key, security_manager::SecurityManager::kUseExisting); if (!ssl_context) { const std::string error("CreateSSLContext failed"); LOG4CXX_ERROR(logger_, error); @@ -1646,12 +1554,18 @@ void ProtocolHandlerImpl::NotifySessionStarted( *fullVersion, *start_session_ack_params); } else { - LOG4CXX_DEBUG(logger_, "Adding Handshake handler to listenets:"); - security_manager_->AddListener(new HandshakeHandler(*handler)); + LOG4CXX_DEBUG(logger_, + "Adding Handshake handler to listeners: " << handler.get()); + security_manager::SecurityManagerListener* listener = + new HandshakeHandler(*handler); + security_manager_->AddListener(listener); + if (!ssl_context->IsHandshakePending()) { // Start handshake process security_manager_->StartHandshake(connection_key); + if (!security_manager_->IsSystemTimeProviderReady()) { + security_manager_->RemoveListener(listener); SendStartSessionNAck(context.connection_id_, packet->session_id(), protocol_version, @@ -1660,6 +1574,7 @@ void ProtocolHandlerImpl::NotifySessionStarted( } } } + LOG4CXX_DEBUG(logger_, "Protection establishing for connection " << connection_key << " is in progress"); diff --git a/src/components/security_manager/include/security_manager/security_manager_impl.h b/src/components/security_manager/include/security_manager/security_manager_impl.h index ab093cc576..dc0284c128 100644 --- a/src/components/security_manager/include/security_manager/security_manager_impl.h +++ b/src/components/security_manager/include/security_manager/security_manager_impl.h @@ -201,6 +201,11 @@ class SecurityManagerImpl : public SecurityManager, */ void NotifyOnCertificateUpdateRequired() OVERRIDE; + /** + * @brief Notify all listeners that handshake was failed + */ + void NotifyListenersOnHandshakeFailed() OVERRIDE; + /** * @brief Check is policy certificate data is empty * @return true if policy certificate data is not empty otherwise false diff --git a/src/components/security_manager/src/security_manager_impl.cc b/src/components/security_manager/src/security_manager_impl.cc index d68e6b456e..66a85956a5 100644 --- a/src/components/security_manager/src/security_manager_impl.cc +++ b/src/components/security_manager/src/security_manager_impl.cc @@ -214,7 +214,7 @@ void SecurityManagerImpl::ResumeHandshake(uint32_t connection_key) { } ssl_context->ResetConnection(); - if (!ssl_context->HasCertificate()) { + if (!waiting_for_certificate_ && !ssl_context->HasCertificate()) { NotifyListenersOnHandshakeDone(connection_key, SSLContext::Handshake_Result_Fail); return; @@ -416,6 +416,20 @@ void SecurityManagerImpl::NotifyOnCertificateUpdateRequired() { } } +void SecurityManagerImpl::NotifyListenersOnHandshakeFailed() { + LOG4CXX_AUTO_TRACE(logger_); + std::list::iterator it = listeners_.begin(); + while (it != listeners_.end()) { + if ((*it)->OnHandshakeFailed()) { + LOG4CXX_DEBUG(logger_, "Destroying listener: " << *it); + delete (*it); + it = listeners_.erase(it); + } else { + ++it; + } + } +} + bool SecurityManagerImpl::IsPolicyCertificateDataEmpty() { LOG4CXX_AUTO_TRACE(logger_); -- cgit v1.2.1 From 9ca6d28bdf22eb1c4db71d417f503568d00d5869 Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Fri, 25 May 2018 20:30:11 +0300 Subject: Fix affected UT and mocks --- .../connection_handler/test/connection_handler_impl_test.cc | 10 ---------- .../include/test/security_manager/mock_security_manager.h | 1 + .../test/security_manager/mock_security_manager_listener.h | 2 +- 3 files changed, 2 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/components/connection_handler/test/connection_handler_impl_test.cc b/src/components/connection_handler/test/connection_handler_impl_test.cc index d0b9ce4ae4..56dbf6b9de 100644 --- a/src/components/connection_handler/test/connection_handler_impl_test.cc +++ b/src/components/connection_handler/test/connection_handler_impl_test.cc @@ -1273,9 +1273,6 @@ TEST_F(ConnectionHandlerTest, SessionStarted_WithRpc) { true, ByRef(empty))); - EXPECT_CALL(mock_connection_handler_observer, CheckAppIsNavi(_)) - .WillOnce(Return(true)); - connection_handler_->set_protocol_handler(&mock_protocol_handler_); EXPECT_CALL(mock_protocol_handler_, NotifySessionStarted(_, _)) .WillOnce(SaveArg<0>(&out_context_)); @@ -1312,8 +1309,6 @@ TEST_F(ConnectionHandlerTest, ServiceStarted_Video_SUCCESS) { session_key, true, ByRef(empty))); - EXPECT_CALL(mock_connection_handler_observer, CheckAppIsNavi(_)) - .WillOnce(Return(true)); // confirm that NotifySessionStarted() is called connection_handler_->set_protocol_handler(&mock_protocol_handler_); @@ -1354,8 +1349,6 @@ TEST_F(ConnectionHandlerTest, ServiceStarted_Video_FAILURE) { session_key, false, ByRef(empty))); - EXPECT_CALL(mock_connection_handler_observer, CheckAppIsNavi(_)) - .WillOnce(Return(true)); // confirm that NotifySessionStarted() is called connection_handler_->set_protocol_handler(&mock_protocol_handler_); @@ -1446,9 +1439,6 @@ TEST_F(ConnectionHandlerTest, ServiceStarted_Video_Multiple) { session_key1, true, ByRef(empty)))); - EXPECT_CALL(mock_connection_handler_observer, CheckAppIsNavi(_)) - .Times(2) - .WillRepeatedly(Return(true)); // verify that connection handler will not mix up the two results SessionContext new_context_first, new_context_second; diff --git a/src/components/include/test/security_manager/mock_security_manager.h b/src/components/include/test/security_manager/mock_security_manager.h index 153ce85422..b2c2e3bf17 100644 --- a/src/components/include/test/security_manager/mock_security_manager.h +++ b/src/components/include/test/security_manager/mock_security_manager.h @@ -68,6 +68,7 @@ class MockSecurityManager : public ::security_manager::SecurityManager { void(const ::protocol_handler::RawMessagePtr)); MOCK_METHOD1(IsCertificateUpdateRequired, bool(const uint32_t)); MOCK_METHOD0(NotifyOnCertificateUpdateRequired, void()); + MOCK_METHOD0(NotifyListenersOnHandshakeFailed, void()); MOCK_METHOD0(IsPolicyCertificateDataEmpty, bool()); MOCK_METHOD1(OnCertificateUpdated, bool(const std::string&)); MOCK_METHOD1(PostponeHandshake, void(const uint32_t)); diff --git a/src/components/include/test/security_manager/mock_security_manager_listener.h b/src/components/include/test/security_manager/mock_security_manager_listener.h index 76273b244d..7a7714d299 100644 --- a/src/components/include/test/security_manager/mock_security_manager_listener.h +++ b/src/components/include/test/security_manager/mock_security_manager_listener.h @@ -49,7 +49,7 @@ class MockSecurityManagerListener ::security_manager::SSLContext::HandshakeResult result)); MOCK_METHOD0(OnCertificateUpdateRequired, void()); MOCK_CONST_METHOD1(GetPolicyCertificateData, bool(std::string& data)); - MOCK_METHOD0(OnHandshakeFailed, void()); + MOCK_METHOD0(OnHandshakeFailed, bool()); }; } // namespace security_manager_test } // namespace components -- cgit v1.2.1 From 112c685ae48d7cf939e3d2147453de1719862ec6 Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Mon, 4 Jun 2018 17:19:21 +0300 Subject: Move out unrelated to feature changes There was included some changes related to certificate processing. They will be included into related pull request --- .../src/policies/policy_handler.cc | 10 +-- .../src/connection_handler_impl.cc | 8 ++ .../include/protocol_handler/session_observer.h | 7 +- .../policy_external/src/policy_manager_impl.cc | 16 ++-- .../protocol_handler/protocol_handler_impl.h | 6 ++ .../protocol_handler/src/protocol_handler_impl.cc | 91 +++++++++++++++++++++- 6 files changed, 123 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index 98fb6bae65..bbf391a9f1 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -1765,11 +1765,11 @@ void PolicyHandler::OnCertificateDecrypted(bool is_succeeded) { void PolicyHandler::OnCertificateUpdated(const std::string& certificate_data) { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock lock(listeners_lock_); - std::for_each( - listeners_.begin(), - listeners_.end(), - std::bind2nd(std::mem_fun(&PolicyHandlerObserver::OnCertificateUpdated), - certificate_data)); + HandlersCollection::const_iterator it = listeners_.begin(); + for (; it != listeners_.end(); ++it) { + PolicyHandlerObserver* observer = *it; + observer->OnCertificateUpdated(certificate_data); + } } #endif // EXTERNAL_PROPRIETARY_MODE diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index 59865ac4b2..b97c6eacd4 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -467,6 +467,14 @@ void ConnectionHandlerImpl::OnSessionStartedCallback( const uint32_t session_key = KeyFromPair(connection_handle, context.new_session_id_); + uint32_t app_id = 0; + GetDataOnSessionKey( + session_key, &app_id, NULL, static_cast(NULL)); + if (app_id > 0) { + context.is_ptu_required_ = + !connection_handler_observer_->CheckAppIsNavi(app_id); + } + { sync_primitives::AutoLock auto_lock(start_service_context_map_lock_); start_service_context_map_[session_key] = context; diff --git a/src/components/include/protocol_handler/session_observer.h b/src/components/include/protocol_handler/session_observer.h index 242775bf25..3482c6569c 100644 --- a/src/components/include/protocol_handler/session_observer.h +++ b/src/components/include/protocol_handler/session_observer.h @@ -66,6 +66,7 @@ struct SessionContext { uint32_t hash_id_; bool is_protected_; bool is_new_service_; + bool is_ptu_required_; /** * @brief Constructor @@ -77,7 +78,8 @@ struct SessionContext { , service_type_(protocol_handler::kInvalidServiceType) , hash_id_(0) , is_protected_(false) - , is_new_service_(false) {} + , is_new_service_(false) + , is_ptu_required_(false) {} /** * @brief Constructor @@ -103,7 +105,8 @@ struct SessionContext { , service_type_(service_type) , hash_id_(hash_id) , is_protected_(is_protected) - , is_new_service_(false) {} + , is_new_service_(false) + , is_ptu_required_(false) {} }; /** 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 f84df92dba..cc5e64d254 100644 --- a/src/components/policy/policy_external/src/policy_manager_impl.cc +++ b/src/components/policy/policy_external/src/policy_manager_impl.cc @@ -588,7 +588,8 @@ void PolicyManagerImpl::CheckPermissions(const PTString& app_id, policy_table::FunctionalGroupings functional_groupings; cache_->GetFunctionalGroupings(functional_groupings); - policy_table::Strings app_groups = GetGroupsNames(app_group_permissions); + policy_table::Strings app_groups = + GetGroupsNames(app_group_permissions); // Undefined groups (without user consent) disallowed by default, since // OnPermissionsChange notification has no "undefined" section @@ -620,7 +621,8 @@ void PolicyManagerImpl::CheckPermissions(const PTString& app_id, } const bool known_rpc = rpc_permissions.end() != rpc_permissions.find(rpc); - LOG4CXX_DEBUG(logger_, "Is known rpc " << (known_rpc ? "true" : "false")); + LOG4CXX_DEBUG(logger_, "Is known rpc " << + (known_rpc ? "true" : "false")); if (!known_rpc) { // RPC not found in list == disallowed by backend result.hmi_level_permitted = kRpcDisallowed; @@ -642,9 +644,7 @@ void PolicyManagerImpl::CheckPermissions(const PTString& app_id, rpc_permissions[rpc].hmi_permissions[kUserDisallowedKey].find( hmi_level)) { // RPC found in allowed == allowed by backend, but disallowed by user - LOG4CXX_DEBUG( - logger_, - "RPC found in allowed == allowed by backend, but disallowed by user"); + LOG4CXX_DEBUG(logger_, "RPC found in allowed == allowed by backend, but disallowed by user"); result.hmi_level_permitted = kRpcUserDisallowed; } else { LOG4CXX_DEBUG(logger_, @@ -984,6 +984,7 @@ void PolicyManagerImpl::SetUserConsentForApp( const PermissionConsent& permissions, const NotificationMode mode) { LOG4CXX_AUTO_TRACE(logger_); + cache_->ResetCalculatedPermissions(); PermissionConsent verified_permissions = EnsureCorrectPermissionConsent(permissions); @@ -1766,6 +1767,11 @@ StatusNotifier PolicyManagerImpl::AddApplication( device_consent); } else { PromoteExistedApplication(application_id, device_consent); + if (helpers::in_range(hmi_types, policy_table::AHT_NAVIGATION) && + !HasCertificate()) { + LOG4CXX_DEBUG(logger_, "Certificate does not exist, scheduling update."); + update_status_manager_.ScheduleUpdate(); + } return utils::MakeShared(); } } 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 e03e29d9bc..4d86a78688 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 @@ -685,6 +685,12 @@ class ProtocolHandlerImpl #ifdef ENABLE_SECURITY security_manager::SecurityManager* security_manager_; + + bool is_ptu_triggered_; + std::list > ptu_pending_handlers_; + std::list > handshake_handlers_; + sync_primitives::Lock ptu_handlers_lock_; + sync_primitives::Lock handshake_handlers_lock_; #endif // ENABLE_SECURITY // Thread that pumps non-parsed messages coming from mobile side. diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index 4cc4f883f0..e5bacdbf6f 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -75,6 +75,7 @@ ProtocolHandlerImpl::ProtocolHandlerImpl( , #ifdef ENABLE_SECURITY security_manager_(NULL) + , is_ptu_triggered_(false) , #endif // ENABLE_SECURITY raw_ford_messages_from_mobile_( @@ -148,6 +149,7 @@ ProtocolHandlerImpl::~ProtocolHandlerImpl() { "Not all observers have unsubscribed" " from ProtocolHandlerImpl"); } + handshake_handlers_.clear(); } void ProtocolHandlerImpl::AddProtocolObserver(ProtocolObserver* observer) { @@ -843,7 +845,60 @@ void ProtocolHandlerImpl::NotifyOnFailedHandshake() { security_manager_->NotifyListenersOnHandshakeFailed(); } -void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) {} +void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) { + LOG4CXX_AUTO_TRACE(logger_); + +#ifdef ENABLE_SECURITY + sync_primitives::AutoLock lock(ptu_handlers_lock_); + + if (!is_ptu_triggered_) { + LOG4CXX_ERROR(logger_, + "PTU was not triggered by service starting. Ignored"); + return; + } + + for (auto handler : ptu_pending_handlers_) { + const bool is_cert_expired = security_manager_->IsCertificateUpdateRequired( + handler->connection_key()); + security_manager::SSLContext* ssl_context = + is_cert_expired ? NULL + : security_manager_->CreateSSLContext( + handler->connection_key(), + security_manager::SecurityManager::kUseExisting); + + if (!ssl_context) { + const std::string error("CreateSSLContext failed"); + LOG4CXX_ERROR(logger_, error); + security_manager_->SendInternalError( + handler->connection_key(), + security_manager::SecurityManager::ERROR_INTERNAL, + error); + + handler->OnHandshakeDone( + handler->connection_key(), + security_manager::SSLContext::Handshake_Result_Fail); + + continue; + } + + if (ssl_context->IsInitCompleted()) { + handler->OnHandshakeDone( + handler->connection_key(), + security_manager::SSLContext::Handshake_Result_Success); + } else { + security_manager_->AddListener(new HandshakeHandler(*handler)); + if (!ssl_context->IsHandshakePending()) { + // Start handshake process + security_manager_->StartHandshake(handler->connection_key()); + } + } + } + + LOG4CXX_DEBUG(logger_, "Handshake handlers were notified"); + ptu_pending_handlers_.clear(); + is_ptu_triggered_ = false; +#endif // ENABLE_SECURITY +} RESULT_CODE ProtocolHandlerImpl::SendFrame(const ProtocolFramePtr packet) { LOG4CXX_AUTO_TRACE(logger_); @@ -1517,10 +1572,40 @@ void ProtocolHandlerImpl::NotifySessionStarted( context, packet->protocol_version(), bson_object_bytes); + handshake_handlers_.push_back(handler); + + const bool is_certificate_empty = + security_manager_->IsPolicyCertificateDataEmpty(); + + if (context.is_ptu_required_ && is_certificate_empty) { + LOG4CXX_DEBUG(logger_, + "PTU for StartSessionHandler " + << handler.get() + << " is required and certificate data is empty"); + + sync_primitives::AutoLock lock(ptu_handlers_lock_); + if (!is_ptu_triggered_) { + LOG4CXX_DEBUG(logger_, + "PTU is not triggered yet. " + << "Starting PTU and postponing SSL handshake"); + + ptu_pending_handlers_.push_back(handler); + is_ptu_triggered_ = true; + security_manager_->NotifyOnCertificateUpdateRequired(); + security_manager_->PostponeHandshake(connection_key); + } else { + LOG4CXX_DEBUG(logger_, "PTU has been triggered. Added to pending."); + ptu_pending_handlers_.push_back(handler); + } + return; + } security_manager::SSLContext* ssl_context = - security_manager_->CreateSSLContext( - connection_key, security_manager::SecurityManager::kUseExisting); + is_certificate_empty + ? NULL + : security_manager_->CreateSSLContext( + connection_key, + security_manager::SecurityManager::kUseExisting); if (!ssl_context) { const std::string error("CreateSSLContext failed"); LOG4CXX_ERROR(logger_, error); -- cgit v1.2.1 From a194d35bcc39560ef47f39a5dd95cd75cfd193ba Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Tue, 12 Jun 2018 14:34:31 +0300 Subject: Updates after Livio review --- .../test/connection_handler_impl_test.cc | 10 ++++++++++ .../include/test/utils/mock_system_time_handler.h | 2 +- src/components/interfaces/HMI_API.xml | 5 +++-- .../policy/policy_regular/src/policy_manager_impl.cc | 7 +++++++ .../include/security_manager/crypto_manager_impl.h | 7 ------- .../include/security_manager/security_manager_impl.h | 2 ++ .../security_manager/src/crypto_manager_impl.cc | 15 --------------- .../security_manager/src/security_manager_impl.cc | 10 +++++----- src/components/security_manager/src/ssl_context_impl.cc | 10 ++++++++++ .../test/ssl_certificate_handshake_test.cc | 3 --- src/components/utils/include/utils/system_time_handler.h | 4 ++-- src/components/utils/src/system_time_handler.cc | 3 +-- 12 files changed, 41 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/components/connection_handler/test/connection_handler_impl_test.cc b/src/components/connection_handler/test/connection_handler_impl_test.cc index 56dbf6b9de..b231ee625f 100644 --- a/src/components/connection_handler/test/connection_handler_impl_test.cc +++ b/src/components/connection_handler/test/connection_handler_impl_test.cc @@ -1273,6 +1273,9 @@ TEST_F(ConnectionHandlerTest, SessionStarted_WithRpc) { true, ByRef(empty))); + EXPECT_CALL(mock_connection_handler_observer, CheckAppIsNavi(_)) + .WillOnce(Return(true)); + connection_handler_->set_protocol_handler(&mock_protocol_handler_); EXPECT_CALL(mock_protocol_handler_, NotifySessionStarted(_, _)) .WillOnce(SaveArg<0>(&out_context_)); @@ -1309,6 +1312,8 @@ TEST_F(ConnectionHandlerTest, ServiceStarted_Video_SUCCESS) { session_key, true, ByRef(empty))); + EXPECT_CALL(mock_connection_handler_observer, CheckAppIsNavi(_)) + .WillOnce(Return(true)); // confirm that NotifySessionStarted() is called connection_handler_->set_protocol_handler(&mock_protocol_handler_); @@ -1349,6 +1354,8 @@ TEST_F(ConnectionHandlerTest, ServiceStarted_Video_FAILURE) { session_key, false, ByRef(empty))); + EXPECT_CALL(mock_connection_handler_observer, CheckAppIsNavi(_)) + .WillOnce(Return(true)); // confirm that NotifySessionStarted() is called connection_handler_->set_protocol_handler(&mock_protocol_handler_); @@ -1439,6 +1446,9 @@ TEST_F(ConnectionHandlerTest, ServiceStarted_Video_Multiple) { session_key1, true, ByRef(empty)))); + EXPECT_CALL(mock_connection_handler_observer, CheckAppIsNavi(_)) + .Times(2) + .WillOnce(Return(true)); // verify that connection handler will not mix up the two results SessionContext new_context_first, new_context_second; diff --git a/src/components/include/test/utils/mock_system_time_handler.h b/src/components/include/test/utils/mock_system_time_handler.h index ef80e698f5..7bb2a7f0a5 100644 --- a/src/components/include/test/utils/mock_system_time_handler.h +++ b/src/components/include/test/utils/mock_system_time_handler.h @@ -46,7 +46,7 @@ class MockSystemTimeHandler : public ::utils::SystemTimeHandler { MOCK_METHOD0(QuerySystemTime, void()); MOCK_METHOD1(SubscribeOnSystemTime, void(utils::SystemTimeListener* listener)); - MOCK_METHOD1(UnSubscribeFromSystemTime, + MOCK_METHOD1(UnsubscribeFromSystemTime, void(utils::SystemTimeListener* listener)); MOCK_METHOD0(GetUTCTime, time_t()); MOCK_CONST_METHOD0(system_time_can_be_received, bool()); diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml index ef891f86a1..6b192a8d0d 100644 --- a/src/components/interfaces/HMI_API.xml +++ b/src/components/interfaces/HMI_API.xml @@ -2842,14 +2842,15 @@ - Allows to obtain current sytem time + Request from SDL to HMI to obtain current UTC time. + Current UTC system time - HMI notifies SDL with this notification that NAVI module is ready to provide system time. + HMI must notify SDL about readiness to provide system time. HMI must notify SDL about its readiness to start communication. In fact, this has to be the first message between SDL and HMI. 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 5226a15aeb..4e744cf716 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -1061,6 +1061,13 @@ StatusNotifier PolicyManagerImpl::AddApplication( device_consent); } else { PromoteExistedApplication(application_id, device_consent); + const policy_table::AppHMIType type = policy_table::AHT_NAVIGATION; + if (helpers::in_range(hmi_types, + (rpc::Enum)type) && + !HasCertificate()) { + LOG4CXX_DEBUG(logger_, "Certificate does not exist, scheduling update."); + update_status_manager_.ScheduleUpdate(); + } return utils::MakeShared(); } } diff --git a/src/components/security_manager/include/security_manager/crypto_manager_impl.h b/src/components/security_manager/include/security_manager/crypto_manager_impl.h index c31e02cf48..228666d22f 100644 --- a/src/components/security_manager/include/security_manager/crypto_manager_impl.h +++ b/src/components/security_manager/include/security_manager/crypto_manager_impl.h @@ -152,15 +152,8 @@ class CryptoManagerImpl : public CryptoManager { private: bool set_certificate(const std::string& cert_data); - - /** - * @brief Sets initial certificate datetime - */ - void InitCertExpTime(); - const utils::SharedPtr settings_; SSL_CTX* context_; - mutable struct tm expiration_time_; static uint32_t instance_count_; static sync_primitives::Lock instance_lock_; DISALLOW_COPY_AND_ASSIGN(CryptoManagerImpl); diff --git a/src/components/security_manager/include/security_manager/security_manager_impl.h b/src/components/security_manager/include/security_manager/security_manager_impl.h index dc0284c128..70b87de0ef 100644 --- a/src/components/security_manager/include/security_manager/security_manager_impl.h +++ b/src/components/security_manager/include/security_manager/security_manager_impl.h @@ -143,6 +143,7 @@ class SecurityManagerImpl : public SecurityManager, * Do not notify listeners, send security error on occure * \param connection_key Unique key used by other components as session * identifier + * @param cc_strategy - SSL context creation strategy * @return new \c SSLContext or \c NULL on any error */ SSLContext* CreateSSLContext(const uint32_t& connection_key, @@ -163,6 +164,7 @@ class SecurityManagerImpl : public SecurityManager, /** * @brief Checks whether certificate should be updated + * @param connection_key the connection identifier to check certificate for. * @return true if certificate should be updated otherwise false */ bool IsCertificateUpdateRequired(const uint32_t connection_key) OVERRIDE; diff --git a/src/components/security_manager/src/crypto_manager_impl.cc b/src/components/security_manager/src/crypto_manager_impl.cc index bdf266fda8..1e1b4ef44a 100644 --- a/src/components/security_manager/src/crypto_manager_impl.cc +++ b/src/components/security_manager/src/crypto_manager_impl.cc @@ -98,7 +98,6 @@ CryptoManagerImpl::CryptoManagerImpl( OpenSSL_add_all_algorithms(); SSL_library_init(); } - InitCertExpTime(); } CryptoManagerImpl::~CryptoManagerImpl() { @@ -360,18 +359,4 @@ bool CryptoManagerImpl::set_certificate(const std::string& cert_data) { return true; } -int CryptoManagerImpl::SSLContextImpl::get_number_from_char_buf( - char* buf, int* idx) const { - if (!idx) { - return 0; - } - const int val = ((buf[*idx] - '0') * 10) + buf[(*idx) + 1] - '0'; - *idx = *idx + 2; - return val; -} - -void CryptoManagerImpl::InitCertExpTime() { - strptime("1 Jan 1970 00:00:00", "%d %b %Y %H:%M:%S", &expiration_time_); -} - } // namespace security_manager diff --git a/src/components/security_manager/src/security_manager_impl.cc b/src/components/security_manager/src/security_manager_impl.cc index 66a85956a5..401491c5dc 100644 --- a/src/components/security_manager/src/security_manager_impl.cc +++ b/src/components/security_manager/src/security_manager_impl.cc @@ -60,7 +60,7 @@ SecurityManagerImpl::SecurityManagerImpl( } SecurityManagerImpl::~SecurityManagerImpl() { - system_time_handler_->UnSubscribeFromSystemTime(this); + system_time_handler_->UnsubscribeFromSystemTime(this); } void SecurityManagerImpl::OnMessageReceived( @@ -242,7 +242,7 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) { LOG4CXX_ERROR(logger_, "Security certificate is absent"); sync_primitives::AutoLock lock(waiters_lock_); waiting_for_certificate_ = true; - NotifyOnCertififcateUpdateRequired(); + NotifyOnCertificateUpdateRequired(); } { @@ -293,7 +293,7 @@ void SecurityManagerImpl::ProceedHandshake( waiting_for_certificate_ = true; } PostponeHandshake(connection_key); - NotifyOnCertififcateUpdateRequired(); + NotifyOnCertificateUpdateRequired(); return; } @@ -369,7 +369,7 @@ bool SecurityManagerImpl::OnCertificateUpdated(const std::string& data) { awaiting_certificate_connections_.end(), std::bind1st(std::mem_fun(&SecurityManagerImpl::ResumeHandshake), this)); - std::set().swap(awaiting_certificate_connections_); + awaiting_certificate_connections_.clear(); return true; } @@ -385,7 +385,7 @@ void SecurityManagerImpl::OnSystemTimeArrived(const time_t utc_time) { awaiting_time_connections_.end(), std::bind1st(std::mem_fun(&SecurityManagerImpl::ResumeHandshake), this)); - std::set().swap(awaiting_time_connections_); + awaiting_time_connections_.clear(); } void SecurityManagerImpl::NotifyListenersOnHandshakeDone( diff --git a/src/components/security_manager/src/ssl_context_impl.cc b/src/components/security_manager/src/ssl_context_impl.cc index bccb885511..866e825e0b 100644 --- a/src/components/security_manager/src/ssl_context_impl.cc +++ b/src/components/security_manager/src/ssl_context_impl.cc @@ -280,6 +280,16 @@ CryptoManagerImpl::SSLContextImpl::CheckCertContext() { return Handshake_Result_Success; } +int CryptoManagerImpl::SSLContextImpl::get_number_from_char_buf( + char* buf, int* idx) const { + if (!idx) { + return 0; + } + const int val = ((buf[*idx] - '0') * 10) + buf[(*idx) + 1] - '0'; + *idx = *idx + 2; + return val; +} + time_t CryptoManagerImpl::SSLContextImpl::convert_asn1_time_to_time_t( ASN1_TIME* time_to_convert) const { struct tm cert_time; diff --git a/src/components/security_manager/test/ssl_certificate_handshake_test.cc b/src/components/security_manager/test/ssl_certificate_handshake_test.cc index f6521c253a..dc335c8da2 100644 --- a/src/components/security_manager/test/ssl_certificate_handshake_test.cc +++ b/src/components/security_manager/test/ssl_certificate_handshake_test.cc @@ -335,9 +335,6 @@ class SSLHandshakeTest : public testing::Test { std::string client_certificate_; std::string client_ciphers_list_; std::string client_ca_certificate_path_; - - std::vector forced_protected_services_; - std::vector forced_unprotected_services_; }; TEST_F(SSLHandshakeTest, NoVerification) { diff --git a/src/components/utils/include/utils/system_time_handler.h b/src/components/utils/include/utils/system_time_handler.h index 99bbfa39e5..15b2dd0cca 100644 --- a/src/components/utils/include/utils/system_time_handler.h +++ b/src/components/utils/include/utils/system_time_handler.h @@ -82,12 +82,12 @@ class SystemTimeHandler { void SubscribeOnSystemTime(SystemTimeListener* listener); /** - * @brief UnSubscribeFromSystemTime allows to unsubscribe listener + * @brief UnsubscribeFromSystemTime allows to unsubscribe listener * from the certain event. This class does not manipulate with storage. * It rather uses private pure virtual function. So the final behaviour * should be defined within the descendant class */ - void UnSubscribeFromSystemTime(SystemTimeListener* listener); + void UnsubscribeFromSystemTime(SystemTimeListener* listener); /** * @brief GetUTCTime allows to obtain cached result for the diff --git a/src/components/utils/src/system_time_handler.cc b/src/components/utils/src/system_time_handler.cc index ea04d1c0b9..0c3c62cc53 100644 --- a/src/components/utils/src/system_time_handler.cc +++ b/src/components/utils/src/system_time_handler.cc @@ -31,7 +31,6 @@ */ #include "utils/system_time_handler.h" -//#include namespace utils { @@ -47,7 +46,7 @@ void SystemTimeHandler::SubscribeOnSystemTime(SystemTimeListener* listener) { DoSubscribe(listener); } -void SystemTimeHandler::UnSubscribeFromSystemTime( +void SystemTimeHandler::UnsubscribeFromSystemTime( SystemTimeListener* listener) { DoUnsubscribe(listener); } -- cgit v1.2.1 From 572b06a2c5ab174a0be1a9b1526a41950564fa0a Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Tue, 12 Jun 2018 19:16:49 +0300 Subject: Fixed time zones issue while checking certificate exp date --- src/components/security_manager/src/ssl_context_impl.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/components/security_manager/src/ssl_context_impl.cc b/src/components/security_manager/src/ssl_context_impl.cc index 866e825e0b..75e2c8a4f8 100644 --- a/src/components/security_manager/src/ssl_context_impl.cc +++ b/src/components/security_manager/src/ssl_context_impl.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -113,6 +114,12 @@ size_t des_cbc3_sha_max_block_size(size_t mtu) { return 0; return ((mtu - 29) & 0xfffffff8) - 5; } +time_t get_time_zone_offset(time_t in_time) { + tm gmt_cert_tm = *gmtime(&in_time); + tm local_cert_tm = *localtime(&in_time); + + return mktime(&local_cert_tm) - mktime(&gmt_cert_tm); +} } // namespace std::map @@ -328,7 +335,10 @@ time_t CryptoManagerImpl::SSLContextImpl::convert_asn1_time_to_time_t( cert_time.tm_sec = sec; } - return mktime(&cert_time); + const time_t local_cert_time = mktime(&cert_time); + const time_t time_offset = get_time_zone_offset(local_cert_time); + + return local_cert_time + time_offset; } bool CryptoManagerImpl::SSLContextImpl::ReadHandshakeData( -- cgit v1.2.1 From d99d7f2fa71205a5f1a69d07b1abb75ef2c1fc7f Mon Sep 17 00:00:00 2001 From: AKalinich-Luxoft Date: Fri, 15 Jun 2018 12:53:28 +0300 Subject: Removed unused code in regular policies --- .../include/policy/policy_regular/policy/policy_manager.h | 6 ------ .../include/test/policy/policy_regular/policy/mock_cache_manager.h | 1 - .../test/policy/policy_regular/policy/mock_policy_manager.h | 1 - .../policy/policy_regular/include/policy/cache_manager.h | 6 ------ .../policy/policy_regular/include/policy/cache_manager_interface.h | 7 ------- .../policy/policy_regular/include/policy/policy_manager_impl.h | 2 -- src/components/policy/policy_regular/src/cache_manager.cc | 7 ------- src/components/policy/policy_regular/src/policy_manager_impl.cc | 7 ------- 8 files changed, 37 deletions(-) (limited to 'src') 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 f14cce6c4f..3e90cfc094 100644 --- a/src/components/include/policy/policy_regular/policy/policy_manager.h +++ b/src/components/include/policy/policy_regular/policy/policy_manager.h @@ -504,12 +504,6 @@ class PolicyManager : public usage_statistics::StatisticsManager { */ virtual bool HasCertificate() const = 0; - /** - * @brief Sets decrypted certificate in policy table - * @param certificate content of certificate - */ - virtual void SetDecryptedCertificate(const std::string& certificate) = 0; - /** * @brief Getter for policy settings * @return policy settings instance 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 c9f53b8606..2b8dc809a6 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 @@ -206,7 +206,6 @@ class MockCacheManagerInterface : public CacheManagerInterface { MOCK_METHOD1(GetHMITypes, const policy_table::AppHMITypes*(const std::string& app_id)); MOCK_CONST_METHOD0(GetCertificate, std::string()); - MOCK_CONST_METHOD1(SetDecryptedCertificate, void(const std::string&)); MOCK_METHOD1(GetGroups, const policy_table::Strings&(const PTString& app_id)); MOCK_CONST_METHOD2(AppHasHMIType, bool(const std::string& application_id, 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 82012b83c7..53b29cabe7 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 @@ -186,7 +186,6 @@ class MockPolicyManager : public PolicyManager { MOCK_CONST_METHOD0(GetMetaInfo, const policy::MetaInfo()); MOCK_CONST_METHOD0(RetrieveCertificate, std::string()); MOCK_CONST_METHOD0(HasCertificate, bool()); - MOCK_METHOD1(SetDecryptedCertificate, void(const std::string&)); MOCK_METHOD0(ExceededIgnitionCycles, bool()); MOCK_METHOD0(ExceededDays, bool()); MOCK_METHOD0(StartPTExchange, void()); 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 f3fcfccd13..8c0acd44d2 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -279,12 +279,6 @@ class CacheManager : public CacheManagerInterface { */ bool IsDefaultPolicy(const std::string& app_id) const OVERRIDE; - /** - * @brief Sets decrypted certificate in policy table - * @param certificate content of certificate - */ - void SetDecryptedCertificate(const std::string& certificate) const OVERRIDE; - /** * @brief SetIsDefault Sets is_default flag for application * @param app_id app specific application 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 842d8274eb..9f7c7318db 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 @@ -276,13 +276,6 @@ class CacheManagerInterface { */ virtual bool IsDefaultPolicy(const std::string& app_id) const = 0; - /** - * @brief Sets decrypted certificate in policy table - * @param certificate content of certificate - */ - virtual void SetDecryptedCertificate( - const std::string& certificate) const = 0; - /** * @brief SetIsDefault Sets is_default flag for application * @param app_id app specific application 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 6329abbb04..941db1a67f 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 @@ -570,8 +570,6 @@ class PolicyManagerImpl : public PolicyManager { */ bool HasCertificate() const OVERRIDE; - void SetDecryptedCertificate(const std::string& certificate) OVERRIDE; - /** * @brief Finds the next URL that must be sent on OnSystemRequest retry * @param urls vector of vectors that contain urls for each application diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index 8390a232c3..6a142374d5 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -1290,13 +1290,6 @@ bool CacheManager::IsDefaultPolicy(const std::string& app_id) const { return result; } -void CacheManager::SetDecryptedCertificate( - const std::string& certificate) const { - CACHE_MANAGER_CHECK_VOID(); - sync_primitives::AutoLock auto_lock(cache_lock_); - *pt_->policy_table.module_config.certificate = certificate; -} - bool CacheManager::SetIsDefault(const std::string& app_id) { CACHE_MANAGER_CHECK(false); sync_primitives::AutoLock auto_lock(cache_lock_); 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 4e744cf716..c033c0c8e7 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -1025,13 +1025,6 @@ bool PolicyManagerImpl::HasCertificate() const { return !cache_->GetCertificate().empty(); } -void PolicyManagerImpl::SetDecryptedCertificate( - const std::string& certificate) { - LOG4CXX_AUTO_TRACE(logger_); - cache_->SetDecryptedCertificate(certificate); - cache_->Backup(); -} - class CallStatusChange : public utils::Callable { public: CallStatusChange(UpdateStatusManager& upd_manager, -- cgit v1.2.1