~ubuntu-branches/ubuntu/feisty/psi/feisty

« back to all changes in this revision

Viewing changes to cutestuff/network/socks.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2005-09-14 16:33:49 UTC
  • mfrom: (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050914163349-3zacov4afysz5cw5
Tags: 0.9.3-2ubuntu1
* Sync with debian
* Applied patch to psi.desktop to start psi without gpg-agent use (known
  issue)
* Updated README.Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include<qptrlist.h>
26
26
#include<qtimer.h>
27
27
#include<qguardedptr.h>
 
28
#include<qsocketdevice.h>
 
29
#include<qsocketnotifier.h>
28
30
 
29
31
#ifdef Q_OS_UNIX
30
32
#include<sys/types.h>
45
47
// CS_NAMESPACE_BEGIN
46
48
 
47
49
//----------------------------------------------------------------------------
 
50
// SocksUDP
 
51
//----------------------------------------------------------------------------
 
52
static QByteArray sp_create_udp(const QString &host, Q_UINT16 port, const QByteArray &buf)
 
53
{
 
54
        // detect for IP addresses
 
55
        //QHostAddress addr;
 
56
        //if(addr.setAddress(host))
 
57
        //      return sp_set_request(addr, port, cmd1);
 
58
 
 
59
        QCString h = host.utf8();
 
60
        h.truncate(255);
 
61
        h = QString::fromUtf8(h).utf8(); // delete any partial characters?
 
62
        int hlen = h.length();
 
63
 
 
64
        int at = 0;
 
65
        QByteArray a(4);
 
66
        a[at++] = 0x00; // reserved
 
67
        a[at++] = 0x00; // reserved
 
68
        a[at++] = 0x00; // frag
 
69
        a[at++] = 0x03; // address type = domain
 
70
 
 
71
        // host
 
72
        a.resize(at+hlen+1);
 
73
        a[at++] = hlen;
 
74
        memcpy(a.data() + at, h.data(), hlen);
 
75
        at += hlen;
 
76
 
 
77
        // port
 
78
        a.resize(at+2);
 
79
        unsigned short p = htons(port);
 
80
        memcpy(a.data() + at, &p, 2);
 
81
        at += 2;
 
82
 
 
83
        a.resize(at+buf.size());
 
84
        memcpy(a.data() + at, buf.data(), buf.size());
 
85
 
 
86
        return a;
 
87
}
 
88
 
 
89
struct SPS_UDP
 
90
{
 
91
        QString host;
 
92
        Q_UINT16 port;
 
93
        QByteArray data;
 
94
};
 
95
 
 
96
static int sp_read_udp(QByteArray *from, SPS_UDP *s)
 
97
{
 
98
        int full_len = 4;
 
99
        if((int)from->size() < full_len)
 
100
                return 0;
 
101
 
 
102
        QString host;
 
103
        QHostAddress addr;
 
104
        unsigned char atype = from->at(3);
 
105
 
 
106
        if(atype == 0x01) {
 
107
                full_len += 4;
 
108
                if((int)from->size() < full_len)
 
109
                        return 0;
 
110
                Q_UINT32 ip4;
 
111
                memcpy(&ip4, from->data() + 4, 4);
 
112
                addr.setAddress(ntohl(ip4));
 
113
                host = addr.toString();
 
114
        }
 
115
        else if(atype == 0x03) {
 
116
                ++full_len;
 
117
                if((int)from->size() < full_len)
 
118
                        return 0;
 
119
                unsigned char host_len = from->at(4);
 
120
                full_len += host_len;
 
121
                if((int)from->size() < full_len)
 
122
                        return 0;
 
123
                QCString cs(host_len+1);
 
124
                memcpy(cs.data(), from->data() + 5, host_len);
 
125
                host = QString::fromLatin1(cs);
 
126
        }
 
127
        else if(atype == 0x04) {
 
128
                full_len += 16;
 
129
                if((int)from->size() < full_len)
 
130
                        return 0;
 
131
                Q_UINT8 a6[16];
 
132
                memcpy(a6, from->data() + 4, 16);
 
133
                addr.setAddress(a6);
 
134
                host = addr.toString();
 
135
        }
 
136
 
 
137
        full_len += 2;
 
138
        if((int)from->size() < full_len)
 
139
                return 0;
 
140
 
 
141
        Q_UINT16 p;
 
142
        memcpy(&p, from->data() + full_len - 2, 2);
 
143
 
 
144
        s->host = host;
 
145
        s->port = ntohs(p);
 
146
        s->data.resize(from->size() - full_len);
 
147
        memcpy(s->data.data(), from->data() + full_len, s->data.size());
 
148
 
 
149
        return 1;
 
150
}
 
151
 
 
152
class SocksUDP::Private
 
153
{
 
154
public:
 
155
        QSocketDevice *sd;
 
156
        QSocketNotifier *sn;
 
157
        SocksClient *sc;
 
158
        QHostAddress routeAddr;
 
159
        int routePort;
 
160
        QString host;
 
161
        int port;
 
162
};
 
163
 
 
164
SocksUDP::SocksUDP(SocksClient *sc, const QString &host, int port, const QHostAddress &routeAddr, int routePort)
 
165
:QObject(sc)
 
166
{
 
167
        d = new Private;
 
168
        d->sc = sc;
 
169
        d->sd = new QSocketDevice(QSocketDevice::Datagram);
 
170
        d->sd->setBlocking(false);
 
171
        d->sn = new QSocketNotifier(d->sd->socket(), QSocketNotifier::Read);
 
172
        connect(d->sn, SIGNAL(activated(int)), SLOT(sn_activated(int)));
 
173
        d->host = host;
 
174
        d->port = port;
 
175
        d->routeAddr = routeAddr;
 
176
        d->routePort = routePort;
 
177
}
 
178
 
 
179
SocksUDP::~SocksUDP()
 
180
{
 
181
        delete d->sn;
 
182
        delete d->sd;
 
183
        delete d;
 
184
}
 
185
 
 
186
void SocksUDP::change(const QString &host, int port)
 
187
{
 
188
        d->host = host;
 
189
        d->port = port;
 
190
}
 
191
 
 
192
void SocksUDP::write(const QByteArray &data)
 
193
{
 
194
        QByteArray buf = sp_create_udp(d->host, d->port, data);
 
195
        d->sd->setBlocking(true);
 
196
        d->sd->writeBlock(buf.data(), buf.size(), d->routeAddr, d->routePort);
 
197
        d->sd->setBlocking(false);
 
198
}
 
199
 
 
200
void SocksUDP::sn_activated(int)
 
201
{
 
202
        QByteArray buf(8192);
 
203
        int actual = d->sd->readBlock(buf.data(), buf.size());
 
204
        buf.resize(actual);
 
205
        packetReady(buf);
 
206
}
 
207
 
 
208
//----------------------------------------------------------------------------
48
209
// SocksClient
49
210
//----------------------------------------------------------------------------
 
211
#define REQ_CONNECT      0x01
 
212
#define REQ_BIND         0x02
 
213
#define REQ_UDPASSOCIATE 0x03
 
214
 
 
215
#define RET_SUCCESS      0x00
 
216
#define RET_UNREACHABLE  0x04
 
217
#define RET_CONNREFUSED  0x05
50
218
 
51
219
// spc = socks packet client
52
220
// sps = socks packet server
189
357
}
190
358
 
191
359
// connectRequest
192
 
static QByteArray sp_set_connectRequest(const QHostAddress &addr, unsigned short port, unsigned char cmd1=0x01)
 
360
static QByteArray sp_set_request(const QHostAddress &addr, unsigned short port, unsigned char cmd1)
193
361
{
194
362
        int at = 0;
195
363
        QByteArray a(4);
228
396
        return a;
229
397
}
230
398
 
231
 
static QByteArray sp_set_connectRequest(const QString &host, Q_UINT16 port, unsigned char cmd1=0x01)
 
399
static QByteArray sp_set_request(const QString &host, Q_UINT16 port, unsigned char cmd1)
232
400
{
233
401
        // detect for IP addresses
234
402
        QHostAddress addr;
235
403
        if(addr.setAddress(host))
236
 
                return sp_set_connectRequest(addr, port, cmd1);
 
404
                return sp_set_request(addr, port, cmd1);
237
405
 
238
406
        QCString h = host.utf8();
239
407
        h.truncate(255);
271
439
        Q_UINT16 port;
272
440
};
273
441
 
274
 
static int sp_get_connectRequest(QByteArray *from, SPS_CONNREQ *s)
 
442
static int sp_get_request(QByteArray *from, SPS_CONNREQ *s)
275
443
{
276
444
        int full_len = 4;
277
445
        if((int)from->size() < full_len)
353
521
        int rport;
354
522
 
355
523
        int pending;
 
524
 
 
525
        bool udp;
 
526
        QString udpAddr;
 
527
        int udpPort;
356
528
};
357
529
 
358
530
SocksClient::SocksClient(QObject *parent)
401
573
        d->recvBuf.resize(0);
402
574
        d->active = false;
403
575
        d->waiting = false;
 
576
        d->udp = false;
404
577
        d->pending = 0;
405
578
}
406
579
 
415
588
        d->pass = pass;
416
589
}
417
590
 
418
 
void SocksClient::connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port)
 
591
void SocksClient::connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port, bool udpMode)
419
592
{
420
593
        reset(true);
421
594
 
423
596
        d->port = proxyPort;
424
597
        d->real_host = host;
425
598
        d->real_port = port;
 
599
        d->udp = udpMode;
426
600
 
427
601
#ifdef PROX_DEBUG
428
602
        fprintf(stderr, "SocksClient: Connecting to %s:%d", proxyHost.latin1(), proxyPort);
454
628
 
455
629
void SocksClient::write(const QByteArray &buf)
456
630
{
457
 
        if(d->active)
 
631
        if(d->active && !d->udp)
458
632
                d->sock.write(buf);
459
633
}
460
634
 
516
690
                        processOutgoing(block);
517
691
        }
518
692
        else {
519
 
                appendRead(block);
520
 
                readyRead();
 
693
                if(!d->udp) {
 
694
                        appendRead(block);
 
695
                        readyRead();
 
696
                }
521
697
        }
522
698
}
523
699
 
608
784
        }
609
785
        else if(d->step == StepRequest) {
610
786
                SPS_CONNREQ s;
611
 
                int r = sp_get_connectRequest(&d->recvBuf, &s);
 
787
                int r = sp_get_request(&d->recvBuf, &s);
612
788
                if(r == -1) {
613
789
                        reset(true);
614
790
                        error(ErrProxyNeg);
615
791
                        return;
616
792
                }
617
793
                else if(r == 1) {
618
 
                        if(s.cmd != 0x00) {
 
794
                        if(s.cmd != RET_SUCCESS) {
619
795
#ifdef PROX_DEBUG
620
796
                                fprintf(stderr, "SocksClient: client << Error >> [%02x]\n", s.cmd);
621
797
#endif
622
798
                                reset(true);
623
 
                                if(s.cmd == 0x04)
 
799
                                if(s.cmd == RET_UNREACHABLE)
624
800
                                        error(ErrHostNotFound);
625
 
                                else if(s.cmd == 0x05)
 
801
                                else if(s.cmd == RET_CONNREFUSED)
626
802
                                        error(ErrConnectionRefused);
627
803
                                else
628
804
                                        error(ErrProxyNeg);
632
808
#ifdef PROX_DEBUG
633
809
                        fprintf(stderr, "SocksClient: client << Success >>\n");
634
810
#endif
 
811
                        if(d->udp) {
 
812
                                if(s.address_type == 0x03)
 
813
                                        d->udpAddr = s.host;
 
814
                                else
 
815
                                        d->udpAddr = s.addr.toString();
 
816
                                d->udpPort = s.port;
 
817
                        }
 
818
 
635
819
                        d->active = true;
636
820
 
637
821
                        QGuardedPtr<QObject> self = this;
654
838
        fprintf(stderr, "SocksClient: Requesting ...\n");
655
839
#endif
656
840
        d->step = StepRequest;
657
 
        writeData(sp_set_connectRequest(d->real_host, d->real_port));
 
841
        int cmd = d->udp ? REQ_UDPASSOCIATE : REQ_CONNECT;
 
842
        QByteArray buf;
 
843
        if(!d->real_host.isEmpty())
 
844
                buf = sp_set_request(d->real_host, d->real_port, cmd);
 
845
        else
 
846
                buf = sp_set_request(QHostAddress(), 0, cmd);
 
847
        writeData(buf);
658
848
}
659
849
 
660
850
void SocksClient::sock_bytesWritten(int x)
758
948
        }
759
949
        else if(d->step == StepRequest) {
760
950
                SPS_CONNREQ s;
761
 
                int r = sp_get_connectRequest(&d->recvBuf, &s);
 
951
                int r = sp_get_request(&d->recvBuf, &s);
762
952
                if(r == -1) {
763
953
                        reset(true);
764
954
                        error(ErrProxyNeg);
766
956
                }
767
957
                else if(r == 1) {
768
958
                        d->waiting = true;
769
 
                        if(!s.host.isEmpty())
770
 
                                d->rhost = s.host;
771
 
                        else
772
 
                                d->rhost = s.addr.toString();
773
 
                        d->rport = s.port;
774
 
                        incomingRequest(d->rhost, d->rport);
 
959
                        if(s.cmd == REQ_CONNECT) {
 
960
                                if(!s.host.isEmpty())
 
961
                                        d->rhost = s.host;
 
962
                                else
 
963
                                        d->rhost = s.addr.toString();
 
964
                                d->rport = s.port;
 
965
                                incomingConnectRequest(d->rhost, d->rport);
 
966
                        }
 
967
                        else if(s.cmd == REQ_UDPASSOCIATE) {
 
968
                                incomingUDPAssociateRequest();
 
969
                        }
 
970
                        else {
 
971
                                requestDeny();
 
972
                                return;
 
973
                        }
775
974
                }
776
975
        }
777
976
}
815
1014
        continueIncoming();
816
1015
}
817
1016
 
818
 
void SocksClient::requestGrant(bool b)
819
 
{
820
 
        if(d->step != StepRequest || !d->waiting)
821
 
                return;
822
 
 
823
 
        // request response
824
 
        d->waiting = false;
825
 
        unsigned char cmd1;
826
 
        if(b)
827
 
                cmd1 = 0x00; // success
828
 
        else
829
 
                cmd1 = 0x04; // host not found
830
 
        writeData(sp_set_connectRequest(d->rhost, d->rport, cmd1));
831
 
        if(!b) {
832
 
                reset(true);
833
 
                return;
834
 
        }
 
1017
void SocksClient::requestDeny()
 
1018
{
 
1019
        if(d->step != StepRequest || !d->waiting)
 
1020
                return;
 
1021
 
 
1022
        // response
 
1023
        d->waiting = false;
 
1024
        writeData(sp_set_request(d->rhost, d->rport, RET_UNREACHABLE));
 
1025
        reset(true);
 
1026
}
 
1027
 
 
1028
void SocksClient::grantConnect()
 
1029
{
 
1030
        if(d->step != StepRequest || !d->waiting)
 
1031
                return;
 
1032
 
 
1033
        // response
 
1034
        d->waiting = false;
 
1035
        writeData(sp_set_request(d->rhost, d->rport, RET_SUCCESS));
835
1036
        d->active = true;
836
1037
#ifdef PROX_DEBUG
837
1038
        fprintf(stderr, "SocksClient: server << Success >>\n");
844
1045
        }
845
1046
}
846
1047
 
 
1048
void SocksClient::grantUDPAssociate(const QString &relayHost, int relayPort)
 
1049
{
 
1050
        if(d->step != StepRequest || !d->waiting)
 
1051
                return;
 
1052
 
 
1053
        // response
 
1054
        d->waiting = false;
 
1055
        writeData(sp_set_request(relayHost, relayPort, RET_SUCCESS));
 
1056
        d->udp = true;
 
1057
        d->active = true;
 
1058
#ifdef PROX_DEBUG
 
1059
        fprintf(stderr, "SocksClient: server << Success >>\n");
 
1060
#endif
 
1061
 
 
1062
        if(!d->recvBuf.isEmpty())
 
1063
                d->recvBuf.resize(0);
 
1064
}
 
1065
 
847
1066
QHostAddress SocksClient::peerAddress() const
848
1067
{
849
1068
        return d->sock.peerAddress();
854
1073
        return d->sock.peerPort();
855
1074
}
856
1075
 
 
1076
QString SocksClient::udpAddress() const
 
1077
{
 
1078
        return d->udpAddr;
 
1079
}
 
1080
 
 
1081
Q_UINT16 SocksClient::udpPort() const
 
1082
{
 
1083
        return d->udpPort;
 
1084
}
 
1085
 
 
1086
SocksUDP *SocksClient::createUDP(const QString &host, int port, const QHostAddress &routeAddr, int routePort)
 
1087
{
 
1088
        return new SocksUDP(this, host, port, routeAddr, routePort);
 
1089
}
 
1090
 
857
1091
//----------------------------------------------------------------------------
858
1092
// SocksServer
859
1093
//----------------------------------------------------------------------------
864
1098
 
865
1099
        ServSock serv;
866
1100
        QPtrList<SocksClient> incomingConns;
 
1101
        QSocketDevice *sd;
 
1102
        QSocketNotifier *sn;
867
1103
};
868
1104
 
869
1105
SocksServer::SocksServer(QObject *parent)
870
1106
:QObject(parent)
871
1107
{
872
1108
        d = new Private;
 
1109
        d->sd = 0;
 
1110
        d->sn = 0;
873
1111
        connect(&d->serv, SIGNAL(connectionReady(int)), SLOT(connectionReady(int)));
874
1112
}
875
1113
 
876
1114
SocksServer::~SocksServer()
877
1115
{
 
1116
        stop();
878
1117
        d->incomingConns.setAutoDelete(true);
879
1118
        d->incomingConns.clear();
880
1119
        delete d;
885
1124
        return d->serv.isActive();
886
1125
}
887
1126
 
888
 
bool SocksServer::listen(Q_UINT16 port)
 
1127
bool SocksServer::listen(Q_UINT16 port, bool udp)
889
1128
{
890
 
        return d->serv.listen(port);
 
1129
        stop();
 
1130
        if(!d->serv.listen(port))
 
1131
                return false;
 
1132
        if(udp) {
 
1133
                d->sd = new QSocketDevice(QSocketDevice::Datagram);
 
1134
                d->sd->setBlocking(false);
 
1135
                if(!d->sd->bind(QHostAddress(), port)) {
 
1136
                        delete d->sd;
 
1137
                        d->sd = 0;
 
1138
                        d->serv.stop();
 
1139
                        return false;
 
1140
                }
 
1141
                d->sn = new QSocketNotifier(d->sd->socket(), QSocketNotifier::Read);
 
1142
                connect(d->sn, SIGNAL(activated(int)), SLOT(sn_activated(int)));
 
1143
        }
 
1144
        return true;
891
1145
}
892
1146
 
893
1147
void SocksServer::stop()
894
1148
{
 
1149
        delete d->sn;
 
1150
        d->sn = 0;
 
1151
        delete d->sd;
 
1152
        d->sd = 0;
895
1153
        d->serv.stop();
896
1154
}
897
1155
 
922
1180
        return c;
923
1181
}
924
1182
 
 
1183
void SocksServer::writeUDP(const QHostAddress &addr, int port, const QByteArray &data)
 
1184
{
 
1185
        if(d->sd) {
 
1186
                d->sd->setBlocking(true);
 
1187
                d->sd->writeBlock(data.data(), data.size(), addr, port);
 
1188
                d->sd->setBlocking(false);
 
1189
        }
 
1190
}
 
1191
 
925
1192
void SocksServer::connectionReady(int s)
926
1193
{
927
1194
        SocksClient *c = new SocksClient(s, this);
937
1204
        c->deleteLater();
938
1205
}
939
1206
 
 
1207
void SocksServer::sn_activated(int)
 
1208
{
 
1209
        QByteArray buf(8192);
 
1210
        int actual = d->sd->readBlock(buf.data(), buf.size());
 
1211
        buf.resize(actual);
 
1212
        QHostAddress pa = d->sd->peerAddress();
 
1213
        int pp = d->sd->peerPort();
 
1214
        SPS_UDP s;
 
1215
        int r = sp_read_udp(&buf, &s);
 
1216
        if(r != 1)
 
1217
                return;
 
1218
        incomingUDP(s.host, s.port, pa, pp, s.data);
 
1219
}
 
1220
 
940
1221
// CS_NAMESPACE_END