Coverage Report

Created: 2026-03-12 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/network/socket/qsocks5socketengine_p.h
Line
Count
Source
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
25
QT_REQUIRE_CONFIG(socks5);
26
27
QT_BEGIN_NAMESPACE
28
29
class QSocks5SocketEnginePrivate;
30
31
class Q_AUTOTEST_EXPORT QSocks5SocketEngine : public QAbstractSocketEngine
32
{
33
0
    Q_OBJECT
34
0
public:
35
0
    QSocks5SocketEngine(QObject *parent = nullptr);
36
0
    ~QSocks5SocketEngine();
37
0
38
0
    bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) override;
39
0
    bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) override;
40
0
41
0
    void setProxy(const QNetworkProxy &networkProxy);
42
0
43
0
    qintptr socketDescriptor() const override;
44
0
45
0
    bool isValid() const override;
46
0
47
0
    bool connectInternal();
48
0
    bool connectToHost(const QHostAddress &address, quint16 port) override;
49
0
    bool connectToHostByName(const QString &name, quint16 port) override;
50
0
    bool bind(const QHostAddress &address, quint16 port) override;
51
0
    bool listen(int backlog) override;
52
0
    qintptr accept() override;
53
0
    void close() override;
54
0
55
0
    qint64 bytesAvailable() const override;
56
0
57
0
    qint64 read(char *data, qint64 maxlen) override;
58
0
    qint64 write(const char *data, qint64 len) override;
59
0
60
0
#ifndef QT_NO_UDPSOCKET
61
0
#ifndef QT_NO_NETWORKINTERFACE
62
0
    bool joinMulticastGroup(const QHostAddress &groupAddress,
63
0
                            const QNetworkInterface &iface) override;
64
0
    bool leaveMulticastGroup(const QHostAddress &groupAddress,
65
0
                             const QNetworkInterface &iface) override;
66
0
    QNetworkInterface multicastInterface() const override;
67
0
    bool setMulticastInterface(const QNetworkInterface &iface) override;
68
0
#endif // QT_NO_NETWORKINTERFACE
69
0
70
0
    bool hasPendingDatagrams() const override;
71
0
    qint64 pendingDatagramSize() const override;
72
0
#endif // QT_NO_UDPSOCKET
73
0
74
0
    qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = nullptr,
75
0
                        PacketHeaderOptions = WantNone) override;
76
0
    qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) override;
77
0
    qint64 bytesToWrite() const override;
78
0
79
0
    int option(SocketOption option) const override;
80
0
    bool setOption(SocketOption option, int value) override;
81
0
82
0
    bool waitForRead(QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout},
83
0
                     bool *timedOut = nullptr) override;
84
0
    bool waitForWrite(QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout},
85
0
                      bool *timedOut = nullptr) override;
86
0
    bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
87
0
                            bool checkRead, bool checkWrite,
88
0
                            QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout},
89
0
                            bool *timedOut = nullptr) override;
90
0
91
0
    bool isReadNotificationEnabled() const override;
92
0
    void setReadNotificationEnabled(bool enable) override;
93
0
    bool isWriteNotificationEnabled() const override;
94
0
    void setWriteNotificationEnabled(bool enable) override;
95
0
    bool isExceptionNotificationEnabled() const override;
96
0
    void setExceptionNotificationEnabled(bool enable) override;
97
0
98
0
private:
99
0
    Q_DECLARE_PRIVATE(QSocks5SocketEngine)
Unexecuted instantiation: QSocks5SocketEngine::d_func()
Unexecuted instantiation: QSocks5SocketEngine::d_func() const
100
0
    Q_DISABLE_COPY_MOVE(QSocks5SocketEngine)
101
0
    Q_PRIVATE_SLOT(d_func(), void _q_controlSocketConnected())
102
0
    Q_PRIVATE_SLOT(d_func(), void _q_controlSocketReadNotification())
103
0
    Q_PRIVATE_SLOT(d_func(), void _q_controlSocketErrorOccurred(QAbstractSocket::SocketError))
104
0
#ifndef QT_NO_UDPSOCKET
105
0
    Q_PRIVATE_SLOT(d_func(), void _q_udpSocketReadNotification())
106
0
#endif
107
0
    Q_PRIVATE_SLOT(d_func(), void _q_controlSocketBytesWritten())
108
0
    Q_PRIVATE_SLOT(d_func(), void _q_emitPendingReadNotification())
109
0
    Q_PRIVATE_SLOT(d_func(), void _q_emitPendingWriteNotification())
110
0
    Q_PRIVATE_SLOT(d_func(), void _q_emitPendingConnectionNotification())
111
0
    Q_PRIVATE_SLOT(d_func(), void _q_controlSocketDisconnected())
112
0
    Q_PRIVATE_SLOT(d_func(), void _q_controlSocketStateChanged(QAbstractSocket::SocketState))
113
0
114
0
};
115
0
116
0
117
0
class QTcpSocket;
118
0
119
0
class QSocks5Authenticator
120
0
{
121
0
public:
122
0
    QSocks5Authenticator();
123
0
    virtual ~QSocks5Authenticator();
124
0
    virtual char methodId();
125
0
    virtual bool beginAuthenticate(QTcpSocket *socket, bool *completed);
126
0
    virtual bool continueAuthenticate(QTcpSocket *socket, bool *completed);
127
0
128
0
    bool seal(const QByteArray &buf, QByteArray *sealedBuf);
129
0
    bool unSeal(const QByteArray &sealedBuf, QByteArray *buf);
130
0
    bool unSeal(QTcpSocket *sealedSocket, QByteArray *buf);
131
0
132
0
    virtual QString errorString() { return QString(); }
133
};
134
135
class QSocks5PasswordAuthenticator : public QSocks5Authenticator
136
{
137
public:
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
145
private:
146
    QString userName;
147
    QString password;
148
};
149
150
struct QSocks5Data;
151
struct QSocks5ConnectData;
152
struct QSocks5UdpAssociateData;
153
struct QSocks5BindData;
154
155
class QSocks5SocketEnginePrivate : public QAbstractSocketEnginePrivate
156
{
157
    Q_DECLARE_PUBLIC(QSocks5SocketEngine)
Unexecuted instantiation: QSocks5SocketEnginePrivate::q_func()
Unexecuted instantiation: QSocks5SocketEnginePrivate::q_func() const
158
public:
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
256
class Q_AUTOTEST_EXPORT QSocks5SocketEngineHandler : public QSocketEngineHandler
257
{
258
public:
259
    virtual QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType,
260
                                                      const QNetworkProxy &, QObject *parent) override;
261
    virtual QAbstractSocketEngine *createSocketEngine(qintptr socketDescriptor, QObject *parent) override;
262
};
263
264
QT_END_NAMESPACE
265
266
#endif // QSOCKS5SOCKETENGINE_H