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;
}
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;
}
Aggregations