349
|
1 package net.sourceforge.jsocks;
|
|
2 import java.io.*;
|
|
3 import java.net.*;
|
|
4
|
352
|
5 /**
|
349
|
6 SOCKS4 Reply/Request message.
|
|
7 */
|
|
8
|
352
|
9 public class Socks4Message extends ProxyMessage{
|
349
|
10
|
|
11 private byte[] msgBytes;
|
|
12 private int msgLength;
|
|
13
|
|
14 /**
|
|
15 * Server failed reply, cmd command for failed request
|
|
16 */
|
|
17 public Socks4Message(int cmd){
|
|
18 super(cmd,null,0);
|
|
19 this.user = null;
|
|
20
|
|
21 msgLength = 2;
|
|
22 msgBytes = new byte[2];
|
|
23
|
|
24 msgBytes[0] = (byte) 0;
|
|
25 msgBytes[1] = (byte) command;
|
|
26 }
|
|
27
|
352
|
28 /**
|
349
|
29 * Server successfull reply
|
|
30 */
|
|
31 public Socks4Message(int cmd,InetAddress ip,int port){
|
|
32 this(0,cmd,ip,port,null);
|
|
33 }
|
|
34
|
352
|
35 /**
|
349
|
36 * Client request
|
|
37 */
|
|
38 public Socks4Message(int cmd,InetAddress ip,int port,String user){
|
|
39 this(SOCKS_VERSION,cmd,ip,port,user);
|
|
40 }
|
|
41
|
|
42 /**
|
|
43 * Most general constructor
|
|
44 */
|
|
45 public Socks4Message(int version, int cmd,
|
|
46 InetAddress ip,int port,String user){
|
|
47 super(cmd,ip,port);
|
|
48 this.user = user;
|
|
49 this.version = version;
|
|
50
|
|
51 msgLength = user == null?8:9+user.length();
|
|
52 msgBytes = new byte[msgLength];
|
|
53
|
|
54 msgBytes[0] = (byte) version;
|
|
55 msgBytes[1] = (byte) command;
|
|
56 msgBytes[2] = (byte) (port >> 8);
|
|
57 msgBytes[3] = (byte) port;
|
|
58
|
|
59 byte[] addr;
|
|
60
|
|
61 if(ip != null)
|
|
62 addr = ip.getAddress();
|
|
63 else{
|
|
64 addr = new byte[4];
|
|
65 addr[0]=addr[1]=addr[2]=addr[3]=0;
|
|
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 public void read(InputStream in) throws IOException{
|
|
88 read(in,true);
|
|
89 }
|
|
90
|
|
91 public void read(InputStream in, boolean clientMode) throws IOException{
|
|
92 DataInputStream d_in = new DataInputStream(in);
|
|
93 version= d_in.readUnsignedByte();
|
|
94 command = d_in.readUnsignedByte();
|
|
95 if(clientMode && command != REPLY_OK){
|
|
96 String errMsg;
|
|
97 if(command >REPLY_OK && command < REPLY_BAD_IDENTD)
|
|
98 errMsg = replyMessage[command-REPLY_OK];
|
|
99 else
|
|
100 errMsg = "Unknown Reply Code";
|
|
101 throw new SocksException(command,errMsg);
|
|
102 }
|
|
103 port = d_in.readUnsignedShort();
|
|
104 byte[] addr = new byte[4];
|
|
105 d_in.readFully(addr);
|
|
106 ip=bytes2IP(addr);
|
|
107 host = ip.getHostName();
|
|
108 if(!clientMode){
|
|
109 int b = in.read();
|
|
110 //Hope there are no idiots with user name bigger than this
|
|
111 byte[] userBytes = new byte[256];
|
|
112 int i = 0;
|
|
113 for(i =0;i<userBytes.length && b>0;++i){
|
|
114 userBytes[i] = (byte) b;
|
|
115 b = in.read();
|
|
116 }
|
|
117 user = new String(userBytes,0,i);
|
|
118 }
|
|
119 }
|
|
120 public void write(OutputStream out) throws IOException{
|
|
121 if(msgBytes == null){
|
|
122 Socks4Message msg = new Socks4Message(version,command,ip,port,user);
|
|
123 msgBytes = msg.msgBytes;
|
|
124 msgLength = msg.msgLength;
|
|
125 }
|
|
126 out.write(msgBytes);
|
|
127 }
|
|
128
|
|
129 //Class methods
|
|
130 static InetAddress bytes2IP(byte[] addr){
|
|
131 String s = bytes2IPV4(addr,0);
|
|
132 try{
|
|
133 return InetAddress.getByName(s);
|
|
134 }catch(UnknownHostException uh_ex){
|
|
135 return null;
|
|
136 }
|
|
137 }
|
|
138
|
|
139 //Constants
|
|
140
|
|
141 static final String[] replyMessage ={
|
|
142 "Request Granted",
|
|
143 "Request Rejected or Failed",
|
|
144 "Failed request, can't connect to Identd",
|
|
145 "Failed request, bad user name"};
|
|
146
|
|
147 static final int SOCKS_VERSION = 4;
|
|
148
|
|
149 public final static int REQUEST_CONNECT = 1;
|
|
150 public final static int REQUEST_BIND = 2;
|
|
151
|
|
152 public final static int REPLY_OK = 90;
|
|
153 public final static int REPLY_REJECTED = 91;
|
|
154 public final static int REPLY_NO_CONNECT = 92;
|
|
155 public final static int REPLY_BAD_IDENTD = 93;
|
|
156
|
|
157 }
|