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

« back to all changes in this revision

Viewing changes to src/openvpn/push.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
#ifdef HAVE_CONFIG_H
 
26
#include "config.h"
 
27
#elif defined(_MSC_VER)
 
28
#include "config-msvc.h"
 
29
#endif
 
30
 
 
31
#include "syshead.h"
 
32
 
 
33
#include "push.h"
 
34
#include "options.h"
 
35
#include "ssl.h"
 
36
#include "manage.h"
 
37
 
 
38
#include "memdbg.h"
 
39
 
 
40
#if P2MP
 
41
 
 
42
/*
 
43
 * Auth username/password
 
44
 *
 
45
 * Client received an authentication failed message from server.
 
46
 * Runs on client.
 
47
 */
 
48
void
 
49
receive_auth_failed (struct context *c, const struct buffer *buffer)
 
50
{
 
51
  msg (M_VERB0, "AUTH: Received control message: %s", BSTR(buffer));
 
52
  connection_list_set_no_advance(&c->options);
 
53
  if (c->options.pull)
 
54
    {
 
55
      switch (auth_retry_get ())
 
56
        {
 
57
        case AR_NONE:
 
58
          c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- Auth failure error */
 
59
          break;
 
60
        case AR_INTERACT:
 
61
          ssl_purge_auth (false);
 
62
        case AR_NOINTERACT:
 
63
          c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Auth failure error */
 
64
          break;
 
65
        default:
 
66
          ASSERT (0);
 
67
        }
 
68
      c->sig->signal_text = "auth-failure";
 
69
#ifdef ENABLE_MANAGEMENT
 
70
      if (management)
 
71
        {
 
72
          const char *reason = NULL;
 
73
          struct buffer buf = *buffer;
 
74
          if (buf_string_compare_advance (&buf, "AUTH_FAILED,") && BLEN (&buf))
 
75
            reason = BSTR (&buf);
 
76
          management_auth_failure (management, UP_TYPE_AUTH, reason);
 
77
        } else
 
78
#endif
 
79
        {
 
80
#ifdef ENABLE_CLIENT_CR
 
81
          struct buffer buf = *buffer;
 
82
          if (buf_string_match_head_str (&buf, "AUTH_FAILED,CRV1:") && BLEN (&buf))
 
83
            {
 
84
              buf_advance (&buf, 12); /* Length of "AUTH_FAILED," substring */
 
85
              ssl_put_auth_challenge (BSTR (&buf));
 
86
            }
 
87
#endif
 
88
        }
 
89
    }
 
90
}
 
91
 
 
92
/*
 
93
 * Act on received restart message from server
 
94
 */
 
95
void
 
96
server_pushed_signal (struct context *c, const struct buffer *buffer, const bool restart, const int adv)
 
97
{
 
98
  if (c->options.pull)
 
99
    {
 
100
      struct buffer buf = *buffer;
 
101
      const char *m = "";
 
102
      if (buf_advance (&buf, adv) && buf_read_u8 (&buf) == ',' && BLEN (&buf))
 
103
        m = BSTR (&buf);
 
104
 
 
105
      /* preserve cached passwords? */
 
106
      {
 
107
        bool purge = true;
 
108
 
 
109
        if (m[0] == '[')
 
110
          {
 
111
            int i;
 
112
            for (i = 1; m[i] != '\0' && m[i] != ']'; ++i)
 
113
              {
 
114
                if (m[i] == 'P')
 
115
                  purge = false;
 
116
              }
 
117
          }
 
118
        if (purge)
 
119
          ssl_purge_auth (true);
 
120
      }
 
121
 
 
122
      if (restart)
 
123
        {
 
124
          msg (D_STREAM_ERRORS, "Connection reset command was pushed by server ('%s')", m);
 
125
          c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */
 
126
          c->sig->signal_text = "server-pushed-connection-reset";
 
127
        }
 
128
      else
 
129
        {
 
130
          msg (D_STREAM_ERRORS, "Halt command was pushed by server ('%s')", m);
 
131
          c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- server-pushed halt */
 
132
          c->sig->signal_text = "server-pushed-halt";
 
133
        }
 
134
#ifdef ENABLE_MANAGEMENT
 
135
      if (management)
 
136
        management_notify (management, "info", c->sig->signal_text, m);
 
137
#endif
 
138
    }
 
139
}
 
140
 
 
141
#if P2MP_SERVER
 
142
 
 
143
/*
 
144
 * Send auth failed message from server to client.
 
145
 */
 
146
void
 
147
send_auth_failed (struct context *c, const char *client_reason)
 
148
{
 
149
  struct gc_arena gc = gc_new ();
 
150
  static const char auth_failed[] = "AUTH_FAILED";
 
151
  size_t len;
 
152
 
 
153
  schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM);
 
154
 
 
155
  len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed);
 
156
  if (len > PUSH_BUNDLE_SIZE)
 
157
    len = PUSH_BUNDLE_SIZE;
 
158
 
 
159
  {
 
160
    struct buffer buf = alloc_buf_gc (len, &gc);
 
161
    buf_printf (&buf, auth_failed);
 
162
    if (client_reason)
 
163
      buf_printf (&buf, ",%s", client_reason);
 
164
    send_control_channel_string (c, BSTR (&buf), D_PUSH);
 
165
  }
 
166
 
 
167
  gc_free (&gc);
 
168
}
 
169
 
 
170
/*
 
171
 * Send restart message from server to client.
 
172
 */
 
173
void
 
174
send_restart (struct context *c, const char *kill_msg)
 
175
{
 
176
  schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM);
 
177
  send_control_channel_string (c, kill_msg ? kill_msg : "RESTART", D_PUSH);
 
178
}
 
179
 
 
180
#endif
 
181
 
 
182
/*
 
183
 * Push/Pull
 
184
 */
 
185
 
 
186
void
 
187
incoming_push_message (struct context *c, const struct buffer *buffer)
 
188
{
 
189
  struct gc_arena gc = gc_new ();
 
190
  unsigned int option_types_found = 0;
 
191
  int status;
 
192
 
 
193
  msg (D_PUSH, "PUSH: Received control message: '%s'", sanitize_control_message(BSTR(buffer), &gc));
 
194
 
 
195
  status = process_incoming_push_msg (c,
 
196
                                      buffer,
 
197
                                      c->options.pull,
 
198
                                      pull_permission_mask (c),
 
199
                                      &option_types_found);
 
200
 
 
201
  if (status == PUSH_MSG_ERROR)
 
202
    msg (D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", sanitize_control_message(BSTR(buffer), &gc));
 
203
  else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION)
 
204
    {
 
205
      if (status == PUSH_MSG_REPLY)
 
206
        do_up (c, true, option_types_found); /* delay bringing tun/tap up until --push parms received from remote */
 
207
      event_timeout_clear (&c->c2.push_request_interval);
 
208
    }
 
209
 
 
210
  gc_free (&gc);
 
211
}
 
212
 
 
213
bool
 
214
send_push_request (struct context *c)
 
215
{
 
216
  const int max_push_requests = c->options.handshake_window / PUSH_REQUEST_INTERVAL;
 
217
  if (++c->c2.n_sent_push_requests <= max_push_requests)
 
218
    {
 
219
      return send_control_channel_string (c, "PUSH_REQUEST", D_PUSH);
 
220
    }
 
221
  else
 
222
    {
 
223
      msg (D_STREAM_ERRORS, "No reply from server after sending %d push requests", max_push_requests);
 
224
      c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */
 
225
      c->sig->signal_text = "no-push-reply";
 
226
      return false;
 
227
    }
 
228
}
 
229
 
 
230
#if P2MP_SERVER
 
231
 
 
232
bool
 
233
send_push_reply (struct context *c)
 
234
{
 
235
  struct gc_arena gc = gc_new ();
 
236
  struct buffer buf = alloc_buf_gc (PUSH_BUNDLE_SIZE, &gc);
 
237
  struct push_entry *e = c->options.push_list.head;
 
238
  bool multi_push = false;
 
239
  static char cmd[] = "PUSH_REPLY";
 
240
  const int extra = 84; /* extra space for possible trailing ifconfig and push-continuation */
 
241
  const int safe_cap = BCAP (&buf) - extra;
 
242
  bool push_sent = false;
 
243
 
 
244
  msg( M_INFO, "send_push_reply(): safe_cap=%d", safe_cap );
 
245
 
 
246
  buf_printf (&buf, "%s", cmd);
 
247
 
 
248
  if ( c->c2.push_ifconfig_ipv6_defined )
 
249
    {
 
250
      /* IPv6 is put into buffer first, could be lengthy */
 
251
      buf_printf( &buf, ",ifconfig-ipv6 %s/%d %s",
 
252
                    print_in6_addr( c->c2.push_ifconfig_ipv6_local, 0, &gc),
 
253
                    c->c2.push_ifconfig_ipv6_netbits,
 
254
                    print_in6_addr( c->c2.push_ifconfig_ipv6_remote, 0, &gc) );
 
255
      if (BLEN (&buf) >= safe_cap)
 
256
        {
 
257
          msg (M_WARN, "--push ifconfig-ipv6 option is too long");
 
258
          goto fail;
 
259
        }
 
260
    }
 
261
 
 
262
  while (e)
 
263
    {
 
264
      if (e->enable)
 
265
        {
 
266
          const int l = strlen (e->option);
 
267
          if (BLEN (&buf) + l >= safe_cap)
 
268
            {
 
269
              buf_printf (&buf, ",push-continuation 2");
 
270
              {
 
271
                const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
 
272
                if (!status)
 
273
                  goto fail;
 
274
                push_sent = true;
 
275
                multi_push = true;
 
276
                buf_reset_len (&buf);
 
277
                buf_printf (&buf, "%s", cmd);
 
278
              }
 
279
            }
 
280
          if (BLEN (&buf) + l >= safe_cap)
 
281
            {
 
282
              msg (M_WARN, "--push option is too long");
 
283
              goto fail;
 
284
            }
 
285
          buf_printf (&buf, ",%s", e->option);
 
286
        }
 
287
      e = e->next;
 
288
    }
 
289
 
 
290
  if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask)
 
291
    {
 
292
      in_addr_t ifconfig_local = c->c2.push_ifconfig_local;
 
293
#ifdef ENABLE_CLIENT_NAT
 
294
      if (c->c2.push_ifconfig_local_alias)
 
295
        ifconfig_local = c->c2.push_ifconfig_local_alias;
 
296
#endif
 
297
      buf_printf (&buf, ",ifconfig %s %s",
 
298
                  print_in_addr_t (ifconfig_local, 0, &gc),
 
299
                  print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc));
 
300
    }
 
301
  if (multi_push)
 
302
    buf_printf (&buf, ",push-continuation 1");
 
303
 
 
304
  if (BLEN (&buf) > sizeof(cmd)-1)
 
305
    {
 
306
      const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
 
307
      if (!status)
 
308
        goto fail;
 
309
      push_sent = true;
 
310
    }
 
311
 
 
312
  /* If nothing have been pushed, send an empty push,
 
313
   * as the client is expecting a response
 
314
   */
 
315
  if (!push_sent)
 
316
    {
 
317
      bool status = false;
 
318
 
 
319
      buf_reset_len (&buf);
 
320
      buf_printf (&buf, "%s", cmd);
 
321
      status = send_control_channel_string (c, BSTR(&buf), D_PUSH);
 
322
      if (!status)
 
323
        goto fail;
 
324
    }
 
325
 
 
326
  gc_free (&gc);
 
327
  return true;
 
328
 
 
329
 fail:
 
330
  gc_free (&gc);
 
331
  return false;
 
332
}
 
333
 
 
334
static void
 
335
push_option_ex (struct options *o, const char *opt, bool enable, int msglevel)
 
336
{
 
337
  if (!string_class (opt, CC_ANY, CC_COMMA))
 
338
    {
 
339
      msg (msglevel, "PUSH OPTION FAILED (illegal comma (',') in string): '%s'", opt);
 
340
    }
 
341
  else
 
342
    {
 
343
      struct push_entry *e;
 
344
      ALLOC_OBJ_CLEAR_GC (e, struct push_entry, &o->gc);
 
345
      e->enable = true;
 
346
      e->option = opt;
 
347
      if (o->push_list.head)
 
348
        {
 
349
          ASSERT(o->push_list.tail);
 
350
          o->push_list.tail->next = e;
 
351
          o->push_list.tail = e;
 
352
        }
 
353
      else
 
354
        {
 
355
          ASSERT(!o->push_list.tail);
 
356
          o->push_list.head = e;
 
357
          o->push_list.tail = e;
 
358
        }
 
359
    }
 
360
}
 
361
 
 
362
void
 
363
push_option (struct options *o, const char *opt, int msglevel)
 
364
{
 
365
  push_option_ex (o, opt, true, msglevel);
 
366
}
 
367
 
 
368
void
 
369
clone_push_list (struct options *o)
 
370
{
 
371
  if (o->push_list.head)
 
372
    {
 
373
      const struct push_entry *e = o->push_list.head;
 
374
      push_reset (o);
 
375
      while (e)
 
376
        {
 
377
          push_option_ex (o, string_alloc (e->option, &o->gc), true, M_FATAL);
 
378
          e = e->next;
 
379
        }
 
380
    }
 
381
}
 
382
 
 
383
void
 
384
push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc)
 
385
{
 
386
  const char **argv = make_extended_arg_array (p, gc);
 
387
  char *opt = print_argv (argv, gc, 0);
 
388
  push_option (o, opt, msglevel);
 
389
}
 
390
 
 
391
void
 
392
push_reset (struct options *o)
 
393
{
 
394
  CLEAR (o->push_list);
 
395
}
 
396
#endif
 
397
 
 
398
int
 
399
process_incoming_push_msg (struct context *c,
 
400
                           const struct buffer *buffer,
 
401
                           bool honor_received_options,
 
402
                           unsigned int permission_mask,
 
403
                           unsigned int *option_types_found)
 
404
{
 
405
  int ret = PUSH_MSG_ERROR;
 
406
  struct buffer buf = *buffer;
 
407
 
 
408
#if P2MP_SERVER
 
409
  if (buf_string_compare_advance (&buf, "PUSH_REQUEST"))
 
410
    {
 
411
      if (tls_authentication_status (c->c2.tls_multi, 0) == TLS_AUTHENTICATION_FAILED || c->c2.context_auth == CAS_FAILED)
 
412
        {
 
413
          const char *client_reason = tls_client_reason (c->c2.tls_multi);
 
414
          send_auth_failed (c, client_reason);
 
415
          ret = PUSH_MSG_AUTH_FAILURE;
 
416
        }
 
417
      else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED)
 
418
        {
 
419
          time_t now;
 
420
 
 
421
          openvpn_time(&now);
 
422
          if (c->c2.sent_push_reply_expiry > now)
 
423
            {
 
424
              ret = PUSH_MSG_ALREADY_REPLIED;
 
425
            }
 
426
          else
 
427
            {
 
428
              if (send_push_reply (c))
 
429
                {
 
430
                  ret = PUSH_MSG_REQUEST;
 
431
                  c->c2.sent_push_reply_expiry = now + 30;
 
432
                }
 
433
            }
 
434
        }
 
435
      else
 
436
        {
 
437
          ret = PUSH_MSG_REQUEST_DEFERRED;
 
438
        }
 
439
    }
 
440
  else
 
441
#endif
 
442
 
 
443
  if (honor_received_options && buf_string_compare_advance (&buf, "PUSH_REPLY"))
 
444
    {
 
445
      const uint8_t ch = buf_read_u8 (&buf);
 
446
      if (ch == ',')
 
447
        {
 
448
          struct buffer buf_orig = buf;
 
449
          if (!c->c2.pulled_options_md5_init_done)
 
450
            {
 
451
              md5_state_init (&c->c2.pulled_options_state);
 
452
              c->c2.pulled_options_md5_init_done = true;
 
453
            }
 
454
          if (!c->c2.did_pre_pull_restore)
 
455
            {
 
456
              pre_pull_restore (&c->options);
 
457
              c->c2.did_pre_pull_restore = true;
 
458
            }
 
459
          if (apply_push_options (&c->options,
 
460
                                  &buf,
 
461
                                  permission_mask,
 
462
                                  option_types_found,
 
463
                                  c->c2.es))
 
464
            switch (c->options.push_continuation)
 
465
              {
 
466
              case 0:
 
467
              case 1:
 
468
                md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig));
 
469
                md5_state_final (&c->c2.pulled_options_state, &c->c2.pulled_options_digest);
 
470
                c->c2.pulled_options_md5_init_done = false;
 
471
                ret = PUSH_MSG_REPLY;
 
472
                break;
 
473
              case 2:
 
474
                md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig));
 
475
                ret = PUSH_MSG_CONTINUATION;
 
476
                break;
 
477
              }
 
478
        }
 
479
      else if (ch == '\0')
 
480
        {
 
481
          ret = PUSH_MSG_REPLY;
 
482
        }
 
483
      /* show_settings (&c->options); */
 
484
    }
 
485
  return ret;
 
486
}
 
487
 
 
488
#if P2MP_SERVER
 
489
 
 
490
/*
 
491
 * Remove iroutes from the push_list.
 
492
 */
 
493
void
 
494
remove_iroutes_from_push_route_list (struct options *o)
 
495
{
 
496
  if (o && o->push_list.head && o->iroutes)
 
497
    {
 
498
      struct gc_arena gc = gc_new ();
 
499
      struct push_entry *e = o->push_list.head;
 
500
 
 
501
      /* cycle through the push list */
 
502
      while (e)
 
503
        {
 
504
          char *p[MAX_PARMS];
 
505
          bool enable = true;
 
506
 
 
507
          /* parse the push item */
 
508
          CLEAR (p);
 
509
          if (parse_line (e->option, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
 
510
            {
 
511
              /* is the push item a route directive? */
 
512
              if (p[0] && !strcmp (p[0], "route") && !p[3])
 
513
                {
 
514
                  /* get route parameters */
 
515
                  bool status1, status2;
 
516
                  const in_addr_t network = getaddr (GETADDR_HOST_ORDER, p[1], 0, &status1, NULL);
 
517
                  const in_addr_t netmask = getaddr (GETADDR_HOST_ORDER, p[2] ? p[2] : "255.255.255.255", 0, &status2, NULL);
 
518
 
 
519
                  /* did route parameters parse correctly? */
 
520
                  if (status1 && status2)
 
521
                    {
 
522
                      const struct iroute *ir;
 
523
 
 
524
                      /* does route match an iroute? */
 
525
                      for (ir = o->iroutes; ir != NULL; ir = ir->next)
 
526
                        {
 
527
                          if (network == ir->network && netmask == netbits_to_netmask (ir->netbits >= 0 ? ir->netbits : 32))
 
528
                            {
 
529
                              enable = false;
 
530
                              break;
 
531
                            }
 
532
                        }
 
533
                    }
 
534
                }
 
535
            }
 
536
 
 
537
          /* should we copy the push item? */
 
538
          e->enable = enable;
 
539
          if (!enable)
 
540
            msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", e->option);
 
541
 
 
542
          e = e->next;
 
543
        }
 
544
 
 
545
      gc_free (&gc);
 
546
    }
 
547
}
 
548
 
 
549
#endif
 
550
 
 
551
#endif