SocksConnection.java

  1package eu.siacs.conversations.xmpp.jingle;
  2
  3import java.io.FileInputStream;
  4import java.io.FileNotFoundException;
  5import java.io.IOException;
  6import java.io.InputStream;
  7import java.io.OutputStream;
  8import java.net.Socket;
  9import java.net.UnknownHostException;
 10import java.security.MessageDigest;
 11import java.security.NoSuchAlgorithmException;
 12import java.util.Arrays;
 13
 14import eu.siacs.conversations.utils.CryptoHelper;
 15
 16import android.util.Log;
 17
 18public class SocksConnection {
 19
 20	private JingleConnection jingleConnection;
 21	private Socket socket;
 22	private String host;
 23	private String jid;
 24	private int port;
 25	private boolean isProxy = false;
 26	private String destination;
 27	private OutputStream outputStream;
 28
 29	public SocksConnection(JingleConnection jingleConnection, String host,
 30			String jid, int port, String type) {
 31		this.jingleConnection = jingleConnection;
 32		this.host = host;
 33		this.jid = jid;
 34		this.port = port;
 35		this.isProxy = "proxy".equalsIgnoreCase(type);
 36		try {
 37			MessageDigest mDigest = MessageDigest.getInstance("SHA-1");
 38			StringBuilder destBuilder = new StringBuilder();
 39			destBuilder.append(jingleConnection.getSessionId());
 40			destBuilder.append(jingleConnection.getInitiator());
 41			destBuilder.append(jingleConnection.getResponder());
 42			mDigest.reset();
 43			this.destination = CryptoHelper.bytesToHex(mDigest
 44					.digest(destBuilder.toString().getBytes()));
 45			Log.d("xmppService", "host=" + host + ", port=" + port
 46					+ ", destination: " + destination);
 47		} catch (NoSuchAlgorithmException e) {
 48
 49		}
 50	}
 51
 52	public boolean connect() {
 53		try {
 54			this.socket = new Socket(this.host, this.port);
 55			InputStream is = socket.getInputStream();
 56			this.outputStream = socket.getOutputStream();
 57			byte[] login = { 0x05, 0x01, 0x00 };
 58			byte[] expectedReply = { 0x05, 0x00 };
 59			byte[] reply = new byte[2];
 60			this.outputStream.write(login);
 61			is.read(reply);
 62			if (Arrays.equals(reply, expectedReply)) {
 63				String connect = "" + '\u0005' + '\u0001' + '\u0000' + '\u0003'
 64						+ '\u0028' + this.destination + '\u0000' + '\u0000';
 65				this.outputStream.write(connect.getBytes());
 66				byte[] result = new byte[2];
 67				is.read(result);
 68				int status = result[0];
 69				return (status == 0);
 70			} else {
 71				socket.close();
 72				return false;
 73			}
 74		} catch (UnknownHostException e) {
 75			return false;
 76		} catch (IOException e) {
 77			return false;
 78		}
 79	}
 80
 81	public void send(final JingleFile file, final OnFileTransmitted callback) {
 82		new Thread(new Runnable() {
 83			
 84			@Override
 85			public void run() {
 86				FileInputStream fileInputStream = null;
 87				try {
 88					MessageDigest digest = MessageDigest.getInstance("SHA-1");
 89					digest.reset();
 90					fileInputStream = new FileInputStream(file);
 91					int count;
 92					byte[] buffer = new byte[8192];
 93					while ((count = fileInputStream.read(buffer)) > 0) {
 94						outputStream.write(buffer, 0, count);
 95						digest.update(buffer, 0, count);
 96					}
 97					outputStream.flush();
 98					file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
 99					if (callback!=null) {
100						callback.onFileTransmitted(file);
101					}
102				} catch (FileNotFoundException e) {
103					// TODO Auto-generated catch block
104					e.printStackTrace();
105				} catch (IOException e) {
106					// TODO Auto-generated catch block
107					e.printStackTrace();
108				} catch (NoSuchAlgorithmException e) {
109					// TODO Auto-generated catch block
110					e.printStackTrace();
111				} finally {
112					try {
113						if (fileInputStream != null) {
114							fileInputStream.close();
115						}
116					} catch (IOException e) {
117						// TODO Auto-generated catch block
118						e.printStackTrace();
119					}
120				}
121			}
122		}).start();
123		
124	}
125
126	public boolean isProxy() {
127		return this.isProxy;
128	}
129
130	public String getJid() {
131		return this.jid;
132	}
133
134	public void disconnect() {
135		if (this.socket!=null) {
136			try {
137				this.socket.close();
138				Log.d("xmppService","cloesd socket with "+this.host);
139			} catch (IOException e) {
140				Log.d("xmppService","error closing socket with "+this.host);
141			}
142		}
143	}
144}