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 
socks_greeting_t(uint8_t method_)44 zmq::socks_greeting_t::socks_greeting_t (uint8_t method_) : num_methods (1)
45 {
46     methods[0] = method_;
47 }
48 
socks_greeting_t(const uint8_t * methods_,uint8_t num_methods_)49 zmq::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 
socks_greeting_encoder_t()57 zmq::socks_greeting_encoder_t::socks_greeting_encoder_t () :
58     _bytes_encoded (0),
59     _bytes_written (0)
60 {
61 }
62 
encode(const socks_greeting_t & greeting_)63 void 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 
output(fd_t fd_)76 int 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 
has_pending_data() const85 bool zmq::socks_greeting_encoder_t::has_pending_data () const
86 {
87     return _bytes_written < _bytes_encoded;
88 }
89 
reset()90 void zmq::socks_greeting_encoder_t::reset ()
91 {
92     _bytes_encoded = _bytes_written = 0;
93 }
94 
socks_choice_t(unsigned char method_)95 zmq::socks_choice_t::socks_choice_t (unsigned char method_) : method (method_)
96 {
97 }
98 
socks_choice_decoder_t()99 zmq::socks_choice_decoder_t::socks_choice_decoder_t () : _bytes_read (0)
100 {
101 }
102 
input(fd_t fd_)103 int 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 
message_ready() const115 bool zmq::socks_choice_decoder_t::message_ready () const
116 {
117     return _bytes_read == 2;
118 }
119 
decode()120 zmq::socks_choice_t zmq::socks_choice_decoder_t::decode ()
121 {
122     zmq_assert (message_ready ());
123     return socks_choice_t (_buf[1]);
124 }
125 
reset()126 void zmq::socks_choice_decoder_t::reset ()
127 {
128     _bytes_read = 0;
129 }
130 
131 
socks_basic_auth_request_t(const std::string & username_,const std::string & password_)132 zmq::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 
socks_basic_auth_request_encoder_t()142 zmq::socks_basic_auth_request_encoder_t::socks_basic_auth_request_encoder_t () :
143     _bytes_encoded (0),
144     _bytes_written (0)
145 {
146 }
147 
encode(const socks_basic_auth_request_t & req_)148 void 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 
output(fd_t fd_)164 int 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 
has_pending_data() const173 bool zmq::socks_basic_auth_request_encoder_t::has_pending_data () const
174 {
175     return _bytes_written < _bytes_encoded;
176 }
177 
reset()178 void zmq::socks_basic_auth_request_encoder_t::reset ()
179 {
180     _bytes_encoded = _bytes_written = 0;
181 }
182 
183 
socks_auth_response_t(uint8_t response_code_)184 zmq::socks_auth_response_t::socks_auth_response_t (uint8_t response_code_) :
185     response_code (response_code_)
186 {
187 }
188 
socks_auth_response_decoder_t()189 zmq::socks_auth_response_decoder_t::socks_auth_response_decoder_t () :
190     _bytes_read (0)
191 {
192 }
193 
input(fd_t fd_)194 int 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 
message_ready() const206 bool zmq::socks_auth_response_decoder_t::message_ready () const
207 {
208     return _bytes_read == 2;
209 }
210 
decode()211 zmq::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 
reset()217 void zmq::socks_auth_response_decoder_t::reset ()
218 {
219     _bytes_read = 0;
220 }
221 
222 
socks_request_t(uint8_t command_,std::string hostname_,uint16_t port_)223 zmq::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 
socks_request_encoder_t()233 zmq::socks_request_encoder_t::socks_request_encoder_t () :
234     _bytes_encoded (0),
235     _bytes_written (0)
236 {
237 }
238 
encode(const socks_request_t & req_)239 void 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 
output(fd_t fd_)289 int 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 
has_pending_data() const298 bool zmq::socks_request_encoder_t::has_pending_data () const
299 {
300     return _bytes_written < _bytes_encoded;
301 }
302 
reset()303 void zmq::socks_request_encoder_t::reset ()
304 {
305     _bytes_encoded = _bytes_written = 0;
306 }
307 
socks_response_t(uint8_t response_code_,const std::string & address_,uint16_t port_)308 zmq::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 
socks_response_decoder_t()317 zmq::socks_response_decoder_t::socks_response_decoder_t () : _bytes_read (0)
318 {
319 }
320 
input(fd_t fd_)321 int 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 
message_ready() const357 bool 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 
decode()372 zmq::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 
reset()378 void zmq::socks_response_decoder_t::reset ()
379 {
380     _bytes_read = 0;
381 }
382