-
Notifications
You must be signed in to change notification settings - Fork 0
/
RelayServer.cpp
191 lines (162 loc) · 6.06 KB
/
RelayServer.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include <Qfile>
#include "RelayServer.h"
RelayServer::RelayServer(QObject *parent) : QObject(parent){
mSslServer = new SslServer(this);
/*
* .crt file: Is a .pem (or rarely .der) formatted file with a different extension,
* one that is recognized by Windows Explorer as a certificate,
* which .pem is not.
*/
QFile certFile("dvp_cert_cc_signed.cert.pem");
//certFile.open(QIODevice::ReadOnly);
if(!certFile.open(QIODevice::ReadOnly ))
{
qDebug() << "Could not open file for reading";
}
QSslCertificate certificate( &certFile, QSsl::Pem );
certFile.close();
/*
* .key file: Is a PEM formatted file containing just the private-key of a specific
* certificate and is merely a conventional name and not a standardized one. The
* rights on these files are very important, and some programs will refuse to
* load these certificates if they are set wrong.
*/
QFile keyFile("dvp_cert_cc_signed.key.pem");
//keyFile.open(QIODevice::ReadOnly);
if(!keyFile.open(QIODevice::ReadOnly))
{
qDebug() << "Could not open file for reading";
}
QSslKey sslKey( &keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
keyFile.close();
mSslServer->setSslLocalCertificate( certificate );
mSslServer->setSslPrivateKey( sslKey );
/*
* We want to find the protocol support sweet spot by supporting
* older protocols but enforcing the newer TLS protocol.
*
* Ref: http://doc.qt.io/qt-5/qssl.html#SslProtocol-enum
*/
mSslServer->setSslProtocol( QSsl::TlsV1_0 );
/*
* This setting does not apply to a server but I am leaving it
* just as a note of something that will need to be considered
* in the future development of this program. Eventually it should
* be set to QSslSocket::VerifyPeer as opposed to the default value
* of QSslSocket::QueryPeer.
*
* Ref: http://doc.qt.io/qt-5/qsslsocket.html#PeerVerifyMode-enum
*/
//mSslServer->setSslPeerVerifyMode( QSslSocket::VerifyNone );
// newConnection() is a signal emitted by SslServer Class and
// is inherited from the QTcpServer Class
connect(mSslServer, SIGNAL(newConnection()), this, SLOT(acceptNewConnection()));
// Listen in on any address accessible through the local interfaces.
// This will likely be localhost (127.0.0.1:8080)
if(!mSslServer->listen(QHostAddress::Any, 8080)){
qDebug() << "Relay Server could not start :(";
}
else{
qDebug() << "Relay Server started and listening...";
}
}
/**
* Sets the host and port that will be used to connect to the static proxy
* @brief ClientConnection::setSP
* @param host IP of the host
* @param port Port number of the host
*/
void RelayServer::setStaticProxy(const QString & host, quint16 port){
mSP_Port = port;
mSP_Host = host;
//mSP_Host = "127.0.0.1";
//mSP_Port = 8081;
}
/**
* [Slot] Accepts the next pending SSL socket conenction.
* @brief ClientConnection::acceptNewConnection
*/
void RelayServer::acceptNewConnection()
{
mClientSocket = (QSslSocket *) mSslServer->nextPendingConnection();
//mClientDataStream.setDevice(mClientSocket);
//mClientDataStream.setVersion(QDataStream::Qt_5_6);
connect(mClientSocket, SIGNAL(encrypted()), this, SLOT(handshakeSuccessful()));
connect(mClientSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(onSslErrors(QList<QSslError>)));
connect(mClientSocket, SIGNAL(peerVerifyError(QSslError)), this, SLOT(onPeerVerifyError(QSslError)));
// Initiate the TLS handshake
mClientSocket->startServerEncryption();
qDebug() << "Connection received, waiting to encrypt";
}
/**
* [Slot] Called when the TLS handshake succeeds
* @brief RelayServer::handshakeSuccessful
*/
void RelayServer::handshakeSuccessful()
{
this->connectToSPorFail();
}
/**
* Attempt to connect to the static proxy. Fail if not able.
* @brief ClientConnection::connectToSPorFail
*/
void RelayServer::connectToSPorFail(){
qDebug() << "Connecting to Static Proxy...";
mStaticProxy = new StaticProxyConnection(this);
mStaticProxy->connectTo(mSP_Host, mSP_Port);
qDebug() << "Connected to Static Proxy and waiting for data transfer";
connect(mClientSocket, SIGNAL(readyRead()), this, SLOT(clientToServerWrite()));
}
/**
* [Slot] Handles the client socket's readyRead signal
* @brief ClientConnection::clientToServerWrite
*/
void RelayServer::clientToServerWrite(){
qDebug() << "[RelayServer] Proposed " << mClientSocket->bytesAvailable() << "bytesAvailable from client";
//if(mClientSocket->bytesAvailable() == 1){ mClientSocket->waitForReadyRead(1000);}
//QByteArray data = mClientSocket->read(mClientSocket->bytesAvailable());
QByteArray data = mClientSocket->readAll();
qDebug() << "[RelayServer] Request [" << data.length() << "] "<< data;
mStaticProxy->write(data);
}
/**
* [Slot] Handle the server socket's readyRead signal
* @brief ClientConnection::serverToClientWrite
*/
void RelayServer::serverToClientWrite(){
qDebug() << "[RelayServer] Proposed " << mStaticProxy->bytesAvailable() << "bytesAvailable from server";
QByteArray data = mStaticProxy->readBytesAvailable();
qDebug() << "[RelayServer] Response [" << data.length() << "] " << data;
mClientSocket->write(data);
}
/**
* Public slot that will handle SSL Socket generated errors.
*
* @brief SslServer::onSslErrors
* @param errors
*/
void RelayServer::onSslErrors(const QList <QSslError> & errors)
{
qDebug() << "Errors with SSL";
foreach (const QSslError &error, errors)
{
qDebug() << error.errorString();
}
}
void RelayServer::onPeerVerifyError(const QSslError & error)
{
qDebug() << error.errorString();
}
/**
* Stops the SSL Server from listening on the current address and port
* @brief ClientConnection::stopListening
*/
void RelayServer::stopListening(){
if(mSslServer->isListening()){
//mSslServer->close();
qDebug() << "stopped listening";
}
// Delete the SSL server object and clean up
mSslServer->deleteLater();
mSslServer = NULL;
}