📄 socks5socketfactory.java
字号:
package lib.commons.net;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import lib.commons.Utils;
import lib.commons.config.DomConfig;
public class Socks5SocketFactory extends SocketFactory {
static final class SocksAddress {
public byte addressType;
public byte[] address;
public byte[] port = new byte[2];
}
private String _address, _userName, _password;
private int _port;
public Socks5SocketFactory() {
}
public Socks5SocketFactory(String address, int port, String userName,
String password) {
_address = address;
_port = port;
_userName = userName;
_password = password;
}
public String getAddress() {
return _address;
}
public int getPort() {
return _port;
}
public String getUserName() {
return _userName;
}
public String getPassword() {
return _password;
}
public Socket createSocket(String arg0, int arg1, InetAddress arg2,
int arg3, HttpConnectionParams arg4) throws IOException,
UnknownHostException, ConnectTimeoutException {
Socket socket = super.createSocket(_address, _port, arg2, arg3, arg4);
boolean needAuthentication = connectSocksServer(socket, arg4);
if (needAuthentication
&& !authenticationSocksServer(socket, this.getUserName(), this
.getPassword(), arg4)) {
if (!socket.isClosed())
socket.close();
throw new IOException("Socks5 server authentication failed");
}
if (!connectRemoteTcpViaSocks(socket, arg0, arg1, arg4)) {
if (!socket.isClosed())
socket.close();
throw new IOException("Socks5 server connect endpoint failed");
}
return socket;
}
private final static boolean connectSocksServer(Socket socket,
HttpConnectionParams params) throws IOException {
boolean needAuthentication = false;
byte[] data = new byte[] { 5, 2, 0, 2 };
socket.getOutputStream().write(data);
socket.getOutputStream().flush();
byte[] respData = new byte[2];
int readCount = 0, pos = 0;
//SocketFactory.setSocketParams(socket, params);
do {
readCount = socket.getInputStream().read(respData, pos,
respData.length - pos);
pos += readCount;
} while (pos < respData.length);
if (respData[0] == 5 && Utils.byteToUint(respData[1]) == 2)
needAuthentication = true;
else if (respData[0] != 5 || Utils.byteToUint(respData[1]) == 255)
throw new IOException("Socks5 server not supprt this connect");
return needAuthentication;
}
public final static boolean authenticationSocksServer(Socket socket,
String userName, String password, HttpConnectionParams params)
throws IOException {
boolean bsucc = false;
byte[] usernameBytes = (null == userName ? new byte[0] : userName
.getBytes());
byte[] passwordBytes = (null == password ? new byte[0] : password
.getBytes());
byte[] data = new byte[3 + usernameBytes.length + passwordBytes.length];
data[0] = 1;
data[1] = (byte) (usernameBytes.length > 255 ? 255
: usernameBytes.length);
for (int i = 2; i < data[1] + 2; i++) {
data[i] = usernameBytes[i - 2];
}
data[data[1] + 2] = (byte) (passwordBytes.length > 255 ? 255
: passwordBytes.length);
for (int i = data[1] + 3; i < data[data[1] + 2] + data[1] + 3; i++) {
data[i] = passwordBytes[i - data[1] - 3];
}
socket.getOutputStream().write(data);
byte[] respData = new byte[2];
int readCount = 0, pos = 0;
//SocketFactory.setSocketParams(socket, params);
do {
readCount = socket.getInputStream().read(respData, pos,
respData.length - pos);
pos += readCount;
} while (pos < respData.length);
if (respData[0] == 1 && respData[1] == 0)
bsucc = true;
return bsucc;
}
public final static boolean connectRemoteTcpViaSocks(Socket socket,
String address, int port, HttpConnectionParams params)
throws IOException {
boolean bsucc = false;
SocksAddress socksAddress = getAddress(address, port);
byte[] data = new byte[4 + socksAddress.address.length + 2];
data[0] = 5;
data[1] = 1;
data[2] = 0;
data[3] = socksAddress.addressType;
for (int i = 4; i < socksAddress.address.length + 4; i++) {
data[i] = socksAddress.address[i - 4];
}
data[4 + socksAddress.address.length] = socksAddress.port[0];
data[4 + socksAddress.address.length + 1] = socksAddress.port[1];
socket.getOutputStream().write(data);
socket.getOutputStream().flush();
byte[] respHeadData = new byte[4];
int readCount = 0, pos = 0;
//SocketFactory.setSocketParams(socket, params);
do {
readCount = socket.getInputStream().read(respHeadData, pos,
respHeadData.length - pos);
pos += readCount;
} while (pos < respHeadData.length);
switch (respHeadData[1]) {
case 0:
bsucc = true;
break;
case 1:
throw new IOException(
"Socks5 connect remote:general SOCKS server failure");
case 2:
throw new IOException(
"Socks5 connect remote:connection is not allowed");
case 3:
throw new IOException(
"Socks5 connect remote:remote network is unreachable");
case 4:
throw new IOException(
"Socks5 connect remote:remote host is unreachable");
case 5:
throw new IOException("Socks5 connect remote:connection is refused");
case 6:
throw new IOException("Socks5 connect remote:TTL expired");
case 7:
throw new IOException(
"Socks5 connect remote:command is not supportted");
case 8:
throw new IOException(
"Socks5 connect remote:address format is not supportted");
default:
bsucc = false;
break;
}
if (!bsucc)
return bsucc;
byte[] respAddressBytes = null;
if (respHeadData[3] == 1) {
respAddressBytes = new byte[4];
readCount = 0;
pos = 0;
//SocketFactory.setSocketParams(socket, params);
do {
readCount = socket.getInputStream().read(respAddressBytes, pos,
respAddressBytes.length - pos);
pos += readCount;
} while (pos < respAddressBytes.length);
} else {
readCount = 0;
byte[] respAddressBytesLen = new byte[1];
//SocketFactory.setSocketParams(socket, params);
do {
readCount = socket.getInputStream().read(respAddressBytesLen);
} while (readCount > 0);
respAddressBytes = new byte[respAddressBytesLen[0]];
if (respAddressBytes.length > 0) {
readCount = 0;
pos = 0;
//SocketFactory.setSocketParams(socket, params);
do {
readCount = socket.getInputStream().read(respAddressBytes,
pos, respAddressBytes.length - pos);
pos += readCount;
} while (pos < respAddressBytes.length);
}
}
byte[] respPortBytes = new byte[2];
readCount = 0;
pos = 0;
//SocketFactory.setSocketParams(socket, params);
do {
readCount = socket.getInputStream().read(respPortBytes, pos,
respPortBytes.length - pos);
pos += readCount;
} while (pos < respPortBytes.length);
// int respPort =
// Utils.bytesToInt(respPortBytes,java.nio.ByteOrder.BIG_ENDIAN);
return bsucc;
}
public final static SocksAddress getAddress(String address, int port) {
if (port < 1 || port > 65535)
throw new IllegalArgumentException("Port-" + port + " is not valid");
SocksAddress socksAddress = new SocksAddress();
if (Utils.isIPv4Address(address)) {
socksAddress.addressType = 1;
java.net.InetSocketAddress socketAddress = new java.net.InetSocketAddress(
address, port);
socksAddress.address = socketAddress.getAddress().getAddress();
} else {
socksAddress.addressType = 3;
if (Utils.StringIsNullOrEmpty(address)) {
socksAddress.address = new byte[1];
socksAddress.address[0] = 0;
} else {
byte[] addressBytes = address.getBytes();
socksAddress.address = new byte[1 + addressBytes.length];
socksAddress.address[0] = (byte) (addressBytes.length > 255 ? 255
: addressBytes.length);
for (int i = 1; i < socksAddress.address[0] + 1; i++) {
socksAddress.address[i] = addressBytes[i - 1];
}
}
}
byte[] bytes = Utils.intToBytes(port, java.nio.ByteOrder.BIG_ENDIAN);
socksAddress.port[0] = bytes[2];
socksAddress.port[1] = bytes[3];
return socksAddress;
}
public SocketFactory createInstance(DomConfig domConfig) throws Exception {
Socks5SocketFactory sockFact = null;
String domainString = null;
if (null != domConfig)
domainString = domConfig.selectValue("domain");
AuthDomain domain = AuthDomain.parseAuthDomain(domainString);
sockFact = new Socks5SocketFactory(domain.getDomain().getAddress(),
domain.getDomain().getPort(), domain.getUserAuthInfo()
.getName(), domain.getUserAuthInfo().getPassword());
return sockFact;
}
public static void main(String[] args) {
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -