1 | package nu.fw.jeti.plugins.filetransfer.socks5.jsocks; |
---|
2 | import java.io.*; |
---|
3 | import java.net.*; |
---|
4 | |
---|
5 | /** |
---|
6 | SOCKS4 Reply/Request message. |
---|
7 | */ |
---|
8 | |
---|
9 | class Socks4Message extends ProxyMessage{ |
---|
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 | |
---|
28 | /** |
---|
29 | * Server successfull reply |
---|
30 | */ |
---|
31 | public Socks4Message(int cmd,InetAddress ip,int port){ |
---|
32 | this(0,cmd,ip,port,null); |
---|
33 | } |
---|
34 | |
---|
35 | /** |
---|
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 | } |
---|