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