2022-09-29 08:35:27 +00:00
|
|
|
/*
|
2024-09-17 19:00:25 +00:00
|
|
|
* Deskflow -- mouse and keyboard sharing utility
|
2025-01-24 00:11:17 +00:00
|
|
|
* SPDX-FileCopyrightText: (C) 2015 - 2022 Symless Ltd.
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
2022-09-29 08:35:27 +00:00
|
|
|
*/
|
2025-01-24 00:11:17 +00:00
|
|
|
|
2022-09-29 08:35:27 +00:00
|
|
|
#include "SslLogger.h"
|
|
|
|
|
#include <iterator>
|
2024-07-02 19:07:06 +00:00
|
|
|
#include <sstream>
|
2022-09-29 08:35:27 +00:00
|
|
|
|
|
|
|
|
#include <base/Log.h>
|
|
|
|
|
#include <openssl/err.h>
|
|
|
|
|
#include <openssl/ssl.h>
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
void showCipherStackDesc(STACK_OF(SSL_CIPHER) * stack)
|
|
|
|
|
{
|
2024-07-02 19:07:06 +00:00
|
|
|
char msg[128] = {0};
|
|
|
|
|
for (int i = 0; i < sk_SSL_CIPHER_num(stack); ++i) {
|
|
|
|
|
auto cipher = sk_SSL_CIPHER_value(stack, i);
|
|
|
|
|
SSL_CIPHER_description(cipher, msg, sizeof(msg));
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// SSL puts a newline in the description
|
2025-05-02 12:03:44 +00:00
|
|
|
if (auto pos = strnlen(msg, sizeof(msg)) - 1; msg[pos] == '\n') {
|
2024-07-02 19:07:06 +00:00
|
|
|
msg[pos] = '\0';
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
LOG((CLOG_DEBUG1 "%s", msg));
|
|
|
|
|
}
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
void logLocalSecureCipherInfo(const SSL *ssl)
|
|
|
|
|
{
|
2024-07-02 19:07:06 +00:00
|
|
|
auto sStack = SSL_get_ciphers(ssl);
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
if (sStack) {
|
|
|
|
|
LOG((CLOG_DEBUG1 "available local ciphers:"));
|
|
|
|
|
showCipherStackDesc(sStack);
|
|
|
|
|
} else {
|
|
|
|
|
LOG((CLOG_DEBUG1 "local cipher list not available"));
|
|
|
|
|
}
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
void logRemoteSecureCipherInfo(const SSL *ssl)
|
|
|
|
|
{
|
2022-09-29 08:35:27 +00:00
|
|
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
2024-07-02 19:07:06 +00:00
|
|
|
// ssl->session->ciphers is not forward compatable,
|
|
|
|
|
// In future release of OpenSSL, it's not visible,
|
|
|
|
|
// however, LibreSSL still uses this.
|
|
|
|
|
auto cStack = ssl->session->ciphers;
|
2022-09-29 08:35:27 +00:00
|
|
|
#else
|
2024-07-02 19:07:06 +00:00
|
|
|
// Use SSL_get_client_ciphers() for newer versions of OpenSSL.
|
|
|
|
|
auto cStack = SSL_get_client_ciphers(ssl);
|
2022-09-29 08:35:27 +00:00
|
|
|
#endif
|
2024-07-02 19:07:06 +00:00
|
|
|
if (cStack) {
|
|
|
|
|
LOG((CLOG_DEBUG1 "available remote ciphers:"));
|
|
|
|
|
showCipherStackDesc(cStack);
|
|
|
|
|
} else {
|
|
|
|
|
LOG((CLOG_DEBUG1 "remote cipher list not available"));
|
|
|
|
|
}
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
} // namespace
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
void SslLogger::logSecureLibInfo()
|
|
|
|
|
{
|
2025-07-07 21:44:21 +00:00
|
|
|
if (CLOG->getFilter() >= LogLevel::Debug) {
|
2024-07-02 19:07:06 +00:00
|
|
|
LOG((CLOG_DEBUG "openssl version: %s", SSLeay_version(SSLEAY_VERSION)));
|
|
|
|
|
LOG((CLOG_DEBUG1 "openssl flags: %s", SSLeay_version(SSLEAY_CFLAGS)));
|
|
|
|
|
LOG((CLOG_DEBUG1 "openssl built on: %s", SSLeay_version(SSLEAY_BUILT_ON)));
|
|
|
|
|
LOG((CLOG_DEBUG1 "openssl platform: %s", SSLeay_version(SSLEAY_PLATFORM)));
|
|
|
|
|
LOG((CLOG_DEBUG1 "openssl dir: %s", SSLeay_version(SSLEAY_DIR)));
|
|
|
|
|
}
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
void SslLogger::logSecureCipherInfo(const SSL *ssl)
|
|
|
|
|
{
|
2025-07-07 21:44:21 +00:00
|
|
|
if (ssl && CLOG->getFilter() >= LogLevel::Debug1) {
|
2024-07-02 19:07:06 +00:00
|
|
|
logLocalSecureCipherInfo(ssl);
|
|
|
|
|
logRemoteSecureCipherInfo(ssl);
|
|
|
|
|
}
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
void SslLogger::logSecureConnectInfo(const SSL *ssl)
|
|
|
|
|
{
|
2024-07-02 19:07:06 +00:00
|
|
|
if (ssl) {
|
|
|
|
|
auto cipher = SSL_get_current_cipher(ssl);
|
|
|
|
|
|
|
|
|
|
if (cipher) {
|
|
|
|
|
char msg[128] = {0};
|
|
|
|
|
SSL_CIPHER_description(cipher, msg, sizeof(msg));
|
|
|
|
|
LOG((CLOG_DEBUG "openssl cipher: %s", msg));
|
|
|
|
|
|
|
|
|
|
// For some reason SSL_get_version is return mismatching information to
|
|
|
|
|
// SSL_CIPHER_description
|
|
|
|
|
// so grab the version out the description instead, This seems like a
|
|
|
|
|
// hacky way of doing it. But when the cipher says "TLSv1.2" but the
|
|
|
|
|
// get_version returns "TLSv1/SSLv3" we it doesn't look right For some
|
|
|
|
|
// reason macOS hates regex's so stringstream is used
|
|
|
|
|
std::istringstream iss(msg);
|
|
|
|
|
|
|
|
|
|
// Take the stream input and splits it into a vetor directly
|
|
|
|
|
const std::vector<std::string> parts{
|
2024-10-17 18:04:35 +00:00
|
|
|
std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}
|
|
|
|
|
};
|
2024-07-02 19:07:06 +00:00
|
|
|
if (parts.size() > 2) {
|
|
|
|
|
// log the section containing the protocol version
|
|
|
|
|
LOG((CLOG_INFO "network encryption protocol: %s", parts[1].c_str()));
|
|
|
|
|
} else {
|
|
|
|
|
// log the error in spliting then display the whole description rather
|
|
|
|
|
// then nothing
|
|
|
|
|
LOG((CLOG_ERR "could not split cipher for protocol"));
|
|
|
|
|
LOG((CLOG_INFO "network encryption protocol: %s", msg));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
LOG((CLOG_ERR "could not get secure socket cipher"));
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|
2024-07-02 19:07:06 +00:00
|
|
|
}
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
void SslLogger::logError(const std::string &reason)
|
|
|
|
|
{
|
2024-07-02 19:07:06 +00:00
|
|
|
if (!reason.empty()) {
|
|
|
|
|
LOG((CLOG_ERR "secure socket error: %s", reason.c_str()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto id = ERR_get_error();
|
|
|
|
|
if (id) {
|
|
|
|
|
char error[65535] = {0};
|
|
|
|
|
ERR_error_string_n(id, error, sizeof(error));
|
|
|
|
|
LOG((CLOG_ERR "openssl error: %s", error));
|
|
|
|
|
}
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
void SslLogger::logErrorByCode(int code, int retry)
|
|
|
|
|
{
|
2024-07-02 19:07:06 +00:00
|
|
|
switch (code) {
|
|
|
|
|
case SSL_ERROR_NONE:
|
|
|
|
|
break;
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
case SSL_ERROR_ZERO_RETURN:
|
|
|
|
|
LOG((CLOG_DEBUG "tls connection closed"));
|
|
|
|
|
break;
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
case SSL_ERROR_WANT_READ:
|
|
|
|
|
LOG((CLOG_DEBUG2 "want to read, error=%d, attempt=%d", code, retry));
|
|
|
|
|
break;
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
case SSL_ERROR_WANT_WRITE:
|
|
|
|
|
LOG((CLOG_DEBUG2 "want to write, error=%d, attempt=%d", code, retry));
|
|
|
|
|
break;
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
case SSL_ERROR_WANT_CONNECT:
|
|
|
|
|
LOG((CLOG_DEBUG2 "want to connect, error=%d, attempt=%d", code, retry));
|
|
|
|
|
break;
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
case SSL_ERROR_WANT_ACCEPT:
|
|
|
|
|
LOG((CLOG_DEBUG2 "want to accept, error=%d, attempt=%d", code, retry));
|
|
|
|
|
break;
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
case SSL_ERROR_SYSCALL:
|
|
|
|
|
LOG((CLOG_ERR "tls error occurred (system call failure)"));
|
|
|
|
|
break;
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
case SSL_ERROR_SSL:
|
|
|
|
|
LOG((CLOG_ERR "tls error occurred (generic failure)"));
|
|
|
|
|
break;
|
2022-09-29 08:35:27 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
default:
|
|
|
|
|
LOG((CLOG_ERR "tls error occurred (unknown failure)"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-09-29 08:35:27 +00:00
|
|
|
}
|