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