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 static final Logger LOGGER = LoggerFactory.getLogger(Socks4LogicHandler.class);
40
41
42
43
44
45
46 public Socks4LogicHandler(final ProxyIoSession proxyIoSession) {
47 super(proxyIoSession);
48 }
49
50
51
52
53
54
55 @Override
56 public void doHandshake(final NextFilter nextFilter) {
57 if (LOGGER.isDebugEnabled()) {
58 LOGGER.debug(" doHandshake()");
59 }
60
61
62 writeRequest(nextFilter, request);
63 }
64
65
66
67
68
69
70
71
72 protected void writeRequest(final NextFilter nextFilter, final SocksProxyRequest request) {
73 try {
74 boolean isV4ARequest = Arrays.equals(request.getIpAddress(), SocksProxyConstants.FAKE_IP);
75 byte[] userID = request.getUserName().getBytes("ASCII");
76 byte[] host = isV4ARequest ? request.getHost().getBytes("ASCII") : null;
77
78 int len = 9 + userID.length;
79
80 if (isV4ARequest) {
81 len += host.length + 1;
82 }
83
84 IoBuffer buf = IoBuffer.allocate(len);
85
86 buf.put(request.getProtocolVersion());
87 buf.put(request.getCommandCode());
88 buf.put(request.getPort());
89 buf.put(request.getIpAddress());
90 buf.put(userID);
91 buf.put(SocksProxyConstants.TERMINATOR);
92
93 if (isV4ARequest) {
94 buf.put(host);
95 buf.put(SocksProxyConstants.TERMINATOR);
96 }
97
98 if (LOGGER.isDebugEnabled()) {
99 if (isV4ARequest) {
100 LOGGER.debug(" sending SOCKS4a request");
101 } else {
102 LOGGER.debug(" sending SOCKS4 request");
103 }
104 }
105
106 buf.flip();
107 writeData(nextFilter, buf);
108 } catch (Exception ex) {
109 closeSession("Unable to send Socks request: ", ex);
110 }
111 }
112
113
114
115
116
117
118
119
120 @Override
121 public void messageReceived(final NextFilter nextFilter, final IoBuffer buf) {
122 try {
123 if (buf.remaining() >= SocksProxyConstants.SOCKS_4_RESPONSE_SIZE) {
124 handleResponse(buf);
125 }
126 } catch (Exception ex) {
127 closeSession("Proxy handshake failed: ", ex);
128 }
129 }
130
131
132
133
134
135
136
137
138
139
140 protected void handleResponse(final IoBuffer buf) throws Exception {
141 byte first = buf.get(0);
142
143 if (first != 0) {
144 throw new Exception("Socks response seems to be malformed");
145 }
146
147 byte status = buf.get(1);
148
149
150 buf.position(buf.position() + SocksProxyConstants.SOCKS_4_RESPONSE_SIZE);
151
152 if (status == SocksProxyConstants.V4_REPLY_REQUEST_GRANTED) {
153 setHandshakeComplete();
154 } else {
155 throw new Exception("Proxy handshake failed - Code: 0x" + ByteUtilities.asHex(new byte[] { status }) + " ("
156 + SocksProxyConstants.getReplyCodeAsString(status) + ")");
157 }
158 }
159 }