From 922ee3ce49d9359067516129f0369fed9ba01f93 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 31 Aug 2018 14:52:51 +0200 Subject: [PATCH] clean up some remaining old stuff --- .../cloud/OpenSSL/OpenSSLConnection.cpp | 572 ------------------ .../cloud/OpenSSL/OpenSSLConnection.hpp | 286 --------- libnymea-core/cloud/awsconnector.cpp | 2 +- libnymea-core/cloud/awsconnector.h | 22 +- 4 files changed, 2 insertions(+), 880 deletions(-) delete mode 100644 libnymea-core/cloud/OpenSSL/OpenSSLConnection.cpp delete mode 100644 libnymea-core/cloud/OpenSSL/OpenSSLConnection.hpp diff --git a/libnymea-core/cloud/OpenSSL/OpenSSLConnection.cpp b/libnymea-core/cloud/OpenSSL/OpenSSLConnection.cpp deleted file mode 100644 index 3bee7040..00000000 --- a/libnymea-core/cloud/OpenSSL/OpenSSLConnection.cpp +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -/** - * @file OpenSSLConnection.hpp - * @brief - * - */ - -#include -#include - -#include "OpenSSLConnection.hpp" -#include "util/logging/LogMacros.hpp" - -#ifdef WIN32 -#define MAX_PATH_LENGTH_ 260 -#include -#define getcwd _getcwd // avoid MSFT "deprecation" warning -#else -#include -#include -#include -#define MAX_PATH_LENGTH_ PATH_MAX -#endif - -#define OPENSSL_WRAPPER_LOG_TAG "[OpenSSL Wrapper]" - -namespace awsiotsdk { - namespace network { - OpenSSLInitializer::~OpenSSLInitializer() { - CONF_modules_free(); -#if OPENSSL_VERSION_NUMBER >= 0x10002000L && OPENSSL_VERSION_NUMBER < 0x10100000L - ERR_remove_thread_state(NULL); -#endif - CONF_modules_unload(1); - SSL_COMP_free_compression_methods(); - ERR_free_strings(); - EVP_cleanup(); - CRYPTO_cleanup_all_ex_data(); - } - - OpenSSLInitializer *OpenSSLInitializer::getInstance() { - static OpenSSLInitializer initializer; - return &initializer; - } - - std::atomic_bool OpenSSLConnection::is_lib_initialized(false); - - OpenSSLConnection::OpenSSLConnection(util::String endpoint, uint16_t endpoint_port, - std::chrono::milliseconds tls_handshake_timeout, - std::chrono::milliseconds tls_read_timeout, - std::chrono::milliseconds tls_write_timeout, - bool server_verification_flag) { - endpoint_ = endpoint; - endpoint_port_ = endpoint_port; - server_verification_flag_ = server_verification_flag; - int timeout_ms = static_cast(tls_handshake_timeout.count()); - tls_handshake_timeout_ = {timeout_ms / 1000, (timeout_ms % 1000) * 1000}; - timeout_ms = static_cast(tls_read_timeout.count()); - tls_read_timeout_ = {timeout_ms / 1000, (timeout_ms % 1000) * 1000}; - timeout_ms = static_cast(tls_write_timeout.count()); - tls_write_timeout_ = {timeout_ms / 1000, (timeout_ms % 1000) * 1000}; - - is_connected_ = false; - certificates_read_flag_ = false; - initializer = OpenSSLInitializer::getInstance(); - p_ssl_handle_ = nullptr; - } - - OpenSSLConnection::OpenSSLConnection(util::String endpoint, - uint16_t endpoint_port, - util::String root_ca_location, - util::String device_cert_location, - util::String device_private_key_location, - std::chrono::milliseconds tls_handshake_timeout, - std::chrono::milliseconds tls_read_timeout, - std::chrono::milliseconds tls_write_timeout, - bool server_verification_flag) - : OpenSSLConnection(endpoint, endpoint_port, tls_handshake_timeout, tls_read_timeout, tls_write_timeout, - server_verification_flag) { - root_ca_location_ = root_ca_location; - device_cert_location_ = device_cert_location; - device_private_key_location_ = device_private_key_location; - } - - OpenSSLConnection::OpenSSLConnection(util::String endpoint, - uint16_t endpoint_port, - util::String root_ca_location, - std::chrono::milliseconds tls_handshake_timeout, - std::chrono::milliseconds tls_read_timeout, - std::chrono::milliseconds tls_write_timeout, - bool server_verification_flag) - : OpenSSLConnection(endpoint, endpoint_port, tls_handshake_timeout, tls_read_timeout, tls_write_timeout, - server_verification_flag) { - root_ca_location_ = root_ca_location; - device_cert_location_.clear(); - device_private_key_location_.clear(); - } - - int OpenSSLConnection::WaitForSelect(int error_code) { - fd_set socketFds; - struct timeval timeout = {tls_write_timeout_.tv_sec, tls_write_timeout_.tv_usec}; - FD_ZERO(&socketFds); - FD_SET(server_tcp_socket_fd_, &socketFds); - if (SSL_ERROR_WANT_READ == error_code) { - return select(server_tcp_socket_fd_ + 1, &socketFds, NULL, NULL, &timeout); - } else if (SSL_ERROR_WANT_WRITE == error_code) { - return select(server_tcp_socket_fd_ + 1, NULL, &socketFds, NULL, &timeout); - } else { - return 0; - } - } - - ResponseCode OpenSSLConnection::Initialize() { -#ifdef WIN32 - // TODO : Check if it is possible to replace this with std::call_once - WSADATA wsa_data; - int result; - bool was_wsa_initialized = true; - int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(INVALID_SOCKET == s) { - if(WSANOTINITIALISED == WSAGetLastError()) { - was_wsa_initialized = false; - } - } else { - closesocket(s); - } - - if(!was_wsa_initialized) { - // Initialize Winsock - result = WSAStartup(MAKEWORD(2, 2), &wsa_data); - if(0 != result) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, "WSAStartup failed: %d", result); - return ResponseCode::NETWORK_SSL_INIT_ERROR; - } - } -#endif - - if (!is_lib_initialized) { - OpenSSL_add_all_algorithms(); - ERR_load_BIO_strings(); - ERR_load_crypto_strings(); - SSL_load_error_strings(); - signal(SIGPIPE, SIG_IGN); - is_lib_initialized = true; - } - const SSL_METHOD *method; - - if (SSL_library_init() < 0) { - return ResponseCode::NETWORK_SSL_INIT_ERROR; - } - -#if OPENSSL_VERSION_NUMBER >= 0x10002000L && OPENSSL_VERSION_NUMBER < 0x10100000L - method = TLSv1_2_method(); -#else - method = TLS_method(); -#endif - - if ((p_ssl_context_ = SSL_CTX_new(method)) == NULL) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " SSL INIT Failed - Unable to create SSL Context"); - return ResponseCode::NETWORK_SSL_INIT_ERROR; - } - - return ResponseCode::SUCCESS; - } - - bool OpenSSLConnection::IsPhysicalLayerConnected() { - // Use this to add implementation which can check for physical layer disconnect - return true; - } - - bool OpenSSLConnection::IsConnected() { - return is_connected_; - } - - ResponseCode OpenSSLConnection::ConnectTCPSocket() { - const char *endpoint_char = endpoint_.c_str(); - if (nullptr == endpoint_char) { - return ResponseCode::NETWORK_TCP_NO_ENDPOINT_SPECIFIED; - } - -#ifndef WIN32 - if (res_init() == -1) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, "DNS initialize error"); - } -#endif - - hostent *host = gethostbyname(endpoint_char); - if (nullptr == host) { - return ResponseCode::NETWORK_TCP_NO_ENDPOINT_SPECIFIED; - } - - sockaddr_in dest_addr; - - dest_addr.sin_family = AF_INET; - dest_addr.sin_port = htons(endpoint_port_); - dest_addr.sin_addr.s_addr = *(uint32_t *) (host->h_addr); - memset(&(dest_addr.sin_zero), '\0', 8); - - AWS_LOG_INFO(OPENSSL_WRAPPER_LOG_TAG, - "resolved %s to %s", - endpoint_.c_str(), - inet_ntoa(dest_addr.sin_addr)); - - int connect_status = connect(server_tcp_socket_fd_, (sockaddr *) &dest_addr, sizeof(sockaddr)); - if (-1 != connect_status) { - return ResponseCode::SUCCESS; - } - -#ifdef WIN32 - closesocket(server_tcp_socket_fd_); -#else - close(server_tcp_socket_fd_); -#endif - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, "connect - %s", strerror(errno)); - return ResponseCode::NETWORK_TCP_CONNECT_ERROR; - } - - ResponseCode OpenSSLConnection::SetSocketToNonBlocking() { - int status; - ResponseCode ret_val = ResponseCode::SUCCESS; -#if defined(WIN32) || defined(WIN64) - u_long flag = 1L; - status = ioctlsocket(server_tcp_socket_fd_, FIONBIO, &flag); - if (0 > status) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, "ioctlsocket - %s", strerror(errno)); - ret_val = ResponseCode::NETWORK_TCP_CONNECT_ERROR; - } -#else - int flags = fcntl(server_tcp_socket_fd_, F_GETFL, 0); - // set underlying socket to non blocking - if (0 > flags) { - ret_val = ResponseCode::NETWORK_TCP_CONNECT_ERROR; - } - - status = fcntl(server_tcp_socket_fd_, F_SETFL, flags | O_NONBLOCK); - if (0 > status) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, "fcntl - %s", strerror(errno)); - ret_val = ResponseCode::NETWORK_TCP_CONNECT_ERROR; - } -#endif - - return ret_val; - } - - ResponseCode OpenSSLConnection::AttemptConnect() { - ResponseCode ret_val = ResponseCode::FAILURE; - int rc = 0; - int errorCode = 0; - int select_retCode = 0; - - do { - ERR_clear_error(); - rc = SSL_connect(p_ssl_handle_); - - if (1 == rc) { //1 = SSL_CONNECTED, <= 0 is Error - ret_val = ResponseCode::SUCCESS; - break; - } - - errorCode = SSL_get_error(p_ssl_handle_, rc); - - if (SSL_ERROR_WANT_READ == errorCode) { - select_retCode = WaitForSelect(errorCode); - if (0 == select_retCode) { // 0 == SELECT_TIMEOUT - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " SSL Connect time out while waiting for read"); - ret_val = ResponseCode::NETWORK_SSL_CONNECT_TIMEOUT_ERROR; - } else if (-1 == select_retCode) { // -1 == SELECT_ERROR - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " SSL Connect Select error for read %d", select_retCode); - ret_val = ResponseCode::NETWORK_SSL_CONNECT_ERROR; - } - } else if (SSL_ERROR_WANT_WRITE == errorCode) { - select_retCode = WaitForSelect(errorCode); - if (0 == select_retCode) { // 0 == SELECT_TIMEOUT - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " SSL Connect time out while waiting for write"); - ret_val = ResponseCode::NETWORK_SSL_CONNECT_TIMEOUT_ERROR; - } else if (-1 == select_retCode) { // -1 == SELECT_ERROR - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, - " SSL Connect Select error for write %d", - select_retCode); - ret_val = ResponseCode::NETWORK_SSL_CONNECT_ERROR; - } - } else { - ret_val = ResponseCode::NETWORK_SSL_CONNECT_ERROR; - } - - } while (ResponseCode::NETWORK_SSL_CONNECT_ERROR != ret_val && - ResponseCode::NETWORK_SSL_CONNECT_TIMEOUT_ERROR != ret_val); - - return ret_val; - } - - ResponseCode OpenSSLConnection::LoadCerts() { - AWS_LOG_DEBUG(OPENSSL_WRAPPER_LOG_TAG, "Root CA : %s", root_ca_location_.c_str()); - if (!SSL_CTX_load_verify_locations(p_ssl_context_, root_ca_location_.c_str(), NULL)) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " Root CA Loading error"); - return ResponseCode::NETWORK_SSL_ROOT_CRT_PARSE_ERROR; - } - - // TODO: streamline error codes for TLS - if (0 < device_cert_location_.length() && 0 < device_private_key_location_.length()) { - AWS_LOG_DEBUG(OPENSSL_WRAPPER_LOG_TAG, "Device crt : %s", device_cert_location_.c_str()); - if (!SSL_CTX_use_certificate_chain_file(p_ssl_context_, device_cert_location_.c_str())) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " Device Certificate Loading error"); - return ResponseCode::NETWORK_SSL_DEVICE_CRT_PARSE_ERROR; - } - AWS_LOG_DEBUG(OPENSSL_WRAPPER_LOG_TAG, "Device privkey : %s", device_private_key_location_.c_str()); - if (1 != SSL_CTX_use_PrivateKey_file(p_ssl_context_, - device_private_key_location_.c_str(), - SSL_FILETYPE_PEM)) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " Device Private Key Loading error"); - return ResponseCode::NETWORK_SSL_KEY_PARSE_ERROR; - } - } - - certificates_read_flag_ = true; - return ResponseCode::SUCCESS; - } - - ResponseCode OpenSSLConnection::PerformSSLConnect() { - ResponseCode networkResponse = ResponseCode::SUCCESS; - - // Configure a non-zero callback if desired - SSL_set_verify(p_ssl_handle_, SSL_VERIFY_PEER, nullptr); - - server_tcp_socket_fd_ = socket(AF_INET, SOCK_STREAM, 0); - if (-1 == server_tcp_socket_fd_) { - return ResponseCode::NETWORK_TCP_SETUP_ERROR; - } - - networkResponse = ConnectTCPSocket(); - if (ResponseCode::SUCCESS != networkResponse) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, "TCP Connection error"); - return networkResponse; - } - - SSL_set_fd(p_ssl_handle_, server_tcp_socket_fd_); - - networkResponse = SetSocketToNonBlocking(); - if (ResponseCode::SUCCESS != networkResponse) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " Unable to set the socket to Non-Blocking"); - } else { - networkResponse = AttemptConnect(); - if (X509_V_OK != SSL_get_verify_result(p_ssl_handle_)) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " Server Certificate Verification failed."); - networkResponse = ResponseCode::NETWORK_SSL_CONNECT_ERROR; - } else { - // ensure you have a valid certificate returned, otherwise no certificate exchange happened - auto cert_destroyer = [](X509 *cert) { - if (nullptr != cert) X509_free(cert); - }; - std::unique_ptr cert(SSL_get_peer_certificate(p_ssl_handle_), - cert_destroyer); - if (nullptr == cert) { - AWS_LOG_ERROR(OPENSSL_WRAPPER_LOG_TAG, " No certificate exchange happened"); - networkResponse = ResponseCode::NETWORK_SSL_CONNECT_ERROR; - } - } - } - - if (ResponseCode::SUCCESS != networkResponse) { -#ifdef WIN32 - closesocket(server_tcp_socket_fd_); -#else - close(server_tcp_socket_fd_); -#endif - } - - return networkResponse; - } - - ResponseCode OpenSSLConnection::ConnectInternal() { - ResponseCode networkResponse = ResponseCode::SUCCESS; - - X509_VERIFY_PARAM *param = nullptr; - - if (!certificates_read_flag_) { - networkResponse = LoadCerts(); - if (ResponseCode::SUCCESS != networkResponse) { - return networkResponse; - } - } - - if (nullptr == p_ssl_handle_) { - p_ssl_handle_ = SSL_new(p_ssl_context_); - } - - // Requires OpenSSL v1.0.2 and above - if (server_verification_flag_) { - param = SSL_get0_param(p_ssl_handle_); - // Enable automatic hostname checks - X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); - - // Check if it is an IPv4 or an IPv6 address to enable ip checking - // Enable host name check otherwise - char dst[INET6_ADDRSTRLEN]; - if (inet_pton(AF_INET, endpoint_.c_str(), (void *) dst) || - inet_pton(AF_INET6, endpoint_.c_str(), (void *) dst)) { - X509_VERIFY_PARAM_set1_ip_asc(param, endpoint_.c_str()); - } else { - X509_VERIFY_PARAM_set1_host(param, endpoint_.c_str(), 0); - } - } - - networkResponse = PerformSSLConnect(); - if (ResponseCode::SUCCESS != networkResponse) { - SSL_free(p_ssl_handle_); - p_ssl_handle_ = nullptr; - } - - if (ResponseCode::SUCCESS == networkResponse) { - is_connected_ = true; - } - - return networkResponse; - } - - ResponseCode OpenSSLConnection::WriteInternal(const util::String &buf, size_t &size_written_bytes_out) { - int error_code = 0; - int select_retCode = -1; - int cur_written_length = 0; - size_t total_written_length = 0; - ResponseCode rc = ResponseCode::SUCCESS; - size_t bytes_to_write = buf.length(); - - do { - ERR_clear_error(); - if (nullptr == p_ssl_handle_) { - return ResponseCode::NETWORK_SSL_WRITE_ERROR; - } - cur_written_length = SSL_write(p_ssl_handle_, buf.c_str(), bytes_to_write); - error_code = SSL_get_error(p_ssl_handle_, cur_written_length); - if (0 < cur_written_length) { - total_written_length += (size_t) cur_written_length; - } else if (SSL_ERROR_WANT_WRITE == error_code) { - select_retCode = WaitForSelect(error_code); - if (0 == select_retCode) { //0 == SELECT_TIMEOUT - rc = ResponseCode::NETWORK_SSL_WRITE_TIMEOUT_ERROR; - } else if (-1 == select_retCode) { //-1 == SELECT_TIMEOUT - rc = ResponseCode::NETWORK_SSL_WRITE_ERROR; - } - } else { - rc = ResponseCode::NETWORK_SSL_WRITE_ERROR; - } - - } while (is_connected_ && ResponseCode::NETWORK_SSL_WRITE_ERROR != rc && - ResponseCode::NETWORK_SSL_WRITE_TIMEOUT_ERROR != rc && - total_written_length < bytes_to_write); - - if (ResponseCode::SUCCESS == rc) { - size_written_bytes_out = total_written_length; - } - - return rc; - } - - ResponseCode OpenSSLConnection::ReadInternal(util::Vector &buf, size_t buf_read_offset, - size_t size_bytes_to_read, size_t &size_read_bytes_out) { - int ssl_retcode; - int select_retCode; - size_t total_read_length = buf_read_offset; - size_t remaining_bytes_to_read = size_bytes_to_read; - int cur_read_len = 0; - ResponseCode errorStatus = ResponseCode::SUCCESS; - - do { - ERR_clear_error(); - if (nullptr == p_ssl_handle_) { - return ResponseCode::NETWORK_SSL_READ_ERROR; - } - cur_read_len = SSL_read(p_ssl_handle_, &buf[total_read_length], (int) remaining_bytes_to_read); - if (0 < cur_read_len) { - total_read_length += (size_t) cur_read_len; - remaining_bytes_to_read -= cur_read_len; - } else { - ssl_retcode = SSL_get_error(p_ssl_handle_, cur_read_len); - switch (ssl_retcode) { - case SSL_ERROR_WANT_READ: - select_retCode = WaitForSelect(SSL_ERROR_WANT_READ); - if (0 < select_retCode) { - continue; - } else if (0 == select_retCode) { //0 == SELECT_TIMEOUT - errorStatus = ResponseCode::NETWORK_SSL_NOTHING_TO_READ; - } else { // SELECT_ERROR - errorStatus = ResponseCode::NETWORK_SSL_READ_ERROR; - } - break; - case SSL_ERROR_ZERO_RETURN: - errorStatus = ResponseCode::NETWORK_SSL_CONNECTION_CLOSED_ERROR; - break; - default: - errorStatus = ResponseCode::NETWORK_SSL_READ_ERROR; - break; - } - } - if (ResponseCode::NETWORK_SSL_NOTHING_TO_READ == errorStatus || - ResponseCode::NETWORK_SSL_READ_ERROR == errorStatus || - ResponseCode::NETWORK_SSL_CONNECTION_CLOSED_ERROR == errorStatus) { - break; - } - } while (is_connected_ && total_read_length < size_bytes_to_read); - - if (ResponseCode::SUCCESS == errorStatus) { - size_read_bytes_out = total_read_length; - } - - return errorStatus; - } - - ResponseCode OpenSSLConnection::DisconnectInternal() { - if (!is_connected_) { - return ResponseCode::SUCCESS; - } - is_connected_ = false; - - std::chrono::milliseconds timeout = std::chrono::milliseconds(tls_read_timeout_.tv_sec * 1000 + - tls_read_timeout_.tv_usec / 1000); - - std::unique_lock shutdown_lock(clean_shutdown_action_lock_); - - // TODO: add config for disconnect timeout - // wait for tls_read_timeout and then exit the shutdown loop if it is not successful - this->shutdown_timeout_condition_.wait_for(shutdown_lock, std::chrono::milliseconds(timeout), [this] { - int rc = SSL_shutdown(p_ssl_handle_); - if (1 == rc) { - return true; - } - int errorCode = SSL_get_error(p_ssl_handle_, rc); - WaitForSelect(errorCode); - return false; - }); - - SSL_free(p_ssl_handle_); - p_ssl_handle_ = nullptr; - -#if OPENSSL_VERSION_NUMBER >= 0x10002000L && OPENSSL_VERSION_NUMBER < 0x10100000L - ERR_remove_thread_state(NULL); -#endif - - certificates_read_flag_ = false; -#ifdef WIN32 - closesocket(server_tcp_socket_fd_); -#else - close(server_tcp_socket_fd_); -#endif - return ResponseCode::SUCCESS; - } - - OpenSSLConnection::~OpenSSLConnection() { - if (is_connected_) { - Disconnect(); - } - SSL_CTX_free(p_ssl_context_); -#ifdef WIN32 - WSACleanup(); -#endif - } - } -} diff --git a/libnymea-core/cloud/OpenSSL/OpenSSLConnection.hpp b/libnymea-core/cloud/OpenSSL/OpenSSLConnection.hpp deleted file mode 100644 index e8aff31e..00000000 --- a/libnymea-core/cloud/OpenSSL/OpenSSLConnection.hpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -/** - * @file OpenSSLConnection.hpp - * @brief Defines a reference implementation for an OpenSSL library wrapper - */ - -#pragma once - -#ifdef WIN32 -#include -#include -#pragma comment(lib,"ws2_32") -#else -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "NetworkConnection.hpp" -#include "ResponseCode.hpp" - -namespace awsiotsdk { - namespace network { - /** - * @brief Dummy class for uninitializing the OpenSSL library' - * - * TODO: This is a hotfix and will be updated after design changes - */ - class OpenSSLInitializer { - private: - // Rule of 5 stuff - // Default constructor - OpenSSLInitializer() = default; - // Default Copy constructor - OpenSSLInitializer(const OpenSSLInitializer &) = default; - // Default Move constructor - OpenSSLInitializer(OpenSSLInitializer &&) = default; - // Default Copy assignment operator - OpenSSLInitializer &operator=(const OpenSSLInitializer &) & = default; - // Default Move assignment operator - OpenSSLInitializer &operator=(OpenSSLInitializer &&) & = default; - - public: - static OpenSSLInitializer* getInstance(); - - ~OpenSSLInitializer(); - - }; - - /** - * @brief OpenSSL Wrapper Class - * - * Defines a reference wrapper for OpenSSL libraries - */ - class OpenSSLConnection : public NetworkConnection { - protected: - static std::atomic_bool is_lib_initialized; ///< Boolean, True = Library is initialized, False otherwise - OpenSSLInitializer *initializer; ///< Pointer to dummy library instance - util::String root_ca_location_; ///< Pointer to string containing the filename (including path) of the root CA file. - util::String device_cert_location_; ///< Pointer to string containing the filename (including path) of the device certificate. - util::String device_private_key_location_; ///< Pointer to string containing the filename (including path) of the device private key file. - bool server_verification_flag_; ///< Boolean. True = perform server certificate hostname validation. False = skip validation \b NOT recommended. - std::atomic_bool is_connected_; ///< Boolean indicating connection status - struct timeval tls_handshake_timeout_; ///< Timeout for TLS handshake command - struct timeval tls_read_timeout_; ///< Timeout for the TLS Read command - struct timeval tls_write_timeout_; ///< Timeout for the TLS Write command - - // Endpoint information - uint16_t endpoint_port_; ///< Endpoint port - util::String endpoint_; ///< Endpoint for this connection - - SSL_CTX *p_ssl_context_; ///< SSL Context instance - SSL *p_ssl_handle_; ///< SSL Handle - int server_tcp_socket_fd_; ///< Server Socket descriptor - - bool certificates_read_flag_; - - std::mutex clean_shutdown_action_lock_; - std::condition_variable shutdown_timeout_condition_; - - /** - * @brief Wait for socket FDs to become ready for read or write operations - * - * It is assumed that this function will be called only on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE - * - * @param error_code - error generated by preceding socket operation - * @return int - return code of the select operation - */ - int WaitForSelect(int error_code); - - /** - * @brief Set TLS socket to non-blocking mode - * - * @return ResponseCode - successful operation or TLS error - */ - ResponseCode SetSocketToNonBlocking(); - - /** - * @brief Create a TCP socket and open the connection - * - * Creates an open socket connection - * - * @return ResponseCode - successful connection or TCP error - */ - ResponseCode ConnectTCPSocket(); - - /** - * @brief Attempt connection - * - * Attempts TLS Connection - * - * @return ResponseCode - successful connection or TLS error - */ - ResponseCode AttemptConnect(); - - /** - * @brief Create a TLS socket and open the connection - * - * Creates an open socket connection including TLS handshake. - * - * @return ResponseCode - successful connection or TLS error - */ - ResponseCode LoadCerts(); - - /** - * @brief Perform the connect process after creating the SSL handle and context - * - * Performs the steps necessary for connecting to an endpoint after the creation of the SSL instance - * - * @return ResponseCode - successful connection or TLS error - */ - ResponseCode PerformSSLConnect(); - - /** - * @brief Create a TLS socket and open the connection - * - * Creates an open socket connection including TLS handshake. - * - * @return ResponseCode - successful connection or TLS error - */ - ResponseCode ConnectInternal(); - - /** - * @brief Write bytes to the network socket - * - * @param util::String - const reference to buffer which should be written to socket - * @return size_t - number of bytes written or Network error - * @return ResponseCode - successful write or Network error code - */ - ResponseCode WriteInternal(const util::String &buf, size_t &size_written_bytes_out); - - /** - * @brief Read bytes from the network socket - * - * @param util::String - reference to buffer where read bytes should be copied - * @param size_t - number of bytes to read - * @param size_t - reference to store number of bytes read - * @return ResponseCode - successful read or TLS error code - */ - ResponseCode ReadInternal(util::Vector &buf, size_t buf_read_offset, - size_t size_bytes_to_read, size_t &size_read_bytes_out); - - /** - * @brief Disconnect from network socket - * - * @return ResponseCode - successful read or TLS error code - */ - ResponseCode DisconnectInternal(); - - public: - - OpenSSLConnection(util::String endpoint, uint16_t endpoint_port, - std::chrono::milliseconds tls_handshake_timeout, - std::chrono::milliseconds tls_read_timeout, - std::chrono::milliseconds tls_write_timeout, - bool server_verification_flag); - - /** - * @brief Constructor for the OpenSSL TLS implementation - * - * Performs any initialization required by the TLS layer. - * - * @param util::String endpoint - The target endpoint to connect to - * @param uint16_t endpoint_port - The port on the target to connect to - * @param util::String root_ca_location - Path of the location of the Root CA - * @param util::String device_cert_location - Path to the location of the Device Cert - * @param util::String device_private_key_location - Path to the location of the device private key file - * @param std::chrono::milliseconds tls_handshake_timeout - The value to use for timeout of handshake operation - * @param std::chrono::milliseconds tls_read_timeout - The value to use for timeout of read operation - * @param std::chrono::milliseconds tls_write_timeout - The value to use for timeout of write operation - * @param bool server_verification_flag - used to decide whether server verification is needed or not - * - */ - OpenSSLConnection(util::String endpoint, uint16_t endpoint_port, util::String root_ca_location, - util::String device_cert_location, util::String device_private_key_location, - std::chrono::milliseconds tls_handshake_timeout, - std::chrono::milliseconds tls_read_timeout, std::chrono::milliseconds tls_write_timeout, - bool server_verification_flag); - - OpenSSLConnection(util::String endpoint, uint16_t endpoint_port, util::String root_ca_location, - std::chrono::milliseconds tls_handshake_timeout, - std::chrono::milliseconds tls_read_timeout, std::chrono::milliseconds tls_write_timeout, - bool server_verification_flag); - - /** - * @brief Initialize the OpenSSL object - * - * Initializes the OpenSSL object - */ - ResponseCode Initialize(); - - /** - * @brief sets the path to the root CA - * - * Called to change the location of the root CA after the constructor has initialized the OpenSSL object. - * - * @param root_ca_location - */ - void SetRootCAPath(util::String root_ca_location) { - root_ca_location_ = root_ca_location; - certificates_read_flag_ = false; - } - - /** - * @brief sets the endpoint and the port - * - * Called to change the endpoint and the port after the constructor has initialized the OpenSSL object. - * @param endpoint - * @param endpoint_port - */ - void SetEndpointAndPort(util::String endpoint, uint16_t endpoint_port) { - endpoint_ = endpoint; - endpoint_port_ = endpoint_port; - } - - /** - * @brief Check if TLS layer is still connected - * - * Called to check if the TLS layer is still connected or not. - * - * @return bool - indicating status of network TLS layer connection - */ - bool IsConnected(); - - /** - * @brief Check if Network Physical layer is still connected - * - * Called to check if the Network Physical layer is still connected or not. - * - * @return bool - indicating status of network physical layer connection - */ - bool IsPhysicalLayerConnected(); - - virtual ~OpenSSLConnection(); - }; - } -} diff --git a/libnymea-core/cloud/awsconnector.cpp b/libnymea-core/cloud/awsconnector.cpp index 3c7a4749..0e50f51f 100644 --- a/libnymea-core/cloud/awsconnector.cpp +++ b/libnymea-core/cloud/awsconnector.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright (C) 2017 Michael Zanetti * + * Copyright (C) 2017-2018 Michael Zanetti * * * * This file is part of nymea. * * * diff --git a/libnymea-core/cloud/awsconnector.h b/libnymea-core/cloud/awsconnector.h index fedf8b93..1b4f3171 100644 --- a/libnymea-core/cloud/awsconnector.h +++ b/libnymea-core/cloud/awsconnector.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright (C) 2017 Michael Zanetti * + * Copyright (C) 2017-2018 Michael Zanetti * * * * This file is part of nymea. * * * @@ -27,13 +27,6 @@ #include -//#include "OpenSSL/OpenSSLConnection.hpp" -//#include -//#include -//#include "util/logging/Logging.hpp" -//#include "util/logging/LogMacros.hpp" -//#include "util/logging/ConsoleLogSystem.hpp" - class AWSConnector : public QObject { Q_OBJECT @@ -93,12 +86,6 @@ private slots: private: quint16 publish(const QString &topic, const QVariantMap &message); void subscribe(const QStringList &topics); -// static void publishCallback(uint16_t actionId, awsiotsdk::ResponseCode rc); -// static void subscribeCallback(uint16_t actionId, awsiotsdk::ResponseCode rc); -// static awsiotsdk::ResponseCode onSubscriptionReceivedCallback(awsiotsdk::util::String topic_name, awsiotsdk::util::String payload, -// std::shared_ptr p_app_handler_data); -// static awsiotsdk::ResponseCode onDisconnectedCallback(awsiotsdk::util::String mqtt_client_id, -// std::shared_ptr p_app_handler_data); void storeRegisteredFlag(bool registered); bool readRegisteredFlag() const; @@ -109,8 +96,6 @@ private: QString getCertificateFingerprint(const QString &certificateFilePath) const; private: -// std::shared_ptr m_networkConnection; -// std::shared_ptr m_client; QMQTT::Client *m_client = nullptr; QString m_currentEndpoint; QString m_caFile; @@ -133,11 +118,6 @@ private: QStringList m_subscriptionCache; QPair m_cachedTURNCredentials; -// std::shared_ptr m_subscriptionContextData; -// std::shared_ptr m_disconnectContextData; - -// static AWSConnector* s_instance; -// QHash m_requestMap; }; Q_DECLARE_METATYPE(AWSConnector::PushNotificationsEndpoint)