forked from Skycoder42/QtRemoteObjectsSslBackend
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsslremoteobjects.cpp
139 lines (118 loc) · 3.82 KB
/
sslremoteobjects.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "sslremoteobjects.h"
#include <QUrlQuery>
#include <QUuid>
#include <QCoreApplication>
#include <QFile>
#include <QSslKey>
#include <QMutex>
#include "rosslclientio.h"
#include "rosslserverio.h"
namespace {
QMutex _sslMutex;
QHash<QString, QSslConfiguration> _sslConfigs;
QUrl createBaseUrl(const QString &host, quint16 port)
{
QUrl url;
url.setScheme(SslRemoteObjects::UrlScheme);
url.setHost(host);
url.setPort(port);
return url;
}
void __setup_tslro()
{
qRegisterRemoteObjectsServer<RoSslServer>(SslRemoteObjects::UrlScheme);
qRegisterRemoteObjectsClient<RoSslClientIo>(SslRemoteObjects::UrlScheme);
}
}
Q_COREAPP_STARTUP_FUNCTION(__setup_tslro)
const QString SslRemoteObjects::UrlScheme = QStringLiteral("ssl");
QUrl SslRemoteObjects::generateP12Url(const QString &host, quint16 port, const QString &path, const QString &passPhrase, bool clearCaCerts, bool requireClientAuth)
{
auto url = createBaseUrl(host, port);
url.setPath(QStringLiteral("/p12"));
QUrlQuery query;
query.addQueryItem(QStringLiteral("path"), path);
if(!passPhrase.isEmpty())
query.addQueryItem(QStringLiteral("pass"), passPhrase);
if(!clearCaCerts)
query.addQueryItem(QStringLiteral("keepca"), QString());
if(!requireClientAuth)
query.addQueryItem(QStringLiteral("noauth"), QString());
url.setQuery(query);
return url;
}
QUrl SslRemoteObjects::generateConfigUrl(const QString &host, quint16 port, const QSslConfiguration &config)
{
auto url = createBaseUrl(host, port);
url.setPath(QStringLiteral("/conf"));
QUrlQuery query;
query.addQueryItem(QStringLiteral("key"), prepareSslConfig(config));
url.setQuery(query);
return url;
}
QUrl SslRemoteObjects::generatePlainUrl(const QString &host, quint16 port, bool verifyPartner)
{
auto url = createBaseUrl(host, port);
url.setPath(QStringLiteral("/plain"));
if(verifyPartner) {
QUrlQuery query;
query.addQueryItem(QStringLiteral("verify"), QString());
url.setQuery(query);
}
return url;
}
QString SslRemoteObjects::prepareSslConfig(const QSslConfiguration &config)
{
QMutexLocker locker(&_sslMutex);
auto id = QUuid::createUuid().toString();
_sslConfigs.insert(id, config);
return id;
}
QSslConfiguration SslRemoteObjects::getSslConfig(const QString &key)
{
QMutexLocker locker(&_sslMutex);
return _sslConfigs.value(key);
}
QSslConfiguration SslRemoteObjects::prepareFromUrl(const QUrl &url)
{
auto type = url.path();
QUrlQuery params(url);
if(type == QStringLiteral("/p12")) {
QFile file(params.queryItemValue(QStringLiteral("path")));
if(!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open file" << file.fileName() << "with error:"
<< file.errorString();
return {};
}
QByteArray passPhrase;
if(params.hasQueryItem(QStringLiteral("pass")))
passPhrase = params.queryItemValue(QStringLiteral("pass")).toUtf8();
QSslKey key;
QSslCertificate cert;
QList<QSslCertificate> caCerts;
if(!QSslCertificate::importPkcs12(&file, &key, &cert, &caCerts, passPhrase)) {
qCritical() << "Failed to read" << file.fileName() << "as PKCS#12 files";
return {};
}
file.close();
auto conf = QSslConfiguration::defaultConfiguration();
if(!params.hasQueryItem(QStringLiteral("noauth")))
conf.setPeerVerifyMode(QSslSocket::VerifyPeer);
if(params.hasQueryItem(QStringLiteral("keepca")))
caCerts.append(conf.caCertificates());
conf.setCaCertificates(caCerts);
conf.setLocalCertificate(cert);
conf.setPrivateKey(key);
return conf;
} else if(type == QStringLiteral("/conf"))
return getSslConfig(params.queryItemValue(QStringLiteral("key")));
else if(type == QStringLiteral("/plain")){
auto conf = QSslConfiguration::defaultConfiguration();
if(!params.hasQueryItem(QStringLiteral("verify")))
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
return conf;
} else {
qCritical() << "Invalid remote objects TLS url" << url;
return QSslConfiguration();
}
}