1
25 package java.net;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.io.BufferedOutputStream;
30 import java.security.AccessController;
31 import java.security.PrivilegedAction;
32 import java.security.PrivilegedExceptionAction;
33
34 import jdk.internal.util.StaticProperty;
35 import sun.net.SocksProxy;
36 import sun.net.spi.DefaultProxySelector;
37 import sun.net.www.ParseUtil;
38
39
40
45
46 class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
47 private String server = null;
48 private int serverPort = DEFAULT_PORT;
49 private InetSocketAddress external_address;
50 private boolean useV4 = false;
51 private Socket cmdsock = null;
52 private InputStream cmdIn = null;
53 private OutputStream cmdOut = null;
54
55 private boolean applicationSetProxy;
56
57
58 SocksSocketImpl() {
59
60 }
61
62 SocksSocketImpl(String server, int port) {
63 this.server = server;
64 this.serverPort = (port == -1 ? DEFAULT_PORT : port);
65 }
66
67 SocksSocketImpl(Proxy proxy) {
68 SocketAddress a = proxy.address();
69 if (a instanceof InetSocketAddress) {
70 InetSocketAddress ad = (InetSocketAddress) a;
71
72 server = ad.getHostString();
73 serverPort = ad.getPort();
74 }
75 useV4 = useV4(proxy);
76 }
77
78 void setV4() {
79 useV4 = true;
80 }
81
82 private static boolean useV4(Proxy proxy) {
83 if (proxy instanceof SocksProxy
84 && ((SocksProxy)proxy).protocolVersion() == 4) {
85 return true;
86 }
87 return DefaultProxySelector.socksProxyVersion() == 4;
88 }
89
90 private synchronized void privilegedConnect(final String host,
91 final int port,
92 final int timeout)
93 throws IOException
94 {
95 try {
96 AccessController.doPrivileged(
97 new java.security.PrivilegedExceptionAction<>() {
98 public Void run() throws IOException {
99 superConnectServer(host, port, timeout);
100 cmdIn = getInputStream();
101 cmdOut = getOutputStream();
102 return null;
103 }
104 });
105 } catch (java.security.PrivilegedActionException pae) {
106 throw (IOException) pae.getException();
107 }
108 }
109
110 private void superConnectServer(String host, int port,
111 int timeout) throws IOException {
112 super.connect(new InetSocketAddress(host, port), timeout);
113 }
114
115 private static int remainingMillis(long deadlineMillis) throws IOException {
116 if (deadlineMillis == 0L)
117 return 0;
118
119 final long remaining = deadlineMillis - System.currentTimeMillis();
120 if (remaining > 0)
121 return (int) remaining;
122
123 throw new SocketTimeoutException();
124 }
125
126 private int readSocksReply(InputStream in, byte[] data) throws IOException {
127 return readSocksReply(in, data, 0L);
128 }
129
130 private int readSocksReply(InputStream in, byte[] data, long deadlineMillis) throws IOException {
131 int len = data.length;
132 int received = 0;
133 while (received < len) {
134 int count;
135 try {
136 count = ((SocketInputStream)in).read(data, received, len - received, remainingMillis(deadlineMillis));
137 } catch (SocketTimeoutException e) {
138 throw new SocketTimeoutException("Connect timed out");
139 }
140 if (count < 0)
141 throw new SocketException("Malformed reply from SOCKS server");
142 received += count;
143 }
144 return received;
145 }
146
147
150 private boolean authenticate(byte method, InputStream in,
151 BufferedOutputStream out) throws IOException {
152 return authenticate(method, in, out, 0L);
153 }
154
155 private boolean authenticate(byte method, InputStream in,
156 BufferedOutputStream out,
157 long deadlineMillis) throws IOException {
158
159 if (method == NO_AUTH)
160 return true;
161
166 if (method == USER_PASSW) {
167 String userName;
168 String password = null;
169 final InetAddress addr = InetAddress.getByName(server);
170 PasswordAuthentication pw =
171 java.security.AccessController.doPrivileged(
172 new java.security.PrivilegedAction<>() {
173 public PasswordAuthentication run() {
174 return Authenticator.requestPasswordAuthentication(
175 server, addr, serverPort, "SOCKS5", "SOCKS authentication", null);
176 }
177 });
178 if (pw != null) {
179 userName = pw.getUserName();
180 password = new String(pw.getPassword());
181 } else {
182 userName = StaticProperty.userName();
183 }
184 if (userName == null)
185 return false;
186 out.write(1);
187 out.write(userName.length());
188 try {
189 out.write(userName.getBytes("ISO-8859-1"));
190 } catch (java.io.UnsupportedEncodingException uee) {
191 assert false;
192 }
193 if (password != null) {
194 out.write(password.length());
195 try {
196 out.write(password.getBytes("ISO-8859-1"));
197 } catch (java.io.UnsupportedEncodingException uee) {
198 assert false;
199 }
200 } else
201 out.write(0);
202 out.flush();
203 byte[] data = new byte[2];
204 int i = readSocksReply(in, data, deadlineMillis);
205 if (i != 2 || data[1] != 0) {
206
208 out.close();
209 in.close();
210 return false;
211 }
212
213 return true;
214 }
215
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
264
265
266
267
268
269 return false;
270 }
271
272 private void connectV4(InputStream in, OutputStream out,
273 InetSocketAddress endpoint,
274 long deadlineMillis) throws IOException {
275 if (!(endpoint.getAddress() instanceof Inet4Address)) {
276 throw new SocketException("SOCKS V4 requires IPv4 only addresses");
277 }
278 out.write(PROTO_VERS4);
279 out.write(CONNECT);
280 out.write((endpoint.getPort() >> 8) & 0xff);
281 out.write((endpoint.getPort() >> 0) & 0xff);
282 out.write(endpoint.getAddress().getAddress());
283 String userName = getUserName();
284 try {
285 out.write(userName.getBytes("ISO-8859-1"));
286 } catch (java.io.UnsupportedEncodingException uee) {
287 assert false;
288 }
289 out.write(0);
290 out.flush();
291 byte[] data = new byte[8];
292 int n = readSocksReply(in, data, deadlineMillis);
293 if (n != 8)
294 throw new SocketException("Reply from SOCKS server has bad length: " + n);
295 if (data[0] != 0 && data[0] != 4)
296 throw new SocketException("Reply from SOCKS server has bad version");
297 SocketException ex = null;
298 switch (data[1]) {
299 case 90:
300
301 external_address = endpoint;
302 break;
303 case 91:
304 ex = new SocketException("SOCKS request rejected");
305 break;
306 case 92:
307 ex = new SocketException("SOCKS server couldn't reach destination");
308 break;
309 case 93:
310 ex = new SocketException("SOCKS authentication failed");
311 break;
312 default:
313 ex = new SocketException("Reply from SOCKS server contains bad status");
314 break;
315 }
316 if (ex != null) {
317 in.close();
318 out.close();
319 throw ex;
320 }
321 }
322
323
337 @Override
338 protected void connect(SocketAddress endpoint, int timeout) throws IOException {
339 final long deadlineMillis;
340
341 if (timeout == 0) {
342 deadlineMillis = 0L;
343 } else {
344 long finish = System.currentTimeMillis() + timeout;
345 deadlineMillis = finish < 0 ? Long.MAX_VALUE : finish;
346 }
347
348 SecurityManager security = System.getSecurityManager();
349 if (endpoint == null || !(endpoint instanceof InetSocketAddress))
350 throw new IllegalArgumentException("Unsupported address type");
351 InetSocketAddress epoint = (InetSocketAddress) endpoint;
352 if (security != null) {
353 if (epoint.isUnresolved())
354 security.checkConnect(epoint.getHostName(),
355 epoint.getPort());
356 else
357 security.checkConnect(epoint.getAddress().getHostAddress(),
358 epoint.getPort());
359 }
360 if (server == null) {
361
362
363
364 ProxySelector sel = java.security.AccessController.doPrivileged(
365 new java.security.PrivilegedAction<>() {
366 public ProxySelector run() {
367 return ProxySelector.getDefault();
368 }
369 });
370 if (sel == null) {
371
374 super.connect(epoint, remainingMillis(deadlineMillis));
375 return;
376 }
377 URI uri;
378
379 String host = epoint.getHostString();
380
381 if (epoint.getAddress() instanceof Inet6Address &&
382 (!host.startsWith("[")) && (host.indexOf(':') >= 0)) {
383 host = "[" + host + "]";
384 }
385 try {
386 uri = new URI("socket: + ParseUtil.encodePath(host) + ":"+ epoint.getPort());
387 } catch (URISyntaxException e) {
388
389 assert false : e;
390 uri = null;
391 }
392 Proxy p = null;
393 IOException savedExc = null;
394 java.util.Iterator<Proxy> iProxy = null;
395 iProxy = sel.select(uri).iterator();
396 if (iProxy == null || !(iProxy.hasNext())) {
397 super.connect(epoint, remainingMillis(deadlineMillis));
398 return;
399 }
400 while (iProxy.hasNext()) {
401 p = iProxy.next();
402 if (p == null || p.type() != Proxy.Type.SOCKS) {
403 super.connect(epoint, remainingMillis(deadlineMillis));
404 return;
405 }
406
407 if (!(p.address() instanceof InetSocketAddress))
408 throw new SocketException("Unknown address type for proxy: " + p);
409
410 server = ((InetSocketAddress) p.address()).getHostString();
411 serverPort = ((InetSocketAddress) p.address()).getPort();
412 useV4 = useV4(p);
413
414
415 try {
416 privilegedConnect(server, serverPort, remainingMillis(deadlineMillis));
417
418 break;
419 } catch (IOException e) {
420
421 sel.connectFailed(uri,p.address(),e);
422 server = null;
423 serverPort = -1;
424 savedExc = e;
425
426 }
427 }
428
429
433 if (server == null) {
434 throw new SocketException("Can't connect to SOCKS proxy:"
435 + savedExc.getMessage());
436 }
437 } else {
438
439 try {
440 privilegedConnect(server, serverPort, remainingMillis(deadlineMillis));
441 } catch (IOException e) {
442 throw new SocketException(e.getMessage());
443 }
444 }
445
446
447 BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512);
448 InputStream in = cmdIn;
449
450 if (useV4) {
451
452
453 if (epoint.isUnresolved())
454 throw new UnknownHostException(epoint.toString());
455 connectV4(in, out, epoint, deadlineMillis);
456 return;
457 }
458
459
460 out.write(PROTO_VERS);
461 out.write(2);
462 out.write(NO_AUTH);
463 out.write(USER_PASSW);
464 out.flush();
465 byte[] data = new byte[2];
466 int i = readSocksReply(in, data, deadlineMillis);
467 if (i != 2 || ((int)data[0]) != PROTO_VERS) {
468
469
470
471
472 if (epoint.isUnresolved())
473 throw new UnknownHostException(epoint.toString());
474 connectV4(in, out, epoint, deadlineMillis);
475 return;
476 }
477 if (((int)data[1]) == NO_METHODS)
478 throw new SocketException("SOCKS : No acceptable methods");
479 if (!authenticate(data[1], in, out, deadlineMillis)) {
480 throw new SocketException("SOCKS : authentication failed");
481 }
482 out.write(PROTO_VERS);
483 out.write(CONNECT);
484 out.write(0);
485
486 if (epoint.isUnresolved()) {
487 out.write(DOMAIN_NAME);
488 out.write(epoint.getHostName().length());
489 try {
490 out.write(epoint.getHostName().getBytes("ISO-8859-1"));
491 } catch (java.io.UnsupportedEncodingException uee) {
492 assert false;
493 }
494 out.write((epoint.getPort() >> 8) & 0xff);
495 out.write((epoint.getPort() >> 0) & 0xff);
496 } else if (epoint.getAddress() instanceof Inet6Address) {
497 out.write(IPV6);
498 out.write(epoint.getAddress().getAddress());
499 out.write((epoint.getPort() >> 8) & 0xff);
500 out.write((epoint.getPort() >> 0) & 0xff);
501 } else {
502 out.write(IPV4);
503 out.write(epoint.getAddress().getAddress());
504 out.write((epoint.getPort() >> 8) & 0xff);
505 out.write((epoint.getPort() >> 0) & 0xff);
506 }
507 out.flush();
508 data = new byte[4];
509 i = readSocksReply(in, data, deadlineMillis);
510 if (i != 4)
511 throw new SocketException("Reply from SOCKS server has bad length");
512 SocketException ex = null;
513 int len;
514 byte[] addr;
515 switch (data[1]) {
516 case REQUEST_OK:
517
518 switch(data[3]) {
519 case IPV4:
520 addr = new byte[4];
521 i = readSocksReply(in, addr, deadlineMillis);
522 if (i != 4)
523 throw new SocketException("Reply from SOCKS server badly formatted");
524 data = new byte[2];
525 i = readSocksReply(in, data, deadlineMillis);
526 if (i != 2)
527 throw new SocketException("Reply from SOCKS server badly formatted");
528 break;
529 case DOMAIN_NAME:
530 byte[] lenByte = new byte[1];
531 i = readSocksReply(in, lenByte, deadlineMillis);
532 if (i != 1)
533 throw new SocketException("Reply from SOCKS server badly formatted");
534 len = lenByte[0] & 0xFF;
535 byte[] host = new byte[len];
536 i = readSocksReply(in, host, deadlineMillis);
537 if (i != len)
538 throw new SocketException("Reply from SOCKS server badly formatted");
539 data = new byte[2];
540 i = readSocksReply(in, data, deadlineMillis);
541 if (i != 2)
542 throw new SocketException("Reply from SOCKS server badly formatted");
543 break;
544 case IPV6:
545 len = 16;
546 addr = new byte[len];
547 i = readSocksReply(in, addr, deadlineMillis);
548 if (i != len)
549 throw new SocketException("Reply from SOCKS server badly formatted");
550 data = new byte[2];
551 i = readSocksReply(in, data, deadlineMillis);
552 if (i != 2)
553 throw new SocketException("Reply from SOCKS server badly formatted");
554 break;
555 default:
556 ex = new SocketException("Reply from SOCKS server contains wrong code");
557 break;
558 }
559 break;
560 case GENERAL_FAILURE:
561 ex = new SocketException("SOCKS server general failure");
562 break;
563 case NOT_ALLOWED:
564 ex = new SocketException("SOCKS: Connection not allowed by ruleset");
565 break;
566 case NET_UNREACHABLE:
567 ex = new SocketException("SOCKS: Network unreachable");
568 break;
569 case HOST_UNREACHABLE:
570 ex = new SocketException("SOCKS: Host unreachable");
571 break;
572 case CONN_REFUSED:
573 ex = new SocketException("SOCKS: Connection refused");
574 break;
575 case TTL_EXPIRED:
576 ex = new SocketException("SOCKS: TTL expired");
577 break;
578 case CMD_NOT_SUPPORTED:
579 ex = new SocketException("SOCKS: Command not supported");
580 break;
581 case ADDR_TYPE_NOT_SUP:
582 ex = new SocketException("SOCKS: address type not supported");
583 break;
584 }
585 if (ex != null) {
586 in.close();
587 out.close();
588 throw ex;
589 }
590 external_address = epoint;
591 }
592
593 private void bindV4(InputStream in, OutputStream out,
594 InetAddress baddr,
595 int lport) throws IOException {
596 if (!(baddr instanceof Inet4Address)) {
597 throw new SocketException("SOCKS V4 requires IPv4 only addresses");
598 }
599 super.bind(baddr, lport);
600 byte[] addr1 = baddr.getAddress();
601
602 InetAddress naddr = baddr;
603 if (naddr.isAnyLocalAddress()) {
604 naddr = AccessController.doPrivileged(
605 new PrivilegedAction<>() {
606 public InetAddress run() {
607 return cmdsock.getLocalAddress();
608
609 }
610 });
611 addr1 = naddr.getAddress();
612 }
613 out.write(PROTO_VERS4);
614 out.write(BIND);
615 out.write((super.getLocalPort() >> 8) & 0xff);
616 out.write((super.getLocalPort() >> 0) & 0xff);
617 out.write(addr1);
618 String userName = getUserName();
619 try {
620 out.write(userName.getBytes("ISO-8859-1"));
621 } catch (java.io.UnsupportedEncodingException uee) {
622 assert false;
623 }
624 out.write(0);
625 out.flush();
626 byte[] data = new byte[8];
627 int n = readSocksReply(in, data);
628 if (n != 8)
629 throw new SocketException("Reply from SOCKS server has bad length: " + n);
630 if (data[0] != 0 && data[0] != 4)
631 throw new SocketException("Reply from SOCKS server has bad version");
632 SocketException ex = null;
633 switch (data[1]) {
634 case 90:
635
636 external_address = new InetSocketAddress(baddr, lport);
637 break;
638 case 91:
639 ex = new SocketException("SOCKS request rejected");
640 break;
641 case 92:
642 ex = new SocketException("SOCKS server couldn't reach destination");
643 break;
644 case 93:
645 ex = new SocketException("SOCKS authentication failed");
646 break;
647 default:
648 ex = new SocketException("Reply from SOCKS server contains bad status");
649 break;
650 }
651 if (ex != null) {
652 in.close();
653 out.close();
654 throw ex;
655 }
656
657 }
658
659
667 protected synchronized void socksBind(InetSocketAddress saddr) throws IOException {
668 if (socket != null) {
669
670
671 return;
672 }
673
674
675
676 if (server == null) {
677
678
679
680 ProxySelector sel = java.security.AccessController.doPrivileged(
681 new java.security.PrivilegedAction<>() {
682 public ProxySelector run() {
683 return ProxySelector.getDefault();
684 }
685 });
686 if (sel == null) {
687
690 return;
691 }
692 URI uri;
693
694 String host = saddr.getHostString();
695
696 if (saddr.getAddress() instanceof Inet6Address &&
697 (!host.startsWith("[")) && (host.indexOf(':') >= 0)) {
698 host = "[" + host + "]";
699 }
700 try {
701 uri = new URI("serversocket: + ParseUtil.encodePath(host) + ":"+ saddr.getPort());
702 } catch (URISyntaxException e) {
703
704 assert false : e;
705 uri = null;
706 }
707 Proxy p = null;
708 Exception savedExc = null;
709 java.util.Iterator<Proxy> iProxy = null;
710 iProxy = sel.select(uri).iterator();
711 if (iProxy == null || !(iProxy.hasNext())) {
712 return;
713 }
714 while (iProxy.hasNext()) {
715 p = iProxy.next();
716 if (p == null || p.type() != Proxy.Type.SOCKS) {
717 return;
718 }
719
720 if (!(p.address() instanceof InetSocketAddress))
721 throw new SocketException("Unknown address type for proxy: " + p);
722
723 server = ((InetSocketAddress) p.address()).getHostString();
724 serverPort = ((InetSocketAddress) p.address()).getPort();
725 useV4 = useV4(p);
726
727
728 try {
729 AccessController.doPrivileged(
730 new PrivilegedExceptionAction<>() {
731 public Void run() throws Exception {
732 cmdsock = new Socket(new PlainSocketImpl());
733 cmdsock.connect(new InetSocketAddress(server, serverPort));
734 cmdIn = cmdsock.getInputStream();
735 cmdOut = cmdsock.getOutputStream();
736 return null;
737 }
738 });
739 } catch (Exception e) {
740
741 sel.connectFailed(uri,p.address(),new SocketException(e.getMessage()));
742 server = null;
743 serverPort = -1;
744 cmdsock = null;
745 savedExc = e;
746
747 }
748 }
749
750
754 if (server == null || cmdsock == null) {
755 throw new SocketException("Can't connect to SOCKS proxy:"
756 + savedExc.getMessage());
757 }
758 } else {
759 try {
760 AccessController.doPrivileged(
761 new PrivilegedExceptionAction<>() {
762 public Void run() throws Exception {
763 cmdsock = new Socket(new PlainSocketImpl());
764 cmdsock.connect(new InetSocketAddress(server, serverPort));
765 cmdIn = cmdsock.getInputStream();
766 cmdOut = cmdsock.getOutputStream();
767 return null;
768 }
769 });
770 } catch (Exception e) {
771 throw new SocketException(e.getMessage());
772 }
773 }
774 BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512);
775 InputStream in = cmdIn;
776 if (useV4) {
777 bindV4(in, out, saddr.getAddress(), saddr.getPort());
778 return;
779 }
780 out.write(PROTO_VERS);
781 out.write(2);
782 out.write(NO_AUTH);
783 out.write(USER_PASSW);
784 out.flush();
785 byte[] data = new byte[2];
786 int i = readSocksReply(in, data);
787 if (i != 2 || ((int)data[0]) != PROTO_VERS) {
788
789
790 bindV4(in, out, saddr.getAddress(), saddr.getPort());
791 return;
792 }
793 if (((int)data[1]) == NO_METHODS)
794 throw new SocketException("SOCKS : No acceptable methods");
795 if (!authenticate(data[1], in, out)) {
796 throw new SocketException("SOCKS : authentication failed");
797 }
798
799 out.write(PROTO_VERS);
800 out.write(BIND);
801 out.write(0);
802 int lport = saddr.getPort();
803 if (saddr.isUnresolved()) {
804 out.write(DOMAIN_NAME);
805 out.write(saddr.getHostName().length());
806 try {
807 out.write(saddr.getHostName().getBytes("ISO-8859-1"));
808 } catch (java.io.UnsupportedEncodingException uee) {
809 assert false;
810 }
811 out.write((lport >> 8) & 0xff);
812 out.write((lport >> 0) & 0xff);
813 } else if (saddr.getAddress() instanceof Inet4Address) {
814 byte[] addr1 = saddr.getAddress().getAddress();
815 out.write(IPV4);
816 out.write(addr1);
817 out.write((lport >> 8) & 0xff);
818 out.write((lport >> 0) & 0xff);
819 out.flush();
820 } else if (saddr.getAddress() instanceof Inet6Address) {
821 byte[] addr1 = saddr.getAddress().getAddress();
822 out.write(IPV6);
823 out.write(addr1);
824 out.write((lport >> 8) & 0xff);
825 out.write((lport >> 0) & 0xff);
826 out.flush();
827 } else {
828 cmdsock.close();
829 throw new SocketException("unsupported address type : " + saddr);
830 }
831 data = new byte[4];
832 i = readSocksReply(in, data);
833 SocketException ex = null;
834 int len, nport;
835 byte[] addr;
836 switch (data[1]) {
837 case REQUEST_OK:
838
839 switch(data[3]) {
840 case IPV4:
841 addr = new byte[4];
842 i = readSocksReply(in, addr);
843 if (i != 4)
844 throw new SocketException("Reply from SOCKS server badly formatted");
845 data = new byte[2];
846 i = readSocksReply(in, data);
847 if (i != 2)
848 throw new SocketException("Reply from SOCKS server badly formatted");
849 nport = ((int)data[0] & 0xff) << 8;
850 nport += ((int)data[1] & 0xff);
851 external_address =
852 new InetSocketAddress(new Inet4Address("", addr) , nport);
853 break;
854 case DOMAIN_NAME:
855 len = data[1];
856 byte[] host = new byte[len];
857 i = readSocksReply(in, host);
858 if (i != len)
859 throw new SocketException("Reply from SOCKS server badly formatted");
860 data = new byte[2];
861 i = readSocksReply(in, data);
862 if (i != 2)
863 throw new SocketException("Reply from SOCKS server badly formatted");
864 nport = ((int)data[0] & 0xff) << 8;
865 nport += ((int)data[1] & 0xff);
866 external_address = new InetSocketAddress(new String(host), nport);
867 break;
868 case IPV6:
869 len = data[1];
870 addr = new byte[len];
871 i = readSocksReply(in, addr);
872 if (i != len)
873 throw new SocketException("Reply from SOCKS server badly formatted");
874 data = new byte[2];
875 i = readSocksReply(in, data);
876 if (i != 2)
877 throw new SocketException("Reply from SOCKS server badly formatted");
878 nport = ((int)data[0] & 0xff) << 8;
879 nport += ((int)data[1] & 0xff);
880 external_address =
881 new InetSocketAddress(new Inet6Address("", addr), nport);
882 break;
883 }
884 break;
885 case GENERAL_FAILURE:
886 ex = new SocketException("SOCKS server general failure");
887 break;
888 case NOT_ALLOWED:
889 ex = new SocketException("SOCKS: Bind not allowed by ruleset");
890 break;
891 case NET_UNREACHABLE:
892 ex = new SocketException("SOCKS: Network unreachable");
893 break;
894 case HOST_UNREACHABLE:
895 ex = new SocketException("SOCKS: Host unreachable");
896 break;
897 case CONN_REFUSED:
898 ex = new SocketException("SOCKS: Connection refused");
899 break;
900 case TTL_EXPIRED:
901 ex = new SocketException("SOCKS: TTL expired");
902 break;
903 case CMD_NOT_SUPPORTED:
904 ex = new SocketException("SOCKS: Command not supported");
905 break;
906 case ADDR_TYPE_NOT_SUP:
907 ex = new SocketException("SOCKS: address type not supported");
908 break;
909 }
910 if (ex != null) {
911 in.close();
912 out.close();
913 cmdsock.close();
914 cmdsock = null;
915 throw ex;
916 }
917 cmdIn = in;
918 cmdOut = out;
919 }
920
921
930 protected void acceptFrom(SocketImpl s, InetSocketAddress saddr) throws IOException {
931 if (cmdsock == null) {
932
933 return;
934 }
935 InputStream in = cmdIn;
936
937 socksBind(saddr);
938 in.read();
939 int i = in.read();
940 in.read();
941 SocketException ex = null;
942 int nport;
943 byte[] addr;
944 InetSocketAddress real_end = null;
945 switch (i) {
946 case REQUEST_OK:
947
948 i = in.read();
949 switch(i) {
950 case IPV4:
951 addr = new byte[4];
952 readSocksReply(in, addr);
953 nport = in.read() << 8;
954 nport += in.read();
955 real_end =
956 new InetSocketAddress(new Inet4Address("", addr) , nport);
957 break;
958 case DOMAIN_NAME:
959 int len = in.read();
960 addr = new byte[len];
961 readSocksReply(in, addr);
962 nport = in.read() << 8;
963 nport += in.read();
964 real_end = new InetSocketAddress(new String(addr), nport);
965 break;
966 case IPV6:
967 addr = new byte[16];
968 readSocksReply(in, addr);
969 nport = in.read() << 8;
970 nport += in.read();
971 real_end =
972 new InetSocketAddress(new Inet6Address("", addr), nport);
973 break;
974 }
975 break;
976 case GENERAL_FAILURE:
977 ex = new SocketException("SOCKS server general failure");
978 break;
979 case NOT_ALLOWED:
980 ex = new SocketException("SOCKS: Accept not allowed by ruleset");
981 break;
982 case NET_UNREACHABLE:
983 ex = new SocketException("SOCKS: Network unreachable");
984 break;
985 case HOST_UNREACHABLE:
986 ex = new SocketException("SOCKS: Host unreachable");
987 break;
988 case CONN_REFUSED:
989 ex = new SocketException("SOCKS: Connection refused");
990 break;
991 case TTL_EXPIRED:
992 ex = new SocketException("SOCKS: TTL expired");
993 break;
994 case CMD_NOT_SUPPORTED:
995 ex = new SocketException("SOCKS: Command not supported");
996 break;
997 case ADDR_TYPE_NOT_SUP:
998 ex = new SocketException("SOCKS: address type not supported");
999 break;
1000 }
1001 if (ex != null) {
1002 cmdIn.close();
1003 cmdOut.close();
1004 cmdsock.close();
1005 cmdsock = null;
1006 throw ex;
1007 }
1008
1009
1014 if (s instanceof SocksSocketImpl) {
1015 ((SocksSocketImpl)s).external_address = real_end;
1016 }
1017 if (s instanceof PlainSocketImpl) {
1018 PlainSocketImpl psi = (PlainSocketImpl) s;
1019 psi.setInputStream((SocketInputStream) in);
1020 psi.setFileDescriptor(cmdsock.getImpl().getFileDescriptor());
1021 psi.setAddress(cmdsock.getImpl().getInetAddress());
1022 psi.setPort(cmdsock.getImpl().getPort());
1023 psi.setLocalPort(cmdsock.getImpl().getLocalPort());
1024 } else {
1025 s.fd = cmdsock.getImpl().fd;
1026 s.address = cmdsock.getImpl().address;
1027 s.port = cmdsock.getImpl().port;
1028 s.localport = cmdsock.getImpl().localport;
1029 }
1030
1031
1032
1033
1034
1035 cmdsock = null;
1036 }
1037
1038
1039
1045 @Override
1046 protected InetAddress getInetAddress() {
1047 if (external_address != null)
1048 return external_address.getAddress();
1049 else
1050 return super.getInetAddress();
1051 }
1052
1053
1059 @Override
1060 protected int getPort() {
1061 if (external_address != null)
1062 return external_address.getPort();
1063 else
1064 return super.getPort();
1065 }
1066
1067 @Override
1068 protected int getLocalPort() {
1069 if (socket != null)
1070 return super.getLocalPort();
1071 if (external_address != null)
1072 return external_address.getPort();
1073 else
1074 return super.getLocalPort();
1075 }
1076
1077 @Override
1078 protected void close() throws IOException {
1079 if (cmdsock != null)
1080 cmdsock.close();
1081 cmdsock = null;
1082 super.close();
1083 }
1084
1085 private String getUserName() {
1086 String userName = "";
1087 if (applicationSetProxy) {
1088 try {
1089 userName = System.getProperty("user.name");
1090 } catch (SecurityException se) { }
1091 } else {
1092 userName = StaticProperty.userName();
1093 }
1094 return userName;
1095 }
1096 }
1097