1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.proxy.handlers.socks;
21
22 import java.util.Arrays;
23
24 import org.apache.mina.core.buffer.IoBuffer;
25 import org.apache.mina.core.filterchain.IoFilter.NextFilter;
26 import org.apache.mina.proxy.session.ProxyIoSession;
27 import org.apache.mina.proxy.utils.ByteUtilities;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31
32
33
34
35
36
37 public class Socks4LogicHandler extends AbstractSocksLogicHandler {
38
39 private final static Logger logger = LoggerFactory
40 .getLogger(Socks4LogicHandler.class);
41
42
43
44
45 public Socks4LogicHandler(final ProxyIoSession proxyIoSession) {
46 super(proxyIoSession);
47 }
48
49
50
51
52
53
54 public void doHandshake(final NextFilter nextFilter) {
55 logger.debug(" doHandshake()");
56
57
58 writeRequest(nextFilter, request);
59 }
60
61
62
63
64
65
66
67
68 protected void writeRequest(final NextFilter nextFilter,
69 final SocksProxyRequest request) {
70 try {
71 boolean isV4ARequest = Arrays.equals(request.getIpAddress(),
72 SocksProxyConstants.FAKE_IP);
73 byte[] userID = request.getUserName().getBytes("ASCII");
74 byte[] host = isV4ARequest ? request.getHost().getBytes("ASCII")
75 : null;
76
77 int len = 9 + userID.length;
78
79 if (isV4ARequest) {
80 len += host.length + 1;
81 }
82
83 IoBuffer buf = IoBuffer.allocate(len);
84
85 buf.put(request.getProtocolVersion());
86 buf.put(request.getCommandCode());
87 buf.put(request.getPort());
88 buf.put(request.getIpAddress());
89 buf.put(userID);
90 buf.put(SocksProxyConstants.TERMINATOR);
91
92 if (isV4ARequest) {
93 buf.put(host);
94 buf.put(SocksProxyConstants.TERMINATOR);
95 }
96
97 if (isV4ARequest) {
98 logger.debug(" sending SOCKS4a request");
99 } else {
100 logger.debug(" sending SOCKS4 request");
101 }
102
103 buf.flip();
104 writeData(nextFilter, buf);
105 } catch (Exception ex) {
106 closeSession("Unable to send Socks request: ", ex);
107 }
108 }
109
110
111
112
113
114
115
116
117 public void messageReceived(final NextFilter nextFilter,
118 final IoBuffer buf) {
119 try {
120 if (buf.remaining() >= SocksProxyConstants.SOCKS_4_RESPONSE_SIZE) {
121 handleResponse(buf);
122 }
123 } catch (Exception ex) {
124 closeSession("Proxy handshake failed: ", ex);
125 }
126 }
127
128
129
130
131
132
133
134
135
136
137 protected void handleResponse(final IoBuffer buf) throws Exception {
138 byte first = buf.get(0);
139
140 if (first != 0) {
141 throw new Exception("Socks response seems to be malformed");
142 }
143
144 byte status = buf.get(1);
145
146
147 buf.position(buf.position() + SocksProxyConstants.SOCKS_4_RESPONSE_SIZE);
148
149 if (status == SocksProxyConstants.V4_REPLY_REQUEST_GRANTED) {
150 setHandshakeComplete();
151 } else {
152 throw new Exception("Proxy handshake failed - Code: 0x"
153 + ByteUtilities.asHex(new byte[] { status }) + " ("
154 + SocksProxyConstants.getReplyCodeAsString(status) + ")");
155 }
156 }
157 }