mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 04:22:05 +01:00
Patch double committed for some reason. Also cleaned up a couple of pointless warnings.
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@10674 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
4c4cc77e42
commit
7f77fda9db
8 changed files with 5 additions and 913 deletions
|
@ -26,7 +26,7 @@ import java.util.*;
|
||||||
* and {@link org.jivesoftware.smack.provider.PrivacyProvider} to allow and block
|
* and {@link org.jivesoftware.smack.provider.PrivacyProvider} to allow and block
|
||||||
* communications from other users. It contains the appropriate structure to suit
|
* communications from other users. It contains the appropriate structure to suit
|
||||||
* user-defined privacy lists. Different configured Privacy packages are used in the
|
* user-defined privacy lists. Different configured Privacy packages are used in the
|
||||||
* Server – Manager communication in order to:
|
* server & manager communication in order to:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Retrieving one's privacy lists.
|
* <li>Retrieving one's privacy lists.
|
||||||
* <li>Adding, removing, and editing one's privacy lists.
|
* <li>Adding, removing, and editing one's privacy lists.
|
||||||
|
|
|
@ -52,57 +52,3 @@ class DirectSocketFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
package org.jivesoftware.smack.proxy;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Proxy;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import javax.net.SocketFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SocketFactory for direct connection
|
|
||||||
*
|
|
||||||
* @author Atul Aggarwal
|
|
||||||
*/
|
|
||||||
class DirectSocketFactory
|
|
||||||
extends SocketFactory
|
|
||||||
{
|
|
||||||
|
|
||||||
public DirectSocketFactory()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(String host, int port)
|
|
||||||
throws IOException, UnknownHostException
|
|
||||||
{
|
|
||||||
Socket newSocket = new Socket(Proxy.NO_PROXY);
|
|
||||||
newSocket.connect(new InetSocketAddress(host,port));
|
|
||||||
return newSocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(String host ,int port, InetAddress localHost,
|
|
||||||
int localPort)
|
|
||||||
throws IOException, UnknownHostException
|
|
||||||
{
|
|
||||||
return new Socket(host,port,localHost,localPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(InetAddress host, int port)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
Socket newSocket = new Socket(Proxy.NO_PROXY);
|
|
||||||
newSocket.connect(new InetSocketAddress(host,port));
|
|
||||||
return newSocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket( InetAddress address, int port,
|
|
||||||
InetAddress localAddress, int localPort)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return new Socket(address,port,localAddress,localPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -154,159 +154,3 @@ class HTTPProxySocketFactory
|
||||||
= Pattern.compile("HTTP/\\S+\\s(\\d+)\\s(.*)\\s*");
|
= Pattern.compile("HTTP/\\S+\\s(\\d+)\\s(.*)\\s*");
|
||||||
|
|
||||||
}
|
}
|
||||||
package org.jivesoftware.smack.proxy;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import javax.net.SocketFactory;
|
|
||||||
import org.jivesoftware.smack.util.Base64;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Http Proxy Socket Factory which returns socket connected to Http Proxy
|
|
||||||
*
|
|
||||||
* @author Atul Aggarwal
|
|
||||||
*/
|
|
||||||
class HTTPProxySocketFactory
|
|
||||||
extends SocketFactory
|
|
||||||
{
|
|
||||||
|
|
||||||
private ProxyInfo proxy;
|
|
||||||
|
|
||||||
public HTTPProxySocketFactory(ProxyInfo proxy)
|
|
||||||
{
|
|
||||||
this.proxy = proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(String host, int port)
|
|
||||||
throws IOException, UnknownHostException
|
|
||||||
{
|
|
||||||
return httpProxifiedSocket(host, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(String host ,int port, InetAddress localHost,
|
|
||||||
int localPort)
|
|
||||||
throws IOException, UnknownHostException
|
|
||||||
{
|
|
||||||
return httpProxifiedSocket(host, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(InetAddress host, int port)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return httpProxifiedSocket(host.getHostAddress(), port);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket( InetAddress address, int port,
|
|
||||||
InetAddress localAddress, int localPort)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return httpProxifiedSocket(address.getHostAddress(), port);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Socket httpProxifiedSocket(String host, int port)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
String proxyhost = proxy.getProxyAddress();
|
|
||||||
int proxyPort = proxy.getProxyPort();
|
|
||||||
Socket socket = new Socket(proxyhost,proxyPort);
|
|
||||||
String hostport = "CONNECT " + host + ":" + port;
|
|
||||||
String proxyLine;
|
|
||||||
String username = proxy.getProxyUsername();
|
|
||||||
if (username == null)
|
|
||||||
{
|
|
||||||
proxyLine = "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String password = proxy.getProxyPassword();
|
|
||||||
proxyLine = "\r\nProxy-Authorization: Basic "
|
|
||||||
+ new String (Base64.encodeBytes((username + ":"
|
|
||||||
+ password).getBytes("UTF-8")));
|
|
||||||
}
|
|
||||||
socket.getOutputStream().write((hostport + " HTTP/1.1\r\nHost: "
|
|
||||||
+ hostport + proxyLine + "\r\n\r\n").getBytes("UTF-8"));
|
|
||||||
|
|
||||||
InputStream in = socket.getInputStream();
|
|
||||||
StringBuilder got = new StringBuilder(100);
|
|
||||||
int nlchars = 0;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
char c = (char) in.read();
|
|
||||||
got.append(c);
|
|
||||||
if (got.length() > 1024)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.HTTP, "Recieved " +
|
|
||||||
"header of >1024 characters from "
|
|
||||||
+ proxyhost + ", cancelling connection");
|
|
||||||
}
|
|
||||||
if (c == -1)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.HTTP);
|
|
||||||
}
|
|
||||||
if ((nlchars == 0 || nlchars == 2) && c == '\r')
|
|
||||||
{
|
|
||||||
nlchars++;
|
|
||||||
}
|
|
||||||
else if ((nlchars == 1 || nlchars == 3) && c == '\n')
|
|
||||||
{
|
|
||||||
nlchars++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nlchars = 0;
|
|
||||||
}
|
|
||||||
if (nlchars == 4)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nlchars != 4)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.HTTP, "Never " +
|
|
||||||
"received blank line from "
|
|
||||||
+ proxyhost + ", cancelling connection");
|
|
||||||
}
|
|
||||||
|
|
||||||
String gotstr = got.toString();
|
|
||||||
|
|
||||||
BufferedReader br = new BufferedReader(new StringReader(gotstr));
|
|
||||||
String response = br.readLine();
|
|
||||||
|
|
||||||
if (response == null)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.HTTP, "Empty proxy " +
|
|
||||||
"response from " + proxyhost + ", cancelling");
|
|
||||||
}
|
|
||||||
|
|
||||||
Matcher m = RESPONSE_PATTERN.matcher(response);
|
|
||||||
if (!m.matches())
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.HTTP , "Unexpected " +
|
|
||||||
"proxy response from " + proxyhost + ": " + response);
|
|
||||||
}
|
|
||||||
|
|
||||||
int code = Integer.parseInt(m.group(1));
|
|
||||||
|
|
||||||
if (code != HttpURLConnection.HTTP_OK)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.HTTP);
|
|
||||||
}
|
|
||||||
|
|
||||||
return socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Pattern RESPONSE_PATTERN
|
|
||||||
= Pattern.compile("HTTP/\\S+\\s(\\d+)\\s(.*)\\s*");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,34 +12,7 @@ public class ProxyException
|
||||||
{
|
{
|
||||||
public ProxyException(ProxyInfo.ProxyType type, String ex, Throwable cause)
|
public ProxyException(ProxyInfo.ProxyType type, String ex, Throwable cause)
|
||||||
{
|
{
|
||||||
super("Proxy Exception " + type.toString() + " : "+ex , cause);
|
super("Proxy Exception " + type.toString() + " : "+ex+", "+cause);
|
||||||
}
|
|
||||||
|
|
||||||
public ProxyException(ProxyInfo.ProxyType type, String ex)
|
|
||||||
{
|
|
||||||
super("Proxy Exception " + type.toString() + " : "+ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProxyException(ProxyInfo.ProxyType type)
|
|
||||||
{
|
|
||||||
super("Proxy Exception " + type.toString() + " : " + "Unknown Error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
package org.jivesoftware.smack.proxy;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An exception class to handle exceptions caused by proxy.
|
|
||||||
*
|
|
||||||
* @author Atul Aggarwal
|
|
||||||
*/
|
|
||||||
public class ProxyException
|
|
||||||
extends IOException
|
|
||||||
{
|
|
||||||
public ProxyException(ProxyInfo.ProxyType type, String ex, Throwable cause)
|
|
||||||
{
|
|
||||||
super("Proxy Exception " + type.toString() + " : "+ex , cause);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProxyException(ProxyInfo.ProxyType type, String ex)
|
public ProxyException(ProxyInfo.ProxyType type, String ex)
|
||||||
|
|
|
@ -112,117 +112,3 @@ public class ProxyInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
package org.jivesoftware.smack.proxy;
|
|
||||||
|
|
||||||
import javax.net.SocketFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class which stores proxy information such as proxy type, host, port,
|
|
||||||
* authentication etc.
|
|
||||||
*
|
|
||||||
* @author Atul Aggarwal
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ProxyInfo
|
|
||||||
{
|
|
||||||
public static enum ProxyType
|
|
||||||
{
|
|
||||||
NONE,
|
|
||||||
HTTP,
|
|
||||||
SOCKS4,
|
|
||||||
SOCKS5
|
|
||||||
}
|
|
||||||
|
|
||||||
private String proxyAddress;
|
|
||||||
private int proxyPort;
|
|
||||||
private String proxyUsername;
|
|
||||||
private String proxyPassword;
|
|
||||||
private ProxyType proxyType;
|
|
||||||
|
|
||||||
public ProxyInfo( ProxyType pType, String pHost, int pPort, String pUser,
|
|
||||||
String pPass)
|
|
||||||
{
|
|
||||||
this.proxyType = pType;
|
|
||||||
this.proxyAddress = pHost;
|
|
||||||
this.proxyPort = pPort;
|
|
||||||
this.proxyUsername = pUser;
|
|
||||||
this.proxyPassword = pPass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProxyInfo forHttpProxy(String pHost, int pPort, String pUser,
|
|
||||||
String pPass)
|
|
||||||
{
|
|
||||||
return new ProxyInfo(ProxyType.HTTP, pHost, pPort, pUser, pPass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProxyInfo forSocks4Proxy(String pHost, int pPort, String pUser,
|
|
||||||
String pPass)
|
|
||||||
{
|
|
||||||
return new ProxyInfo(ProxyType.SOCKS4, pHost, pPort, pUser, pPass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProxyInfo forSocks5Proxy(String pHost, int pPort, String pUser,
|
|
||||||
String pPass)
|
|
||||||
{
|
|
||||||
return new ProxyInfo(ProxyType.SOCKS5, pHost, pPort, pUser, pPass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProxyInfo forNoProxy()
|
|
||||||
{
|
|
||||||
return new ProxyInfo(ProxyType.NONE, null, 0, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProxyInfo forDefaultProxy()
|
|
||||||
{
|
|
||||||
return new ProxyInfo(ProxyType.NONE, null, 0, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProxyType getProxyType()
|
|
||||||
{
|
|
||||||
return proxyType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProxyAddress()
|
|
||||||
{
|
|
||||||
return proxyAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProxyPort()
|
|
||||||
{
|
|
||||||
return proxyPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProxyUsername()
|
|
||||||
{
|
|
||||||
return proxyUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProxyPassword()
|
|
||||||
{
|
|
||||||
return proxyPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SocketFactory getSocketFactory()
|
|
||||||
{
|
|
||||||
if(proxyType == ProxyType.NONE)
|
|
||||||
{
|
|
||||||
return new DirectSocketFactory();
|
|
||||||
}
|
|
||||||
else if(proxyType == ProxyType.HTTP)
|
|
||||||
{
|
|
||||||
return new HTTPProxySocketFactory(this);
|
|
||||||
}
|
|
||||||
else if(proxyType == ProxyType.SOCKS4)
|
|
||||||
{
|
|
||||||
return new Socks4ProxySocketFactory(this);
|
|
||||||
}
|
|
||||||
else if(proxyType == ProxyType.SOCKS5)
|
|
||||||
{
|
|
||||||
return new Socks5ProxySocketFactory(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -197,202 +197,3 @@ public class Socks4ProxySocketFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
package org.jivesoftware.smack.proxy;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import javax.net.SocketFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Socket factory for socks4 proxy
|
|
||||||
*
|
|
||||||
* @author Atul Aggarwal
|
|
||||||
*/
|
|
||||||
public class Socks4ProxySocketFactory
|
|
||||||
extends SocketFactory
|
|
||||||
{
|
|
||||||
private ProxyInfo proxy;
|
|
||||||
|
|
||||||
public Socks4ProxySocketFactory(ProxyInfo proxy)
|
|
||||||
{
|
|
||||||
this.proxy = proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(String host, int port)
|
|
||||||
throws IOException, UnknownHostException
|
|
||||||
{
|
|
||||||
return socks4ProxifiedSocket(host,port);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(String host ,int port, InetAddress localHost,
|
|
||||||
int localPort)
|
|
||||||
throws IOException, UnknownHostException
|
|
||||||
{
|
|
||||||
return socks4ProxifiedSocket(host,port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(InetAddress host, int port)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return socks4ProxifiedSocket(host.getHostAddress(),port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket( InetAddress address, int port,
|
|
||||||
InetAddress localAddress, int localPort)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return socks4ProxifiedSocket(address.getHostAddress(),port);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Socket socks4ProxifiedSocket(String host, int port)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
Socket socket = null;
|
|
||||||
InputStream in = null;
|
|
||||||
OutputStream out = null;
|
|
||||||
String proxy_host = proxy.getProxyAddress();
|
|
||||||
int proxy_port = proxy.getProxyPort();
|
|
||||||
String user = proxy.getProxyUsername();
|
|
||||||
String passwd = proxy.getProxyPassword();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
socket=new Socket(proxy_host, proxy_port);
|
|
||||||
in=socket.getInputStream();
|
|
||||||
out=socket.getOutputStream();
|
|
||||||
socket.setTcpNoDelay(true);
|
|
||||||
|
|
||||||
byte[] buf=new byte[1024];
|
|
||||||
int index=0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
1) CONNECT
|
|
||||||
|
|
||||||
The client connects to the SOCKS server and sends a CONNECT request when
|
|
||||||
it wants to establish a connection to an application server. The client
|
|
||||||
includes in the request packet the IP address and the port number of the
|
|
||||||
destination host, and userid, in the following format.
|
|
||||||
|
|
||||||
+----+----+----+----+----+----+----+----+----+----+....+----+
|
|
||||||
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
|
|
||||||
+----+----+----+----+----+----+----+----+----+----+....+----+
|
|
||||||
# of bytes: 1 1 2 4 variable 1
|
|
||||||
|
|
||||||
VN is the SOCKS protocol version number and should be 4. CD is the
|
|
||||||
SOCKS command code and should be 1 for CONNECT request. NULL is a byte
|
|
||||||
of all zero bits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
index=0;
|
|
||||||
buf[index++]=4;
|
|
||||||
buf[index++]=1;
|
|
||||||
|
|
||||||
buf[index++]=(byte)(port>>>8);
|
|
||||||
buf[index++]=(byte)(port&0xff);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
InetAddress addr=InetAddress.getByName(host);
|
|
||||||
byte[] byteAddress = addr.getAddress();
|
|
||||||
for (int i = 0; i < byteAddress.length; i++)
|
|
||||||
{
|
|
||||||
buf[index++]=byteAddress[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(UnknownHostException uhe)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.SOCKS4,
|
|
||||||
uhe.toString(), uhe);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(user!=null)
|
|
||||||
{
|
|
||||||
System.arraycopy(user.getBytes(), 0, buf, index, user.length());
|
|
||||||
index+=user.length();
|
|
||||||
}
|
|
||||||
buf[index++]=0;
|
|
||||||
out.write(buf, 0, index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
The SOCKS server checks to see whether such a request should be granted
|
|
||||||
based on any combination of source IP address, destination IP address,
|
|
||||||
destination port number, the userid, and information it may obtain by
|
|
||||||
consulting IDENT, cf. RFC 1413. If the request is granted, the SOCKS
|
|
||||||
server makes a connection to the specified port of the destination host.
|
|
||||||
A reply packet is sent to the client when this connection is established,
|
|
||||||
or when the request is rejected or the operation fails.
|
|
||||||
|
|
||||||
+----+----+----+----+----+----+----+----+
|
|
||||||
| VN | CD | DSTPORT | DSTIP |
|
|
||||||
+----+----+----+----+----+----+----+----+
|
|
||||||
# of bytes: 1 1 2 4
|
|
||||||
|
|
||||||
VN is the version of the reply code and should be 0. CD is the result
|
|
||||||
code with one of the following values:
|
|
||||||
|
|
||||||
90: request granted
|
|
||||||
91: request rejected or failed
|
|
||||||
92: request rejected becasue SOCKS server cannot connect to
|
|
||||||
identd on the client
|
|
||||||
93: request rejected because the client program and identd
|
|
||||||
report different user-ids
|
|
||||||
|
|
||||||
The remaining fields are ignored.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int len=6;
|
|
||||||
int s=0;
|
|
||||||
while(s<len)
|
|
||||||
{
|
|
||||||
int i=in.read(buf, s, len-s);
|
|
||||||
if(i<=0)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.SOCKS4,
|
|
||||||
"stream is closed");
|
|
||||||
}
|
|
||||||
s+=i;
|
|
||||||
}
|
|
||||||
if(buf[0]!=0)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.SOCKS4,
|
|
||||||
"server returns VN "+buf[0]);
|
|
||||||
}
|
|
||||||
if(buf[1]!=90)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
catch(Exception eee)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
String message="ProxySOCKS4: server returns CD "+buf[1];
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.SOCKS4,message);
|
|
||||||
}
|
|
||||||
byte[] temp = new byte[2];
|
|
||||||
in.read(temp, 0, 2);
|
|
||||||
return socket;
|
|
||||||
}
|
|
||||||
catch(RuntimeException e)
|
|
||||||
{
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(socket!=null)socket.close();
|
|
||||||
}
|
|
||||||
catch(Exception eee)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -356,361 +356,3 @@ public class Socks5ProxySocketFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
package org.jivesoftware.smack.proxy;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import javax.net.SocketFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Socket factory for Socks5 proxy
|
|
||||||
*
|
|
||||||
* @author Atul Aggarwal
|
|
||||||
*/
|
|
||||||
public class Socks5ProxySocketFactory
|
|
||||||
extends SocketFactory
|
|
||||||
{
|
|
||||||
private ProxyInfo proxy;
|
|
||||||
|
|
||||||
public Socks5ProxySocketFactory(ProxyInfo proxy)
|
|
||||||
{
|
|
||||||
this.proxy = proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(String host, int port)
|
|
||||||
throws IOException, UnknownHostException
|
|
||||||
{
|
|
||||||
return socks5ProxifiedSocket(host,port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(String host ,int port, InetAddress localHost,
|
|
||||||
int localPort)
|
|
||||||
throws IOException, UnknownHostException
|
|
||||||
{
|
|
||||||
|
|
||||||
return socks5ProxifiedSocket(host,port);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket(InetAddress host, int port)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
|
|
||||||
return socks5ProxifiedSocket(host.getHostAddress(),port);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Socket createSocket( InetAddress address, int port,
|
|
||||||
InetAddress localAddress, int localPort)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
|
|
||||||
return socks5ProxifiedSocket(address.getHostAddress(),port);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Socket socks5ProxifiedSocket(String host, int port)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
Socket socket = null;
|
|
||||||
InputStream in = null;
|
|
||||||
OutputStream out = null;
|
|
||||||
String proxy_host = proxy.getProxyAddress();
|
|
||||||
int proxy_port = proxy.getProxyPort();
|
|
||||||
String user = proxy.getProxyUsername();
|
|
||||||
String passwd = proxy.getProxyPassword();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
socket=new Socket(proxy_host, proxy_port);
|
|
||||||
in=socket.getInputStream();
|
|
||||||
out=socket.getOutputStream();
|
|
||||||
|
|
||||||
socket.setTcpNoDelay(true);
|
|
||||||
|
|
||||||
byte[] buf=new byte[1024];
|
|
||||||
int index=0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
+----+----------+----------+
|
|
||||||
|VER | NMETHODS | METHODS |
|
|
||||||
+----+----------+----------+
|
|
||||||
| 1 | 1 | 1 to 255 |
|
|
||||||
+----+----------+----------+
|
|
||||||
|
|
||||||
The VER field is set to X'05' for this version of the protocol. The
|
|
||||||
NMETHODS field contains the number of method identifier octets that
|
|
||||||
appear in the METHODS field.
|
|
||||||
|
|
||||||
The values currently defined for METHOD are:
|
|
||||||
|
|
||||||
o X'00' NO AUTHENTICATION REQUIRED
|
|
||||||
o X'01' GSSAPI
|
|
||||||
o X'02' USERNAME/PASSWORD
|
|
||||||
o X'03' to X'7F' IANA ASSIGNED
|
|
||||||
o X'80' to X'FE' RESERVED FOR PRIVATE METHODS
|
|
||||||
o X'FF' NO ACCEPTABLE METHODS
|
|
||||||
*/
|
|
||||||
|
|
||||||
buf[index++]=5;
|
|
||||||
|
|
||||||
buf[index++]=2;
|
|
||||||
buf[index++]=0; // NO AUTHENTICATION REQUIRED
|
|
||||||
buf[index++]=2; // USERNAME/PASSWORD
|
|
||||||
|
|
||||||
out.write(buf, 0, index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
The server selects from one of the methods given in METHODS, and
|
|
||||||
sends a METHOD selection message:
|
|
||||||
|
|
||||||
+----+--------+
|
|
||||||
|VER | METHOD |
|
|
||||||
+----+--------+
|
|
||||||
| 1 | 1 |
|
|
||||||
+----+--------+
|
|
||||||
*/
|
|
||||||
//in.read(buf, 0, 2);
|
|
||||||
fill(in, buf, 2);
|
|
||||||
|
|
||||||
boolean check=false;
|
|
||||||
switch((buf[1])&0xff)
|
|
||||||
{
|
|
||||||
case 0: // NO AUTHENTICATION REQUIRED
|
|
||||||
check=true;
|
|
||||||
break;
|
|
||||||
case 2: // USERNAME/PASSWORD
|
|
||||||
if(user==null || passwd==null)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Once the SOCKS V5 server has started, and the client has selected the
|
|
||||||
Username/Password Authentication protocol, the Username/Password
|
|
||||||
subnegotiation begins. This begins with the client producing a
|
|
||||||
Username/Password request:
|
|
||||||
|
|
||||||
+----+------+----------+------+----------+
|
|
||||||
|VER | ULEN | UNAME | PLEN | PASSWD |
|
|
||||||
+----+------+----------+------+----------+
|
|
||||||
| 1 | 1 | 1 to 255 | 1 | 1 to 255 |
|
|
||||||
+----+------+----------+------+----------+
|
|
||||||
|
|
||||||
The VER field contains the current version of the subnegotiation,
|
|
||||||
which is X'01'. The ULEN field contains the length of the UNAME field
|
|
||||||
that follows. The UNAME field contains the username as known to the
|
|
||||||
source operating system. The PLEN field contains the length of the
|
|
||||||
PASSWD field that follows. The PASSWD field contains the password
|
|
||||||
association with the given UNAME.
|
|
||||||
*/
|
|
||||||
index=0;
|
|
||||||
buf[index++]=1;
|
|
||||||
buf[index++]=(byte)(user.length());
|
|
||||||
System.arraycopy(user.getBytes(), 0, buf, index,
|
|
||||||
user.length());
|
|
||||||
index+=user.length();
|
|
||||||
buf[index++]=(byte)(passwd.length());
|
|
||||||
System.arraycopy(passwd.getBytes(), 0, buf, index,
|
|
||||||
passwd.length());
|
|
||||||
index+=passwd.length();
|
|
||||||
|
|
||||||
out.write(buf, 0, index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
The server verifies the supplied UNAME and PASSWD, and sends the
|
|
||||||
following response:
|
|
||||||
|
|
||||||
+----+--------+
|
|
||||||
|VER | STATUS |
|
|
||||||
+----+--------+
|
|
||||||
| 1 | 1 |
|
|
||||||
+----+--------+
|
|
||||||
|
|
||||||
A STATUS field of X'00' indicates success. If the server returns a
|
|
||||||
`failure' (STATUS value other than X'00') status, it MUST close the
|
|
||||||
connection.
|
|
||||||
*/
|
|
||||||
//in.read(buf, 0, 2);
|
|
||||||
fill(in, buf, 2);
|
|
||||||
if(buf[1]==0)
|
|
||||||
{
|
|
||||||
check=true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!check)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
catch(Exception eee)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.SOCKS5,
|
|
||||||
"fail in SOCKS5 proxy");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
The SOCKS request is formed as follows:
|
|
||||||
|
|
||||||
+----+-----+-------+------+----------+----------+
|
|
||||||
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
|
|
||||||
+----+-----+-------+------+----------+----------+
|
|
||||||
| 1 | 1 | X'00' | 1 | Variable | 2 |
|
|
||||||
+----+-----+-------+------+----------+----------+
|
|
||||||
|
|
||||||
Where:
|
|
||||||
|
|
||||||
o VER protocol version: X'05'
|
|
||||||
o CMD
|
|
||||||
o CONNECT X'01'
|
|
||||||
o BIND X'02'
|
|
||||||
o UDP ASSOCIATE X'03'
|
|
||||||
o RSV RESERVED
|
|
||||||
o ATYP address type of following address
|
|
||||||
o IP V4 address: X'01'
|
|
||||||
o DOMAINNAME: X'03'
|
|
||||||
o IP V6 address: X'04'
|
|
||||||
o DST.ADDR desired destination address
|
|
||||||
o DST.PORT desired destination port in network octet
|
|
||||||
order
|
|
||||||
*/
|
|
||||||
|
|
||||||
index=0;
|
|
||||||
buf[index++]=5;
|
|
||||||
buf[index++]=1; // CONNECT
|
|
||||||
buf[index++]=0;
|
|
||||||
|
|
||||||
byte[] hostb=host.getBytes();
|
|
||||||
int len=hostb.length;
|
|
||||||
buf[index++]=3; // DOMAINNAME
|
|
||||||
buf[index++]=(byte)(len);
|
|
||||||
System.arraycopy(hostb, 0, buf, index, len);
|
|
||||||
index+=len;
|
|
||||||
buf[index++]=(byte)(port>>>8);
|
|
||||||
buf[index++]=(byte)(port&0xff);
|
|
||||||
|
|
||||||
out.write(buf, 0, index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
The SOCKS request information is sent by the client as soon as it has
|
|
||||||
established a connection to the SOCKS server, and completed the
|
|
||||||
authentication negotiations. The server evaluates the request, and
|
|
||||||
returns a reply formed as follows:
|
|
||||||
|
|
||||||
+----+-----+-------+------+----------+----------+
|
|
||||||
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
|
|
||||||
+----+-----+-------+------+----------+----------+
|
|
||||||
| 1 | 1 | X'00' | 1 | Variable | 2 |
|
|
||||||
+----+-----+-------+------+----------+----------+
|
|
||||||
|
|
||||||
Where:
|
|
||||||
|
|
||||||
o VER protocol version: X'05'
|
|
||||||
o REP Reply field:
|
|
||||||
o X'00' succeeded
|
|
||||||
o X'01' general SOCKS server failure
|
|
||||||
o X'02' connection not allowed by ruleset
|
|
||||||
o X'03' Network unreachable
|
|
||||||
o X'04' Host unreachable
|
|
||||||
o X'05' Connection refused
|
|
||||||
o X'06' TTL expired
|
|
||||||
o X'07' Command not supported
|
|
||||||
o X'08' Address type not supported
|
|
||||||
o X'09' to X'FF' unassigned
|
|
||||||
o RSV RESERVED
|
|
||||||
o ATYP address type of following address
|
|
||||||
o IP V4 address: X'01'
|
|
||||||
o DOMAINNAME: X'03'
|
|
||||||
o IP V6 address: X'04'
|
|
||||||
o BND.ADDR server bound address
|
|
||||||
o BND.PORT server bound port in network octet order
|
|
||||||
*/
|
|
||||||
|
|
||||||
//in.read(buf, 0, 4);
|
|
||||||
fill(in, buf, 4);
|
|
||||||
|
|
||||||
if(buf[1]!=0)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
catch(Exception eee)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.SOCKS5,
|
|
||||||
"server returns "+buf[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(buf[3]&0xff)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
//in.read(buf, 0, 6);
|
|
||||||
fill(in, buf, 6);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
//in.read(buf, 0, 1);
|
|
||||||
fill(in, buf, 1);
|
|
||||||
//in.read(buf, 0, buf[0]+2);
|
|
||||||
fill(in, buf, (buf[0]&0xff)+2);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
//in.read(buf, 0, 18);
|
|
||||||
fill(in, buf, 18);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
return socket;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(RuntimeException e)
|
|
||||||
{
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(socket!=null)
|
|
||||||
{
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception eee)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
String message="ProxySOCKS5: "+e.toString();
|
|
||||||
if(e instanceof Throwable)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.SOCKS5,message,
|
|
||||||
(Throwable)e);
|
|
||||||
}
|
|
||||||
throw new IOException(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fill(InputStream in, byte[] buf, int len)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
int s=0;
|
|
||||||
while(s<len)
|
|
||||||
{
|
|
||||||
int i=in.read(buf, s, len-s);
|
|
||||||
if(i<=0)
|
|
||||||
{
|
|
||||||
throw new ProxyException(ProxyInfo.ProxyType.SOCKS5, "stream " +
|
|
||||||
"is closed");
|
|
||||||
}
|
|
||||||
s+=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -297,7 +297,7 @@ public class AgentSession {
|
||||||
* <p/>
|
* <p/>
|
||||||
* <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
|
* <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
|
||||||
* (equivalent to Presence.Mode.CHAT).
|
* (equivalent to Presence.Mode.CHAT).
|
||||||
* <li>Presence.Mode.DO_NOT_DISTURB -– the agent is busy and should not be disturbed.
|
* <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
|
||||||
* However, special case, or extreme urgency chats may still be offered to the agent.
|
* However, special case, or extreme urgency chats may still be offered to the agent.
|
||||||
* <li>Presence.Mode.AWAY -- the agent is not available and should not
|
* <li>Presence.Mode.AWAY -- the agent is not available and should not
|
||||||
* have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
|
* have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
|
||||||
|
@ -323,7 +323,7 @@ public class AgentSession {
|
||||||
* <p/>
|
* <p/>
|
||||||
* <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
|
* <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
|
||||||
* (equivalent to Presence.Mode.CHAT).
|
* (equivalent to Presence.Mode.CHAT).
|
||||||
* <li>Presence.Mode.DO_NOT_DISTURB -– the agent is busy and should not be disturbed.
|
* <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
|
||||||
* However, special case, or extreme urgency chats may still be offered to the agent.
|
* However, special case, or extreme urgency chats may still be offered to the agent.
|
||||||
* <li>Presence.Mode.AWAY -- the agent is not available and should not
|
* <li>Presence.Mode.AWAY -- the agent is not available and should not
|
||||||
* have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
|
* have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
|
||||||
|
@ -386,7 +386,7 @@ public class AgentSession {
|
||||||
* <p/>
|
* <p/>
|
||||||
* <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
|
* <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
|
||||||
* (equivalent to Presence.Mode.CHAT).
|
* (equivalent to Presence.Mode.CHAT).
|
||||||
* <li>Presence.Mode.DO_NOT_DISTURB -– the agent is busy and should not be disturbed.
|
* <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
|
||||||
* However, special case, or extreme urgency chats may still be offered to the agent.
|
* However, special case, or extreme urgency chats may still be offered to the agent.
|
||||||
* <li>Presence.Mode.AWAY -- the agent is not available and should not
|
* <li>Presence.Mode.AWAY -- the agent is not available and should not
|
||||||
* have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
|
* have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
|
||||||
|
|
Loading…
Reference in a new issue