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

« back to all changes in this revision

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