Mercurial > 510Connectbot
comparison src/net/sourceforge/jsocks/Socks4Message.java @ 0:0ce5cc452d02
initial version
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 22 May 2014 10:41:19 -0700 |
parents | |
children | 205ee2873330 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0ce5cc452d02 |
---|---|
1 package net.sourceforge.jsocks; | |
2 import java.io.DataInputStream; | |
3 import java.io.IOException; | |
4 import java.io.InputStream; | |
5 import java.io.OutputStream; | |
6 import java.net.InetAddress; | |
7 import java.net.UnknownHostException; | |
8 | |
9 /** | |
10 SOCKS4 Reply/Request message. | |
11 */ | |
12 | |
13 public class Socks4Message extends ProxyMessage { | |
14 | |
15 private byte[] msgBytes; | |
16 private int msgLength; | |
17 | |
18 /** | |
19 * Server failed reply, cmd command for failed request | |
20 */ | |
21 public Socks4Message(int cmd) { | |
22 super(cmd, null, 0); | |
23 this.user = null; | |
24 msgLength = 2; | |
25 msgBytes = new byte[2]; | |
26 msgBytes[0] = (byte) 0; | |
27 msgBytes[1] = (byte) command; | |
28 } | |
29 | |
30 /** | |
31 * Server successfull reply | |
32 */ | |
33 public Socks4Message(int cmd, InetAddress ip, int port) { | |
34 this(0, cmd, ip, port, null); | |
35 } | |
36 | |
37 /** | |
38 * Client request | |
39 */ | |
40 public Socks4Message(int cmd, InetAddress ip, int port, String user) { | |
41 this(SOCKS_VERSION, cmd, ip, port, user); | |
42 } | |
43 | |
44 /** | |
45 * Most general constructor | |
46 */ | |
47 public Socks4Message(int version, int cmd, | |
48 InetAddress ip, int port, String user) { | |
49 super(cmd, ip, port); | |
50 this.user = user; | |
51 this.version = version; | |
52 msgLength = user == null ? 8 : 9 + user.length(); | |
53 msgBytes = new byte[msgLength]; | |
54 msgBytes[0] = (byte) version; | |
55 msgBytes[1] = (byte) command; | |
56 msgBytes[2] = (byte)(port >> 8); | |
57 msgBytes[3] = (byte) port; | |
58 byte[] addr; | |
59 | |
60 if (ip != null) | |
61 addr = ip.getAddress(); | |
62 else { | |
63 addr = new byte[4]; | |
64 addr[0] = addr[1] = addr[2] = addr[3] = 0; | |
65 } | |
66 | |
67 System.arraycopy(addr, 0, msgBytes, 4, 4); | |
68 | |
69 if (user != null) { | |
70 byte[] buf = user.getBytes(); | |
71 System.arraycopy(buf, 0, msgBytes, 8, buf.length); | |
72 msgBytes[msgBytes.length - 1 ] = 0; | |
73 } | |
74 } | |
75 | |
76 /** | |
77 *Initialise from the stream | |
78 *If clientMode is true attempts to read a server response | |
79 *otherwise reads a client request | |
80 *see read for more detail | |
81 */ | |
82 public Socks4Message(InputStream in, boolean clientMode) throws IOException { | |
83 msgBytes = null; | |
84 read(in, clientMode); | |
85 } | |
86 | |
87 @Override | |
88 public void read(InputStream in) throws IOException { | |
89 read(in, true); | |
90 } | |
91 | |
92 @Override | |
93 public void read(InputStream in, boolean clientMode) throws IOException { | |
94 boolean mode4a = false; | |
95 DataInputStream d_in = new DataInputStream(in); | |
96 version = d_in.readUnsignedByte(); | |
97 command = d_in.readUnsignedByte(); | |
98 | |
99 if (clientMode && command != REPLY_OK) { | |
100 String errMsg; | |
101 | |
102 if (command > REPLY_OK && command < REPLY_BAD_IDENTD) | |
103 errMsg = replyMessage[command - REPLY_OK]; | |
104 else | |
105 errMsg = "Unknown Reply Code"; | |
106 | |
107 throw new SocksException(command, errMsg); | |
108 } | |
109 | |
110 port = d_in.readUnsignedShort(); | |
111 byte[] addr = new byte[4]; | |
112 d_in.readFully(addr); | |
113 | |
114 if (addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] != 0) | |
115 mode4a = true; | |
116 else { | |
117 ip = bytes2IP(addr); | |
118 host = ip.getHostName(); | |
119 } | |
120 | |
121 if (!clientMode) { | |
122 StringBuilder sb = new StringBuilder(); | |
123 int b; | |
124 | |
125 while ((b = in.read()) != 0) | |
126 sb.append((char) b); | |
127 | |
128 user = sb.toString(); | |
129 | |
130 if (mode4a) { | |
131 sb.setLength(0); | |
132 | |
133 while ((b = in.read()) != 0) | |
134 sb.append((char) b); | |
135 | |
136 host = sb.toString(); | |
137 } | |
138 } | |
139 } | |
140 @Override | |
141 public void write(OutputStream out) throws IOException { | |
142 if (msgBytes == null) { | |
143 Socks4Message msg = new Socks4Message(version, command, ip, port, user); | |
144 msgBytes = msg.msgBytes; | |
145 msgLength = msg.msgLength; | |
146 } | |
147 | |
148 out.write(msgBytes); | |
149 } | |
150 | |
151 //Class methods | |
152 static InetAddress bytes2IP(byte[] addr) { | |
153 String s = bytes2IPV4(addr, 0); | |
154 | |
155 try { | |
156 return InetAddress.getByName(s); | |
157 } | |
158 catch (UnknownHostException uh_ex) { | |
159 return null; | |
160 } | |
161 } | |
162 | |
163 //Constants | |
164 | |
165 static final String[] replyMessage = { | |
166 "Request Granted", | |
167 "Request Rejected or Failed", | |
168 "Failed request, can't connect to Identd", | |
169 "Failed request, bad user name" | |
170 }; | |
171 | |
172 static final int SOCKS_VERSION = 4; | |
173 | |
174 public final static int REQUEST_CONNECT = 1; | |
175 public final static int REQUEST_BIND = 2; | |
176 | |
177 public final static int REPLY_OK = 90; | |
178 public final static int REPLY_REJECTED = 91; | |
179 public final static int REPLY_NO_CONNECT = 92; | |
180 public final static int REPLY_BAD_IDENTD = 93; | |
181 | |
182 } |