[1001] | 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 | } |
---|