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