1/*
2 Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3
4 This file is part of libzmq, the ZeroMQ core engine in C++.
5
6 libzmq is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 As a special exception, the Contributors give you permission to link
12 this library with independent modules to produce an executable,
13 regardless of the license terms of these independent modules, and to
14 copy and distribute the resulting executable under terms of your choice,
15 provided that you also meet, for each linked independent module, the
16 terms and conditions of the license of that module. An independent
17 module is a module which is not derived from or based on this library.
18 If you modify this library, you must extend this exception to your
19 version of the library.
20
21 libzmq is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28*/
29
30#include "precompiled.hpp"
31#include <sys/types.h>
32
33#include "err.hpp"
34#include "socks.hpp"
35#include "tcp.hpp"
36#include "blob.hpp"
37
38#ifndef ZMQ_HAVE_WINDOWS
39#include <sys/socket.h>
40#include <netinet/in.h>
41#include <netdb.h>
42#endif
43
44zmq::socks_greeting_t::socks_greeting_t (uint8_t method_) : num_methods (1)
45{
46 methods[0] = method_;
47}
48
49zmq::socks_greeting_t::socks_greeting_t (const uint8_t *methods_,
50 uint8_t num_methods_) :
51 num_methods (num_methods_)
52{
53 for (uint8_t i = 0; i < num_methods_; i++)
54 methods[i] = methods_[i];
55}
56
57zmq::socks_greeting_encoder_t::socks_greeting_encoder_t () :
58 _bytes_encoded (0),
59 _bytes_written (0)
60{
61}
62
63void zmq::socks_greeting_encoder_t::encode (const socks_greeting_t &greeting_)
64{
65 uint8_t *ptr = _buf;
66
67 *ptr++ = 0x05;
68 *ptr++ = static_cast<uint8_t> (greeting_.num_methods);
69 for (uint8_t i = 0; i < greeting_.num_methods; i++)
70 *ptr++ = greeting_.methods[i];
71
72 _bytes_encoded = 2 + greeting_.num_methods;
73 _bytes_written = 0;
74}
75
76int zmq::socks_greeting_encoder_t::output (fd_t fd_)
77{
78 const int rc =
79 tcp_write (fd_, _buf + _bytes_written, _bytes_encoded - _bytes_written);
80 if (rc > 0)
81 _bytes_written += static_cast<size_t> (rc);
82 return rc;
83}
84
85bool zmq::socks_greeting_encoder_t::has_pending_data () const
86{
87 return _bytes_written < _bytes_encoded;
88}
89
90void zmq::socks_greeting_encoder_t::reset ()
91{
92 _bytes_encoded = _bytes_written = 0;
93}
94
95zmq::socks_choice_t::socks_choice_t (unsigned char method_) : method (method_)
96{
97}
98
99zmq::socks_choice_decoder_t::socks_choice_decoder_t () : _bytes_read (0)
100{
101}
102
103int zmq::socks_choice_decoder_t::input (fd_t fd_)
104{
105 zmq_assert (_bytes_read < 2);
106 const int rc = tcp_read (fd_, _buf + _bytes_read, 2 - _bytes_read);
107 if (rc > 0) {
108 _bytes_read += static_cast<size_t> (rc);
109 if (_buf[0] != 0x05)
110 return -1;
111 }
112 return rc;
113}
114
115bool zmq::socks_choice_decoder_t::message_ready () const
116{
117 return _bytes_read == 2;
118}
119
120zmq::socks_choice_t zmq::socks_choice_decoder_t::decode ()
121{
122 zmq_assert (message_ready ());
123 return socks_choice_t (_buf[1]);
124}
125
126void zmq::socks_choice_decoder_t::reset ()
127{
128 _bytes_read = 0;
129}
130
131
132zmq::socks_basic_auth_request_t::socks_basic_auth_request_t (
133 const std::string &username_, const std::string &password_) :
134 username (username_),
135 password (password_)
136{
137 zmq_assert (username_.size () <= UINT8_MAX);
138 zmq_assert (password_.size () <= UINT8_MAX);
139}
140
141
142zmq::socks_basic_auth_request_encoder_t::socks_basic_auth_request_encoder_t () :
143 _bytes_encoded (0),
144 _bytes_written (0)
145{
146}
147
148void zmq::socks_basic_auth_request_encoder_t::encode (
149 const socks_basic_auth_request_t &req_)
150{
151 unsigned char *ptr = _buf;
152 *ptr++ = 0x01;
153 *ptr++ = static_cast<unsigned char> (req_.username.size ());
154 memcpy (ptr, req_.username.c_str (), req_.username.size ());
155 ptr += req_.username.size ();
156 *ptr++ = static_cast<unsigned char> (req_.password.size ());
157 memcpy (ptr, req_.password.c_str (), req_.password.size ());
158 ptr += req_.password.size ();
159
160 _bytes_encoded = ptr - _buf;
161 _bytes_written = 0;
162}
163
164int zmq::socks_basic_auth_request_encoder_t::output (fd_t fd_)
165{
166 const int rc =
167 tcp_write (fd_, _buf + _bytes_written, _bytes_encoded - _bytes_written);
168 if (rc > 0)
169 _bytes_written += static_cast<size_t> (rc);
170 return rc;
171}
172
173bool zmq::socks_basic_auth_request_encoder_t::has_pending_data () const
174{
175 return _bytes_written < _bytes_encoded;
176}
177
178void zmq::socks_basic_auth_request_encoder_t::reset ()
179{
180 _bytes_encoded = _bytes_written = 0;
181}
182
183
184zmq::socks_auth_response_t::socks_auth_response_t (uint8_t response_code_) :
185 response_code (response_code_)
186{
187}
188
189zmq::socks_auth_response_decoder_t::socks_auth_response_decoder_t () :
190 _bytes_read (0)
191{
192}
193
194int zmq::socks_auth_response_decoder_t::input (fd_t fd_)
195{
196 zmq_assert (_bytes_read < 2);
197 const int rc = tcp_read (fd_, _buf + _bytes_read, 2 - _bytes_read);
198 if (rc > 0) {
199 _bytes_read += static_cast<size_t> (rc);
200 if (_buf[0] != 0x01)
201 return -1;
202 }
203 return rc;
204}
205
206bool zmq::socks_auth_response_decoder_t::message_ready () const
207{
208 return _bytes_read == 2;
209}
210
211zmq::socks_auth_response_t zmq::socks_auth_response_decoder_t::decode ()
212{
213 zmq_assert (message_ready ());
214 return socks_auth_response_t (_buf[1]);
215}
216
217void zmq::socks_auth_response_decoder_t::reset ()
218{
219 _bytes_read = 0;
220}
221
222
223zmq::socks_request_t::socks_request_t (uint8_t command_,
224 std::string hostname_,
225 uint16_t port_) :
226 command (command_),
227 hostname (ZMQ_MOVE (hostname_)),
228 port (port_)
229{
230 zmq_assert (hostname.size () <= UINT8_MAX);
231}
232
233zmq::socks_request_encoder_t::socks_request_encoder_t () :
234 _bytes_encoded (0),
235 _bytes_written (0)
236{
237}
238
239void zmq::socks_request_encoder_t::encode (const socks_request_t &req_)
240{
241 zmq_assert (req_.hostname.size () <= UINT8_MAX);
242
243 unsigned char *ptr = _buf;
244 *ptr++ = 0x05;
245 *ptr++ = req_.command;
246 *ptr++ = 0x00;
247
248#if defined ZMQ_HAVE_OPENVMS && defined __ia64 && __INITIAL_POINTER_SIZE == 64
249 __addrinfo64 hints, *res = NULL;
250#else
251 addrinfo hints, *res = NULL;
252#endif
253
254 memset (&hints, 0, sizeof hints);
255
256 // Suppress potential DNS lookups.
257 hints.ai_flags = AI_NUMERICHOST;
258
259 const int rc = getaddrinfo (req_.hostname.c_str (), NULL, &hints, &res);
260 if (rc == 0 && res->ai_family == AF_INET) {
261 const struct sockaddr_in *sockaddr_in =
262 reinterpret_cast<const struct sockaddr_in *> (res->ai_addr);
263 *ptr++ = 0x01;
264 memcpy (ptr, &sockaddr_in->sin_addr, 4);
265 ptr += 4;
266 } else if (rc == 0 && res->ai_family == AF_INET6) {
267 const struct sockaddr_in6 *sockaddr_in6 =
268 reinterpret_cast<const struct sockaddr_in6 *> (res->ai_addr);
269 *ptr++ = 0x04;
270 memcpy (ptr, &sockaddr_in6->sin6_addr, 16);
271 ptr += 16;
272 } else {
273 *ptr++ = 0x03;
274 *ptr++ = static_cast<unsigned char> (req_.hostname.size ());
275 memcpy (ptr, req_.hostname.c_str (), req_.hostname.size ());
276 ptr += req_.hostname.size ();
277 }
278
279 if (rc == 0)
280 freeaddrinfo (res);
281
282 *ptr++ = req_.port / 256;
283 *ptr++ = req_.port % 256;
284
285 _bytes_encoded = ptr - _buf;
286 _bytes_written = 0;
287}
288
289int zmq::socks_request_encoder_t::output (fd_t fd_)
290{
291 const int rc =
292 tcp_write (fd_, _buf + _bytes_written, _bytes_encoded - _bytes_written);
293 if (rc > 0)
294 _bytes_written += static_cast<size_t> (rc);
295 return rc;
296}
297
298bool zmq::socks_request_encoder_t::has_pending_data () const
299{
300 return _bytes_written < _bytes_encoded;
301}
302
303void zmq::socks_request_encoder_t::reset ()
304{
305 _bytes_encoded = _bytes_written = 0;
306}
307
308zmq::socks_response_t::socks_response_t (uint8_t response_code_,
309 const std::string &address_,
310 uint16_t port_) :
311 response_code (response_code_),
312 address (address_),
313 port (port_)
314{
315}
316
317zmq::socks_response_decoder_t::socks_response_decoder_t () : _bytes_read (0)
318{
319}
320
321int zmq::socks_response_decoder_t::input (fd_t fd_)
322{
323 size_t n = 0;
324
325 if (_bytes_read < 5)
326 n = 5 - _bytes_read;
327 else {
328 const uint8_t atyp = _buf[3];
329 zmq_assert (atyp == 0x01 || atyp == 0x03 || atyp == 0x04);
330 if (atyp == 0x01)
331 n = 3 + 2;
332 else if (atyp == 0x03)
333 n = _buf[4] + 2;
334 else if (atyp == 0x04)
335 n = 15 + 2;
336 }
337 const int rc = tcp_read (fd_, _buf + _bytes_read, n);
338 if (rc > 0) {
339 _bytes_read += static_cast<size_t> (rc);
340 if (_buf[0] != 0x05)
341 return -1;
342 if (_bytes_read >= 2)
343 if (_buf[1] > 0x08)
344 return -1;
345 if (_bytes_read >= 3)
346 if (_buf[2] != 0x00)
347 return -1;
348 if (_bytes_read >= 4) {
349 const uint8_t atyp = _buf[3];
350 if (atyp != 0x01 && atyp != 0x03 && atyp != 0x04)
351 return -1;
352 }
353 }
354 return rc;
355}
356
357bool zmq::socks_response_decoder_t::message_ready () const
358{
359 if (_bytes_read < 4)
360 return false;
361
362 const uint8_t atyp = _buf[3];
363 zmq_assert (atyp == 0x01 || atyp == 0x03 || atyp == 0x04);
364 if (atyp == 0x01)
365 return _bytes_read == 10;
366 if (atyp == 0x03)
367 return _bytes_read > 4 && _bytes_read == 4 + 1 + _buf[4] + 2u;
368
369 return _bytes_read == 22;
370}
371
372zmq::socks_response_t zmq::socks_response_decoder_t::decode ()
373{
374 zmq_assert (message_ready ());
375 return socks_response_t (_buf[1], "", 0);
376}
377
378void zmq::socks_response_decoder_t::reset ()
379{
380 _bytes_read = 0;
381}
382