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

« back to all changes in this revision

Viewing changes to manage.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
 
#include "syshead.h"
26
 
 
27
 
#ifdef ENABLE_MANAGEMENT
28
 
 
29
 
#include "error.h"
30
 
#include "fdmisc.h"
31
 
#include "options.h"
32
 
#include "sig.h"
33
 
#include "event.h"
34
 
#include "otime.h"
35
 
#include "integer.h"
36
 
#include "misc.h"
37
 
#include "ssl.h"
38
 
#include "common.h"
39
 
#include "manage.h"
40
 
 
41
 
#include "memdbg.h"
42
 
 
43
 
#ifdef ENABLE_PKCS11
44
 
#include "pkcs11.h"
45
 
#endif
46
 
 
47
 
#define MANAGEMENT_ECHO_PULL_INFO 0
48
 
 
49
 
#if MANAGEMENT_ECHO_PULL_INFO
50
 
#define MANAGEMENT_ECHO_FLAGS LOG_PRINT_INTVAL
51
 
#else
52
 
#define MANAGEMENT_ECHO_FLAGS 0
53
 
#endif
54
 
 
55
 
/* tag for blank username/password */
56
 
static const char blank_up[] = "[[BLANK]]";
57
 
 
58
 
struct management *management; /* GLOBAL */
59
 
 
60
 
/* static forward declarations */
61
 
static void man_output_standalone (struct management *man, volatile int *signal_received);
62
 
static void man_reset_client_socket (struct management *man, const bool exiting);
63
 
 
64
 
static void
65
 
man_help ()
66
 
{
67
 
  msg (M_CLIENT, "Management Interface for %s", title_string);
68
 
  msg (M_CLIENT, "Commands:");
69
 
  msg (M_CLIENT, "auth-retry t           : Auth failure retry mode (none,interact,nointeract).");
70
 
  msg (M_CLIENT, "bytecount n            : Show bytes in/out, update every n secs (0=off).");
71
 
  msg (M_CLIENT, "echo [on|off] [N|all]  : Like log, but only show messages in echo buffer.");
72
 
  msg (M_CLIENT, "exit|quit              : Close management session.");
73
 
  msg (M_CLIENT, "forget-passwords       : Forget passwords entered so far.");
74
 
  msg (M_CLIENT, "help                   : Print this message.");
75
 
  msg (M_CLIENT, "hold [on|off|release]  : Set/show hold flag to on/off state, or"); 
76
 
  msg (M_CLIENT, "                         release current hold and start tunnel."); 
77
 
  msg (M_CLIENT, "kill cn                : Kill the client instance(s) having common name cn.");
78
 
  msg (M_CLIENT, "kill IP:port           : Kill the client instance connecting from IP:port.");
79
 
  msg (M_CLIENT, "load-stats             : Show global server load stats.");
80
 
  msg (M_CLIENT, "log [on|off] [N|all]   : Turn on/off realtime log display");
81
 
  msg (M_CLIENT, "                         + show last N lines or 'all' for entire history.");
82
 
  msg (M_CLIENT, "mute [n]               : Set log mute level to n, or show level if n is absent.");
83
 
  msg (M_CLIENT, "needok type action     : Enter confirmation for NEED-OK request of 'type',");
84
 
  msg (M_CLIENT, "                         where action = 'ok' or 'cancel'.");
85
 
  msg (M_CLIENT, "needstr type action    : Enter confirmation for NEED-STR request of 'type',");
86
 
  msg (M_CLIENT, "                         where action is reply string.");
87
 
  msg (M_CLIENT, "net                    : (Windows only) Show network info and routing table.");
88
 
  msg (M_CLIENT, "password type p        : Enter password p for a queried OpenVPN password.");
89
 
  msg (M_CLIENT, "pid                    : Show process ID of the current OpenVPN process.");
90
 
#ifdef ENABLE_PKCS11
91
 
  msg (M_CLIENT, "pkcs11-id-count        : Get number of available PKCS#11 identities.");
92
 
  msg (M_CLIENT, "pkcs11-id-get index    : Get PKCS#11 identity at index.");
93
 
#endif
94
 
#ifdef MANAGEMENT_DEF_AUTH
95
 
  msg (M_CLIENT, "client-auth CID KID    : Authenticate client-id/key-id CID/KID (MULTILINE)");
96
 
  msg (M_CLIENT, "client-auth-nt CID KID : Authenticate client-id/key-id CID/KID");
97
 
  msg (M_CLIENT, "client-deny CID KID R [CR] : Deny auth client-id/key-id CID/KID with log reason");
98
 
  msg (M_CLIENT, "                             text R and optional client reason text CR");
99
 
  msg (M_CLIENT, "client-kill CID        : Kill client instance CID");
100
 
  msg (M_CLIENT, "env-filter [level]     : Set env-var filter level");
101
 
#ifdef MANAGEMENT_PF
102
 
  msg (M_CLIENT, "client-pf CID          : Define packet filter for client CID (MULTILINE)");
103
 
#endif
104
 
#endif
105
 
  msg (M_CLIENT, "signal s               : Send signal s to daemon,");
106
 
  msg (M_CLIENT, "                         s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2.");
107
 
  msg (M_CLIENT, "state [on|off] [N|all] : Like log, but show state history.");
108
 
  msg (M_CLIENT, "status [n]             : Show current daemon status info using format #n.");
109
 
  msg (M_CLIENT, "test n                 : Produce n lines of output for testing/debugging.");
110
 
  msg (M_CLIENT, "username type u        : Enter username u for a queried OpenVPN username.");
111
 
  msg (M_CLIENT, "verb [n]               : Set log verbosity level to n, or show if n is absent.");
112
 
  msg (M_CLIENT, "version                : Show current version number.");
113
 
#if HTTP_PROXY_FALLBACK
114
 
  msg (M_CLIENT, "http-proxy-fallback <server> <port> [flags] : Enter dynamic HTTP proxy fallback info.");
115
 
  msg (M_CLIENT, "http-proxy-fallback-disable : Disable HTTP proxy fallback.");
116
 
#endif
117
 
  msg (M_CLIENT, "END");
118
 
}
119
 
 
120
 
static const char *
121
 
man_state_name (const int state)
122
 
{
123
 
  switch (state)
124
 
    {
125
 
    case OPENVPN_STATE_INITIAL:
126
 
      return "INITIAL";
127
 
    case OPENVPN_STATE_CONNECTING:
128
 
      return "CONNECTING";
129
 
    case OPENVPN_STATE_WAIT:
130
 
      return "WAIT";
131
 
    case OPENVPN_STATE_AUTH:
132
 
      return "AUTH";
133
 
    case OPENVPN_STATE_GET_CONFIG:
134
 
      return "GET_CONFIG";
135
 
    case OPENVPN_STATE_ASSIGN_IP:
136
 
      return "ASSIGN_IP";
137
 
    case OPENVPN_STATE_ADD_ROUTES:
138
 
      return "ADD_ROUTES";
139
 
    case OPENVPN_STATE_CONNECTED:
140
 
      return "CONNECTED";
141
 
    case OPENVPN_STATE_RECONNECTING:
142
 
      return "RECONNECTING";
143
 
    case OPENVPN_STATE_EXITING:
144
 
      return "EXITING";
145
 
    case OPENVPN_STATE_RESOLVE:
146
 
      return "RESOLVE";
147
 
    case OPENVPN_STATE_TCP_CONNECT:
148
 
      return "TCP_CONNECT";
149
 
    default:
150
 
      return "?";
151
 
    }
152
 
}
153
 
 
154
 
static void
155
 
man_welcome (struct management *man)
156
 
{
157
 
  msg (M_CLIENT, ">INFO:OpenVPN Management Interface Version %d -- type 'help' for more info",
158
 
       MANAGEMENT_VERSION);
159
 
  if (man->persist.special_state_msg)
160
 
    msg (M_CLIENT, "%s", man->persist.special_state_msg);
161
 
}
162
 
 
163
 
static inline bool
164
 
man_password_needed (struct management *man)
165
 
{
166
 
  return man->settings.up.defined && !man->connection.password_verified;
167
 
}
168
 
 
169
 
static void
170
 
man_check_password (struct management *man, const char *line)
171
 
{
172
 
  if (man_password_needed (man))
173
 
    {
174
 
      if (streq (line, man->settings.up.password))
175
 
        {
176
 
          man->connection.password_verified = true;
177
 
          msg (M_CLIENT, "SUCCESS: password is correct");
178
 
          man_welcome (man);
179
 
        }
180
 
      else
181
 
        {
182
 
          man->connection.password_verified = false;
183
 
          msg (M_CLIENT, "ERROR: bad password");
184
 
          if (++man->connection.password_tries >= MANAGEMENT_N_PASSWORD_RETRIES)
185
 
            {
186
 
              msg (M_WARN, "MAN: client connection rejected after %d failed password attempts",
187
 
                   MANAGEMENT_N_PASSWORD_RETRIES);
188
 
              man->connection.halt = true;
189
 
            }
190
 
        }
191
 
    }
192
 
}
193
 
 
194
 
static void
195
 
man_update_io_state (struct management *man)
196
 
{
197
 
  if (socket_defined (man->connection.sd_cli))
198
 
    {
199
 
      if (buffer_list_defined (man->connection.out))
200
 
        {
201
 
          man->connection.state = MS_CC_WAIT_WRITE;
202
 
        }
203
 
      else
204
 
        {
205
 
          man->connection.state = MS_CC_WAIT_READ;
206
 
        }
207
 
    }
208
 
}
209
 
 
210
 
static void
211
 
man_output_list_push_finalize (struct management *man)
212
 
{
213
 
  if (management_connected (man))
214
 
    {
215
 
      man_update_io_state (man);
216
 
      if (!man->persist.standalone_disabled)
217
 
        {
218
 
          volatile int signal_received = 0;
219
 
          man_output_standalone (man, &signal_received);
220
 
        }
221
 
    }
222
 
}
223
 
 
224
 
static void
225
 
man_output_list_push_str (struct management *man, const char *str)
226
 
{
227
 
  if (management_connected (man) && str)
228
 
    {
229
 
      buffer_list_push (man->connection.out, (const unsigned char *) str);
230
 
    }
231
 
}
232
 
 
233
 
static void
234
 
man_output_list_push (struct management *man, const char *str)
235
 
{
236
 
  man_output_list_push_str (man, str);
237
 
  man_output_list_push_finalize (man);
238
 
}
239
 
 
240
 
static void
241
 
man_prompt (struct management *man)
242
 
{
243
 
  if (man_password_needed (man))
244
 
    man_output_list_push (man, "ENTER PASSWORD:");
245
 
#if 0 /* should we use prompt? */
246
 
  else
247
 
    man_output_list_push (man, ">");
248
 
#endif
249
 
}
250
 
 
251
 
static void
252
 
man_delete_unix_socket (struct management *man)
253
 
{
254
 
#if UNIX_SOCK_SUPPORT
255
 
  if ((man->settings.flags & (MF_UNIX_SOCK|MF_CONNECT_AS_CLIENT)) == MF_UNIX_SOCK)
256
 
    socket_delete_unix (&man->settings.local_unix);
257
 
#endif
258
 
}
259
 
 
260
 
static void
261
 
man_close_socket (struct management *man, const socket_descriptor_t sd)
262
 
{
263
 
#ifndef WIN32
264
 
  /*
265
 
   * Windows doesn't need this because the ne32 event is permanently
266
 
   * enabled at struct management scope.
267
 
   */
268
 
  if (man->persist.callback.delete_event)
269
 
    (*man->persist.callback.delete_event) (man->persist.callback.arg, sd);
270
 
#endif
271
 
  openvpn_close_socket (sd);
272
 
}
273
 
 
274
 
static void
275
 
virtual_output_callback_func (void *arg, const unsigned int flags, const char *str)
276
 
{
277
 
  struct management *man = (struct management *) arg;
278
 
  static int recursive_level = 0; /* GLOBAL */
279
 
  bool did_push = false;
280
 
 
281
 
  if (!recursive_level) /* don't allow recursion */
282
 
    {
283
 
      struct gc_arena gc = gc_new ();
284
 
      struct log_entry e;
285
 
      const char *out = NULL;
286
 
 
287
 
      ++recursive_level;
288
 
 
289
 
      CLEAR (e);
290
 
      update_time ();
291
 
      e.timestamp = now;
292
 
      e.u.msg_flags = flags;
293
 
      e.string = str;
294
 
 
295
 
      if (flags & M_FATAL)
296
 
        man->persist.standalone_disabled = false;
297
 
 
298
 
      if (flags != M_CLIENT)
299
 
        log_history_add (man->persist.log, &e);
300
 
 
301
 
      if (!man_password_needed (man))
302
 
        {
303
 
          if (flags == M_CLIENT)
304
 
            out = log_entry_print (&e, LOG_PRINT_CRLF, &gc);
305
 
          else if (man->connection.log_realtime)
306
 
            out = log_entry_print (&e, LOG_PRINT_INT_DATE
307
 
                                   |   LOG_PRINT_MSG_FLAGS
308
 
                                   |   LOG_PRINT_LOG_PREFIX
309
 
                                   |   LOG_PRINT_CRLF, &gc);
310
 
          if (out)
311
 
            {
312
 
              man_output_list_push_str (man, out);
313
 
              did_push = true;
314
 
            }
315
 
          if (flags & M_FATAL)
316
 
            {
317
 
              out = log_entry_print (&e, LOG_FATAL_NOTIFY|LOG_PRINT_CRLF, &gc);
318
 
              if (out)
319
 
                {
320
 
                  man_output_list_push_str (man, out);
321
 
                  did_push = true;
322
 
                  man_reset_client_socket (man, true);
323
 
                }
324
 
            }
325
 
        }
326
 
 
327
 
      --recursive_level;
328
 
      gc_free (&gc);
329
 
    }
330
 
 
331
 
  if (did_push)
332
 
    man_output_list_push_finalize (man);
333
 
}
334
 
 
335
 
/*
336
 
 * Given a signal, return the signal with possible remapping applied,
337
 
 * or -1 if the signal should be ignored.
338
 
 */
339
 
static int
340
 
man_mod_signal (const struct management *man, const int signum)
341
 
{
342
 
  const unsigned int flags = man->settings.mansig;
343
 
  int s = signum;
344
 
  if (s == SIGUSR1)
345
 
    {
346
 
      if (flags & MANSIG_MAP_USR1_TO_HUP)
347
 
        s = SIGHUP;
348
 
      if (flags & MANSIG_MAP_USR1_TO_TERM)
349
 
        s = SIGTERM;
350
 
    }
351
 
  if (flags & MANSIG_IGNORE_USR1_HUP)
352
 
    {
353
 
      if (s == SIGHUP || s == SIGUSR1)
354
 
        s = -1;
355
 
    }
356
 
  return s;
357
 
}
358
 
 
359
 
static void
360
 
man_signal (struct management *man, const char *name)
361
 
{
362
 
  const int sig = parse_signal (name);
363
 
  if (sig >= 0)
364
 
    {
365
 
      const int sig_mod = man_mod_signal (man, sig);
366
 
      if (sig_mod >= 0)
367
 
        {
368
 
          throw_signal (sig_mod);
369
 
          msg (M_CLIENT, "SUCCESS: signal %s thrown", signal_name (sig_mod, true));
370
 
        }
371
 
      else
372
 
        {
373
 
          if (man->persist.special_state_msg)
374
 
            msg (M_CLIENT, "%s", man->persist.special_state_msg);
375
 
          else
376
 
            msg (M_CLIENT, "ERROR: signal '%s' is currently ignored", name);
377
 
        }
378
 
    }
379
 
  else
380
 
    {
381
 
      msg (M_CLIENT, "ERROR: signal '%s' is not a known signal type", name);
382
 
    }
383
 
}
384
 
 
385
 
static void
386
 
man_status (struct management *man, const int version, struct status_output *so)
387
 
{
388
 
  if (man->persist.callback.status)
389
 
    {
390
 
      (*man->persist.callback.status) (man->persist.callback.arg, version, so);
391
 
    }
392
 
  else
393
 
    {
394
 
      msg (M_CLIENT, "ERROR: The 'status' command is not supported by the current daemon mode");
395
 
    }
396
 
}
397
 
 
398
 
static void
399
 
man_bytecount (struct management *man, const int update_seconds)
400
 
{
401
 
  if (update_seconds >= 0)
402
 
    man->connection.bytecount_update_seconds = update_seconds;
403
 
  else
404
 
    man->connection.bytecount_update_seconds = 0;
405
 
  msg (M_CLIENT, "SUCCESS: bytecount interval changed");
406
 
}
407
 
 
408
 
void
409
 
man_bytecount_output_client (struct management *man)
410
 
{
411
 
  char in[32];
412
 
  char out[32];
413
 
  /* do in a roundabout way to work around possible mingw or mingw-glibc bug */
414
 
  openvpn_snprintf (in, sizeof (in), counter_format, man->persist.bytes_in);
415
 
  openvpn_snprintf (out, sizeof (out), counter_format, man->persist.bytes_out);
416
 
  msg (M_CLIENT, ">BYTECOUNT:%s,%s", in, out);
417
 
  man->connection.bytecount_last_update = now;
418
 
}
419
 
 
420
 
#ifdef MANAGEMENT_DEF_AUTH
421
 
 
422
 
void
423
 
man_bytecount_output_server (struct management *man,
424
 
                             const counter_type *bytes_in_total,
425
 
                             const counter_type *bytes_out_total,
426
 
                             struct man_def_auth_context *mdac)
427
 
{
428
 
  char in[32];
429
 
  char out[32];
430
 
  /* do in a roundabout way to work around possible mingw or mingw-glibc bug */
431
 
  openvpn_snprintf (in, sizeof (in), counter_format, *bytes_in_total);
432
 
  openvpn_snprintf (out, sizeof (out), counter_format, *bytes_out_total);
433
 
  msg (M_CLIENT, ">BYTECOUNT_CLI:%lu,%s,%s", mdac->cid, in, out);
434
 
  mdac->bytecount_last_update = now;
435
 
}
436
 
 
437
 
#endif
438
 
 
439
 
static void
440
 
man_kill (struct management *man, const char *victim)
441
 
{
442
 
  struct gc_arena gc = gc_new ();
443
 
 
444
 
  if (man->persist.callback.kill_by_cn && man->persist.callback.kill_by_addr)
445
 
    {
446
 
      struct buffer buf;
447
 
      char p1[128];
448
 
      char p2[128];
449
 
      int n_killed;
450
 
 
451
 
      buf_set_read (&buf, (uint8_t*) victim, strlen (victim) + 1);
452
 
      buf_parse (&buf, ':', p1, sizeof (p1));
453
 
      buf_parse (&buf, ':', p2, sizeof (p2));
454
 
 
455
 
      if (strlen (p1) && strlen (p2))
456
 
        {
457
 
          /* IP:port specified */
458
 
          bool status;
459
 
          const in_addr_t addr = getaddr (GETADDR_HOST_ORDER|GETADDR_MSG_VIRT_OUT, p1, 0, &status, NULL);
460
 
          if (status)
461
 
            {
462
 
              const int port = atoi (p2);
463
 
              if (port > 0 && port < 65536)
464
 
                {
465
 
                  n_killed = (*man->persist.callback.kill_by_addr) (man->persist.callback.arg, addr, port);
466
 
                  if (n_killed > 0)
467
 
                    {
468
 
                      msg (M_CLIENT, "SUCCESS: %d client(s) at address %s:%d killed",
469
 
                           n_killed,
470
 
                           print_in_addr_t (addr, 0, &gc),
471
 
                           port);
472
 
                    }
473
 
                  else
474
 
                    {
475
 
                      msg (M_CLIENT, "ERROR: client at address %s:%d not found",
476
 
                           print_in_addr_t (addr, 0, &gc),
477
 
                           port);
478
 
                    }
479
 
                }
480
 
              else
481
 
                {
482
 
                  msg (M_CLIENT, "ERROR: port number is out of range: %s", p2);
483
 
                }
484
 
            }
485
 
          else
486
 
            {
487
 
              msg (M_CLIENT, "ERROR: error parsing IP address: %s", p1);
488
 
            }
489
 
        }
490
 
      else if (strlen (p1))
491
 
        {
492
 
          /* common name specified */
493
 
          n_killed = (*man->persist.callback.kill_by_cn) (man->persist.callback.arg, p1);
494
 
          if (n_killed > 0)
495
 
            {
496
 
              msg (M_CLIENT, "SUCCESS: common name '%s' found, %d client(s) killed", p1, n_killed);
497
 
            }
498
 
          else
499
 
            {
500
 
              msg (M_CLIENT, "ERROR: common name '%s' not found", p1);
501
 
            }
502
 
        }
503
 
      else
504
 
        {
505
 
          msg (M_CLIENT, "ERROR: kill parse");
506
 
        }
507
 
    }
508
 
  else
509
 
    {
510
 
      msg (M_CLIENT, "ERROR: The 'kill' command is not supported by the current daemon mode");
511
 
    }
512
 
 
513
 
  gc_free (&gc);
514
 
}
515
 
 
516
 
/*
517
 
 * General-purpose history command handler
518
 
 * for the log and echo commands.
519
 
 */
520
 
static void
521
 
man_history (struct management *man,
522
 
             const char *parm,
523
 
             const char *type,
524
 
             struct log_history *log,
525
 
             bool *realtime,
526
 
             const unsigned int lep_flags)
527
 
{
528
 
  struct gc_arena gc = gc_new ();
529
 
  int n = 0;
530
 
 
531
 
  if (streq (parm, "on"))
532
 
    {
533
 
      *realtime = true;
534
 
      msg (M_CLIENT, "SUCCESS: real-time %s notification set to ON", type);
535
 
    }
536
 
  else if (streq (parm, "off"))
537
 
    {
538
 
      *realtime = false;
539
 
      msg (M_CLIENT, "SUCCESS: real-time %s notification set to OFF", type);
540
 
    }
541
 
  else if (streq (parm, "all") || (n = atoi (parm)) > 0)
542
 
    {
543
 
      const int size = log_history_size (log);
544
 
      const int start = (n ? n : size) - 1;
545
 
      int i;
546
 
 
547
 
      for (i = start; i >= 0; --i)
548
 
        {
549
 
          const struct log_entry *e = log_history_ref (log, i);
550
 
          if (e)
551
 
            {
552
 
              const char *out = log_entry_print (e, lep_flags, &gc);
553
 
              virtual_output_callback_func (man, M_CLIENT, out);
554
 
            }
555
 
        }
556
 
      msg (M_CLIENT, "END");
557
 
    }
558
 
  else
559
 
    {
560
 
      msg (M_CLIENT, "ERROR: %s parameter must be 'on' or 'off' or some number n or 'all'", type);
561
 
    }
562
 
 
563
 
  gc_free (&gc);
564
 
}
565
 
 
566
 
static void
567
 
man_log (struct management *man, const char *parm)
568
 
{
569
 
  man_history (man,
570
 
               parm,
571
 
               "log",
572
 
               man->persist.log,
573
 
               &man->connection.log_realtime,
574
 
               LOG_PRINT_INT_DATE|LOG_PRINT_MSG_FLAGS);
575
 
}
576
 
 
577
 
static void
578
 
man_echo (struct management *man, const char *parm)
579
 
{
580
 
  man_history (man,
581
 
               parm,
582
 
               "echo",
583
 
               man->persist.echo,
584
 
               &man->connection.echo_realtime,
585
 
               LOG_PRINT_INT_DATE|MANAGEMENT_ECHO_FLAGS);
586
 
}
587
 
 
588
 
static void
589
 
man_state (struct management *man, const char *parm)
590
 
{
591
 
  man_history (man,
592
 
               parm,
593
 
               "state",
594
 
               man->persist.state,
595
 
               &man->connection.state_realtime,
596
 
               LOG_PRINT_INT_DATE|LOG_PRINT_STATE|
597
 
               LOG_PRINT_LOCAL_IP|LOG_PRINT_REMOTE_IP);
598
 
}
599
 
 
600
 
static void
601
 
man_up_finalize (struct management *man)
602
 
{
603
 
  switch (man->connection.up_query_mode)
604
 
    {
605
 
    case UP_QUERY_DISABLED:
606
 
      man->connection.up_query.defined = false;
607
 
      break;
608
 
    case UP_QUERY_USER_PASS:
609
 
      if (strlen (man->connection.up_query.username) && strlen (man->connection.up_query.password))
610
 
        man->connection.up_query.defined = true;
611
 
      break;
612
 
    case UP_QUERY_PASS:
613
 
      if (strlen (man->connection.up_query.password))
614
 
        man->connection.up_query.defined = true;
615
 
      break;
616
 
    case UP_QUERY_NEED_OK:
617
 
      if (strlen (man->connection.up_query.password))
618
 
        man->connection.up_query.defined = true;
619
 
      break;
620
 
    case UP_QUERY_NEED_STR:
621
 
      if (strlen (man->connection.up_query.password))
622
 
        man->connection.up_query.defined = true;
623
 
      break;
624
 
    default:
625
 
      ASSERT (0);
626
 
    }
627
 
}
628
 
 
629
 
static void
630
 
man_query_user_pass (struct management *man,
631
 
                     const char *type,
632
 
                     const char *string,
633
 
                     const bool needed,
634
 
                     const char *prompt,
635
 
                     char *dest,
636
 
                     int len)
637
 
{
638
 
  if (needed)
639
 
    {
640
 
      ASSERT (man->connection.up_query_type);
641
 
      if (streq (man->connection.up_query_type, type))
642
 
        {
643
 
          strncpynt (dest, string, len);
644
 
          man_up_finalize (man);
645
 
          msg (M_CLIENT, "SUCCESS: '%s' %s entered, but not yet verified",
646
 
               type,
647
 
               prompt);
648
 
        }
649
 
      else
650
 
        msg (M_CLIENT, "ERROR: %s of type '%s' entered, but we need one of type '%s'",
651
 
             prompt,
652
 
             type,
653
 
             man->connection.up_query_type);
654
 
    }
655
 
  else
656
 
    {
657
 
      msg (M_CLIENT, "ERROR: no %s is currently needed at this time", prompt);
658
 
    }
659
 
}
660
 
 
661
 
static void
662
 
man_query_username (struct management *man, const char *type, const char *string)
663
 
{
664
 
  const bool needed = (man->connection.up_query_mode == UP_QUERY_USER_PASS && man->connection.up_query_type);
665
 
  man_query_user_pass (man, type, string, needed, "username", man->connection.up_query.username, USER_PASS_LEN);
666
 
}
667
 
 
668
 
static void
669
 
man_query_password (struct management *man, const char *type, const char *string)
670
 
{
671
 
  const bool needed = ((man->connection.up_query_mode == UP_QUERY_USER_PASS
672
 
                        || man->connection.up_query_mode == UP_QUERY_PASS)
673
 
                       && man->connection.up_query_type);
674
 
  if (!string[0]) /* allow blank passwords to be passed through using the blank_up tag */
675
 
    string = blank_up;
676
 
  man_query_user_pass (man, type, string, needed, "password", man->connection.up_query.password, USER_PASS_LEN);
677
 
}
678
 
 
679
 
static void
680
 
man_query_need_ok (struct management *man, const char *type, const char *action)
681
 
{
682
 
  const bool needed = ((man->connection.up_query_mode == UP_QUERY_NEED_OK) && man->connection.up_query_type);
683
 
  man_query_user_pass (man, type, action, needed, "needok-confirmation", man->connection.up_query.password, USER_PASS_LEN);
684
 
}
685
 
 
686
 
static void
687
 
man_query_need_str (struct management *man, const char *type, const char *action)
688
 
{
689
 
  const bool needed = ((man->connection.up_query_mode == UP_QUERY_NEED_STR) && man->connection.up_query_type);
690
 
  man_query_user_pass (man, type, action, needed, "needstr-string", man->connection.up_query.password, USER_PASS_LEN);
691
 
}
692
 
 
693
 
static void
694
 
man_forget_passwords (struct management *man)
695
 
{
696
 
#if defined(USE_CRYPTO) && defined(USE_SSL)
697
 
  ssl_purge_auth ();
698
 
  msg (M_CLIENT, "SUCCESS: Passwords were forgotten");
699
 
#endif
700
 
}
701
 
 
702
 
static void
703
 
man_net (struct management *man)
704
 
{
705
 
  if (man->persist.callback.show_net)
706
 
    {
707
 
      (*man->persist.callback.show_net) (man->persist.callback.arg, M_CLIENT);
708
 
    }
709
 
  else
710
 
    {
711
 
      msg (M_CLIENT, "ERROR: The 'net' command is not supported by the current daemon mode");
712
 
    }
713
 
}
714
 
 
715
 
#ifdef ENABLE_PKCS11
716
 
 
717
 
static void
718
 
man_pkcs11_id_count (struct management *man)
719
 
{
720
 
  msg (M_CLIENT, ">PKCS11ID-COUNT:%d", pkcs11_management_id_count ());
721
 
}
722
 
 
723
 
static void
724
 
man_pkcs11_id_get (struct management *man, const int index)
725
 
{
726
 
  char *id = NULL;
727
 
  char *base64 = NULL;
728
 
 
729
 
  if (pkcs11_management_id_get (index, &id, &base64))
730
 
    msg (M_CLIENT, ">PKCS11ID-ENTRY:'%d', ID:'%s', BLOB:'%s'", index, id, base64);
731
 
  else
732
 
    msg (M_CLIENT, ">PKCS11ID-ENTRY:'%d'", index);
733
 
 
734
 
  if (id != NULL)
735
 
    free (id);
736
 
  if (base64 != NULL)
737
 
    free (base64);
738
 
}
739
 
 
740
 
#endif
741
 
 
742
 
static void
743
 
man_hold (struct management *man, const char *cmd)
744
 
{
745
 
  if (cmd)
746
 
    {
747
 
      if (streq (cmd, "on"))
748
 
        {
749
 
          man->settings.flags |= MF_HOLD;
750
 
          msg (M_CLIENT, "SUCCESS: hold flag set to ON");
751
 
        }
752
 
      else if (streq (cmd, "off"))
753
 
        {
754
 
          man->settings.flags &= ~MF_HOLD;
755
 
          msg (M_CLIENT, "SUCCESS: hold flag set to OFF");
756
 
        }
757
 
      else if (streq (cmd, "release"))
758
 
        {
759
 
          man->persist.hold_release = true;
760
 
          msg (M_CLIENT, "SUCCESS: hold release succeeded");
761
 
        }
762
 
      else
763
 
        {
764
 
          msg (M_CLIENT, "ERROR: bad hold command parameter");
765
 
        }
766
 
    }
767
 
  else
768
 
    msg (M_CLIENT, "SUCCESS: hold=%d", BOOL_CAST(man->settings.flags & MF_HOLD));
769
 
}
770
 
 
771
 
#ifdef MANAGEMENT_DEF_AUTH
772
 
 
773
 
static bool
774
 
parse_cid (const char *str, unsigned long *cid)
775
 
{
776
 
  if (sscanf (str, "%lu", cid) == 1)
777
 
    return true;
778
 
  else
779
 
    {
780
 
      msg (M_CLIENT, "ERROR: cannot parse CID");
781
 
      return false;
782
 
    }
783
 
}
784
 
 
785
 
static bool
786
 
parse_kid (const char *str, unsigned int *kid)
787
 
{
788
 
  if (sscanf (str, "%u", kid) == 1)
789
 
    return true;
790
 
  else
791
 
    {
792
 
      msg (M_CLIENT, "ERROR: cannot parse KID");
793
 
      return false;
794
 
    }
795
 
}
796
 
 
797
 
static void
798
 
in_extra_reset (struct man_connection *mc, const bool new)
799
 
{
800
 
  if (mc)
801
 
    {
802
 
      if (!new)
803
 
        {
804
 
          mc->in_extra_cmd = IEC_UNDEF;
805
 
          mc->in_extra_cid = 0;
806
 
          mc->in_extra_kid = 0;
807
 
        }
808
 
      if (mc->in_extra)
809
 
        {
810
 
          buffer_list_free (mc->in_extra);
811
 
          mc->in_extra = NULL;
812
 
        }
813
 
      if (new)
814
 
        mc->in_extra = buffer_list_new (0);
815
 
    }
816
 
}
817
 
 
818
 
static void
819
 
in_extra_dispatch (struct management *man)
820
 
{
821
 
   switch (man->connection.in_extra_cmd)
822
 
    {
823
 
    case IEC_CLIENT_AUTH:
824
 
       if (man->persist.callback.client_auth)
825
 
        {
826
 
          const bool status = (*man->persist.callback.client_auth)
827
 
            (man->persist.callback.arg,
828
 
             man->connection.in_extra_cid,
829
 
             man->connection.in_extra_kid,
830
 
             true,
831
 
             NULL,
832
 
             NULL,
833
 
             man->connection.in_extra);
834
 
          man->connection.in_extra = NULL;
835
 
          if (status)
836
 
            {
837
 
              msg (M_CLIENT, "SUCCESS: client-auth command succeeded");
838
 
            }
839
 
          else
840
 
            {
841
 
              msg (M_CLIENT, "ERROR: client-auth command failed");
842
 
            }
843
 
        }
844
 
      else
845
 
        {
846
 
          msg (M_CLIENT, "ERROR: The client-auth command is not supported by the current daemon mode");
847
 
        }
848
 
      break;
849
 
#ifdef MANAGEMENT_PF
850
 
    case IEC_CLIENT_PF:
851
 
      if (man->persist.callback.client_pf)
852
 
        {
853
 
          const bool status = (*man->persist.callback.client_pf)
854
 
            (man->persist.callback.arg,
855
 
             man->connection.in_extra_cid,
856
 
             man->connection.in_extra);
857
 
          man->connection.in_extra = NULL;
858
 
          if (status)
859
 
            {
860
 
              msg (M_CLIENT, "SUCCESS: client-pf command succeeded");
861
 
            }
862
 
          else
863
 
            {
864
 
              msg (M_CLIENT, "ERROR: client-pf command failed");
865
 
            }
866
 
        }
867
 
      else
868
 
        {
869
 
          msg (M_CLIENT, "ERROR: The client-pf command is not supported by the current daemon mode");
870
 
        }
871
 
      break;
872
 
#endif
873
 
    }
874
 
   in_extra_reset (&man->connection, false);
875
 
}
876
 
 
877
 
static void
878
 
man_client_auth (struct management *man, const char *cid_str, const char *kid_str, const bool extra)
879
 
{
880
 
  struct man_connection *mc = &man->connection;
881
 
  mc->in_extra_cid = 0;
882
 
  mc->in_extra_kid = 0;
883
 
  if (parse_cid (cid_str, &mc->in_extra_cid)
884
 
      && parse_kid (kid_str, &mc->in_extra_kid))
885
 
    {
886
 
      mc->in_extra_cmd = IEC_CLIENT_AUTH;
887
 
      in_extra_reset (mc, true);
888
 
      if (!extra)
889
 
        in_extra_dispatch (man);
890
 
    }
891
 
}
892
 
 
893
 
static void
894
 
man_client_deny (struct management *man, const char *cid_str, const char *kid_str, const char *reason, const char *client_reason)
895
 
{
896
 
  unsigned long cid = 0;
897
 
  unsigned int kid = 0;
898
 
  if (parse_cid (cid_str, &cid) && parse_kid (kid_str, &kid))
899
 
    {
900
 
      if (man->persist.callback.client_auth)
901
 
        {
902
 
          const bool status = (*man->persist.callback.client_auth)
903
 
            (man->persist.callback.arg,
904
 
             cid,
905
 
             kid,
906
 
             false,
907
 
             reason,
908
 
             client_reason,
909
 
             NULL);
910
 
          if (status)
911
 
            {
912
 
              msg (M_CLIENT, "SUCCESS: client-deny command succeeded");
913
 
            }
914
 
          else
915
 
            {
916
 
              msg (M_CLIENT, "ERROR: client-deny command failed");
917
 
            }
918
 
        }
919
 
      else
920
 
        {
921
 
          msg (M_CLIENT, "ERROR: The client-deny command is not supported by the current daemon mode");
922
 
        }
923
 
    }
924
 
}
925
 
 
926
 
static void
927
 
man_client_kill (struct management *man, const char *cid_str)
928
 
{
929
 
  unsigned long cid = 0;
930
 
  if (parse_cid (cid_str, &cid))
931
 
    {
932
 
      if (man->persist.callback.kill_by_cid)
933
 
        {
934
 
          const bool status = (*man->persist.callback.kill_by_cid) (man->persist.callback.arg, cid);
935
 
          if (status)
936
 
            {
937
 
              msg (M_CLIENT, "SUCCESS: client-kill command succeeded");
938
 
            }
939
 
          else
940
 
            {
941
 
              msg (M_CLIENT, "ERROR: client-kill command failed");
942
 
            }
943
 
        }
944
 
      else
945
 
        {
946
 
          msg (M_CLIENT, "ERROR: The client-kill command is not supported by the current daemon mode");
947
 
        }
948
 
    }
949
 
}
950
 
 
951
 
static void
952
 
man_client_n_clients (struct management *man)
953
 
{
954
 
  if (man->persist.callback.n_clients)
955
 
    {
956
 
      const int nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg);
957
 
      msg (M_CLIENT, "SUCCESS: nclients=%d", nclients);
958
 
    }
959
 
  else
960
 
    {
961
 
      msg (M_CLIENT, "ERROR: The nclients command is not supported by the current daemon mode");
962
 
    }
963
 
}
964
 
 
965
 
static void
966
 
man_env_filter (struct management *man, const int level)
967
 
{
968
 
  man->connection.env_filter_level = level;
969
 
  msg (M_CLIENT, "SUCCESS: env_filter_level=%d", level);
970
 
}
971
 
 
972
 
#ifdef MANAGEMENT_PF
973
 
 
974
 
static void
975
 
man_client_pf (struct management *man, const char *cid_str)
976
 
{
977
 
  struct man_connection *mc = &man->connection;
978
 
  mc->in_extra_cid = 0;
979
 
  mc->in_extra_kid = 0;
980
 
  if (parse_cid (cid_str, &mc->in_extra_cid))
981
 
    {
982
 
      mc->in_extra_cmd = IEC_CLIENT_PF;
983
 
      in_extra_reset (mc, true);
984
 
    }
985
 
}
986
 
 
987
 
#endif
988
 
#endif
989
 
 
990
 
static void
991
 
man_load_stats (struct management *man)
992
 
{
993
 
  extern counter_type link_read_bytes_global;
994
 
  extern counter_type link_write_bytes_global;
995
 
  int nclients = 0;
996
 
 
997
 
  if (man->persist.callback.n_clients)
998
 
    nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg);
999
 
  msg (M_CLIENT, "SUCCESS: nclients=%d,bytesin=" counter_format ",bytesout=" counter_format,
1000
 
       nclients,
1001
 
       link_read_bytes_global,
1002
 
       link_write_bytes_global);
1003
 
}
1004
 
 
1005
 
#define MN_AT_LEAST (1<<0)
1006
 
 
1007
 
static bool
1008
 
man_need (struct management *man, const char **p, const int n, unsigned int flags)
1009
 
{
1010
 
  int i;
1011
 
  ASSERT (p[0]);
1012
 
  for (i = 1; i <= n; ++i)
1013
 
    {
1014
 
      if (!p[i])
1015
 
        {
1016
 
          msg (M_CLIENT, "ERROR: the '%s' command requires %s%d parameter%s",
1017
 
               p[0],
1018
 
               (flags & MN_AT_LEAST) ? "at least " : "",
1019
 
               n,
1020
 
               n > 1 ? "s" : "");
1021
 
          return false;
1022
 
        }
1023
 
    }
1024
 
  return true;
1025
 
}
1026
 
 
1027
 
#if HTTP_PROXY_FALLBACK
1028
 
 
1029
 
static void
1030
 
man_http_proxy_fallback (struct management *man, const char *server, const char *port, const char *flags)
1031
 
{
1032
 
  if (man->persist.callback.http_proxy_fallback_cmd)
1033
 
    {
1034
 
      const bool status = (*man->persist.callback.http_proxy_fallback_cmd)(man->persist.callback.arg, server, port, flags);
1035
 
      if (status)
1036
 
        {
1037
 
          msg (M_CLIENT, "SUCCESS: proxy-fallback command succeeded");
1038
 
        }
1039
 
      else
1040
 
        {
1041
 
          msg (M_CLIENT, "ERROR: proxy-fallback command failed");
1042
 
        }
1043
 
    }
1044
 
  else
1045
 
    {
1046
 
      msg (M_CLIENT, "ERROR: The proxy-fallback command is not supported by the current daemon mode");
1047
 
    }
1048
 
}
1049
 
 
1050
 
#endif
1051
 
 
1052
 
static void
1053
 
man_dispatch_command (struct management *man, struct status_output *so, const char **p, const int nparms)
1054
 
{
1055
 
  struct gc_arena gc = gc_new ();
1056
 
 
1057
 
  ASSERT (p[0]);
1058
 
  if (streq (p[0], "exit") || streq (p[0], "quit"))
1059
 
    {
1060
 
      man->connection.halt = true;
1061
 
      goto done;
1062
 
    }
1063
 
  else if (streq (p[0], "help"))
1064
 
    {
1065
 
      man_help ();
1066
 
    }
1067
 
  else if (streq (p[0], "version"))
1068
 
    {
1069
 
      msg (M_CLIENT, "OpenVPN Version: %s", title_string);
1070
 
      msg (M_CLIENT, "Management Version: %d", MANAGEMENT_VERSION);
1071
 
      msg (M_CLIENT, "END");
1072
 
    }
1073
 
  else if (streq (p[0], "pid"))
1074
 
    {
1075
 
      msg (M_CLIENT, "SUCCESS: pid=%d", openvpn_getpid ());
1076
 
    }
1077
 
#ifdef MANAGEMENT_DEF_AUTH
1078
 
  else if (streq (p[0], "nclients"))
1079
 
    {
1080
 
      man_client_n_clients (man);
1081
 
    }
1082
 
  else if (streq (p[0], "env-filter"))
1083
 
    {
1084
 
      int level = 0;
1085
 
      if (p[1])
1086
 
        level = atoi (p[1]);
1087
 
      man_env_filter (man, level);
1088
 
    }
1089
 
#endif
1090
 
  else if (streq (p[0], "signal"))
1091
 
    {
1092
 
      if (man_need (man, p, 1, 0))
1093
 
        man_signal (man, p[1]);
1094
 
    }
1095
 
  else if (streq (p[0], "load-stats"))
1096
 
    {
1097
 
      man_load_stats (man);
1098
 
    }
1099
 
  else if (streq (p[0], "status"))
1100
 
    {
1101
 
      int version = 0;
1102
 
      if (p[1])
1103
 
        version = atoi (p[1]);
1104
 
      man_status (man, version, so);
1105
 
    }
1106
 
  else if (streq (p[0], "kill"))
1107
 
    {
1108
 
      if (man_need (man, p, 1, 0))
1109
 
        man_kill (man, p[1]);
1110
 
    }
1111
 
  else if (streq (p[0], "verb"))
1112
 
    {
1113
 
      if (p[1])
1114
 
        {
1115
 
          const int level = atoi(p[1]);
1116
 
          if (set_debug_level (level, 0))
1117
 
            msg (M_CLIENT, "SUCCESS: verb level changed");
1118
 
          else
1119
 
            msg (M_CLIENT, "ERROR: verb level is out of range");
1120
 
        }
1121
 
      else
1122
 
        msg (M_CLIENT, "SUCCESS: verb=%d", get_debug_level ());
1123
 
    }
1124
 
  else if (streq (p[0], "mute"))
1125
 
    {
1126
 
      if (p[1])
1127
 
        {
1128
 
          const int level = atoi(p[1]);
1129
 
          if (set_mute_cutoff (level))
1130
 
            msg (M_CLIENT, "SUCCESS: mute level changed");
1131
 
          else
1132
 
            msg (M_CLIENT, "ERROR: mute level is out of range");
1133
 
        }
1134
 
      else
1135
 
        msg (M_CLIENT, "SUCCESS: mute=%d", get_mute_cutoff ());
1136
 
    }
1137
 
  else if (streq (p[0], "auth-retry"))
1138
 
    {
1139
 
#if P2MP
1140
 
      if (p[1])
1141
 
        {
1142
 
          if (auth_retry_set (M_CLIENT, p[1]))
1143
 
            msg (M_CLIENT, "SUCCESS: auth-retry parameter changed");
1144
 
          else
1145
 
            msg (M_CLIENT, "ERROR: bad auth-retry parameter");
1146
 
        }
1147
 
      else
1148
 
        msg (M_CLIENT, "SUCCESS: auth-retry=%s", auth_retry_print ());  
1149
 
#else
1150
 
      msg (M_CLIENT, "ERROR: auth-retry feature is unavailable");
1151
 
#endif
1152
 
    }
1153
 
  else if (streq (p[0], "state"))
1154
 
    {
1155
 
      if (!p[1])
1156
 
        {
1157
 
          man_state (man, "1");
1158
 
        }
1159
 
      else
1160
 
        {
1161
 
          if (p[1])
1162
 
            man_state (man, p[1]);
1163
 
          if (p[2])
1164
 
            man_state (man, p[2]);
1165
 
        }
1166
 
    }
1167
 
  else if (streq (p[0], "log"))
1168
 
    {
1169
 
      if (man_need (man, p, 1, MN_AT_LEAST))
1170
 
        {
1171
 
          if (p[1])
1172
 
            man_log (man, p[1]);
1173
 
          if (p[2])
1174
 
            man_log (man, p[2]);
1175
 
        }
1176
 
    }
1177
 
  else if (streq (p[0], "echo"))
1178
 
    {
1179
 
      if (man_need (man, p, 1, MN_AT_LEAST))
1180
 
        {
1181
 
          if (p[1])
1182
 
            man_echo (man, p[1]);
1183
 
          if (p[2])
1184
 
            man_echo (man, p[2]);
1185
 
        }
1186
 
    }
1187
 
  else if (streq (p[0], "username"))
1188
 
    {
1189
 
      if (man_need (man, p, 2, 0))
1190
 
        man_query_username (man, p[1], p[2]);
1191
 
    }
1192
 
  else if (streq (p[0], "password"))
1193
 
    {
1194
 
      if (man_need (man, p, 2, 0))
1195
 
        man_query_password (man, p[1], p[2]);
1196
 
    }
1197
 
  else if (streq (p[0], "forget-passwords"))
1198
 
    {
1199
 
      man_forget_passwords (man);
1200
 
    }
1201
 
  else if (streq (p[0], "needok"))
1202
 
    {
1203
 
      if (man_need (man, p, 2, 0))
1204
 
        man_query_need_ok (man, p[1], p[2]);
1205
 
    }
1206
 
  else if (streq (p[0], "needstr"))
1207
 
    {
1208
 
      if (man_need (man, p, 2, 0))
1209
 
        man_query_need_str (man, p[1], p[2]);
1210
 
    }
1211
 
  else if (streq (p[0], "net"))
1212
 
    {
1213
 
      man_net (man);
1214
 
    }
1215
 
  else if (streq (p[0], "hold"))
1216
 
    {
1217
 
      man_hold (man, p[1]);
1218
 
    }
1219
 
  else if (streq (p[0], "bytecount"))
1220
 
    {
1221
 
      if (man_need (man, p, 1, 0))
1222
 
        man_bytecount (man, atoi(p[1]));
1223
 
    }
1224
 
#ifdef MANAGEMENT_DEF_AUTH
1225
 
  else if (streq (p[0], "client-kill"))
1226
 
    {
1227
 
      if (man_need (man, p, 1, 0))
1228
 
        man_client_kill (man, p[1]);
1229
 
    }
1230
 
  else if (streq (p[0], "client-deny"))
1231
 
    {
1232
 
      if (man_need (man, p, 3, MN_AT_LEAST))
1233
 
        man_client_deny (man, p[1], p[2], p[3], p[4]);
1234
 
    }
1235
 
  else if (streq (p[0], "client-auth-nt"))
1236
 
    {
1237
 
      if (man_need (man, p, 2, 0))
1238
 
        man_client_auth (man, p[1], p[2], false);
1239
 
    }
1240
 
  else if (streq (p[0], "client-auth"))
1241
 
    {
1242
 
      if (man_need (man, p, 2, 0))
1243
 
        man_client_auth (man, p[1], p[2], true);
1244
 
    }
1245
 
#ifdef MANAGEMENT_PF
1246
 
  else if (streq (p[0], "client-pf"))
1247
 
    {
1248
 
      if (man_need (man, p, 1, 0))
1249
 
        man_client_pf (man, p[1]);
1250
 
    }
1251
 
#endif
1252
 
#endif
1253
 
#ifdef ENABLE_PKCS11
1254
 
  else if (streq (p[0], "pkcs11-id-count"))
1255
 
    {
1256
 
      man_pkcs11_id_count (man);
1257
 
    }
1258
 
  else if (streq (p[0], "pkcs11-id-get"))
1259
 
    {
1260
 
      if (man_need (man, p, 1, 0))
1261
 
        man_pkcs11_id_get (man, atoi(p[1]));
1262
 
    }
1263
 
#endif
1264
 
#if HTTP_PROXY_FALLBACK
1265
 
  else if (streq (p[0], "http-proxy-fallback"))
1266
 
    {
1267
 
      if (man_need (man, p, 2, MN_AT_LEAST))
1268
 
        man_http_proxy_fallback (man, p[1], p[2], p[3]);
1269
 
    }
1270
 
  else if (streq (p[0], "http-proxy-fallback-disable"))
1271
 
    {
1272
 
      man_http_proxy_fallback (man, NULL, NULL, NULL);
1273
 
    }
1274
 
#endif
1275
 
#if 1
1276
 
  else if (streq (p[0], "test"))
1277
 
    {
1278
 
      if (man_need (man, p, 1, 0))
1279
 
        {
1280
 
          int i;
1281
 
          const int n = atoi (p[1]);
1282
 
          for (i = 0; i < n; ++i)
1283
 
            {
1284
 
              msg (M_CLIENT, "[%d] The purpose of this command is to generate large amounts of output.", i);
1285
 
            }
1286
 
        }
1287
 
    }
1288
 
#endif
1289
 
  else
1290
 
    {
1291
 
      msg (M_CLIENT, "ERROR: unknown command, enter 'help' for more options");
1292
 
    }
1293
 
 
1294
 
 done:
1295
 
  gc_free (&gc);
1296
 
}
1297
 
 
1298
 
#ifdef WIN32
1299
 
 
1300
 
static void
1301
 
man_start_ne32 (struct management *man)
1302
 
{
1303
 
  switch (man->connection.state)
1304
 
    {
1305
 
    case MS_LISTEN:
1306
 
      net_event_win32_start (&man->connection.ne32, FD_ACCEPT, man->connection.sd_top);
1307
 
      break;
1308
 
    case MS_CC_WAIT_READ:
1309
 
    case MS_CC_WAIT_WRITE:
1310
 
      net_event_win32_start (&man->connection.ne32, FD_READ|FD_WRITE|FD_CLOSE, man->connection.sd_cli);
1311
 
      break;
1312
 
    default:
1313
 
      ASSERT (0);
1314
 
    }  
1315
 
}
1316
 
 
1317
 
static void
1318
 
man_stop_ne32 (struct management *man)
1319
 
{
1320
 
  net_event_win32_stop (&man->connection.ne32);
1321
 
}
1322
 
 
1323
 
#endif
1324
 
 
1325
 
static void
1326
 
man_record_peer_info (struct management *man)
1327
 
{
1328
 
  struct gc_arena gc = gc_new ();
1329
 
  if (man->settings.write_peer_info_file)
1330
 
    {
1331
 
      bool success = false;
1332
 
#ifdef HAVE_GETSOCKNAME
1333
 
      if (socket_defined (man->connection.sd_cli))
1334
 
        {
1335
 
          struct sockaddr_in addr;
1336
 
          socklen_t addrlen = sizeof (addr);
1337
 
          int status;
1338
 
 
1339
 
          CLEAR (addr);
1340
 
          status = getsockname (man->connection.sd_cli, (struct sockaddr *)&addr, &addrlen);
1341
 
          if (!status && addrlen == sizeof (addr))
1342
 
            {
1343
 
              const in_addr_t a = ntohl (addr.sin_addr.s_addr);
1344
 
              const int p = ntohs (addr.sin_port);
1345
 
              FILE *fp = fopen (man->settings.write_peer_info_file, "w");
1346
 
              if (fp)
1347
 
                {
1348
 
                  fprintf (fp, "%s\n%d\n", print_in_addr_t (a, 0, &gc), p);
1349
 
                  if (!fclose (fp))
1350
 
                    success = true;
1351
 
                }
1352
 
            }
1353
 
        }
1354
 
#endif
1355
 
      if (!success)
1356
 
        {
1357
 
          msg (D_MANAGEMENT, "MANAGEMENT: failed to write peer info to file %s",
1358
 
               man->settings.write_peer_info_file);
1359
 
          throw_signal_soft (SIGTERM, "management-connect-failed");
1360
 
        }
1361
 
    }
1362
 
  gc_free (&gc);
1363
 
}
1364
 
 
1365
 
static void
1366
 
man_connection_settings_reset (struct management *man)
1367
 
{
1368
 
  man->connection.state_realtime = false;
1369
 
  man->connection.log_realtime = false;
1370
 
  man->connection.echo_realtime = false;
1371
 
  man->connection.bytecount_update_seconds = 0;
1372
 
  man->connection.password_verified = false;
1373
 
  man->connection.password_tries = 0;
1374
 
  man->connection.halt = false;
1375
 
  man->connection.state = MS_CC_WAIT_WRITE;
1376
 
}
1377
 
 
1378
 
static void
1379
 
man_new_connection_post (struct management *man, const char *description)
1380
 
{
1381
 
  struct gc_arena gc = gc_new ();
1382
 
 
1383
 
  set_nonblock (man->connection.sd_cli);
1384
 
  set_cloexec (man->connection.sd_cli);
1385
 
 
1386
 
  man_connection_settings_reset (man);
1387
 
 
1388
 
#ifdef WIN32
1389
 
  man_start_ne32 (man);
1390
 
#endif
1391
 
 
1392
 
#if UNIX_SOCK_SUPPORT
1393
 
  if (man->settings.flags & MF_UNIX_SOCK)
1394
 
    {
1395
 
      msg (D_MANAGEMENT, "MANAGEMENT: %s %s",
1396
 
           description,
1397
 
           sockaddr_unix_name (&man->settings.local_unix, "NULL"));
1398
 
    }
1399
 
  else
1400
 
#endif
1401
 
    msg (D_MANAGEMENT, "MANAGEMENT: %s %s",
1402
 
         description,
1403
 
         print_sockaddr (&man->settings.local, &gc));
1404
 
 
1405
 
  buffer_list_reset (man->connection.out);
1406
 
 
1407
 
  if (!man_password_needed (man))
1408
 
    man_welcome (man);
1409
 
  man_prompt (man);
1410
 
  man_update_io_state (man);
1411
 
 
1412
 
  gc_free (&gc);
1413
 
}
1414
 
 
1415
 
#if UNIX_SOCK_SUPPORT
1416
 
static bool
1417
 
man_verify_unix_peer_uid_gid (struct management *man, const socket_descriptor_t sd)
1418
 
{
1419
 
  if (socket_defined (sd) && (man->settings.client_uid != -1 || man->settings.client_gid != -1))
1420
 
    {
1421
 
      static const char err_prefix[] = "MANAGEMENT: unix domain socket client connection rejected --";
1422
 
      int uid, gid;
1423
 
      if (unix_socket_get_peer_uid_gid (man->connection.sd_cli, &uid, &gid))
1424
 
        {
1425
 
          if (man->settings.client_uid != -1 && man->settings.client_uid != uid)
1426
 
            {
1427
 
              msg (D_MANAGEMENT, "%s UID of socket peer (%d) doesn't match required value (%d) as given by --management-client-user",
1428
 
                   err_prefix, uid, man->settings.client_uid);
1429
 
              return false;
1430
 
            }
1431
 
          if (man->settings.client_gid != -1 && man->settings.client_gid != gid)
1432
 
            {
1433
 
              msg (D_MANAGEMENT, "%s GID of socket peer (%d) doesn't match required value (%d) as given by --management-client-group",
1434
 
                   err_prefix, gid, man->settings.client_gid);
1435
 
              return false;
1436
 
            }
1437
 
        }
1438
 
      else
1439
 
        {
1440
 
          msg (D_MANAGEMENT, "%s cannot get UID/GID of socket peer", err_prefix);
1441
 
          return false;
1442
 
        }
1443
 
    }
1444
 
  return true;
1445
 
}
1446
 
#endif
1447
 
 
1448
 
static void
1449
 
man_accept (struct management *man)
1450
 
{
1451
 
  struct link_socket_actual act;
1452
 
  CLEAR (act);
1453
 
 
1454
 
  /*
1455
 
   * Accept the TCP or Unix domain socket client.
1456
 
   */
1457
 
#if UNIX_SOCK_SUPPORT
1458
 
  if (man->settings.flags & MF_UNIX_SOCK)
1459
 
    {
1460
 
      struct sockaddr_un remote;
1461
 
      man->connection.sd_cli = socket_accept_unix (man->connection.sd_top, &remote);
1462
 
      if (!man_verify_unix_peer_uid_gid (man, man->connection.sd_cli))
1463
 
        sd_close (&man->connection.sd_cli);
1464
 
    }
1465
 
  else
1466
 
#endif
1467
 
    man->connection.sd_cli = socket_do_accept (man->connection.sd_top, &act, false);
1468
 
 
1469
 
  if (socket_defined (man->connection.sd_cli))
1470
 
    {
1471
 
      man->connection.remote = act.dest;
1472
 
 
1473
 
      if (socket_defined (man->connection.sd_top))
1474
 
        {
1475
 
#ifdef WIN32
1476
 
          man_stop_ne32 (man);
1477
 
#endif
1478
 
        }
1479
 
 
1480
 
      man_new_connection_post (man, "Client connected from");
1481
 
    }
1482
 
}
1483
 
 
1484
 
static void
1485
 
man_listen (struct management *man)
1486
 
{
1487
 
  struct gc_arena gc = gc_new ();
1488
 
 
1489
 
  /*
1490
 
   * Initialize state
1491
 
   */
1492
 
  man->connection.state = MS_LISTEN;
1493
 
  man->connection.sd_cli = SOCKET_UNDEFINED;
1494
 
 
1495
 
  /*
1496
 
   * Initialize listening socket
1497
 
   */
1498
 
  if (man->connection.sd_top == SOCKET_UNDEFINED)
1499
 
    {
1500
 
#if UNIX_SOCK_SUPPORT
1501
 
      if (man->settings.flags & MF_UNIX_SOCK)
1502
 
        {
1503
 
          man_delete_unix_socket (man);
1504
 
          man->connection.sd_top = create_socket_unix ();
1505
 
          socket_bind_unix (man->connection.sd_top, &man->settings.local_unix, "MANAGEMENT");
1506
 
        }
1507
 
      else
1508
 
#endif
1509
 
        {
1510
 
          man->connection.sd_top = create_socket_tcp ();
1511
 
          socket_bind (man->connection.sd_top, &man->settings.local, "MANAGEMENT");
1512
 
        }
1513
 
 
1514
 
      /*
1515
 
       * Listen for connection
1516
 
       */
1517
 
      if (listen (man->connection.sd_top, 1))
1518
 
        msg (M_SOCKERR, "MANAGEMENT: listen() failed");
1519
 
 
1520
 
      /*
1521
 
       * Set misc socket properties
1522
 
       */
1523
 
      set_nonblock (man->connection.sd_top);
1524
 
      set_cloexec (man->connection.sd_top);
1525
 
 
1526
 
#if UNIX_SOCK_SUPPORT
1527
 
      if (man->settings.flags & MF_UNIX_SOCK)
1528
 
        {
1529
 
          msg (D_MANAGEMENT, "MANAGEMENT: unix domain socket listening on %s",
1530
 
               sockaddr_unix_name (&man->settings.local_unix, "NULL"));
1531
 
        }
1532
 
      else
1533
 
#endif
1534
 
        msg (D_MANAGEMENT, "MANAGEMENT: TCP Socket listening on %s",
1535
 
             print_sockaddr (&man->settings.local, &gc));
1536
 
    }
1537
 
 
1538
 
#ifdef WIN32
1539
 
  man_start_ne32 (man);
1540
 
#endif
1541
 
  
1542
 
  gc_free (&gc);
1543
 
}
1544
 
 
1545
 
static void
1546
 
man_connect (struct management *man)
1547
 
{
1548
 
  struct gc_arena gc = gc_new ();
1549
 
  int status;
1550
 
  int signal_received = 0;
1551
 
 
1552
 
  /*
1553
 
   * Initialize state
1554
 
   */
1555
 
  man->connection.state = MS_INITIAL;
1556
 
  man->connection.sd_top = SOCKET_UNDEFINED;
1557
 
 
1558
 
#if UNIX_SOCK_SUPPORT
1559
 
  if (man->settings.flags & MF_UNIX_SOCK)
1560
 
    {
1561
 
      man->connection.sd_cli = create_socket_unix ();
1562
 
      status = socket_connect_unix (man->connection.sd_cli, &man->settings.local_unix);
1563
 
      if (!status && !man_verify_unix_peer_uid_gid (man, man->connection.sd_cli))
1564
 
          {
1565
 
#ifdef EPERM
1566
 
            status = EPERM;
1567
 
#else
1568
 
            status = 1;
1569
 
#endif
1570
 
            sd_close (&man->connection.sd_cli);
1571
 
          }
1572
 
    }
1573
 
  else
1574
 
#endif
1575
 
    {
1576
 
      man->connection.sd_cli = create_socket_tcp ();
1577
 
      status = openvpn_connect (man->connection.sd_cli,
1578
 
                                &man->settings.local,
1579
 
                                5,
1580
 
                                &signal_received);
1581
 
    }
1582
 
 
1583
 
  if (signal_received)
1584
 
    {
1585
 
      throw_signal (signal_received);
1586
 
      goto done;
1587
 
    }
1588
 
 
1589
 
  if (status)
1590
 
    {
1591
 
#if UNIX_SOCK_SUPPORT
1592
 
      if (man->settings.flags & MF_UNIX_SOCK)
1593
 
        {
1594
 
          msg (D_LINK_ERRORS,
1595
 
               "MANAGEMENT: connect to unix socket %s failed: %s",
1596
 
               sockaddr_unix_name (&man->settings.local_unix, "NULL"),
1597
 
               strerror_ts (status, &gc));
1598
 
        }
1599
 
      else
1600
 
#endif
1601
 
      msg (D_LINK_ERRORS,
1602
 
           "MANAGEMENT: connect to %s failed: %s",
1603
 
           print_sockaddr (&man->settings.local, &gc),
1604
 
           strerror_ts (status, &gc));
1605
 
      throw_signal_soft (SIGTERM, "management-connect-failed");
1606
 
      goto done;
1607
 
    }
1608
 
 
1609
 
  man_record_peer_info (man);
1610
 
  man_new_connection_post (man, "Connected to management server at");
1611
 
 
1612
 
 done:
1613
 
  gc_free (&gc);
1614
 
}
1615
 
 
1616
 
static void
1617
 
man_reset_client_socket (struct management *man, const bool exiting)
1618
 
{
1619
 
  if (socket_defined (man->connection.sd_cli))
1620
 
    {
1621
 
#ifdef WIN32
1622
 
      man_stop_ne32 (man);
1623
 
#endif
1624
 
      man_close_socket (man, man->connection.sd_cli);
1625
 
      man->connection.sd_cli = SOCKET_UNDEFINED;
1626
 
      man->connection.state = MS_INITIAL;
1627
 
      command_line_reset (man->connection.in);
1628
 
      buffer_list_reset (man->connection.out);
1629
 
#ifdef MANAGEMENT_DEF_AUTH
1630
 
      in_extra_reset (&man->connection, false);
1631
 
#endif
1632
 
      msg (D_MANAGEMENT, "MANAGEMENT: Client disconnected");
1633
 
    }
1634
 
  if (!exiting)
1635
 
    {
1636
 
#if defined(USE_CRYPTO) && defined(USE_SSL)
1637
 
      if (man->settings.flags & MF_FORGET_DISCONNECT)
1638
 
        ssl_purge_auth ();
1639
 
#endif
1640
 
      if (man->settings.flags & MF_SIGNAL) {
1641
 
          int mysig = man_mod_signal (man, SIGUSR1);
1642
 
          if (mysig >= 0)
1643
 
            {
1644
 
              msg (D_MANAGEMENT, "MANAGEMENT: Triggering management signal");
1645
 
              throw_signal_soft (mysig, "management-disconnect");
1646
 
            }
1647
 
      }
1648
 
 
1649
 
      if (man->settings.flags & MF_CONNECT_AS_CLIENT)
1650
 
        {
1651
 
          msg (D_MANAGEMENT, "MANAGEMENT: Triggering management exit");
1652
 
          throw_signal_soft (SIGTERM, "management-exit");
1653
 
        }
1654
 
      else
1655
 
        man_listen (man);
1656
 
    }
1657
 
}
1658
 
 
1659
 
static void
1660
 
man_process_command (struct management *man, const char *line)
1661
 
{
1662
 
  struct gc_arena gc = gc_new ();
1663
 
  struct status_output *so;
1664
 
  int nparms;
1665
 
  char *parms[MAX_PARMS+1];
1666
 
 
1667
 
  CLEAR (parms);
1668
 
  so = status_open (NULL, 0, -1, &man->persist.vout, 0);
1669
 
#ifdef MANAGEMENT_DEF_AUTH
1670
 
  in_extra_reset (&man->connection, false);
1671
 
#endif
1672
 
 
1673
 
  if (man_password_needed (man))
1674
 
    {
1675
 
      man_check_password (man, line);
1676
 
    }
1677
 
  else
1678
 
    {
1679
 
      nparms = parse_line (line, parms, MAX_PARMS, "TCP", 0, M_CLIENT, &gc);
1680
 
      if (parms[0] && streq (parms[0], "password"))
1681
 
        msg (D_MANAGEMENT_DEBUG, "MANAGEMENT: CMD 'password [...]'");
1682
 
      else if (!streq (line, "load-stats"))
1683
 
        msg (D_MANAGEMENT_DEBUG, "MANAGEMENT: CMD '%s'", line);
1684
 
 
1685
 
#if 0
1686
 
      /* DEBUGGING -- print args */
1687
 
      {
1688
 
        int i;
1689
 
        for (i = 0; i < nparms; ++i)
1690
 
          msg (M_INFO, "[%d] '%s'", i, parms[i]);
1691
 
      }
1692
 
#endif
1693
 
 
1694
 
      if (nparms > 0)
1695
 
        man_dispatch_command (man, so, (const char **)parms, nparms);
1696
 
    }
1697
 
 
1698
 
  CLEAR (parms);
1699
 
  status_close (so);
1700
 
  gc_free (&gc);
1701
 
}
1702
 
 
1703
 
static bool
1704
 
man_io_error (struct management *man, const char *prefix)
1705
 
{
1706
 
  const int err = openvpn_errno_socket ();
1707
 
 
1708
 
  if (!ignore_sys_error (err))
1709
 
    {
1710
 
      struct gc_arena gc = gc_new ();
1711
 
      msg (D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s",
1712
 
           prefix,
1713
 
           strerror_ts (err, &gc));
1714
 
      gc_free (&gc);
1715
 
      return true;
1716
 
    }
1717
 
  else
1718
 
    return false;
1719
 
}
1720
 
 
1721
 
static int
1722
 
man_read (struct management *man)
1723
 
{
1724
 
  /*
1725
 
   * read command line from socket
1726
 
   */
1727
 
  unsigned char buf[256];
1728
 
  int len = 0;
1729
 
 
1730
 
  len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);
1731
 
  if (len == 0)
1732
 
    {
1733
 
      man_reset_client_socket (man, false);
1734
 
    }
1735
 
  else if (len > 0)
1736
 
    {
1737
 
      bool processed_command = false;
1738
 
 
1739
 
      ASSERT (len <= (int) sizeof (buf));
1740
 
      command_line_add (man->connection.in, buf, len);
1741
 
 
1742
 
      /*
1743
 
       * Reset output object
1744
 
       */
1745
 
      buffer_list_reset (man->connection.out);
1746
 
 
1747
 
      /*
1748
 
       * process command line if complete
1749
 
       */
1750
 
      {
1751
 
        const unsigned char *line;
1752
 
        while ((line = command_line_get (man->connection.in)))
1753
 
          {
1754
 
#ifdef MANAGEMENT_DEF_AUTH
1755
 
            if (man->connection.in_extra)
1756
 
              {
1757
 
                if (!strcmp ((char *)line, "END"))
1758
 
                  {
1759
 
                    in_extra_dispatch (man);
1760
 
                    in_extra_reset (&man->connection, false);
1761
 
                  }
1762
 
                else
1763
 
                  {
1764
 
                    buffer_list_push (man->connection.in_extra, line);
1765
 
                  }
1766
 
              }
1767
 
            else
1768
 
#endif
1769
 
              man_process_command (man, (char *) line);
1770
 
            if (man->connection.halt)
1771
 
              break;
1772
 
            command_line_next (man->connection.in);
1773
 
            processed_command = true;
1774
 
          }
1775
 
      }
1776
 
 
1777
 
      /*
1778
 
       * Reset output state to MS_CC_WAIT_(READ|WRITE)
1779
 
       */
1780
 
      if (man->connection.halt)
1781
 
        {
1782
 
          man_reset_client_socket (man, false);
1783
 
          len = 0;
1784
 
        }
1785
 
      else
1786
 
        {
1787
 
          if (processed_command)
1788
 
            man_prompt (man);
1789
 
          man_update_io_state (man);
1790
 
        }
1791
 
    }
1792
 
  else /* len < 0 */
1793
 
    {
1794
 
      if (man_io_error (man, "recv"))
1795
 
        man_reset_client_socket (man, false);
1796
 
    }
1797
 
  return len;
1798
 
}
1799
 
 
1800
 
static int
1801
 
man_write (struct management *man)
1802
 
{
1803
 
  const int size_hint = 1024;
1804
 
  int sent = 0;
1805
 
  const struct buffer *buf;
1806
 
 
1807
 
  buffer_list_aggregate(man->connection.out, size_hint);
1808
 
  buf = buffer_list_peek (man->connection.out);
1809
 
  if (buf && BLEN (buf))
1810
 
    {
1811
 
      const int len = min_int (size_hint, BLEN (buf));
1812
 
      sent = send (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL);
1813
 
      if (sent >= 0)
1814
 
        {
1815
 
          buffer_list_advance (man->connection.out, sent);
1816
 
        }
1817
 
      else if (sent < 0)
1818
 
        {
1819
 
          if (man_io_error (man, "send"))
1820
 
            man_reset_client_socket (man, false);
1821
 
        }
1822
 
    }
1823
 
 
1824
 
  /*
1825
 
   * Reset output state to MS_CC_WAIT_(READ|WRITE)
1826
 
   */
1827
 
  man_update_io_state (man);
1828
 
 
1829
 
  return sent;
1830
 
}
1831
 
 
1832
 
static void
1833
 
man_connection_clear (struct man_connection *mc)
1834
 
{
1835
 
  CLEAR (*mc);
1836
 
 
1837
 
  /* set initial state */
1838
 
  mc->state = MS_INITIAL;
1839
 
 
1840
 
  /* clear socket descriptors */
1841
 
  mc->sd_top = SOCKET_UNDEFINED;
1842
 
  mc->sd_cli = SOCKET_UNDEFINED;
1843
 
}
1844
 
 
1845
 
static void
1846
 
man_persist_init (struct management *man,
1847
 
                  const int log_history_cache,
1848
 
                  const int echo_buffer_size,
1849
 
                  const int state_buffer_size)
1850
 
{
1851
 
  struct man_persist *mp = &man->persist;
1852
 
  if (!mp->defined)
1853
 
    {
1854
 
      CLEAR (*mp);
1855
 
 
1856
 
      /* initialize log history store */
1857
 
      mp->log = log_history_init (log_history_cache);  
1858
 
 
1859
 
      /*
1860
 
       * Initialize virtual output object, so that functions
1861
 
       * which write to a virtual_output object can be redirected
1862
 
       * here to the management object.
1863
 
       */
1864
 
      mp->vout.func = virtual_output_callback_func;
1865
 
      mp->vout.arg = man;
1866
 
      mp->vout.flags_default = M_CLIENT;
1867
 
      msg_set_virtual_output (&mp->vout);
1868
 
 
1869
 
      /*
1870
 
       * Initialize --echo list
1871
 
       */
1872
 
      man->persist.echo = log_history_init (echo_buffer_size);
1873
 
 
1874
 
      /*
1875
 
       * Initialize --state list
1876
 
       */
1877
 
      man->persist.state = log_history_init (state_buffer_size);
1878
 
 
1879
 
      mp->defined = true;
1880
 
    }
1881
 
}
1882
 
 
1883
 
static void
1884
 
man_persist_close (struct man_persist *mp)
1885
 
{
1886
 
  if (mp->log)
1887
 
    {
1888
 
      msg_set_virtual_output (NULL);
1889
 
      log_history_close (mp->log);
1890
 
    }
1891
 
 
1892
 
  if (mp->echo)
1893
 
    log_history_close (mp->echo);
1894
 
 
1895
 
  if (mp->state)
1896
 
    log_history_close (mp->state);
1897
 
 
1898
 
  CLEAR (*mp);
1899
 
}
1900
 
      
1901
 
static void
1902
 
man_settings_init (struct man_settings *ms,
1903
 
                   const char *addr,
1904
 
                   const int port,
1905
 
                   const char *pass_file,
1906
 
                   const char *client_user,
1907
 
                   const char *client_group,
1908
 
                   const int log_history_cache,
1909
 
                   const int echo_buffer_size,
1910
 
                   const int state_buffer_size,
1911
 
                   const char *write_peer_info_file,
1912
 
                   const int remap_sigusr1,
1913
 
                   const unsigned int flags)
1914
 
{
1915
 
  if (!ms->defined)
1916
 
    {
1917
 
      CLEAR (*ms);
1918
 
 
1919
 
      ms->flags = flags;
1920
 
      ms->client_uid = -1;
1921
 
      ms->client_gid = -1;
1922
 
 
1923
 
      /*
1924
 
       * Get username/password
1925
 
       */
1926
 
      if (pass_file)
1927
 
        get_user_pass (&ms->up, pass_file, "Management", GET_USER_PASS_PASSWORD_ONLY);
1928
 
 
1929
 
      /*
1930
 
       * lookup client UID/GID if specified
1931
 
       */
1932
 
      if (client_user)
1933
 
        {
1934
 
          struct user_state s;
1935
 
          get_user (client_user, &s);
1936
 
          ms->client_uid = user_state_uid (&s);
1937
 
          msg (D_MANAGEMENT, "MANAGEMENT: client_uid=%d", ms->client_uid);
1938
 
          ASSERT (ms->client_uid >= 0);
1939
 
        }
1940
 
      if (client_group)
1941
 
        {
1942
 
          struct group_state s;
1943
 
          get_group (client_group, &s);
1944
 
          ms->client_gid = group_state_gid (&s);
1945
 
          msg (D_MANAGEMENT, "MANAGEMENT: client_gid=%d", ms->client_gid);
1946
 
          ASSERT (ms->client_gid >= 0);
1947
 
        }
1948
 
 
1949
 
      ms->write_peer_info_file = string_alloc (write_peer_info_file, NULL);
1950
 
 
1951
 
#if UNIX_SOCK_SUPPORT
1952
 
      if (ms->flags & MF_UNIX_SOCK)
1953
 
        sockaddr_unix_init (&ms->local_unix, addr);
1954
 
      else
1955
 
#endif
1956
 
        {
1957
 
          /*
1958
 
           * Initialize socket address
1959
 
           */
1960
 
          ms->local.addr.in4.sin_family = AF_INET;
1961
 
          ms->local.addr.in4.sin_addr.s_addr = 0;
1962
 
          ms->local.addr.in4.sin_port = htons (port);
1963
 
 
1964
 
          /*
1965
 
           * Run management over tunnel, or
1966
 
           * separate channel?
1967
 
           */
1968
 
          if (streq (addr, "tunnel") && !(flags & MF_CONNECT_AS_CLIENT))
1969
 
            {
1970
 
              ms->management_over_tunnel = true;
1971
 
            }
1972
 
          else
1973
 
            {
1974
 
              ms->local.addr.in4.sin_addr.s_addr = getaddr
1975
 
                (GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, NULL, NULL);
1976
 
            }
1977
 
        }
1978
 
      
1979
 
      /*
1980
 
       * Log history and echo buffer may need to be resized
1981
 
       */
1982
 
      ms->log_history_cache = log_history_cache;
1983
 
      ms->echo_buffer_size = echo_buffer_size;
1984
 
      ms->state_buffer_size = state_buffer_size;
1985
 
 
1986
 
      /*
1987
 
       * Set remap sigusr1 flags
1988
 
       */
1989
 
      if (remap_sigusr1 == SIGHUP)
1990
 
        ms->mansig |= MANSIG_MAP_USR1_TO_HUP;
1991
 
      else if (remap_sigusr1 == SIGTERM)
1992
 
        ms->mansig |= MANSIG_MAP_USR1_TO_TERM;
1993
 
 
1994
 
      ms->defined = true;
1995
 
    }
1996
 
}
1997
 
 
1998
 
static void
1999
 
man_settings_close (struct man_settings *ms)
2000
 
{
2001
 
  free (ms->write_peer_info_file);
2002
 
  CLEAR (*ms);
2003
 
}
2004
 
 
2005
 
 
2006
 
static void
2007
 
man_connection_init (struct management *man)
2008
 
{
2009
 
  if (man->connection.state == MS_INITIAL)
2010
 
    {
2011
 
#ifdef WIN32
2012
 
      /*
2013
 
       * This object is a sort of TCP/IP helper
2014
 
       * for Windows.
2015
 
       */
2016
 
      net_event_win32_init (&man->connection.ne32);
2017
 
#endif
2018
 
 
2019
 
      /*
2020
 
       * Allocate helper objects for command line input and
2021
 
       * command output from/to the socket.
2022
 
       */
2023
 
      man->connection.in = command_line_new (1024);
2024
 
      man->connection.out = buffer_list_new (0);
2025
 
 
2026
 
      /*
2027
 
       * Initialize event set for standalone usage, when we are
2028
 
       * running outside of the primary event loop.
2029
 
       */
2030
 
      {
2031
 
        int maxevents = 1;
2032
 
        man->connection.es = event_set_init (&maxevents, EVENT_METHOD_FAST);
2033
 
      }
2034
 
 
2035
 
      /*
2036
 
       * Listen/connect socket
2037
 
       */
2038
 
      if (man->settings.flags & MF_CONNECT_AS_CLIENT)
2039
 
        man_connect (man);
2040
 
      else
2041
 
        man_listen (man);
2042
 
    }
2043
 
}
2044
 
 
2045
 
static void
2046
 
man_connection_close (struct management *man)
2047
 
{
2048
 
  struct man_connection *mc = &man->connection;
2049
 
 
2050
 
  if (mc->es)
2051
 
    event_free (mc->es);
2052
 
#ifdef WIN32
2053
 
  net_event_win32_close (&mc->ne32);
2054
 
#endif
2055
 
  if (socket_defined (mc->sd_top))
2056
 
    {
2057
 
      man_close_socket (man, mc->sd_top);
2058
 
      man_delete_unix_socket (man);
2059
 
    }
2060
 
  if (socket_defined (mc->sd_cli))
2061
 
    man_close_socket (man, mc->sd_cli);
2062
 
  if (mc->in)
2063
 
    command_line_free (mc->in);
2064
 
  if (mc->out)
2065
 
    buffer_list_free (mc->out);
2066
 
#ifdef MANAGEMENT_DEF_AUTH
2067
 
  in_extra_reset (&man->connection, false);
2068
 
#endif
2069
 
  man_connection_clear (mc);
2070
 
}
2071
 
 
2072
 
struct management *
2073
 
management_init (void)
2074
 
{
2075
 
  struct management *man;
2076
 
  ALLOC_OBJ_CLEAR (man, struct management);
2077
 
 
2078
 
  man_persist_init (man,
2079
 
                    MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
2080
 
                    MANAGEMENT_ECHO_BUFFER_SIZE,
2081
 
                    MANAGEMENT_STATE_BUFFER_SIZE);
2082
 
 
2083
 
  man_connection_clear (&man->connection);
2084
 
 
2085
 
  return man;
2086
 
}
2087
 
 
2088
 
bool
2089
 
management_open (struct management *man,
2090
 
                 const char *addr,
2091
 
                 const int port,
2092
 
                 const char *pass_file,
2093
 
                 const char *client_user,
2094
 
                 const char *client_group,
2095
 
                 const int log_history_cache,
2096
 
                 const int echo_buffer_size,
2097
 
                 const int state_buffer_size,
2098
 
                 const char *write_peer_info_file,
2099
 
                 const int remap_sigusr1,
2100
 
                 const unsigned int flags)
2101
 
{
2102
 
  bool ret = false;
2103
 
 
2104
 
  /*
2105
 
   * Save the settings only if they have not
2106
 
   * been saved before.
2107
 
   */
2108
 
  man_settings_init (&man->settings,
2109
 
                     addr,
2110
 
                     port,
2111
 
                     pass_file,
2112
 
                     client_user,
2113
 
                     client_group,
2114
 
                     log_history_cache,
2115
 
                     echo_buffer_size,
2116
 
                     state_buffer_size,
2117
 
                     write_peer_info_file,
2118
 
                     remap_sigusr1,
2119
 
                     flags);
2120
 
 
2121
 
  /*
2122
 
   * The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
2123
 
   * but may be changed here.  Ditto for echo and state buffers.
2124
 
   */
2125
 
  log_history_resize (man->persist.log, man->settings.log_history_cache);
2126
 
  log_history_resize (man->persist.echo, man->settings.echo_buffer_size);
2127
 
  log_history_resize (man->persist.state, man->settings.state_buffer_size);
2128
 
 
2129
 
  /*
2130
 
   * If connection object is uninitialized and we are not doing
2131
 
   * over-the-tunnel management, then open (listening) connection.
2132
 
   */
2133
 
  if (man->connection.state == MS_INITIAL)
2134
 
    {
2135
 
      if (!man->settings.management_over_tunnel)
2136
 
        {
2137
 
          man_connection_init (man);
2138
 
          ret = true;
2139
 
        }
2140
 
    }
2141
 
 
2142
 
  return ret;
2143
 
}
2144
 
 
2145
 
void
2146
 
management_close (struct management *man)
2147
 
{
2148
 
  man_connection_close (man);
2149
 
  man_settings_close (&man->settings);
2150
 
  man_persist_close (&man->persist);
2151
 
  free (man);
2152
 
}
2153
 
 
2154
 
void
2155
 
management_set_callback (struct management *man,
2156
 
                         const struct management_callback *cb)
2157
 
{
2158
 
  man->persist.standalone_disabled = true;
2159
 
  man->persist.callback = *cb;
2160
 
}
2161
 
 
2162
 
void
2163
 
management_clear_callback (struct management *man)
2164
 
{
2165
 
  man->persist.standalone_disabled = false;
2166
 
  man->persist.hold_release = false;
2167
 
  CLEAR (man->persist.callback);
2168
 
  man_output_list_push_finalize (man); /* flush output queue */
2169
 
}
2170
 
 
2171
 
void
2172
 
management_set_state (struct management *man,
2173
 
                      const int state,
2174
 
                      const char *detail,
2175
 
                      const in_addr_t tun_local_ip,
2176
 
                      const in_addr_t tun_remote_ip)
2177
 
{
2178
 
  if (man->persist.state && (!(man->settings.flags & MF_SERVER) || state < OPENVPN_STATE_CLIENT_BASE))
2179
 
    {
2180
 
      struct gc_arena gc = gc_new ();
2181
 
      struct log_entry e;
2182
 
      const char *out = NULL;
2183
 
 
2184
 
      update_time ();
2185
 
      CLEAR (e);
2186
 
      e.timestamp = now;
2187
 
      e.u.state = state;
2188
 
      e.string = detail;
2189
 
      e.local_ip = tun_local_ip;
2190
 
      e.remote_ip = tun_remote_ip;
2191
 
      
2192
 
      log_history_add (man->persist.state, &e);
2193
 
 
2194
 
      if (man->connection.state_realtime)
2195
 
        out = log_entry_print (&e, LOG_PRINT_STATE_PREFIX
2196
 
                               |   LOG_PRINT_INT_DATE
2197
 
                               |   LOG_PRINT_STATE
2198
 
                               |   LOG_PRINT_LOCAL_IP
2199
 
                               |   LOG_PRINT_REMOTE_IP
2200
 
                               |   LOG_PRINT_CRLF
2201
 
                               |   LOG_ECHO_TO_LOG, &gc);
2202
 
 
2203
 
      if (out)
2204
 
        man_output_list_push (man, out);
2205
 
 
2206
 
      gc_free (&gc);
2207
 
    }
2208
 
}
2209
 
 
2210
 
#ifdef MANAGEMENT_DEF_AUTH
2211
 
 
2212
 
static bool
2213
 
env_filter_match (const char *env_str, const int env_filter_level)
2214
 
{
2215
 
  static const char *env_names[] = {
2216
 
    "username=",
2217
 
    "password=",
2218
 
    "X509_0_CN=",
2219
 
    "tls_serial_0=",
2220
 
    "untrusted_ip=",
2221
 
    "ifconfig_local=",
2222
 
    "ifconfig_netmask=",
2223
 
    "daemon_start_time=",
2224
 
    "daemon_pid=",
2225
 
    "dev=",
2226
 
    "ifconfig_pool_remote_ip=",
2227
 
    "ifconfig_pool_netmask=",
2228
 
    "time_duration=",
2229
 
    "bytes_sent=",
2230
 
    "bytes_received="
2231
 
  };
2232
 
  if (env_filter_level >= 1)
2233
 
    {
2234
 
      size_t i;
2235
 
      for (i = 0; i < SIZE(env_names); ++i)
2236
 
        {
2237
 
          const char *en = env_names[i];
2238
 
          const size_t len = strlen(en);
2239
 
          if (strncmp(env_str, en, len) == 0)
2240
 
            return true;
2241
 
        }
2242
 
      return false;
2243
 
    }
2244
 
  else
2245
 
    return true;
2246
 
}
2247
 
 
2248
 
static void
2249
 
man_output_env (const struct env_set *es, const bool tail, const int env_filter_level)
2250
 
{
2251
 
  if (es)
2252
 
    {
2253
 
      struct env_item *e;
2254
 
      for (e = es->list; e != NULL; e = e->next)
2255
 
        {
2256
 
          if (e->string && (!env_filter_level || env_filter_match(e->string, env_filter_level)))
2257
 
            msg (M_CLIENT, ">CLIENT:ENV,%s", e->string);
2258
 
        }
2259
 
    }
2260
 
  if (tail)
2261
 
    msg (M_CLIENT, ">CLIENT:ENV,END");
2262
 
}
2263
 
 
2264
 
static void
2265
 
man_output_extra_env (struct management *man)
2266
 
{
2267
 
  struct gc_arena gc = gc_new ();
2268
 
  struct env_set *es = env_set_create (&gc);
2269
 
  if (man->persist.callback.n_clients)
2270
 
    {
2271
 
      const int nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg);
2272
 
      setenv_int (es, "n_clients", nclients);
2273
 
    }
2274
 
  man_output_env (es, false, man->connection.env_filter_level);
2275
 
  gc_free (&gc);
2276
 
}
2277
 
 
2278
 
static bool
2279
 
validate_peer_info_line(const char *line)
2280
 
{
2281
 
  uint8_t c;
2282
 
  int state = 0;
2283
 
  while ((c=*line++))
2284
 
    {
2285
 
      switch (state)
2286
 
        {
2287
 
        case 0:
2288
 
        case 1:
2289
 
          if (c == '=' && state == 1)
2290
 
            state = 2;
2291
 
          else if (isalnum(c) || c == '_')
2292
 
            state = 1;
2293
 
          else
2294
 
            return false;
2295
 
        case 2:
2296
 
          if (isprint(c))
2297
 
            ;
2298
 
          else
2299
 
            return false;
2300
 
        }
2301
 
    }
2302
 
  return (state == 2);
2303
 
}
2304
 
 
2305
 
static void
2306
 
man_output_peer_info_env (struct management *man, struct man_def_auth_context *mdac)
2307
 
{
2308
 
  char line[256];
2309
 
  if (man->persist.callback.get_peer_info)
2310
 
    {
2311
 
      const char *peer_info = (*man->persist.callback.get_peer_info) (man->persist.callback.arg, mdac->cid);
2312
 
      if (peer_info)
2313
 
        {
2314
 
          struct buffer buf;
2315
 
          buf_set_read (&buf, (const uint8_t *) peer_info, strlen(peer_info));
2316
 
          while (buf_parse (&buf, '\n', line, sizeof (line)))
2317
 
            {
2318
 
              chomp (line);
2319
 
              if (validate_peer_info_line(line))
2320
 
                {
2321
 
                  msg (M_CLIENT, ">CLIENT:ENV,%s", line);
2322
 
                }
2323
 
              else
2324
 
                msg (D_MANAGEMENT, "validation failed on peer_info line received from client");
2325
 
            }
2326
 
        }
2327
 
    }
2328
 
}
2329
 
 
2330
 
void
2331
 
management_notify_client_needing_auth (struct management *management,
2332
 
                                       const unsigned int mda_key_id,
2333
 
                                       struct man_def_auth_context *mdac,
2334
 
                                       const struct env_set *es)
2335
 
{
2336
 
  if (!(mdac->flags & DAF_CONNECTION_CLOSED))
2337
 
    {
2338
 
      const char *mode = "CONNECT";
2339
 
      if (mdac->flags & DAF_CONNECTION_ESTABLISHED)
2340
 
        mode = "REAUTH";
2341
 
      msg (M_CLIENT, ">CLIENT:%s,%lu,%u", mode, mdac->cid, mda_key_id);
2342
 
      man_output_extra_env (management);
2343
 
      man_output_peer_info_env(management, mdac);
2344
 
      man_output_env (es, true, management->connection.env_filter_level);
2345
 
      mdac->flags |= DAF_INITIAL_AUTH;
2346
 
    }
2347
 
}
2348
 
 
2349
 
void
2350
 
management_connection_established (struct management *management,
2351
 
                                   struct man_def_auth_context *mdac,
2352
 
                                   const struct env_set *es)
2353
 
{
2354
 
  mdac->flags |= DAF_CONNECTION_ESTABLISHED;
2355
 
  msg (M_CLIENT, ">CLIENT:ESTABLISHED,%lu", mdac->cid);
2356
 
  man_output_extra_env (management);
2357
 
  man_output_env (es, true, management->connection.env_filter_level);
2358
 
}
2359
 
 
2360
 
void
2361
 
management_notify_client_close (struct management *management,
2362
 
                                struct man_def_auth_context *mdac,
2363
 
                                const struct env_set *es)
2364
 
{
2365
 
  if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED))
2366
 
    {
2367
 
      msg (M_CLIENT, ">CLIENT:DISCONNECT,%lu", mdac->cid);
2368
 
      man_output_env (es, true, management->connection.env_filter_level);
2369
 
      mdac->flags |= DAF_CONNECTION_CLOSED;
2370
 
    }
2371
 
}
2372
 
 
2373
 
void
2374
 
management_learn_addr (struct management *management,
2375
 
                       struct man_def_auth_context *mdac,
2376
 
                       const struct mroute_addr *addr,
2377
 
                       const bool primary)
2378
 
{
2379
 
  struct gc_arena gc = gc_new ();
2380
 
  if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED))
2381
 
    {
2382
 
      msg (M_CLIENT, ">CLIENT:ADDRESS,%lu,%s,%d",
2383
 
           mdac->cid,
2384
 
           mroute_addr_print_ex (addr, MAPF_SUBNET, &gc),
2385
 
           BOOL_CAST (primary));
2386
 
    }
2387
 
  gc_free (&gc);
2388
 
}
2389
 
 
2390
 
#endif
2391
 
 
2392
 
void
2393
 
management_echo (struct management *man, const char *string, const bool pull)
2394
 
{
2395
 
  if (man->persist.echo)
2396
 
    {
2397
 
      struct gc_arena gc = gc_new ();
2398
 
      struct log_entry e;
2399
 
      const char *out = NULL;
2400
 
 
2401
 
      update_time ();
2402
 
      CLEAR (e);
2403
 
      e.timestamp = now;
2404
 
      e.string = string;
2405
 
      e.u.intval = BOOL_CAST (pull);
2406
 
 
2407
 
      log_history_add (man->persist.echo, &e);
2408
 
 
2409
 
      if (man->connection.echo_realtime)
2410
 
        out = log_entry_print (&e, LOG_PRINT_INT_DATE|LOG_PRINT_ECHO_PREFIX|LOG_PRINT_CRLF|MANAGEMENT_ECHO_FLAGS, &gc);
2411
 
 
2412
 
      if (out)
2413
 
        man_output_list_push (man, out);
2414
 
 
2415
 
      gc_free (&gc);
2416
 
    }
2417
 
}
2418
 
 
2419
 
void
2420
 
management_post_tunnel_open (struct management *man, const in_addr_t tun_local_ip)
2421
 
{
2422
 
  /*
2423
 
   * If we are running management over the tunnel,
2424
 
   * this is the place to initialize the connection.
2425
 
   */
2426
 
  if (man->settings.management_over_tunnel
2427
 
      && man->connection.state == MS_INITIAL)
2428
 
    {
2429
 
      /* listen on our local TUN/TAP IP address */
2430
 
      man->settings.local.addr.in4.sin_addr.s_addr = htonl (tun_local_ip);
2431
 
      man_connection_init (man);
2432
 
    }
2433
 
 
2434
 
}
2435
 
 
2436
 
void
2437
 
management_pre_tunnel_close (struct management *man)
2438
 
{
2439
 
  if (man->settings.management_over_tunnel)
2440
 
    man_connection_close (man);
2441
 
}
2442
 
 
2443
 
void
2444
 
management_auth_failure (struct management *man, const char *type, const char *reason)
2445
 
{
2446
 
  if (reason)
2447
 
    msg (M_CLIENT, ">PASSWORD:Verification Failed: '%s' ['%s']", type, reason);
2448
 
  else
2449
 
    msg (M_CLIENT, ">PASSWORD:Verification Failed: '%s'", type);
2450
 
}
2451
 
 
2452
 
static inline bool
2453
 
man_persist_state (unsigned int *persistent, const int n)
2454
 
{
2455
 
  if (persistent)
2456
 
    {
2457
 
      if (*persistent == (unsigned int)n)
2458
 
        return false;
2459
 
      *persistent = n;
2460
 
    }
2461
 
  return true;
2462
 
}
2463
 
 
2464
 
#ifdef WIN32
2465
 
 
2466
 
void
2467
 
management_socket_set (struct management *man,
2468
 
                       struct event_set *es,
2469
 
                       void *arg,
2470
 
                       unsigned int *persistent)
2471
 
{
2472
 
  if (man->connection.state != MS_INITIAL)
2473
 
    {
2474
 
      event_t ev = net_event_win32_get_event (&man->connection.ne32);
2475
 
      net_event_win32_reset_write (&man->connection.ne32);
2476
 
 
2477
 
      switch (man->connection.state)
2478
 
        {
2479
 
        case MS_LISTEN:
2480
 
          if (man_persist_state (persistent, 1))
2481
 
            event_ctl (es, ev, EVENT_READ, arg);
2482
 
          break;
2483
 
        case MS_CC_WAIT_READ:
2484
 
          if (man_persist_state (persistent, 2))
2485
 
            event_ctl (es, ev, EVENT_READ, arg);
2486
 
          break;
2487
 
        case MS_CC_WAIT_WRITE:
2488
 
          if (man_persist_state (persistent, 3))
2489
 
            event_ctl (es, ev, EVENT_READ|EVENT_WRITE, arg);
2490
 
          break;
2491
 
        default:
2492
 
          ASSERT (0);
2493
 
        }
2494
 
    }
2495
 
}
2496
 
 
2497
 
void
2498
 
management_io (struct management *man)
2499
 
{
2500
 
  if (man->connection.state != MS_INITIAL)
2501
 
    {
2502
 
      long net_events;
2503
 
      net_event_win32_reset (&man->connection.ne32);
2504
 
      net_events = net_event_win32_get_event_mask (&man->connection.ne32);
2505
 
 
2506
 
      if (net_events & FD_CLOSE)
2507
 
        {
2508
 
          man_reset_client_socket (man, false);
2509
 
        }
2510
 
      else
2511
 
        {
2512
 
          if (man->connection.state == MS_LISTEN)
2513
 
            {
2514
 
              if (net_events & FD_ACCEPT)
2515
 
                {
2516
 
                  man_accept (man);
2517
 
                  net_event_win32_clear_selected_events (&man->connection.ne32, FD_ACCEPT);
2518
 
                }
2519
 
            }
2520
 
          else if (man->connection.state == MS_CC_WAIT_READ || man->connection.state == MS_CC_WAIT_WRITE)
2521
 
            {
2522
 
              if (net_events & FD_READ)
2523
 
                {
2524
 
                  while (man_read (man) > 0)
2525
 
                    ;
2526
 
                  net_event_win32_clear_selected_events (&man->connection.ne32, FD_READ);
2527
 
                }
2528
 
 
2529
 
              if (net_events & FD_WRITE)
2530
 
                {
2531
 
                  int status;
2532
 
                  status = man_write (man);
2533
 
                  if (status < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
2534
 
                    {
2535
 
                      net_event_win32_clear_selected_events (&man->connection.ne32, FD_WRITE);
2536
 
                    }
2537
 
                }
2538
 
            }
2539
 
        }
2540
 
    }
2541
 
}
2542
 
 
2543
 
#else
2544
 
 
2545
 
void
2546
 
management_socket_set (struct management *man,
2547
 
                       struct event_set *es,
2548
 
                       void *arg,
2549
 
                       unsigned int *persistent)
2550
 
{
2551
 
  switch (man->connection.state)
2552
 
    {
2553
 
    case MS_LISTEN:
2554
 
      if (man_persist_state (persistent, 1))
2555
 
        event_ctl (es, man->connection.sd_top, EVENT_READ, arg);
2556
 
      break;
2557
 
    case MS_CC_WAIT_READ:
2558
 
      if (man_persist_state (persistent, 2))
2559
 
        event_ctl (es, man->connection.sd_cli, EVENT_READ, arg);
2560
 
      break;
2561
 
    case MS_CC_WAIT_WRITE:
2562
 
      if (man_persist_state (persistent, 3))
2563
 
        event_ctl (es, man->connection.sd_cli, EVENT_WRITE, arg);
2564
 
      break;
2565
 
    case MS_INITIAL:
2566
 
      break;
2567
 
    default:
2568
 
      ASSERT (0);
2569
 
    }
2570
 
}
2571
 
 
2572
 
void
2573
 
management_io (struct management *man)
2574
 
{
2575
 
  switch (man->connection.state)
2576
 
    {
2577
 
    case MS_LISTEN:
2578
 
      man_accept (man);
2579
 
      break;
2580
 
    case MS_CC_WAIT_READ:
2581
 
      man_read (man);
2582
 
      break;
2583
 
    case MS_CC_WAIT_WRITE:
2584
 
      man_write (man);
2585
 
      break;
2586
 
    case MS_INITIAL:
2587
 
      break;
2588
 
    default:
2589
 
      ASSERT (0);
2590
 
    }
2591
 
}
2592
 
 
2593
 
#endif
2594
 
 
2595
 
static inline bool
2596
 
man_standalone_ok (const struct management *man)
2597
 
{
2598
 
  return !man->settings.management_over_tunnel && man->connection.state != MS_INITIAL;
2599
 
}
2600
 
 
2601
 
static bool
2602
 
man_check_for_signals (volatile int *signal_received)
2603
 
{
2604
 
  if (signal_received)
2605
 
    {
2606
 
      get_signal (signal_received);
2607
 
      if (*signal_received)
2608
 
        return true;
2609
 
    }
2610
 
  return false;
2611
 
}
2612
 
 
2613
 
/*
2614
 
 * Wait for socket I/O when outside primary event loop
2615
 
 */
2616
 
static int
2617
 
man_block (struct management *man, volatile int *signal_received, const time_t expire)
2618
 
{
2619
 
  struct timeval tv;
2620
 
  struct event_set_return esr;
2621
 
  int status = -1;
2622
 
  
2623
 
  if (man_standalone_ok (man))
2624
 
    {
2625
 
      while (true)
2626
 
        {
2627
 
          event_reset (man->connection.es);
2628
 
          management_socket_set (man, man->connection.es, NULL, NULL);
2629
 
          tv.tv_usec = 0;
2630
 
          tv.tv_sec = 1;
2631
 
          if (man_check_for_signals (signal_received))
2632
 
            {
2633
 
              status = -1;
2634
 
              break;
2635
 
            }
2636
 
          status = event_wait (man->connection.es, &tv, &esr, 1);
2637
 
          update_time ();
2638
 
          if (man_check_for_signals (signal_received))
2639
 
            {
2640
 
              status = -1;
2641
 
              break;
2642
 
            }
2643
 
 
2644
 
          if (status > 0)
2645
 
            break;
2646
 
          else if (expire && now >= expire)
2647
 
            {
2648
 
              /* set SIGINT signal if expiration time exceeded */
2649
 
              status = 0;
2650
 
              if (signal_received)
2651
 
                *signal_received = SIGINT;
2652
 
              break;
2653
 
            }
2654
 
        }
2655
 
    }
2656
 
  return status;
2657
 
}
2658
 
 
2659
 
/*
2660
 
 * Perform management socket output outside primary event loop
2661
 
 */
2662
 
static void
2663
 
man_output_standalone (struct management *man, volatile int *signal_received)
2664
 
{
2665
 
  if (man_standalone_ok (man))
2666
 
    {
2667
 
      while (man->connection.state == MS_CC_WAIT_WRITE)
2668
 
        {
2669
 
          management_io (man);
2670
 
          if (man->connection.state == MS_CC_WAIT_WRITE)
2671
 
            man_block (man, signal_received, 0);
2672
 
          if (signal_received && *signal_received)
2673
 
            break;
2674
 
        }
2675
 
    }
2676
 
}
2677
 
 
2678
 
/*
2679
 
 * Process management event loop outside primary event loop
2680
 
 */
2681
 
static int
2682
 
man_standalone_event_loop (struct management *man, volatile int *signal_received, const time_t expire)
2683
 
{
2684
 
  int status = -1;
2685
 
  if (man_standalone_ok (man))
2686
 
    {
2687
 
      status = man_block (man, signal_received, expire);
2688
 
      if (status > 0)
2689
 
        management_io (man);
2690
 
    }
2691
 
  return status;
2692
 
}
2693
 
 
2694
 
#define MWCC_PASSWORD_WAIT (1<<0)
2695
 
#define MWCC_HOLD_WAIT     (1<<1)
2696
 
 
2697
 
/*
2698
 
 * Block until client connects
2699
 
 */
2700
 
static void
2701
 
man_wait_for_client_connection (struct management *man,
2702
 
                                volatile int *signal_received,
2703
 
                                const time_t expire,
2704
 
                                unsigned int flags)
2705
 
{
2706
 
  ASSERT (man_standalone_ok (man));
2707
 
  if (man->connection.state == MS_LISTEN)
2708
 
    {
2709
 
      if (flags & MWCC_PASSWORD_WAIT)
2710
 
        msg (D_MANAGEMENT, "Need password(s) from management interface, waiting...");
2711
 
      if (flags & MWCC_HOLD_WAIT)
2712
 
        msg (D_MANAGEMENT, "Need hold release from management interface, waiting...");
2713
 
      do {
2714
 
        man_standalone_event_loop (man, signal_received, expire);
2715
 
        if (signal_received && *signal_received)
2716
 
          break;
2717
 
      } while (man->connection.state == MS_LISTEN || man_password_needed (man));
2718
 
    }
2719
 
}
2720
 
 
2721
 
/*
2722
 
 * Process the management event loop for sec seconds
2723
 
 */
2724
 
void
2725
 
management_event_loop_n_seconds (struct management *man, int sec)
2726
 
{
2727
 
  if (man_standalone_ok (man))
2728
 
    {
2729
 
      volatile int signal_received = 0;
2730
 
      const bool standalone_disabled_save = man->persist.standalone_disabled;
2731
 
      time_t expire = 0;
2732
 
 
2733
 
      man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
2734
 
 
2735
 
      /* set expire time */
2736
 
      update_time ();
2737
 
      if (sec)
2738
 
        expire = now + sec;
2739
 
 
2740
 
      /* if no client connection, wait for one */
2741
 
      man_wait_for_client_connection (man, &signal_received, expire, 0);
2742
 
      if (signal_received)
2743
 
        return;
2744
 
 
2745
 
      /* run command processing event loop */
2746
 
      do
2747
 
        {
2748
 
          man_standalone_event_loop (man, &signal_received, expire);
2749
 
          if (!signal_received)
2750
 
            man_check_for_signals (&signal_received);
2751
 
          if (signal_received)
2752
 
            return;
2753
 
        } while (expire);
2754
 
 
2755
 
      /* revert state */
2756
 
      man->persist.standalone_disabled = standalone_disabled_save;
2757
 
    }
2758
 
  else
2759
 
    {
2760
 
      sleep (sec);
2761
 
    }
2762
 
}
2763
 
 
2764
 
/*
2765
 
 * Get a username/password from management channel in standalone mode.
2766
 
 */
2767
 
bool
2768
 
management_query_user_pass (struct management *man,
2769
 
                            struct user_pass *up,
2770
 
                            const char *type,
2771
 
                            const unsigned int flags)
2772
 
{
2773
 
  struct gc_arena gc = gc_new ();
2774
 
  bool ret = false;
2775
 
 
2776
 
  if (man_standalone_ok (man))
2777
 
    {
2778
 
      volatile int signal_received = 0;
2779
 
      const bool standalone_disabled_save = man->persist.standalone_disabled;
2780
 
      struct buffer alert_msg = alloc_buf_gc (128, &gc);
2781
 
      const char *alert_type = NULL;
2782
 
      const char *prefix = NULL;
2783
 
      unsigned int up_query_mode = 0;
2784
 
 
2785
 
      ret = true;
2786
 
      man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
2787
 
      man->persist.special_state_msg = NULL;
2788
 
 
2789
 
      CLEAR (man->connection.up_query);
2790
 
 
2791
 
      if (flags & GET_USER_PASS_NEED_OK)
2792
 
        {
2793
 
          up_query_mode = UP_QUERY_NEED_OK;
2794
 
          prefix= "NEED-OK";
2795
 
          alert_type = "confirmation";
2796
 
        }
2797
 
      else if (flags & GET_USER_PASS_NEED_STR)
2798
 
        {
2799
 
          up_query_mode = UP_QUERY_NEED_STR;
2800
 
          prefix= "NEED-STR";
2801
 
          alert_type = "string";
2802
 
        }
2803
 
      else if (flags & GET_USER_PASS_PASSWORD_ONLY)
2804
 
        {
2805
 
          up_query_mode = UP_QUERY_PASS;
2806
 
          prefix = "PASSWORD";
2807
 
          alert_type = "password";
2808
 
        }
2809
 
      else
2810
 
        {
2811
 
          up_query_mode = UP_QUERY_USER_PASS;
2812
 
          prefix = "PASSWORD";
2813
 
          alert_type = "username/password";
2814
 
        }
2815
 
      buf_printf (&alert_msg, ">%s:Need '%s' %s",
2816
 
                  prefix,
2817
 
                  type,
2818
 
                  alert_type);
2819
 
 
2820
 
      if (flags & (GET_USER_PASS_NEED_OK | GET_USER_PASS_NEED_STR))
2821
 
        buf_printf (&alert_msg, " MSG:%s", up->username);
2822
 
 
2823
 
      man_wait_for_client_connection (man, &signal_received, 0, MWCC_PASSWORD_WAIT);
2824
 
      if (signal_received)
2825
 
        ret = false;
2826
 
 
2827
 
      if (ret)
2828
 
        {
2829
 
          man->persist.special_state_msg = BSTR (&alert_msg);
2830
 
          msg (M_CLIENT, "%s", man->persist.special_state_msg);
2831
 
 
2832
 
          /* tell command line parser which info we need */
2833
 
          man->connection.up_query_mode = up_query_mode;
2834
 
          man->connection.up_query_type = type;
2835
 
 
2836
 
          /* run command processing event loop until we get our username/password */
2837
 
          do
2838
 
            {
2839
 
              man_standalone_event_loop (man, &signal_received, 0);
2840
 
              if (!signal_received)
2841
 
                man_check_for_signals (&signal_received);
2842
 
              if (signal_received)
2843
 
                {
2844
 
                  ret = false;
2845
 
                  break;
2846
 
                }
2847
 
            } while (!man->connection.up_query.defined);
2848
 
        }
2849
 
 
2850
 
      /* revert state */
2851
 
      man->connection.up_query_mode = UP_QUERY_DISABLED;
2852
 
      man->connection.up_query_type = NULL;
2853
 
      man->persist.standalone_disabled = standalone_disabled_save;
2854
 
      man->persist.special_state_msg = NULL;
2855
 
 
2856
 
      /* pass through blank passwords */
2857
 
      if (!strcmp (man->connection.up_query.password, blank_up))
2858
 
        CLEAR (man->connection.up_query.password);
2859
 
 
2860
 
      /*
2861
 
       * Transfer u/p to return object, zero any record
2862
 
       * we hold in the management object.
2863
 
       */
2864
 
      if (ret)
2865
 
        {
2866
 
          man->connection.up_query.nocache = up->nocache; /* preserve caller's nocache setting */
2867
 
          *up = man->connection.up_query;
2868
 
        }
2869
 
      CLEAR (man->connection.up_query);
2870
 
    }
2871
 
 
2872
 
  gc_free (&gc);
2873
 
  return ret;
2874
 
}
2875
 
 
2876
 
/*
2877
 
 * Return true if management_hold() would block
2878
 
 */
2879
 
bool
2880
 
management_would_hold (struct management *man)
2881
 
{
2882
 
  return (man->settings.flags & MF_HOLD) && !man->persist.hold_release && man_standalone_ok (man);
2883
 
}
2884
 
 
2885
 
/*
2886
 
 * Return true if (from the management interface's perspective) OpenVPN should
2887
 
 * daemonize.
2888
 
 */
2889
 
bool
2890
 
management_should_daemonize (struct management *man)
2891
 
{
2892
 
  return management_would_hold (man) || (man->settings.flags & MF_QUERY_PASSWORDS);
2893
 
}
2894
 
 
2895
 
/*
2896
 
 * If the hold flag is enabled, hibernate until a management client releases the hold.
2897
 
 * Return true if the caller should not sleep for an additional time interval.
2898
 
 */
2899
 
bool
2900
 
management_hold (struct management *man)
2901
 
{
2902
 
  if (management_would_hold (man))
2903
 
    {
2904
 
      volatile int signal_received = 0;
2905
 
      const bool standalone_disabled_save = man->persist.standalone_disabled;
2906
 
 
2907
 
      man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
2908
 
      man->persist.special_state_msg = NULL;
2909
 
      man->settings.mansig |= MANSIG_IGNORE_USR1_HUP;
2910
 
 
2911
 
      man_wait_for_client_connection (man, &signal_received, 0, MWCC_HOLD_WAIT);
2912
 
 
2913
 
      if (!signal_received)
2914
 
        {
2915
 
          man->persist.special_state_msg = ">HOLD:Waiting for hold release";
2916
 
          msg (M_CLIENT, "%s", man->persist.special_state_msg);
2917
 
 
2918
 
          /* run command processing event loop until we get our username/password */
2919
 
          do
2920
 
            {
2921
 
              man_standalone_event_loop (man, &signal_received, 0);
2922
 
              if (!signal_received)
2923
 
                man_check_for_signals (&signal_received);
2924
 
              if (signal_received)
2925
 
                break;
2926
 
            } while (!man->persist.hold_release);
2927
 
        }
2928
 
 
2929
 
      /* revert state */
2930
 
      man->persist.standalone_disabled = standalone_disabled_save;
2931
 
      man->persist.special_state_msg = NULL;
2932
 
      man->settings.mansig &= ~MANSIG_IGNORE_USR1_HUP;
2933
 
 
2934
 
      return true;
2935
 
    }
2936
 
  return false;
2937
 
}
2938
 
 
2939
 
/*
2940
 
 * struct command_line
2941
 
 */
2942
 
 
2943
 
struct command_line *
2944
 
command_line_new (const int buf_len)
2945
 
{
2946
 
  struct command_line *cl;
2947
 
  ALLOC_OBJ_CLEAR (cl, struct command_line);
2948
 
  cl->buf = alloc_buf (buf_len);
2949
 
  cl->residual = alloc_buf (buf_len);
2950
 
  return cl;
2951
 
}
2952
 
 
2953
 
void
2954
 
command_line_reset (struct command_line *cl)
2955
 
{
2956
 
  buf_clear (&cl->buf);
2957
 
  buf_clear (&cl->residual);
2958
 
}
2959
 
 
2960
 
void
2961
 
command_line_free (struct command_line *cl)
2962
 
{
2963
 
  command_line_reset (cl);
2964
 
  free_buf (&cl->buf);
2965
 
  free_buf (&cl->residual);
2966
 
  free (cl);
2967
 
}
2968
 
 
2969
 
void
2970
 
command_line_add (struct command_line *cl, const unsigned char *buf, const int len)
2971
 
{
2972
 
  int i;
2973
 
  for (i = 0; i < len; ++i)
2974
 
    {
2975
 
      if (buf[i] && (isprint(buf[i]) || buf[i] == '\n'))
2976
 
        {
2977
 
          if (!buf_write_u8 (&cl->buf, buf[i]))
2978
 
            buf_clear (&cl->buf);
2979
 
        }
2980
 
    }
2981
 
}
2982
 
 
2983
 
const unsigned char *
2984
 
command_line_get (struct command_line *cl)
2985
 
{
2986
 
  int i;
2987
 
  const unsigned char *ret = NULL;
2988
 
 
2989
 
  i = buf_substring_len (&cl->buf, '\n');
2990
 
  if (i >= 0)
2991
 
    {
2992
 
      buf_copy_excess (&cl->residual, &cl->buf, i);
2993
 
      buf_chomp (&cl->buf);
2994
 
      ret = (const unsigned char *) BSTR (&cl->buf);
2995
 
    }
2996
 
  return ret;
2997
 
}
2998
 
 
2999
 
void
3000
 
command_line_next (struct command_line *cl)
3001
 
{
3002
 
  buf_clear (&cl->buf);
3003
 
  buf_copy (&cl->buf, &cl->residual);
3004
 
  buf_clear (&cl->residual);
3005
 
}
3006
 
 
3007
 
/*
3008
 
 * struct log_entry
3009
 
 */
3010
 
 
3011
 
const char *
3012
 
log_entry_print (const struct log_entry *e, unsigned int flags, struct gc_arena *gc)
3013
 
{
3014
 
  struct buffer out = alloc_buf_gc (ERR_BUF_SIZE, gc);
3015
 
  if (flags & LOG_FATAL_NOTIFY)
3016
 
    buf_printf (&out, ">FATAL:");    
3017
 
  if (flags & LOG_PRINT_LOG_PREFIX)
3018
 
    buf_printf (&out, ">LOG:");
3019
 
  if (flags & LOG_PRINT_ECHO_PREFIX)
3020
 
    buf_printf (&out, ">ECHO:");
3021
 
  if (flags & LOG_PRINT_STATE_PREFIX)
3022
 
    buf_printf (&out, ">STATE:");
3023
 
  if (flags & LOG_PRINT_INT_DATE)
3024
 
    buf_printf (&out, "%u,", (unsigned int)e->timestamp);
3025
 
  if (flags & LOG_PRINT_MSG_FLAGS)
3026
 
    buf_printf (&out, "%s,", msg_flags_string (e->u.msg_flags, gc));
3027
 
  if (flags & LOG_PRINT_STATE)
3028
 
    buf_printf (&out, "%s,", man_state_name (e->u.state));
3029
 
  if (flags & LOG_PRINT_INTVAL)
3030
 
    buf_printf (&out, "%d,", e->u.intval);
3031
 
  if (e->string)
3032
 
    buf_printf (&out, "%s", e->string);
3033
 
  if (flags & LOG_PRINT_LOCAL_IP)
3034
 
    buf_printf (&out, ",%s", print_in_addr_t (e->local_ip, IA_EMPTY_IF_UNDEF, gc));
3035
 
  if (flags & LOG_PRINT_REMOTE_IP)
3036
 
    buf_printf (&out, ",%s", print_in_addr_t (e->remote_ip, IA_EMPTY_IF_UNDEF, gc));
3037
 
  if (flags & LOG_ECHO_TO_LOG)
3038
 
    msg (D_MANAGEMENT, "MANAGEMENT: %s", BSTR (&out));
3039
 
  if (flags & LOG_PRINT_CRLF)
3040
 
    buf_printf (&out, "\r\n");
3041
 
  return BSTR (&out);
3042
 
}
3043
 
 
3044
 
static void
3045
 
log_entry_free_contents (struct log_entry *e)
3046
 
{
3047
 
  if (e->string)
3048
 
    free ((char *)e->string);
3049
 
  CLEAR (*e);
3050
 
}
3051
 
 
3052
 
/*
3053
 
 * struct log_history
3054
 
 */
3055
 
 
3056
 
static inline int
3057
 
log_index (const struct log_history *h, int i)
3058
 
{
3059
 
  return modulo_add (h->base, i, h->capacity);
3060
 
}
3061
 
 
3062
 
static void
3063
 
log_history_obj_init (struct log_history *h, int capacity)
3064
 
{
3065
 
  CLEAR (*h);
3066
 
  h->capacity = capacity;
3067
 
  ALLOC_ARRAY_CLEAR (h->array, struct log_entry, capacity);
3068
 
}
3069
 
 
3070
 
struct log_history *
3071
 
log_history_init (const int capacity)
3072
 
{
3073
 
  struct log_history *h;
3074
 
  ASSERT (capacity > 0);
3075
 
  ALLOC_OBJ (h, struct log_history);
3076
 
  log_history_obj_init (h, capacity);
3077
 
  return h;
3078
 
}
3079
 
 
3080
 
static void
3081
 
log_history_free_contents (struct log_history *h)
3082
 
{
3083
 
  int i;
3084
 
  for (i = 0; i < h->size; ++i)
3085
 
    log_entry_free_contents (&h->array[log_index(h, i)]);
3086
 
  free (h->array);
3087
 
}
3088
 
 
3089
 
void
3090
 
log_history_close (struct log_history *h)
3091
 
{
3092
 
  log_history_free_contents (h);
3093
 
  free (h);
3094
 
}
3095
 
 
3096
 
void
3097
 
log_history_add (struct log_history *h, const struct log_entry *le)
3098
 
{
3099
 
  struct log_entry *e;
3100
 
  ASSERT (h->size >= 0 && h->size <= h->capacity);
3101
 
  if (h->size == h->capacity)
3102
 
    {
3103
 
      e = &h->array[h->base];
3104
 
      log_entry_free_contents (e);
3105
 
      h->base = log_index (h, 1);
3106
 
    }
3107
 
  else
3108
 
    {
3109
 
      e = &h->array[log_index(h, h->size)];
3110
 
      ++h->size;
3111
 
    }
3112
 
 
3113
 
  *e = *le;
3114
 
  e->string = string_alloc (le->string, NULL);
3115
 
}
3116
 
 
3117
 
void
3118
 
log_history_resize (struct log_history *h, const int capacity)
3119
 
{
3120
 
  if (capacity != h->capacity)
3121
 
    {
3122
 
      struct log_history newlog;
3123
 
      int i;
3124
 
 
3125
 
      ASSERT (capacity > 0);
3126
 
      log_history_obj_init (&newlog, capacity);
3127
 
 
3128
 
      for (i = 0; i < h->size; ++i)
3129
 
        log_history_add (&newlog, &h->array[log_index(h, i)]);
3130
 
                         
3131
 
      log_history_free_contents (h);
3132
 
      *h = newlog;
3133
 
    }
3134
 
}
3135
 
 
3136
 
const struct log_entry *
3137
 
log_history_ref (const struct log_history *h, const int index)
3138
 
{
3139
 
  if (index >= 0 && index < h->size)
3140
 
    return &h->array[log_index(h, (h->size - 1) - index)];
3141
 
  else
3142
 
    return NULL;
3143
 
}
3144
 
 
3145
 
#if HTTP_PROXY_FALLBACK
3146
 
 
3147
 
void
3148
 
management_http_proxy_fallback_notify (struct management *man, const char *type, const char *remote_ip_hint)
3149
 
{
3150
 
  if (remote_ip_hint)
3151
 
    msg (M_CLIENT, ">PROXY:%s,%s", type, remote_ip_hint);
3152
 
  else
3153
 
    msg (M_CLIENT, ">PROXY:%s", type);
3154
 
}
3155
 
 
3156
 
#endif /* HTTP_PROXY_FALLBACK */
3157
 
 
3158
 
#else
3159
 
static void dummy(void) {}
3160
 
#endif /* ENABLE_MANAGEMENT */