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	private boolean isEstablished = false;
 29
 30	public SocksConnection(JingleConnection jingleConnection, String host,
 31			String jid, int port, String type) {
 32		this.jingleConnection = jingleConnection;
 33		this.host = host;
 34		this.jid = jid;
 35		this.port = port;
 36		this.isProxy = "proxy".equalsIgnoreCase(type);
 37		try {
 38			MessageDigest mDigest = MessageDigest.getInstance("SHA-1");
 39			StringBuilder destBuilder = new StringBuilder();
 40			destBuilder.append(jingleConnection.getSessionId());
 41			destBuilder.append(jingleConnection.getInitiator());
 42			destBuilder.append(jingleConnection.getResponder());
 43			mDigest.reset();
 44			this.destination = CryptoHelper.bytesToHex(mDigest
 45					.digest(destBuilder.toString().getBytes()));
 46		} catch (NoSuchAlgorithmException e) {
 47
 48		}
 49	}
 50
 51	public void connect(final OnSocksConnection callback) {
 52		new Thread(new Runnable() {
 53			
 54			@Override
 55			public void run() {
 56				try {
 57					socket = new Socket(host, port);
 58					InputStream is = socket.getInputStream();
 59					outputStream = socket.getOutputStream();
 60					byte[] login = { 0x05, 0x01, 0x00 };
 61					byte[] expectedReply = { 0x05, 0x00 };
 62					byte[] reply = new byte[2];
 63					outputStream.write(login);
 64					is.read(reply);
 65					if (Arrays.equals(reply, expectedReply)) {
 66						String connect = "" + '\u0005' + '\u0001' + '\u0000' + '\u0003'
 67								+ '\u0028' + destination + '\u0000' + '\u0000';
 68						outputStream.write(connect.getBytes());
 69						byte[] result = new byte[2];
 70						is.read(result);
 71						int status = result[1];
 72						if (status == 0) {
 73							Log.d("xmppService", "established connection with "+host + ":" + port
 74									+ "/" + destination);
 75							isEstablished = true;
 76							callback.established();
 77						} else {
 78							callback.failed();
 79						}
 80					} else {
 81						socket.close();
 82						callback.failed();
 83					}
 84				} catch (UnknownHostException e) {
 85					callback.failed();
 86				} catch (IOException e) {
 87					callback.failed();
 88				}
 89			}
 90		}).start();
 91		
 92	}
 93
 94	public void send(final JingleFile file, final OnFileTransmitted callback) {
 95		new Thread(new Runnable() {
 96			
 97			@Override
 98			public void run() {
 99				FileInputStream fileInputStream = null;
100				try {
101					MessageDigest digest = MessageDigest.getInstance("SHA-1");
102					digest.reset();
103					fileInputStream = new FileInputStream(file);
104					int count;
105					byte[] buffer = new byte[8192];
106					while ((count = fileInputStream.read(buffer)) > 0) {
107						outputStream.write(buffer, 0, count);
108						digest.update(buffer, 0, count);
109					}
110					outputStream.flush();
111					file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
112					if (callback!=null) {
113						callback.onFileTransmitted(file);
114					}
115				} catch (FileNotFoundException e) {
116					// TODO Auto-generated catch block
117					e.printStackTrace();
118				} catch (IOException e) {
119					// TODO Auto-generated catch block
120					e.printStackTrace();
121				} catch (NoSuchAlgorithmException e) {
122					// TODO Auto-generated catch block
123					e.printStackTrace();
124				} finally {
125					try {
126						if (fileInputStream != null) {
127							fileInputStream.close();
128						}
129					} catch (IOException e) {
130						// TODO Auto-generated catch block
131						e.printStackTrace();
132					}
133				}
134			}
135		}).start();
136		
137	}
138
139	public boolean isProxy() {
140		return this.isProxy;
141	}
142
143	public String getJid() {
144		return this.jid;
145	}
146
147	public void disconnect() {
148		if (this.socket!=null) {
149			try {
150				this.socket.close();
151				Log.d("xmppService","cloesd socket with "+this.host);
152			} catch (IOException e) {
153				Log.d("xmppService","error closing socket with "+this.host);
154			}
155		}
156	}
157	
158	public boolean isEstablished() {
159		return this.isEstablished;
160	}
161}