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 }