1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2015 The Qt Company Ltd. 4 ** Contact: http://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtNetwork module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see http://www.qt.io/terms-conditions. For further 15 ** information use the contact form at http://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 2.1 or version 3 as published by the Free 20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 ** following information to ensure the GNU Lesser General Public License 23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 ** 26 ** As a special exception, The Qt Company gives you certain additional 27 ** rights. These rights are described in The Qt Company LGPL Exception 28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 ** 30 ** GNU General Public License Usage 31 ** Alternatively, this file may be used under the terms of the GNU 32 ** General Public License version 3.0 as published by the Free Software 33 ** Foundation and appearing in the file LICENSE.GPL included in the 34 ** packaging of this file. Please review the following information to 35 ** ensure the GNU General Public License version 3.0 requirements will be 36 ** met: http://www.gnu.org/copyleft/gpl.html. 37 ** 38 ** $QT_END_LICENSE$ 39 ** 40 ****************************************************************************/ 41 42 #ifndef QSOCKS5SOCKETENGINE_P_H 43 #define QSOCKS5SOCKETENGINE_P_H 44 45 // 46 // W A R N I N G 47 // ------------- 48 // 49 // This file is not part of the Qt API. It exists purely as an 50 // implementation detail. This header file may change from version to 51 // version without notice, or even be removed. 52 // 53 // We mean it. 54 // 55 56 #include "qabstractsocketengine_p.h" 57 #include "qnetworkproxy.h" 58 59 QT_BEGIN_NAMESPACE 60 61 #ifndef QT_NO_SOCKS5 62 63 class QSocks5SocketEnginePrivate; 64 65 class Q_AUTOTEST_EXPORT QSocks5SocketEngine : public QAbstractSocketEngine 66 { 67 Q_OBJECT 68 public: 69 QSocks5SocketEngine(QObject *parent = 0); 70 ~QSocks5SocketEngine(); 71 72 bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol); 73 bool initialize(int socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState); 74 75 void setProxy(const QNetworkProxy &networkProxy); 76 77 int socketDescriptor() const; 78 79 bool isValid() const; 80 81 bool connectInternal(); 82 bool connectToHost(const QHostAddress &address, quint16 port); 83 bool connectToHostByName(const QString &name, quint16 port); 84 bool bind(const QHostAddress &address, quint16 port); 85 bool listen(); 86 int accept(); 87 void close(); 88 89 qint64 bytesAvailable() const; 90 91 qint64 read(char *data, qint64 maxlen); 92 qint64 write(const char *data, qint64 len); 93 94 #ifndef QT_NO_UDPSOCKET 95 #ifndef QT_NO_NETWORKINTERFACE 96 bool joinMulticastGroup(const QHostAddress &groupAddress, 97 const QNetworkInterface &interface); 98 bool leaveMulticastGroup(const QHostAddress &groupAddress, 99 const QNetworkInterface &interface); 100 QNetworkInterface multicastInterface() const; 101 bool setMulticastInterface(const QNetworkInterface &iface); 102 #endif // QT_NO_NETWORKINTERFACE 103 104 qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0, 105 quint16 *port = 0); 106 qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr, 107 quint16 port); 108 bool hasPendingDatagrams() const; 109 qint64 pendingDatagramSize() const; 110 #endif // QT_NO_UDPSOCKET 111 112 qint64 bytesToWrite() const; 113 114 int option(SocketOption option) const; 115 bool setOption(SocketOption option, int value); 116 117 bool waitForRead(int msecs = 30000, bool *timedOut = 0); 118 bool waitForWrite(int msecs = 30000, bool *timedOut = 0); 119 bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite, 120 bool checkRead, bool checkWrite, 121 int msecs = 30000, bool *timedOut = 0); 122 123 bool isReadNotificationEnabled() const; 124 void setReadNotificationEnabled(bool enable); 125 bool isWriteNotificationEnabled() const; 126 void setWriteNotificationEnabled(bool enable); 127 bool isExceptionNotificationEnabled() const; 128 void setExceptionNotificationEnabled(bool enable); 129 130 private: 131 Q_DECLARE_PRIVATE(QSocks5SocketEngine) 132 Q_DISABLE_COPY(QSocks5SocketEngine) 133 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketConnected()) 134 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketReadNotification()) 135 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketError(QAbstractSocket::SocketError)) 136 #ifndef QT_NO_UDPSOCKET 137 Q_PRIVATE_SLOT(d_func(), void _q_udpSocketReadNotification()) 138 #endif 139 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketBytesWritten()) 140 Q_PRIVATE_SLOT(d_func(), void _q_emitPendingReadNotification()) 141 Q_PRIVATE_SLOT(d_func(), void _q_emitPendingWriteNotification()) 142 Q_PRIVATE_SLOT(d_func(), void _q_emitPendingConnectionNotification()) 143 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketDisconnected()) 144 Q_PRIVATE_SLOT(d_func(), void _q_controlSocketStateChanged(QAbstractSocket::SocketState)) 145 146 }; 147 148 149 class QTcpSocket; 150 151 class QSocks5Authenticator 152 { 153 public: 154 QSocks5Authenticator(); 155 virtual ~QSocks5Authenticator(); 156 virtual char methodId(); 157 virtual bool beginAuthenticate(QTcpSocket *socket, bool *completed); 158 virtual bool continueAuthenticate(QTcpSocket *socket, bool *completed); 159 160 virtual bool seal(const QByteArray buf, QByteArray *sealedBuf); 161 virtual bool unSeal(const QByteArray sealedBuf, QByteArray *buf); 162 virtual bool unSeal(QTcpSocket *sealedSocket, QByteArray *buf); 163 errorString()164 virtual QString errorString() { return QString(); } 165 }; 166 167 class QSocks5PasswordAuthenticator : public QSocks5Authenticator 168 { 169 public: 170 QSocks5PasswordAuthenticator(const QString &userName, const QString &password); 171 char methodId(); 172 bool beginAuthenticate(QTcpSocket *socket, bool *completed); 173 bool continueAuthenticate(QTcpSocket *socket, bool *completed); 174 175 QString errorString(); 176 177 private: 178 QString userName; 179 QString password; 180 }; 181 182 struct QSocks5Data; 183 struct QSocks5ConnectData; 184 struct QSocks5UdpAssociateData; 185 struct QSocks5BindData; 186 187 class QSocks5SocketEnginePrivate : public QAbstractSocketEnginePrivate 188 { 189 Q_DECLARE_PUBLIC(QSocks5SocketEngine) 190 public: 191 QSocks5SocketEnginePrivate(); 192 ~QSocks5SocketEnginePrivate(); 193 194 enum Socks5State 195 { 196 Uninitialized = 0, 197 ConnectError, 198 AuthenticationMethodsSent, 199 Authenticating, 200 AuthenticatingError, 201 RequestMethodSent, 202 RequestError, 203 Connected, 204 UdpAssociateSuccess, 205 BindSuccess, 206 ControlSocketError, 207 SocksError, 208 HostNameLookupError 209 }; 210 Socks5State socks5State; 211 212 enum Socks5Mode 213 { 214 NoMode, 215 ConnectMode, 216 BindMode, 217 UdpAssociateMode 218 }; 219 Socks5Mode mode; 220 221 enum Socks5Error 222 { 223 SocksFailure = 0x01, 224 ConnectionNotAllowed = 0x02, 225 NetworkUnreachable = 0x03, 226 HostUnreachable = 0x04, 227 ConnectionRefused = 0x05, 228 TTLExpired = 0x06, 229 CommandNotSupported = 0x07, 230 AddressTypeNotSupported = 0x08, 231 LastKnownError = AddressTypeNotSupported, 232 UnknownError 233 }; 234 235 void initialize(Socks5Mode socks5Mode); 236 237 void setErrorState(Socks5State state, const QString &extraMessage = QString()); 238 void setErrorState(Socks5State state, Socks5Error socks5error); 239 240 void reauthenticate(); 241 void parseAuthenticationMethodReply(); 242 void parseAuthenticatingReply(); 243 void sendRequestMethod(); 244 void parseRequestMethodReply(); 245 void parseNewConnection(); 246 247 bool waitForConnected(int msecs, bool *timedOut); 248 249 void _q_controlSocketConnected(); 250 void _q_controlSocketReadNotification(); 251 void _q_controlSocketError(QAbstractSocket::SocketError); 252 #ifndef QT_NO_UDPSOCKET 253 void checkForDatagrams() const; 254 void _q_udpSocketReadNotification(); 255 #endif 256 void _q_controlSocketBytesWritten(); 257 void _q_controlSocketDisconnected(); 258 void _q_controlSocketStateChanged(QAbstractSocket::SocketState); 259 260 QNetworkProxy proxyInfo; 261 262 bool readNotificationEnabled, writeNotificationEnabled, exceptNotificationEnabled; 263 264 int socketDescriptor; 265 266 QSocks5Data *data; 267 QSocks5ConnectData *connectData; 268 #ifndef QT_NO_UDPSOCKET 269 QSocks5UdpAssociateData *udpData; 270 #endif 271 QSocks5BindData *bindData; 272 QString peerName; 273 274 mutable bool readNotificationActivated; 275 mutable bool writeNotificationActivated; 276 277 bool readNotificationPending; 278 void _q_emitPendingReadNotification(); 279 void emitReadNotification(); 280 bool writeNotificationPending; 281 void _q_emitPendingWriteNotification(); 282 void emitWriteNotification(); 283 bool connectionNotificationPending; 284 void _q_emitPendingConnectionNotification(); 285 void emitConnectionNotification(); 286 }; 287 288 class Q_AUTOTEST_EXPORT QSocks5SocketEngineHandler : public QSocketEngineHandler 289 { 290 public: 291 virtual QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType, 292 const QNetworkProxy &, QObject *parent); 293 virtual QAbstractSocketEngine *createSocketEngine(int socketDescripter, QObject *parent); 294 }; 295 296 297 QT_END_NAMESPACE 298 #endif // QT_NO_SOCKS5 299 #endif // QSOCKS5SOCKETENGINE_H 300