diff options
| -rw-r--r-- | Swiften/Client/CoreClient.cpp | 2 | ||||
| -rw-r--r-- | Swiften/Network/BOSHConnection.cpp | 6 | ||||
| -rw-r--r-- | Swiften/TLS/OpenSSL/OpenSSLContext.cpp | 23 | ||||
| -rw-r--r-- | Swiften/TLS/TLSContext.h | 1 | ||||
| -rw-r--r-- | Swiften/TLS/TLSError.h | 18 |
5 files changed, 30 insertions, 20 deletions
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp index d3711cb..ccde0c2 100644 --- a/Swiften/Client/CoreClient.cpp +++ b/Swiften/Client/CoreClient.cpp @@ -310,18 +310,20 @@ void CoreClient::handleSessionFinished(std::shared_ptr<Error> error) { } clientError.setErrorCode(actualError->errorCode); } else if (std::shared_ptr<TLSError> actualError = std::dynamic_pointer_cast<TLSError>(error)) { switch(actualError->getType()) { case TLSError::CertificateCardRemoved: clientError = ClientError(ClientError::CertificateCardRemoved); break; case TLSError::UnknownError: + case TLSError::AcceptFailed: + case TLSError::ConnectFailed: clientError = ClientError(ClientError::TLSError); break; } } else if (std::shared_ptr<SessionStream::SessionStreamError> actualError = std::dynamic_pointer_cast<SessionStream::SessionStreamError>(error)) { switch(actualError->type) { case SessionStream::SessionStreamError::ParseError: clientError = ClientError(ClientError::XMLError); break; diff --git a/Swiften/Network/BOSHConnection.cpp b/Swiften/Network/BOSHConnection.cpp index 4bbb121..aaec9f2 100644 --- a/Swiften/Network/BOSHConnection.cpp +++ b/Swiften/Network/BOSHConnection.cpp @@ -1,17 +1,17 @@ /* * Copyright (c) 2011 Thilo Cestonaro * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2011-2018 Isode Limited. + * Copyright (c) 2011-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Network/BOSHConnection.h> #include <string> #include <thread> @@ -87,20 +87,20 @@ void BOSHConnection::handleTLSNetowrkDataWriteRequest(const SafeByteArray& data) SWIFT_LOG(debug) << std::endl; connection_->write(data); } void BOSHConnection::handleRawDataRead(std::shared_ptr<SafeByteArray> data) { SWIFT_LOG(debug) << std::endl; tlsLayer_->handleDataRead(*data.get()); } -void BOSHConnection::handleTLSError(std::shared_ptr<TLSError> /* error */) { - +void BOSHConnection::handleTLSError(std::shared_ptr<TLSError> error) { + SWIFT_LOG(debug) << (error ? error->getMessage() : "Unknown TLS error") << std::endl; } void BOSHConnection::writeData(const SafeByteArray& data) { if (tlsLayer_) { tlsLayer_->writeData(data); } else { connection_->write(data); } diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp index 89917ee..968ef8f 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp +++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2010-2018 Isode Limited. + * Copyright (c) 2010-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Base/Platform.h> #ifdef SWIFTEN_PLATFORM_WINDOWS #include <windows.h> #include <wincrypt.h> @@ -174,44 +174,45 @@ void OpenSSLContext::initAndSetBIOs() { writeBIO_ = BIO_new(BIO_s_mem()); SSL_set_bio(handle_.get(), readBIO_, writeBIO_); } void OpenSSLContext::accept() { assert(mode_ == Mode::Server); handle_ = std::unique_ptr<SSL>(SSL_new(context_.get())); if (!handle_) { state_ = State::Error; - onError(std::make_shared<TLSError>()); + onError(std::make_shared<TLSError>(TLSError::AcceptFailed, openSSLInternalErrorToString())); return; } initAndSetBIOs(); state_ = State::Accepting; doAccept(); } void OpenSSLContext::connect() { connect(std::string()); } void OpenSSLContext::connect(const std::string& requestedServerName) { assert(mode_ == Mode::Client); handle_ = std::unique_ptr<SSL>(SSL_new(context_.get())); if (!handle_) { state_ = State::Error; - onError(std::make_shared<TLSError>()); + onError(std::make_shared<TLSError>(TLSError::ConnectFailed, openSSLInternalErrorToString())); return; } if (!requestedServerName.empty()) { if (SSL_set_tlsext_host_name(handle_.get(), const_cast<char*>(requestedServerName.c_str())) != 1) { - SWIFT_LOG(error) << "Failed on SSL_set_tlsext_host_name()." << std::endl; + onError(std::make_shared<TLSError>(TLSError::ConnectFailed, "Failed to set Server Name Indication: " + openSSLInternalErrorToString()));\ + return; } } // Ownership of BIOs is transferred to the SSL_CTX instance in handle_. initAndSetBIOs(); state_ = State::Connecting; doConnect(); } @@ -231,21 +232,20 @@ void OpenSSLContext::doAccept() { break; } case SSL_ERROR_WANT_READ: sendPendingDataToNetwork(); break; case SSL_ERROR_WANT_WRITE: sendPendingDataToNetwork(); break; default: - SWIFT_LOG(warning) << openSSLInternalErrorToString() << std::endl; state_ = State::Error; - onError(std::make_shared<TLSError>()); + onError(std::make_shared<TLSError>(TLSError::AcceptFailed, openSSLInternalErrorToString())); sendPendingDataToNetwork(); } } void OpenSSLContext::doConnect() { int connectResult = SSL_connect(handle_.get()); int error = SSL_get_error(handle_.get(), connectResult); switch (error) { case SSL_ERROR_NONE: { @@ -254,21 +254,21 @@ void OpenSSLContext::doConnect() { //const char* comp = SSL_get_current_compression(handle_.get()); //std::cout << "Compression: " << SSL_COMP_get_name(comp) << std::endl; onConnected(); break; } case SSL_ERROR_WANT_READ: sendPendingDataToNetwork(); break; default: - SWIFT_LOG(warning) << openSSLInternalErrorToString() << std::endl; state_ = State::Error; onError(std::make_shared<TLSError>()); + onError(std::make_shared<TLSError>(TLSError::ConnectFailed, openSSLInternalErrorToString())); } } int OpenSSLContext::handleServerNameCallback(SSL* ssl, int*, void* arg) { if (ssl == nullptr) return SSL_TLSEXT_ERR_NOACK; const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); if (servername) { @@ -306,40 +306,41 @@ void OpenSSLContext::handleDataFromNetwork(const SafeByteArray& data) { case State::Connected: sendPendingDataToApplication(); break; case State::Start: assert(false); break; case State::Error: /*assert(false);*/ break; } } void OpenSSLContext::handleDataFromApplication(const SafeByteArray& data) { - if (SSL_write(handle_.get(), vecptr(data), data.size()) >= 0) { - sendPendingDataToNetwork(); + auto ret = SSL_write(handle_.get(), vecptr(data), data.size()); + if (ret > 0 || SSL_get_error(handle_.get(), ret) == SSL_ERROR_WANT_READ) { + sendPendingDataToNetwork(); } else { state_ = State::Error; - onError(std::make_shared<TLSError>()); + onError(std::make_shared<TLSError>(TLSError::UnknownError, openSSLInternalErrorToString())); } } void OpenSSLContext::sendPendingDataToApplication() { SafeByteArray data; data.resize(SSL_READ_BUFFERSIZE); int ret = SSL_read(handle_.get(), vecptr(data), data.size()); while (ret > 0) { data.resize(ret); onDataForApplication(data); data.resize(SSL_READ_BUFFERSIZE); ret = SSL_read(handle_.get(), vecptr(data), data.size()); } if (ret < 0 && SSL_get_error(handle_.get(), ret) != SSL_ERROR_WANT_READ) { state_ = State::Error; - onError(std::make_shared<TLSError>()); + onError(std::make_shared<TLSError>(TLSError::UnknownError, openSSLInternalErrorToString())); } } bool OpenSSLContext::setCertificateChain(const std::vector<Certificate::ref>& certificateChain) { if (certificateChain.size() == 0) { SWIFT_LOG(warning) << "Trying to load empty certificate chain." << std::endl; return false; } diff --git a/Swiften/TLS/TLSContext.h b/Swiften/TLS/TLSContext.h index 55a86cd..9b0a2eb 100644 --- a/Swiften/TLS/TLSContext.h +++ b/Swiften/TLS/TLSContext.h @@ -44,19 +44,18 @@ namespace Swift { virtual void handleDataFromApplication(const SafeByteArray&) = 0; Certificate::ref getPeerCertificate() const; virtual std::vector<Certificate::ref> getPeerCertificateChain() const = 0; virtual CertificateVerificationError::ref getPeerCertificateVerificationError() const = 0; virtual ByteArray getFinishMessage() const = 0; virtual ByteArray getPeerFinishMessage() const; - public: enum class Mode { Client, Server }; public: boost::signals2::signal<void (const SafeByteArray&)> onDataForNetwork; boost::signals2::signal<void (const SafeByteArray&)> onDataForApplication; diff --git a/Swiften/TLS/TLSError.h b/Swiften/TLS/TLSError.h index ae775e6..9e4af2f 100644 --- a/Swiften/TLS/TLSError.h +++ b/Swiften/TLS/TLSError.h @@ -1,33 +1,41 @@ /* - * Copyright (c) 2012-2016 Isode Limited. + * Copyright (c) 2012-2019 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <memory> +#include <string> #include <Swiften/Base/API.h> #include <Swiften/Base/Error.h> namespace Swift { class SWIFTEN_API TLSError : public Error { public: typedef std::shared_ptr<TLSError> ref; enum Type { UnknownError, - CertificateCardRemoved + CertificateCardRemoved, + AcceptFailed, + ConnectFailed }; - TLSError(Type type = UnknownError) : type(type) {} + TLSError(Type type = UnknownError, std::string message = "") : type_(type), message_(std::move(message)) {} Type getType() const { - return type; + return type_; + } + + const std::string& getMessage() const { + return message_; } private: - Type type; + Type type_; + std::string message_; }; } |
Swift