Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/net/Socks/SocksServer.java
41149 views
1
/*
2
* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
import java.net.*;
24
import java.io.*;
25
import java.util.HashMap;
26
27
public class SocksServer extends Thread implements Closeable {
28
// Some useful SOCKS constant
29
30
static final int PROTO_VERS4 = 4;
31
static final int PROTO_VERS = 5;
32
static final int DEFAULT_PORT = 1080;
33
34
static final int NO_AUTH = 0;
35
static final int GSSAPI = 1;
36
static final int USER_PASSW = 2;
37
static final int NO_METHODS = -1;
38
39
static final int CONNECT = 1;
40
static final int BIND = 2;
41
static final int UDP_ASSOC = 3;
42
43
static final int IPV4 = 1;
44
static final int DOMAIN_NAME = 3;
45
static final int IPV6 = 4;
46
47
static final int REQUEST_OK = 0;
48
static final int GENERAL_FAILURE = 1;
49
static final int NOT_ALLOWED = 2;
50
static final int NET_UNREACHABLE = 3;
51
static final int HOST_UNREACHABLE = 4;
52
static final int CONN_REFUSED = 5;
53
static final int TTL_EXPIRED = 6;
54
static final int CMD_NOT_SUPPORTED = 7;
55
static final int ADDR_TYPE_NOT_SUP = 8;
56
57
private int port;
58
private ServerSocket server;
59
private boolean useV4 = false;
60
private HashMap<String,String> users = new HashMap<>();
61
private volatile boolean done = false;
62
// Inner class to handle protocol with client
63
// This is the bulk of the work (protocol handler)
64
class ClientHandler extends Thread {
65
private InputStream in;
66
private OutputStream out;
67
private Socket client;
68
private Socket dest;
69
70
// Simple tunneling class, moving bits from one stream to another
71
72
class Tunnel extends Thread {
73
private InputStream tin;
74
private OutputStream tout;
75
76
Tunnel(InputStream in, OutputStream out) {
77
tin = in;
78
tout = out;
79
}
80
81
public void run() {
82
int b;
83
while (true) {
84
try {
85
b = tin.read();
86
if (b == -1) {
87
tin.close();
88
tout.close();
89
return;
90
}
91
tout.write(b);
92
tout.flush();
93
} catch (IOException e) {
94
// actually exit from the thread
95
return;
96
}
97
}
98
}
99
}
100
101
ClientHandler(Socket s) throws IOException {
102
client = s;
103
in = new BufferedInputStream(client.getInputStream());
104
out = new BufferedOutputStream(client.getOutputStream());
105
}
106
107
private void readBuf(InputStream is, byte[] buf) throws IOException {
108
int l = buf.length;
109
int count = 0;
110
int i;
111
do {
112
i = is.read(buf, count, l - count);
113
if (i == -1)
114
throw new IOException("unexpected EOF");
115
count += i;
116
} while (count < l);
117
}
118
119
120
private boolean userPassAuth() throws IOException {
121
int ver = in.read();
122
int ulen = in.read();
123
if (ulen <= 0)
124
throw new SocketException("SOCKS protocol error");
125
byte[] buf = new byte[ulen];
126
readBuf(in, buf);
127
String uname = new String(buf);
128
String password = null;
129
ulen = in.read();
130
if (ulen < 0)
131
throw new SocketException("SOCKS protocol error");
132
if (ulen > 0) {
133
buf = new byte[ulen];
134
readBuf(in, buf);
135
password = new String(buf);
136
}
137
// Check username/password validity here
138
System.err.println("User: '" + uname);
139
System.err.println("PSWD: '" + password);
140
if (users.containsKey(uname)) {
141
String p1 = users.get(uname);
142
System.err.println("p1 = " + p1);
143
if (p1.equals(password)) {
144
out.write(PROTO_VERS);
145
out.write(REQUEST_OK);
146
out.flush();
147
return true;
148
}
149
}
150
out.write(PROTO_VERS);
151
out.write(NOT_ALLOWED);
152
out.flush();
153
return false;
154
}
155
156
private void purge() throws IOException {
157
boolean done = false;
158
int i = 0;
159
client.setSoTimeout(1000);
160
while(!done && i != -1) {
161
try {
162
i = in.read();
163
} catch(IOException e) {
164
done = true;
165
}
166
}
167
}
168
169
170
// Handle the SOCKS version 4 protocl
171
172
private void getRequestV4() throws IOException {
173
int ver = in.read();
174
int cmd = in.read();
175
if (ver == -1 || cmd == -1) {
176
// EOF
177
in.close();
178
out.close();
179
return;
180
}
181
182
if (ver != 0 && ver != 4) {
183
out.write(PROTO_VERS4);
184
out.write(91); // Bad Request
185
out.write(0);
186
out.write(0);
187
out.write(0);
188
out.write(0);
189
out.write(0);
190
out.write(0);
191
out.write(0);
192
out.flush();
193
purge();
194
out.close();
195
in.close();
196
return;
197
}
198
199
if (cmd == CONNECT) {
200
int port = ((in.read() & 0xff) << 8);
201
port += (in.read() & 0xff);
202
byte[] buf = new byte[4];
203
readBuf(in, buf);
204
InetAddress addr = InetAddress.getByAddress(buf);
205
// We don't use the username...
206
int c;
207
do {
208
c = (in.read() & 0xff);
209
} while (c!=0);
210
boolean ok = true;
211
try {
212
dest = new Socket(addr, port);
213
} catch (IOException e) {
214
ok = false;
215
}
216
if (!ok) {
217
out.write(PROTO_VERS4);
218
out.write(91);
219
out.write(0);
220
out.write(0);
221
out.write(buf);
222
out.flush();
223
purge();
224
out.close();
225
in.close();
226
return;
227
}
228
out.write(PROTO_VERS4);
229
out.write(90); // Success
230
out.write((port >> 8) & 0xff);
231
out.write(port & 0xff);
232
out.write(buf);
233
out.flush();
234
InputStream in2 = new BufferedInputStream(dest.getInputStream());
235
OutputStream out2 = new BufferedOutputStream(dest.getOutputStream());
236
237
Tunnel tunnel = new Tunnel(in2, out);
238
tunnel.start();
239
240
int b = 0;
241
do {
242
try {
243
b = in.read();
244
if (b == -1) {
245
in.close();
246
out2.close();
247
return;
248
}
249
out2.write(b);
250
out2.flush();
251
} catch (IOException ex) {
252
}
253
} while (!client.isClosed());
254
}
255
}
256
257
258
// Negociate the authentication scheme with the client
259
private void negociate() throws IOException {
260
int ver = in.read();
261
int n = in.read();
262
byte[] buf = null;
263
if (n > 0) {
264
buf = new byte[n];
265
readBuf(in, buf);
266
}
267
int scheme = NO_AUTH;
268
for (int i = 0; i < n; i++)
269
if (buf[i] == USER_PASSW)
270
scheme = USER_PASSW;
271
out.write(PROTO_VERS);
272
out.write(scheme);
273
out.flush();
274
if (scheme == USER_PASSW)
275
userPassAuth();
276
}
277
278
// Send error message then close the streams
279
private void sendError(int code) {
280
try {
281
out.write(PROTO_VERS);
282
out.write(code);
283
out.write(0);
284
out.write(IPV4);
285
for (int i=0; i<6; i++)
286
out.write(0);
287
out.flush();
288
out.close();
289
} catch (IOException ex) {
290
}
291
}
292
293
// Actually connect the proxy to the destination then initiate tunneling
294
295
private void doConnect(InetSocketAddress addr) throws IOException {
296
dest = new Socket();
297
try {
298
dest.connect(addr, 10000);
299
} catch (SocketTimeoutException ex) {
300
sendError(HOST_UNREACHABLE);
301
return;
302
} catch (ConnectException cex) {
303
sendError(CONN_REFUSED);
304
return;
305
}
306
// Success
307
InetAddress iadd = addr.getAddress();
308
if (iadd instanceof Inet4Address) {
309
out.write(PROTO_VERS);
310
out.write(REQUEST_OK);
311
out.write(0);
312
out.write(IPV4);
313
out.write(iadd.getAddress());
314
} else if (iadd instanceof Inet6Address) {
315
out.write(PROTO_VERS);
316
out.write(REQUEST_OK);
317
out.write(0);
318
out.write(IPV6);
319
out.write(iadd.getAddress());
320
} else {
321
sendError(GENERAL_FAILURE);
322
return;
323
}
324
out.write((addr.getPort() >> 8) & 0xff);
325
out.write((addr.getPort() >> 0) & 0xff);
326
out.flush();
327
328
InputStream in2 = new BufferedInputStream(dest.getInputStream());
329
OutputStream out2 = new BufferedOutputStream(dest.getOutputStream());
330
331
Tunnel tunnel = new Tunnel(in2, out);
332
tunnel.start();
333
334
int b = 0;
335
do {
336
// Note that the socket might be closed from another thread (the tunnel)
337
try {
338
b = in.read();
339
if (b == -1) {
340
in.close();
341
out2.close();
342
return;
343
}
344
out2.write(b);
345
out2.flush();
346
} catch(IOException ioe) {
347
}
348
} while (!client.isClosed());
349
}
350
351
private void doBind(InetSocketAddress addr) throws IOException {
352
ServerSocket svr = new ServerSocket();
353
svr.bind(null);
354
InetSocketAddress bad = (InetSocketAddress) svr.getLocalSocketAddress();
355
out.write(PROTO_VERS);
356
out.write(REQUEST_OK);
357
out.write(0);
358
out.write(IPV4);
359
out.write(bad.getAddress().getAddress());
360
out.write((bad.getPort() >> 8) & 0xff);
361
out.write((bad.getPort() & 0xff));
362
out.flush();
363
dest = svr.accept();
364
bad = (InetSocketAddress) dest.getRemoteSocketAddress();
365
out.write(PROTO_VERS);
366
out.write(REQUEST_OK);
367
out.write(0);
368
out.write(IPV4);
369
out.write(bad.getAddress().getAddress());
370
out.write((bad.getPort() >> 8) & 0xff);
371
out.write((bad.getPort() & 0xff));
372
out.flush();
373
InputStream in2 = dest.getInputStream();
374
OutputStream out2 = dest.getOutputStream();
375
376
Tunnel tunnel = new Tunnel(in2, out);
377
tunnel.start();
378
379
int b = 0;
380
do {
381
// Note that the socket might be close from another thread (the tunnel)
382
try {
383
b = in.read();
384
if (b == -1) {
385
in.close();
386
out2.close();
387
return;
388
}
389
out2.write(b);
390
out2.flush();
391
} catch(IOException ioe) {
392
}
393
} while (!client.isClosed());
394
395
}
396
397
// Handle the SOCKS v5 requests
398
399
private void getRequest() throws IOException {
400
int ver = in.read();
401
int cmd = in.read();
402
if (ver == -1 || cmd == -1) {
403
in.close();
404
out.close();
405
return;
406
}
407
int rsv = in.read();
408
int atyp = in.read();
409
String addr = null;
410
int port = 0;
411
412
switch(atyp) {
413
case IPV4:
414
{
415
byte[] buf = new byte[4];
416
readBuf(in, buf);
417
addr = InetAddress.getByAddress(buf).getHostAddress();
418
}
419
break;
420
case DOMAIN_NAME:
421
{
422
int i = in.read();
423
byte[] buf = new byte[i];
424
readBuf(in, buf);
425
addr = new String(buf);
426
}
427
break;
428
case IPV6:
429
{
430
byte[] buf = new byte[16];
431
readBuf(in, buf);
432
addr = InetAddress.getByAddress(buf).getHostAddress();
433
}
434
break;
435
}
436
437
port = ((in.read()&0xff) << 8);
438
port += (in.read()&0xff);
439
440
InetSocketAddress socAddr = new InetSocketAddress(addr, port);
441
switch(cmd) {
442
case CONNECT:
443
doConnect(socAddr);
444
break;
445
case BIND:
446
doBind(socAddr);
447
break;
448
case UDP_ASSOC:
449
// doUDP(socAddr);
450
break;
451
}
452
}
453
454
public void run() {
455
String line = null;
456
try {
457
if (useV4) {
458
getRequestV4();
459
} else {
460
negociate();
461
getRequest();
462
}
463
} catch (IOException ex) {
464
try {
465
sendError(GENERAL_FAILURE);
466
} catch (Exception e) {
467
}
468
} finally {
469
try {
470
client.close();
471
} catch (IOException e2) {
472
}
473
}
474
}
475
476
}
477
478
public SocksServer(int port, boolean v4) throws IOException {
479
this(port);
480
this.useV4 = v4;
481
}
482
483
public SocksServer(int port) throws IOException {
484
this.port = port;
485
server = new ServerSocket();
486
if (port == 0) {
487
server.bind(null);
488
this.port = server.getLocalPort();
489
} else {
490
server.bind(new InetSocketAddress(port));
491
}
492
}
493
494
public SocksServer(InetAddress addr, int port, boolean useV4) throws IOException {
495
this.port = port;
496
this.useV4 = useV4;
497
server = new ServerSocket();
498
if (port == 0 && addr == null) {
499
server.bind(null);
500
this.port = server.getLocalPort();
501
} else if (port == 0 && addr != null) {
502
server.bind(new InetSocketAddress(addr, 0));
503
this.port = server.getLocalPort();
504
} else if (addr == null) {
505
assert port != 0;
506
server.bind(new InetSocketAddress(port));
507
} else {
508
assert port != 0;
509
server.bind(new InetSocketAddress(addr, port));
510
}
511
}
512
513
public SocksServer() throws IOException {
514
this (DEFAULT_PORT);
515
}
516
517
public void addUser(String user, String passwd) {
518
users.put(user, passwd);
519
}
520
521
public int getPort() {
522
return port;
523
}
524
525
public void close() {
526
done = true;
527
try { server.close(); } catch (IOException unused) {}
528
}
529
530
public void run() {
531
ClientHandler cl = null;
532
while (!done) {
533
try {
534
Socket s = server.accept();
535
cl = new ClientHandler(s);
536
cl.start();
537
} catch (IOException ex) {
538
if (cl != null)
539
cl.interrupt();
540
}
541
}
542
}
543
}
544
545