10#define LOC QString("SSL: ")
15 if (!QSslSocket::supportsSsl())
18 LOG(VB_HTTP, LOG_INFO,
LOC + QSslSocket::sslLibraryVersionString());
20 Config = QSslConfiguration::defaultConfiguration();
21 Config.setProtocol(QSsl::SecureProtocols);
22 Config.setSslOption(QSsl::SslOptionDisableLegacyRenegotiation,
true);
23 Config.setSslOption(QSsl::SslOptionDisableCompression,
true);
25 auto availableCiphers = QSslConfiguration::supportedCiphers();
26 QList<QSslCipher> secureCiphers;
27 for (
const auto & cipher : std::as_const(availableCiphers))
30 if (cipher.usedBits() < 128)
33 if (cipher.name().startsWith(
"RC4") ||
34 cipher.name().startsWith(
"EXP") ||
35 cipher.name().startsWith(
"ADH") ||
36 cipher.name().contains(
"NULL"))
39 secureCiphers.append(cipher);
41 Config.setCiphers(secureCiphers);
45 while (configdir.endsWith(
"/"))
47 configdir.append(QStringLiteral(
"/certificates/"));
50 if (hostKeyPath.isEmpty())
51 hostKeyPath = configdir +
"key.pem";
52 LOG(VB_HTTP, LOG_DEBUG,
LOC +
"key " + hostKeyPath);
54 QFile hostKeyFile(hostKeyPath);
55 if (!hostKeyFile.exists() || !hostKeyFile.open(QIODevice::ReadOnly))
57 LOG(VB_GENERAL, LOG_WARNING,
LOC +
58 QString(
"SSL Host key file (%1) does not exist or is not readable").arg(hostKeyPath));
62 auto rawHostKey = hostKeyFile.readAll();
63 auto hostKey = QSslKey(rawHostKey, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
66 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unable to load host key from file (%1)").arg(hostKeyPath));
69 Config.setPrivateKey(hostKey);
72 if (hostCertPath.isEmpty())
73 hostCertPath = configdir +
"cert.pem";
74 LOG(VB_HTTP, LOG_DEBUG,
LOC +
"cert " + hostCertPath);
76 QSslCertificate hostCert;
77 auto certList = QSslCertificate::fromPath(hostCertPath);
78 if (!certList.isEmpty())
79 hostCert = certList.first();
81 if (hostCert.isNull())
83 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unable to load host cert from file (%1)").arg(hostCertPath));
86 if (hostCert.effectiveDate() > QDateTime::currentDateTime())
88 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Host certificate start date in future (%1)").arg(hostCertPath));
91 if (hostCert.expiryDate() < QDateTime::currentDateTime())
93 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Host certificate has expired (%1)").arg(hostCertPath));
97 Config.setLocalCertificate(hostCert);
100 bool caCertPathDefault {
false};
101 if (caCertPath.isEmpty())
103 caCertPath = configdir +
"cacert.pem";
104 caCertPathDefault =
true;
106 LOG(VB_HTTP, LOG_DEBUG,
LOC +
"cacert " + caCertPath);
107 auto CACertList = QSslCertificate::fromPath(caCertPath);
108 if (!CACertList.isEmpty())
110 Config.setCaCertificates(CACertList);
112 else if (!caCertPathDefault)
115 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unable to load CA cert file (%1)").arg(caCertPath));
125 auto Encrypted = [](
const QSslSocket* SslSocket)
127 LOG(VB_HTTP, LOG_INFO,
LOC +
"Socket encrypted");
129 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Cypher: %1").arg(SslSocket->sessionCipher().name()));
132 auto SSLErrors = [](
const QList<QSslError>& Errors)
134 for (
const auto &
error : Errors)
135 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"SslError: %1").arg(
error.errorString()));
138 QObject::connect(Socket, &QSslSocket::encrypted,
139 Socket, [Encrypted, Socket] { Encrypted(Socket); } );
140 QObject::connect(Socket, qOverload<
const QList<QSslError> &>(&QSslSocket::sslErrors),
142 Socket->setSslConfiguration(Config);
143 Socket->startServerEncryption();
QString GetSetting(const QString &key, const QString &defaultval="")
static void InitSSLSocket(QSslSocket *Socket, QSslConfiguration &Config)
static bool InitSSLServer(QSslConfiguration &Config)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)