1 | #include"socksd.h"
|
---|
2 |
|
---|
3 | #include<qapplication.h>
|
---|
4 | #include"bconsole.h"
|
---|
5 | #include"bsocket.h"
|
---|
6 | #include"socks.h"
|
---|
7 |
|
---|
8 | #include<stdio.h>
|
---|
9 |
|
---|
10 | class App::Private
|
---|
11 | {
|
---|
12 | public:
|
---|
13 | Private() {}
|
---|
14 |
|
---|
15 | ByteStream *bs;
|
---|
16 | BConsole *c;
|
---|
17 | SocksServer *serv;
|
---|
18 | SocksClient *client;
|
---|
19 |
|
---|
20 | QString user, pass;
|
---|
21 | };
|
---|
22 |
|
---|
23 | App::App(int port, const QString &user, const QString &pass)
|
---|
24 | :QObject(0)
|
---|
25 | {
|
---|
26 | d = new Private;
|
---|
27 | d->user = user;
|
---|
28 | d->pass = pass;
|
---|
29 | d->c = new BConsole;
|
---|
30 | connect(d->c, SIGNAL(connectionClosed()), SLOT(con_connectionClosed()));
|
---|
31 | connect(d->c, SIGNAL(readyRead()), SLOT(con_readyRead()));
|
---|
32 |
|
---|
33 | d->bs = 0;
|
---|
34 | d->client = 0;
|
---|
35 | d->serv = new SocksServer;
|
---|
36 | connect(d->serv, SIGNAL(incomingReady()), SLOT(ss_incomingReady()));
|
---|
37 | d->serv->listen(port);
|
---|
38 |
|
---|
39 | fprintf(stderr, "socksd: listening on port %d\n", port);
|
---|
40 | }
|
---|
41 |
|
---|
42 | App::~App()
|
---|
43 | {
|
---|
44 | if(d->client)
|
---|
45 | d->client->deleteLater();
|
---|
46 | delete d->serv;
|
---|
47 | delete d->c;
|
---|
48 | delete d;
|
---|
49 | }
|
---|
50 |
|
---|
51 | void App::st_connectionClosed()
|
---|
52 | {
|
---|
53 | fprintf(stderr, "socksd: Connection closed by foreign host.\n");
|
---|
54 | quit();
|
---|
55 | }
|
---|
56 |
|
---|
57 | void App::st_delayedCloseFinished()
|
---|
58 | {
|
---|
59 | quit();
|
---|
60 | }
|
---|
61 |
|
---|
62 | void App::st_readyRead()
|
---|
63 | {
|
---|
64 | QByteArray a = d->bs->read();
|
---|
65 | d->c->write(a);
|
---|
66 | }
|
---|
67 |
|
---|
68 | void App::st_error(int x)
|
---|
69 | {
|
---|
70 | fprintf(stderr, "socksd: Stream error [%d].\n", x);
|
---|
71 | quit();
|
---|
72 | }
|
---|
73 |
|
---|
74 | void App::con_connectionClosed()
|
---|
75 | {
|
---|
76 | fprintf(stderr, "adconn: Closing.\n");
|
---|
77 | d->bs->close();
|
---|
78 | if(d->bs->bytesToWrite() == 0)
|
---|
79 | quit();
|
---|
80 | }
|
---|
81 |
|
---|
82 | void App::con_readyRead()
|
---|
83 | {
|
---|
84 | QByteArray a = d->c->read();
|
---|
85 | d->bs->write(a);
|
---|
86 | }
|
---|
87 |
|
---|
88 | void App::ss_incomingReady()
|
---|
89 | {
|
---|
90 | fprintf(stderr, "incoming connection!\n");
|
---|
91 | SocksClient *c = d->serv->takeIncoming();
|
---|
92 | if(!c)
|
---|
93 | return;
|
---|
94 | fprintf(stderr, "accepted\n");
|
---|
95 | connect(c, SIGNAL(incomingMethods(int)), SLOT(sc_incomingMethods(int)));
|
---|
96 | connect(c, SIGNAL(incomingAuth(const QString &, const QString &)), SLOT(sc_incomingAuth(const QString &, const QString &)));
|
---|
97 | connect(c, SIGNAL(incomingRequest(const QString &, int)), SLOT(sc_incomingRequest(const QString &, int)));
|
---|
98 | connect(c, SIGNAL(error(int)), SLOT(sc_error(int)));
|
---|
99 | d->client = c;
|
---|
100 | }
|
---|
101 |
|
---|
102 | void App::sc_incomingMethods(int m)
|
---|
103 | {
|
---|
104 | fprintf(stderr, "m=%d\n", m);
|
---|
105 | if(d->user.isEmpty() && m & SocksClient::AuthNone)
|
---|
106 | d->client->chooseMethod(SocksClient::AuthNone);
|
---|
107 | else if(m & SocksClient::AuthUsername)
|
---|
108 | d->client->chooseMethod(SocksClient::AuthUsername);
|
---|
109 | else {
|
---|
110 | d->client->deleteLater();
|
---|
111 | d->client = 0;
|
---|
112 | fprintf(stderr, "unsupported method!\n");
|
---|
113 | }
|
---|
114 | }
|
---|
115 |
|
---|
116 | void App::sc_incomingAuth(const QString &user, const QString &pass)
|
---|
117 | {
|
---|
118 | fprintf(stderr, "incoming auth: user=[%s], pass=[%s]\n", user.latin1(), pass.latin1());
|
---|
119 | if(user == d->user && pass == d->pass) {
|
---|
120 | d->client->authGrant(true);
|
---|
121 | }
|
---|
122 | else {
|
---|
123 | d->client->authGrant(false);
|
---|
124 | d->client->deleteLater();
|
---|
125 | d->client = 0;
|
---|
126 | }
|
---|
127 | }
|
---|
128 |
|
---|
129 | void App::sc_incomingRequest(const QString &host, int port)
|
---|
130 | {
|
---|
131 | fprintf(stderr, "request: host=[%s], port=[%d]\n", host.latin1(), port);
|
---|
132 |
|
---|
133 | disconnect(d->client, SIGNAL(error(int)), this, SLOT(sc_error(int)));
|
---|
134 | connect(d->client, SIGNAL(connectionClosed()), SLOT(st_connectionClosed()));
|
---|
135 | connect(d->client, SIGNAL(delayedCloseFinished()), SLOT(st_delayedCloseFinished()));
|
---|
136 | connect(d->client, SIGNAL(readyRead()), SLOT(st_readyRead()));
|
---|
137 | connect(d->client, SIGNAL(error(int)), SLOT(st_error(int)));
|
---|
138 | d->bs = d->client;
|
---|
139 |
|
---|
140 | d->client->requestGrant(true);
|
---|
141 | fprintf(stderr, "<< Active >>\n");
|
---|
142 | }
|
---|
143 |
|
---|
144 | void App::sc_error(int)
|
---|
145 | {
|
---|
146 | d->client->deleteLater();
|
---|
147 | d->client = 0;
|
---|
148 |
|
---|
149 | fprintf(stderr, "error!\n");
|
---|
150 | }
|
---|
151 |
|
---|
152 |
|
---|
153 | int main(int argc, char **argv)
|
---|
154 | {
|
---|
155 | QApplication app(argc, argv, false);
|
---|
156 |
|
---|
157 | if(argc < 2) {
|
---|
158 | printf("usage: socksd [port] [user] [pass]\n\n");
|
---|
159 | return 0;
|
---|
160 | }
|
---|
161 |
|
---|
162 | QString p = argv[1];
|
---|
163 | int port = p.toInt();
|
---|
164 |
|
---|
165 | QString user, pass;
|
---|
166 | if(argc >= 4) {
|
---|
167 | user = argv[2];
|
---|
168 | pass = argv[3];
|
---|
169 | }
|
---|
170 |
|
---|
171 | App *a = new App(port, user, pass);
|
---|
172 | QObject::connect(a, SIGNAL(quit()), &app, SLOT(quit()));
|
---|
173 | app.exec();
|
---|
174 | delete a;
|
---|
175 |
|
---|
176 | return 0;
|
---|
177 | }
|
---|
178 |
|
---|