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-2009 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");
101 msg (M_CLIENT
, "client-pf CID : Define packet filter for client CID (MULTILINE)");
104 msg (M_CLIENT
, "signal s : Send signal s to daemon,");
105 msg (M_CLIENT
, " s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2.");
106 msg (M_CLIENT
, "state [on|off] [N|all] : Like log, but show state history.");
107 msg (M_CLIENT
, "status [n] : Show current daemon status info using format #n.");
108 msg (M_CLIENT
, "test n : Produce n lines of output for testing/debugging.");
109 msg (M_CLIENT
, "username type u : Enter username u for a queried OpenVPN username.");
110 msg (M_CLIENT
, "verb [n] : Set log verbosity level to n, or show if n is absent.");
111 msg (M_CLIENT
, "version : Show current version number.");
112 msg (M_CLIENT
, "END");
116 man_state_name (const int state
)
120 case OPENVPN_STATE_INITIAL
:
122 case OPENVPN_STATE_CONNECTING
:
124 case OPENVPN_STATE_WAIT
:
126 case OPENVPN_STATE_AUTH
:
128 case OPENVPN_STATE_GET_CONFIG
:
130 case OPENVPN_STATE_ASSIGN_IP
:
132 case OPENVPN_STATE_ADD_ROUTES
:
134 case OPENVPN_STATE_CONNECTED
:
136 case OPENVPN_STATE_RECONNECTING
:
137 return "RECONNECTING";
138 case OPENVPN_STATE_EXITING
:
140 case OPENVPN_STATE_RESOLVE
:
142 case OPENVPN_STATE_TCP_CONNECT
:
143 return "TCP_CONNECT";
150 man_welcome (struct management
*man
)
152 msg (M_CLIENT
, ">INFO:OpenVPN Management Interface Version %d -- type 'help' for more info",
154 if (man
->persist
.special_state_msg
)
155 msg (M_CLIENT
, "%s", man
->persist
.special_state_msg
);
159 man_password_needed (struct management
*man
)
161 return man
->settings
.up
.defined
&& !man
->connection
.password_verified
;
165 man_check_password (struct management
*man
, const char *line
)
167 if (man_password_needed (man
))
169 if (streq (line
, man
->settings
.up
.password
))
171 man
->connection
.password_verified
= true;
172 msg (M_CLIENT
, "SUCCESS: password is correct");
177 man
->connection
.password_verified
= false;
178 msg (M_CLIENT
, "ERROR: bad password");
179 if (++man
->connection
.password_tries
>= MANAGEMENT_N_PASSWORD_RETRIES
)
181 msg (M_WARN
, "MAN: client connection rejected after %d failed password attempts",
182 MANAGEMENT_N_PASSWORD_RETRIES
);
183 man
->connection
.halt
= true;
190 man_update_io_state (struct management
*man
)
192 if (socket_defined (man
->connection
.sd_cli
))
194 if (buffer_list_defined (man
->connection
.out
))
196 man
->connection
.state
= MS_CC_WAIT_WRITE
;
200 man
->connection
.state
= MS_CC_WAIT_READ
;
206 man_output_list_push (struct management
*man
, const char *str
)
208 if (management_connected (man
))
211 buffer_list_push (man
->connection
.out
, (const unsigned char *) str
);
212 man_update_io_state (man
);
213 if (!man
->persist
.standalone_disabled
)
215 volatile int signal_received
= 0;
216 man_output_standalone (man
, &signal_received
);
222 man_prompt (struct management
*man
)
224 if (man_password_needed (man
))
225 man_output_list_push (man
, "ENTER PASSWORD:");
226 #if 0 /* should we use prompt? */
228 man_output_list_push (man
, PACKAGE_NAME
">");
233 man_delete_unix_socket (struct management
*man
)
235 #if UNIX_SOCK_SUPPORT
236 if ((man
->settings
.flags
& (MF_UNIX_SOCK
|MF_CONNECT_AS_CLIENT
)) == MF_UNIX_SOCK
)
237 socket_delete_unix (&man
->settings
.local_unix
);
242 man_close_socket (struct management
*man
, const socket_descriptor_t sd
)
246 * Windows doesn't need this because the ne32 event is permanently
247 * enabled at struct management scope.
249 if (man
->persist
.callback
.delete_event
)
250 (*man
->persist
.callback
.delete_event
) (man
->persist
.callback
.arg
, sd
);
252 openvpn_close_socket (sd
);
256 virtual_output_callback_func (void *arg
, const unsigned int flags
, const char *str
)
258 static int recursive_level
= 0; /* GLOBAL */
260 if (!recursive_level
) /* don't allow recursion */
262 struct gc_arena gc
= gc_new ();
263 struct management
*man
= (struct management
*) arg
;
265 const char *out
= NULL
;
272 e
.u
.msg_flags
= flags
;
276 man
->persist
.standalone_disabled
= false;
278 if (flags
!= M_CLIENT
)
279 log_history_add (man
->persist
.log
, &e
);
281 if (!man_password_needed (man
))
283 if (flags
== M_CLIENT
)
284 out
= log_entry_print (&e
, LOG_PRINT_CRLF
, &gc
);
285 else if (man
->connection
.log_realtime
)
286 out
= log_entry_print (&e
, LOG_PRINT_INT_DATE
287 | LOG_PRINT_MSG_FLAGS
288 | LOG_PRINT_LOG_PREFIX
289 | LOG_PRINT_CRLF
, &gc
);
291 man_output_list_push (man
, out
);
294 out
= log_entry_print (&e
, LOG_FATAL_NOTIFY
|LOG_PRINT_CRLF
, &gc
);
297 man_output_list_push (man
, out
);
298 man_reset_client_socket (man
, true);
309 * Given a signal, return the signal with possible remapping applied,
310 * or -1 if the signal should be ignored.
313 man_mod_signal (const struct management
*man
, const int signum
)
315 const unsigned int flags
= man
->settings
.mansig
;
319 if (flags
& MANSIG_MAP_USR1_TO_HUP
)
321 if (flags
& MANSIG_MAP_USR1_TO_TERM
)
324 if (flags
& MANSIG_IGNORE_USR1_HUP
)
326 if (s
== SIGHUP
|| s
== SIGUSR1
)
333 man_signal (struct management
*man
, const char *name
)
335 const int sig
= parse_signal (name
);
338 const int sig_mod
= man_mod_signal (man
, sig
);
341 throw_signal (sig_mod
);
342 msg (M_CLIENT
, "SUCCESS: signal %s thrown", signal_name (sig_mod
, true));
346 if (man
->persist
.special_state_msg
)
347 msg (M_CLIENT
, "%s", man
->persist
.special_state_msg
);
349 msg (M_CLIENT
, "ERROR: signal '%s' is currently ignored", name
);
354 msg (M_CLIENT
, "ERROR: signal '%s' is not a known signal type", name
);
359 man_status (struct management
*man
, const int version
, struct status_output
*so
)
361 if (man
->persist
.callback
.status
)
363 (*man
->persist
.callback
.status
) (man
->persist
.callback
.arg
, version
, so
);
367 msg (M_CLIENT
, "ERROR: The 'status' command is not supported by the current daemon mode");
372 man_bytecount (struct management
*man
, const int update_seconds
)
374 if (update_seconds
>= 0)
375 man
->connection
.bytecount_update_seconds
= update_seconds
;
377 man
->connection
.bytecount_update_seconds
= 0;
378 msg (M_CLIENT
, "SUCCESS: bytecount interval changed");
382 man_bytecount_output_client (struct management
*man
)
386 /* do in a roundabout way to work around possible mingw or mingw-glibc bug */
387 openvpn_snprintf (in
, sizeof (in
), counter_format
, man
->persist
.bytes_in
);
388 openvpn_snprintf (out
, sizeof (out
), counter_format
, man
->persist
.bytes_out
);
389 msg (M_CLIENT
, ">BYTECOUNT:%s,%s", in
, out
);
390 man
->connection
.bytecount_last_update
= now
;
393 #ifdef MANAGEMENT_DEF_AUTH
396 man_bytecount_output_server (struct management
*man
,
397 const counter_type
*bytes_in_total
,
398 const counter_type
*bytes_out_total
,
399 struct man_def_auth_context
*mdac
)
403 /* do in a roundabout way to work around possible mingw or mingw-glibc bug */
404 openvpn_snprintf (in
, sizeof (in
), counter_format
, *bytes_in_total
);
405 openvpn_snprintf (out
, sizeof (out
), counter_format
, *bytes_out_total
);
406 msg (M_CLIENT
, ">BYTECOUNT_CLI:%lu,%s,%s", mdac
->cid
, in
, out
);
407 mdac
->bytecount_last_update
= now
;
413 man_kill (struct management
*man
, const char *victim
)
415 struct gc_arena gc
= gc_new ();
417 if (man
->persist
.callback
.kill_by_cn
&& man
->persist
.callback
.kill_by_addr
)
424 buf_set_read (&buf
, (uint8_t*) victim
, strlen (victim
) + 1);
425 buf_parse (&buf
, ':', p1
, sizeof (p1
));
426 buf_parse (&buf
, ':', p2
, sizeof (p2
));
428 if (strlen (p1
) && strlen (p2
))
430 /* IP:port specified */
432 const in_addr_t addr
= getaddr (GETADDR_HOST_ORDER
|GETADDR_MSG_VIRT_OUT
, p1
, 0, &status
, NULL
);
435 const int port
= atoi (p2
);
436 if (port
> 0 && port
< 65536)
438 n_killed
= (*man
->persist
.callback
.kill_by_addr
) (man
->persist
.callback
.arg
, addr
, port
);
441 msg (M_CLIENT
, "SUCCESS: %d client(s) at address %s:%d killed",
443 print_in_addr_t (addr
, 0, &gc
),
448 msg (M_CLIENT
, "ERROR: client at address %s:%d not found",
449 print_in_addr_t (addr
, 0, &gc
),
455 msg (M_CLIENT
, "ERROR: port number is out of range: %s", p2
);
460 msg (M_CLIENT
, "ERROR: error parsing IP address: %s", p1
);
463 else if (strlen (p1
))
465 /* common name specified */
466 n_killed
= (*man
->persist
.callback
.kill_by_cn
) (man
->persist
.callback
.arg
, p1
);
469 msg (M_CLIENT
, "SUCCESS: common name '%s' found, %d client(s) killed", p1
, n_killed
);
473 msg (M_CLIENT
, "ERROR: common name '%s' not found", p1
);
478 msg (M_CLIENT
, "ERROR: kill parse");
483 msg (M_CLIENT
, "ERROR: The 'kill' command is not supported by the current daemon mode");
490 * General-purpose history command handler
491 * for the log and echo commands.
494 man_history (struct management
*man
,
497 struct log_history
*log
,
499 const unsigned int lep_flags
)
501 struct gc_arena gc
= gc_new ();
504 if (streq (parm
, "on"))
507 msg (M_CLIENT
, "SUCCESS: real-time %s notification set to ON", type
);
509 else if (streq (parm
, "off"))
512 msg (M_CLIENT
, "SUCCESS: real-time %s notification set to OFF", type
);
514 else if (streq (parm
, "all") || (n
= atoi (parm
)) > 0)
516 const int size
= log_history_size (log
);
517 const int start
= (n
? n
: size
) - 1;
520 for (i
= start
; i
>= 0; --i
)
522 const struct log_entry
*e
= log_history_ref (log
, i
);
525 const char *out
= log_entry_print (e
, lep_flags
, &gc
);
526 virtual_output_callback_func (man
, M_CLIENT
, out
);
529 msg (M_CLIENT
, "END");
533 msg (M_CLIENT
, "ERROR: %s parameter must be 'on' or 'off' or some number n or 'all'", type
);
540 man_log (struct management
*man
, const char *parm
)
546 &man
->connection
.log_realtime
,
547 LOG_PRINT_INT_DATE
|LOG_PRINT_MSG_FLAGS
);
551 man_echo (struct management
*man
, const char *parm
)
557 &man
->connection
.echo_realtime
,
558 LOG_PRINT_INT_DATE
|MANAGEMENT_ECHO_FLAGS
);
562 man_state (struct management
*man
, const char *parm
)
568 &man
->connection
.state_realtime
,
569 LOG_PRINT_INT_DATE
|LOG_PRINT_STATE
|
570 LOG_PRINT_LOCAL_IP
|LOG_PRINT_REMOTE_IP
);
574 man_up_finalize (struct management
*man
)
576 switch (man
->connection
.up_query_mode
)
578 case UP_QUERY_DISABLED
:
579 man
->connection
.up_query
.defined
= false;
581 case UP_QUERY_USER_PASS
:
582 if (strlen (man
->connection
.up_query
.username
) && strlen (man
->connection
.up_query
.password
))
583 man
->connection
.up_query
.defined
= true;
586 if (strlen (man
->connection
.up_query
.password
))
587 man
->connection
.up_query
.defined
= true;
589 case UP_QUERY_NEED_OK
:
590 if (strlen (man
->connection
.up_query
.password
))
591 man
->connection
.up_query
.defined
= true;
593 case UP_QUERY_NEED_STR
:
594 if (strlen (man
->connection
.up_query
.password
))
595 man
->connection
.up_query
.defined
= true;
603 man_query_user_pass (struct management
*man
,
613 ASSERT (man
->connection
.up_query_type
);
614 if (streq (man
->connection
.up_query_type
, type
))
616 strncpynt (dest
, string
, len
);
617 man_up_finalize (man
);
618 msg (M_CLIENT
, "SUCCESS: '%s' %s entered, but not yet verified",
623 msg (M_CLIENT
, "ERROR: %s of type '%s' entered, but we need one of type '%s'",
626 man
->connection
.up_query_type
);
630 msg (M_CLIENT
, "ERROR: no %s is currently needed at this time", prompt
);
635 man_query_username (struct management
*man
, const char *type
, const char *string
)
637 const bool needed
= (man
->connection
.up_query_mode
== UP_QUERY_USER_PASS
&& man
->connection
.up_query_type
);
638 man_query_user_pass (man
, type
, string
, needed
, "username", man
->connection
.up_query
.username
, USER_PASS_LEN
);
642 man_query_password (struct management
*man
, const char *type
, const char *string
)
644 const bool needed
= ((man
->connection
.up_query_mode
== UP_QUERY_USER_PASS
645 || man
->connection
.up_query_mode
== UP_QUERY_PASS
)
646 && man
->connection
.up_query_type
);
647 if (!string
[0]) /* allow blank passwords to be passed through using the blank_up tag */
649 man_query_user_pass (man
, type
, string
, needed
, "password", man
->connection
.up_query
.password
, USER_PASS_LEN
);
653 man_query_need_ok (struct management
*man
, const char *type
, const char *action
)
655 const bool needed
= ((man
->connection
.up_query_mode
== UP_QUERY_NEED_OK
) && man
->connection
.up_query_type
);
656 man_query_user_pass (man
, type
, action
, needed
, "needok-confirmation", man
->connection
.up_query
.password
, USER_PASS_LEN
);
660 man_query_need_str (struct management
*man
, const char *type
, const char *action
)
662 const bool needed
= ((man
->connection
.up_query_mode
== UP_QUERY_NEED_STR
) && man
->connection
.up_query_type
);
663 man_query_user_pass (man
, type
, action
, needed
, "needstr-string", man
->connection
.up_query
.password
, USER_PASS_LEN
);
667 man_forget_passwords (struct management
*man
)
669 #if defined(USE_CRYPTO) && defined(USE_SSL)
671 msg (M_CLIENT
, "SUCCESS: Passwords were forgotten");
676 man_net (struct management
*man
)
678 if (man
->persist
.callback
.show_net
)
680 (*man
->persist
.callback
.show_net
) (man
->persist
.callback
.arg
, M_CLIENT
);
684 msg (M_CLIENT
, "ERROR: The 'net' command is not supported by the current daemon mode");
691 man_pkcs11_id_count (struct management
*man
)
693 msg (M_CLIENT
, ">PKCS11ID-COUNT:%d", pkcs11_management_id_count ());
697 man_pkcs11_id_get (struct management
*man
, const int index
)
702 if (pkcs11_management_id_get (index
, &id
, &base64
))
703 msg (M_CLIENT
, ">PKCS11ID-ENTRY:'%d', ID:'%s', BLOB:'%s'", index
, id
, base64
);
705 msg (M_CLIENT
, ">PKCS11ID-ENTRY:'%d'", index
);
716 man_hold (struct management
*man
, const char *cmd
)
720 if (streq (cmd
, "on"))
722 man
->settings
.flags
|= MF_HOLD
;
723 msg (M_CLIENT
, "SUCCESS: hold flag set to ON");
725 else if (streq (cmd
, "off"))
727 man
->settings
.flags
&= ~MF_HOLD
;
728 msg (M_CLIENT
, "SUCCESS: hold flag set to OFF");
730 else if (streq (cmd
, "release"))
732 man
->persist
.hold_release
= true;
733 msg (M_CLIENT
, "SUCCESS: hold release succeeded");
737 msg (M_CLIENT
, "ERROR: bad hold command parameter");
741 msg (M_CLIENT
, "SUCCESS: hold=%d", BOOL_CAST(man
->settings
.flags
& MF_HOLD
));
744 #ifdef MANAGEMENT_DEF_AUTH
747 parse_cid (const char *str
, unsigned long *cid
)
749 if (sscanf (str
, "%lu", cid
) == 1)
753 msg (M_CLIENT
, "ERROR: cannot parse CID");
759 parse_kid (const char *str
, unsigned int *kid
)
761 if (sscanf (str
, "%u", kid
) == 1)
765 msg (M_CLIENT
, "ERROR: cannot parse KID");
771 in_extra_reset (struct man_connection
*mc
, const bool new)
777 mc
->in_extra_cmd
= IEC_UNDEF
;
778 mc
->in_extra_cid
= 0;
779 mc
->in_extra_kid
= 0;
783 buffer_list_free (mc
->in_extra
);
787 mc
->in_extra
= buffer_list_new (0);
792 in_extra_dispatch (struct management
*man
)
794 switch (man
->connection
.in_extra_cmd
)
796 case IEC_CLIENT_AUTH
:
797 if (man
->persist
.callback
.client_auth
)
799 const bool status
= (*man
->persist
.callback
.client_auth
)
800 (man
->persist
.callback
.arg
,
801 man
->connection
.in_extra_cid
,
802 man
->connection
.in_extra_kid
,
806 man
->connection
.in_extra
);
807 man
->connection
.in_extra
= NULL
;
810 msg (M_CLIENT
, "SUCCESS: client-auth command succeeded");
814 msg (M_CLIENT
, "ERROR: client-auth command failed");
819 msg (M_CLIENT
, "ERROR: The client-auth command is not supported by the current daemon mode");
824 if (man
->persist
.callback
.client_pf
)
826 const bool status
= (*man
->persist
.callback
.client_pf
)
827 (man
->persist
.callback
.arg
,
828 man
->connection
.in_extra_cid
,
829 man
->connection
.in_extra
);
830 man
->connection
.in_extra
= NULL
;
833 msg (M_CLIENT
, "SUCCESS: client-pf command succeeded");
837 msg (M_CLIENT
, "ERROR: client-pf command failed");
842 msg (M_CLIENT
, "ERROR: The client-pf command is not supported by the current daemon mode");
847 in_extra_reset (&man
->connection
, false);
851 man_client_auth (struct management
*man
, const char *cid_str
, const char *kid_str
, const bool extra
)
853 struct man_connection
*mc
= &man
->connection
;
854 mc
->in_extra_cid
= 0;
855 mc
->in_extra_kid
= 0;
856 if (parse_cid (cid_str
, &mc
->in_extra_cid
)
857 && parse_kid (kid_str
, &mc
->in_extra_kid
))
859 mc
->in_extra_cmd
= IEC_CLIENT_AUTH
;
860 in_extra_reset (mc
, true);
862 in_extra_dispatch (man
);
867 man_client_deny (struct management
*man
, const char *cid_str
, const char *kid_str
, const char *reason
, const char *client_reason
)
869 unsigned long cid
= 0;
870 unsigned int kid
= 0;
871 if (parse_cid (cid_str
, &cid
) && parse_kid (kid_str
, &kid
))
873 if (man
->persist
.callback
.client_auth
)
875 const bool status
= (*man
->persist
.callback
.client_auth
)
876 (man
->persist
.callback
.arg
,
885 msg (M_CLIENT
, "SUCCESS: client-deny command succeeded");
889 msg (M_CLIENT
, "ERROR: client-deny command failed");
894 msg (M_CLIENT
, "ERROR: The client-deny command is not supported by the current daemon mode");
900 man_client_kill (struct management
*man
, const char *cid_str
)
902 unsigned long cid
= 0;
903 if (parse_cid (cid_str
, &cid
))
905 if (man
->persist
.callback
.kill_by_cid
)
907 const bool status
= (*man
->persist
.callback
.kill_by_cid
) (man
->persist
.callback
.arg
, cid
);
910 msg (M_CLIENT
, "SUCCESS: client-kill command succeeded");
914 msg (M_CLIENT
, "ERROR: client-kill command failed");
919 msg (M_CLIENT
, "ERROR: The client-kill command is not supported by the current daemon mode");
925 man_client_n_clients (struct management
*man
)
927 if (man
->persist
.callback
.n_clients
)
929 const int nclients
= (*man
->persist
.callback
.n_clients
) (man
->persist
.callback
.arg
);
930 msg (M_CLIENT
, "SUCCESS: nclients=%d", nclients
);
934 msg (M_CLIENT
, "ERROR: The nclients command is not supported by the current daemon mode");
941 man_client_pf (struct management
*man
, const char *cid_str
)
943 struct man_connection
*mc
= &man
->connection
;
944 mc
->in_extra_cid
= 0;
945 mc
->in_extra_kid
= 0;
946 if (parse_cid (cid_str
, &mc
->in_extra_cid
))
948 mc
->in_extra_cmd
= IEC_CLIENT_PF
;
949 in_extra_reset (mc
, true);
957 man_load_stats (struct management
*man
)
959 extern counter_type link_read_bytes_global
;
960 extern counter_type link_write_bytes_global
;
963 if (man
->persist
.callback
.n_clients
)
964 nclients
= (*man
->persist
.callback
.n_clients
) (man
->persist
.callback
.arg
);
965 msg (M_CLIENT
, "SUCCESS: nclients=%d,bytesin=" counter_format
",bytesout=" counter_format
,
967 link_read_bytes_global
,
968 link_write_bytes_global
);
971 #define MN_AT_LEAST (1<<0)
974 man_need (struct management
*man
, const char **p
, const int n
, unsigned int flags
)
978 for (i
= 1; i
<= n
; ++i
)
982 msg (M_CLIENT
, "ERROR: the '%s' command requires %s%d parameter%s",
984 (flags
& MN_AT_LEAST
) ? "at least " : "",
994 man_dispatch_command (struct management
*man
, struct status_output
*so
, const char **p
, const int nparms
)
996 struct gc_arena gc
= gc_new ();
999 if (streq (p
[0], "exit") || streq (p
[0], "quit"))
1001 man
->connection
.halt
= true;
1004 else if (streq (p
[0], "help"))
1008 else if (streq (p
[0], "version"))
1010 msg (M_CLIENT
, "OpenVPN Version: %s", title_string
);
1011 msg (M_CLIENT
, "Management Version: %d", MANAGEMENT_VERSION
);
1012 msg (M_CLIENT
, "END");
1014 else if (streq (p
[0], "pid"))
1016 msg (M_CLIENT
, "SUCCESS: pid=%d", openvpn_getpid ());
1018 #ifdef MANAGEMENT_DEF_AUTH
1019 else if (streq (p
[0], "nclients"))
1021 man_client_n_clients (man
);
1024 else if (streq (p
[0], "signal"))
1026 if (man_need (man
, p
, 1, 0))
1027 man_signal (man
, p
[1]);
1029 else if (streq (p
[0], "load-stats"))
1031 man_load_stats (man
);
1033 else if (streq (p
[0], "status"))
1037 version
= atoi (p
[1]);
1038 man_status (man
, version
, so
);
1040 else if (streq (p
[0], "kill"))
1042 if (man_need (man
, p
, 1, 0))
1043 man_kill (man
, p
[1]);
1045 else if (streq (p
[0], "verb"))
1049 const int level
= atoi(p
[1]);
1050 if (set_debug_level (level
, 0))
1051 msg (M_CLIENT
, "SUCCESS: verb level changed");
1053 msg (M_CLIENT
, "ERROR: verb level is out of range");
1056 msg (M_CLIENT
, "SUCCESS: verb=%d", get_debug_level ());
1058 else if (streq (p
[0], "mute"))
1062 const int level
= atoi(p
[1]);
1063 if (set_mute_cutoff (level
))
1064 msg (M_CLIENT
, "SUCCESS: mute level changed");
1066 msg (M_CLIENT
, "ERROR: mute level is out of range");
1069 msg (M_CLIENT
, "SUCCESS: mute=%d", get_mute_cutoff ());
1071 else if (streq (p
[0], "auth-retry"))
1076 if (auth_retry_set (M_CLIENT
, p
[1]))
1077 msg (M_CLIENT
, "SUCCESS: auth-retry parameter changed");
1079 msg (M_CLIENT
, "ERROR: bad auth-retry parameter");
1082 msg (M_CLIENT
, "SUCCESS: auth-retry=%s", auth_retry_print ());
1084 msg (M_CLIENT
, "ERROR: auth-retry feature is unavailable");
1087 else if (streq (p
[0], "state"))
1091 man_state (man
, "1");
1096 man_state (man
, p
[1]);
1098 man_state (man
, p
[2]);
1101 else if (streq (p
[0], "log"))
1103 if (man_need (man
, p
, 1, MN_AT_LEAST
))
1106 man_log (man
, p
[1]);
1108 man_log (man
, p
[2]);
1111 else if (streq (p
[0], "echo"))
1113 if (man_need (man
, p
, 1, MN_AT_LEAST
))
1116 man_echo (man
, p
[1]);
1118 man_echo (man
, p
[2]);
1121 else if (streq (p
[0], "username"))
1123 if (man_need (man
, p
, 2, 0))
1124 man_query_username (man
, p
[1], p
[2]);
1126 else if (streq (p
[0], "password"))
1128 if (man_need (man
, p
, 2, 0))
1129 man_query_password (man
, p
[1], p
[2]);
1131 else if (streq (p
[0], "forget-passwords"))
1133 man_forget_passwords (man
);
1135 else if (streq (p
[0], "needok"))
1137 if (man_need (man
, p
, 2, 0))
1138 man_query_need_ok (man
, p
[1], p
[2]);
1140 else if (streq (p
[0], "needstr"))
1142 if (man_need (man
, p
, 2, 0))
1143 man_query_need_str (man
, p
[1], p
[2]);
1145 else if (streq (p
[0], "net"))
1149 else if (streq (p
[0], "hold"))
1151 man_hold (man
, p
[1]);
1153 else if (streq (p
[0], "bytecount"))
1155 if (man_need (man
, p
, 1, 0))
1156 man_bytecount (man
, atoi(p
[1]));
1158 #ifdef MANAGEMENT_DEF_AUTH
1159 else if (streq (p
[0], "client-kill"))
1161 if (man_need (man
, p
, 1, 0))
1162 man_client_kill (man
, p
[1]);
1164 else if (streq (p
[0], "client-deny"))
1166 if (man_need (man
, p
, 3, MN_AT_LEAST
))
1167 man_client_deny (man
, p
[1], p
[2], p
[3], p
[4]);
1169 else if (streq (p
[0], "client-auth-nt"))
1171 if (man_need (man
, p
, 2, 0))
1172 man_client_auth (man
, p
[1], p
[2], false);
1174 else if (streq (p
[0], "client-auth"))
1176 if (man_need (man
, p
, 2, 0))
1177 man_client_auth (man
, p
[1], p
[2], true);
1179 #ifdef MANAGEMENT_PF
1180 else if (streq (p
[0], "client-pf"))
1182 if (man_need (man
, p
, 1, 0))
1183 man_client_pf (man
, p
[1]);
1187 #ifdef ENABLE_PKCS11
1188 else if (streq (p
[0], "pkcs11-id-count"))
1190 man_pkcs11_id_count (man
);
1192 else if (streq (p
[0], "pkcs11-id-get"))
1194 if (man_need (man
, p
, 1, 0))
1195 man_pkcs11_id_get (man
, atoi(p
[1]));
1199 else if (streq (p
[0], "test"))
1201 if (man_need (man
, p
, 1, 0))
1204 const int n
= atoi (p
[1]);
1205 for (i
= 0; i
< n
; ++i
)
1207 msg (M_CLIENT
, "[%d] The purpose of this command is to generate large amounts of output.", i
);
1214 msg (M_CLIENT
, "ERROR: unknown command, enter 'help' for more options");
1224 man_start_ne32 (struct management
*man
)
1226 switch (man
->connection
.state
)
1229 net_event_win32_start (&man
->connection
.ne32
, FD_ACCEPT
, man
->connection
.sd_top
);
1231 case MS_CC_WAIT_READ
:
1232 case MS_CC_WAIT_WRITE
:
1233 net_event_win32_start (&man
->connection
.ne32
, FD_READ
|FD_WRITE
|FD_CLOSE
, man
->connection
.sd_cli
);
1241 man_stop_ne32 (struct management
*man
)
1243 net_event_win32_stop (&man
->connection
.ne32
);
1249 man_record_peer_info (struct management
*man
)
1251 struct gc_arena gc
= gc_new ();
1252 if (man
->settings
.write_peer_info_file
)
1254 bool success
= false;
1255 #ifdef HAVE_GETSOCKNAME
1256 if (socket_defined (man
->connection
.sd_cli
))
1258 struct sockaddr_in addr
;
1259 socklen_t addrlen
= sizeof (addr
);
1263 status
= getsockname (man
->connection
.sd_cli
, (struct sockaddr
*)&addr
, &addrlen
);
1264 if (!status
&& addrlen
== sizeof (addr
))
1266 const in_addr_t a
= ntohl (addr
.sin_addr
.s_addr
);
1267 const int p
= ntohs (addr
.sin_port
);
1268 FILE *fp
= fopen (man
->settings
.write_peer_info_file
, "w");
1271 fprintf (fp
, "%s\n%d\n", print_in_addr_t (a
, 0, &gc
), p
);
1280 msg (D_MANAGEMENT
, "MANAGEMENT: failed to write peer info to file %s",
1281 man
->settings
.write_peer_info_file
);
1282 throw_signal_soft (SIGTERM
, "management-connect-failed");
1289 man_connection_settings_reset (struct management
*man
)
1291 man
->connection
.state_realtime
= false;
1292 man
->connection
.log_realtime
= false;
1293 man
->connection
.echo_realtime
= false;
1294 man
->connection
.bytecount_update_seconds
= 0;
1295 man
->connection
.password_verified
= false;
1296 man
->connection
.password_tries
= 0;
1297 man
->connection
.halt
= false;
1298 man
->connection
.state
= MS_CC_WAIT_WRITE
;
1302 man_new_connection_post (struct management
*man
, const char *description
)
1304 struct gc_arena gc
= gc_new ();
1306 set_nonblock (man
->connection
.sd_cli
);
1307 set_cloexec (man
->connection
.sd_cli
);
1309 man_connection_settings_reset (man
);
1312 man_start_ne32 (man
);
1315 #if UNIX_SOCK_SUPPORT
1316 if (man
->settings
.flags
& MF_UNIX_SOCK
)
1318 msg (D_MANAGEMENT
, "MANAGEMENT: %s %s",
1320 sockaddr_unix_name (&man
->settings
.local_unix
, "NULL"));
1324 msg (D_MANAGEMENT
, "MANAGEMENT: %s %s",
1326 print_sockaddr (&man
->settings
.local
, &gc
));
1328 buffer_list_reset (man
->connection
.out
);
1330 if (!man_password_needed (man
))
1333 man_update_io_state (man
);
1338 #if UNIX_SOCK_SUPPORT
1340 man_verify_unix_peer_uid_gid (struct management
*man
, const socket_descriptor_t sd
)
1342 if (socket_defined (sd
) && (man
->settings
.client_uid
!= -1 || man
->settings
.client_gid
!= -1))
1344 static const char err_prefix
[] = "MANAGEMENT: unix domain socket client connection rejected --";
1346 if (unix_socket_get_peer_uid_gid (man
->connection
.sd_cli
, &uid
, &gid
))
1348 if (man
->settings
.client_uid
!= -1 && man
->settings
.client_uid
!= uid
)
1350 msg (D_MANAGEMENT
, "%s UID of socket peer (%d) doesn't match required value (%d) as given by --management-client-user",
1351 err_prefix
, uid
, man
->settings
.client_uid
);
1354 if (man
->settings
.client_gid
!= -1 && man
->settings
.client_gid
!= gid
)
1356 msg (D_MANAGEMENT
, "%s GID of socket peer (%d) doesn't match required value (%d) as given by --management-client-group",
1357 err_prefix
, gid
, man
->settings
.client_gid
);
1363 msg (D_MANAGEMENT
, "%s cannot get UID/GID of socket peer", err_prefix
);
1372 man_accept (struct management
*man
)
1374 struct link_socket_actual act
;
1378 * Accept the TCP or Unix domain socket client.
1380 #if UNIX_SOCK_SUPPORT
1381 if (man
->settings
.flags
& MF_UNIX_SOCK
)
1383 struct sockaddr_un remote
;
1384 man
->connection
.sd_cli
= socket_accept_unix (man
->connection
.sd_top
, &remote
);
1385 if (!man_verify_unix_peer_uid_gid (man
, man
->connection
.sd_cli
))
1386 sd_close (&man
->connection
.sd_cli
);
1390 man
->connection
.sd_cli
= socket_do_accept (man
->connection
.sd_top
, &act
, false);
1392 if (socket_defined (man
->connection
.sd_cli
))
1394 man
->connection
.remote
= act
.dest
;
1396 if (socket_defined (man
->connection
.sd_top
))
1399 man_stop_ne32 (man
);
1403 man_new_connection_post (man
, "Client connected from");
1408 man_listen (struct management
*man
)
1410 struct gc_arena gc
= gc_new ();
1415 man
->connection
.state
= MS_LISTEN
;
1416 man
->connection
.sd_cli
= SOCKET_UNDEFINED
;
1419 * Initialize listening socket
1421 if (man
->connection
.sd_top
== SOCKET_UNDEFINED
)
1423 #if UNIX_SOCK_SUPPORT
1424 if (man
->settings
.flags
& MF_UNIX_SOCK
)
1426 man_delete_unix_socket (man
);
1427 man
->connection
.sd_top
= create_socket_unix ();
1428 socket_bind_unix (man
->connection
.sd_top
, &man
->settings
.local_unix
, "MANAGEMENT");
1433 man
->connection
.sd_top
= create_socket_tcp ();
1434 socket_bind (man
->connection
.sd_top
, &man
->settings
.local
, "MANAGEMENT");
1438 * Listen for connection
1440 if (listen (man
->connection
.sd_top
, 1))
1441 msg (M_SOCKERR
, "MANAGEMENT: listen() failed");
1444 * Set misc socket properties
1446 set_nonblock (man
->connection
.sd_top
);
1447 set_cloexec (man
->connection
.sd_top
);
1449 #if UNIX_SOCK_SUPPORT
1450 if (man
->settings
.flags
& MF_UNIX_SOCK
)
1452 msg (D_MANAGEMENT
, "MANAGEMENT: unix domain socket listening on %s",
1453 sockaddr_unix_name (&man
->settings
.local_unix
, "NULL"));
1457 msg (D_MANAGEMENT
, "MANAGEMENT: TCP Socket listening on %s",
1458 print_sockaddr (&man
->settings
.local
, &gc
));
1462 man_start_ne32 (man
);
1469 man_connect (struct management
*man
)
1471 struct gc_arena gc
= gc_new ();
1473 int signal_received
= 0;
1478 man
->connection
.state
= MS_INITIAL
;
1479 man
->connection
.sd_top
= SOCKET_UNDEFINED
;
1481 #if UNIX_SOCK_SUPPORT
1482 if (man
->settings
.flags
& MF_UNIX_SOCK
)
1484 man
->connection
.sd_cli
= create_socket_unix ();
1485 status
= socket_connect_unix (man
->connection
.sd_cli
, &man
->settings
.local_unix
);
1486 if (!status
&& !man_verify_unix_peer_uid_gid (man
, man
->connection
.sd_cli
))
1493 sd_close (&man
->connection
.sd_cli
);
1499 man
->connection
.sd_cli
= create_socket_tcp ();
1500 status
= openvpn_connect (man
->connection
.sd_cli
,
1501 &man
->settings
.local
,
1506 if (signal_received
)
1508 throw_signal (signal_received
);
1514 #if UNIX_SOCK_SUPPORT
1515 if (man
->settings
.flags
& MF_UNIX_SOCK
)
1518 "MANAGEMENT: connect to unix socket %s failed: %s",
1519 sockaddr_unix_name (&man
->settings
.local_unix
, "NULL"),
1520 strerror_ts (status
, &gc
));
1525 "MANAGEMENT: connect to %s failed: %s",
1526 print_sockaddr (&man
->settings
.local
, &gc
),
1527 strerror_ts (status
, &gc
));
1528 throw_signal_soft (SIGTERM
, "management-connect-failed");
1532 man_record_peer_info (man
);
1533 man_new_connection_post (man
, "Connected to management server at");
1540 man_reset_client_socket (struct management
*man
, const bool exiting
)
1542 if (socket_defined (man
->connection
.sd_cli
))
1544 msg (D_MANAGEMENT
, "MANAGEMENT: Client disconnected");
1546 man_stop_ne32 (man
);
1548 man_close_socket (man
, man
->connection
.sd_cli
);
1549 man
->connection
.sd_cli
= SOCKET_UNDEFINED
;
1550 command_line_reset (man
->connection
.in
);
1551 buffer_list_reset (man
->connection
.out
);
1552 #ifdef MANAGEMENT_DEF_AUTH
1553 in_extra_reset (&man
->connection
, false);
1558 #if defined(USE_CRYPTO) && defined(USE_SSL)
1559 if (man
->settings
.flags
& MF_FORGET_DISCONNECT
)
1562 if (man
->settings
.flags
& MF_SIGNAL
) {
1563 int mysig
= man_mod_signal (man
, SIGUSR1
);
1566 msg (D_MANAGEMENT
, "MANAGEMENT: Triggering management signal");
1567 throw_signal_soft (mysig
, "management-disconnect");
1571 if (man
->settings
.flags
& MF_CONNECT_AS_CLIENT
)
1573 msg (D_MANAGEMENT
, "MANAGEMENT: Triggering management exit");
1574 throw_signal_soft (SIGTERM
, "management-exit");
1582 man_process_command (struct management
*man
, const char *line
)
1584 struct gc_arena gc
= gc_new ();
1585 struct status_output
*so
;
1587 char *parms
[MAX_PARMS
+1];
1590 so
= status_open (NULL
, 0, -1, &man
->persist
.vout
, 0);
1591 #ifdef MANAGEMENT_DEF_AUTH
1592 in_extra_reset (&man
->connection
, false);
1595 if (man_password_needed (man
))
1597 man_check_password (man
, line
);
1601 nparms
= parse_line (line
, parms
, MAX_PARMS
, "TCP", 0, M_CLIENT
, &gc
);
1602 if (parms
[0] && streq (parms
[0], "password"))
1603 msg (D_MANAGEMENT_DEBUG
, "MANAGEMENT: CMD 'password [...]'");
1604 else if (!streq (line
, "load-stats"))
1605 msg (D_MANAGEMENT_DEBUG
, "MANAGEMENT: CMD '%s'", line
);
1608 /* DEBUGGING -- print args */
1611 for (i
= 0; i
< nparms
; ++i
)
1612 msg (M_INFO
, "[%d] '%s'", i
, parms
[i
]);
1617 man_dispatch_command (man
, so
, (const char **)parms
, nparms
);
1626 man_io_error (struct management
*man
, const char *prefix
)
1628 const int err
= openvpn_errno_socket ();
1630 if (!ignore_sys_error (err
))
1632 struct gc_arena gc
= gc_new ();
1633 msg (D_MANAGEMENT
, "MANAGEMENT: TCP %s error: %s",
1635 strerror_ts (err
, &gc
));
1644 man_read (struct management
*man
)
1647 * read command line from socket
1649 unsigned char buf
[256];
1652 len
= recv (man
->connection
.sd_cli
, buf
, sizeof (buf
), MSG_NOSIGNAL
);
1655 man_reset_client_socket (man
, false);
1659 bool processed_command
= false;
1661 ASSERT (len
<= (int) sizeof (buf
));
1662 command_line_add (man
->connection
.in
, buf
, len
);
1665 * Reset output object
1667 buffer_list_reset (man
->connection
.out
);
1670 * process command line if complete
1673 const unsigned char *line
;
1674 while ((line
= command_line_get (man
->connection
.in
)))
1676 #ifdef MANAGEMENT_DEF_AUTH
1677 if (man
->connection
.in_extra
)
1679 if (!strcmp ((char *)line
, "END"))
1681 in_extra_dispatch (man
);
1682 in_extra_reset (&man
->connection
, false);
1686 buffer_list_push (man
->connection
.in_extra
, line
);
1691 man_process_command (man
, (char *) line
);
1692 if (man
->connection
.halt
)
1694 command_line_next (man
->connection
.in
);
1695 processed_command
= true;
1700 * Reset output state to MS_CC_WAIT_(READ|WRITE)
1702 if (man
->connection
.halt
)
1704 man_reset_client_socket (man
, false);
1709 if (processed_command
)
1711 man_update_io_state (man
);
1716 if (man_io_error (man
, "recv"))
1717 man_reset_client_socket (man
, false);
1723 man_write (struct management
*man
)
1725 const int max_send
= 256;
1728 const struct buffer
*buf
= buffer_list_peek (man
->connection
.out
);
1729 if (buf
&& BLEN (buf
))
1731 const int len
= min_int (max_send
, BLEN (buf
));
1732 sent
= send (man
->connection
.sd_cli
, BPTR (buf
), len
, MSG_NOSIGNAL
);
1735 buffer_list_advance (man
->connection
.out
, sent
);
1739 if (man_io_error (man
, "send"))
1740 man_reset_client_socket (man
, false);
1745 * Reset output state to MS_CC_WAIT_(READ|WRITE)
1747 man_update_io_state (man
);
1753 man_connection_clear (struct man_connection
*mc
)
1757 /* set initial state */
1758 mc
->state
= MS_INITIAL
;
1760 /* clear socket descriptors */
1761 mc
->sd_top
= SOCKET_UNDEFINED
;
1762 mc
->sd_cli
= SOCKET_UNDEFINED
;
1766 man_persist_init (struct management
*man
,
1767 const int log_history_cache
,
1768 const int echo_buffer_size
,
1769 const int state_buffer_size
)
1771 struct man_persist
*mp
= &man
->persist
;
1776 /* initialize log history store */
1777 mp
->log
= log_history_init (log_history_cache
);
1780 * Initialize virtual output object, so that functions
1781 * which write to a virtual_output object can be redirected
1782 * here to the management object.
1784 mp
->vout
.func
= virtual_output_callback_func
;
1786 mp
->vout
.flags_default
= M_CLIENT
;
1787 msg_set_virtual_output (&mp
->vout
);
1790 * Initialize --echo list
1792 man
->persist
.echo
= log_history_init (echo_buffer_size
);
1795 * Initialize --state list
1797 man
->persist
.state
= log_history_init (state_buffer_size
);
1804 man_persist_close (struct man_persist
*mp
)
1808 msg_set_virtual_output (NULL
);
1809 log_history_close (mp
->log
);
1813 log_history_close (mp
->echo
);
1816 log_history_close (mp
->state
);
1822 man_settings_init (struct man_settings
*ms
,
1825 const char *pass_file
,
1826 const char *client_user
,
1827 const char *client_group
,
1828 const int log_history_cache
,
1829 const int echo_buffer_size
,
1830 const int state_buffer_size
,
1831 const char *write_peer_info_file
,
1832 const int remap_sigusr1
,
1833 const unsigned int flags
)
1840 ms
->client_uid
= -1;
1841 ms
->client_gid
= -1;
1844 * Get username/password
1847 get_user_pass (&ms
->up
, pass_file
, "Management", GET_USER_PASS_PASSWORD_ONLY
);
1850 * lookup client UID/GID if specified
1854 struct user_state s
;
1855 get_user (client_user
, &s
);
1856 ms
->client_uid
= user_state_uid (&s
);
1857 msg (D_MANAGEMENT
, "MANAGEMENT: client_uid=%d", ms
->client_uid
);
1858 ASSERT (ms
->client_uid
>= 0);
1862 struct group_state s
;
1863 get_group (client_group
, &s
);
1864 ms
->client_gid
= group_state_gid (&s
);
1865 msg (D_MANAGEMENT
, "MANAGEMENT: client_gid=%d", ms
->client_gid
);
1866 ASSERT (ms
->client_gid
>= 0);
1869 ms
->write_peer_info_file
= string_alloc (write_peer_info_file
, NULL
);
1871 #if UNIX_SOCK_SUPPORT
1872 if (ms
->flags
& MF_UNIX_SOCK
)
1873 sockaddr_unix_init (&ms
->local_unix
, addr
);
1878 * Initialize socket address
1880 ms
->local
.sa
.sin_family
= AF_INET
;
1881 ms
->local
.sa
.sin_addr
.s_addr
= 0;
1882 ms
->local
.sa
.sin_port
= htons (port
);
1885 * Run management over tunnel, or
1888 if (streq (addr
, "tunnel") && !(flags
& MF_CONNECT_AS_CLIENT
))
1890 ms
->management_over_tunnel
= true;
1894 ms
->local
.sa
.sin_addr
.s_addr
= getaddr
1895 (GETADDR_RESOLVE
|GETADDR_WARN_ON_SIGNAL
|GETADDR_FATAL
, addr
, 0, NULL
, NULL
);
1900 * Log history and echo buffer may need to be resized
1902 ms
->log_history_cache
= log_history_cache
;
1903 ms
->echo_buffer_size
= echo_buffer_size
;
1904 ms
->state_buffer_size
= state_buffer_size
;
1907 * Set remap sigusr1 flags
1909 if (remap_sigusr1
== SIGHUP
)
1910 ms
->mansig
|= MANSIG_MAP_USR1_TO_HUP
;
1911 else if (remap_sigusr1
== SIGTERM
)
1912 ms
->mansig
|= MANSIG_MAP_USR1_TO_TERM
;
1919 man_settings_close (struct man_settings
*ms
)
1921 free (ms
->write_peer_info_file
);
1927 man_connection_init (struct management
*man
)
1929 if (man
->connection
.state
== MS_INITIAL
)
1933 * This object is a sort of TCP/IP helper
1936 net_event_win32_init (&man
->connection
.ne32
);
1940 * Allocate helper objects for command line input and
1941 * command output from/to the socket.
1943 man
->connection
.in
= command_line_new (1024);
1944 man
->connection
.out
= buffer_list_new (0);
1947 * Initialize event set for standalone usage, when we are
1948 * running outside of the primary event loop.
1952 man
->connection
.es
= event_set_init (&maxevents
, EVENT_METHOD_FAST
);
1956 * Listen/connect socket
1958 if (man
->settings
.flags
& MF_CONNECT_AS_CLIENT
)
1966 man_connection_close (struct management
*man
)
1968 struct man_connection
*mc
= &man
->connection
;
1971 event_free (mc
->es
);
1973 net_event_win32_close (&mc
->ne32
);
1975 if (socket_defined (mc
->sd_top
))
1977 man_close_socket (man
, mc
->sd_top
);
1978 man_delete_unix_socket (man
);
1980 if (socket_defined (mc
->sd_cli
))
1981 man_close_socket (man
, mc
->sd_cli
);
1983 command_line_free (mc
->in
);
1985 buffer_list_free (mc
->out
);
1986 #ifdef MANAGEMENT_DEF_AUTH
1987 in_extra_reset (&man
->connection
, false);
1989 man_connection_clear (mc
);
1993 management_init (void)
1995 struct management
*man
;
1996 ALLOC_OBJ_CLEAR (man
, struct management
);
1998 man_persist_init (man
,
1999 MANAGEMENT_LOG_HISTORY_INITIAL_SIZE
,
2000 MANAGEMENT_ECHO_BUFFER_SIZE
,
2001 MANAGEMENT_STATE_BUFFER_SIZE
);
2003 man_connection_clear (&man
->connection
);
2009 management_open (struct management
*man
,
2012 const char *pass_file
,
2013 const char *client_user
,
2014 const char *client_group
,
2015 const int log_history_cache
,
2016 const int echo_buffer_size
,
2017 const int state_buffer_size
,
2018 const char *write_peer_info_file
,
2019 const int remap_sigusr1
,
2020 const unsigned int flags
)
2025 * Save the settings only if they have not
2026 * been saved before.
2028 man_settings_init (&man
->settings
,
2037 write_peer_info_file
,
2042 * The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
2043 * but may be changed here. Ditto for echo and state buffers.
2045 log_history_resize (man
->persist
.log
, man
->settings
.log_history_cache
);
2046 log_history_resize (man
->persist
.echo
, man
->settings
.echo_buffer_size
);
2047 log_history_resize (man
->persist
.state
, man
->settings
.state_buffer_size
);
2050 * If connection object is uninitialized and we are not doing
2051 * over-the-tunnel management, then open (listening) connection.
2053 if (man
->connection
.state
== MS_INITIAL
)
2055 if (!man
->settings
.management_over_tunnel
)
2057 man_connection_init (man
);
2066 management_close (struct management
*man
)
2068 man_connection_close (man
);
2069 man_settings_close (&man
->settings
);
2070 man_persist_close (&man
->persist
);
2075 management_set_callback (struct management
*man
,
2076 const struct management_callback
*cb
)
2078 man
->persist
.standalone_disabled
= true;
2079 man
->persist
.callback
= *cb
;
2083 management_clear_callback (struct management
*man
)
2085 man
->persist
.standalone_disabled
= false;
2086 man
->persist
.hold_release
= false;
2087 CLEAR (man
->persist
.callback
);
2088 man_output_list_push (man
, NULL
); /* flush output queue */
2092 management_set_state (struct management
*man
,
2095 const in_addr_t tun_local_ip
,
2096 const in_addr_t tun_remote_ip
)
2098 if (man
->persist
.state
&& (!(man
->settings
.flags
& MF_SERVER
) || state
< OPENVPN_STATE_CLIENT_BASE
))
2100 struct gc_arena gc
= gc_new ();
2102 const char *out
= NULL
;
2109 e
.local_ip
= tun_local_ip
;
2110 e
.remote_ip
= tun_remote_ip
;
2112 log_history_add (man
->persist
.state
, &e
);
2114 if (man
->connection
.state_realtime
)
2115 out
= log_entry_print (&e
, LOG_PRINT_STATE_PREFIX
2116 | LOG_PRINT_INT_DATE
2118 | LOG_PRINT_LOCAL_IP
2119 | LOG_PRINT_REMOTE_IP
2121 | LOG_ECHO_TO_LOG
, &gc
);
2124 man_output_list_push (man
, out
);
2130 #ifdef MANAGEMENT_DEF_AUTH
2133 man_output_env (const struct env_set
*es
, const bool tail
)
2138 for (e
= es
->list
; e
!= NULL
; e
= e
->next
)
2141 msg (M_CLIENT
, ">CLIENT:ENV,%s", e
->string
);
2145 msg (M_CLIENT
, ">CLIENT:ENV,END");
2149 man_output_extra_env (struct management
*man
)
2151 struct gc_arena gc
= gc_new ();
2152 struct env_set
*es
= env_set_create (&gc
);
2153 if (man
->persist
.callback
.n_clients
)
2155 const int nclients
= (*man
->persist
.callback
.n_clients
) (man
->persist
.callback
.arg
);
2156 setenv_int (es
, "n_clients", nclients
);
2158 man_output_env (es
, false);
2163 management_notify_client_needing_auth (struct management
*management
,
2164 const unsigned int mda_key_id
,
2165 struct man_def_auth_context
*mdac
,
2166 const struct env_set
*es
)
2168 if (!(mdac
->flags
& DAF_CONNECTION_CLOSED
))
2170 const char *mode
= "CONNECT";
2171 if (mdac
->flags
& DAF_CONNECTION_ESTABLISHED
)
2173 msg (M_CLIENT
, ">CLIENT:%s,%lu,%u", mode
, mdac
->cid
, mda_key_id
);
2174 man_output_extra_env (management
);
2175 man_output_env (es
, true);
2176 mdac
->flags
|= DAF_INITIAL_AUTH
;
2181 management_connection_established (struct management
*management
,
2182 struct man_def_auth_context
*mdac
,
2183 const struct env_set
*es
)
2185 mdac
->flags
|= DAF_CONNECTION_ESTABLISHED
;
2186 msg (M_CLIENT
, ">CLIENT:ESTABLISHED,%lu", mdac
->cid
);
2187 man_output_extra_env (management
);
2188 man_output_env (es
, true);
2192 management_notify_client_close (struct management
*management
,
2193 struct man_def_auth_context
*mdac
,
2194 const struct env_set
*es
)
2196 if ((mdac
->flags
& DAF_INITIAL_AUTH
) && !(mdac
->flags
& DAF_CONNECTION_CLOSED
))
2198 msg (M_CLIENT
, ">CLIENT:DISCONNECT,%lu", mdac
->cid
);
2199 man_output_env (es
, true);
2200 mdac
->flags
|= DAF_CONNECTION_CLOSED
;
2205 management_learn_addr (struct management
*management
,
2206 struct man_def_auth_context
*mdac
,
2207 const struct mroute_addr
*addr
,
2210 struct gc_arena gc
= gc_new ();
2211 if ((mdac
->flags
& DAF_INITIAL_AUTH
) && !(mdac
->flags
& DAF_CONNECTION_CLOSED
))
2213 msg (M_CLIENT
, ">CLIENT:ADDRESS,%lu,%s,%d",
2215 mroute_addr_print_ex (addr
, MAPF_SUBNET
, &gc
),
2216 BOOL_CAST (primary
));
2224 management_echo (struct management
*man
, const char *string
, const bool pull
)
2226 if (man
->persist
.echo
)
2228 struct gc_arena gc
= gc_new ();
2230 const char *out
= NULL
;
2236 e
.u
.intval
= BOOL_CAST (pull
);
2238 log_history_add (man
->persist
.echo
, &e
);
2240 if (man
->connection
.echo_realtime
)
2241 out
= log_entry_print (&e
, LOG_PRINT_INT_DATE
|LOG_PRINT_ECHO_PREFIX
|LOG_PRINT_CRLF
|MANAGEMENT_ECHO_FLAGS
, &gc
);
2244 man_output_list_push (man
, out
);
2251 management_post_tunnel_open (struct management
*man
, const in_addr_t tun_local_ip
)
2254 * If we are running management over the tunnel,
2255 * this is the place to initialize the connection.
2257 if (man
->settings
.management_over_tunnel
2258 && man
->connection
.state
== MS_INITIAL
)
2260 /* listen on our local TUN/TAP IP address */
2261 man
->settings
.local
.sa
.sin_addr
.s_addr
= htonl (tun_local_ip
);
2262 man_connection_init (man
);
2268 management_pre_tunnel_close (struct management
*man
)
2270 if (man
->settings
.management_over_tunnel
)
2271 man_connection_close (man
);
2275 management_auth_failure (struct management
*man
, const char *type
)
2277 msg (M_CLIENT
, ">PASSWORD:Verification Failed: '%s'", type
);
2281 man_persist_state (unsigned int *persistent
, const int n
)
2285 if (*persistent
== (unsigned int)n
)
2295 management_socket_set (struct management
*man
,
2296 struct event_set
*es
,
2298 unsigned int *persistent
)
2300 if (man
->connection
.state
!= MS_INITIAL
)
2302 event_t ev
= net_event_win32_get_event (&man
->connection
.ne32
);
2303 net_event_win32_reset_write (&man
->connection
.ne32
);
2305 switch (man
->connection
.state
)
2308 if (man_persist_state (persistent
, 1))
2309 event_ctl (es
, ev
, EVENT_READ
, arg
);
2311 case MS_CC_WAIT_READ
:
2312 if (man_persist_state (persistent
, 2))
2313 event_ctl (es
, ev
, EVENT_READ
, arg
);
2315 case MS_CC_WAIT_WRITE
:
2316 if (man_persist_state (persistent
, 3))
2317 event_ctl (es
, ev
, EVENT_READ
|EVENT_WRITE
, arg
);
2326 management_io (struct management
*man
)
2328 if (man
->connection
.state
!= MS_INITIAL
)
2331 net_event_win32_reset (&man
->connection
.ne32
);
2332 net_events
= net_event_win32_get_event_mask (&man
->connection
.ne32
);
2334 if (net_events
& FD_CLOSE
)
2336 man_reset_client_socket (man
, false);
2340 if (man
->connection
.state
== MS_LISTEN
)
2342 if (net_events
& FD_ACCEPT
)
2345 net_event_win32_clear_selected_events (&man
->connection
.ne32
, FD_ACCEPT
);
2348 else if (man
->connection
.state
== MS_CC_WAIT_READ
)
2350 if (net_events
& FD_READ
)
2352 while (man_read (man
) > 0)
2354 net_event_win32_clear_selected_events (&man
->connection
.ne32
, FD_READ
);
2358 if (man
->connection
.state
== MS_CC_WAIT_WRITE
)
2360 if (net_events
& FD_WRITE
)
2363 /* dmsg (M_INFO, "FD_WRITE set"); */
2364 status
= man_write (man
);
2365 if (status
< 0 && WSAGetLastError() == WSAEWOULDBLOCK
)
2367 /* dmsg (M_INFO, "FD_WRITE cleared"); */
2368 net_event_win32_clear_selected_events (&man
->connection
.ne32
, FD_WRITE
);
2379 management_socket_set (struct management
*man
,
2380 struct event_set
*es
,
2382 unsigned int *persistent
)
2384 switch (man
->connection
.state
)
2387 if (man_persist_state (persistent
, 1))
2388 event_ctl (es
, man
->connection
.sd_top
, EVENT_READ
, arg
);
2390 case MS_CC_WAIT_READ
:
2391 if (man_persist_state (persistent
, 2))
2392 event_ctl (es
, man
->connection
.sd_cli
, EVENT_READ
, arg
);
2394 case MS_CC_WAIT_WRITE
:
2395 if (man_persist_state (persistent
, 3))
2396 event_ctl (es
, man
->connection
.sd_cli
, EVENT_WRITE
, arg
);
2406 management_io (struct management
*man
)
2408 switch (man
->connection
.state
)
2413 case MS_CC_WAIT_READ
:
2416 case MS_CC_WAIT_WRITE
:
2429 man_standalone_ok (const struct management
*man
)
2431 return !man
->settings
.management_over_tunnel
&& man
->connection
.state
!= MS_INITIAL
;
2435 man_check_for_signals (volatile int *signal_received
)
2437 if (signal_received
)
2439 get_signal (signal_received
);
2440 if (*signal_received
)
2447 * Wait for socket I/O when outside primary event loop
2450 man_block (struct management
*man
, volatile int *signal_received
, const time_t expire
)
2453 struct event_set_return esr
;
2456 if (man_standalone_ok (man
))
2460 event_reset (man
->connection
.es
);
2461 management_socket_set (man
, man
->connection
.es
, NULL
, NULL
);
2464 if (man_check_for_signals (signal_received
))
2469 status
= event_wait (man
->connection
.es
, &tv
, &esr
, 1);
2471 if (man_check_for_signals (signal_received
))
2476 /* set SIGINT signal if expiration time exceeded */
2477 if (expire
&& now
>= expire
)
2480 if (signal_received
)
2481 *signal_received
= SIGINT
;
2484 } while (status
!= 1);
2490 * Perform management socket output outside primary event loop
2493 man_output_standalone (struct management
*man
, volatile int *signal_received
)
2495 if (man_standalone_ok (man
))
2497 while (man
->connection
.state
== MS_CC_WAIT_WRITE
)
2499 management_io (man
);
2500 if (man
->connection
.state
== MS_CC_WAIT_WRITE
)
2501 man_block (man
, signal_received
, 0);
2502 if (signal_received
&& *signal_received
)
2509 * Process management event loop outside primary event loop
2512 man_standalone_event_loop (struct management
*man
, volatile int *signal_received
, const time_t expire
)
2515 ASSERT (man_standalone_ok (man
));
2516 status
= man_block (man
, signal_received
, expire
);
2518 management_io (man
);
2522 #define MWCC_PASSWORD_WAIT (1<<0)
2523 #define MWCC_HOLD_WAIT (1<<1)
2526 * Block until client connects
2529 man_wait_for_client_connection (struct management
*man
,
2530 volatile int *signal_received
,
2531 const time_t expire
,
2534 ASSERT (man_standalone_ok (man
));
2535 if (man
->connection
.state
== MS_LISTEN
)
2537 if (flags
& MWCC_PASSWORD_WAIT
)
2538 msg (D_MANAGEMENT
, "Need password(s) from management interface, waiting...");
2539 if (flags
& MWCC_HOLD_WAIT
)
2540 msg (D_MANAGEMENT
, "Need hold release from management interface, waiting...");
2542 man_standalone_event_loop (man
, signal_received
, expire
);
2543 if (signal_received
&& *signal_received
)
2545 } while (man
->connection
.state
== MS_LISTEN
|| man_password_needed (man
));
2550 * Process the management event loop for sec seconds
2553 management_event_loop_n_seconds (struct management
*man
, int sec
)
2555 if (man_standalone_ok (man
))
2557 volatile int signal_received
= 0;
2558 const bool standalone_disabled_save
= man
->persist
.standalone_disabled
;
2561 man
->persist
.standalone_disabled
= false; /* This is so M_CLIENT messages will be correctly passed through msg() */
2563 /* set expire time */
2567 /* if no client connection, wait for one */
2568 man_wait_for_client_connection (man
, &signal_received
, expire
, 0);
2569 if (signal_received
)
2572 /* run command processing event loop until we get our username/password */
2575 man_standalone_event_loop (man
, &signal_received
, expire
);
2576 if (signal_received
)
2581 man
->persist
.standalone_disabled
= standalone_disabled_save
;
2590 * Get a username/password from management channel in standalone mode.
2593 management_query_user_pass (struct management
*man
,
2594 struct user_pass
*up
,
2596 const unsigned int flags
)
2598 struct gc_arena gc
= gc_new ();
2601 if (man_standalone_ok (man
))
2603 volatile int signal_received
= 0;
2604 const bool standalone_disabled_save
= man
->persist
.standalone_disabled
;
2605 struct buffer alert_msg
= alloc_buf_gc (128, &gc
);
2606 const char *alert_type
= NULL
;
2607 const char *prefix
= NULL
;
2608 unsigned int up_query_mode
= 0;
2611 man
->persist
.standalone_disabled
= false; /* This is so M_CLIENT messages will be correctly passed through msg() */
2612 man
->persist
.special_state_msg
= NULL
;
2614 CLEAR (man
->connection
.up_query
);
2616 if (flags
& GET_USER_PASS_NEED_OK
)
2618 up_query_mode
= UP_QUERY_NEED_OK
;
2620 alert_type
= "confirmation";
2622 else if (flags
& GET_USER_PASS_NEED_STR
)
2624 up_query_mode
= UP_QUERY_NEED_STR
;
2626 alert_type
= "string";
2628 else if (flags
& GET_USER_PASS_PASSWORD_ONLY
)
2630 up_query_mode
= UP_QUERY_PASS
;
2631 prefix
= "PASSWORD";
2632 alert_type
= "password";
2636 up_query_mode
= UP_QUERY_USER_PASS
;
2637 prefix
= "PASSWORD";
2638 alert_type
= "username/password";
2640 buf_printf (&alert_msg
, ">%s:Need '%s' %s",
2645 if (flags
& (GET_USER_PASS_NEED_OK
| GET_USER_PASS_NEED_STR
))
2646 buf_printf (&alert_msg
, " MSG:%s", up
->username
);
2648 man_wait_for_client_connection (man
, &signal_received
, 0, MWCC_PASSWORD_WAIT
);
2649 if (signal_received
)
2654 man
->persist
.special_state_msg
= BSTR (&alert_msg
);
2655 msg (M_CLIENT
, "%s", man
->persist
.special_state_msg
);
2657 /* tell command line parser which info we need */
2658 man
->connection
.up_query_mode
= up_query_mode
;
2659 man
->connection
.up_query_type
= type
;
2661 /* run command processing event loop until we get our username/password */
2664 man_standalone_event_loop (man
, &signal_received
, 0);
2665 if (signal_received
)
2670 } while (!man
->connection
.up_query
.defined
);
2674 man
->connection
.up_query_mode
= UP_QUERY_DISABLED
;
2675 man
->connection
.up_query_type
= NULL
;
2676 man
->persist
.standalone_disabled
= standalone_disabled_save
;
2677 man
->persist
.special_state_msg
= NULL
;
2679 /* pass through blank passwords */
2680 if (!strcmp (man
->connection
.up_query
.password
, blank_up
))
2681 CLEAR (man
->connection
.up_query
.password
);
2684 * Transfer u/p to return object, zero any record
2685 * we hold in the management object.
2689 man
->connection
.up_query
.nocache
= up
->nocache
; /* preserve caller's nocache setting */
2690 *up
= man
->connection
.up_query
;
2692 CLEAR (man
->connection
.up_query
);
2700 * Return true if management_hold() would block
2703 management_would_hold (struct management
*man
)
2705 return (man
->settings
.flags
& MF_HOLD
) && !man
->persist
.hold_release
&& man_standalone_ok (man
);
2709 * Return true if (from the management interface's perspective) OpenVPN should
2713 management_should_daemonize (struct management
*man
)
2715 return management_would_hold (man
) || (man
->settings
.flags
& MF_QUERY_PASSWORDS
);
2719 * If the hold flag is enabled, hibernate until a management client releases the hold.
2720 * Return true if the caller should not sleep for an additional time interval.
2723 management_hold (struct management
*man
)
2725 if (management_would_hold (man
))
2727 volatile int signal_received
= 0;
2728 const bool standalone_disabled_save
= man
->persist
.standalone_disabled
;
2730 man
->persist
.standalone_disabled
= false; /* This is so M_CLIENT messages will be correctly passed through msg() */
2731 man
->persist
.special_state_msg
= NULL
;
2732 man
->settings
.mansig
|= MANSIG_IGNORE_USR1_HUP
;
2734 man_wait_for_client_connection (man
, &signal_received
, 0, MWCC_HOLD_WAIT
);
2736 if (!signal_received
)
2738 man
->persist
.special_state_msg
= ">HOLD:Waiting for hold release";
2739 msg (M_CLIENT
, "%s", man
->persist
.special_state_msg
);
2741 /* run command processing event loop until we get our username/password */
2744 man_standalone_event_loop (man
, &signal_received
, 0);
2745 if (signal_received
)
2747 } while (!man
->persist
.hold_release
);
2751 man
->persist
.standalone_disabled
= standalone_disabled_save
;
2752 man
->persist
.special_state_msg
= NULL
;
2753 man
->settings
.mansig
&= ~MANSIG_IGNORE_USR1_HUP
;
2761 * struct command_line
2764 struct command_line
*
2765 command_line_new (const int buf_len
)
2767 struct command_line
*cl
;
2768 ALLOC_OBJ_CLEAR (cl
, struct command_line
);
2769 cl
->buf
= alloc_buf (buf_len
);
2770 cl
->residual
= alloc_buf (buf_len
);
2775 command_line_reset (struct command_line
*cl
)
2777 buf_clear (&cl
->buf
);
2778 buf_clear (&cl
->residual
);
2782 command_line_free (struct command_line
*cl
)
2784 command_line_reset (cl
);
2785 free_buf (&cl
->buf
);
2786 free_buf (&cl
->residual
);
2791 command_line_add (struct command_line
*cl
, const unsigned char *buf
, const int len
)
2794 for (i
= 0; i
< len
; ++i
)
2796 if (buf
[i
] && (isprint(buf
[i
]) || buf
[i
] == '\n'))
2798 if (!buf_write_u8 (&cl
->buf
, buf
[i
]))
2799 buf_clear (&cl
->buf
);
2804 const unsigned char *
2805 command_line_get (struct command_line
*cl
)
2808 const unsigned char *ret
= NULL
;
2810 i
= buf_substring_len (&cl
->buf
, '\n');
2813 buf_copy_excess (&cl
->residual
, &cl
->buf
, i
);
2814 buf_chomp (&cl
->buf
);
2815 ret
= (const unsigned char *) BSTR (&cl
->buf
);
2821 command_line_next (struct command_line
*cl
)
2823 buf_clear (&cl
->buf
);
2824 buf_copy (&cl
->buf
, &cl
->residual
);
2825 buf_clear (&cl
->residual
);
2833 log_entry_print (const struct log_entry
*e
, unsigned int flags
, struct gc_arena
*gc
)
2835 struct buffer out
= alloc_buf_gc (ERR_BUF_SIZE
, gc
);
2836 if (flags
& LOG_FATAL_NOTIFY
)
2837 buf_printf (&out
, ">FATAL:");
2838 if (flags
& LOG_PRINT_LOG_PREFIX
)
2839 buf_printf (&out
, ">LOG:");
2840 if (flags
& LOG_PRINT_ECHO_PREFIX
)
2841 buf_printf (&out
, ">ECHO:");
2842 if (flags
& LOG_PRINT_STATE_PREFIX
)
2843 buf_printf (&out
, ">STATE:");
2844 if (flags
& LOG_PRINT_INT_DATE
)
2845 buf_printf (&out
, "%u,", (unsigned int)e
->timestamp
);
2846 if (flags
& LOG_PRINT_MSG_FLAGS
)
2847 buf_printf (&out
, "%s,", msg_flags_string (e
->u
.msg_flags
, gc
));
2848 if (flags
& LOG_PRINT_STATE
)
2849 buf_printf (&out
, "%s,", man_state_name (e
->u
.state
));
2850 if (flags
& LOG_PRINT_INTVAL
)
2851 buf_printf (&out
, "%d,", e
->u
.intval
);
2853 buf_printf (&out
, "%s", e
->string
);
2854 if (flags
& LOG_PRINT_LOCAL_IP
)
2855 buf_printf (&out
, ",%s", print_in_addr_t (e
->local_ip
, IA_EMPTY_IF_UNDEF
, gc
));
2856 if (flags
& LOG_PRINT_REMOTE_IP
)
2857 buf_printf (&out
, ",%s", print_in_addr_t (e
->remote_ip
, IA_EMPTY_IF_UNDEF
, gc
));
2858 if (flags
& LOG_ECHO_TO_LOG
)
2859 msg (D_MANAGEMENT
, "MANAGEMENT: %s", BSTR (&out
));
2860 if (flags
& LOG_PRINT_CRLF
)
2861 buf_printf (&out
, "\r\n");
2866 log_entry_free_contents (struct log_entry
*e
)
2869 free ((char *)e
->string
);
2874 * struct log_history
2878 log_index (const struct log_history
*h
, int i
)
2880 return modulo_add (h
->base
, i
, h
->capacity
);
2884 log_history_obj_init (struct log_history
*h
, int capacity
)
2887 h
->capacity
= capacity
;
2888 ALLOC_ARRAY_CLEAR (h
->array
, struct log_entry
, capacity
);
2891 struct log_history
*
2892 log_history_init (const int capacity
)
2894 struct log_history
*h
;
2895 ASSERT (capacity
> 0);
2896 ALLOC_OBJ (h
, struct log_history
);
2897 log_history_obj_init (h
, capacity
);
2902 log_history_free_contents (struct log_history
*h
)
2905 for (i
= 0; i
< h
->size
; ++i
)
2906 log_entry_free_contents (&h
->array
[log_index(h
, i
)]);
2911 log_history_close (struct log_history
*h
)
2913 log_history_free_contents (h
);
2918 log_history_add (struct log_history
*h
, const struct log_entry
*le
)
2920 struct log_entry
*e
;
2921 ASSERT (h
->size
>= 0 && h
->size
<= h
->capacity
);
2922 if (h
->size
== h
->capacity
)
2924 e
= &h
->array
[h
->base
];
2925 log_entry_free_contents (e
);
2926 h
->base
= log_index (h
, 1);
2930 e
= &h
->array
[log_index(h
, h
->size
)];
2935 e
->string
= string_alloc (le
->string
, NULL
);
2939 log_history_resize (struct log_history
*h
, const int capacity
)
2941 if (capacity
!= h
->capacity
)
2943 struct log_history newlog
;
2946 ASSERT (capacity
> 0);
2947 log_history_obj_init (&newlog
, capacity
);
2949 for (i
= 0; i
< h
->size
; ++i
)
2950 log_history_add (&newlog
, &h
->array
[log_index(h
, i
)]);
2952 log_history_free_contents (h
);
2957 const struct log_entry
*
2958 log_history_ref (const struct log_history
*h
, const int index
)
2960 if (index
>= 0 && index
< h
->size
)
2961 return &h
->array
[log_index(h
, (h
->size
- 1) - index
)];
2967 static void dummy(void) {}
2968 #endif /* ENABLE_MANAGEMENT */