torsslsocket.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "torsslsocket.h"
00018
00019 #include <QDataStream>
00020 #include <QStringList>
00021
00022
00023 #define SOCKS_VERSION 0x04
00024 #define SOCKS_CONNECT 0x01
00025 #define SOCKS_FAKE_IP 0x00000001
00026 #define SOCKS_RESPONSE_LEN 0x08
00027 #define SOCKS_RESPONSE_VERSION 0x00
00028 #define SOCKS_CONNECT_STATUS_OK 0x5A
00029
00030
00031
00032 TorSslSocket::TorSslSocket(const QHostAddress &socksAddr,
00033 quint16 socksPort, QObject *parent)
00034 : QSslSocket(parent),
00035 _socksAddr(socksAddr),
00036 _socksPort(socksPort)
00037 {
00038 QObject::connect(this, SIGNAL(sslErrors(QList<QSslError>)),
00039 this, SLOT(onSslErrors(QList<QSslError>)));
00040 QObject::connect(this, SIGNAL(error(QAbstractSocket::SocketError)),
00041 this, SLOT(onError(QAbstractSocket::SocketError)));
00042 QObject::connect(this, SIGNAL(readyRead()),
00043 this, SLOT(onHandshakeResponse()));
00044 QObject::connect(this, SIGNAL(connected()),
00045 this, SLOT(connectedToProxy()));
00046 QObject::connect(this, SIGNAL(encrypted()),
00047 this, SLOT(onEncrypted()));
00048 }
00049
00050
00051 void
00052 TorSslSocket::connectToRemoteHost(const QString &remoteHost, quint16 remotePort,
00053 bool encrypted)
00054 {
00055 _remoteHost = remoteHost;
00056 _remotePort = remotePort;
00057 _encrypted = encrypted;
00058 QTcpSocket::connectToHost(_socksAddr, _socksPort);
00059 }
00060
00061
00062 void
00063 TorSslSocket::onError(QAbstractSocket::SocketError error)
00064 {
00065 Q_UNUSED(error);
00066 emit socketError(errorString());
00067 }
00068
00069
00070 void
00071 TorSslSocket::onSslErrors(const QList<QSslError> &errors)
00072 {
00073 QStringList errorStrings;
00074 foreach (QSslError error, errors) {
00075 errorStrings << "\"" + error.errorString() + "\"";
00076 }
00077 emit socketError(errorStrings.join(","));
00078 }
00079
00080
00081
00082 void
00083 TorSslSocket::connectedToProxy()
00084 {
00085 sendSocksHandshake(_remoteHost, _remotePort);
00086 }
00087
00088
00089
00090 void
00091 TorSslSocket::onEncrypted()
00092 {
00093 emit connectedToRemoteHost();
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 void
00109 TorSslSocket::sendSocksHandshake(const QString &remoteHost, quint16 remotePort)
00110 {
00111 QDataStream sock(this);
00112 sock << (quint8)SOCKS_VERSION;
00113 sock << (quint8)SOCKS_CONNECT;
00114 sock << (quint16)remotePort;
00115 sock << (quint32)SOCKS_FAKE_IP;
00116 sock << (quint8)0;
00117 sock.writeRawData(qPrintable(remoteHost), remoteHost.length());
00118 sock << (quint8)0;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void
00130 TorSslSocket::onHandshakeResponse()
00131 {
00132 QByteArray response;
00133 if (bytesAvailable() >= SOCKS_RESPONSE_LEN) {
00134
00135 QObject::disconnect(this, SIGNAL(readyRead()),
00136 this, SLOT(onHandshakeResponse()));
00137
00138
00139 response = read(SOCKS_RESPONSE_LEN);
00140
00141
00142 if ((uchar)response[0] == (uchar)SOCKS_RESPONSE_VERSION &&
00143 (uchar)response[1] == (uchar)SOCKS_CONNECT_STATUS_OK) {
00144 if (_encrypted) {
00145
00146
00147
00148
00149 setPeerName(_remoteHost);
00150 startClientEncryption();
00151 } else {
00152
00153 emit connectedToRemoteHost();
00154 }
00155 } else {
00156
00157 disconnectFromHost();
00158 }
00159 }
00160 }
00161