Search in sources :

Example 1 with SocksProxy

use of sun.net.SocksProxy in project jdk8u_jdk by JetBrains.

the class SocksSocketImpl method socksBind.

/**
     * Sends the Bind request to the SOCKS proxy. In the SOCKS protocol, bind
     * means "accept incoming connection from", so the SocketAddress is the
     * the one of the host we do accept connection from.
     *
     * @param      saddr   the Socket address of the remote host.
     * @exception  IOException  if an I/O error occurs when binding this socket.
     */
protected synchronized void socksBind(InetSocketAddress saddr) throws IOException {
    if (socket != null) {
        // call the SOCKS proxy for a bind!
        return;
    }
    if (server == null) {
        // This is the general case
        // server is not null only when the socket was created with a
        // specified proxy in which case it does bypass the ProxySelector
        ProxySelector sel = java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<ProxySelector>() {

            public ProxySelector run() {
                return ProxySelector.getDefault();
            }
        });
        if (sel == null) {
            /*
                 * No default proxySelector --> direct connection
                 */
            return;
        }
        URI uri;
        // Use getHostString() to avoid reverse lookups
        String host = saddr.getHostString();
        // IPv6 litteral?
        if (saddr.getAddress() instanceof Inet6Address && (!host.startsWith("[")) && (host.indexOf(":") >= 0)) {
            host = "[" + host + "]";
        }
        try {
            uri = new URI("serversocket://" + ParseUtil.encodePath(host) + ":" + saddr.getPort());
        } catch (URISyntaxException e) {
            // This shouldn't happen
            assert false : e;
            uri = null;
        }
        Proxy p = null;
        Exception savedExc = null;
        java.util.Iterator<Proxy> iProxy = null;
        iProxy = sel.select(uri).iterator();
        if (iProxy == null || !(iProxy.hasNext())) {
            return;
        }
        while (iProxy.hasNext()) {
            p = iProxy.next();
            if (p == null || p.type() != Proxy.Type.SOCKS) {
                return;
            }
            if (!(p.address() instanceof InetSocketAddress))
                throw new SocketException("Unknown address type for proxy: " + p);
            // Use getHostString() to avoid reverse lookups
            server = ((InetSocketAddress) p.address()).getHostString();
            serverPort = ((InetSocketAddress) p.address()).getPort();
            if (p instanceof SocksProxy) {
                if (((SocksProxy) p).protocolVersion() == 4) {
                    useV4 = true;
                }
            }
            // Connects to the SOCKS server
            try {
                AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {

                    public Void run() throws Exception {
                        cmdsock = new Socket(new PlainSocketImpl());
                        cmdsock.connect(new InetSocketAddress(server, serverPort));
                        cmdIn = cmdsock.getInputStream();
                        cmdOut = cmdsock.getOutputStream();
                        return null;
                    }
                });
            } catch (Exception e) {
                // Ooops, let's notify the ProxySelector
                sel.connectFailed(uri, p.address(), new SocketException(e.getMessage()));
                server = null;
                serverPort = -1;
                cmdsock = null;
                savedExc = e;
            // Will continue the while loop and try the next proxy
            }
        }
        /*
             * If server is still null at this point, none of the proxy
             * worked
             */
        if (server == null || cmdsock == null) {
            throw new SocketException("Can't connect to SOCKS proxy:" + savedExc.getMessage());
        }
    } else {
        try {
            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {

                public Void run() throws Exception {
                    cmdsock = new Socket(new PlainSocketImpl());
                    cmdsock.connect(new InetSocketAddress(server, serverPort));
                    cmdIn = cmdsock.getInputStream();
                    cmdOut = cmdsock.getOutputStream();
                    return null;
                }
            });
        } catch (Exception e) {
            throw new SocketException(e.getMessage());
        }
    }
    BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512);
    InputStream in = cmdIn;
    if (useV4) {
        bindV4(in, out, saddr.getAddress(), saddr.getPort());
        return;
    }
    out.write(PROTO_VERS);
    out.write(2);
    out.write(NO_AUTH);
    out.write(USER_PASSW);
    out.flush();
    byte[] data = new byte[2];
    int i = readSocksReply(in, data);
    if (i != 2 || ((int) data[0]) != PROTO_VERS) {
        // Maybe it's not a V5 sever after all
        // Let's try V4 before we give up
        bindV4(in, out, saddr.getAddress(), saddr.getPort());
        return;
    }
    if (((int) data[1]) == NO_METHODS)
        throw new SocketException("SOCKS : No acceptable methods");
    if (!authenticate(data[1], in, out)) {
        throw new SocketException("SOCKS : authentication failed");
    }
    // We're OK. Let's issue the BIND command.
    out.write(PROTO_VERS);
    out.write(BIND);
    out.write(0);
    int lport = saddr.getPort();
    if (saddr.isUnresolved()) {
        out.write(DOMAIN_NAME);
        out.write(saddr.getHostName().length());
        try {
            out.write(saddr.getHostName().getBytes("ISO-8859-1"));
        } catch (java.io.UnsupportedEncodingException uee) {
            assert false;
        }
        out.write((lport >> 8) & 0xff);
        out.write((lport >> 0) & 0xff);
    } else if (saddr.getAddress() instanceof Inet4Address) {
        byte[] addr1 = saddr.getAddress().getAddress();
        out.write(IPV4);
        out.write(addr1);
        out.write((lport >> 8) & 0xff);
        out.write((lport >> 0) & 0xff);
        out.flush();
    } else if (saddr.getAddress() instanceof Inet6Address) {
        byte[] addr1 = saddr.getAddress().getAddress();
        out.write(IPV6);
        out.write(addr1);
        out.write((lport >> 8) & 0xff);
        out.write((lport >> 0) & 0xff);
        out.flush();
    } else {
        cmdsock.close();
        throw new SocketException("unsupported address type : " + saddr);
    }
    data = new byte[4];
    i = readSocksReply(in, data);
    SocketException ex = null;
    int len, nport;
    byte[] addr;
    switch(data[1]) {
        case REQUEST_OK:
            // success!
            switch(data[3]) {
                case IPV4:
                    addr = new byte[4];
                    i = readSocksReply(in, addr);
                    if (i != 4)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    data = new byte[2];
                    i = readSocksReply(in, data);
                    if (i != 2)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    nport = ((int) data[0] & 0xff) << 8;
                    nport += ((int) data[1] & 0xff);
                    external_address = new InetSocketAddress(new Inet4Address("", addr), nport);
                    break;
                case DOMAIN_NAME:
                    len = data[1];
                    byte[] host = new byte[len];
                    i = readSocksReply(in, host);
                    if (i != len)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    data = new byte[2];
                    i = readSocksReply(in, data);
                    if (i != 2)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    nport = ((int) data[0] & 0xff) << 8;
                    nport += ((int) data[1] & 0xff);
                    external_address = new InetSocketAddress(new String(host), nport);
                    break;
                case IPV6:
                    len = data[1];
                    addr = new byte[len];
                    i = readSocksReply(in, addr);
                    if (i != len)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    data = new byte[2];
                    i = readSocksReply(in, data);
                    if (i != 2)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    nport = ((int) data[0] & 0xff) << 8;
                    nport += ((int) data[1] & 0xff);
                    external_address = new InetSocketAddress(new Inet6Address("", addr), nport);
                    break;
            }
            break;
        case GENERAL_FAILURE:
            ex = new SocketException("SOCKS server general failure");
            break;
        case NOT_ALLOWED:
            ex = new SocketException("SOCKS: Bind not allowed by ruleset");
            break;
        case NET_UNREACHABLE:
            ex = new SocketException("SOCKS: Network unreachable");
            break;
        case HOST_UNREACHABLE:
            ex = new SocketException("SOCKS: Host unreachable");
            break;
        case CONN_REFUSED:
            ex = new SocketException("SOCKS: Connection refused");
            break;
        case TTL_EXPIRED:
            ex = new SocketException("SOCKS: TTL expired");
            break;
        case CMD_NOT_SUPPORTED:
            ex = new SocketException("SOCKS: Command not supported");
            break;
        case ADDR_TYPE_NOT_SUP:
            ex = new SocketException("SOCKS: address type not supported");
            break;
    }
    if (ex != null) {
        in.close();
        out.close();
        cmdsock.close();
        cmdsock = null;
        throw ex;
    }
    cmdIn = in;
    cmdOut = out;
}
Also used : SocksProxy(sun.net.SocksProxy) BufferedOutputStream(java.io.BufferedOutputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) SocksProxy(sun.net.SocksProxy)

Example 2 with SocksProxy

use of sun.net.SocksProxy in project jdk8u_jdk by JetBrains.

the class SocksSocketImpl method connect.

/**
     * Connects the Socks Socket to the specified endpoint. It will first
     * connect to the SOCKS proxy and negotiate the access. If the proxy
     * grants the connections, then the connect is successful and all
     * further traffic will go to the "real" endpoint.
     *
     * @param   endpoint        the {@code SocketAddress} to connect to.
     * @param   timeout         the timeout value in milliseconds
     * @throws  IOException     if the connection can't be established.
     * @throws  SecurityException if there is a security manager and it
     *                          doesn't allow the connection
     * @throws  IllegalArgumentException if endpoint is null or a
     *          SocketAddress subclass not supported by this socket
     */
@Override
protected void connect(SocketAddress endpoint, int timeout) throws IOException {
    final long deadlineMillis;
    if (timeout == 0) {
        deadlineMillis = 0L;
    } else {
        long finish = System.currentTimeMillis() + timeout;
        deadlineMillis = finish < 0 ? Long.MAX_VALUE : finish;
    }
    SecurityManager security = System.getSecurityManager();
    if (endpoint == null || !(endpoint instanceof InetSocketAddress))
        throw new IllegalArgumentException("Unsupported address type");
    InetSocketAddress epoint = (InetSocketAddress) endpoint;
    if (security != null) {
        if (epoint.isUnresolved())
            security.checkConnect(epoint.getHostName(), epoint.getPort());
        else
            security.checkConnect(epoint.getAddress().getHostAddress(), epoint.getPort());
    }
    if (server == null) {
        // This is the general case
        // server is not null only when the socket was created with a
        // specified proxy in which case it does bypass the ProxySelector
        ProxySelector sel = java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<ProxySelector>() {

            public ProxySelector run() {
                return ProxySelector.getDefault();
            }
        });
        if (sel == null) {
            /*
                 * No default proxySelector --> direct connection
                 */
            super.connect(epoint, remainingMillis(deadlineMillis));
            return;
        }
        URI uri;
        // Use getHostString() to avoid reverse lookups
        String host = epoint.getHostString();
        // IPv6 litteral?
        if (epoint.getAddress() instanceof Inet6Address && (!host.startsWith("[")) && (host.indexOf(":") >= 0)) {
            host = "[" + host + "]";
        }
        try {
            uri = new URI("socket://" + ParseUtil.encodePath(host) + ":" + epoint.getPort());
        } catch (URISyntaxException e) {
            // This shouldn't happen
            assert false : e;
            uri = null;
        }
        Proxy p = null;
        IOException savedExc = null;
        java.util.Iterator<Proxy> iProxy = null;
        iProxy = sel.select(uri).iterator();
        if (iProxy == null || !(iProxy.hasNext())) {
            super.connect(epoint, remainingMillis(deadlineMillis));
            return;
        }
        while (iProxy.hasNext()) {
            p = iProxy.next();
            if (p == null || p.type() != Proxy.Type.SOCKS) {
                super.connect(epoint, remainingMillis(deadlineMillis));
                return;
            }
            if (!(p.address() instanceof InetSocketAddress))
                throw new SocketException("Unknown address type for proxy: " + p);
            // Use getHostString() to avoid reverse lookups
            server = ((InetSocketAddress) p.address()).getHostString();
            serverPort = ((InetSocketAddress) p.address()).getPort();
            if (p instanceof SocksProxy) {
                if (((SocksProxy) p).protocolVersion() == 4) {
                    useV4 = true;
                }
            }
            // Connects to the SOCKS server
            try {
                privilegedConnect(server, serverPort, remainingMillis(deadlineMillis));
                // Worked, let's get outta here
                break;
            } catch (IOException e) {
                // Ooops, let's notify the ProxySelector
                sel.connectFailed(uri, p.address(), e);
                server = null;
                serverPort = -1;
                savedExc = e;
            // Will continue the while loop and try the next proxy
            }
        }
        /*
             * If server is still null at this point, none of the proxy
             * worked
             */
        if (server == null) {
            throw new SocketException("Can't connect to SOCKS proxy:" + savedExc.getMessage());
        }
    } else {
        // Connects to the SOCKS server
        try {
            privilegedConnect(server, serverPort, remainingMillis(deadlineMillis));
        } catch (IOException e) {
            throw new SocketException(e.getMessage());
        }
    }
    // cmdIn & cmdOut were initialized during the privilegedConnect() call
    BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512);
    InputStream in = cmdIn;
    if (useV4) {
        // DOMAIN type of addresses (unresolved addresses here)
        if (epoint.isUnresolved())
            throw new UnknownHostException(epoint.toString());
        connectV4(in, out, epoint, deadlineMillis);
        return;
    }
    // This is SOCKS V5
    out.write(PROTO_VERS);
    out.write(2);
    out.write(NO_AUTH);
    out.write(USER_PASSW);
    out.flush();
    byte[] data = new byte[2];
    int i = readSocksReply(in, data, deadlineMillis);
    if (i != 2 || ((int) data[0]) != PROTO_VERS) {
        // DOMAIN type of addresses (unresolved addresses here)
        if (epoint.isUnresolved())
            throw new UnknownHostException(epoint.toString());
        connectV4(in, out, epoint, deadlineMillis);
        return;
    }
    if (((int) data[1]) == NO_METHODS)
        throw new SocketException("SOCKS : No acceptable methods");
    if (!authenticate(data[1], in, out, deadlineMillis)) {
        throw new SocketException("SOCKS : authentication failed");
    }
    out.write(PROTO_VERS);
    out.write(CONNECT);
    out.write(0);
    /* Test for IPV4/IPV6/Unresolved */
    if (epoint.isUnresolved()) {
        out.write(DOMAIN_NAME);
        out.write(epoint.getHostName().length());
        try {
            out.write(epoint.getHostName().getBytes("ISO-8859-1"));
        } catch (java.io.UnsupportedEncodingException uee) {
            assert false;
        }
        out.write((epoint.getPort() >> 8) & 0xff);
        out.write((epoint.getPort() >> 0) & 0xff);
    } else if (epoint.getAddress() instanceof Inet6Address) {
        out.write(IPV6);
        out.write(epoint.getAddress().getAddress());
        out.write((epoint.getPort() >> 8) & 0xff);
        out.write((epoint.getPort() >> 0) & 0xff);
    } else {
        out.write(IPV4);
        out.write(epoint.getAddress().getAddress());
        out.write((epoint.getPort() >> 8) & 0xff);
        out.write((epoint.getPort() >> 0) & 0xff);
    }
    out.flush();
    data = new byte[4];
    i = readSocksReply(in, data, deadlineMillis);
    if (i != 4)
        throw new SocketException("Reply from SOCKS server has bad length");
    SocketException ex = null;
    int len;
    byte[] addr;
    switch(data[1]) {
        case REQUEST_OK:
            // success!
            switch(data[3]) {
                case IPV4:
                    addr = new byte[4];
                    i = readSocksReply(in, addr, deadlineMillis);
                    if (i != 4)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    data = new byte[2];
                    i = readSocksReply(in, data, deadlineMillis);
                    if (i != 2)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    break;
                case DOMAIN_NAME:
                    len = data[1];
                    byte[] host = new byte[len];
                    i = readSocksReply(in, host, deadlineMillis);
                    if (i != len)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    data = new byte[2];
                    i = readSocksReply(in, data, deadlineMillis);
                    if (i != 2)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    break;
                case IPV6:
                    len = data[1];
                    addr = new byte[len];
                    i = readSocksReply(in, addr, deadlineMillis);
                    if (i != len)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    data = new byte[2];
                    i = readSocksReply(in, data, deadlineMillis);
                    if (i != 2)
                        throw new SocketException("Reply from SOCKS server badly formatted");
                    break;
                default:
                    ex = new SocketException("Reply from SOCKS server contains wrong code");
                    break;
            }
            break;
        case GENERAL_FAILURE:
            ex = new SocketException("SOCKS server general failure");
            break;
        case NOT_ALLOWED:
            ex = new SocketException("SOCKS: Connection not allowed by ruleset");
            break;
        case NET_UNREACHABLE:
            ex = new SocketException("SOCKS: Network unreachable");
            break;
        case HOST_UNREACHABLE:
            ex = new SocketException("SOCKS: Host unreachable");
            break;
        case CONN_REFUSED:
            ex = new SocketException("SOCKS: Connection refused");
            break;
        case TTL_EXPIRED:
            ex = new SocketException("SOCKS: TTL expired");
            break;
        case CMD_NOT_SUPPORTED:
            ex = new SocketException("SOCKS: Command not supported");
            break;
        case ADDR_TYPE_NOT_SUP:
            ex = new SocketException("SOCKS: address type not supported");
            break;
    }
    if (ex != null) {
        in.close();
        out.close();
        throw ex;
    }
    external_address = epoint;
}
Also used : InputStream(java.io.InputStream) IOException(java.io.IOException) SocksProxy(sun.net.SocksProxy) SocksProxy(sun.net.SocksProxy) BufferedOutputStream(java.io.BufferedOutputStream)

Aggregations

BufferedOutputStream (java.io.BufferedOutputStream)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 SocksProxy (sun.net.SocksProxy)2