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}