~ubuntu-branches/ubuntu/saucy/openvpn/saucy-proposed

« back to all changes in this revision

Viewing changes to src/openvpn/socks.c

  • Committer: Package Import Robot
  • Author(s): Stéphane Graber
  • Date: 2013-05-24 17:42:45 UTC
  • mfrom: (1.1.19) (10.2.22 sid)
  • Revision ID: package-import@ubuntu.com-20130524174245-g9y6wlforycufqy5
Tags: 2.3.1-2ubuntu1
* Merge from Debian unstable. Remaining changes:
  - debian/openvpn.init.d:
    + Do not use start-stop-daemon and </dev/null to avoid blocking boot.
    + Show per-VPN result messages.
    + Add "--script-security 2" by default for backwards compatabliity.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  OpenVPN -- An application to securely tunnel IP networks
 
3
 *             over a single TCP/UDP port, with support for SSL/TLS-based
 
4
 *             session authentication and key exchange,
 
5
 *             packet encryption, packet authentication, and
 
6
 *             packet compression.
 
7
 *
 
8
 *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License version 2
 
12
 *  as published by the Free Software Foundation.
 
13
 *
 
14
 *  This program is distributed in the hope that it will be useful,
 
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 *  GNU General Public License for more details.
 
18
 *
 
19
 *  You should have received a copy of the GNU General Public License
 
20
 *  along with this program (see the file COPYING included with this
 
21
 *  distribution); if not, write to the Free Software Foundation, Inc.,
 
22
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
23
 */
 
24
 
 
25
/*
 
26
 * 2004-01-30: Added Socks5 proxy support, see RFC 1928
 
27
 *   (Christof Meerwald, http://cmeerw.org)
 
28
 *
 
29
 * 2010-10-10: Added Socks5 plain text authentication support (RFC 1929)
 
30
 *   (Pierre Bourdon <delroth@gmail.com>)
 
31
 */
 
32
 
 
33
#ifdef HAVE_CONFIG_H
 
34
#include "config.h"
 
35
#elif defined(_MSC_VER)
 
36
#include "config-msvc.h"
 
37
#endif
 
38
 
 
39
#include "syshead.h"
 
40
 
 
41
#ifdef ENABLE_SOCKS
 
42
 
 
43
#include "common.h"
 
44
#include "misc.h"
 
45
#include "win32.h"
 
46
#include "socket.h"
 
47
#include "fdmisc.h"
 
48
#include "misc.h"
 
49
#include "proxy.h"
 
50
 
 
51
#include "memdbg.h"
 
52
 
 
53
#define UP_TYPE_SOCKS           "SOCKS Proxy"
 
54
 
 
55
void
 
56
socks_adjust_frame_parameters (struct frame *frame, int proto)
 
57
{
 
58
  if (proto == PROTO_UDPv4)
 
59
    frame_add_to_extra_link (frame, 10);
 
60
}
 
61
 
 
62
struct socks_proxy_info *
 
63
socks_proxy_new (const char *server,
 
64
                 int port,
 
65
                 const char *authfile,
 
66
                 bool retry)
 
67
{
 
68
  struct socks_proxy_info *p;
 
69
 
 
70
  ALLOC_OBJ_CLEAR (p, struct socks_proxy_info);
 
71
 
 
72
  ASSERT (server);
 
73
  ASSERT (legal_ipv4_port (port));
 
74
 
 
75
  strncpynt (p->server, server, sizeof (p->server));
 
76
  p->port = port;
 
77
 
 
78
  if (authfile)
 
79
    strncpynt (p->authfile, authfile, sizeof (p->authfile));
 
80
  else
 
81
    p->authfile[0] = 0;
 
82
 
 
83
  p->retry = retry;
 
84
  p->defined = true;
 
85
 
 
86
  return p;
 
87
}
 
88
 
 
89
void
 
90
socks_proxy_close (struct socks_proxy_info *sp)
 
91
{
 
92
  free (sp);
 
93
}
 
94
 
 
95
static bool
 
96
socks_username_password_auth (struct socks_proxy_info *p,
 
97
                              socket_descriptor_t sd,
 
98
                              volatile int *signal_received)
 
99
{
 
100
  char to_send[516];
 
101
  char buf[2];
 
102
  int len = 0;
 
103
  const int timeout_sec = 5;
 
104
  struct user_pass creds;
 
105
  ssize_t size;
 
106
 
 
107
  creds.defined = 0;
 
108
  get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT);
 
109
 
 
110
  if( !creds.username || (strlen(creds.username) > 255)
 
111
      || !creds.password || (strlen(creds.password) > 255) ) {
 
112
          msg (M_NONFATAL,
 
113
               "SOCKS username and/or password exceeds 255 characters.  "
 
114
               "Authentication not possible.");
 
115
          return false;
 
116
  }
 
117
  openvpn_snprintf (to_send, sizeof (to_send), "\x01%c%s%c%s", (int) strlen(creds.username),
 
118
            creds.username, (int) strlen(creds.password), creds.password);
 
119
  size = send (sd, to_send, strlen(to_send), MSG_NOSIGNAL);
 
120
 
 
121
  if (size != strlen (to_send))
 
122
    {
 
123
      msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port write failed on send()");
 
124
      return false;
 
125
    }
 
126
 
 
127
  while (len < 2)
 
128
    {
 
129
      int status;
 
130
      ssize_t size;
 
131
      fd_set reads;
 
132
      struct timeval tv;
 
133
      char c;
 
134
 
 
135
      FD_ZERO (&reads);
 
136
      FD_SET (sd, &reads);
 
137
      tv.tv_sec = timeout_sec;
 
138
      tv.tv_usec = 0;
 
139
 
 
140
      status = select (sd + 1, &reads, NULL, NULL, &tv);
 
141
 
 
142
      get_signal (signal_received);
 
143
      if (*signal_received)
 
144
        return false;
 
145
 
 
146
      /* timeout? */
 
147
      if (status == 0)
 
148
        {
 
149
          msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read timeout expired");
 
150
          return false;
 
151
        }
 
152
 
 
153
      /* error */
 
154
      if (status < 0)
 
155
        {
 
156
          msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on select()");
 
157
          return false;
 
158
        }
 
159
 
 
160
      /* read single char */
 
161
      size = recv(sd, &c, 1, MSG_NOSIGNAL);
 
162
 
 
163
      /* error? */
 
164
      if (size != 1)
 
165
        {
 
166
          msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on recv()");
 
167
          return false;
 
168
        }
 
169
 
 
170
      /* store char in buffer */
 
171
      buf[len++] = c;
 
172
    }
 
173
 
 
174
  /* VER = 5, SUCCESS = 0 --> auth success */
 
175
  if (buf[0] != 5 && buf[1] != 0)
 
176
  {
 
177
    msg (D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication");
 
178
    return false;
 
179
  }
 
180
 
 
181
  return true;
 
182
}
 
183
 
 
184
static bool
 
185
socks_handshake (struct socks_proxy_info *p,
 
186
                 socket_descriptor_t sd,
 
187
                 volatile int *signal_received)
 
188
{
 
189
  char buf[2];
 
190
  int len = 0;
 
191
  const int timeout_sec = 5;
 
192
 
 
193
  /* VER = 5, NMETHODS = 2, METHODS = [0 (no auth), 2 (plain login)] */
 
194
  const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL);
 
195
  if (size != 4)
 
196
    {
 
197
      msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port write failed on send()");
 
198
      return false;
 
199
    }
 
200
 
 
201
  while (len < 2)
 
202
    {
 
203
      int status;
 
204
      ssize_t size;
 
205
      fd_set reads;
 
206
      struct timeval tv;
 
207
      char c;
 
208
 
 
209
      FD_ZERO (&reads);
 
210
      FD_SET (sd, &reads);
 
211
      tv.tv_sec = timeout_sec;
 
212
      tv.tv_usec = 0;
 
213
 
 
214
      status = select (sd + 1, &reads, NULL, NULL, &tv);
 
215
 
 
216
      get_signal (signal_received);
 
217
      if (*signal_received)
 
218
        return false;
 
219
 
 
220
      /* timeout? */
 
221
      if (status == 0)
 
222
        {
 
223
          msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read timeout expired");
 
224
          return false;
 
225
        }
 
226
 
 
227
      /* error */
 
228
      if (status < 0)
 
229
        {
 
230
          msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on select()");
 
231
          return false;
 
232
        }
 
233
 
 
234
      /* read single char */
 
235
      size = recv(sd, &c, 1, MSG_NOSIGNAL);
 
236
 
 
237
      /* error? */
 
238
      if (size != 1)
 
239
        {
 
240
          msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on recv()");
 
241
          return false;
 
242
        }
 
243
 
 
244
      /* store char in buffer */
 
245
      buf[len++] = c;
 
246
    }
 
247
 
 
248
  /* VER == 5 */
 
249
  if (buf[0] != '\x05')
 
250
    {
 
251
      msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status");
 
252
      return false;
 
253
    }
 
254
 
 
255
  /* select the appropriate authentication method */
 
256
  switch (buf[1])
 
257
    {
 
258
    case 0: /* no authentication */
 
259
      break;
 
260
 
 
261
    case 2: /* login/password */
 
262
      if (!p->authfile[0])
 
263
      {
 
264
        msg(D_LINK_ERRORS, "socks_handshake: server asked for username/login auth but we were "
 
265
                           "not provided any credentials");
 
266
        return false;
 
267
      }
 
268
 
 
269
      if (!socks_username_password_auth(p, sd, signal_received))
 
270
        return false;
 
271
 
 
272
      break;
 
273
 
 
274
    default: /* unknown auth method */
 
275
      msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method");
 
276
      return false;
 
277
    }
 
278
 
 
279
  return true;
 
280
}
 
281
 
 
282
static bool
 
283
recv_socks_reply (socket_descriptor_t sd,
 
284
                  struct openvpn_sockaddr *addr,
 
285
                  volatile int *signal_received)
 
286
{
 
287
  char atyp = '\0';
 
288
  int alen = 0;
 
289
  int len = 0;
 
290
  char buf[22];
 
291
  const int timeout_sec = 5;
 
292
 
 
293
  if (addr != NULL)
 
294
    {
 
295
      addr->addr.in4.sin_family = AF_INET;
 
296
      addr->addr.in4.sin_addr.s_addr = htonl (INADDR_ANY);
 
297
      addr->addr.in4.sin_port = htons (0);
 
298
    }
 
299
 
 
300
  while (len < 4 + alen + 2)
 
301
    {
 
302
      int status;
 
303
      ssize_t size;
 
304
      fd_set reads;
 
305
      struct timeval tv;
 
306
      char c;
 
307
 
 
308
      FD_ZERO (&reads);
 
309
      FD_SET (sd, &reads);
 
310
      tv.tv_sec = timeout_sec;
 
311
      tv.tv_usec = 0;
 
312
 
 
313
      status = select (sd + 1, &reads, NULL, NULL, &tv);
 
314
 
 
315
      get_signal (signal_received);
 
316
      if (*signal_received)
 
317
        return false;
 
318
 
 
319
      /* timeout? */
 
320
      if (status == 0)
 
321
        {
 
322
          msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read timeout expired");
 
323
          return false;
 
324
        }
 
325
 
 
326
      /* error */
 
327
      if (status < 0)
 
328
        {
 
329
          msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on select()");
 
330
          return false;
 
331
        }
 
332
 
 
333
      /* read single char */
 
334
      size = recv(sd, &c, 1, MSG_NOSIGNAL);
 
335
 
 
336
      /* error? */
 
337
      if (size != 1)
 
338
        {
 
339
          msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on recv()");
 
340
          return false;
 
341
        }
 
342
 
 
343
      if (len == 3)
 
344
        atyp = c;
 
345
 
 
346
      if (len == 4)
 
347
        {
 
348
          switch (atyp)
 
349
            {
 
350
            case '\x01':        /* IP V4 */
 
351
              alen = 4;
 
352
              break;
 
353
 
 
354
            case '\x03':        /* DOMAINNAME */
 
355
              alen = (unsigned char) c;
 
356
              break;
 
357
 
 
358
            case '\x04':        /* IP V6 */
 
359
              alen = 16;
 
360
              break;
 
361
 
 
362
            default:
 
363
              msg (D_LINK_ERRORS, "recv_socks_reply: Socks proxy returned bad address type");
 
364
              return false;
 
365
            }
 
366
        }
 
367
 
 
368
      /* store char in buffer */
 
369
      if (len < (int)sizeof(buf))
 
370
        buf[len] = c;
 
371
      ++len;
 
372
    }
 
373
 
 
374
  /* VER == 5 && REP == 0 (succeeded) */
 
375
  if (buf[0] != '\x05' || buf[1] != '\x00')
 
376
    {
 
377
      msg (D_LINK_ERRORS, "recv_socks_reply: Socks proxy returned bad reply");
 
378
      return false;
 
379
    }
 
380
 
 
381
  /* ATYP == 1 (IP V4 address) */
 
382
  if (atyp == '\x01' && addr != NULL)
 
383
    {
 
384
      memcpy (&addr->addr.in4.sin_addr, buf + 4, sizeof (addr->addr.in4.sin_addr));
 
385
      memcpy (&addr->addr.in4.sin_port, buf + 8, sizeof (addr->addr.in4.sin_port));
 
386
    }
 
387
 
 
388
 
 
389
  return true;
 
390
}
 
391
 
 
392
void
 
393
establish_socks_proxy_passthru (struct socks_proxy_info *p,
 
394
                                socket_descriptor_t sd, /* already open to proxy */
 
395
                                const char *host,       /* openvpn server remote */
 
396
                                const int port,         /* openvpn server port */
 
397
                                volatile int *signal_received)
 
398
{
 
399
  char buf[128];
 
400
  size_t len;
 
401
 
 
402
  if (!socks_handshake (p, sd, signal_received))
 
403
    goto error;
 
404
 
 
405
  /* format Socks CONNECT message */
 
406
  buf[0] = '\x05';              /* VER = 5 */
 
407
  buf[1] = '\x01';              /* CMD = 1 (CONNECT) */
 
408
  buf[2] = '\x00';              /* RSV */
 
409
  buf[3] = '\x03';              /* ATYP = 3 (DOMAINNAME) */
 
410
 
 
411
  len = strlen(host);
 
412
  len = (5 + len + 2 > sizeof(buf)) ? (sizeof(buf) - 5 - 2) : len;
 
413
 
 
414
  buf[4] = (char) len;
 
415
  memcpy(buf + 5, host, len);
 
416
 
 
417
  buf[5 + len] = (char) (port >> 8);
 
418
  buf[5 + len + 1] = (char) (port & 0xff);
 
419
 
 
420
  {
 
421
    const ssize_t size = send (sd, buf, 5 + len + 2, MSG_NOSIGNAL);
 
422
    if ((int)size != 5 + (int)len + 2)
 
423
      {
 
424
        msg (D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");
 
425
        goto error;
 
426
      }
 
427
  }
 
428
 
 
429
  /* receive reply from Socks proxy and discard */
 
430
  if (!recv_socks_reply (sd, NULL, signal_received))
 
431
    goto error;
 
432
 
 
433
  return;
 
434
 
 
435
 error:
 
436
  /* on error, should we exit or restart? */
 
437
  if (!*signal_received)
 
438
    *signal_received = (p->retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- socks error */
 
439
  return;
 
440
}
 
441
 
 
442
void
 
443
establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
 
444
                                socket_descriptor_t ctrl_sd, /* already open to proxy */
 
445
                                socket_descriptor_t udp_sd,
 
446
                                struct openvpn_sockaddr *relay_addr,
 
447
                                volatile int *signal_received)
 
448
{
 
449
  if (!socks_handshake (p, ctrl_sd, signal_received))
 
450
    goto error;
 
451
 
 
452
  {
 
453
    /* send Socks UDP ASSOCIATE message */
 
454
    /* VER = 5, CMD = 3 (UDP ASSOCIATE), RSV = 0, ATYP = 1 (IP V4),
 
455
       BND.ADDR = 0, BND.PORT = 0 */
 
456
    const ssize_t size = send (ctrl_sd,
 
457
                               "\x05\x03\x00\x01\x00\x00\x00\x00\x00\x00",
 
458
                               10, MSG_NOSIGNAL);
 
459
    if (size != 10)
 
460
      {
 
461
        msg (D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");
 
462
        goto error;
 
463
      }
 
464
  }
 
465
 
 
466
  /* receive reply from Socks proxy */
 
467
  CLEAR (*relay_addr);
 
468
  if (!recv_socks_reply (ctrl_sd, relay_addr, signal_received))
 
469
    goto error;
 
470
 
 
471
  return;
 
472
 
 
473
 error:
 
474
  /* on error, should we exit or restart? */
 
475
  if (!*signal_received)
 
476
    *signal_received = (p->retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- socks error */
 
477
  return;
 
478
}
 
479
 
 
480
/*
 
481
 * Remove the 10 byte socks5 header from an incoming
 
482
 * UDP packet, setting *from to the source address.
 
483
 *
 
484
 * Run after UDP read.
 
485
 */
 
486
void
 
487
socks_process_incoming_udp (struct buffer *buf,
 
488
                            struct link_socket_actual *from)
 
489
{
 
490
  int atyp;
 
491
 
 
492
  if (BLEN (buf) < 10)
 
493
    goto error;
 
494
 
 
495
  buf_read_u16 (buf);
 
496
  if (buf_read_u8 (buf) != 0)
 
497
    goto error;
 
498
 
 
499
  atyp = buf_read_u8 (buf);
 
500
  if (atyp != 1)                /* ATYP == 1 (IP V4) */
 
501
    goto error;
 
502
 
 
503
  buf_read (buf, &from->dest.addr.in4.sin_addr, sizeof (from->dest.addr.in4.sin_addr));
 
504
  buf_read (buf, &from->dest.addr.in4.sin_port, sizeof (from->dest.addr.in4.sin_port));
 
505
 
 
506
  return;
 
507
 
 
508
 error:
 
509
  buf->len = 0;
 
510
}
 
511
 
 
512
/*
 
513
 * Add a 10 byte socks header prior to UDP write.
 
514
 * *to is the destination address.
 
515
 *
 
516
 * Run before UDP write.
 
517
 * Returns the size of the header.
 
518
 */
 
519
int
 
520
socks_process_outgoing_udp (struct buffer *buf,
 
521
                            const struct link_socket_actual *to)
 
522
{
 
523
  /* 
 
524
   * Get a 10 byte subset buffer prepended to buf --
 
525
   * we expect these bytes will be here because
 
526
   * we allocated frame space in socks_adjust_frame_parameters.
 
527
   */
 
528
  struct buffer head = buf_sub (buf, 10, true);
 
529
 
 
530
  /* crash if not enough headroom in buf */
 
531
  ASSERT (buf_defined (&head));
 
532
 
 
533
  buf_write_u16 (&head, 0);     /* RSV = 0 */
 
534
  buf_write_u8 (&head, 0);      /* FRAG = 0 */
 
535
  buf_write_u8 (&head, '\x01'); /* ATYP = 1 (IP V4) */
 
536
  buf_write (&head, &to->dest.addr.in4.sin_addr, sizeof (to->dest.addr.in4.sin_addr));
 
537
  buf_write (&head, &to->dest.addr.in4.sin_port, sizeof (to->dest.addr.in4.sin_port));
 
538
 
 
539
  return 10;
 
540
}
 
541
 
 
542
#else
 
543
static void dummy(void) {}
 
544
#endif /* ENABLE_SOCKS */