OSDN Git Service

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