1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QSOCKS5SOCKETENGINE_P_H
6#define QSOCKS5SOCKETENGINE_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtNetwork/private/qtnetworkglobal_p.h>
20
21#include <QtNetwork/qnetworkproxy.h>
22
23#include "qabstractsocketengine_p.h"
24
25QT_REQUIRE_CONFIG(socks5);
26
27QT_BEGIN_NAMESPACE
28
29class QSocks5SocketEnginePrivate;
30
31class Q_AUTOTEST_EXPORT QSocks5SocketEngine : public QAbstractSocketEngine
32{
33 Q_OBJECT
34public:
35 QSocks5SocketEngine(QObject *parent = nullptr);
36 ~QSocks5SocketEngine();
37
38 bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) override;
39 bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) override;
40
41 void setProxy(const QNetworkProxy &networkProxy);
42
43 qintptr socketDescriptor() const override;
44
45 bool isValid() const override;
46
47 bool connectInternal();
48 bool connectToHost(const QHostAddress &address, quint16 port) override;
49 bool connectToHostByName(const QString &name, quint16 port) override;
50 bool bind(const QHostAddress &address, quint16 port) override;
51 bool listen(int backlog) override;
52 qintptr accept() override;
53 void close() override;
54
55 qint64 bytesAvailable() const override;
56
57 qint64 read(char *data, qint64 maxlen) override;
58 qint64 write(const char *data, qint64 len) override;
59
60#ifndef QT_NO_UDPSOCKET
61#ifndef QT_NO_NETWORKINTERFACE
62 bool joinMulticastGroup(const QHostAddress &groupAddress,
63 const QNetworkInterface &iface) override;
64 bool leaveMulticastGroup(const QHostAddress &groupAddress,
65 const QNetworkInterface &iface) override;
66 QNetworkInterface multicastInterface() const override;
67 bool setMulticastInterface(const QNetworkInterface &iface) override;
68#endif // QT_NO_NETWORKINTERFACE
69
70 bool hasPendingDatagrams() const override;
71 qint64 pendingDatagramSize() const override;
72#endif // QT_NO_UDPSOCKET
73
74 qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = nullptr,
75 PacketHeaderOptions = WantNone) override;
76 qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) override;
77 qint64 bytesToWrite() const override;
78
79 int option(SocketOption option) const override;
80 bool setOption(SocketOption option, int value) override;
81
82 bool waitForRead(QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout},
83 bool *timedOut = nullptr) override;
84 bool waitForWrite(QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout},
85 bool *timedOut = nullptr) override;
86 bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
87 bool checkRead, bool checkWrite,
88 QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout},
89 bool *timedOut = nullptr) override;
90
91 bool isReadNotificationEnabled() const override;
92 void setReadNotificationEnabled(bool enable) override;
93 bool isWriteNotificationEnabled() const override;
94 void setWriteNotificationEnabled(bool enable) override;
95 bool isExceptionNotificationEnabled() const override;
96 void setExceptionNotificationEnabled(bool enable) override;
97
98private:
99 Q_DECLARE_PRIVATE(QSocks5SocketEngine)
100 Q_DISABLE_COPY_MOVE(QSocks5SocketEngine)
101 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketConnected())
102 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketReadNotification())
103 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketErrorOccurred(QAbstractSocket::SocketError))
104#ifndef QT_NO_UDPSOCKET
105 Q_PRIVATE_SLOT(d_func(), void _q_udpSocketReadNotification())
106#endif
107 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketBytesWritten())
108 Q_PRIVATE_SLOT(d_func(), void _q_emitPendingReadNotification())
109 Q_PRIVATE_SLOT(d_func(), void _q_emitPendingWriteNotification())
110 Q_PRIVATE_SLOT(d_func(), void _q_emitPendingConnectionNotification())
111 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketDisconnected())
112 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketStateChanged(QAbstractSocket::SocketState))
113
114};
115
116
117class QTcpSocket;
118
119class QSocks5Authenticator
120{
121public:
122 QSocks5Authenticator();
123 virtual ~QSocks5Authenticator();
124 virtual char methodId();
125 virtual bool beginAuthenticate(QTcpSocket *socket, bool *completed);
126 virtual bool continueAuthenticate(QTcpSocket *socket, bool *completed);
127
128 bool seal(const QByteArray &buf, QByteArray *sealedBuf);
129 bool unSeal(const QByteArray &sealedBuf, QByteArray *buf);
130 bool unSeal(QTcpSocket *sealedSocket, QByteArray *buf);
131
132 virtual QString errorString() { return QString(); }
133};
134
135class QSocks5PasswordAuthenticator : public QSocks5Authenticator
136{
137public:
138 QSocks5PasswordAuthenticator(const QString &userName, const QString &password);
139 char methodId() override;
140 bool beginAuthenticate(QTcpSocket *socket, bool *completed) override;
141 bool continueAuthenticate(QTcpSocket *socket, bool *completed) override;
142
143 QString errorString() override;
144
145private:
146 QString userName;
147 QString password;
148};
149
150struct QSocks5Data;
151struct QSocks5ConnectData;
152struct QSocks5UdpAssociateData;
153struct QSocks5BindData;
154
155class QSocks5SocketEnginePrivate : public QAbstractSocketEnginePrivate
156{
157 Q_DECLARE_PUBLIC(QSocks5SocketEngine)
158public:
159 QSocks5SocketEnginePrivate();
160 ~QSocks5SocketEnginePrivate();
161
162 enum Socks5State
163 {
164 Uninitialized = 0,
165 ConnectError,
166 AuthenticationMethodsSent,
167 Authenticating,
168 AuthenticatingError,
169 RequestMethodSent,
170 RequestError,
171 Connected,
172 UdpAssociateSuccess,
173 BindSuccess,
174 ControlSocketError,
175 SocksError,
176 HostNameLookupError
177 };
178 Socks5State socks5State;
179
180 enum Socks5Mode
181 {
182 NoMode,
183 ConnectMode,
184 BindMode,
185 UdpAssociateMode
186 };
187 Socks5Mode mode;
188
189 enum Socks5Error
190 {
191 SocksFailure = 0x01,
192 ConnectionNotAllowed = 0x02,
193 NetworkUnreachable = 0x03,
194 HostUnreachable = 0x04,
195 ConnectionRefused = 0x05,
196 TTLExpired = 0x06,
197 CommandNotSupported = 0x07,
198 AddressTypeNotSupported = 0x08,
199 LastKnownError = AddressTypeNotSupported,
200 UnknownError
201 };
202
203 void initialize(Socks5Mode socks5Mode);
204
205 void setErrorState(Socks5State state, const QString &extraMessage = QString());
206 void setErrorState(Socks5State state, Socks5Error socks5error);
207
208 void reauthenticate();
209 void parseAuthenticationMethodReply();
210 void parseAuthenticatingReply();
211 void sendRequestMethod();
212 void parseRequestMethodReply();
213 void parseNewConnection();
214
215 bool waitForConnected(QDeadlineTimer deadline, bool *timedOut);
216
217 void _q_controlSocketConnected();
218 void _q_controlSocketReadNotification();
219 void _q_controlSocketErrorOccurred(QAbstractSocket::SocketError);
220#ifndef QT_NO_UDPSOCKET
221 void _q_udpSocketReadNotification();
222#endif
223 void _q_controlSocketBytesWritten();
224 void _q_controlSocketDisconnected();
225 void _q_controlSocketStateChanged(QAbstractSocket::SocketState);
226
227 QNetworkProxy proxyInfo;
228
229 bool readNotificationEnabled, writeNotificationEnabled, exceptNotificationEnabled;
230
231 qintptr socketDescriptor;
232
233 QSocks5Data *data;
234 QSocks5ConnectData *connectData;
235#ifndef QT_NO_UDPSOCKET
236 QSocks5UdpAssociateData *udpData;
237#endif
238 QSocks5BindData *bindData;
239 QString peerName;
240 QByteArray receivedHeaderFragment;
241
242 mutable bool readNotificationActivated;
243 mutable bool writeNotificationActivated;
244
245 bool readNotificationPending;
246 void _q_emitPendingReadNotification();
247 void emitReadNotification();
248 bool writeNotificationPending;
249 void _q_emitPendingWriteNotification();
250 void emitWriteNotification();
251 bool connectionNotificationPending;
252 void _q_emitPendingConnectionNotification();
253 void emitConnectionNotification();
254};
255
256class Q_AUTOTEST_EXPORT QSocks5SocketEngineHandler : public QSocketEngineHandler
257{
258public:
259 virtual QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType,
260 const QNetworkProxy &, QObject *parent) override;
261 virtual QAbstractSocketEngine *createSocketEngine(qintptr socketDescriptor, QObject *parent) override;
262};
263
264QT_END_NAMESPACE
265
266#endif // QSOCKS5SOCKETENGINE_H
267

source code of qtbase/src/network/socket/qsocks5socketengine_p.h