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

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