File indexing completed on 2024-06-23 04:03:32

0001 /*
0002  * socks.cpp - SOCKS5 TCP proxy client/server
0003  * Copyright (C) 2003  Justin Karneges
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Lesser General Public
0007  * License as published by the Free Software Foundation; either
0008  * either version 2
0009    of the License, or (at your option) any later version.1 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Lesser General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Lesser General Public
0017  * License along with this library; if not, write to the Free Software
0018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0019  *
0020  */
0021 
0022 #include "socks.h"
0023 
0024 #include <QHostAddress>
0025 #include <QStringList>
0026 #include <QTimer>
0027 #include <QPointer>
0028 #include <QSocketNotifier>
0029 #include <QByteArray>
0030 
0031 #ifdef Q_OS_UNIX
0032 #include <sys/types.h>
0033 #include <netinet/in.h>
0034 #endif
0035 
0036 #ifdef Q_OS_WIN32
0037 #include <windows.h>
0038 #include <winsock2.h>
0039 #endif
0040 
0041 #ifdef Q_OS_UNIX
0042 #include <unistd.h>
0043 #include <fcntl.h>
0044 #endif
0045 
0046 #include "servsock.h"
0047 #include "bsocket.h"
0048 
0049 #ifdef PROX_DEBUG
0050 #include <stdio.h>
0051 #endif
0052 
0053 // CS_NAMESPACE_BEGIN
0054 
0055 //----------------------------------------------------------------------------
0056 // SocksUDP
0057 //----------------------------------------------------------------------------
0058 
0059 class SocksUDP::Private
0060 {
0061 public:
0062     QUdpSocket *sd;
0063     SocksClient *sc;
0064     QHostAddress routeAddr;
0065     int routePort;
0066     QString host;
0067     int port;
0068 };
0069 
0070 SocksUDP::SocksUDP(SocksClient *sc, const QString &host, int port, const QHostAddress &routeAddr, int routePort)
0071 :QObject(sc)
0072 {
0073     d = new Private;
0074     d->sc = sc;
0075     d->sd = new QUdpSocket();
0076     connect(d->sd, SIGNAL(readyRead()), SLOT(sd_readyRead()));
0077     d->host = host;
0078     d->port = port;
0079     d->routeAddr = routeAddr;
0080     d->routePort = routePort;
0081 }
0082 
0083 SocksUDP::~SocksUDP()
0084 {
0085     delete d->sd;
0086     delete d;
0087 }
0088 
0089 void SocksUDP::change(const QString &host, int port)
0090 {
0091     d->host = host;
0092     d->port = port;
0093 }
0094 
0095 void SocksUDP::write(const QByteArray &data)
0096 {
0097     d->sd->writeDatagram(data.data(), data.size(), d->routeAddr, d->routePort);
0098 }
0099 
0100 void SocksUDP::sd_activated()
0101 {
0102   while (d->sd->hasPendingDatagrams()) {
0103     QByteArray datagram;
0104     datagram.resize(d->sd->pendingDatagramSize());
0105     d->sd->readDatagram(datagram.data(), datagram.size());
0106     packetReady(datagram);
0107   }
0108 }
0109 
0110 //----------------------------------------------------------------------------
0111 // SocksClient
0112 //----------------------------------------------------------------------------
0113 #define REQ_CONNECT      0x01
0114 #define REQ_BIND         0x02
0115 #define REQ_UDPASSOCIATE 0x03
0116 
0117 #define RET_SUCCESS      0x00
0118 #define RET_UNREACHABLE  0x04
0119 #define RET_CONNREFUSED  0x05
0120 
0121 // spc = socks packet client
0122 // sps = socks packet server
0123 // SPCS = socks packet client struct
0124 // SPSS = socks packet server struct
0125 
0126 // Version
0127 static QByteArray spc_set_version()
0128 {
0129     QByteArray ver;
0130   ver.resize(4);
0131     ver[0] = 0x05; // socks version 5
0132     ver[1] = 0x02; // number of methods
0133     ver[2] = 0x00; // no-auth
0134     ver[3] = 0x02; // username
0135     return ver;
0136 }
0137 
0138 static QByteArray sps_set_version(int method)
0139 {
0140     QByteArray ver;
0141   ver.resize(2);
0142     ver[0] = 0x05;
0143     ver[1] = method;
0144     return ver;
0145 }
0146 
0147 struct SPCS_VERSION
0148 {
0149     unsigned char version;
0150     QByteArray methodList;
0151 };
0152 
0153 static int spc_get_version(QByteArray *from, SPCS_VERSION *s)
0154 {
0155     if(from->size() < 1)
0156         return 0;
0157     if(from->at(0) != 0x05) // only SOCKS5 supported
0158         return -1;
0159     if(from->size() < 2)
0160         return 0;
0161     int num = from->at(1);
0162     if(num > 16) // who the heck has over 16 auth methods??
0163         return -1;
0164     if(from->size() < 2 + num)
0165         return 0;
0166     QByteArray a = ByteStream::takeArray(from, 2+num);
0167     s->version = a[0];
0168     s->methodList.resize(num);
0169     memcpy(s->methodList.data(), a.data() + 2, num);
0170     return 1;
0171 }
0172 
0173 struct SPSS_VERSION
0174 {
0175     unsigned char version;
0176     unsigned char method;
0177 };
0178 
0179 static int sps_get_version(QByteArray *from, SPSS_VERSION *s)
0180 {
0181     if(from->size() < 2)
0182         return 0;
0183     QByteArray a = ByteStream::takeArray(from, 2);
0184     s->version = a[0];
0185     s->method = a[1];
0186     return 1;
0187 }
0188 
0189 // authUsername
0190 static QByteArray spc_set_authUsername(const QByteArray &user, const QByteArray &pass)
0191 {
0192     int len1 = user.length();
0193     int len2 = pass.length();
0194     if(len1 > 255)
0195         len1 = 255;
0196     if(len2 > 255)
0197         len2 = 255;
0198     QByteArray a;
0199   a.resize(1+1+len1+1+len2);
0200     a[0] = 0x01; // username auth version 1
0201     a[1] = len1;
0202     memcpy(a.data() + 2, user.data(), len1);
0203     a[2+len1] = len2;
0204     memcpy(a.data() + 3 + len1, pass.data(), len2);
0205     return a;
0206 }
0207 
0208 static QByteArray sps_set_authUsername(bool success)
0209 {
0210     QByteArray a;
0211   a.resize(2);
0212     a[0] = 0x01;
0213     a[1] = success ? 0x00 : 0xff;
0214     return a;
0215 }
0216 
0217 struct SPCS_AUTHUSERNAME
0218 {
0219     QString user, pass;
0220 };
0221 
0222 static int spc_get_authUsername(QByteArray *from, SPCS_AUTHUSERNAME *s)
0223 {
0224     if(from->size() < 1)
0225         return 0;
0226     unsigned char ver = from->at(0);
0227     if(ver != 0x01)
0228         return -1;
0229     if(from->size() < 2)
0230         return 0;
0231     unsigned char ulen = from->at(1);
0232     if((int)from->size() < ulen + 3)
0233         return 0;
0234     unsigned char plen = from->at(ulen+2);
0235     if((int)from->size() < ulen + plen + 3)
0236         return 0;
0237     QByteArray a = ByteStream::takeArray(from, ulen + plen + 3);
0238 
0239     QByteArray user, pass;
0240     user.resize(ulen+1);
0241     pass.resize(plen+1);
0242     memcpy(user.data(), a.data()+2, ulen);
0243     memcpy(pass.data(), a.data()+ulen+3, plen);
0244     s->user = QString::fromUtf8(user);
0245     s->pass = QString::fromUtf8(pass);
0246     return 1;
0247 }
0248 
0249 struct SPSS_AUTHUSERNAME
0250 {
0251     unsigned char version;
0252     bool success;
0253 };
0254 
0255 static int sps_get_authUsername(QByteArray *from, SPSS_AUTHUSERNAME *s)
0256 {
0257     if(from->size() < 2)
0258         return 0;
0259     QByteArray a = ByteStream::takeArray(from, 2);
0260     s->version = a[0];
0261     s->success = ((char) a[1] == 0 ? true: false);
0262     return 1;
0263 }
0264 
0265 // connectRequest
0266 static QByteArray sp_set_request(const QHostAddress &addr, unsigned short port, unsigned char cmd1)
0267 {
0268     int at = 0;
0269     QByteArray a;
0270   a.resize(4);
0271     a[at++] = 0x05; // socks version 5
0272     a[at++] = cmd1;
0273     a[at++] = 0x00; // reserved
0274     if(addr.protocol() == QAbstractSocket::IPv4Protocol || addr.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
0275         a[at++] = 0x01; // address type = ipv4
0276         quint32 ip4 = htonl(addr.toIPv4Address());
0277         a.resize(at+4);
0278         memcpy(a.data() + at, &ip4, 4);
0279         at += 4;
0280     }
0281     else {
0282         a[at++] = 0x04;
0283         quint8 a6[16];
0284         QStringList s6 = addr.toString().split(':');
0285         int at = 0;
0286         quint16 c;
0287         bool ok;
0288         for(QStringList::ConstIterator it = s6.constBegin(); it != s6.constEnd(); ++it) {
0289             c = (*it).toInt(&ok, 16);
0290             a6[at++] = (c >> 8);
0291             a6[at++] = c & 0xff;
0292         }
0293         a.resize(at+16);
0294         memcpy(a.data() + at, a6, 16);
0295         at += 16;
0296     }
0297 
0298     // port
0299     a.resize(at+2);
0300     unsigned short p = htons(port);
0301     memcpy(a.data() + at, &p, 2);
0302 
0303     return a;
0304 }
0305 
0306 static QByteArray sp_set_request(const QString &host, quint16 port, unsigned char cmd1)
0307 {
0308     // detect for IP addresses
0309     QHostAddress addr;
0310     if(addr.setAddress(host))
0311         return sp_set_request(addr, port, cmd1);
0312 
0313     QByteArray h = host.toUtf8();
0314     h.truncate(255);
0315     h = QString::fromUtf8(h).toUtf8(); // delete any partial characters?
0316     int hlen = h.length();
0317 
0318     int at = 0;
0319     QByteArray a;
0320   a.resize(4);
0321     a[at++] = 0x05; // socks version 5
0322     a[at++] = cmd1;
0323     a[at++] = 0x00; // reserved
0324     a[at++] = 0x03; // address type = domain
0325 
0326     // host
0327     a.resize(at+hlen+1);
0328     a[at++] = hlen;
0329     memcpy(a.data() + at, h.data(), hlen);
0330     at += hlen;
0331 
0332     // port
0333     a.resize(at+2);
0334     unsigned short p = htons(port);
0335     memcpy(a.data() + at, &p, 2);
0336 
0337     return a;
0338 }
0339 
0340 struct SPS_CONNREQ
0341 {
0342     unsigned char version;
0343     unsigned char cmd;
0344     int address_type;
0345     QString host;
0346     QHostAddress addr;
0347     quint16 port;
0348 };
0349 
0350 static int sp_get_request(QByteArray *from, SPS_CONNREQ *s)
0351 {
0352     int full_len = 4;
0353     if((int)from->size() < full_len)
0354         return 0;
0355 
0356     QString host;
0357     QHostAddress addr;
0358     unsigned char atype = from->at(3);
0359 
0360     if(atype == 0x01) {
0361         full_len += 4;
0362         if((int)from->size() < full_len)
0363             return 0;
0364         quint32 ip4;
0365         memcpy(&ip4, from->data() + 4, 4);
0366         addr.setAddress(ntohl(ip4));
0367     }
0368     else if(atype == 0x03) {
0369         ++full_len;
0370         if((int)from->size() < full_len)
0371             return 0;
0372         unsigned char host_len = from->at(4);
0373         full_len += host_len;
0374         if((int)from->size() < full_len)
0375             return 0;
0376         QByteArray cs;
0377     cs.resize(host_len+1);
0378         memcpy(cs.data(), from->data() + 5, host_len);
0379         host = QString::fromLatin1(cs);
0380     }
0381     else if(atype == 0x04) {
0382         full_len += 16;
0383         if((int)from->size() < full_len)
0384             return 0;
0385         quint8 a6[16];
0386         memcpy(a6, from->data() + 4, 16);
0387         addr.setAddress(a6);
0388     }
0389 
0390     full_len += 2;
0391     if((int)from->size() < full_len)
0392         return 0;
0393 
0394     QByteArray a = ByteStream::takeArray(from, full_len);
0395 
0396     quint16 p;
0397     memcpy(&p, a.data() + full_len - 2, 2);
0398 
0399     s->version = a[0];
0400     s->cmd = a[1];
0401     s->address_type = atype;
0402     s->host = host;
0403     s->addr = addr;
0404     s->port = ntohs(p);
0405 
0406     return 1;
0407 }
0408 
0409 enum { StepVersion, StepAuth, StepRequest };
0410 
0411 class SocksClient::Private
0412 {
0413 public:
0414     Private() {}
0415 
0416     BSocket sock;
0417     QString host;
0418     int port;
0419     QString user, pass;
0420     QString real_host;
0421     int real_port;
0422 
0423     QByteArray recvBuf;
0424     bool active;
0425     int step;
0426     int authMethod;
0427     bool incoming, waiting;
0428 
0429     QString rhost;
0430     int rport;
0431 
0432     int pending;
0433 
0434     bool udp;
0435     QString udpAddr;
0436     int udpPort;
0437 };
0438 
0439 SocksClient::SocksClient(QObject *parent)
0440 :ByteStream(parent)
0441 {
0442     init();
0443 
0444     d->incoming = false;
0445 }
0446 
0447 SocksClient::SocksClient(int s, QObject *parent)
0448 :ByteStream(parent)
0449 {
0450     init();
0451 
0452     d->incoming = true;
0453     d->waiting = true;
0454     d->sock.setSocket(s);
0455 }
0456 
0457 void SocksClient::init()
0458 {
0459     d = new Private;
0460     connect(&d->sock, &BSocket::connected, this, &SocksClient::sock_connected);
0461     connect(&d->sock, &ByteStream::connectionClosed, this, &SocksClient::sock_connectionClosed);
0462     connect(&d->sock, &ByteStream::delayedCloseFinished, this, &SocksClient::sock_delayedCloseFinished);
0463     connect(&d->sock, &ByteStream::readyRead, this, &SocksClient::sock_readyRead);
0464     connect(&d->sock, &ByteStream::bytesWritten, this, &SocksClient::sock_bytesWritten);
0465     connect(&d->sock, &ByteStream::error, this, &SocksClient::sock_error);
0466 
0467     reset(true);
0468 }
0469 
0470 SocksClient::~SocksClient()
0471 {
0472     reset(true);
0473     delete d;
0474 }
0475 
0476 void SocksClient::reset(bool clear)
0477 {
0478     if(d->sock.state() != BSocket::Idle)
0479         d->sock.close();
0480     if(clear)
0481         clearReadBuffer();
0482     d->recvBuf.resize(0);
0483     d->active = false;
0484     d->waiting = false;
0485     d->udp = false;
0486     d->pending = 0;
0487 }
0488 
0489 bool SocksClient::isIncoming() const
0490 {
0491     return d->incoming;
0492 }
0493 
0494 void SocksClient::setAuth(const QString &user, const QString &pass)
0495 {
0496     d->user = user;
0497     d->pass = pass;
0498 }
0499 
0500 void SocksClient::connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port, bool udpMode)
0501 {
0502     reset(true);
0503 
0504     d->host = proxyHost;
0505     d->port = proxyPort;
0506     d->real_host = host;
0507     d->real_port = port;
0508     d->udp = udpMode;
0509 
0510 #ifdef PROX_DEBUG
0511     fprintf(stderr, "SocksClient: Connecting to %s:%d", proxyHost.toLatin1(), proxyPort);
0512     if(d->user.isEmpty())
0513         fprintf(stderr, "\n");
0514     else
0515         fprintf(stderr, ", auth {%s,%s}\n", d->user.toLatin1(), d->pass.toLatin1());
0516 #endif
0517     d->sock.connectToHost(d->host, d->port);
0518 }
0519 
0520 bool SocksClient::isOpen() const
0521 {
0522     return d->active;
0523 }
0524 
0525 void SocksClient::close()
0526 {
0527     d->sock.close();
0528     if(d->sock.bytesToWrite() == 0)
0529         reset();
0530 }
0531 
0532 void SocksClient::writeData(const QByteArray &buf)
0533 {
0534     d->pending += buf.size();
0535     d->sock.write(buf);
0536 }
0537 
0538 void SocksClient::write(const QByteArray &buf)
0539 {
0540     if(d->active && !d->udp)
0541         d->sock.write(buf);
0542 }
0543 
0544 QByteArray SocksClient::read(int bytes)
0545 {
0546     return ByteStream::read(bytes);
0547 }
0548 
0549 int SocksClient::bytesAvailable() const
0550 {
0551     return ByteStream::bytesAvailable();
0552 }
0553 
0554 int SocksClient::bytesToWrite() const
0555 {
0556     if(d->active)
0557         return d->sock.bytesToWrite();
0558     else
0559         return 0;
0560 }
0561 
0562 void SocksClient::sock_connected()
0563 {
0564 #ifdef PROX_DEBUG
0565     fprintf(stderr, "SocksClient: Connected\n");
0566 #endif
0567 
0568     d->step = StepVersion;
0569     writeData(spc_set_version());
0570 }
0571 
0572 void SocksClient::sock_connectionClosed()
0573 {
0574     if(d->active) {
0575         reset();
0576         connectionClosed();
0577     }
0578     else {
0579         error(ErrProxyNeg);
0580     }
0581 }
0582 
0583 void SocksClient::sock_delayedCloseFinished()
0584 {
0585     if(d->active) {
0586         reset();
0587         delayedCloseFinished();
0588     }
0589 }
0590 
0591 void SocksClient::sock_readyRead()
0592 {
0593     QByteArray block = d->sock.read();
0594 
0595     if(!d->active) {
0596         if(d->incoming)
0597             processIncoming(block);
0598         else
0599             processOutgoing(block);
0600     }
0601     else {
0602         if(!d->udp) {
0603             appendRead(block);
0604             readyRead();
0605         }
0606     }
0607 }
0608 
0609 void SocksClient::processOutgoing(const QByteArray &block)
0610 {
0611 #ifdef PROX_DEBUG
0612     // show hex
0613     fprintf(stderr, "SocksClient: client recv { ");
0614     for(int n = 0; n < (int)block.size(); ++n)
0615         fprintf(stderr, "%02X ", (unsigned char)block[n]);
0616     fprintf(stderr, " } \n");
0617 #endif
0618     ByteStream::appendArray(&d->recvBuf, block);
0619 
0620     if(d->step == StepVersion) {
0621         SPSS_VERSION s;
0622         int r = sps_get_version(&d->recvBuf, &s);
0623         if(r == -1) {
0624             reset(true);
0625             error(ErrProxyNeg);
0626             return;
0627         }
0628         else if(r == 1) {
0629             if(s.version != 0x05 || s.method == 0xff) {
0630 #ifdef PROX_DEBUG
0631                 fprintf(stderr, "SocksClient: Method selection failed\n");
0632 #endif
0633                 reset(true);
0634                 error(ErrProxyNeg);
0635                 return;
0636             }
0637 
0638             QString str;
0639             if(s.method == 0x00) {
0640                 str = "None";
0641                 d->authMethod = AuthNone;
0642             }
0643             else if(s.method == 0x02) {
0644                 str = "Username/Password";
0645                 d->authMethod = AuthUsername;
0646             }
0647             else {
0648 #ifdef PROX_DEBUG
0649                 fprintf(stderr, "SocksClient: Server wants to use unknown method '%02x'\n", s.method);
0650 #endif
0651                 reset(true);
0652                 error(ErrProxyNeg);
0653                 return;
0654             }
0655 
0656             if(d->authMethod == AuthNone) {
0657                 // no auth, go straight to the request
0658                 do_request();
0659             }
0660             else if(d->authMethod == AuthUsername) {
0661                 d->step = StepAuth;
0662 #ifdef PROX_DEBUG
0663                 fprintf(stderr, "SocksClient: Authenticating [Username] ...\n");
0664 #endif
0665                 writeData(spc_set_authUsername(d->user.toLatin1(), d->pass.toLatin1()));
0666             }
0667         }
0668     }
0669     if(d->step == StepAuth) {
0670         if(d->authMethod == AuthUsername) {
0671             SPSS_AUTHUSERNAME s;
0672             int r = sps_get_authUsername(&d->recvBuf, &s);
0673             if(r == -1) {
0674                 reset(true);
0675                 error(ErrProxyNeg);
0676                 return;
0677             }
0678             else if(r == 1) {
0679                 if(s.version != 0x01) {
0680                     reset(true);
0681                     error(ErrProxyNeg);
0682                     return;
0683                 }
0684                 if(!s.success) {
0685                     reset(true);
0686                     error(ErrProxyAuth);
0687                     return;
0688                 }
0689 
0690                 do_request();
0691             }
0692         }
0693     }
0694     else if(d->step == StepRequest) {
0695         SPS_CONNREQ s;
0696         int r = sp_get_request(&d->recvBuf, &s);
0697         if(r == -1) {
0698             reset(true);
0699             error(ErrProxyNeg);
0700             return;
0701         }
0702         else if(r == 1) {
0703             if(s.cmd != RET_SUCCESS) {
0704 #ifdef PROX_DEBUG
0705                 fprintf(stderr, "SocksClient: client << Error >> [%02x]\n", s.cmd);
0706 #endif
0707                 reset(true);
0708                 if(s.cmd == RET_UNREACHABLE)
0709                     error(ErrHostNotFound);
0710                 else if(s.cmd == RET_CONNREFUSED)
0711                     error(ErrConnectionRefused);
0712                 else
0713                     error(ErrProxyNeg);
0714                 return;
0715             }
0716 
0717 #ifdef PROX_DEBUG
0718             fprintf(stderr, "SocksClient: client << Success >>\n");
0719 #endif
0720             if(d->udp) {
0721                 if(s.address_type == 0x03)
0722                     d->udpAddr = s.host;
0723                 else
0724                     d->udpAddr = s.addr.toString();
0725                 d->udpPort = s.port;
0726             }
0727 
0728             d->active = true;
0729 
0730             QPointer<QObject> self = this;
0731             connected();
0732             if(!self)
0733                 return;
0734 
0735             if(!d->recvBuf.isEmpty()) {
0736                 appendRead(d->recvBuf);
0737                 d->recvBuf.resize(0);
0738                 readyRead();
0739             }
0740         }
0741     }
0742 }
0743 
0744 void SocksClient::do_request()
0745 {
0746 #ifdef PROX_DEBUG
0747     fprintf(stderr, "SocksClient: Requesting ...\n");
0748 #endif
0749     d->step = StepRequest;
0750     int cmd = d->udp ? REQ_UDPASSOCIATE : REQ_CONNECT;
0751     QByteArray buf;
0752     if(!d->real_host.isEmpty())
0753         buf = sp_set_request(d->real_host, d->real_port, cmd);
0754     else
0755         buf = sp_set_request(QHostAddress(), 0, cmd);
0756     writeData(buf);
0757 }
0758 
0759 void SocksClient::sock_bytesWritten(int x)
0760 {
0761     int bytes = x;
0762     if(d->pending >= bytes) {
0763         d->pending -= bytes;
0764         bytes = 0;
0765     }
0766     else {
0767         bytes -= d->pending;
0768         d->pending = 0;
0769     }
0770     if(bytes > 0)
0771         bytesWritten(bytes);
0772 }
0773 
0774 void SocksClient::sock_error(int x)
0775 {
0776     if(d->active) {
0777         reset();
0778         error(ErrRead);
0779     }
0780     else {
0781         reset(true);
0782         if(x == BSocket::ErrHostNotFound)
0783             error(ErrProxyConnect);
0784         else if(x == BSocket::ErrConnectionRefused)
0785             error(ErrProxyConnect);
0786         else if(x == BSocket::ErrRead)
0787             error(ErrProxyNeg);
0788     }
0789 }
0790 
0791 void SocksClient::serve()
0792 {
0793     d->waiting = false;
0794     d->step = StepVersion;
0795     continueIncoming();
0796 }
0797 
0798 void SocksClient::processIncoming(const QByteArray &block)
0799 {
0800 #ifdef PROX_DEBUG
0801     // show hex
0802     fprintf(stderr, "SocksClient: server recv { ");
0803     for(int n = 0; n < (int)block.size(); ++n)
0804         fprintf(stderr, "%02X ", (unsigned char)block[n]);
0805     fprintf(stderr, " } \n");
0806 #endif
0807     ByteStream::appendArray(&d->recvBuf, block);
0808 
0809     if(!d->waiting)
0810         continueIncoming();
0811 }
0812 
0813 void SocksClient::continueIncoming()
0814 {
0815     if(d->recvBuf.isEmpty())
0816         return;
0817 
0818     if(d->step == StepVersion) {
0819         SPCS_VERSION s;
0820         int r = spc_get_version(&d->recvBuf, &s);
0821         if(r == -1) {
0822             reset(true);
0823             error(ErrProxyNeg);
0824             return;
0825         }
0826         else if(r == 1) {
0827             if(s.version != 0x05) {
0828                 reset(true);
0829                 error(ErrProxyNeg);
0830                 return;
0831             }
0832 
0833             int methods = 0;
0834             for(int n = 0; n < (int)s.methodList.size(); ++n) {
0835                 unsigned char c = s.methodList[n];
0836                 if(c == 0x00)
0837                     methods |= AuthNone;
0838                 else if(c == 0x02)
0839                     methods |= AuthUsername;
0840             }
0841             d->waiting = true;
0842             incomingMethods(methods);
0843         }
0844     }
0845     else if(d->step == StepAuth) {
0846         SPCS_AUTHUSERNAME s;
0847         int r = spc_get_authUsername(&d->recvBuf, &s);
0848         if(r == -1) {
0849             reset(true);
0850             error(ErrProxyNeg);
0851             return;
0852         }
0853         else if(r == 1) {
0854             d->waiting = true;
0855             incomingAuth(s.user, s.pass);
0856         }
0857     }
0858     else if(d->step == StepRequest) {
0859         SPS_CONNREQ s;
0860         int r = sp_get_request(&d->recvBuf, &s);
0861         if(r == -1) {
0862             reset(true);
0863             error(ErrProxyNeg);
0864             return;
0865         }
0866         else if(r == 1) {
0867             d->waiting = true;
0868             if(s.cmd == REQ_CONNECT) {
0869                 if(!s.host.isEmpty())
0870                     d->rhost = s.host;
0871                 else
0872                     d->rhost = s.addr.toString();
0873                 d->rport = s.port;
0874                 incomingConnectRequest(d->rhost, d->rport);
0875             }
0876             else if(s.cmd == REQ_UDPASSOCIATE) {
0877                 incomingUDPAssociateRequest();
0878             }
0879             else {
0880                 requestDeny();
0881                 return;
0882             }
0883         }
0884     }
0885 }
0886 
0887 void SocksClient::chooseMethod(int method)
0888 {
0889     if(d->step != StepVersion || !d->waiting)
0890         return;
0891 
0892     unsigned char c;
0893     if(method == AuthNone) {
0894         d->step = StepRequest;
0895         c = 0x00;
0896     }
0897     else {
0898         d->step = StepAuth;
0899         c = 0x02;
0900     }
0901 
0902     // version response
0903     d->waiting = false;
0904     writeData(sps_set_version(c));
0905     continueIncoming();
0906 }
0907 
0908 void SocksClient::authGrant(bool b)
0909 {
0910     if(d->step != StepAuth || !d->waiting)
0911         return;
0912 
0913     if(b)
0914         d->step = StepRequest;
0915 
0916     // auth response
0917     d->waiting = false;
0918     writeData(sps_set_authUsername(b));
0919     if(!b) {
0920         reset(true);
0921         return;
0922     }
0923     continueIncoming();
0924 }
0925 
0926 void SocksClient::requestDeny()
0927 {
0928     if(d->step != StepRequest || !d->waiting)
0929         return;
0930 
0931     // response
0932     d->waiting = false;
0933     writeData(sp_set_request(d->rhost, d->rport, RET_UNREACHABLE));
0934     reset(true);
0935 }
0936 
0937 void SocksClient::grantConnect()
0938 {
0939     if(d->step != StepRequest || !d->waiting)
0940         return;
0941 
0942     // response
0943     d->waiting = false;
0944     writeData(sp_set_request(d->rhost, d->rport, RET_SUCCESS));
0945     d->active = true;
0946 #ifdef PROX_DEBUG
0947     fprintf(stderr, "SocksClient: server << Success >>\n");
0948 #endif
0949 
0950     if(!d->recvBuf.isEmpty()) {
0951         appendRead(d->recvBuf);
0952         d->recvBuf.resize(0);
0953         readyRead();
0954     }
0955 }
0956 
0957 void SocksClient::grantUDPAssociate(const QString &relayHost, int relayPort)
0958 {
0959     if(d->step != StepRequest || !d->waiting)
0960         return;
0961 
0962     // response
0963     d->waiting = false;
0964     writeData(sp_set_request(relayHost, relayPort, RET_SUCCESS));
0965     d->udp = true;
0966     d->active = true;
0967 #ifdef PROX_DEBUG
0968     fprintf(stderr, "SocksClient: server << Success >>\n");
0969 #endif
0970 
0971     if(!d->recvBuf.isEmpty())
0972         d->recvBuf.resize(0);
0973 }
0974 
0975 QHostAddress SocksClient::peerAddress() const
0976 {
0977     return d->sock.peerAddress();
0978 }
0979 
0980 quint16 SocksClient::peerPort() const
0981 {
0982     return d->sock.peerPort();
0983 }
0984 
0985 QString SocksClient::udpAddress() const
0986 {
0987     return d->udpAddr;
0988 }
0989 
0990 quint16 SocksClient::udpPort() const
0991 {
0992     return d->udpPort;
0993 }
0994 
0995 SocksUDP *SocksClient::createUDP(const QString &host, int port, const QHostAddress &routeAddr, int routePort)
0996 {
0997     return new SocksUDP(this, host, port, routeAddr, routePort);
0998 }
0999 
1000 //----------------------------------------------------------------------------
1001 // SocksServer
1002 //----------------------------------------------------------------------------
1003 class SocksServer::Private
1004 {
1005 public:
1006     Private() {}
1007 
1008     ServSock serv;
1009     QList<SocksClient*> incomingConns;
1010     QUdpSocket *sd;
1011 };
1012 
1013 SocksServer::SocksServer(QObject *parent)
1014 :QObject(parent)
1015 {
1016     d = new Private;
1017     d->sd = 0;
1018     connect(&d->serv, &ServSock::connectionReady, this, &SocksServer::connectionReady);
1019 }
1020 
1021 SocksServer::~SocksServer()
1022 {
1023     stop();
1024   while (d->incomingConns.count()) {
1025     delete d->incomingConns.takeFirst();
1026   }
1027     delete d;
1028 }
1029 
1030 bool SocksServer::isActive() const
1031 {
1032     return d->serv.isActive();
1033 }
1034 
1035 bool SocksServer::listen(quint16 port, bool udp)
1036 {
1037     stop();
1038     if(!d->serv.listen(port))
1039         return false;
1040     if(udp) {
1041         d->sd = new QUdpSocket();
1042         if(!d->sd->bind(QHostAddress::LocalHost, port)) {
1043             delete d->sd;
1044             d->sd = 0;
1045             d->serv.stop();
1046             return false;
1047         }
1048         connect(d->sd, &QIODevice::readyRead, this, &SocksServer::sd_activated);
1049     }
1050     return true;
1051 }
1052 
1053 void SocksServer::stop()
1054 {
1055     delete d->sd;
1056     d->sd = 0;
1057     d->serv.stop();
1058 }
1059 
1060 int SocksServer::port() const
1061 {
1062     return d->serv.port();
1063 }
1064 
1065 QHostAddress SocksServer::address() const
1066 {
1067     return d->serv.address();
1068 }
1069 
1070 SocksClient *SocksServer::takeIncoming()
1071 {
1072     if(d->incomingConns.isEmpty())
1073         return 0;
1074 
1075     SocksClient *c = d->incomingConns.takeFirst();
1076 
1077     // we don't care about errors anymore
1078     disconnect(c, &ByteStream::error, this, &SocksServer::connectionError);
1079 
1080     // don't serve the connection until the event loop, to give the caller a chance to map signals
1081     QTimer::singleShot(0, c, SLOT(serve()));
1082 
1083     return c;
1084 }
1085 
1086 void SocksServer::writeUDP(const QHostAddress &addr, int port, const QByteArray &data)
1087 {
1088     if(d->sd) {
1089         d->sd->writeDatagram(data.data(), data.size(), addr, port);
1090     }
1091 }
1092 
1093 void SocksServer::connectionReady(int s)
1094 {
1095     SocksClient *c = new SocksClient(s, this);
1096     connect(c, &ByteStream::error, this, &SocksServer::connectionError);
1097     d->incomingConns.append(c);
1098     incomingReady();
1099 }
1100 
1101 void SocksServer::connectionError()
1102 {
1103     SocksClient *c = (SocksClient *)sender();
1104     d->incomingConns.removeAll(c);
1105     c->deleteLater();
1106 }
1107 
1108 void SocksServer::sd_activated()
1109 {
1110   while (d->sd->hasPendingDatagrams()) {
1111     QByteArray datagram;
1112     QHostAddress sender;
1113     quint16 senderPort;
1114     datagram.resize(d->sd->pendingDatagramSize());
1115     d->sd->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
1116     incomingUDP(sender.toString(), senderPort, d->sd->peerAddress(), d->sd->peerPort(), datagram);
1117   }
1118 }
1119 
1120 // CS_NAMESPACE_END