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
8
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
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.
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.
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
27
#ifdef ENABLE_MANAGEMENT
47
#define MANAGEMENT_ECHO_PULL_INFO 0
49
#if MANAGEMENT_ECHO_PULL_INFO
50
#define MANAGEMENT_ECHO_FLAGS LOG_PRINT_INTVAL
52
#define MANAGEMENT_ECHO_FLAGS 0
55
/* tag for blank username/password */
56
static const char blank_up[] = "[[BLANK]]";
58
struct management *management; /* GLOBAL */
60
/* static forward declarations */
61
static void man_output_standalone (struct management *man, volatile int *signal_received);
62
static void man_reset_client_socket (struct management *man, const bool exiting);
67
msg (M_CLIENT, "Management Interface for %s", title_string);
68
msg (M_CLIENT, "Commands:");
69
msg (M_CLIENT, "auth-retry t : Auth failure retry mode (none,interact,nointeract).");
70
msg (M_CLIENT, "bytecount n : Show bytes in/out, update every n secs (0=off).");
71
msg (M_CLIENT, "echo [on|off] [N|all] : Like log, but only show messages in echo buffer.");
72
msg (M_CLIENT, "exit|quit : Close management session.");
73
msg (M_CLIENT, "forget-passwords : Forget passwords entered so far.");
74
msg (M_CLIENT, "help : Print this message.");
75
msg (M_CLIENT, "hold [on|off|release] : Set/show hold flag to on/off state, or");
76
msg (M_CLIENT, " release current hold and start tunnel.");
77
msg (M_CLIENT, "kill cn : Kill the client instance(s) having common name cn.");
78
msg (M_CLIENT, "kill IP:port : Kill the client instance connecting from IP:port.");
79
msg (M_CLIENT, "load-stats : Show global server load stats.");
80
msg (M_CLIENT, "log [on|off] [N|all] : Turn on/off realtime log display");
81
msg (M_CLIENT, " + show last N lines or 'all' for entire history.");
82
msg (M_CLIENT, "mute [n] : Set log mute level to n, or show level if n is absent.");
83
msg (M_CLIENT, "needok type action : Enter confirmation for NEED-OK request of 'type',");
84
msg (M_CLIENT, " where action = 'ok' or 'cancel'.");
85
msg (M_CLIENT, "needstr type action : Enter confirmation for NEED-STR request of 'type',");
86
msg (M_CLIENT, " where action is reply string.");
87
msg (M_CLIENT, "net : (Windows only) Show network info and routing table.");
88
msg (M_CLIENT, "password type p : Enter password p for a queried OpenVPN password.");
89
msg (M_CLIENT, "pid : Show process ID of the current OpenVPN process.");
91
msg (M_CLIENT, "pkcs11-id-count : Get number of available PKCS#11 identities.");
92
msg (M_CLIENT, "pkcs11-id-get index : Get PKCS#11 identity at index.");
94
#ifdef MANAGEMENT_DEF_AUTH
95
msg (M_CLIENT, "client-auth CID KID : Authenticate client-id/key-id CID/KID (MULTILINE)");
96
msg (M_CLIENT, "client-auth-nt CID KID : Authenticate client-id/key-id CID/KID");
97
msg (M_CLIENT, "client-deny CID KID R [CR] : Deny auth client-id/key-id CID/KID with log reason");
98
msg (M_CLIENT, " text R and optional client reason text CR");
99
msg (M_CLIENT, "client-kill CID : Kill client instance CID");
100
msg (M_CLIENT, "env-filter [level] : Set env-var filter level");
102
msg (M_CLIENT, "client-pf CID : Define packet filter for client CID (MULTILINE)");
105
msg (M_CLIENT, "signal s : Send signal s to daemon,");
106
msg (M_CLIENT, " s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2.");
107
msg (M_CLIENT, "state [on|off] [N|all] : Like log, but show state history.");
108
msg (M_CLIENT, "status [n] : Show current daemon status info using format #n.");
109
msg (M_CLIENT, "test n : Produce n lines of output for testing/debugging.");
110
msg (M_CLIENT, "username type u : Enter username u for a queried OpenVPN username.");
111
msg (M_CLIENT, "verb [n] : Set log verbosity level to n, or show if n is absent.");
112
msg (M_CLIENT, "version : Show current version number.");
113
#if HTTP_PROXY_FALLBACK
114
msg (M_CLIENT, "http-proxy-fallback <server> <port> [flags] : Enter dynamic HTTP proxy fallback info.");
115
msg (M_CLIENT, "http-proxy-fallback-disable : Disable HTTP proxy fallback.");
117
msg (M_CLIENT, "END");
121
man_state_name (const int state)
125
case OPENVPN_STATE_INITIAL:
127
case OPENVPN_STATE_CONNECTING:
129
case OPENVPN_STATE_WAIT:
131
case OPENVPN_STATE_AUTH:
133
case OPENVPN_STATE_GET_CONFIG:
135
case OPENVPN_STATE_ASSIGN_IP:
137
case OPENVPN_STATE_ADD_ROUTES:
139
case OPENVPN_STATE_CONNECTED:
141
case OPENVPN_STATE_RECONNECTING:
142
return "RECONNECTING";
143
case OPENVPN_STATE_EXITING:
145
case OPENVPN_STATE_RESOLVE:
147
case OPENVPN_STATE_TCP_CONNECT:
148
return "TCP_CONNECT";
155
man_welcome (struct management *man)
157
msg (M_CLIENT, ">INFO:OpenVPN Management Interface Version %d -- type 'help' for more info",
159
if (man->persist.special_state_msg)
160
msg (M_CLIENT, "%s", man->persist.special_state_msg);
164
man_password_needed (struct management *man)
166
return man->settings.up.defined && !man->connection.password_verified;
170
man_check_password (struct management *man, const char *line)
172
if (man_password_needed (man))
174
if (streq (line, man->settings.up.password))
176
man->connection.password_verified = true;
177
msg (M_CLIENT, "SUCCESS: password is correct");
182
man->connection.password_verified = false;
183
msg (M_CLIENT, "ERROR: bad password");
184
if (++man->connection.password_tries >= MANAGEMENT_N_PASSWORD_RETRIES)
186
msg (M_WARN, "MAN: client connection rejected after %d failed password attempts",
187
MANAGEMENT_N_PASSWORD_RETRIES);
188
man->connection.halt = true;
195
man_update_io_state (struct management *man)
197
if (socket_defined (man->connection.sd_cli))
199
if (buffer_list_defined (man->connection.out))
201
man->connection.state = MS_CC_WAIT_WRITE;
205
man->connection.state = MS_CC_WAIT_READ;
211
man_output_list_push_finalize (struct management *man)
213
if (management_connected (man))
215
man_update_io_state (man);
216
if (!man->persist.standalone_disabled)
218
volatile int signal_received = 0;
219
man_output_standalone (man, &signal_received);
225
man_output_list_push_str (struct management *man, const char *str)
227
if (management_connected (man) && str)
229
buffer_list_push (man->connection.out, (const unsigned char *) str);
234
man_output_list_push (struct management *man, const char *str)
236
man_output_list_push_str (man, str);
237
man_output_list_push_finalize (man);
241
man_prompt (struct management *man)
243
if (man_password_needed (man))
244
man_output_list_push (man, "ENTER PASSWORD:");
245
#if 0 /* should we use prompt? */
247
man_output_list_push (man, ">");
252
man_delete_unix_socket (struct management *man)
254
#if UNIX_SOCK_SUPPORT
255
if ((man->settings.flags & (MF_UNIX_SOCK|MF_CONNECT_AS_CLIENT)) == MF_UNIX_SOCK)
256
socket_delete_unix (&man->settings.local_unix);
261
man_close_socket (struct management *man, const socket_descriptor_t sd)
265
* Windows doesn't need this because the ne32 event is permanently
266
* enabled at struct management scope.
268
if (man->persist.callback.delete_event)
269
(*man->persist.callback.delete_event) (man->persist.callback.arg, sd);
271
openvpn_close_socket (sd);
275
virtual_output_callback_func (void *arg, const unsigned int flags, const char *str)
277
struct management *man = (struct management *) arg;
278
static int recursive_level = 0; /* GLOBAL */
279
bool did_push = false;
281
if (!recursive_level) /* don't allow recursion */
283
struct gc_arena gc = gc_new ();
285
const char *out = NULL;
292
e.u.msg_flags = flags;
296
man->persist.standalone_disabled = false;
298
if (flags != M_CLIENT)
299
log_history_add (man->persist.log, &e);
301
if (!man_password_needed (man))
303
if (flags == M_CLIENT)
304
out = log_entry_print (&e, LOG_PRINT_CRLF, &gc);
305
else if (man->connection.log_realtime)
306
out = log_entry_print (&e, LOG_PRINT_INT_DATE
307
| LOG_PRINT_MSG_FLAGS
308
| LOG_PRINT_LOG_PREFIX
309
| LOG_PRINT_CRLF, &gc);
312
man_output_list_push_str (man, out);
317
out = log_entry_print (&e, LOG_FATAL_NOTIFY|LOG_PRINT_CRLF, &gc);
320
man_output_list_push_str (man, out);
322
man_reset_client_socket (man, true);
332
man_output_list_push_finalize (man);
336
* Given a signal, return the signal with possible remapping applied,
337
* or -1 if the signal should be ignored.
340
man_mod_signal (const struct management *man, const int signum)
342
const unsigned int flags = man->settings.mansig;
346
if (flags & MANSIG_MAP_USR1_TO_HUP)
348
if (flags & MANSIG_MAP_USR1_TO_TERM)
351
if (flags & MANSIG_IGNORE_USR1_HUP)
353
if (s == SIGHUP || s == SIGUSR1)
360
man_signal (struct management *man, const char *name)
362
const int sig = parse_signal (name);
365
const int sig_mod = man_mod_signal (man, sig);
368
throw_signal (sig_mod);
369
msg (M_CLIENT, "SUCCESS: signal %s thrown", signal_name (sig_mod, true));
373
if (man->persist.special_state_msg)
374
msg (M_CLIENT, "%s", man->persist.special_state_msg);
376
msg (M_CLIENT, "ERROR: signal '%s' is currently ignored", name);
381
msg (M_CLIENT, "ERROR: signal '%s' is not a known signal type", name);
386
man_status (struct management *man, const int version, struct status_output *so)
388
if (man->persist.callback.status)
390
(*man->persist.callback.status) (man->persist.callback.arg, version, so);
394
msg (M_CLIENT, "ERROR: The 'status' command is not supported by the current daemon mode");
399
man_bytecount (struct management *man, const int update_seconds)
401
if (update_seconds >= 0)
402
man->connection.bytecount_update_seconds = update_seconds;
404
man->connection.bytecount_update_seconds = 0;
405
msg (M_CLIENT, "SUCCESS: bytecount interval changed");
409
man_bytecount_output_client (struct management *man)
413
/* do in a roundabout way to work around possible mingw or mingw-glibc bug */
414
openvpn_snprintf (in, sizeof (in), counter_format, man->persist.bytes_in);
415
openvpn_snprintf (out, sizeof (out), counter_format, man->persist.bytes_out);
416
msg (M_CLIENT, ">BYTECOUNT:%s,%s", in, out);
417
man->connection.bytecount_last_update = now;
420
#ifdef MANAGEMENT_DEF_AUTH
423
man_bytecount_output_server (struct management *man,
424
const counter_type *bytes_in_total,
425
const counter_type *bytes_out_total,
426
struct man_def_auth_context *mdac)
430
/* do in a roundabout way to work around possible mingw or mingw-glibc bug */
431
openvpn_snprintf (in, sizeof (in), counter_format, *bytes_in_total);
432
openvpn_snprintf (out, sizeof (out), counter_format, *bytes_out_total);
433
msg (M_CLIENT, ">BYTECOUNT_CLI:%lu,%s,%s", mdac->cid, in, out);
434
mdac->bytecount_last_update = now;
440
man_kill (struct management *man, const char *victim)
442
struct gc_arena gc = gc_new ();
444
if (man->persist.callback.kill_by_cn && man->persist.callback.kill_by_addr)
451
buf_set_read (&buf, (uint8_t*) victim, strlen (victim) + 1);
452
buf_parse (&buf, ':', p1, sizeof (p1));
453
buf_parse (&buf, ':', p2, sizeof (p2));
455
if (strlen (p1) && strlen (p2))
457
/* IP:port specified */
459
const in_addr_t addr = getaddr (GETADDR_HOST_ORDER|GETADDR_MSG_VIRT_OUT, p1, 0, &status, NULL);
462
const int port = atoi (p2);
463
if (port > 0 && port < 65536)
465
n_killed = (*man->persist.callback.kill_by_addr) (man->persist.callback.arg, addr, port);
468
msg (M_CLIENT, "SUCCESS: %d client(s) at address %s:%d killed",
470
print_in_addr_t (addr, 0, &gc),
475
msg (M_CLIENT, "ERROR: client at address %s:%d not found",
476
print_in_addr_t (addr, 0, &gc),
482
msg (M_CLIENT, "ERROR: port number is out of range: %s", p2);
487
msg (M_CLIENT, "ERROR: error parsing IP address: %s", p1);
490
else if (strlen (p1))
492
/* common name specified */
493
n_killed = (*man->persist.callback.kill_by_cn) (man->persist.callback.arg, p1);
496
msg (M_CLIENT, "SUCCESS: common name '%s' found, %d client(s) killed", p1, n_killed);
500
msg (M_CLIENT, "ERROR: common name '%s' not found", p1);
505
msg (M_CLIENT, "ERROR: kill parse");
510
msg (M_CLIENT, "ERROR: The 'kill' command is not supported by the current daemon mode");
517
* General-purpose history command handler
518
* for the log and echo commands.
521
man_history (struct management *man,
524
struct log_history *log,
526
const unsigned int lep_flags)
528
struct gc_arena gc = gc_new ();
531
if (streq (parm, "on"))
534
msg (M_CLIENT, "SUCCESS: real-time %s notification set to ON", type);
536
else if (streq (parm, "off"))
539
msg (M_CLIENT, "SUCCESS: real-time %s notification set to OFF", type);
541
else if (streq (parm, "all") || (n = atoi (parm)) > 0)
543
const int size = log_history_size (log);
544
const int start = (n ? n : size) - 1;
547
for (i = start; i >= 0; --i)
549
const struct log_entry *e = log_history_ref (log, i);
552
const char *out = log_entry_print (e, lep_flags, &gc);
553
virtual_output_callback_func (man, M_CLIENT, out);
556
msg (M_CLIENT, "END");
560
msg (M_CLIENT, "ERROR: %s parameter must be 'on' or 'off' or some number n or 'all'", type);
567
man_log (struct management *man, const char *parm)
573
&man->connection.log_realtime,
574
LOG_PRINT_INT_DATE|LOG_PRINT_MSG_FLAGS);
578
man_echo (struct management *man, const char *parm)
584
&man->connection.echo_realtime,
585
LOG_PRINT_INT_DATE|MANAGEMENT_ECHO_FLAGS);
589
man_state (struct management *man, const char *parm)
595
&man->connection.state_realtime,
596
LOG_PRINT_INT_DATE|LOG_PRINT_STATE|
597
LOG_PRINT_LOCAL_IP|LOG_PRINT_REMOTE_IP);
601
man_up_finalize (struct management *man)
603
switch (man->connection.up_query_mode)
605
case UP_QUERY_DISABLED:
606
man->connection.up_query.defined = false;
608
case UP_QUERY_USER_PASS:
609
if (strlen (man->connection.up_query.username) && strlen (man->connection.up_query.password))
610
man->connection.up_query.defined = true;
613
if (strlen (man->connection.up_query.password))
614
man->connection.up_query.defined = true;
616
case UP_QUERY_NEED_OK:
617
if (strlen (man->connection.up_query.password))
618
man->connection.up_query.defined = true;
620
case UP_QUERY_NEED_STR:
621
if (strlen (man->connection.up_query.password))
622
man->connection.up_query.defined = true;
630
man_query_user_pass (struct management *man,
640
ASSERT (man->connection.up_query_type);
641
if (streq (man->connection.up_query_type, type))
643
strncpynt (dest, string, len);
644
man_up_finalize (man);
645
msg (M_CLIENT, "SUCCESS: '%s' %s entered, but not yet verified",
650
msg (M_CLIENT, "ERROR: %s of type '%s' entered, but we need one of type '%s'",
653
man->connection.up_query_type);
657
msg (M_CLIENT, "ERROR: no %s is currently needed at this time", prompt);
662
man_query_username (struct management *man, const char *type, const char *string)
664
const bool needed = (man->connection.up_query_mode == UP_QUERY_USER_PASS && man->connection.up_query_type);
665
man_query_user_pass (man, type, string, needed, "username", man->connection.up_query.username, USER_PASS_LEN);
669
man_query_password (struct management *man, const char *type, const char *string)
671
const bool needed = ((man->connection.up_query_mode == UP_QUERY_USER_PASS
672
|| man->connection.up_query_mode == UP_QUERY_PASS)
673
&& man->connection.up_query_type);
674
if (!string[0]) /* allow blank passwords to be passed through using the blank_up tag */
676
man_query_user_pass (man, type, string, needed, "password", man->connection.up_query.password, USER_PASS_LEN);
680
man_query_need_ok (struct management *man, const char *type, const char *action)
682
const bool needed = ((man->connection.up_query_mode == UP_QUERY_NEED_OK) && man->connection.up_query_type);
683
man_query_user_pass (man, type, action, needed, "needok-confirmation", man->connection.up_query.password, USER_PASS_LEN);
687
man_query_need_str (struct management *man, const char *type, const char *action)
689
const bool needed = ((man->connection.up_query_mode == UP_QUERY_NEED_STR) && man->connection.up_query_type);
690
man_query_user_pass (man, type, action, needed, "needstr-string", man->connection.up_query.password, USER_PASS_LEN);
694
man_forget_passwords (struct management *man)
696
#if defined(USE_CRYPTO) && defined(USE_SSL)
698
msg (M_CLIENT, "SUCCESS: Passwords were forgotten");
703
man_net (struct management *man)
705
if (man->persist.callback.show_net)
707
(*man->persist.callback.show_net) (man->persist.callback.arg, M_CLIENT);
711
msg (M_CLIENT, "ERROR: The 'net' command is not supported by the current daemon mode");
718
man_pkcs11_id_count (struct management *man)
720
msg (M_CLIENT, ">PKCS11ID-COUNT:%d", pkcs11_management_id_count ());
724
man_pkcs11_id_get (struct management *man, const int index)
729
if (pkcs11_management_id_get (index, &id, &base64))
730
msg (M_CLIENT, ">PKCS11ID-ENTRY:'%d', ID:'%s', BLOB:'%s'", index, id, base64);
732
msg (M_CLIENT, ">PKCS11ID-ENTRY:'%d'", index);
743
man_hold (struct management *man, const char *cmd)
747
if (streq (cmd, "on"))
749
man->settings.flags |= MF_HOLD;
750
msg (M_CLIENT, "SUCCESS: hold flag set to ON");
752
else if (streq (cmd, "off"))
754
man->settings.flags &= ~MF_HOLD;
755
msg (M_CLIENT, "SUCCESS: hold flag set to OFF");
757
else if (streq (cmd, "release"))
759
man->persist.hold_release = true;
760
msg (M_CLIENT, "SUCCESS: hold release succeeded");
764
msg (M_CLIENT, "ERROR: bad hold command parameter");
768
msg (M_CLIENT, "SUCCESS: hold=%d", BOOL_CAST(man->settings.flags & MF_HOLD));
771
#ifdef MANAGEMENT_DEF_AUTH
774
parse_cid (const char *str, unsigned long *cid)
776
if (sscanf (str, "%lu", cid) == 1)
780
msg (M_CLIENT, "ERROR: cannot parse CID");
786
parse_kid (const char *str, unsigned int *kid)
788
if (sscanf (str, "%u", kid) == 1)
792
msg (M_CLIENT, "ERROR: cannot parse KID");
798
in_extra_reset (struct man_connection *mc, const bool new)
804
mc->in_extra_cmd = IEC_UNDEF;
805
mc->in_extra_cid = 0;
806
mc->in_extra_kid = 0;
810
buffer_list_free (mc->in_extra);
814
mc->in_extra = buffer_list_new (0);
819
in_extra_dispatch (struct management *man)
821
switch (man->connection.in_extra_cmd)
823
case IEC_CLIENT_AUTH:
824
if (man->persist.callback.client_auth)
826
const bool status = (*man->persist.callback.client_auth)
827
(man->persist.callback.arg,
828
man->connection.in_extra_cid,
829
man->connection.in_extra_kid,
833
man->connection.in_extra);
834
man->connection.in_extra = NULL;
837
msg (M_CLIENT, "SUCCESS: client-auth command succeeded");
841
msg (M_CLIENT, "ERROR: client-auth command failed");
846
msg (M_CLIENT, "ERROR: The client-auth command is not supported by the current daemon mode");
851
if (man->persist.callback.client_pf)
853
const bool status = (*man->persist.callback.client_pf)
854
(man->persist.callback.arg,
855
man->connection.in_extra_cid,
856
man->connection.in_extra);
857
man->connection.in_extra = NULL;
860
msg (M_CLIENT, "SUCCESS: client-pf command succeeded");
864
msg (M_CLIENT, "ERROR: client-pf command failed");
869
msg (M_CLIENT, "ERROR: The client-pf command is not supported by the current daemon mode");
874
in_extra_reset (&man->connection, false);
878
man_client_auth (struct management *man, const char *cid_str, const char *kid_str, const bool extra)
880
struct man_connection *mc = &man->connection;
881
mc->in_extra_cid = 0;
882
mc->in_extra_kid = 0;
883
if (parse_cid (cid_str, &mc->in_extra_cid)
884
&& parse_kid (kid_str, &mc->in_extra_kid))
886
mc->in_extra_cmd = IEC_CLIENT_AUTH;
887
in_extra_reset (mc, true);
889
in_extra_dispatch (man);
894
man_client_deny (struct management *man, const char *cid_str, const char *kid_str, const char *reason, const char *client_reason)
896
unsigned long cid = 0;
897
unsigned int kid = 0;
898
if (parse_cid (cid_str, &cid) && parse_kid (kid_str, &kid))
900
if (man->persist.callback.client_auth)
902
const bool status = (*man->persist.callback.client_auth)
903
(man->persist.callback.arg,
912
msg (M_CLIENT, "SUCCESS: client-deny command succeeded");
916
msg (M_CLIENT, "ERROR: client-deny command failed");
921
msg (M_CLIENT, "ERROR: The client-deny command is not supported by the current daemon mode");
927
man_client_kill (struct management *man, const char *cid_str)
929
unsigned long cid = 0;
930
if (parse_cid (cid_str, &cid))
932
if (man->persist.callback.kill_by_cid)
934
const bool status = (*man->persist.callback.kill_by_cid) (man->persist.callback.arg, cid);
937
msg (M_CLIENT, "SUCCESS: client-kill command succeeded");
941
msg (M_CLIENT, "ERROR: client-kill command failed");
946
msg (M_CLIENT, "ERROR: The client-kill command is not supported by the current daemon mode");
952
man_client_n_clients (struct management *man)
954
if (man->persist.callback.n_clients)
956
const int nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg);
957
msg (M_CLIENT, "SUCCESS: nclients=%d", nclients);
961
msg (M_CLIENT, "ERROR: The nclients command is not supported by the current daemon mode");
966
man_env_filter (struct management *man, const int level)
968
man->connection.env_filter_level = level;
969
msg (M_CLIENT, "SUCCESS: env_filter_level=%d", level);
975
man_client_pf (struct management *man, const char *cid_str)
977
struct man_connection *mc = &man->connection;
978
mc->in_extra_cid = 0;
979
mc->in_extra_kid = 0;
980
if (parse_cid (cid_str, &mc->in_extra_cid))
982
mc->in_extra_cmd = IEC_CLIENT_PF;
983
in_extra_reset (mc, true);
991
man_load_stats (struct management *man)
993
extern counter_type link_read_bytes_global;
994
extern counter_type link_write_bytes_global;
997
if (man->persist.callback.n_clients)
998
nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg);
999
msg (M_CLIENT, "SUCCESS: nclients=%d,bytesin=" counter_format ",bytesout=" counter_format,
1001
link_read_bytes_global,
1002
link_write_bytes_global);
1005
#define MN_AT_LEAST (1<<0)
1008
man_need (struct management *man, const char **p, const int n, unsigned int flags)
1012
for (i = 1; i <= n; ++i)
1016
msg (M_CLIENT, "ERROR: the '%s' command requires %s%d parameter%s",
1018
(flags & MN_AT_LEAST) ? "at least " : "",
1027
#if HTTP_PROXY_FALLBACK
1030
man_http_proxy_fallback (struct management *man, const char *server, const char *port, const char *flags)
1032
if (man->persist.callback.http_proxy_fallback_cmd)
1034
const bool status = (*man->persist.callback.http_proxy_fallback_cmd)(man->persist.callback.arg, server, port, flags);
1037
msg (M_CLIENT, "SUCCESS: proxy-fallback command succeeded");
1041
msg (M_CLIENT, "ERROR: proxy-fallback command failed");
1046
msg (M_CLIENT, "ERROR: The proxy-fallback command is not supported by the current daemon mode");
1053
man_dispatch_command (struct management *man, struct status_output *so, const char **p, const int nparms)
1055
struct gc_arena gc = gc_new ();
1058
if (streq (p[0], "exit") || streq (p[0], "quit"))
1060
man->connection.halt = true;
1063
else if (streq (p[0], "help"))
1067
else if (streq (p[0], "version"))
1069
msg (M_CLIENT, "OpenVPN Version: %s", title_string);
1070
msg (M_CLIENT, "Management Version: %d", MANAGEMENT_VERSION);
1071
msg (M_CLIENT, "END");
1073
else if (streq (p[0], "pid"))
1075
msg (M_CLIENT, "SUCCESS: pid=%d", openvpn_getpid ());
1077
#ifdef MANAGEMENT_DEF_AUTH
1078
else if (streq (p[0], "nclients"))
1080
man_client_n_clients (man);
1082
else if (streq (p[0], "env-filter"))
1086
level = atoi (p[1]);
1087
man_env_filter (man, level);
1090
else if (streq (p[0], "signal"))
1092
if (man_need (man, p, 1, 0))
1093
man_signal (man, p[1]);
1095
else if (streq (p[0], "load-stats"))
1097
man_load_stats (man);
1099
else if (streq (p[0], "status"))
1103
version = atoi (p[1]);
1104
man_status (man, version, so);
1106
else if (streq (p[0], "kill"))
1108
if (man_need (man, p, 1, 0))
1109
man_kill (man, p[1]);
1111
else if (streq (p[0], "verb"))
1115
const int level = atoi(p[1]);
1116
if (set_debug_level (level, 0))
1117
msg (M_CLIENT, "SUCCESS: verb level changed");
1119
msg (M_CLIENT, "ERROR: verb level is out of range");
1122
msg (M_CLIENT, "SUCCESS: verb=%d", get_debug_level ());
1124
else if (streq (p[0], "mute"))
1128
const int level = atoi(p[1]);
1129
if (set_mute_cutoff (level))
1130
msg (M_CLIENT, "SUCCESS: mute level changed");
1132
msg (M_CLIENT, "ERROR: mute level is out of range");
1135
msg (M_CLIENT, "SUCCESS: mute=%d", get_mute_cutoff ());
1137
else if (streq (p[0], "auth-retry"))
1142
if (auth_retry_set (M_CLIENT, p[1]))
1143
msg (M_CLIENT, "SUCCESS: auth-retry parameter changed");
1145
msg (M_CLIENT, "ERROR: bad auth-retry parameter");
1148
msg (M_CLIENT, "SUCCESS: auth-retry=%s", auth_retry_print ());
1150
msg (M_CLIENT, "ERROR: auth-retry feature is unavailable");
1153
else if (streq (p[0], "state"))
1157
man_state (man, "1");
1162
man_state (man, p[1]);
1164
man_state (man, p[2]);
1167
else if (streq (p[0], "log"))
1169
if (man_need (man, p, 1, MN_AT_LEAST))
1172
man_log (man, p[1]);
1174
man_log (man, p[2]);
1177
else if (streq (p[0], "echo"))
1179
if (man_need (man, p, 1, MN_AT_LEAST))
1182
man_echo (man, p[1]);
1184
man_echo (man, p[2]);
1187
else if (streq (p[0], "username"))
1189
if (man_need (man, p, 2, 0))
1190
man_query_username (man, p[1], p[2]);
1192
else if (streq (p[0], "password"))
1194
if (man_need (man, p, 2, 0))
1195
man_query_password (man, p[1], p[2]);
1197
else if (streq (p[0], "forget-passwords"))
1199
man_forget_passwords (man);
1201
else if (streq (p[0], "needok"))
1203
if (man_need (man, p, 2, 0))
1204
man_query_need_ok (man, p[1], p[2]);
1206
else if (streq (p[0], "needstr"))
1208
if (man_need (man, p, 2, 0))
1209
man_query_need_str (man, p[1], p[2]);
1211
else if (streq (p[0], "net"))
1215
else if (streq (p[0], "hold"))
1217
man_hold (man, p[1]);
1219
else if (streq (p[0], "bytecount"))
1221
if (man_need (man, p, 1, 0))
1222
man_bytecount (man, atoi(p[1]));
1224
#ifdef MANAGEMENT_DEF_AUTH
1225
else if (streq (p[0], "client-kill"))
1227
if (man_need (man, p, 1, 0))
1228
man_client_kill (man, p[1]);
1230
else if (streq (p[0], "client-deny"))
1232
if (man_need (man, p, 3, MN_AT_LEAST))
1233
man_client_deny (man, p[1], p[2], p[3], p[4]);
1235
else if (streq (p[0], "client-auth-nt"))
1237
if (man_need (man, p, 2, 0))
1238
man_client_auth (man, p[1], p[2], false);
1240
else if (streq (p[0], "client-auth"))
1242
if (man_need (man, p, 2, 0))
1243
man_client_auth (man, p[1], p[2], true);
1245
#ifdef MANAGEMENT_PF
1246
else if (streq (p[0], "client-pf"))
1248
if (man_need (man, p, 1, 0))
1249
man_client_pf (man, p[1]);
1253
#ifdef ENABLE_PKCS11
1254
else if (streq (p[0], "pkcs11-id-count"))
1256
man_pkcs11_id_count (man);
1258
else if (streq (p[0], "pkcs11-id-get"))
1260
if (man_need (man, p, 1, 0))
1261
man_pkcs11_id_get (man, atoi(p[1]));
1264
#if HTTP_PROXY_FALLBACK
1265
else if (streq (p[0], "http-proxy-fallback"))
1267
if (man_need (man, p, 2, MN_AT_LEAST))
1268
man_http_proxy_fallback (man, p[1], p[2], p[3]);
1270
else if (streq (p[0], "http-proxy-fallback-disable"))
1272
man_http_proxy_fallback (man, NULL, NULL, NULL);
1276
else if (streq (p[0], "test"))
1278
if (man_need (man, p, 1, 0))
1281
const int n = atoi (p[1]);
1282
for (i = 0; i < n; ++i)
1284
msg (M_CLIENT, "[%d] The purpose of this command is to generate large amounts of output.", i);
1291
msg (M_CLIENT, "ERROR: unknown command, enter 'help' for more options");
1301
man_start_ne32 (struct management *man)
1303
switch (man->connection.state)
1306
net_event_win32_start (&man->connection.ne32, FD_ACCEPT, man->connection.sd_top);
1308
case MS_CC_WAIT_READ:
1309
case MS_CC_WAIT_WRITE:
1310
net_event_win32_start (&man->connection.ne32, FD_READ|FD_WRITE|FD_CLOSE, man->connection.sd_cli);
1318
man_stop_ne32 (struct management *man)
1320
net_event_win32_stop (&man->connection.ne32);
1326
man_record_peer_info (struct management *man)
1328
struct gc_arena gc = gc_new ();
1329
if (man->settings.write_peer_info_file)
1331
bool success = false;
1332
#ifdef HAVE_GETSOCKNAME
1333
if (socket_defined (man->connection.sd_cli))
1335
struct sockaddr_in addr;
1336
socklen_t addrlen = sizeof (addr);
1340
status = getsockname (man->connection.sd_cli, (struct sockaddr *)&addr, &addrlen);
1341
if (!status && addrlen == sizeof (addr))
1343
const in_addr_t a = ntohl (addr.sin_addr.s_addr);
1344
const int p = ntohs (addr.sin_port);
1345
FILE *fp = fopen (man->settings.write_peer_info_file, "w");
1348
fprintf (fp, "%s\n%d\n", print_in_addr_t (a, 0, &gc), p);
1357
msg (D_MANAGEMENT, "MANAGEMENT: failed to write peer info to file %s",
1358
man->settings.write_peer_info_file);
1359
throw_signal_soft (SIGTERM, "management-connect-failed");
1366
man_connection_settings_reset (struct management *man)
1368
man->connection.state_realtime = false;
1369
man->connection.log_realtime = false;
1370
man->connection.echo_realtime = false;
1371
man->connection.bytecount_update_seconds = 0;
1372
man->connection.password_verified = false;
1373
man->connection.password_tries = 0;
1374
man->connection.halt = false;
1375
man->connection.state = MS_CC_WAIT_WRITE;
1379
man_new_connection_post (struct management *man, const char *description)
1381
struct gc_arena gc = gc_new ();
1383
set_nonblock (man->connection.sd_cli);
1384
set_cloexec (man->connection.sd_cli);
1386
man_connection_settings_reset (man);
1389
man_start_ne32 (man);
1392
#if UNIX_SOCK_SUPPORT
1393
if (man->settings.flags & MF_UNIX_SOCK)
1395
msg (D_MANAGEMENT, "MANAGEMENT: %s %s",
1397
sockaddr_unix_name (&man->settings.local_unix, "NULL"));
1401
msg (D_MANAGEMENT, "MANAGEMENT: %s %s",
1403
print_sockaddr (&man->settings.local, &gc));
1405
buffer_list_reset (man->connection.out);
1407
if (!man_password_needed (man))
1410
man_update_io_state (man);
1415
#if UNIX_SOCK_SUPPORT
1417
man_verify_unix_peer_uid_gid (struct management *man, const socket_descriptor_t sd)
1419
if (socket_defined (sd) && (man->settings.client_uid != -1 || man->settings.client_gid != -1))
1421
static const char err_prefix[] = "MANAGEMENT: unix domain socket client connection rejected --";
1423
if (unix_socket_get_peer_uid_gid (man->connection.sd_cli, &uid, &gid))
1425
if (man->settings.client_uid != -1 && man->settings.client_uid != uid)
1427
msg (D_MANAGEMENT, "%s UID of socket peer (%d) doesn't match required value (%d) as given by --management-client-user",
1428
err_prefix, uid, man->settings.client_uid);
1431
if (man->settings.client_gid != -1 && man->settings.client_gid != gid)
1433
msg (D_MANAGEMENT, "%s GID of socket peer (%d) doesn't match required value (%d) as given by --management-client-group",
1434
err_prefix, gid, man->settings.client_gid);
1440
msg (D_MANAGEMENT, "%s cannot get UID/GID of socket peer", err_prefix);
1449
man_accept (struct management *man)
1451
struct link_socket_actual act;
1455
* Accept the TCP or Unix domain socket client.
1457
#if UNIX_SOCK_SUPPORT
1458
if (man->settings.flags & MF_UNIX_SOCK)
1460
struct sockaddr_un remote;
1461
man->connection.sd_cli = socket_accept_unix (man->connection.sd_top, &remote);
1462
if (!man_verify_unix_peer_uid_gid (man, man->connection.sd_cli))
1463
sd_close (&man->connection.sd_cli);
1467
man->connection.sd_cli = socket_do_accept (man->connection.sd_top, &act, false);
1469
if (socket_defined (man->connection.sd_cli))
1471
man->connection.remote = act.dest;
1473
if (socket_defined (man->connection.sd_top))
1476
man_stop_ne32 (man);
1480
man_new_connection_post (man, "Client connected from");
1485
man_listen (struct management *man)
1487
struct gc_arena gc = gc_new ();
1492
man->connection.state = MS_LISTEN;
1493
man->connection.sd_cli = SOCKET_UNDEFINED;
1496
* Initialize listening socket
1498
if (man->connection.sd_top == SOCKET_UNDEFINED)
1500
#if UNIX_SOCK_SUPPORT
1501
if (man->settings.flags & MF_UNIX_SOCK)
1503
man_delete_unix_socket (man);
1504
man->connection.sd_top = create_socket_unix ();
1505
socket_bind_unix (man->connection.sd_top, &man->settings.local_unix, "MANAGEMENT");
1510
man->connection.sd_top = create_socket_tcp ();
1511
socket_bind (man->connection.sd_top, &man->settings.local, "MANAGEMENT");
1515
* Listen for connection
1517
if (listen (man->connection.sd_top, 1))
1518
msg (M_SOCKERR, "MANAGEMENT: listen() failed");
1521
* Set misc socket properties
1523
set_nonblock (man->connection.sd_top);
1524
set_cloexec (man->connection.sd_top);
1526
#if UNIX_SOCK_SUPPORT
1527
if (man->settings.flags & MF_UNIX_SOCK)
1529
msg (D_MANAGEMENT, "MANAGEMENT: unix domain socket listening on %s",
1530
sockaddr_unix_name (&man->settings.local_unix, "NULL"));
1534
msg (D_MANAGEMENT, "MANAGEMENT: TCP Socket listening on %s",
1535
print_sockaddr (&man->settings.local, &gc));
1539
man_start_ne32 (man);
1546
man_connect (struct management *man)
1548
struct gc_arena gc = gc_new ();
1550
int signal_received = 0;
1555
man->connection.state = MS_INITIAL;
1556
man->connection.sd_top = SOCKET_UNDEFINED;
1558
#if UNIX_SOCK_SUPPORT
1559
if (man->settings.flags & MF_UNIX_SOCK)
1561
man->connection.sd_cli = create_socket_unix ();
1562
status = socket_connect_unix (man->connection.sd_cli, &man->settings.local_unix);
1563
if (!status && !man_verify_unix_peer_uid_gid (man, man->connection.sd_cli))
1570
sd_close (&man->connection.sd_cli);
1576
man->connection.sd_cli = create_socket_tcp ();
1577
status = openvpn_connect (man->connection.sd_cli,
1578
&man->settings.local,
1583
if (signal_received)
1585
throw_signal (signal_received);
1591
#if UNIX_SOCK_SUPPORT
1592
if (man->settings.flags & MF_UNIX_SOCK)
1595
"MANAGEMENT: connect to unix socket %s failed: %s",
1596
sockaddr_unix_name (&man->settings.local_unix, "NULL"),
1597
strerror_ts (status, &gc));
1602
"MANAGEMENT: connect to %s failed: %s",
1603
print_sockaddr (&man->settings.local, &gc),
1604
strerror_ts (status, &gc));
1605
throw_signal_soft (SIGTERM, "management-connect-failed");
1609
man_record_peer_info (man);
1610
man_new_connection_post (man, "Connected to management server at");
1617
man_reset_client_socket (struct management *man, const bool exiting)
1619
if (socket_defined (man->connection.sd_cli))
1622
man_stop_ne32 (man);
1624
man_close_socket (man, man->connection.sd_cli);
1625
man->connection.sd_cli = SOCKET_UNDEFINED;
1626
man->connection.state = MS_INITIAL;
1627
command_line_reset (man->connection.in);
1628
buffer_list_reset (man->connection.out);
1629
#ifdef MANAGEMENT_DEF_AUTH
1630
in_extra_reset (&man->connection, false);
1632
msg (D_MANAGEMENT, "MANAGEMENT: Client disconnected");
1636
#if defined(USE_CRYPTO) && defined(USE_SSL)
1637
if (man->settings.flags & MF_FORGET_DISCONNECT)
1640
if (man->settings.flags & MF_SIGNAL) {
1641
int mysig = man_mod_signal (man, SIGUSR1);
1644
msg (D_MANAGEMENT, "MANAGEMENT: Triggering management signal");
1645
throw_signal_soft (mysig, "management-disconnect");
1649
if (man->settings.flags & MF_CONNECT_AS_CLIENT)
1651
msg (D_MANAGEMENT, "MANAGEMENT: Triggering management exit");
1652
throw_signal_soft (SIGTERM, "management-exit");
1660
man_process_command (struct management *man, const char *line)
1662
struct gc_arena gc = gc_new ();
1663
struct status_output *so;
1665
char *parms[MAX_PARMS+1];
1668
so = status_open (NULL, 0, -1, &man->persist.vout, 0);
1669
#ifdef MANAGEMENT_DEF_AUTH
1670
in_extra_reset (&man->connection, false);
1673
if (man_password_needed (man))
1675
man_check_password (man, line);
1679
nparms = parse_line (line, parms, MAX_PARMS, "TCP", 0, M_CLIENT, &gc);
1680
if (parms[0] && streq (parms[0], "password"))
1681
msg (D_MANAGEMENT_DEBUG, "MANAGEMENT: CMD 'password [...]'");
1682
else if (!streq (line, "load-stats"))
1683
msg (D_MANAGEMENT_DEBUG, "MANAGEMENT: CMD '%s'", line);
1686
/* DEBUGGING -- print args */
1689
for (i = 0; i < nparms; ++i)
1690
msg (M_INFO, "[%d] '%s'", i, parms[i]);
1695
man_dispatch_command (man, so, (const char **)parms, nparms);
1704
man_io_error (struct management *man, const char *prefix)
1706
const int err = openvpn_errno_socket ();
1708
if (!ignore_sys_error (err))
1710
struct gc_arena gc = gc_new ();
1711
msg (D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s",
1713
strerror_ts (err, &gc));
1722
man_read (struct management *man)
1725
* read command line from socket
1727
unsigned char buf[256];
1730
len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);
1733
man_reset_client_socket (man, false);
1737
bool processed_command = false;
1739
ASSERT (len <= (int) sizeof (buf));
1740
command_line_add (man->connection.in, buf, len);
1743
* Reset output object
1745
buffer_list_reset (man->connection.out);
1748
* process command line if complete
1751
const unsigned char *line;
1752
while ((line = command_line_get (man->connection.in)))
1754
#ifdef MANAGEMENT_DEF_AUTH
1755
if (man->connection.in_extra)
1757
if (!strcmp ((char *)line, "END"))
1759
in_extra_dispatch (man);
1760
in_extra_reset (&man->connection, false);
1764
buffer_list_push (man->connection.in_extra, line);
1769
man_process_command (man, (char *) line);
1770
if (man->connection.halt)
1772
command_line_next (man->connection.in);
1773
processed_command = true;
1778
* Reset output state to MS_CC_WAIT_(READ|WRITE)
1780
if (man->connection.halt)
1782
man_reset_client_socket (man, false);
1787
if (processed_command)
1789
man_update_io_state (man);
1794
if (man_io_error (man, "recv"))
1795
man_reset_client_socket (man, false);
1801
man_write (struct management *man)
1803
const int size_hint = 1024;
1805
const struct buffer *buf;
1807
buffer_list_aggregate(man->connection.out, size_hint);
1808
buf = buffer_list_peek (man->connection.out);
1809
if (buf && BLEN (buf))
1811
const int len = min_int (size_hint, BLEN (buf));
1812
sent = send (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL);
1815
buffer_list_advance (man->connection.out, sent);
1819
if (man_io_error (man, "send"))
1820
man_reset_client_socket (man, false);
1825
* Reset output state to MS_CC_WAIT_(READ|WRITE)
1827
man_update_io_state (man);
1833
man_connection_clear (struct man_connection *mc)
1837
/* set initial state */
1838
mc->state = MS_INITIAL;
1840
/* clear socket descriptors */
1841
mc->sd_top = SOCKET_UNDEFINED;
1842
mc->sd_cli = SOCKET_UNDEFINED;
1846
man_persist_init (struct management *man,
1847
const int log_history_cache,
1848
const int echo_buffer_size,
1849
const int state_buffer_size)
1851
struct man_persist *mp = &man->persist;
1856
/* initialize log history store */
1857
mp->log = log_history_init (log_history_cache);
1860
* Initialize virtual output object, so that functions
1861
* which write to a virtual_output object can be redirected
1862
* here to the management object.
1864
mp->vout.func = virtual_output_callback_func;
1866
mp->vout.flags_default = M_CLIENT;
1867
msg_set_virtual_output (&mp->vout);
1870
* Initialize --echo list
1872
man->persist.echo = log_history_init (echo_buffer_size);
1875
* Initialize --state list
1877
man->persist.state = log_history_init (state_buffer_size);
1884
man_persist_close (struct man_persist *mp)
1888
msg_set_virtual_output (NULL);
1889
log_history_close (mp->log);
1893
log_history_close (mp->echo);
1896
log_history_close (mp->state);
1902
man_settings_init (struct man_settings *ms,
1905
const char *pass_file,
1906
const char *client_user,
1907
const char *client_group,
1908
const int log_history_cache,
1909
const int echo_buffer_size,
1910
const int state_buffer_size,
1911
const char *write_peer_info_file,
1912
const int remap_sigusr1,
1913
const unsigned int flags)
1920
ms->client_uid = -1;
1921
ms->client_gid = -1;
1924
* Get username/password
1927
get_user_pass (&ms->up, pass_file, "Management", GET_USER_PASS_PASSWORD_ONLY);
1930
* lookup client UID/GID if specified
1934
struct user_state s;
1935
get_user (client_user, &s);
1936
ms->client_uid = user_state_uid (&s);
1937
msg (D_MANAGEMENT, "MANAGEMENT: client_uid=%d", ms->client_uid);
1938
ASSERT (ms->client_uid >= 0);
1942
struct group_state s;
1943
get_group (client_group, &s);
1944
ms->client_gid = group_state_gid (&s);
1945
msg (D_MANAGEMENT, "MANAGEMENT: client_gid=%d", ms->client_gid);
1946
ASSERT (ms->client_gid >= 0);
1949
ms->write_peer_info_file = string_alloc (write_peer_info_file, NULL);
1951
#if UNIX_SOCK_SUPPORT
1952
if (ms->flags & MF_UNIX_SOCK)
1953
sockaddr_unix_init (&ms->local_unix, addr);
1958
* Initialize socket address
1960
ms->local.addr.in4.sin_family = AF_INET;
1961
ms->local.addr.in4.sin_addr.s_addr = 0;
1962
ms->local.addr.in4.sin_port = htons (port);
1965
* Run management over tunnel, or
1968
if (streq (addr, "tunnel") && !(flags & MF_CONNECT_AS_CLIENT))
1970
ms->management_over_tunnel = true;
1974
ms->local.addr.in4.sin_addr.s_addr = getaddr
1975
(GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, NULL, NULL);
1980
* Log history and echo buffer may need to be resized
1982
ms->log_history_cache = log_history_cache;
1983
ms->echo_buffer_size = echo_buffer_size;
1984
ms->state_buffer_size = state_buffer_size;
1987
* Set remap sigusr1 flags
1989
if (remap_sigusr1 == SIGHUP)
1990
ms->mansig |= MANSIG_MAP_USR1_TO_HUP;
1991
else if (remap_sigusr1 == SIGTERM)
1992
ms->mansig |= MANSIG_MAP_USR1_TO_TERM;
1999
man_settings_close (struct man_settings *ms)
2001
free (ms->write_peer_info_file);
2007
man_connection_init (struct management *man)
2009
if (man->connection.state == MS_INITIAL)
2013
* This object is a sort of TCP/IP helper
2016
net_event_win32_init (&man->connection.ne32);
2020
* Allocate helper objects for command line input and
2021
* command output from/to the socket.
2023
man->connection.in = command_line_new (1024);
2024
man->connection.out = buffer_list_new (0);
2027
* Initialize event set for standalone usage, when we are
2028
* running outside of the primary event loop.
2032
man->connection.es = event_set_init (&maxevents, EVENT_METHOD_FAST);
2036
* Listen/connect socket
2038
if (man->settings.flags & MF_CONNECT_AS_CLIENT)
2046
man_connection_close (struct management *man)
2048
struct man_connection *mc = &man->connection;
2051
event_free (mc->es);
2053
net_event_win32_close (&mc->ne32);
2055
if (socket_defined (mc->sd_top))
2057
man_close_socket (man, mc->sd_top);
2058
man_delete_unix_socket (man);
2060
if (socket_defined (mc->sd_cli))
2061
man_close_socket (man, mc->sd_cli);
2063
command_line_free (mc->in);
2065
buffer_list_free (mc->out);
2066
#ifdef MANAGEMENT_DEF_AUTH
2067
in_extra_reset (&man->connection, false);
2069
man_connection_clear (mc);
2073
management_init (void)
2075
struct management *man;
2076
ALLOC_OBJ_CLEAR (man, struct management);
2078
man_persist_init (man,
2079
MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
2080
MANAGEMENT_ECHO_BUFFER_SIZE,
2081
MANAGEMENT_STATE_BUFFER_SIZE);
2083
man_connection_clear (&man->connection);
2089
management_open (struct management *man,
2092
const char *pass_file,
2093
const char *client_user,
2094
const char *client_group,
2095
const int log_history_cache,
2096
const int echo_buffer_size,
2097
const int state_buffer_size,
2098
const char *write_peer_info_file,
2099
const int remap_sigusr1,
2100
const unsigned int flags)
2105
* Save the settings only if they have not
2106
* been saved before.
2108
man_settings_init (&man->settings,
2117
write_peer_info_file,
2122
* The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
2123
* but may be changed here. Ditto for echo and state buffers.
2125
log_history_resize (man->persist.log, man->settings.log_history_cache);
2126
log_history_resize (man->persist.echo, man->settings.echo_buffer_size);
2127
log_history_resize (man->persist.state, man->settings.state_buffer_size);
2130
* If connection object is uninitialized and we are not doing
2131
* over-the-tunnel management, then open (listening) connection.
2133
if (man->connection.state == MS_INITIAL)
2135
if (!man->settings.management_over_tunnel)
2137
man_connection_init (man);
2146
management_close (struct management *man)
2148
man_connection_close (man);
2149
man_settings_close (&man->settings);
2150
man_persist_close (&man->persist);
2155
management_set_callback (struct management *man,
2156
const struct management_callback *cb)
2158
man->persist.standalone_disabled = true;
2159
man->persist.callback = *cb;
2163
management_clear_callback (struct management *man)
2165
man->persist.standalone_disabled = false;
2166
man->persist.hold_release = false;
2167
CLEAR (man->persist.callback);
2168
man_output_list_push_finalize (man); /* flush output queue */
2172
management_set_state (struct management *man,
2175
const in_addr_t tun_local_ip,
2176
const in_addr_t tun_remote_ip)
2178
if (man->persist.state && (!(man->settings.flags & MF_SERVER) || state < OPENVPN_STATE_CLIENT_BASE))
2180
struct gc_arena gc = gc_new ();
2182
const char *out = NULL;
2189
e.local_ip = tun_local_ip;
2190
e.remote_ip = tun_remote_ip;
2192
log_history_add (man->persist.state, &e);
2194
if (man->connection.state_realtime)
2195
out = log_entry_print (&e, LOG_PRINT_STATE_PREFIX
2196
| LOG_PRINT_INT_DATE
2198
| LOG_PRINT_LOCAL_IP
2199
| LOG_PRINT_REMOTE_IP
2201
| LOG_ECHO_TO_LOG, &gc);
2204
man_output_list_push (man, out);
2210
#ifdef MANAGEMENT_DEF_AUTH
2213
env_filter_match (const char *env_str, const int env_filter_level)
2215
static const char *env_names[] = {
2222
"ifconfig_netmask=",
2223
"daemon_start_time=",
2226
"ifconfig_pool_remote_ip=",
2227
"ifconfig_pool_netmask=",
2232
if (env_filter_level >= 1)
2235
for (i = 0; i < SIZE(env_names); ++i)
2237
const char *en = env_names[i];
2238
const size_t len = strlen(en);
2239
if (strncmp(env_str, en, len) == 0)
2249
man_output_env (const struct env_set *es, const bool tail, const int env_filter_level)
2254
for (e = es->list; e != NULL; e = e->next)
2256
if (e->string && (!env_filter_level || env_filter_match(e->string, env_filter_level)))
2257
msg (M_CLIENT, ">CLIENT:ENV,%s", e->string);
2261
msg (M_CLIENT, ">CLIENT:ENV,END");
2265
man_output_extra_env (struct management *man)
2267
struct gc_arena gc = gc_new ();
2268
struct env_set *es = env_set_create (&gc);
2269
if (man->persist.callback.n_clients)
2271
const int nclients = (*man->persist.callback.n_clients) (man->persist.callback.arg);
2272
setenv_int (es, "n_clients", nclients);
2274
man_output_env (es, false, man->connection.env_filter_level);
2279
validate_peer_info_line(const char *line)
2289
if (c == '=' && state == 1)
2291
else if (isalnum(c) || c == '_')
2302
return (state == 2);
2306
man_output_peer_info_env (struct management *man, struct man_def_auth_context *mdac)
2309
if (man->persist.callback.get_peer_info)
2311
const char *peer_info = (*man->persist.callback.get_peer_info) (man->persist.callback.arg, mdac->cid);
2315
buf_set_read (&buf, (const uint8_t *) peer_info, strlen(peer_info));
2316
while (buf_parse (&buf, '\n', line, sizeof (line)))
2319
if (validate_peer_info_line(line))
2321
msg (M_CLIENT, ">CLIENT:ENV,%s", line);
2324
msg (D_MANAGEMENT, "validation failed on peer_info line received from client");
2331
management_notify_client_needing_auth (struct management *management,
2332
const unsigned int mda_key_id,
2333
struct man_def_auth_context *mdac,
2334
const struct env_set *es)
2336
if (!(mdac->flags & DAF_CONNECTION_CLOSED))
2338
const char *mode = "CONNECT";
2339
if (mdac->flags & DAF_CONNECTION_ESTABLISHED)
2341
msg (M_CLIENT, ">CLIENT:%s,%lu,%u", mode, mdac->cid, mda_key_id);
2342
man_output_extra_env (management);
2343
man_output_peer_info_env(management, mdac);
2344
man_output_env (es, true, management->connection.env_filter_level);
2345
mdac->flags |= DAF_INITIAL_AUTH;
2350
management_connection_established (struct management *management,
2351
struct man_def_auth_context *mdac,
2352
const struct env_set *es)
2354
mdac->flags |= DAF_CONNECTION_ESTABLISHED;
2355
msg (M_CLIENT, ">CLIENT:ESTABLISHED,%lu", mdac->cid);
2356
man_output_extra_env (management);
2357
man_output_env (es, true, management->connection.env_filter_level);
2361
management_notify_client_close (struct management *management,
2362
struct man_def_auth_context *mdac,
2363
const struct env_set *es)
2365
if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED))
2367
msg (M_CLIENT, ">CLIENT:DISCONNECT,%lu", mdac->cid);
2368
man_output_env (es, true, management->connection.env_filter_level);
2369
mdac->flags |= DAF_CONNECTION_CLOSED;
2374
management_learn_addr (struct management *management,
2375
struct man_def_auth_context *mdac,
2376
const struct mroute_addr *addr,
2379
struct gc_arena gc = gc_new ();
2380
if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED))
2382
msg (M_CLIENT, ">CLIENT:ADDRESS,%lu,%s,%d",
2384
mroute_addr_print_ex (addr, MAPF_SUBNET, &gc),
2385
BOOL_CAST (primary));
2393
management_echo (struct management *man, const char *string, const bool pull)
2395
if (man->persist.echo)
2397
struct gc_arena gc = gc_new ();
2399
const char *out = NULL;
2405
e.u.intval = BOOL_CAST (pull);
2407
log_history_add (man->persist.echo, &e);
2409
if (man->connection.echo_realtime)
2410
out = log_entry_print (&e, LOG_PRINT_INT_DATE|LOG_PRINT_ECHO_PREFIX|LOG_PRINT_CRLF|MANAGEMENT_ECHO_FLAGS, &gc);
2413
man_output_list_push (man, out);
2420
management_post_tunnel_open (struct management *man, const in_addr_t tun_local_ip)
2423
* If we are running management over the tunnel,
2424
* this is the place to initialize the connection.
2426
if (man->settings.management_over_tunnel
2427
&& man->connection.state == MS_INITIAL)
2429
/* listen on our local TUN/TAP IP address */
2430
man->settings.local.addr.in4.sin_addr.s_addr = htonl (tun_local_ip);
2431
man_connection_init (man);
2437
management_pre_tunnel_close (struct management *man)
2439
if (man->settings.management_over_tunnel)
2440
man_connection_close (man);
2444
management_auth_failure (struct management *man, const char *type, const char *reason)
2447
msg (M_CLIENT, ">PASSWORD:Verification Failed: '%s' ['%s']", type, reason);
2449
msg (M_CLIENT, ">PASSWORD:Verification Failed: '%s'", type);
2453
man_persist_state (unsigned int *persistent, const int n)
2457
if (*persistent == (unsigned int)n)
2467
management_socket_set (struct management *man,
2468
struct event_set *es,
2470
unsigned int *persistent)
2472
if (man->connection.state != MS_INITIAL)
2474
event_t ev = net_event_win32_get_event (&man->connection.ne32);
2475
net_event_win32_reset_write (&man->connection.ne32);
2477
switch (man->connection.state)
2480
if (man_persist_state (persistent, 1))
2481
event_ctl (es, ev, EVENT_READ, arg);
2483
case MS_CC_WAIT_READ:
2484
if (man_persist_state (persistent, 2))
2485
event_ctl (es, ev, EVENT_READ, arg);
2487
case MS_CC_WAIT_WRITE:
2488
if (man_persist_state (persistent, 3))
2489
event_ctl (es, ev, EVENT_READ|EVENT_WRITE, arg);
2498
management_io (struct management *man)
2500
if (man->connection.state != MS_INITIAL)
2503
net_event_win32_reset (&man->connection.ne32);
2504
net_events = net_event_win32_get_event_mask (&man->connection.ne32);
2506
if (net_events & FD_CLOSE)
2508
man_reset_client_socket (man, false);
2512
if (man->connection.state == MS_LISTEN)
2514
if (net_events & FD_ACCEPT)
2517
net_event_win32_clear_selected_events (&man->connection.ne32, FD_ACCEPT);
2520
else if (man->connection.state == MS_CC_WAIT_READ || man->connection.state == MS_CC_WAIT_WRITE)
2522
if (net_events & FD_READ)
2524
while (man_read (man) > 0)
2526
net_event_win32_clear_selected_events (&man->connection.ne32, FD_READ);
2529
if (net_events & FD_WRITE)
2532
status = man_write (man);
2533
if (status < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
2535
net_event_win32_clear_selected_events (&man->connection.ne32, FD_WRITE);
2546
management_socket_set (struct management *man,
2547
struct event_set *es,
2549
unsigned int *persistent)
2551
switch (man->connection.state)
2554
if (man_persist_state (persistent, 1))
2555
event_ctl (es, man->connection.sd_top, EVENT_READ, arg);
2557
case MS_CC_WAIT_READ:
2558
if (man_persist_state (persistent, 2))
2559
event_ctl (es, man->connection.sd_cli, EVENT_READ, arg);
2561
case MS_CC_WAIT_WRITE:
2562
if (man_persist_state (persistent, 3))
2563
event_ctl (es, man->connection.sd_cli, EVENT_WRITE, arg);
2573
management_io (struct management *man)
2575
switch (man->connection.state)
2580
case MS_CC_WAIT_READ:
2583
case MS_CC_WAIT_WRITE:
2596
man_standalone_ok (const struct management *man)
2598
return !man->settings.management_over_tunnel && man->connection.state != MS_INITIAL;
2602
man_check_for_signals (volatile int *signal_received)
2604
if (signal_received)
2606
get_signal (signal_received);
2607
if (*signal_received)
2614
* Wait for socket I/O when outside primary event loop
2617
man_block (struct management *man, volatile int *signal_received, const time_t expire)
2620
struct event_set_return esr;
2623
if (man_standalone_ok (man))
2627
event_reset (man->connection.es);
2628
management_socket_set (man, man->connection.es, NULL, NULL);
2631
if (man_check_for_signals (signal_received))
2636
status = event_wait (man->connection.es, &tv, &esr, 1);
2638
if (man_check_for_signals (signal_received))
2646
else if (expire && now >= expire)
2648
/* set SIGINT signal if expiration time exceeded */
2650
if (signal_received)
2651
*signal_received = SIGINT;
2660
* Perform management socket output outside primary event loop
2663
man_output_standalone (struct management *man, volatile int *signal_received)
2665
if (man_standalone_ok (man))
2667
while (man->connection.state == MS_CC_WAIT_WRITE)
2669
management_io (man);
2670
if (man->connection.state == MS_CC_WAIT_WRITE)
2671
man_block (man, signal_received, 0);
2672
if (signal_received && *signal_received)
2679
* Process management event loop outside primary event loop
2682
man_standalone_event_loop (struct management *man, volatile int *signal_received, const time_t expire)
2685
if (man_standalone_ok (man))
2687
status = man_block (man, signal_received, expire);
2689
management_io (man);
2694
#define MWCC_PASSWORD_WAIT (1<<0)
2695
#define MWCC_HOLD_WAIT (1<<1)
2698
* Block until client connects
2701
man_wait_for_client_connection (struct management *man,
2702
volatile int *signal_received,
2703
const time_t expire,
2706
ASSERT (man_standalone_ok (man));
2707
if (man->connection.state == MS_LISTEN)
2709
if (flags & MWCC_PASSWORD_WAIT)
2710
msg (D_MANAGEMENT, "Need password(s) from management interface, waiting...");
2711
if (flags & MWCC_HOLD_WAIT)
2712
msg (D_MANAGEMENT, "Need hold release from management interface, waiting...");
2714
man_standalone_event_loop (man, signal_received, expire);
2715
if (signal_received && *signal_received)
2717
} while (man->connection.state == MS_LISTEN || man_password_needed (man));
2722
* Process the management event loop for sec seconds
2725
management_event_loop_n_seconds (struct management *man, int sec)
2727
if (man_standalone_ok (man))
2729
volatile int signal_received = 0;
2730
const bool standalone_disabled_save = man->persist.standalone_disabled;
2733
man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
2735
/* set expire time */
2740
/* if no client connection, wait for one */
2741
man_wait_for_client_connection (man, &signal_received, expire, 0);
2742
if (signal_received)
2745
/* run command processing event loop */
2748
man_standalone_event_loop (man, &signal_received, expire);
2749
if (!signal_received)
2750
man_check_for_signals (&signal_received);
2751
if (signal_received)
2756
man->persist.standalone_disabled = standalone_disabled_save;
2765
* Get a username/password from management channel in standalone mode.
2768
management_query_user_pass (struct management *man,
2769
struct user_pass *up,
2771
const unsigned int flags)
2773
struct gc_arena gc = gc_new ();
2776
if (man_standalone_ok (man))
2778
volatile int signal_received = 0;
2779
const bool standalone_disabled_save = man->persist.standalone_disabled;
2780
struct buffer alert_msg = alloc_buf_gc (128, &gc);
2781
const char *alert_type = NULL;
2782
const char *prefix = NULL;
2783
unsigned int up_query_mode = 0;
2786
man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
2787
man->persist.special_state_msg = NULL;
2789
CLEAR (man->connection.up_query);
2791
if (flags & GET_USER_PASS_NEED_OK)
2793
up_query_mode = UP_QUERY_NEED_OK;
2795
alert_type = "confirmation";
2797
else if (flags & GET_USER_PASS_NEED_STR)
2799
up_query_mode = UP_QUERY_NEED_STR;
2801
alert_type = "string";
2803
else if (flags & GET_USER_PASS_PASSWORD_ONLY)
2805
up_query_mode = UP_QUERY_PASS;
2806
prefix = "PASSWORD";
2807
alert_type = "password";
2811
up_query_mode = UP_QUERY_USER_PASS;
2812
prefix = "PASSWORD";
2813
alert_type = "username/password";
2815
buf_printf (&alert_msg, ">%s:Need '%s' %s",
2820
if (flags & (GET_USER_PASS_NEED_OK | GET_USER_PASS_NEED_STR))
2821
buf_printf (&alert_msg, " MSG:%s", up->username);
2823
man_wait_for_client_connection (man, &signal_received, 0, MWCC_PASSWORD_WAIT);
2824
if (signal_received)
2829
man->persist.special_state_msg = BSTR (&alert_msg);
2830
msg (M_CLIENT, "%s", man->persist.special_state_msg);
2832
/* tell command line parser which info we need */
2833
man->connection.up_query_mode = up_query_mode;
2834
man->connection.up_query_type = type;
2836
/* run command processing event loop until we get our username/password */
2839
man_standalone_event_loop (man, &signal_received, 0);
2840
if (!signal_received)
2841
man_check_for_signals (&signal_received);
2842
if (signal_received)
2847
} while (!man->connection.up_query.defined);
2851
man->connection.up_query_mode = UP_QUERY_DISABLED;
2852
man->connection.up_query_type = NULL;
2853
man->persist.standalone_disabled = standalone_disabled_save;
2854
man->persist.special_state_msg = NULL;
2856
/* pass through blank passwords */
2857
if (!strcmp (man->connection.up_query.password, blank_up))
2858
CLEAR (man->connection.up_query.password);
2861
* Transfer u/p to return object, zero any record
2862
* we hold in the management object.
2866
man->connection.up_query.nocache = up->nocache; /* preserve caller's nocache setting */
2867
*up = man->connection.up_query;
2869
CLEAR (man->connection.up_query);
2877
* Return true if management_hold() would block
2880
management_would_hold (struct management *man)
2882
return (man->settings.flags & MF_HOLD) && !man->persist.hold_release && man_standalone_ok (man);
2886
* Return true if (from the management interface's perspective) OpenVPN should
2890
management_should_daemonize (struct management *man)
2892
return management_would_hold (man) || (man->settings.flags & MF_QUERY_PASSWORDS);
2896
* If the hold flag is enabled, hibernate until a management client releases the hold.
2897
* Return true if the caller should not sleep for an additional time interval.
2900
management_hold (struct management *man)
2902
if (management_would_hold (man))
2904
volatile int signal_received = 0;
2905
const bool standalone_disabled_save = man->persist.standalone_disabled;
2907
man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
2908
man->persist.special_state_msg = NULL;
2909
man->settings.mansig |= MANSIG_IGNORE_USR1_HUP;
2911
man_wait_for_client_connection (man, &signal_received, 0, MWCC_HOLD_WAIT);
2913
if (!signal_received)
2915
man->persist.special_state_msg = ">HOLD:Waiting for hold release";
2916
msg (M_CLIENT, "%s", man->persist.special_state_msg);
2918
/* run command processing event loop until we get our username/password */
2921
man_standalone_event_loop (man, &signal_received, 0);
2922
if (!signal_received)
2923
man_check_for_signals (&signal_received);
2924
if (signal_received)
2926
} while (!man->persist.hold_release);
2930
man->persist.standalone_disabled = standalone_disabled_save;
2931
man->persist.special_state_msg = NULL;
2932
man->settings.mansig &= ~MANSIG_IGNORE_USR1_HUP;
2940
* struct command_line
2943
struct command_line *
2944
command_line_new (const int buf_len)
2946
struct command_line *cl;
2947
ALLOC_OBJ_CLEAR (cl, struct command_line);
2948
cl->buf = alloc_buf (buf_len);
2949
cl->residual = alloc_buf (buf_len);
2954
command_line_reset (struct command_line *cl)
2956
buf_clear (&cl->buf);
2957
buf_clear (&cl->residual);
2961
command_line_free (struct command_line *cl)
2963
command_line_reset (cl);
2964
free_buf (&cl->buf);
2965
free_buf (&cl->residual);
2970
command_line_add (struct command_line *cl, const unsigned char *buf, const int len)
2973
for (i = 0; i < len; ++i)
2975
if (buf[i] && (isprint(buf[i]) || buf[i] == '\n'))
2977
if (!buf_write_u8 (&cl->buf, buf[i]))
2978
buf_clear (&cl->buf);
2983
const unsigned char *
2984
command_line_get (struct command_line *cl)
2987
const unsigned char *ret = NULL;
2989
i = buf_substring_len (&cl->buf, '\n');
2992
buf_copy_excess (&cl->residual, &cl->buf, i);
2993
buf_chomp (&cl->buf);
2994
ret = (const unsigned char *) BSTR (&cl->buf);
3000
command_line_next (struct command_line *cl)
3002
buf_clear (&cl->buf);
3003
buf_copy (&cl->buf, &cl->residual);
3004
buf_clear (&cl->residual);
3012
log_entry_print (const struct log_entry *e, unsigned int flags, struct gc_arena *gc)
3014
struct buffer out = alloc_buf_gc (ERR_BUF_SIZE, gc);
3015
if (flags & LOG_FATAL_NOTIFY)
3016
buf_printf (&out, ">FATAL:");
3017
if (flags & LOG_PRINT_LOG_PREFIX)
3018
buf_printf (&out, ">LOG:");
3019
if (flags & LOG_PRINT_ECHO_PREFIX)
3020
buf_printf (&out, ">ECHO:");
3021
if (flags & LOG_PRINT_STATE_PREFIX)
3022
buf_printf (&out, ">STATE:");
3023
if (flags & LOG_PRINT_INT_DATE)
3024
buf_printf (&out, "%u,", (unsigned int)e->timestamp);
3025
if (flags & LOG_PRINT_MSG_FLAGS)
3026
buf_printf (&out, "%s,", msg_flags_string (e->u.msg_flags, gc));
3027
if (flags & LOG_PRINT_STATE)
3028
buf_printf (&out, "%s,", man_state_name (e->u.state));
3029
if (flags & LOG_PRINT_INTVAL)
3030
buf_printf (&out, "%d,", e->u.intval);
3032
buf_printf (&out, "%s", e->string);
3033
if (flags & LOG_PRINT_LOCAL_IP)
3034
buf_printf (&out, ",%s", print_in_addr_t (e->local_ip, IA_EMPTY_IF_UNDEF, gc));
3035
if (flags & LOG_PRINT_REMOTE_IP)
3036
buf_printf (&out, ",%s", print_in_addr_t (e->remote_ip, IA_EMPTY_IF_UNDEF, gc));
3037
if (flags & LOG_ECHO_TO_LOG)
3038
msg (D_MANAGEMENT, "MANAGEMENT: %s", BSTR (&out));
3039
if (flags & LOG_PRINT_CRLF)
3040
buf_printf (&out, "\r\n");
3045
log_entry_free_contents (struct log_entry *e)
3048
free ((char *)e->string);
3053
* struct log_history
3057
log_index (const struct log_history *h, int i)
3059
return modulo_add (h->base, i, h->capacity);
3063
log_history_obj_init (struct log_history *h, int capacity)
3066
h->capacity = capacity;
3067
ALLOC_ARRAY_CLEAR (h->array, struct log_entry, capacity);
3070
struct log_history *
3071
log_history_init (const int capacity)
3073
struct log_history *h;
3074
ASSERT (capacity > 0);
3075
ALLOC_OBJ (h, struct log_history);
3076
log_history_obj_init (h, capacity);
3081
log_history_free_contents (struct log_history *h)
3084
for (i = 0; i < h->size; ++i)
3085
log_entry_free_contents (&h->array[log_index(h, i)]);
3090
log_history_close (struct log_history *h)
3092
log_history_free_contents (h);
3097
log_history_add (struct log_history *h, const struct log_entry *le)
3099
struct log_entry *e;
3100
ASSERT (h->size >= 0 && h->size <= h->capacity);
3101
if (h->size == h->capacity)
3103
e = &h->array[h->base];
3104
log_entry_free_contents (e);
3105
h->base = log_index (h, 1);
3109
e = &h->array[log_index(h, h->size)];
3114
e->string = string_alloc (le->string, NULL);
3118
log_history_resize (struct log_history *h, const int capacity)
3120
if (capacity != h->capacity)
3122
struct log_history newlog;
3125
ASSERT (capacity > 0);
3126
log_history_obj_init (&newlog, capacity);
3128
for (i = 0; i < h->size; ++i)
3129
log_history_add (&newlog, &h->array[log_index(h, i)]);
3131
log_history_free_contents (h);
3136
const struct log_entry *
3137
log_history_ref (const struct log_history *h, const int index)
3139
if (index >= 0 && index < h->size)
3140
return &h->array[log_index(h, (h->size - 1) - index)];
3145
#if HTTP_PROXY_FALLBACK
3148
management_http_proxy_fallback_notify (struct management *man, const char *type, const char *remote_ip_hint)
3151
msg (M_CLIENT, ">PROXY:%s,%s", type, remote_ip_hint);
3153
msg (M_CLIENT, ">PROXY:%s", type);
3156
#endif /* HTTP_PROXY_FALLBACK */
3159
static void dummy(void) {}
3160
#endif /* ENABLE_MANAGEMENT */