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