src/java.base/share/classes/java/net/SocksSocketImpl.java
branchniosocketimpl-branch
changeset 57112 d7b54daf5e1a
parent 57110 b848ca1ef778
parent 53473 9366628d727b
child 57167 82874527373e
equal deleted inserted replaced
57111:a57c4dc7e2fe 57112:d7b54daf5e1a
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 package java.net;
    25 package java.net;
       
    26 
    26 import java.io.IOException;
    27 import java.io.IOException;
    27 import java.io.InputStream;
    28 import java.io.InputStream;
    28 import java.io.OutputStream;
    29 import java.io.OutputStream;
    29 import java.io.BufferedOutputStream;
    30 import java.io.BufferedOutputStream;
    30 import java.security.AccessController;
    31 import java.security.AccessController;
    31 import java.security.PrivilegedAction;
       
    32 import java.security.PrivilegedExceptionAction;
       
    33 
    32 
    34 import jdk.internal.util.StaticProperty;
    33 import jdk.internal.util.StaticProperty;
    35 import sun.net.SocksProxy;
    34 import sun.net.SocksProxy;
    36 import sun.net.spi.DefaultProxySelector;
    35 import sun.net.spi.DefaultProxySelector;
    37 import sun.net.www.ParseUtil;
    36 import sun.net.www.ParseUtil;
    38 import sun.nio.ch.NioSocketImpl;
    37 import sun.nio.ch.NioSocketImpl;
    39 /* import org.ietf.jgss.*; */
       
    40 
    38 
    41 /**
    39 /**
    42  * SOCKS (V4 & V5) TCP socket implementation (RFC 1928).
    40  * SOCKS (V4 & V5) TCP socket implementation (RFC 1928).
    43  * Note this class should <b>NOT</b> be public.
    41  * Note this class should <b>NOT</b> be public.
    44  */
    42  */
    49     private InetSocketAddress external_address;
    47     private InetSocketAddress external_address;
    50     private boolean useV4 = false;
    48     private boolean useV4 = false;
    51     private Socket cmdsock = null;
    49     private Socket cmdsock = null;
    52     private InputStream cmdIn = null;
    50     private InputStream cmdIn = null;
    53     private OutputStream cmdOut = null;
    51     private OutputStream cmdOut = null;
    54     /* true if the Proxy has been set programmatically */
       
    55     private boolean applicationSetProxy;  /* false */
       
    56 
    52 
    57     SocksSocketImpl() {
    53     SocksSocketImpl() {
    58         super(false);
    54         super(false);
    59     }
    55     }
    60 
    56 
    66             // Use getHostString() to avoid reverse lookups
    62             // Use getHostString() to avoid reverse lookups
    67             server = ad.getHostString();
    63             server = ad.getHostString();
    68             serverPort = ad.getPort();
    64             serverPort = ad.getPort();
    69         }
    65         }
    70         useV4 = useV4(proxy);
    66         useV4 = useV4(proxy);
    71     }
       
    72 
       
    73     void setV4() {
       
    74         useV4 = true;
       
    75     }
    67     }
    76 
    68 
    77     private static boolean useV4(Proxy proxy) {
    69     private static boolean useV4(Proxy proxy) {
    78         if (proxy instanceof SocksProxy
    70         if (proxy instanceof SocksProxy
    79             && ((SocksProxy)proxy).protocolVersion() == 4) {
    71             && ((SocksProxy)proxy).protocolVersion() == 4) {
   116             return (int) remaining;
   108             return (int) remaining;
   117 
   109 
   118         throw new SocketTimeoutException();
   110         throw new SocketTimeoutException();
   119     }
   111     }
   120 
   112 
   121     private int readSocksReply(InputStream in, byte[] data) throws IOException {
       
   122         return readSocksReply(in, data, 0L);
       
   123     }
       
   124 
       
   125     private int readSocksReply(InputStream in, byte[] data, long deadlineMillis) throws IOException {
   113     private int readSocksReply(InputStream in, byte[] data, long deadlineMillis) throws IOException {
   126         int len = data.length;
   114         int len = data.length;
   127         int received = 0;
   115         int received = 0;
   128         int originalTimeout = (int) getOption(SocketOptions.SO_TIMEOUT);
   116         int originalTimeout = (int) getOption(SocketOptions.SO_TIMEOUT);
   129         try {
   117         try {
   142             }
   130             }
   143         } finally {
   131         } finally {
   144             setOption(SocketOptions.SO_TIMEOUT, originalTimeout);
   132             setOption(SocketOptions.SO_TIMEOUT, originalTimeout);
   145         }
   133         }
   146         return received;
   134         return received;
   147     }
       
   148 
       
   149     /**
       
   150      * Provides the authentication mechanism required by the proxy.
       
   151      */
       
   152     private boolean authenticate(byte method, InputStream in,
       
   153                                  BufferedOutputStream out) throws IOException {
       
   154         return authenticate(method, in, out, 0L);
       
   155     }
   135     }
   156 
   136 
   157     private boolean authenticate(byte method, InputStream in,
   137     private boolean authenticate(byte method, InputStream in,
   158                                  BufferedOutputStream out,
   138                                  BufferedOutputStream out,
   159                                  long deadlineMillis) throws IOException {
   139                                  long deadlineMillis) throws IOException {
   212                 return false;
   192                 return false;
   213             }
   193             }
   214             /* Authentication succeeded */
   194             /* Authentication succeeded */
   215             return true;
   195             return true;
   216         }
   196         }
   217         /**
       
   218          * GSSAPI authentication mechanism.
       
   219          * Unfortunately the RFC seems out of sync with the Reference
       
   220          * implementation. I'll leave this in for future completion.
       
   221          */
       
   222 //      if (method == GSSAPI) {
       
   223 //          try {
       
   224 //              GSSManager manager = GSSManager.getInstance();
       
   225 //              GSSName name = manager.createName("SERVICE:socks@"+server,
       
   226 //                                                   null);
       
   227 //              GSSContext context = manager.createContext(name, null, null,
       
   228 //                                                         GSSContext.DEFAULT_LIFETIME);
       
   229 //              context.requestMutualAuth(true);
       
   230 //              context.requestReplayDet(true);
       
   231 //              context.requestSequenceDet(true);
       
   232 //              context.requestCredDeleg(true);
       
   233 //              byte []inToken = new byte[0];
       
   234 //              while (!context.isEstablished()) {
       
   235 //                  byte[] outToken
       
   236 //                      = context.initSecContext(inToken, 0, inToken.length);
       
   237 //                  // send the output token if generated
       
   238 //                  if (outToken != null) {
       
   239 //                      out.write(1);
       
   240 //                      out.write(1);
       
   241 //                      out.writeShort(outToken.length);
       
   242 //                      out.write(outToken);
       
   243 //                      out.flush();
       
   244 //                      data = new byte[2];
       
   245 //                      i = readSocksReply(in, data, deadlineMillis);
       
   246 //                      if (i != 2 || data[1] == 0xff) {
       
   247 //                          in.close();
       
   248 //                          out.close();
       
   249 //                          return false;
       
   250 //                      }
       
   251 //                      i = readSocksReply(in, data, deadlineMillis);
       
   252 //                      int len = 0;
       
   253 //                      len = ((int)data[0] & 0xff) << 8;
       
   254 //                      len += data[1];
       
   255 //                      data = new byte[len];
       
   256 //                      i = readSocksReply(in, data, deadlineMillis);
       
   257 //                      if (i == len)
       
   258 //                          return true;
       
   259 //                      in.close();
       
   260 //                      out.close();
       
   261 //                  }
       
   262 //              }
       
   263 //          } catch (GSSException e) {
       
   264 //              /* RFC 1961 states that if Context initialisation fails the connection
       
   265 //                 MUST be closed */
       
   266 //              e.printStackTrace();
       
   267 //              in.close();
       
   268 //              out.close();
       
   269 //          }
       
   270 //      }
       
   271         return false;
   197         return false;
   272     }
   198     }
   273 
   199 
   274     private void connectV4(InputStream in, OutputStream out,
   200     private void connectV4(InputStream in, OutputStream out,
   275                            InetSocketAddress endpoint,
   201                            InetSocketAddress endpoint,
   590             throw ex;
   516             throw ex;
   591         }
   517         }
   592         external_address = epoint;
   518         external_address = epoint;
   593     }
   519     }
   594 
   520 
   595     private void bindV4(InputStream in, OutputStream out,
       
   596                         InetAddress baddr,
       
   597                         int lport) throws IOException {
       
   598         if (!(baddr instanceof Inet4Address)) {
       
   599             throw new SocketException("SOCKS V4 requires IPv4 only addresses");
       
   600         }
       
   601         super.bind(baddr, lport);
       
   602         byte[] addr1 = baddr.getAddress();
       
   603         /* Test for AnyLocal */
       
   604         InetAddress naddr = baddr;
       
   605         if (naddr.isAnyLocalAddress()) {
       
   606             naddr = AccessController.doPrivileged(
       
   607                         new PrivilegedAction<>() {
       
   608                             public InetAddress run() {
       
   609                                 return cmdsock.getLocalAddress();
       
   610 
       
   611                             }
       
   612                         });
       
   613             addr1 = naddr.getAddress();
       
   614         }
       
   615         out.write(PROTO_VERS4);
       
   616         out.write(BIND);
       
   617         out.write((super.getLocalPort() >> 8) & 0xff);
       
   618         out.write((super.getLocalPort() >> 0) & 0xff);
       
   619         out.write(addr1);
       
   620         String userName = getUserName();
       
   621         try {
       
   622             out.write(userName.getBytes("ISO-8859-1"));
       
   623         } catch (java.io.UnsupportedEncodingException uee) {
       
   624             assert false;
       
   625         }
       
   626         out.write(0);
       
   627         out.flush();
       
   628         byte[] data = new byte[8];
       
   629         int n = readSocksReply(in, data);
       
   630         if (n != 8)
       
   631             throw new SocketException("Reply from SOCKS server has bad length: " + n);
       
   632         if (data[0] != 0 && data[0] != 4)
       
   633             throw new SocketException("Reply from SOCKS server has bad version");
       
   634         SocketException ex = null;
       
   635         switch (data[1]) {
       
   636         case 90:
       
   637             // Success!
       
   638             external_address = new InetSocketAddress(baddr, lport);
       
   639             break;
       
   640         case 91:
       
   641             ex = new SocketException("SOCKS request rejected");
       
   642             break;
       
   643         case 92:
       
   644             ex = new SocketException("SOCKS server couldn't reach destination");
       
   645             break;
       
   646         case 93:
       
   647             ex = new SocketException("SOCKS authentication failed");
       
   648             break;
       
   649         default:
       
   650             ex = new SocketException("Reply from SOCKS server contains bad status");
       
   651             break;
       
   652         }
       
   653         if (ex != null) {
       
   654             in.close();
       
   655             out.close();
       
   656             throw ex;
       
   657         }
       
   658 
       
   659     }
       
   660 
       
   661     /**
       
   662      * Sends the Bind request to the SOCKS proxy. In the SOCKS protocol, bind
       
   663      * means "accept incoming connection from", so the SocketAddress is
       
   664      * the one of the host we do accept connection from.
       
   665      *
       
   666      * @param      saddr   the Socket address of the remote host.
       
   667      * @exception  IOException  if an I/O error occurs when binding this socket.
       
   668      */
       
   669     protected synchronized void socksBind(InetSocketAddress saddr) throws IOException {
       
   670         if (((SocketImpl) this).socket != null) {
       
   671             // this is a client socket, not a server socket, don't
       
   672             // call the SOCKS proxy for a bind!
       
   673             return;
       
   674         }
       
   675 
       
   676         // Connects to the SOCKS server
       
   677 
       
   678         if (server == null) {
       
   679             // This is the general case
       
   680             // server is not null only when the socket was created with a
       
   681             // specified proxy in which case it does bypass the ProxySelector
       
   682             ProxySelector sel = java.security.AccessController.doPrivileged(
       
   683                 new java.security.PrivilegedAction<>() {
       
   684                     public ProxySelector run() {
       
   685                             return ProxySelector.getDefault();
       
   686                         }
       
   687                     });
       
   688             if (sel == null) {
       
   689                 /*
       
   690                  * No default proxySelector --> direct connection
       
   691                  */
       
   692                 return;
       
   693             }
       
   694             URI uri;
       
   695             // Use getHostString() to avoid reverse lookups
       
   696             String host = saddr.getHostString();
       
   697             // IPv6 literal?
       
   698             if (saddr.getAddress() instanceof Inet6Address &&
       
   699                 (!host.startsWith("[")) && (host.indexOf(':') >= 0)) {
       
   700                 host = "[" + host + "]";
       
   701             }
       
   702             try {
       
   703                 uri = new URI("serversocket://" + ParseUtil.encodePath(host) + ":"+ saddr.getPort());
       
   704             } catch (URISyntaxException e) {
       
   705                 // This shouldn't happen
       
   706                 assert false : e;
       
   707                 uri = null;
       
   708             }
       
   709             Proxy p = null;
       
   710             Exception savedExc = null;
       
   711             java.util.Iterator<Proxy> iProxy = null;
       
   712             iProxy = sel.select(uri).iterator();
       
   713             if (iProxy == null || !(iProxy.hasNext())) {
       
   714                 return;
       
   715             }
       
   716             while (iProxy.hasNext()) {
       
   717                 p = iProxy.next();
       
   718                 if (p == null || p.type() != Proxy.Type.SOCKS) {
       
   719                     return;
       
   720                 }
       
   721 
       
   722                 if (!(p.address() instanceof InetSocketAddress))
       
   723                     throw new SocketException("Unknown address type for proxy: " + p);
       
   724                 // Use getHostString() to avoid reverse lookups
       
   725                 server = ((InetSocketAddress) p.address()).getHostString();
       
   726                 serverPort = ((InetSocketAddress) p.address()).getPort();
       
   727                 useV4 = useV4(p);
       
   728 
       
   729                 // Connects to the SOCKS server
       
   730                 try {
       
   731                     AccessController.doPrivileged(
       
   732                         new PrivilegedExceptionAction<>() {
       
   733                             public Void run() throws Exception {
       
   734                                 cmdsock = new Socket(new NioSocketImpl(false));
       
   735                                 cmdsock.connect(new InetSocketAddress(server, serverPort));
       
   736                                 cmdIn = cmdsock.getInputStream();
       
   737                                 cmdOut = cmdsock.getOutputStream();
       
   738                                 return null;
       
   739                             }
       
   740                         });
       
   741                 } catch (Exception e) {
       
   742                     // Ooops, let's notify the ProxySelector
       
   743                     sel.connectFailed(uri,p.address(),new SocketException(e.getMessage()));
       
   744                     server = null;
       
   745                     serverPort = -1;
       
   746                     cmdsock = null;
       
   747                     savedExc = e;
       
   748                     // Will continue the while loop and try the next proxy
       
   749                 }
       
   750             }
       
   751 
       
   752             /*
       
   753              * If server is still null at this point, none of the proxy
       
   754              * worked
       
   755              */
       
   756             if (server == null || cmdsock == null) {
       
   757                 throw new SocketException("Can't connect to SOCKS proxy:"
       
   758                                           + savedExc.getMessage());
       
   759             }
       
   760         } else {
       
   761             try {
       
   762                 AccessController.doPrivileged(
       
   763                     new PrivilegedExceptionAction<>() {
       
   764                         public Void run() throws Exception {
       
   765                             cmdsock = new Socket(new NioSocketImpl(false));
       
   766                             cmdsock.connect(new InetSocketAddress(server, serverPort));
       
   767                             cmdIn = cmdsock.getInputStream();
       
   768                             cmdOut = cmdsock.getOutputStream();
       
   769                             return null;
       
   770                         }
       
   771                     });
       
   772             } catch (Exception e) {
       
   773                 throw new SocketException(e.getMessage());
       
   774             }
       
   775         }
       
   776         BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512);
       
   777         InputStream in = cmdIn;
       
   778         if (useV4) {
       
   779             bindV4(in, out, saddr.getAddress(), saddr.getPort());
       
   780             return;
       
   781         }
       
   782         out.write(PROTO_VERS);
       
   783         out.write(2);
       
   784         out.write(NO_AUTH);
       
   785         out.write(USER_PASSW);
       
   786         out.flush();
       
   787         byte[] data = new byte[2];
       
   788         int i = readSocksReply(in, data);
       
   789         if (i != 2 || ((int)data[0]) != PROTO_VERS) {
       
   790             // Maybe it's not a V5 sever after all
       
   791             // Let's try V4 before we give up
       
   792             bindV4(in, out, saddr.getAddress(), saddr.getPort());
       
   793             return;
       
   794         }
       
   795         if (((int)data[1]) == NO_METHODS)
       
   796             throw new SocketException("SOCKS : No acceptable methods");
       
   797         if (!authenticate(data[1], in, out)) {
       
   798             throw new SocketException("SOCKS : authentication failed");
       
   799         }
       
   800         // We're OK. Let's issue the BIND command.
       
   801         out.write(PROTO_VERS);
       
   802         out.write(BIND);
       
   803         out.write(0);
       
   804         int lport = saddr.getPort();
       
   805         if (saddr.isUnresolved()) {
       
   806             out.write(DOMAIN_NAME);
       
   807             out.write(saddr.getHostName().length());
       
   808             try {
       
   809                 out.write(saddr.getHostName().getBytes("ISO-8859-1"));
       
   810             } catch (java.io.UnsupportedEncodingException uee) {
       
   811                 assert false;
       
   812             }
       
   813             out.write((lport >> 8) & 0xff);
       
   814             out.write((lport >> 0) & 0xff);
       
   815         } else if (saddr.getAddress() instanceof Inet4Address) {
       
   816             byte[] addr1 = saddr.getAddress().getAddress();
       
   817             out.write(IPV4);
       
   818             out.write(addr1);
       
   819             out.write((lport >> 8) & 0xff);
       
   820             out.write((lport >> 0) & 0xff);
       
   821             out.flush();
       
   822         } else if (saddr.getAddress() instanceof Inet6Address) {
       
   823             byte[] addr1 = saddr.getAddress().getAddress();
       
   824             out.write(IPV6);
       
   825             out.write(addr1);
       
   826             out.write((lport >> 8) & 0xff);
       
   827             out.write((lport >> 0) & 0xff);
       
   828             out.flush();
       
   829         } else {
       
   830             cmdsock.close();
       
   831             throw new SocketException("unsupported address type : " + saddr);
       
   832         }
       
   833         data = new byte[4];
       
   834         i = readSocksReply(in, data);
       
   835         SocketException ex = null;
       
   836         int len, nport;
       
   837         byte[] addr;
       
   838         switch (data[1]) {
       
   839         case REQUEST_OK:
       
   840             // success!
       
   841             switch(data[3]) {
       
   842             case IPV4:
       
   843                 addr = new byte[4];
       
   844                 i = readSocksReply(in, addr);
       
   845                 if (i != 4)
       
   846                     throw new SocketException("Reply from SOCKS server badly formatted");
       
   847                 data = new byte[2];
       
   848                 i = readSocksReply(in, data);
       
   849                 if (i != 2)
       
   850                     throw new SocketException("Reply from SOCKS server badly formatted");
       
   851                 nport = ((int)data[0] & 0xff) << 8;
       
   852                 nport += ((int)data[1] & 0xff);
       
   853                 external_address =
       
   854                     new InetSocketAddress(new Inet4Address("", addr) , nport);
       
   855                 break;
       
   856             case DOMAIN_NAME:
       
   857                 len = data[1];
       
   858                 byte[] host = new byte[len];
       
   859                 i = readSocksReply(in, host);
       
   860                 if (i != len)
       
   861                     throw new SocketException("Reply from SOCKS server badly formatted");
       
   862                 data = new byte[2];
       
   863                 i = readSocksReply(in, data);
       
   864                 if (i != 2)
       
   865                     throw new SocketException("Reply from SOCKS server badly formatted");
       
   866                 nport = ((int)data[0] & 0xff) << 8;
       
   867                 nport += ((int)data[1] & 0xff);
       
   868                 external_address = new InetSocketAddress(new String(host), nport);
       
   869                 break;
       
   870             case IPV6:
       
   871                 len = data[1];
       
   872                 addr = new byte[len];
       
   873                 i = readSocksReply(in, addr);
       
   874                 if (i != len)
       
   875                     throw new SocketException("Reply from SOCKS server badly formatted");
       
   876                 data = new byte[2];
       
   877                 i = readSocksReply(in, data);
       
   878                 if (i != 2)
       
   879                     throw new SocketException("Reply from SOCKS server badly formatted");
       
   880                 nport = ((int)data[0] & 0xff) << 8;
       
   881                 nport += ((int)data[1] & 0xff);
       
   882                 external_address =
       
   883                     new InetSocketAddress(new Inet6Address("", addr), nport);
       
   884                 break;
       
   885             }
       
   886             break;
       
   887         case GENERAL_FAILURE:
       
   888             ex = new SocketException("SOCKS server general failure");
       
   889             break;
       
   890         case NOT_ALLOWED:
       
   891             ex = new SocketException("SOCKS: Bind not allowed by ruleset");
       
   892             break;
       
   893         case NET_UNREACHABLE:
       
   894             ex = new SocketException("SOCKS: Network unreachable");
       
   895             break;
       
   896         case HOST_UNREACHABLE:
       
   897             ex = new SocketException("SOCKS: Host unreachable");
       
   898             break;
       
   899         case CONN_REFUSED:
       
   900             ex = new SocketException("SOCKS: Connection refused");
       
   901             break;
       
   902         case TTL_EXPIRED:
       
   903             ex =  new SocketException("SOCKS: TTL expired");
       
   904             break;
       
   905         case CMD_NOT_SUPPORTED:
       
   906             ex = new SocketException("SOCKS: Command not supported");
       
   907             break;
       
   908         case ADDR_TYPE_NOT_SUP:
       
   909             ex = new SocketException("SOCKS: address type not supported");
       
   910             break;
       
   911         }
       
   912         if (ex != null) {
       
   913             in.close();
       
   914             out.close();
       
   915             cmdsock.close();
       
   916             cmdsock = null;
       
   917             throw ex;
       
   918         }
       
   919         cmdIn = in;
       
   920         cmdOut = out;
       
   921     }
       
   922 
       
   923     /**
       
   924      * Accepts a connection from a specific host.
       
   925      *
       
   926      * @param      s   the accepted connection.
       
   927      * @param      saddr the socket address of the host we do accept
       
   928      *               connection from
       
   929      * @exception  IOException  if an I/O error occurs when accepting the
       
   930      *               connection.
       
   931      */
       
   932     protected void acceptFrom(SocketImpl s, InetSocketAddress saddr) throws IOException {
       
   933         if (cmdsock == null) {
       
   934             // Not a Socks ServerSocket.
       
   935             return;
       
   936         }
       
   937         InputStream in = cmdIn;
       
   938         // Sends the "SOCKS BIND" request.
       
   939         socksBind(saddr);
       
   940         in.read();
       
   941         int i = in.read();
       
   942         in.read();
       
   943         SocketException ex = null;
       
   944         int nport;
       
   945         byte[] addr;
       
   946         InetSocketAddress real_end = null;
       
   947         switch (i) {
       
   948         case REQUEST_OK:
       
   949             // success!
       
   950             i = in.read();
       
   951             switch(i) {
       
   952             case IPV4:
       
   953                 addr = new byte[4];
       
   954                 readSocksReply(in, addr);
       
   955                 nport = in.read() << 8;
       
   956                 nport += in.read();
       
   957                 real_end =
       
   958                     new InetSocketAddress(new Inet4Address("", addr) , nport);
       
   959                 break;
       
   960             case DOMAIN_NAME:
       
   961                 int len = in.read();
       
   962                 addr = new byte[len];
       
   963                 readSocksReply(in, addr);
       
   964                 nport = in.read() << 8;
       
   965                 nport += in.read();
       
   966                 real_end = new InetSocketAddress(new String(addr), nport);
       
   967                 break;
       
   968             case IPV6:
       
   969                 addr = new byte[16];
       
   970                 readSocksReply(in, addr);
       
   971                 nport = in.read() << 8;
       
   972                 nport += in.read();
       
   973                 real_end =
       
   974                     new InetSocketAddress(new Inet6Address("", addr), nport);
       
   975                 break;
       
   976             }
       
   977             break;
       
   978         case GENERAL_FAILURE:
       
   979             ex = new SocketException("SOCKS server general failure");
       
   980             break;
       
   981         case NOT_ALLOWED:
       
   982             ex = new SocketException("SOCKS: Accept not allowed by ruleset");
       
   983             break;
       
   984         case NET_UNREACHABLE:
       
   985             ex = new SocketException("SOCKS: Network unreachable");
       
   986             break;
       
   987         case HOST_UNREACHABLE:
       
   988             ex = new SocketException("SOCKS: Host unreachable");
       
   989             break;
       
   990         case CONN_REFUSED:
       
   991             ex = new SocketException("SOCKS: Connection refused");
       
   992             break;
       
   993         case TTL_EXPIRED:
       
   994             ex =  new SocketException("SOCKS: TTL expired");
       
   995             break;
       
   996         case CMD_NOT_SUPPORTED:
       
   997             ex = new SocketException("SOCKS: Command not supported");
       
   998             break;
       
   999         case ADDR_TYPE_NOT_SUP:
       
  1000             ex = new SocketException("SOCKS: address type not supported");
       
  1001             break;
       
  1002         }
       
  1003         if (ex != null) {
       
  1004             cmdIn.close();
       
  1005             cmdOut.close();
       
  1006             cmdsock.close();
       
  1007             cmdsock = null;
       
  1008             throw ex;
       
  1009         }
       
  1010 
       
  1011         /**
       
  1012          * This is where we have to do some fancy stuff.
       
  1013          * The datastream from the socket "accepted" by the proxy will
       
  1014          * come through the cmdSocket. So we have to swap the socketImpls
       
  1015          */
       
  1016         if (s instanceof SocksSocketImpl) {
       
  1017             ((SocksSocketImpl)s).external_address = real_end;
       
  1018         }
       
  1019         if (s instanceof PlainSocketImpl) {
       
  1020             PlainSocketImpl psi = (PlainSocketImpl) s;
       
  1021             psi.setInputStream((SocketInputStream) in);
       
  1022             psi.setFileDescriptor(cmdsock.getImpl().getFileDescriptor());
       
  1023             psi.setAddress(cmdsock.getImpl().getInetAddress());
       
  1024             psi.setPort(cmdsock.getImpl().getPort());
       
  1025             psi.setLocalPort(cmdsock.getImpl().getLocalPort());
       
  1026         } else {
       
  1027             s.fd = cmdsock.getImpl().fd;
       
  1028             s.address = cmdsock.getImpl().address;
       
  1029             s.port = cmdsock.getImpl().port;
       
  1030             s.localport = cmdsock.getImpl().localport;
       
  1031         }
       
  1032 
       
  1033         // Need to do that so that the socket won't be closed
       
  1034         // when the ServerSocket is closed by the user.
       
  1035         // It kinds of detaches the Socket because it is now
       
  1036         // used elsewhere.
       
  1037         cmdsock = null;
       
  1038     }
       
  1039 
   521 
  1040 
   522 
  1041     /**
   523     /**
  1042      * Returns the value of this socket's {@code address} field.
   524      * Returns the value of this socket's {@code address} field.
  1043      *
   525      *
  1073         cmdsock = null;
   555         cmdsock = null;
  1074         super.close();
   556         super.close();
  1075     }
   557     }
  1076 
   558 
  1077     private String getUserName() {
   559     private String getUserName() {
  1078         String userName = "";
   560         return StaticProperty.userName();
  1079         if (applicationSetProxy) {
       
  1080             try {
       
  1081                 userName = System.getProperty("user.name");
       
  1082             } catch (SecurityException se) { /* swallow Exception */ }
       
  1083         } else {
       
  1084             userName = StaticProperty.userName();
       
  1085         }
       
  1086         return userName;
       
  1087     }
   561     }
  1088 }
   562 }