OpenVPN
manage.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2025 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#ifdef ENABLE_MANAGEMENT
30
31#include "error.h"
32#include "fdmisc.h"
33#include "options.h"
34#include "sig.h"
35#include "event.h"
36#include "otime.h"
37#include "integer.h"
38#include "misc.h"
39#include "ssl.h"
40#include "common.h"
41#include "manage.h"
42#include "openvpn.h"
43#include "dco.h"
44#include "push.h"
45#include "multi.h"
46
47#include "memdbg.h"
48
49#ifdef ENABLE_PKCS11
50#include "pkcs11.h"
51#endif
52
53#define MANAGEMENT_ECHO_PULL_INFO 0
54
55#if MANAGEMENT_ECHO_PULL_INFO
56#define MANAGEMENT_ECHO_FLAGS LOG_PRINT_INTVAL
57#else
58#define MANAGEMENT_ECHO_FLAGS 0
59#endif
60
61/* tag for blank username/password */
62static const char blank_up[] = "[[BLANK]]";
63
64struct management *management; /* GLOBAL */
65
66/* static forward declarations */
67static void man_output_standalone(struct management *man, volatile int *signal_received);
68
69static void man_reset_client_socket(struct management *man, const bool exiting);
70
71static void
73{
74 msg(M_CLIENT, "Management Interface for %s", title_string);
75 msg(M_CLIENT, "Commands:");
76 msg(M_CLIENT, "auth-retry t : Auth failure retry mode (none,interact,nointeract).");
77 msg(M_CLIENT, "bytecount n : Show bytes in/out, update every n secs (0=off).");
78 msg(M_CLIENT, "echo [on|off] [N|all] : Like log, but only show messages in echo buffer.");
80 "cr-response response : Send a challenge response answer via CR_RESPONSE to server");
81 msg(M_CLIENT, "exit|quit : Close management session.");
82 msg(M_CLIENT, "forget-passwords : Forget passwords entered so far.");
83 msg(M_CLIENT, "help : Print this message.");
84 msg(M_CLIENT, "hold [on|off|release] : Set/show hold flag to on/off state, or");
85 msg(M_CLIENT, " release current hold and start tunnel.");
86 msg(M_CLIENT, "kill cn : Kill the client instance(s) having common name cn.");
87 msg(M_CLIENT, "kill IP:port : Kill the client instance connecting from IP:port.");
88 msg(M_CLIENT, "load-stats : Show global server load stats.");
89 msg(M_CLIENT, "log [on|off] [N|all] : Turn on/off realtime log display");
90 msg(M_CLIENT, " + show last N lines or 'all' for entire history.");
92 "mute [n] : Set log mute level to n, or show level if n is absent.");
93 msg(M_CLIENT, "needok type action : Enter confirmation for NEED-OK request of 'type',");
94 msg(M_CLIENT, " where action = 'ok' or 'cancel'.");
95 msg(M_CLIENT, "needstr type action : Enter confirmation for NEED-STR request of 'type',");
96 msg(M_CLIENT, " where action is reply string.");
97 msg(M_CLIENT, "net : (Windows only) Show network info and routing table.");
98 msg(M_CLIENT, "password type p : Enter password p for a queried OpenVPN password.");
99 msg(M_CLIENT, "remote type [host port] : Override remote directive, type=ACCEPT|MOD|SKIP.");
100 msg(M_CLIENT, "remote-entry-count : Get number of available remote entries.");
101 msg(M_CLIENT, "remote-entry-get i|all [j]: Get remote entry at index = i to to j-1 or all.");
102 msg(M_CLIENT, "proxy type [host port flags] : Enter dynamic proxy server info.");
103 msg(M_CLIENT, "pid : Show process ID of the current OpenVPN process.");
104#ifdef ENABLE_PKCS11
105 msg(M_CLIENT, "pkcs11-id-count : Get number of available PKCS#11 identities.");
106 msg(M_CLIENT, "pkcs11-id-get index : Get PKCS#11 identity at index.");
107#endif
108 msg(M_CLIENT, "client-auth CID KID : Authenticate client-id/key-id CID/KID (MULTILINE)");
109 msg(M_CLIENT, "client-auth-nt CID KID : Authenticate client-id/key-id CID/KID");
111 "client-deny CID KID R [CR] : Deny auth client-id/key-id CID/KID with log reason");
112 msg(M_CLIENT, " text R and optional client reason text CR");
114 "client-pending-auth CID KID MSG timeout : Instruct OpenVPN to send AUTH_PENDING and INFO_PRE msg");
116 " to the client and wait for a final client-auth/client-deny");
117 msg(M_CLIENT, "client-kill CID [M] : Kill client instance CID with message M (def=RESTART)");
118 msg(M_CLIENT, "env-filter [level] : Set env-var filter level");
119 msg(M_CLIENT, "rsa-sig : Enter a signature in response to >RSA_SIGN challenge");
121 " Enter signature base64 on subsequent lines followed by END");
122 msg(M_CLIENT, "pk-sig : Enter a signature in response to >PK_SIGN challenge");
124 " Enter signature base64 on subsequent lines followed by END");
126 "certificate : Enter a client certificate in response to >NEED-CERT challenge");
128 " Enter certificate base64 on subsequent lines followed by END");
129 msg(M_CLIENT, "signal s : Send signal s to daemon,");
130 msg(M_CLIENT, " s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2.");
131 msg(M_CLIENT, "state [on|off] [N|all] : Like log, but show state history.");
132 msg(M_CLIENT, "status [n] : Show current daemon status info using format #n.");
133 msg(M_CLIENT, "test n : Produce n lines of output for testing/debugging.");
134 msg(M_CLIENT, "username type u : Enter username u for a queried OpenVPN username.");
135 msg(M_CLIENT, "verb [n] : Set log verbosity level to n, or show if n is absent.");
136 msg(M_CLIENT, "version [n] : Set client's version to n or show current version of daemon.");
137 msg(M_CLIENT, "push-update-broad options : Broadcast a message to update the specified options.");
138 msg(M_CLIENT, " Ex. push-update-broad \"route something, -dns\"");
139 msg(M_CLIENT, "push-update-cid CID options : Send an update message to the client identified by CID.");
140 msg(M_CLIENT, "END");
141}
142
143static const char *
144man_state_name(const int state)
145{
146 switch (state)
147 {
149 return "INITIAL";
150
152 return "CONNECTING";
153
155 return "WAIT";
156
158 return "AUTH";
159
161 return "GET_CONFIG";
162
164 return "ASSIGN_IP";
165
167 return "ADD_ROUTES";
168
170 return "CONNECTED";
171
173 return "RECONNECTING";
174
176 return "EXITING";
177
179 return "RESOLVE";
180
182 return "TCP_CONNECT";
183
185 return "AUTH_PENDING";
186
187 default:
188 return "?";
189 }
190}
191
192static void
194{
195 msg(M_CLIENT, ">INFO:OpenVPN Management Interface Version %d -- type 'help' for more info",
197 if (man->persist.special_state_msg)
198 {
200 }
201}
202
203static inline bool
205{
206 return man->settings.up.defined && !man->connection.password_verified;
207}
208
209#if defined(__GNUC__) || defined(__clang__)
210#pragma GCC diagnostic push
211#pragma GCC diagnostic ignored "-Wconversion"
212#endif
213
214static void
215man_check_password(struct management *man, const char *line)
216{
217 if (man_password_needed(man))
218 {
219 /* This comparison is not fixed time but since strlen(time) is based on
220 * the attacker choice, it should not give any indication of the real
221 * password length, use + 1 to include the NUL byte that terminates the
222 * string*/
223 size_t compare_len = min_uint(strlen(line) + 1, sizeof(man->settings.up.password));
224 if (memcmp_constant_time(line, man->settings.up.password, compare_len) == 0)
225 {
226 man->connection.password_verified = true;
227 msg(M_CLIENT, "SUCCESS: password is correct");
228 man_welcome(man);
229 }
230 else
231 {
232 man->connection.password_verified = false;
233 msg(M_CLIENT, "ERROR: bad password");
235 {
236 msg(M_WARN, "MAN: client connection rejected after %d failed password attempts",
238 man->connection.halt = true;
239 }
240 }
241 }
242}
243
244#if defined(__GNUC__) || defined(__clang__)
245#pragma GCC diagnostic pop
246#endif
247
248static void
250{
252 {
254 {
256 }
257 else
258 {
260 }
261 }
262}
263
264static void
266{
267 if (management_connected(man))
268 {
271 {
272 volatile int signal_received = 0;
273 man_output_standalone(man, &signal_received);
274 }
275 }
276}
277
278static void
279man_output_list_push_str(struct management *man, const char *str)
280{
281 if (management_connected(man) && str)
282 {
284 }
285}
286
287static void
288man_output_list_push(struct management *man, const char *str)
289{
290 man_output_list_push_str(man, str);
292}
293
294static void
296{
297 if (man_password_needed(man))
298 {
299 man_output_list_push(man, "ENTER PASSWORD:");
300 }
301#if 0 /* should we use prompt? */
302 else
303 {
304 man_output_list_push(man, ">");
305 }
306#endif
307}
308
309
314static void
315report_command_status(const bool status, const char *command)
316{
317 if (status)
318 {
319 msg(M_CLIENT, "SUCCESS: %s command succeeded", command);
320 }
321 else
322 {
323 msg(M_CLIENT, "ERROR: %s command failed", command);
324 }
325}
326
327static void
329{
330#if UNIX_SOCK_SUPPORT
332 {
333 socket_delete_unix(&man->settings.local_unix);
334 }
335#endif
336}
337
338static void
340{
341#ifndef _WIN32
342 /*
343 * Windows doesn't need this because the ne32 event is permanently
344 * enabled at struct management scope.
345 */
347 {
349 }
350#endif
352}
353
354static void
355virtual_output_callback_func(void *arg, const unsigned int flags, const char *str)
356{
357 struct management *man = (struct management *)arg;
358 static int recursive_level = 0; /* GLOBAL */
359
360#define AF_DID_PUSH (1 << 0)
361#define AF_DID_RESET (1 << 1)
362 if (recursive_level < 5) /* limit recursion */
363 {
364 struct gc_arena gc = gc_new();
365 struct log_entry e;
366 const char *out = NULL;
367 unsigned int action_flags = 0;
368
369 ++recursive_level;
370
371 CLEAR(e);
372 update_time();
373 e.timestamp = now;
374 e.u.msg_flags = flags;
375 e.string = str;
376
377 if (flags & M_FATAL)
378 {
379 man->persist.standalone_disabled = false;
380 }
381
382 if (flags != M_CLIENT)
383 {
384 log_history_add(man->persist.log, &e);
385 }
386
387 if (!man_password_needed(man))
388 {
389 if (flags == M_CLIENT)
390 {
391 out = log_entry_print(&e, LOG_PRINT_CRLF, &gc);
392 }
393 else if (man->connection.log_realtime)
394 {
395 out = log_entry_print(&e,
398 &gc);
399 }
400 if (out)
401 {
402 man_output_list_push_str(man, out);
403 action_flags |= AF_DID_PUSH;
404 }
405 if (flags & M_FATAL)
406 {
408 if (out)
409 {
410 man_output_list_push_str(man, out);
411 action_flags |= (AF_DID_PUSH | AF_DID_RESET);
412 }
413 }
414 }
415
416 gc_free(&gc);
417
418 if (action_flags & AF_DID_PUSH)
419 {
421 }
422 if (action_flags & AF_DID_RESET)
423 {
424 man_reset_client_socket(man, true);
425 }
426
427 --recursive_level;
428 }
429 else
430 {
431 /* cannot use msg here */
432 printf("virtual_output: message to management interface "
433 "dropped due to recursion: <%s>\n",
434 str);
435 }
436}
437
438/*
439 * Given a signal, return the signal with possible remapping applied,
440 * or -1 if the signal should be ignored.
441 */
442static int
443man_mod_signal(const struct management *man, const int signum)
444{
445 const unsigned int flags = man->settings.mansig;
446 int s = signum;
447 if (s == SIGUSR1)
448 {
449 if (flags & MANSIG_MAP_USR1_TO_HUP)
450 {
451 s = SIGHUP;
452 }
453 if (flags & MANSIG_MAP_USR1_TO_TERM)
454 {
455 s = SIGTERM;
456 }
457 }
458 if (flags & MANSIG_IGNORE_USR1_HUP)
459 {
460 if (s == SIGHUP || s == SIGUSR1)
461 {
462 s = -1;
463 }
464 }
465 return s;
466}
467
468static void
469man_signal(struct management *man, const char *name)
470{
471 const int sig = parse_signal(name);
472 if (sig >= 0)
473 {
474 const int sig_mod = man_mod_signal(man, sig);
475 if (sig_mod >= 0)
476 {
477 throw_signal(sig_mod);
478 msg(M_CLIENT, "SUCCESS: signal %s thrown", signal_name(sig_mod, true));
479 }
480 else
481 {
482 msg(M_CLIENT, "ERROR: signal '%s' is currently ignored", name);
483 if (man->persist.special_state_msg)
484 {
486 }
487 }
488 }
489 else
490 {
491 msg(M_CLIENT, "ERROR: signal '%s' is not a known signal type", name);
492 }
493}
494
495static void
496man_command_unsupported(const char *command_name)
497{
498 msg(M_CLIENT, "ERROR: The '%s' command is not supported by the current daemon mode",
499 command_name);
500}
501
502static void
503man_status(struct management *man, const int version, struct status_output *so)
504{
505 if (man->persist.callback.status)
506 {
507 (*man->persist.callback.status)(man->persist.callback.arg, version, so);
508 }
509 else
510 {
511 man_command_unsupported("status");
512 }
513}
514
515static void
521
522static void
523man_bytecount(struct management *man, const int update_seconds)
524{
525 if (update_seconds > 0)
526 {
527 man->connection.bytecount_update_seconds = update_seconds;
530 }
531 else
532 {
534 }
535
536 /* The newly received bytecount interval may be sooner than the existing
537 * coarse timer wakeup. Reset the timer to ensure it fires at the correct,
538 * earlier time.
539 */
540 if (man->persist.callback.arg)
541 {
542 struct context *c;
543
544 if (man->settings.flags & MF_SERVER)
545 {
546 struct multi_context *m = man->persist.callback.arg;
547 c = &m->top;
548 }
549 else
550 {
551 c = man->persist.callback.arg;
552 }
553
555 }
556
557 msg(M_CLIENT, "SUCCESS: bytecount interval changed");
558}
559
560static void
562{
563 char in[32];
564 char out[32];
565
566 /* do in a roundabout way to work around possible mingw or mingw-glibc bug */
567 snprintf(in, sizeof(in), counter_format, bytes_in_total);
568 snprintf(out, sizeof(out), counter_format, bytes_out_total);
569 msg(M_CLIENT, ">BYTECOUNT:%s,%s", in, out);
570}
571
572static void
573man_bytecount_output_server(const counter_type bytes_in_total, const counter_type bytes_out_total,
574 struct man_def_auth_context *mdac)
575{
576 char in[32];
577 char out[32];
578 /* do in a roundabout way to work around possible mingw or mingw-glibc bug */
579 snprintf(in, sizeof(in), counter_format, bytes_in_total);
580 snprintf(out, sizeof(out), counter_format, bytes_out_total);
581 msg(M_CLIENT, ">BYTECOUNT_CLI:%lu,%s,%s", mdac->cid, in, out);
582}
583
584static void
585man_kill(struct management *man, const char *victim)
586{
587 struct gc_arena gc = gc_new();
588
590 {
591 struct buffer buf;
592 char p1[128];
593 char p2[128];
594 char p3[128];
595 int n_killed;
596
597 buf_set_read(&buf, (uint8_t *)victim, strlen(victim) + 1);
598 buf_parse(&buf, ':', p1, sizeof(p1));
599 buf_parse(&buf, ':', p2, sizeof(p2));
600 buf_parse(&buf, ':', p3, sizeof(p3));
601
602 if (strlen(p1) && strlen(p2) && strlen(p3))
603 {
604 /* IP:port specified */
605 bool status;
606 const in_addr_t addr =
608 if (status)
609 {
610 const int port = atoi(p3);
611 const int proto = (streq(p1, "tcp")) ? PROTO_TCP_SERVER
612 : (streq(p1, "udp")) ? PROTO_UDP
613 : PROTO_NONE;
614
615 if ((port > 0 && port < 65536) && (proto != PROTO_NONE))
616 {
617 n_killed = (*man->persist.callback.kill_by_addr)(man->persist.callback.arg,
618 addr, port, proto);
619 if (n_killed > 0)
620 {
621 msg(M_CLIENT, "SUCCESS: %d client(s) at address %s:%s:%d killed", n_killed,
622 proto2ascii(proto, AF_UNSPEC, false), print_in_addr_t(addr, 0, &gc),
623 port);
624 }
625 else
626 {
627 msg(M_CLIENT, "ERROR: client at address %s:%s:%d not found",
628 proto2ascii(proto, AF_UNSPEC, false), print_in_addr_t(addr, 0, &gc),
629 port);
630 }
631 }
632 else
633 {
634 msg(M_CLIENT, "ERROR: port number or protocol out of range: %s %s", p3, p1);
635 }
636 }
637 else
638 {
639 msg(M_CLIENT, "ERROR: error parsing IP address: %s", p2);
640 }
641 }
642 else if (strlen(p1))
643 {
644 /* common name specified */
645 n_killed = (*man->persist.callback.kill_by_cn)(man->persist.callback.arg, p1);
646 if (n_killed > 0)
647 {
648 msg(M_CLIENT, "SUCCESS: common name '%s' found, %d client(s) killed", p1, n_killed);
649 }
650 else
651 {
652 msg(M_CLIENT, "ERROR: common name '%s' not found", p1);
653 }
654 }
655 else
656 {
657 msg(M_CLIENT, "ERROR: kill parse");
658 }
659 }
660 else
661 {
663 }
664
665 gc_free(&gc);
666}
667
668/*
669 * General-purpose history command handler
670 * for the log and echo commands.
671 */
672static void
673man_history(struct management *man, const char *parm, const char *type, struct log_history *log,
674 bool *realtime, const unsigned int lep_flags)
675{
676 struct gc_arena gc = gc_new();
677 int n = 0;
678
679 if (streq(parm, "on"))
680 {
681 *realtime = true;
682 msg(M_CLIENT, "SUCCESS: real-time %s notification set to ON", type);
683 }
684 else if (streq(parm, "off"))
685 {
686 *realtime = false;
687 msg(M_CLIENT, "SUCCESS: real-time %s notification set to OFF", type);
688 }
689 else if (streq(parm, "all") || (n = atoi(parm)) > 0)
690 {
691 const int size = log_history_size(log);
692 const int start = (n ? n : size) - 1;
693 int i;
694
695 for (i = start; i >= 0; --i)
696 {
697 const struct log_entry *e = log_history_ref(log, i);
698 if (e)
699 {
700 const char *out = log_entry_print(e, lep_flags, &gc);
702 }
703 }
704 msg(M_CLIENT, "END");
705 }
706 else
707 {
708 msg(M_CLIENT, "ERROR: %s parameter must be 'on' or 'off' or some number n or 'all'", type);
709 }
710
711 gc_free(&gc);
712}
713
714static void
715man_log(struct management *man, const char *parm)
716{
717 man_history(man, parm, "log", man->persist.log, &man->connection.log_realtime,
719}
720
721static void
722man_echo(struct management *man, const char *parm)
723{
724 man_history(man, parm, "echo", man->persist.echo, &man->connection.echo_realtime,
726}
727
728static void
729man_state(struct management *man, const char *parm)
730{
731 man_history(man, parm, "state", man->persist.state, &man->connection.state_realtime,
733}
734
735static void
737{
738 switch (man->connection.up_query_mode)
739 {
741 if (!strlen(man->connection.up_query.username))
742 {
743 break;
744 }
745
746 /* fall through */
747 case UP_QUERY_PASS:
748 case UP_QUERY_NEED_OK:
750 if (strlen(man->connection.up_query.password))
751 {
752 man->connection.up_query.defined = true;
753 }
754 break;
755
757 man->connection.up_query.defined = false;
758 break;
759
760 default:
761 ASSERT(0);
762 }
763}
764
765static void
766man_query_user_pass(struct management *man, const char *type, const char *string, const bool needed,
767 const char *prompt, char *dest, int len)
768{
769 if (needed)
770 {
772 if (streq(man->connection.up_query_type, type))
773 {
774 strncpynt(dest, string, len);
775 man_up_finalize(man);
776 msg(M_CLIENT, "SUCCESS: '%s' %s entered, but not yet verified", type, prompt);
777 }
778 else
779 {
780 msg(M_CLIENT, "ERROR: %s of type '%s' entered, but we need one of type '%s'", prompt,
781 type, man->connection.up_query_type);
782 }
783 }
784 else
785 {
786 msg(M_CLIENT, "ERROR: no %s is currently needed at this time", prompt);
787 }
788}
789
790static void
791man_query_username(struct management *man, const char *type, const char *string)
792{
793 const bool needed =
795 man_query_user_pass(man, type, string, needed, "username", man->connection.up_query.username,
797}
798
799static void
800man_query_password(struct management *man, const char *type, const char *string)
801{
802 const bool needed = ((man->connection.up_query_mode == UP_QUERY_PASS
804 && man->connection.up_query_type);
805 if (!string[0]) /* allow blank passwords to be passed through using the blank_up tag */
806 {
807 string = blank_up;
808 }
809 man_query_user_pass(man, type, string, needed, "password", man->connection.up_query.password,
811}
812
813static void
814man_query_need_ok(struct management *man, const char *type, const char *action)
815{
816 const bool needed =
818 man_query_user_pass(man, type, action, needed, "needok-confirmation",
820}
821
822static void
823man_query_need_str(struct management *man, const char *type, const char *action)
824{
825 const bool needed =
827 man_query_user_pass(man, type, action, needed, "needstr-string",
829}
830
831static void
833{
834 ssl_purge_auth(false);
835 (void)ssl_clean_auth_token();
836 msg(M_CLIENT, "SUCCESS: Passwords were forgotten");
837}
838
839static void
840man_net(struct management *man)
841{
842 if (man->persist.callback.show_net)
843 {
845 }
846 else
847 {
849 }
850}
851
852static void
853man_send_cc_message(struct management *man, const char *message, const char *parameters)
854{
856 {
857 const bool status = (*man->persist.callback.send_cc_message)(man->persist.callback.arg,
858 message, parameters);
859 if (status)
860 {
861 msg(M_CLIENT, "SUCCESS: command succeeded");
862 }
863 else
864 {
865 msg(M_CLIENT, "ERROR: command failed");
866 }
867 }
868 else
869 {
870 man_command_unsupported("cr-repsonse");
871 }
872}
873#ifdef ENABLE_PKCS11
874
875static void
876man_pkcs11_id_count(struct management *man)
877{
878 msg(M_CLIENT, ">PKCS11ID-COUNT:%d", pkcs11_management_id_count());
879}
880
881static void
882man_pkcs11_id_get(struct management *man, const int index)
883{
884 char *id = NULL;
885 char *base64 = NULL;
886
887 if (pkcs11_management_id_get(index, &id, &base64))
888 {
889 msg(M_CLIENT, ">PKCS11ID-ENTRY:'%d', ID:'%s', BLOB:'%s'", index, id, base64);
890 }
891 else
892 {
893 msg(M_CLIENT, ">PKCS11ID-ENTRY:'%d'", index);
894 }
895
896 free(id);
897 free(base64);
898}
899
900#endif /* ifdef ENABLE_PKCS11 */
901
902static void
904{
905 unsigned count = 0;
907 {
909 msg(M_CLIENT, "%u", count);
910 msg(M_CLIENT, "END");
911 }
912 else
913 {
914 man_command_unsupported("remote-entry-count");
915 }
916}
917
918static void
919man_remote_entry_get(struct management *man, const char *p1, const char *p2)
920{
921 ASSERT(p1);
922
924 {
925 unsigned int count = (*man->persist.callback.remote_entry_count)(man->persist.callback.arg);
926
927 unsigned int from = (unsigned int)atoi(p1);
928 unsigned int to = p2 ? (unsigned int)atoi(p2) : from + 1;
929
930 if (!strcmp(p1, "all"))
931 {
932 from = 0;
933 to = count;
934 }
935
936 for (unsigned int i = from; i < min_uint(to, count); i++)
937 {
938 char *remote = NULL;
939 bool res =
940 (*man->persist.callback.remote_entry_get)(man->persist.callback.arg, i, &remote);
941 if (res && remote)
942 {
943 msg(M_CLIENT, "%u,%s", i, remote);
944 }
945 free(remote);
946 }
947 msg(M_CLIENT, "END");
948 }
949 else
950 {
951 man_command_unsupported("remote-entry-get");
952 }
953}
954
955static void
956man_hold(struct management *man, const char *cmd)
957{
958 if (cmd)
959 {
960 if (streq(cmd, "on"))
961 {
962 man->settings.flags |= MF_HOLD;
963 msg(M_CLIENT, "SUCCESS: hold flag set to ON");
964 }
965 else if (streq(cmd, "off"))
966 {
967 man->settings.flags &= ~MF_HOLD;
968 msg(M_CLIENT, "SUCCESS: hold flag set to OFF");
969 }
970 else if (streq(cmd, "release"))
971 {
972 man->persist.hold_release = true;
973 msg(M_CLIENT, "SUCCESS: hold release succeeded");
974 }
975 else
976 {
977 msg(M_CLIENT, "ERROR: bad hold command parameter");
978 }
979 }
980 else
981 {
982 msg(M_CLIENT, "SUCCESS: hold=%d", BOOL_CAST(man->settings.flags & MF_HOLD));
983 }
984}
985
986#define IER_RESET 0
987#define IER_NEW 1
988
989static void
990in_extra_reset(struct man_connection *mc, const int mode)
991{
992 if (mc)
993 {
994 if (mode != IER_NEW)
995 {
997 mc->in_extra_cid = 0;
998 mc->in_extra_kid = 0;
999 }
1000 if (mc->in_extra)
1001 {
1003 mc->in_extra = NULL;
1004 }
1005 if (mode == IER_NEW)
1006 {
1007 mc->in_extra = buffer_list_new();
1008 }
1009 }
1010}
1011
1012static void
1014{
1015 switch (man->connection.in_extra_cmd)
1016 {
1017 case IEC_CLIENT_AUTH:
1018 if (man->persist.callback.client_auth)
1019 {
1020 const bool status = (*man->persist.callback.client_auth)(
1022 man->connection.in_extra_kid, true, NULL, NULL, man->connection.in_extra);
1023 man->connection.in_extra = NULL;
1024 report_command_status(status, "client-auth");
1025 }
1026 else
1027 {
1028 man_command_unsupported("client-auth");
1029 }
1030 break;
1031
1032 case IEC_PK_SIGN:
1036 man->connection.in_extra = NULL;
1037 return;
1038
1039 case IEC_CERTIFICATE:
1043 man->connection.in_extra = NULL;
1044 return;
1045 }
1047}
1048
1049static bool
1050parse_cid(const char *str, unsigned long *cid)
1051{
1052 if (sscanf(str, "%lu", cid) == 1)
1053 {
1054 return true;
1055 }
1056 else
1057 {
1058 msg(M_CLIENT, "ERROR: cannot parse CID");
1059 return false;
1060 }
1061}
1062
1063static bool
1064parse_uint(const char *str, const char *what, unsigned int *uint)
1065{
1066 if (sscanf(str, "%u", uint) == 1)
1067 {
1068 return true;
1069 }
1070 else
1071 {
1072 msg(M_CLIENT, "ERROR: cannot parse %s", what);
1073 return false;
1074 }
1075}
1076
1088static void
1089man_client_pending_auth(struct management *man, const char *cid_str, const char *kid_str,
1090 const char *extra, const char *timeout_str)
1091{
1092 unsigned long cid = 0;
1093 unsigned int kid = 0;
1094 unsigned int timeout = 0;
1095 if (parse_cid(cid_str, &cid) && parse_uint(kid_str, "KID", &kid)
1096 && parse_uint(timeout_str, "TIMEOUT", &timeout))
1097 {
1099 {
1100 bool ret = (*man->persist.callback.client_pending_auth)(man->persist.callback.arg, cid,
1101 kid, extra, timeout);
1102
1103 if (ret)
1104 {
1105 msg(M_CLIENT, "SUCCESS: client-pending-auth command succeeded");
1106 }
1107 else
1108 {
1109 msg(M_CLIENT, "ERROR: client-pending-auth command failed."
1110 " Extra parameter might be too long");
1111 }
1112 }
1113 else
1114 {
1115 man_command_unsupported("client-pending-auth");
1116 }
1117 }
1118}
1119
1120static void
1121man_client_auth(struct management *man, const char *cid_str, const char *kid_str, const bool extra)
1122{
1123 struct man_connection *mc = &man->connection;
1124 mc->in_extra_cid = 0;
1125 mc->in_extra_kid = 0;
1126 if (parse_cid(cid_str, &mc->in_extra_cid) && parse_uint(kid_str, "KID", &mc->in_extra_kid))
1127 {
1130 if (!extra)
1131 {
1132 in_extra_dispatch(man);
1133 }
1134 }
1135}
1136
1137static void
1138man_client_deny(struct management *man, const char *cid_str, const char *kid_str,
1139 const char *reason, const char *client_reason)
1140{
1141 unsigned long cid = 0;
1142 unsigned int kid = 0;
1143 if (parse_cid(cid_str, &cid) && parse_uint(kid_str, "KID", &kid))
1144 {
1145 if (man->persist.callback.client_auth)
1146 {
1147 const bool status = (*man->persist.callback.client_auth)(
1148 man->persist.callback.arg, cid, kid, false, reason, client_reason, NULL);
1149 if (status)
1150 {
1151 msg(M_CLIENT, "SUCCESS: client-deny command succeeded");
1152 }
1153 else
1154 {
1155 msg(M_CLIENT, "ERROR: client-deny command failed");
1156 }
1157 }
1158 else
1159 {
1160 man_command_unsupported("client-deny");
1161 }
1162 }
1163}
1164
1165static void
1166man_client_kill(struct management *man, const char *cid_str, const char *kill_msg)
1167{
1168 unsigned long cid = 0;
1169 if (parse_cid(cid_str, &cid))
1170 {
1171 if (man->persist.callback.kill_by_cid)
1172 {
1173 const bool status =
1174 (*man->persist.callback.kill_by_cid)(man->persist.callback.arg, cid, kill_msg);
1175 if (status)
1176 {
1177 msg(M_CLIENT, "SUCCESS: client-kill command succeeded");
1178 }
1179 else
1180 {
1181 msg(M_CLIENT, "ERROR: client-kill command failed");
1182 }
1183 }
1184 else
1185 {
1186 man_command_unsupported("client-kill");
1187 }
1188 }
1189}
1190
1191static void
1193{
1194 if (man->persist.callback.n_clients)
1195 {
1196 const int nclients = (*man->persist.callback.n_clients)(man->persist.callback.arg);
1197 msg(M_CLIENT, "SUCCESS: nclients=%d", nclients);
1198 }
1199 else
1200 {
1201 man_command_unsupported("nclients");
1202 }
1203}
1204
1205static void
1206man_env_filter(struct management *man, const int level)
1207{
1208 man->connection.env_filter_level = level;
1209 msg(M_CLIENT, "SUCCESS: env_filter_level=%d", level);
1210}
1211
1212
1213static void
1214man_pk_sig(struct management *man, const char *cmd_name)
1215{
1216 struct man_connection *mc = &man->connection;
1217 if (mc->ext_key_state == EKS_SOLICIT)
1218 {
1222 }
1223 else
1224 {
1225 msg(M_CLIENT, "ERROR: The %s command is not currently available", cmd_name);
1226 }
1227}
1228
1229static void
1231{
1232 struct man_connection *mc = &man->connection;
1233 if (mc->ext_cert_state == EKS_SOLICIT)
1234 {
1238 }
1239 else
1240 {
1241 msg(M_CLIENT, "ERROR: The certificate command is not currently available");
1242 }
1243}
1244
1245static void
1247{
1250 int nclients = 0;
1251
1252 if (man->persist.callback.n_clients)
1253 {
1254 nclients = (*man->persist.callback.n_clients)(man->persist.callback.arg);
1255 }
1256 msg(M_CLIENT, "SUCCESS: nclients=%d,bytesin=" counter_format ",bytesout=" counter_format,
1258}
1259
1260#define MN_AT_LEAST (1 << 0)
1271static bool
1272man_need(struct management *man, const char **p, const int n, unsigned int flags)
1273{
1274 int i;
1275 ASSERT(p[0]);
1276 for (i = 1; i <= n; ++i)
1277 {
1278 if (!p[i])
1279 {
1280 msg(M_CLIENT, "ERROR: the '%s' command requires %s%d parameter%s", p[0],
1281 (flags & MN_AT_LEAST) ? "at least " : "", n, n > 1 ? "s" : "");
1282 return false;
1283 }
1284 }
1285 return true;
1286}
1287
1288static void
1289man_proxy(struct management *man, const char **p)
1290{
1291 if (man->persist.callback.proxy_cmd)
1292 {
1293 const bool status = (*man->persist.callback.proxy_cmd)(man->persist.callback.arg, p);
1294 report_command_status(status, "proxy");
1295 }
1296 else
1297 {
1298 man_command_unsupported("proxy");
1299 }
1300}
1301
1302static void
1303man_remote(struct management *man, const char **p)
1304{
1305 if (man->persist.callback.remote_cmd)
1306 {
1307 const bool status = (*man->persist.callback.remote_cmd)(man->persist.callback.arg, p);
1308 report_command_status(status, "remote");
1309 }
1310 else
1311 {
1312 man_command_unsupported("remote");
1313 }
1314}
1315
1316#ifdef TARGET_ANDROID
1317static void
1318man_network_change(struct management *man, bool samenetwork)
1319{
1320 /* Called to signal the OpenVPN that the network configuration has changed and
1321 * the client should either float or reconnect.
1322 *
1323 * The code is currently only used by ics-openvpn
1324 */
1325 if (man->persist.callback.network_change)
1326 {
1327 int fd = (*man->persist.callback.network_change)(man->persist.callback.arg, samenetwork);
1328 man->connection.fdtosend = fd;
1329 msg(M_CLIENT, "PROTECTFD: fd '%d' sent to be protected", fd);
1330 if (fd == -2)
1331 {
1332 man_signal(man, "SIGUSR1");
1333 }
1334 }
1335}
1336#endif
1337
1338static void
1339set_client_version(struct management *man, const char *version)
1340{
1341 if (version)
1342 {
1343 man->connection.client_version = atoi(version);
1344 }
1345}
1346
1347static void
1348man_push_update(struct management *man, const char **p, const push_update_type type)
1349{
1350 bool status = false;
1351
1352 if (type == UPT_BROADCAST)
1353 {
1355 {
1356 man_command_unsupported("push-update-broad");
1357 return;
1358 }
1359
1361 }
1362 else if (type == UPT_BY_CID)
1363 {
1365 {
1366 man_command_unsupported("push-update-cid");
1367 return;
1368 }
1369
1370 unsigned long cid = 0;
1371
1372 if (!parse_cid(p[1], &cid))
1373 {
1374 msg(M_CLIENT, "ERROR: push-update-cid fail during cid parsing");
1375 return;
1376 }
1377
1378 status = (*man->persist.callback.push_update_by_cid)(man->persist.callback.arg, cid, p[2]);
1379 }
1380
1381 if (status)
1382 {
1383 msg(M_CLIENT, "SUCCESS: push-update command succeeded");
1384 return;
1385 }
1386 msg(M_CLIENT, "ERROR: push-update command failed");
1387}
1388
1389static void
1390man_dispatch_command(struct management *man, struct status_output *so, const char **p,
1391 const int nparms)
1392{
1393 struct gc_arena gc = gc_new();
1394
1395 ASSERT(p[0]);
1396 if (streq(p[0], "exit") || streq(p[0], "quit"))
1397 {
1398 man->connection.halt = true;
1399 goto done;
1400 }
1401 else if (streq(p[0], "help"))
1402 {
1403 man_help();
1404 }
1405 else if (streq(p[0], "version") && p[1])
1406 {
1407 set_client_version(man, p[1]);
1408 }
1409 else if (streq(p[0], "version"))
1410 {
1411 msg(M_CLIENT, "OpenVPN Version: %s", title_string);
1412 msg(M_CLIENT, "Management Version: %d", MANAGEMENT_VERSION);
1413 msg(M_CLIENT, "END");
1414 }
1415 else if (streq(p[0], "pid"))
1416 {
1417 msg(M_CLIENT, "SUCCESS: pid=%d", platform_getpid());
1418 }
1419 else if (streq(p[0], "nclients"))
1420 {
1422 }
1423 else if (streq(p[0], "env-filter"))
1424 {
1425 int level = 0;
1426 if (p[1])
1427 {
1428 level = atoi(p[1]);
1429 }
1430 man_env_filter(man, level);
1431 }
1432 else if (streq(p[0], "signal"))
1433 {
1434 if (man_need(man, p, 1, 0))
1435 {
1436 man_signal(man, p[1]);
1437 }
1438 }
1439#ifdef TARGET_ANDROID
1440 else if (streq(p[0], "network-change"))
1441 {
1442 bool samenetwork = false;
1443 if (p[1] && streq(p[1], "samenetwork"))
1444 {
1445 samenetwork = true;
1446 }
1447
1448 man_network_change(man, samenetwork);
1449 }
1450#endif
1451 else if (streq(p[0], "load-stats"))
1452 {
1453 man_load_stats(man);
1454 }
1455 else if (streq(p[0], "status"))
1456 {
1457 int version = 0;
1458 if (p[1])
1459 {
1460 version = atoi(p[1]);
1461 }
1462 man_status(man, version, so);
1463 }
1464 else if (streq(p[0], "kill"))
1465 {
1466 if (man_need(man, p, 1, 0))
1467 {
1468 man_kill(man, p[1]);
1469 }
1470 }
1471 else if (streq(p[0], "verb"))
1472 {
1473 if (p[1])
1474 {
1475 const int level = atoi(p[1]);
1476 if (set_debug_level(level, 0))
1477 {
1478 msg(M_CLIENT, "SUCCESS: verb level changed");
1479 }
1480 else
1481 {
1482 msg(M_CLIENT, "ERROR: verb level is out of range");
1483 }
1484 }
1485 else
1486 {
1487 msg(M_CLIENT, "SUCCESS: verb=%u", get_debug_level());
1488 }
1489 }
1490 else if (streq(p[0], "mute"))
1491 {
1492 if (p[1])
1493 {
1494 const int level = atoi(p[1]);
1495 if (set_mute_cutoff(level))
1496 {
1497 msg(M_CLIENT, "SUCCESS: mute level changed");
1498 }
1499 else
1500 {
1501 msg(M_CLIENT, "ERROR: mute level is out of range");
1502 }
1503 }
1504 else
1505 {
1506 msg(M_CLIENT, "SUCCESS: mute=%d", get_mute_cutoff());
1507 }
1508 }
1509 else if (streq(p[0], "auth-retry"))
1510 {
1511 if (p[1])
1512 {
1513 if (auth_retry_set(M_CLIENT, p[1]))
1514 {
1515 msg(M_CLIENT, "SUCCESS: auth-retry parameter changed");
1516 }
1517 else
1518 {
1519 msg(M_CLIENT, "ERROR: bad auth-retry parameter");
1520 }
1521 }
1522 else
1523 {
1524 msg(M_CLIENT, "SUCCESS: auth-retry=%s", auth_retry_print());
1525 }
1526 }
1527 else if (streq(p[0], "state"))
1528 {
1529 if (!p[1])
1530 {
1531 man_state(man, "1");
1532 }
1533 else
1534 {
1535 if (p[1])
1536 {
1537 man_state(man, p[1]);
1538 }
1539 if (p[2])
1540 {
1541 man_state(man, p[2]);
1542 }
1543 }
1544 }
1545 else if (streq(p[0], "log"))
1546 {
1547 if (man_need(man, p, 1, MN_AT_LEAST))
1548 {
1549 if (p[1])
1550 {
1551 man_log(man, p[1]);
1552 }
1553 if (p[2])
1554 {
1555 man_log(man, p[2]);
1556 }
1557 }
1558 }
1559 else if (streq(p[0], "echo"))
1560 {
1561 if (man_need(man, p, 1, MN_AT_LEAST))
1562 {
1563 if (p[1])
1564 {
1565 man_echo(man, p[1]);
1566 }
1567 if (p[2])
1568 {
1569 man_echo(man, p[2]);
1570 }
1571 }
1572 }
1573 else if (streq(p[0], "username"))
1574 {
1575 if (man_need(man, p, 2, 0))
1576 {
1577 man_query_username(man, p[1], p[2]);
1578 }
1579 }
1580 else if (streq(p[0], "password"))
1581 {
1582 if (man_need(man, p, 2, 0))
1583 {
1584 man_query_password(man, p[1], p[2]);
1585 }
1586 }
1587 else if (streq(p[0], "forget-passwords"))
1588 {
1590 }
1591 else if (streq(p[0], "needok"))
1592 {
1593 if (man_need(man, p, 2, 0))
1594 {
1595 man_query_need_ok(man, p[1], p[2]);
1596 }
1597 }
1598 else if (streq(p[0], "needstr"))
1599 {
1600 if (man_need(man, p, 2, 0))
1601 {
1602 man_query_need_str(man, p[1], p[2]);
1603 }
1604 }
1605 else if (streq(p[0], "cr-response"))
1606 {
1607 if (man_need(man, p, 1, 0))
1608 {
1609 man_send_cc_message(man, "CR_RESPONSE", p[1]);
1610 }
1611 }
1612 else if (streq(p[0], "net"))
1613 {
1614 man_net(man);
1615 }
1616 else if (streq(p[0], "hold"))
1617 {
1618 man_hold(man, p[1]);
1619 }
1620 else if (streq(p[0], "bytecount"))
1621 {
1622 if (man_need(man, p, 1, 0))
1623 {
1624 man_bytecount(man, atoi(p[1]));
1625 }
1626 }
1627 else if (streq(p[0], "client-kill"))
1628 {
1629 if (man_need(man, p, 1, MN_AT_LEAST))
1630 {
1631 man_client_kill(man, p[1], p[2]);
1632 }
1633 }
1634 else if (streq(p[0], "client-deny"))
1635 {
1636 if (man_need(man, p, 3, MN_AT_LEAST))
1637 {
1638 man_client_deny(man, p[1], p[2], p[3], p[4]);
1639 }
1640 }
1641 else if (streq(p[0], "client-auth-nt"))
1642 {
1643 if (man_need(man, p, 2, 0))
1644 {
1645 man_client_auth(man, p[1], p[2], false);
1646 }
1647 }
1648 else if (streq(p[0], "client-auth"))
1649 {
1650 if (man_need(man, p, 2, 0))
1651 {
1652 man_client_auth(man, p[1], p[2], true);
1653 }
1654 }
1655 else if (streq(p[0], "client-pending-auth"))
1656 {
1657 if (man_need(man, p, 4, 0))
1658 {
1659 man_client_pending_auth(man, p[1], p[2], p[3], p[4]);
1660 }
1661 }
1662 else if (streq(p[0], "rsa-sig"))
1663 {
1664 man_pk_sig(man, "rsa-sig");
1665 }
1666 else if (streq(p[0], "pk-sig"))
1667 {
1668 man_pk_sig(man, "pk-sig");
1669 }
1670 else if (streq(p[0], "certificate"))
1671 {
1672 man_certificate(man);
1673 }
1674#ifdef ENABLE_PKCS11
1675 else if (streq(p[0], "pkcs11-id-count"))
1676 {
1677 man_pkcs11_id_count(man);
1678 }
1679 else if (streq(p[0], "pkcs11-id-get"))
1680 {
1681 if (man_need(man, p, 1, 0))
1682 {
1683 man_pkcs11_id_get(man, atoi(p[1]));
1684 }
1685 }
1686#endif
1687 else if (streq(p[0], "remote-entry-count"))
1688 {
1690 }
1691 else if (streq(p[0], "remote-entry-get"))
1692 {
1693 if (man_need(man, p, 1, MN_AT_LEAST))
1694 {
1695 man_remote_entry_get(man, p[1], p[2]);
1696 }
1697 }
1698 else if (streq(p[0], "proxy"))
1699 {
1700 if (man_need(man, p, 1, MN_AT_LEAST))
1701 {
1702 man_proxy(man, p);
1703 }
1704 }
1705 else if (streq(p[0], "remote"))
1706 {
1707 if (man_need(man, p, 1, MN_AT_LEAST))
1708 {
1709 man_remote(man, p);
1710 }
1711 }
1712 else if (streq(p[0], "push-update-broad"))
1713 {
1714 if (man_need(man, p, 1, 0))
1715 {
1717 }
1718 }
1719 else if (streq(p[0], "push-update-cid"))
1720 {
1721 if (man_need(man, p, 2, 0))
1722 {
1723 man_push_update(man, p, UPT_BY_CID);
1724 }
1725 }
1726#if 1
1727 else if (streq(p[0], "test"))
1728 {
1729 if (man_need(man, p, 1, 0))
1730 {
1731 int i;
1732 const int n = atoi(p[1]);
1733 for (i = 0; i < n; ++i)
1734 {
1735 msg(M_CLIENT,
1736 "[%d] The purpose of this command is to generate large amounts of output.", i);
1737 }
1738 }
1739 }
1740#endif
1741 else
1742 {
1743 msg(M_CLIENT, "ERROR: unknown command [%s], enter 'help' for more options", p[0]);
1744 }
1745
1746done:
1747 gc_free(&gc);
1748}
1749
1750#ifdef _WIN32
1751
1752static void
1754{
1755 switch (man->connection.state)
1756 {
1757 case MS_LISTEN:
1758 net_event_win32_start(&man->connection.ne32, FD_ACCEPT, man->connection.sd_top);
1759 break;
1760
1761 case MS_CC_WAIT_READ:
1762 case MS_CC_WAIT_WRITE:
1763 net_event_win32_start(&man->connection.ne32, FD_READ | FD_WRITE | FD_CLOSE,
1764 man->connection.sd_cli);
1765 break;
1766
1767 default:
1768 ASSERT(0);
1769 }
1770}
1771
1772static void
1774{
1776}
1777
1778#endif /* ifdef _WIN32 */
1779
1780static void
1782{
1783 man->connection.state_realtime = false;
1784 man->connection.log_realtime = false;
1785 man->connection.echo_realtime = false;
1787 man->connection.password_verified = false;
1788 man->connection.password_tries = 0;
1789 man->connection.halt = false;
1791}
1792
1793static void
1794man_new_connection_post(struct management *man, const char *description)
1795{
1796 struct gc_arena gc = gc_new();
1797
1799
1801
1802#ifdef _WIN32
1803 man_start_ne32(man);
1804#endif
1805
1806#if UNIX_SOCK_SUPPORT
1807 if (man->settings.flags & MF_UNIX_SOCK)
1808 {
1809 msg(D_MANAGEMENT, "MANAGEMENT: %s %s", description,
1810 sockaddr_unix_name(&man->settings.local_unix, "NULL"));
1811 }
1812 else
1813#endif
1815 {
1816 msg(D_MANAGEMENT, "MANAGEMENT: %s %s", description,
1817 print_sockaddr(man->settings.local->ai_addr, &gc));
1818 }
1819 else
1820 {
1821 struct sockaddr_storage addr;
1822 socklen_t addrlen = sizeof(addr);
1823 if (!getpeername(man->connection.sd_cli, (struct sockaddr *)&addr, &addrlen))
1824 {
1825 msg(D_MANAGEMENT, "MANAGEMENT: %s %s", description,
1826 print_sockaddr((struct sockaddr *)&addr, &gc));
1827 }
1828 else
1829 {
1830 msg(D_MANAGEMENT, "MANAGEMENT: %s %s", description, "unknown");
1831 }
1832 }
1833
1835
1836 if (!man_password_needed(man))
1837 {
1838 man_welcome(man);
1839 }
1840 man_prompt(man);
1842
1843 gc_free(&gc);
1844}
1845
1846#if UNIX_SOCK_SUPPORT
1847static bool
1848man_verify_unix_peer_uid_gid(struct management *man, const socket_descriptor_t sd)
1849{
1850 if (socket_defined(sd) && (man->settings.client_uid != -1 || man->settings.client_gid != -1))
1851 {
1852 static const char err_prefix[] =
1853 "MANAGEMENT: unix domain socket client connection rejected --";
1854 int uid, gid;
1855 if (unix_socket_get_peer_uid_gid(man->connection.sd_cli, &uid, &gid))
1856 {
1857 if (man->settings.client_uid != -1 && man->settings.client_uid != uid)
1858 {
1860 "%s UID of socket peer (%d) doesn't match required value (%d) as given by --management-client-user",
1861 err_prefix, uid, man->settings.client_uid);
1862 return false;
1863 }
1864 if (man->settings.client_gid != -1 && man->settings.client_gid != gid)
1865 {
1867 "%s GID of socket peer (%d) doesn't match required value (%d) as given by --management-client-group",
1868 err_prefix, gid, man->settings.client_gid);
1869 return false;
1870 }
1871 }
1872 else
1873 {
1874 msg(D_MANAGEMENT, "%s cannot get UID/GID of socket peer", err_prefix);
1875 return false;
1876 }
1877 }
1878 return true;
1879}
1880#endif /* if UNIX_SOCK_SUPPORT */
1881
1882static void
1884{
1885 struct link_socket_actual act;
1886 CLEAR(act);
1887
1888 /*
1889 * Accept the TCP or Unix domain socket client.
1890 */
1891#if UNIX_SOCK_SUPPORT
1892 if (man->settings.flags & MF_UNIX_SOCK)
1893 {
1894 struct sockaddr_un remote;
1895 man->connection.sd_cli = socket_accept_unix(man->connection.sd_top, &remote);
1896 if (!man_verify_unix_peer_uid_gid(man, man->connection.sd_cli))
1897 {
1898 sd_close(&man->connection.sd_cli);
1899 }
1900 }
1901 else
1902#endif
1903 {
1904 man->connection.sd_cli = socket_do_accept(man->connection.sd_top, &act, false);
1905 }
1906
1908 {
1909 man->connection.remote = act.dest;
1910
1912 {
1913#ifdef _WIN32
1914 man_stop_ne32(man);
1915#endif
1916 }
1917
1918 man_new_connection_post(man, "Client connected from");
1919 }
1920}
1921
1922static void
1924{
1925 struct gc_arena gc = gc_new();
1926
1927 /*
1928 * Initialize state
1929 */
1930 man->connection.state = MS_LISTEN;
1932
1933 /*
1934 * Initialize listening socket
1935 */
1937 {
1938#if UNIX_SOCK_SUPPORT
1939 if (man->settings.flags & MF_UNIX_SOCK)
1940 {
1942 man->connection.sd_top = create_socket_unix();
1943 socket_bind_unix(man->connection.sd_top, &man->settings.local_unix, "MANAGEMENT");
1944 }
1945 else
1946#endif
1947 {
1949 socket_bind(man->connection.sd_top, man->settings.local, man->settings.local->ai_family,
1950 "MANAGEMENT", false);
1951 }
1952
1953 /*
1954 * Listen for connection
1955 */
1956 if (listen(man->connection.sd_top, 1))
1957 {
1958 msg(M_ERR, "MANAGEMENT: listen() failed");
1959 }
1960
1961 /*
1962 * Set misc socket properties
1963 */
1965
1966#if UNIX_SOCK_SUPPORT
1967 if (man->settings.flags & MF_UNIX_SOCK)
1968 {
1969 msg(D_MANAGEMENT, "MANAGEMENT: unix domain socket listening on %s",
1970 sockaddr_unix_name(&man->settings.local_unix, "NULL"));
1971 }
1972 else
1973#endif
1974 {
1975 const struct sockaddr *man_addr = man->settings.local->ai_addr;
1976 struct sockaddr_storage addr;
1977 socklen_t addrlen = sizeof(addr);
1978 if (!getsockname(man->connection.sd_top, (struct sockaddr *)&addr, &addrlen))
1979 {
1980 man_addr = (struct sockaddr *)&addr;
1981 }
1982 else
1983 {
1984 msg(M_WARN | M_ERRNO, "Failed to get the management socket address");
1985 }
1986 msg(D_MANAGEMENT, "MANAGEMENT: TCP Socket listening on %s",
1987 print_sockaddr(man_addr, &gc));
1988 }
1989 }
1990
1991#ifdef _WIN32
1992 man_start_ne32(man);
1993#endif
1994
1995 gc_free(&gc);
1996}
1997
1998static void
2000{
2001 struct gc_arena gc = gc_new();
2002 int status;
2003 int signal_received = 0;
2004
2005 /*
2006 * Initialize state
2007 */
2010
2011#if UNIX_SOCK_SUPPORT
2012 if (man->settings.flags & MF_UNIX_SOCK)
2013 {
2014 man->connection.sd_cli = create_socket_unix();
2015 status = socket_connect_unix(man->connection.sd_cli, &man->settings.local_unix);
2016 if (!status && !man_verify_unix_peer_uid_gid(man, man->connection.sd_cli))
2017 {
2018#ifdef EPERM
2019 status = EPERM;
2020#else
2021 status = 1;
2022#endif
2023 sd_close(&man->connection.sd_cli);
2024 }
2025 }
2026 else
2027#endif
2028 {
2030 status = openvpn_connect(man->connection.sd_cli, man->settings.local->ai_addr, 5,
2031 &signal_received);
2032 }
2033
2034 if (signal_received)
2035 {
2036 throw_signal(signal_received);
2037 goto done;
2038 }
2039
2040 if (status)
2041 {
2042#if UNIX_SOCK_SUPPORT
2043 if (man->settings.flags & MF_UNIX_SOCK)
2044 {
2045 msg(D_LINK_ERRORS | M_ERRNO, "MANAGEMENT: connect to unix socket %s failed",
2046 sockaddr_unix_name(&man->settings.local_unix, "NULL"));
2047 }
2048 else
2049#endif
2050 {
2051 msg(D_LINK_ERRORS | M_ERRNO, "MANAGEMENT: connect to %s failed",
2052 print_sockaddr(man->settings.local->ai_addr, &gc));
2053 }
2054 throw_signal_soft(SIGTERM, "management-connect-failed");
2055 goto done;
2056 }
2057
2058 man_new_connection_post(man, "Connected to management server at");
2059
2060done:
2061 gc_free(&gc);
2062}
2063
2064static void
2065man_reset_client_socket(struct management *man, const bool exiting)
2066{
2068 {
2069 man_bytecount_stop(man);
2070#ifdef _WIN32
2071 man_stop_ne32(man);
2072#endif
2079 msg(D_MANAGEMENT, "MANAGEMENT: Client disconnected");
2080 }
2081 if (!exiting)
2082 {
2084 {
2085 ssl_purge_auth(false);
2086 (void)ssl_clean_auth_token();
2087 }
2088
2089 if (man->settings.flags & MF_SIGNAL)
2090 {
2091 int mysig = man_mod_signal(man, SIGUSR1);
2092 if (mysig >= 0)
2093 {
2094 msg(D_MANAGEMENT, "MANAGEMENT: Triggering management signal");
2095 throw_signal_soft(mysig, "management-disconnect");
2096 }
2097 }
2098
2100 {
2101 msg(D_MANAGEMENT, "MANAGEMENT: Triggering management exit");
2102 throw_signal_soft(SIGTERM, "management-exit");
2103 }
2104 else
2105 {
2106 man_listen(man);
2107 }
2108 }
2109}
2110
2111static void
2112man_process_command(struct management *man, const char *line)
2113{
2114 struct gc_arena gc = gc_new();
2115 struct status_output *so;
2116 int nparms;
2117 char *parms[MAX_PARMS + 1];
2118
2119 CLEAR(parms);
2120 so = status_open(NULL, 0, -1, &man->persist.vout, 0);
2122
2123 if (man_password_needed(man))
2124 {
2125 man_check_password(man, line);
2126 }
2127 else
2128 {
2129 nparms = parse_line(line, parms, MAX_PARMS, "TCP", 0, M_CLIENT, &gc);
2130 if (parms[0] && streq(parms[0], "password"))
2131 {
2132 msg(D_MANAGEMENT_DEBUG, "MANAGEMENT: CMD 'password [...]'");
2133 }
2134 else if (!streq(line, "load-stats"))
2135 {
2136 msg(D_MANAGEMENT_DEBUG, "MANAGEMENT: CMD '%s'", line);
2137 }
2138
2139#if 0
2140 /* DEBUGGING -- print args */
2141 {
2142 int i;
2143 for (i = 0; i < nparms; ++i)
2144 {
2145 msg(M_INFO, "[%d] '%s'", i, parms[i]);
2146 }
2147 }
2148#endif
2149
2150 if (nparms > 0)
2151 {
2152 man_dispatch_command(man, so, (const char **)parms, nparms);
2153 }
2154 }
2155
2156 CLEAR(parms);
2157 status_close(so);
2158 gc_free(&gc);
2159}
2160
2161static bool
2162man_io_error(struct management *man, const char *prefix)
2163{
2164 bool crt_error = false;
2165 int err = openvpn_errno_maybe_crt(&crt_error);
2166
2167 if (!ignore_sys_error(err, crt_error))
2168 {
2169 struct gc_arena gc = gc_new();
2170 msg(D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s", prefix, strerror(err));
2171 gc_free(&gc);
2172 return true;
2173 }
2174 else
2175 {
2176 return false;
2177 }
2178}
2179
2180#ifdef TARGET_ANDROID
2181static ssize_t
2182man_send_with_fd(int fd, void *ptr, size_t nbytes, int flags, int sendfd)
2183{
2184 struct msghdr msg = { 0 };
2185 struct iovec iov[1];
2186
2187 union
2188 {
2189 struct cmsghdr cm;
2190 char control[CMSG_SPACE(sizeof(int))];
2191 } control_un;
2192 struct cmsghdr *cmptr;
2193
2194 msg.msg_control = control_un.control;
2195 msg.msg_controllen = sizeof(control_un.control);
2196
2197 cmptr = CMSG_FIRSTHDR(&msg);
2198 cmptr->cmsg_len = CMSG_LEN(sizeof(int));
2199 cmptr->cmsg_level = SOL_SOCKET;
2200 cmptr->cmsg_type = SCM_RIGHTS;
2201 *((int *)CMSG_DATA(cmptr)) = sendfd;
2202
2203 msg.msg_name = NULL;
2204 msg.msg_namelen = 0;
2205
2206 iov[0].iov_base = ptr;
2207 iov[0].iov_len = nbytes;
2208 msg.msg_iov = iov;
2209 msg.msg_iovlen = 1;
2210
2211 return (sendmsg(fd, &msg, flags));
2212}
2213
2214static ssize_t
2215man_recv_with_fd(int fd, void *ptr, size_t nbytes, int flags, int *recvfd)
2216{
2217 struct msghdr msghdr = { 0 };
2218 struct iovec iov[1];
2219 ssize_t n;
2220
2221 union
2222 {
2223 struct cmsghdr cm;
2224 char control[CMSG_SPACE(sizeof(int))];
2225 } control_un;
2226 struct cmsghdr *cmptr;
2227
2228 msghdr.msg_control = control_un.control;
2229 msghdr.msg_controllen = sizeof(control_un.control);
2230
2231 msghdr.msg_name = NULL;
2232 msghdr.msg_namelen = 0;
2233
2234 iov[0].iov_base = ptr;
2235 iov[0].iov_len = nbytes;
2236 msghdr.msg_iov = iov;
2237 msghdr.msg_iovlen = 1;
2238
2239 if ((n = recvmsg(fd, &msghdr, flags)) <= 0)
2240 {
2241 return (n);
2242 }
2243
2244 if ((cmptr = CMSG_FIRSTHDR(&msghdr)) != NULL && cmptr->cmsg_len == CMSG_LEN(sizeof(int)))
2245 {
2246 if (cmptr->cmsg_level != SOL_SOCKET)
2247 {
2248 msg(M_ERR, "control level != SOL_SOCKET");
2249 }
2250 if (cmptr->cmsg_type != SCM_RIGHTS)
2251 {
2252 msg(M_ERR, "control type != SCM_RIGHTS");
2253 }
2254 *recvfd = *((int *)CMSG_DATA(cmptr));
2255 }
2256 else
2257 {
2258 *recvfd = -1; /* descriptor was not passed */
2259 }
2260 return (n);
2261}
2262
2263/*
2264 * The android control method will instruct the GUI part of openvpn to do
2265 * the route/ifconfig/open tun command. See doc/android.txt for details.
2266 */
2267bool
2268management_android_control(struct management *man, const char *command, const char *msg)
2269{
2270 if (!man)
2271 {
2272 msg(M_FATAL, "Required management interface not available.");
2273 }
2274 struct user_pass up;
2275 CLEAR(up);
2276 strncpy(up.username, msg, sizeof(up.username) - 1);
2277
2279 return strcmp("ok", up.password) == 0;
2280}
2281
2282/*
2283 * In Android 4.4 it is not possible to open a new tun device and then close the
2284 * old tun device without breaking the whole VPNService stack until the device
2285 * is rebooted. This management method ask the UI what method should be taken to
2286 * ensure the optimal solution for the situation
2287 */
2288int
2289managment_android_persisttun_action(struct management *man)
2290{
2291 struct user_pass up;
2292 CLEAR(up);
2293 strcpy(up.username, "tunmethod");
2295 (void *)0);
2296 if (!strcmp("NOACTION", up.password))
2297 {
2298 return ANDROID_KEEP_OLD_TUN;
2299 }
2300 else if (!strcmp("OPEN_BEFORE_CLOSE", up.password))
2301 {
2302 return ANDROID_OPEN_BEFORE_CLOSE;
2303 }
2304 else
2305 {
2306 msg(M_ERR, "Got unrecognised '%s' from management for PERSIST_TUN_ACTION query",
2307 up.password);
2308 }
2309
2310 ASSERT(0);
2311 return ANDROID_OPEN_BEFORE_CLOSE;
2312}
2313
2314
2315#endif /* ifdef TARGET_ANDROID */
2316
2317#if defined(__GNUC__) || defined(__clang__)
2318#pragma GCC diagnostic push
2319#pragma GCC diagnostic ignored "-Wconversion"
2320#endif
2321
2322static int
2324{
2325 /*
2326 * read command line from socket
2327 */
2328 unsigned char buf[256];
2329 int len = 0;
2330
2331#ifdef TARGET_ANDROID
2332 int fd;
2333 len = man_recv_with_fd(man->connection.sd_cli, buf, sizeof(buf), MSG_NOSIGNAL, &fd);
2334 if (fd >= 0)
2335 {
2336 man->connection.lastfdreceived = fd;
2337 }
2338#else /* ifdef TARGET_ANDROID */
2339 len = recv(man->connection.sd_cli, (void *)buf, sizeof(buf), MSG_NOSIGNAL);
2340#endif
2341
2342 if (len == 0)
2343 {
2344 man_reset_client_socket(man, false);
2345 }
2346 else if (len > 0)
2347 {
2348 bool processed_command = false;
2349
2350 ASSERT(len <= (int)sizeof(buf));
2351 command_line_add(man->connection.in, buf, (size_t)len);
2352
2353 /*
2354 * Reset output object
2355 */
2357
2358 /*
2359 * process command line if complete
2360 */
2361 {
2362 const char *line;
2363 while ((line = command_line_get(man->connection.in)))
2364 {
2365 if (man->connection.in_extra)
2366 {
2367 if (!strcmp(line, "END"))
2368 {
2369 in_extra_dispatch(man);
2370 }
2371 else
2372 {
2374 }
2375 }
2376 else
2377 {
2378 man_process_command(man, (char *)line);
2379 }
2380 if (man->connection.halt)
2381 {
2382 break;
2383 }
2385 processed_command = true;
2386 }
2387 }
2388
2389 /*
2390 * Reset output state to MS_CC_WAIT_(READ|WRITE)
2391 */
2392 if (man->connection.halt)
2393 {
2394 man_reset_client_socket(man, false);
2395 len = 0;
2396 }
2397 else
2398 {
2399 if (processed_command)
2400 {
2401 man_prompt(man);
2402 }
2404 }
2405 }
2406 else /* len < 0 */
2407 {
2408 if (man_io_error(man, "recv"))
2409 {
2410 man_reset_client_socket(man, false);
2411 }
2412 }
2413 return len;
2414}
2415
2416static int
2418{
2419 const int size_hint = 1024;
2420 int sent = 0;
2421 const struct buffer *buf;
2422
2423 buffer_list_aggregate(man->connection.out, size_hint);
2424 buf = buffer_list_peek(man->connection.out);
2425 if (buf && BLEN(buf))
2426 {
2427 const int len = min_int(size_hint, BLEN(buf));
2428#ifdef TARGET_ANDROID
2429 if (man->connection.fdtosend > 0)
2430 {
2431 sent = man_send_with_fd(man->connection.sd_cli, BPTR(buf), len, MSG_NOSIGNAL,
2432 man->connection.fdtosend);
2433 man->connection.fdtosend = -1;
2434 }
2435 else
2436#endif
2437 sent = send(man->connection.sd_cli, (const void *)BPTR(buf), len, MSG_NOSIGNAL);
2438 if (sent >= 0)
2439 {
2440 buffer_list_advance(man->connection.out, sent);
2441 }
2442 else if (sent < 0)
2443 {
2444 if (man_io_error(man, "send"))
2445 {
2447 }
2448 }
2449 }
2450
2451 /*
2452 * Reset output state to MS_CC_WAIT_(READ|WRITE)
2453 */
2455
2456 return sent;
2457}
2458
2459#if defined(__GNUC__) || defined(__clang__)
2460#pragma GCC diagnostic pop
2461#endif
2462
2463static void
2465{
2466 CLEAR(*mc);
2467
2468 /* set initial state */
2469 mc->state = MS_INITIAL;
2470
2471 /* clear socket descriptors */
2472 mc->sd_top = SOCKET_UNDEFINED;
2473 mc->sd_cli = SOCKET_UNDEFINED;
2474}
2475
2476static void
2477man_persist_init(struct management *man, const int log_history_cache, const int echo_buffer_size,
2478 const int state_buffer_size)
2479{
2480 struct man_persist *mp = &man->persist;
2481 if (!mp->defined)
2482 {
2483 CLEAR(*mp);
2484
2485 /* initialize log history store */
2486 mp->log = log_history_init(log_history_cache);
2487
2488 /*
2489 * Initialize virtual output object, so that functions
2490 * which write to a virtual_output object can be redirected
2491 * here to the management object.
2492 */
2494 mp->vout.arg = man;
2497
2498 /*
2499 * Initialize --echo list
2500 */
2501 man->persist.echo = log_history_init(echo_buffer_size);
2502
2503 /*
2504 * Initialize --state list
2505 */
2506 man->persist.state = log_history_init(state_buffer_size);
2507
2508 mp->defined = true;
2509 }
2510}
2511
2512static void
2514{
2515 if (mp->log)
2516 {
2519 }
2520
2521 if (mp->echo)
2522 {
2524 }
2525
2526 if (mp->state)
2527 {
2529 }
2530
2531 CLEAR(*mp);
2532}
2533
2534static void
2535man_settings_init(struct man_settings *ms, const char *addr, const char *port,
2536 const char *pass_file, const char *client_user, const char *client_group,
2537 const int log_history_cache, const int echo_buffer_size,
2538 const int state_buffer_size, const int remap_sigusr1, const unsigned int flags)
2539{
2540 if (!ms->defined)
2541 {
2542 CLEAR(*ms);
2543
2544 ms->flags = flags;
2545 ms->client_uid = -1;
2546 ms->client_gid = -1;
2547
2548 /*
2549 * Get username/password
2550 */
2551 if (pass_file)
2552 {
2553 get_user_pass(&ms->up, pass_file, "Management", GET_USER_PASS_PASSWORD_ONLY);
2554 }
2555
2556 /*
2557 * lookup client UID/GID if specified
2558 */
2559 if (client_user)
2560 {
2561 struct platform_state_user s;
2562 platform_user_get(client_user, &s);
2564 msg(D_MANAGEMENT, "MANAGEMENT: client_uid=%d", ms->client_uid);
2565 ASSERT(ms->client_uid >= 0);
2566 }
2567 if (client_group)
2568 {
2569 struct platform_state_group s;
2570 platform_group_get(client_group, &s);
2572 msg(D_MANAGEMENT, "MANAGEMENT: client_gid=%d", ms->client_gid);
2573 ASSERT(ms->client_gid >= 0);
2574 }
2575
2576#if UNIX_SOCK_SUPPORT
2577 if (ms->flags & MF_UNIX_SOCK)
2578 {
2579 sockaddr_unix_init(&ms->local_unix, addr);
2580 }
2581 else
2582#endif
2583 {
2584 /*
2585 * Run management over tunnel, or
2586 * separate channel?
2587 */
2588 if (streq(addr, "tunnel") && !(flags & MF_CONNECT_AS_CLIENT))
2589 {
2590 ms->management_over_tunnel = true;
2591 }
2592 else
2593 {
2594 int status;
2596
2597 if (!(flags & MF_CONNECT_AS_CLIENT))
2598 {
2599 resolve_flags |= GETADDR_PASSIVE;
2600 }
2601
2602 status =
2603 openvpn_getaddrinfo(resolve_flags, addr, port, 0, NULL, AF_UNSPEC, &ms->local);
2604 ASSERT(status == 0);
2605 }
2606 }
2607
2608 /*
2609 * Log history and echo buffer may need to be resized
2610 */
2611 ms->log_history_cache = log_history_cache;
2612 ms->echo_buffer_size = echo_buffer_size;
2613 ms->state_buffer_size = state_buffer_size;
2614
2615 /*
2616 * Set remap sigusr1 flags
2617 */
2618 if (remap_sigusr1 == SIGHUP)
2619 {
2621 }
2622 else if (remap_sigusr1 == SIGTERM)
2623 {
2625 }
2626
2627 ms->defined = true;
2628 }
2629}
2630
2631static void
2633{
2634 if (ms->local)
2635 {
2636 freeaddrinfo(ms->local);
2637 }
2638 CLEAR(*ms);
2639}
2640
2641
2642static void
2644{
2645 if (man->connection.state == MS_INITIAL)
2646 {
2647#ifdef _WIN32
2648 /*
2649 * This object is a sort of TCP/IP helper
2650 * for Windows.
2651 */
2653#endif
2654
2655 /*
2656 * Allocate helper objects for command line input and
2657 * command output from/to the socket.
2658 */
2659 man->connection.in = command_line_new(1024);
2661
2662 /*
2663 * Initialize event set for standalone usage, when we are
2664 * running outside of the primary event loop.
2665 */
2666 {
2667 int maxevents = 1;
2668 man->connection.es = event_set_init(&maxevents, EVENT_METHOD_FAST);
2669 }
2670
2671 man->connection.client_version = 1; /* default version */
2672
2673 /*
2674 * Listen/connect socket
2675 */
2677 {
2678 man_connect(man);
2679 }
2680 else
2681 {
2682 man_listen(man);
2683 }
2684 }
2685}
2686
2687static void
2689{
2690 struct man_connection *mc = &man->connection;
2691
2692 event_free(mc->es);
2693#ifdef _WIN32
2695#endif
2696 if (socket_defined(mc->sd_top))
2697 {
2698 man_close_socket(man, mc->sd_top);
2700 }
2701 if (socket_defined(mc->sd_cli))
2702 {
2703 man_close_socket(man, mc->sd_cli);
2704 }
2705
2706 command_line_free(mc->in);
2707 buffer_list_free(mc->out);
2708
2710
2714}
2715
2716struct management *
2718{
2719 struct management *man;
2720 ALLOC_OBJ_CLEAR(man, struct management);
2721
2724
2726
2727 return man;
2728}
2729
2730bool
2731management_open(struct management *man, const char *addr, const char *port, const char *pass_file,
2732 const char *client_user, const char *client_group, const int log_history_cache,
2733 const int echo_buffer_size, const int state_buffer_size, const int remap_sigusr1,
2734 const unsigned int flags)
2735{
2736 bool ret = false;
2737
2738 /*
2739 * Save the settings only if they have not
2740 * been saved before.
2741 */
2742 man_settings_init(&man->settings, addr, port, pass_file, client_user, client_group,
2743 log_history_cache, echo_buffer_size, state_buffer_size, remap_sigusr1, flags);
2744
2745 /*
2746 * The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
2747 * but may be changed here. Ditto for echo and state buffers.
2748 */
2752
2753 /*
2754 * If connection object is uninitialized and we are not doing
2755 * over-the-tunnel management, then open (listening) connection.
2756 */
2757 if (man->connection.state == MS_INITIAL)
2758 {
2760 {
2762 ret = true;
2763 }
2764 }
2765
2766 return ret;
2767}
2768
2769void
2771{
2772 man_output_list_push_finalize(man); /* flush output queue */
2776 free(man);
2777}
2778
2779void
2781{
2782 man->persist.standalone_disabled = true;
2783 man->persist.callback = *cb;
2784}
2785
2786void
2788{
2789 man->persist.standalone_disabled = false;
2790 man->persist.hold_release = false;
2791 CLEAR(man->persist.callback);
2792 man_output_list_push_finalize(man); /* flush output queue */
2793}
2794
2795void
2796management_set_state(struct management *man, const int state, const char *detail,
2797 const in_addr_t *tun_local_ip, const struct in6_addr *tun_local_ip6,
2798 const struct openvpn_sockaddr *local, const struct openvpn_sockaddr *remote)
2799{
2800 if (man->persist.state
2801 && (!(man->settings.flags & MF_SERVER) || state < OPENVPN_STATE_CLIENT_BASE))
2802 {
2803 struct gc_arena gc = gc_new();
2804 struct log_entry e;
2805 const char *out = NULL;
2806
2807 update_time();
2808 CLEAR(e);
2809 e.timestamp = now;
2810 e.u.state = state;
2811 e.string = detail;
2812 if (tun_local_ip)
2813 {
2814 e.local_ip = *tun_local_ip;
2815 }
2816 if (tun_local_ip6)
2817 {
2818 e.local_ip6 = *tun_local_ip6;
2819 }
2820 if (local)
2821 {
2822 e.local_sock = *local;
2823 }
2824 if (remote)
2825 {
2826 e.remote_sock = *remote;
2827 }
2828
2829 log_history_add(man->persist.state, &e);
2830
2831 if (man->connection.state_realtime)
2832 {
2833 out = log_entry_print(&e,
2837 &gc);
2838 }
2839
2840 if (out)
2841 {
2842 man_output_list_push(man, out);
2843 }
2844
2845 gc_free(&gc);
2846 }
2847}
2848
2849static bool
2850env_filter_match(const char *env_str, const int env_filter_level)
2851{
2852 static const char *env_names[] = { "username=",
2853 "password=",
2854 "X509_0_CN=",
2855 "tls_serial_",
2856 "untrusted_ip=",
2857 "ifconfig_local=",
2858 "ifconfig_netmask=",
2859 "daemon_start_time=",
2860 "daemon_pid=",
2861 "dev=",
2862 "ifconfig_pool_remote_ip=",
2863 "ifconfig_pool_netmask=",
2864 "time_duration=",
2865 "bytes_sent=",
2866 "bytes_received=",
2867 "session_id=",
2868 "session_state=" };
2869
2870 if (env_filter_level == 0)
2871 {
2872 return true;
2873 }
2874 else if (env_filter_level <= 1 && !strncmp(env_str, "X509_", 5))
2875 {
2876 return true;
2877 }
2878 else if (env_filter_level <= 2)
2879 {
2880 size_t i;
2881 for (i = 0; i < SIZE(env_names); ++i)
2882 {
2883 const char *en = env_names[i];
2884 const size_t len = strlen(en);
2885 if (!strncmp(env_str, en, len))
2886 {
2887 return true;
2888 }
2889 }
2890 return false;
2891 }
2892 return false;
2893}
2894
2895static void
2896man_output_env(const struct env_set *es, const bool tail, const int env_filter_level,
2897 const char *prefix)
2898{
2899 if (es)
2900 {
2901 struct env_item *e;
2902 for (e = es->list; e != NULL; e = e->next)
2903 {
2904 if (e->string && (!env_filter_level || env_filter_match(e->string, env_filter_level)))
2905 {
2906 msg(M_CLIENT, ">%s:ENV,%s", prefix, e->string);
2907 }
2908 }
2909 }
2910 if (tail)
2911 {
2912 msg(M_CLIENT, ">%s:ENV,END", prefix);
2913 }
2914}
2915
2916static void
2917man_output_extra_env(struct management *man, const char *prefix)
2918{
2919 struct gc_arena gc = gc_new();
2920 struct env_set *es = env_set_create(&gc);
2921 if (man->persist.callback.n_clients)
2922 {
2923 const int nclients = (*man->persist.callback.n_clients)(man->persist.callback.arg);
2924 setenv_int(es, "n_clients", nclients);
2925 }
2926 man_output_env(es, false, man->connection.env_filter_level, prefix);
2927 gc_free(&gc);
2928}
2929
2930void
2931management_up_down(struct management *man, const char *updown, const struct env_set *es)
2932{
2933 if (man->settings.flags & MF_UP_DOWN)
2934 {
2935 msg(M_CLIENT, ">UPDOWN:%s", updown);
2936 man_output_env(es, true, 0, "UPDOWN");
2937 }
2938}
2939
2940void
2941management_notify(struct management *man, const char *severity, const char *type, const char *text)
2942{
2943 msg(M_CLIENT, ">NOTIFY:%s,%s,%s", severity, type, text);
2944}
2945
2946void
2947management_notify_generic(struct management *man, const char *str)
2948{
2949 msg(M_CLIENT, "%s", str);
2950}
2951
2952static void
2954{
2955 char line[256];
2957 {
2958 const char *peer_info =
2959 (*man->persist.callback.get_peer_info)(man->persist.callback.arg, mdac->cid);
2960 if (peer_info)
2961 {
2962 struct buffer buf;
2963 buf_set_read(&buf, (const uint8_t *)peer_info, strlen(peer_info));
2964 while (buf_parse(&buf, '\n', line, sizeof(line)))
2965 {
2966 chomp(line);
2968 {
2969 msg(M_CLIENT, ">CLIENT:ENV,%s", line);
2970 }
2971 else
2972 {
2973 msg(D_MANAGEMENT, "validation failed on peer_info line received from client");
2974 }
2975 }
2976 }
2977 }
2978}
2979
2980void
2981management_notify_client_needing_auth(struct management *management, const unsigned int mda_key_id,
2982 struct man_def_auth_context *mdac, const struct env_set *es)
2983{
2984 if (!(mdac->flags & DAF_CONNECTION_CLOSED))
2985 {
2986 const char *mode = "CONNECT";
2987 if (mdac->flags & DAF_CONNECTION_ESTABLISHED)
2988 {
2989 mode = "REAUTH";
2990 }
2991 msg(M_CLIENT, ">CLIENT:%s,%lu,%u", mode, mdac->cid, mda_key_id);
2994 {
2996 }
2998 mdac->flags |= DAF_INITIAL_AUTH;
2999 }
3000}
3001
3002void
3004 const struct env_set *es, const char *response)
3005{
3006 struct gc_arena gc;
3007 if (management)
3008 {
3009 gc = gc_new();
3010
3011 msg(M_CLIENT, ">CLIENT:CR_RESPONSE,%lu,%u,%s", mdac->cid, mda_key_id, response);
3014 {
3016 }
3018 gc_free(&gc);
3019 }
3020}
3021
3022void
3024 const struct env_set *es)
3025{
3027 msg(M_CLIENT, ">CLIENT:ESTABLISHED,%lu", mdac->cid);
3030}
3031
3032void
3034 const struct env_set *es)
3035{
3036 if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED))
3037 {
3038 msg(M_CLIENT, ">CLIENT:DISCONNECT,%lu", mdac->cid);
3041 }
3042}
3043
3044void
3046 const struct mroute_addr *addr, const bool primary)
3047{
3048 struct gc_arena gc = gc_new();
3049 if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED))
3050 {
3051 msg(M_CLIENT, ">CLIENT:ADDRESS,%lu,%s,%d", mdac->cid,
3052 mroute_addr_print_ex(addr, MAPF_SUBNET, &gc), BOOL_CAST(primary));
3053 }
3054 gc_free(&gc);
3055}
3056
3057void
3058management_echo(struct management *man, const char *string, const bool pull)
3059{
3060 if (man->persist.echo)
3061 {
3062 struct gc_arena gc = gc_new();
3063 struct log_entry e;
3064 const char *out = NULL;
3065
3066 update_time();
3067 CLEAR(e);
3068 e.timestamp = now;
3069 e.string = string;
3070 e.u.intval = BOOL_CAST(pull);
3071
3072 log_history_add(man->persist.echo, &e);
3073
3074 if (man->connection.echo_realtime)
3075 {
3076 out = log_entry_print(&e,
3079 &gc);
3080 }
3081
3082 if (out)
3083 {
3084 man_output_list_push(man, out);
3085 }
3086
3087 gc_free(&gc);
3088 }
3089}
3090
3091void
3092management_post_tunnel_open(struct management *man, const in_addr_t tun_local_ip)
3093{
3094 /*
3095 * If we are running management over the tunnel,
3096 * this is the place to initialize the connection.
3097 */
3099 {
3100 /* listen on our local TUN/TAP IP address */
3101 struct in_addr ia;
3102 int ret;
3103 char buf[INET_ADDRSTRLEN];
3104
3105 ia.s_addr = htonl(tun_local_ip);
3106 inet_ntop(AF_INET, &ia, buf, sizeof(buf));
3107 ret =
3108 openvpn_getaddrinfo(GETADDR_PASSIVE, buf, NULL, 0, NULL, AF_INET, &man->settings.local);
3109 ASSERT(ret == 0);
3111 }
3112}
3113
3114void
3116{
3118 {
3120 }
3121}
3122
3123void
3124management_auth_failure(struct management *man, const char *type, const char *reason)
3125{
3126 if (reason)
3127 {
3128 msg(M_CLIENT, ">PASSWORD:Verification Failed: '%s' ['%s']", type, reason);
3129 }
3130 else
3131 {
3132 msg(M_CLIENT, ">PASSWORD:Verification Failed: '%s'", type);
3133 }
3134}
3135
3136void
3137management_auth_token(struct management *man, const char *token)
3138{
3139 msg(M_CLIENT, ">PASSWORD:Auth-Token:%s", token);
3140}
3141
3142static inline bool
3143man_persist_state(unsigned int *persistent, const int n)
3144{
3145 if (persistent)
3146 {
3147 if (*persistent == (unsigned int)n)
3148 {
3149 return false;
3150 }
3151 *persistent = n;
3152 }
3153 return true;
3154}
3155
3156#ifdef _WIN32
3157
3158void
3159management_socket_set(struct management *man, struct event_set *es, void *arg,
3160 unsigned int *persistent)
3161{
3162 if (man->connection.state != MS_INITIAL)
3163 {
3166
3167 switch (man->connection.state)
3168 {
3169 case MS_LISTEN:
3170 if (man_persist_state(persistent, 1))
3171 {
3172 event_ctl(es, ev, EVENT_READ, arg);
3173 }
3174 break;
3175
3176 case MS_CC_WAIT_READ:
3177 if (man_persist_state(persistent, 2))
3178 {
3179 event_ctl(es, ev, EVENT_READ, arg);
3180 }
3181 break;
3182
3183 case MS_CC_WAIT_WRITE:
3184 if (man_persist_state(persistent, 3))
3185 {
3186 event_ctl(es, ev, EVENT_READ | EVENT_WRITE, arg);
3187 }
3188 break;
3189
3190 default:
3191 ASSERT(0);
3192 }
3193 }
3194}
3195
3196void
3198{
3199 if (man->connection.state != MS_INITIAL)
3200 {
3201 long net_events;
3204
3205 if (net_events & FD_CLOSE)
3206 {
3207 man_reset_client_socket(man, false);
3208 }
3209 else
3210 {
3211 if (man->connection.state == MS_LISTEN)
3212 {
3213 if (net_events & FD_ACCEPT)
3214 {
3215 man_accept(man);
3217 }
3218 }
3219 else if (man->connection.state == MS_CC_WAIT_READ
3221 {
3222 if (net_events & FD_READ)
3223 {
3224 while (man_read(man) > 0)
3225 {
3226 }
3228 }
3229
3230 if (net_events & FD_WRITE)
3231 {
3232 int status;
3233 status = man_write(man);
3234 if (status < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
3235 {
3237 }
3238 }
3239 }
3240 }
3241 }
3242}
3243
3244#else /* ifdef _WIN32 */
3245
3246void
3247management_socket_set(struct management *man, struct event_set *es, void *arg,
3248 unsigned int *persistent)
3249{
3250 switch (man->connection.state)
3251 {
3252 case MS_LISTEN:
3253 if (man_persist_state(persistent, 1))
3254 {
3256 }
3257 break;
3258
3259 case MS_CC_WAIT_READ:
3260 if (man_persist_state(persistent, 2))
3261 {
3263 }
3264 break;
3265
3266 case MS_CC_WAIT_WRITE:
3267 if (man_persist_state(persistent, 3))
3268 {
3270 }
3271 break;
3272
3273 case MS_INITIAL:
3274 break;
3275
3276 default:
3277 ASSERT(0);
3278 }
3279}
3280
3281void
3282management_io(struct management *man)
3283{
3284 switch (man->connection.state)
3285 {
3286 case MS_LISTEN:
3287 man_accept(man);
3288 break;
3289
3290 case MS_CC_WAIT_READ:
3291 man_read(man);
3292 break;
3293
3294 case MS_CC_WAIT_WRITE:
3295 man_write(man);
3296 break;
3297
3298 case MS_INITIAL:
3299 break;
3300
3301 default:
3302 ASSERT(0);
3303 }
3304}
3305
3306#endif /* ifdef _WIN32 */
3307
3308static inline bool
3310{
3312}
3313
3314static bool
3315man_check_for_signals(volatile int *signal_received)
3316{
3317 if (signal_received)
3318 {
3319 get_signal(signal_received);
3320 if (*signal_received)
3321 {
3322 return true;
3323 }
3324 }
3325 return false;
3326}
3327
3328/*
3329 * Wait for socket I/O when outside primary event loop
3330 */
3331static int
3332man_block(struct management *man, volatile int *signal_received, const time_t expire)
3333{
3334 struct timeval tv;
3335 struct event_set_return esr;
3336 int status = -1;
3337
3338 if (man_standalone_ok(man))
3339 {
3340 /* expire time can be already overdue, for this case init zero
3341 * timeout to avoid waiting first time and exit loop early with
3342 * either obtained event or timeout.
3343 */
3344 tv.tv_usec = 0;
3345 tv.tv_sec = 0;
3346
3347 while (true)
3348 {
3350 management_socket_set(man, man->connection.es, NULL, NULL);
3351 if (man_check_for_signals(signal_received))
3352 {
3353 status = -1;
3354 break;
3355 }
3356 status = event_wait(man->connection.es, &tv, &esr, 1);
3357 update_time();
3358 if (man_check_for_signals(signal_received))
3359 {
3360 status = -1;
3361 break;
3362 }
3363
3364 if (status > 0)
3365 {
3366 break;
3367 }
3368 else if (expire && now >= expire)
3369 {
3370 /* set SIGINT signal if expiration time exceeded */
3371 status = 0;
3372 if (signal_received)
3373 {
3374 *signal_received = SIGINT;
3375 }
3376 break;
3377 }
3378
3379 /* wait one second more */
3380 tv.tv_sec = 1;
3381 tv.tv_usec = 0;
3382 }
3383 }
3384 return status;
3385}
3386
3387/*
3388 * Perform management socket output outside primary event loop
3389 */
3390static void
3391man_output_standalone(struct management *man, volatile int *signal_received)
3392{
3393 if (man_standalone_ok(man))
3394 {
3395 while (man->connection.state == MS_CC_WAIT_WRITE)
3396 {
3397 management_io(man);
3398 if (man->connection.state == MS_CC_WAIT_WRITE)
3399 {
3400 man_block(man, signal_received, 0);
3401 }
3402 if (signal_received && *signal_received)
3403 {
3404 break;
3405 }
3406 }
3407 }
3408}
3409
3410/*
3411 * Process management event loop outside primary event loop
3412 */
3413static int
3414man_standalone_event_loop(struct management *man, volatile int *signal_received,
3415 const time_t expire)
3416{
3417 int status = -1;
3418 if (man_standalone_ok(man))
3419 {
3420 status = man_block(man, signal_received, expire);
3421 if (status > 0)
3422 {
3423 management_io(man);
3424 }
3425 }
3426 return status;
3427}
3428
3429#define MWCC_PASSWORD_WAIT (1 << 0)
3430#define MWCC_HOLD_WAIT (1 << 1)
3431#define MWCC_OTHER_WAIT (1 << 2)
3432
3433/*
3434 * Block until client connects
3435 */
3436static void
3437man_wait_for_client_connection(struct management *man, volatile int *signal_received,
3438 const time_t expire, unsigned int flags)
3439{
3441 if (man->connection.state == MS_LISTEN)
3442 {
3443 if (flags & MWCC_PASSWORD_WAIT)
3444 {
3445 msg(D_MANAGEMENT, "Need password(s) from management interface, waiting...");
3446 }
3447 if (flags & MWCC_HOLD_WAIT)
3448 {
3449 msg(D_MANAGEMENT, "Need hold release from management interface, waiting...");
3450 }
3451 if (flags & MWCC_OTHER_WAIT)
3452 {
3453 msg(D_MANAGEMENT, "Need information from management interface, waiting...");
3454 }
3455 do
3456 {
3457 man_standalone_event_loop(man, signal_received, expire);
3458 if (signal_received && *signal_received)
3459 {
3460 break;
3461 }
3462 } while (man->connection.state == MS_LISTEN || man_password_needed(man));
3463 }
3464}
3465
3466/*
3467 * Process the management event loop for sec seconds
3468 */
3469void
3471{
3472 if (man_standalone_ok(man))
3473 {
3474 volatile int signal_received = 0;
3475 const bool standalone_disabled_save = man->persist.standalone_disabled;
3476 time_t expire = 0;
3477
3478 /* This is so M_CLIENT messages will be correctly passed through msg() */
3479 man->persist.standalone_disabled = false;
3480
3481 /* set expire time */
3482 update_time();
3483 if (sec >= 0)
3484 {
3485 expire = now + sec;
3486 }
3487
3488 /* if no client connection, wait for one */
3489 man_wait_for_client_connection(man, &signal_received, expire, 0);
3490 if (signal_received)
3491 {
3492 return;
3493 }
3494
3495 /* run command processing event loop */
3496 do
3497 {
3498 man_standalone_event_loop(man, &signal_received, expire);
3499 if (!signal_received)
3500 {
3501 man_check_for_signals(&signal_received);
3502 }
3503 if (signal_received)
3504 {
3505 return;
3506 }
3507 update_time();
3508 } while (expire && expire > now);
3509
3510 /* revert state */
3511 man->persist.standalone_disabled = standalone_disabled_save;
3512 }
3513 else if (sec > 0)
3514 {
3515 sleep(sec);
3516 }
3517}
3518
3519/*
3520 * Get a username/password from management channel in standalone mode.
3521 */
3522bool
3523management_query_user_pass(struct management *man, struct user_pass *up, const char *type,
3524 const unsigned int flags, const char *static_challenge)
3525{
3526 struct gc_arena gc = gc_new();
3527 bool ret = false;
3528
3529 if (man_standalone_ok(man))
3530 {
3531 volatile int signal_received = 0;
3532 const bool standalone_disabled_save = man->persist.standalone_disabled;
3533 struct buffer alert_msg = alloc_buf_gc(128, &gc);
3534 const char *alert_type = NULL;
3535 const char *prefix = NULL;
3536 unsigned int up_query_mode = 0;
3537 const char *sc = NULL;
3538 ret = true;
3539 /* This is so M_CLIENT messages will be correctly passed through msg() */
3540 man->persist.standalone_disabled = false;
3541 man->persist.special_state_msg = NULL;
3542
3543 CLEAR(man->connection.up_query);
3544
3545 if (flags & GET_USER_PASS_NEED_OK)
3546 {
3547 up_query_mode = UP_QUERY_NEED_OK;
3548 prefix = "NEED-OK";
3549 alert_type = "confirmation";
3550 }
3551 else if (flags & GET_USER_PASS_NEED_STR)
3552 {
3553 up_query_mode = UP_QUERY_NEED_STR;
3554 prefix = "NEED-STR";
3555 alert_type = "string";
3556 }
3557 else if (flags & GET_USER_PASS_PASSWORD_ONLY)
3558 {
3559 up_query_mode = UP_QUERY_PASS;
3560 prefix = "PASSWORD";
3561 alert_type = "password";
3562 }
3563 else
3564 {
3565 up_query_mode = UP_QUERY_USER_PASS;
3566 prefix = "PASSWORD";
3567 alert_type = "username/password";
3568 if (static_challenge)
3569 {
3571 }
3572 }
3573 buf_printf(&alert_msg, ">%s:Need '%s' %s", prefix, type, alert_type);
3574
3576 {
3577 buf_printf(&alert_msg, " MSG:%s", up->username);
3578 }
3579
3580 if (sc)
3581 {
3582 buf_printf(&alert_msg, " SC:%d,%s",
3585 sc);
3586 }
3587
3589 if (signal_received)
3590 {
3591 ret = false;
3592 }
3593
3594 if (ret)
3595 {
3596 man->persist.special_state_msg = BSTR(&alert_msg);
3597 msg(M_CLIENT, "%s", man->persist.special_state_msg);
3598
3599 /* tell command line parser which info we need */
3600 man->connection.up_query_mode = up_query_mode;
3601 man->connection.up_query_type = type;
3602
3603 /* run command processing event loop until we get our username/password/response */
3604 do
3605 {
3606 man_standalone_event_loop(man, &signal_received, 0);
3607 if (!signal_received)
3608 {
3609 man_check_for_signals(&signal_received);
3610 }
3611 if (signal_received)
3612 {
3613 ret = false;
3614 break;
3615 }
3616 } while (!man->connection.up_query.defined);
3617 }
3618
3619 /* revert state */
3620 man->connection.up_query_mode = UP_QUERY_DISABLED;
3621 man->connection.up_query_type = NULL;
3622 man->persist.standalone_disabled = standalone_disabled_save;
3623 man->persist.special_state_msg = NULL;
3624
3625 /* pass through blank passwords */
3626 if (!strcmp(man->connection.up_query.password, blank_up))
3627 {
3628 CLEAR(man->connection.up_query.password);
3629 }
3630
3631 /*
3632 * Transfer u/p to return object, zero any record
3633 * we hold in the management object.
3634 */
3635 if (ret)
3636 {
3637 /* preserve caller's settings */
3638 man->connection.up_query.nocache = up->nocache;
3639 *up = man->connection.up_query;
3640 }
3641 secure_memzero(&man->connection.up_query, sizeof(man->connection.up_query));
3642 }
3643
3644 gc_free(&gc);
3645 return ret;
3646}
3647
3648static int
3649management_query_multiline(struct management *man, const char *b64_data, const char *prompt,
3650 const char *cmd, int *state, struct buffer_list **input)
3651{
3652 struct gc_arena gc = gc_new();
3653 int ret = 0;
3654 volatile int signal_received = 0;
3655 struct buffer alert_msg = clear_buf();
3656 const bool standalone_disabled_save = man->persist.standalone_disabled;
3657 struct man_connection *mc = &man->connection;
3658
3659 if (man_standalone_ok(man))
3660 {
3661 /* This is so M_CLIENT messages will be correctly passed through msg() */
3662 man->persist.standalone_disabled = false;
3663 man->persist.special_state_msg = NULL;
3664
3665 *state = EKS_SOLICIT;
3666
3667 if (b64_data)
3668 {
3669 alert_msg = alloc_buf_gc(strlen(b64_data) + strlen(prompt) + 3, &gc);
3670 buf_printf(&alert_msg, ">%s:%s", prompt, b64_data);
3671 }
3672 else
3673 {
3674 alert_msg = alloc_buf_gc(strlen(prompt) + 3, &gc);
3675 buf_printf(&alert_msg, ">%s", prompt);
3676 }
3677
3678 man_wait_for_client_connection(man, &signal_received, 0, MWCC_OTHER_WAIT);
3679
3680 if (signal_received)
3681 {
3682 goto done;
3683 }
3684
3685 man->persist.special_state_msg = BSTR(&alert_msg);
3687
3688 /* run command processing event loop until we get our signature */
3689 do
3690 {
3691 man_standalone_event_loop(man, &signal_received, 0);
3692 if (!signal_received)
3693 {
3694 man_check_for_signals(&signal_received);
3695 }
3696 if (signal_received)
3697 {
3698 goto done;
3699 }
3700 } while (*state != EKS_READY);
3701
3702 ret = 1;
3703 }
3704
3705done:
3706 if (*state == EKS_READY && ret)
3707 {
3708 msg(M_CLIENT, "SUCCESS: %s command succeeded", cmd);
3709 }
3710 else if (*state == EKS_INPUT || *state == EKS_READY)
3711 {
3712 msg(M_CLIENT, "ERROR: %s command failed", cmd);
3713 }
3714
3715 /* revert state */
3716 man->persist.standalone_disabled = standalone_disabled_save;
3717 man->persist.special_state_msg = NULL;
3719 *state = EKS_UNDEF;
3720
3721 gc_free(&gc);
3722 return ret;
3723}
3724
3725static char *
3726/* returns allocated base64 signature */
3728 const char *prompt, const char *cmd, int *state,
3729 struct buffer_list **input)
3730{
3731 int ok;
3732 char *result = NULL;
3733 struct buffer *buf;
3734
3735 ok = management_query_multiline(man, b64_data, prompt, cmd, state, input);
3736 if (ok && buffer_list_defined(*input))
3737 {
3739 buf = buffer_list_peek(*input);
3740 if (buf && BLEN(buf) > 0)
3741 {
3742 result = (char *)malloc(BLEN(buf) + 1);
3744 memcpy(result, buf->data, BLEN(buf));
3745 result[BLEN(buf)] = '\0';
3746 }
3747 }
3748
3750 *input = NULL;
3751
3752 return result;
3753}
3754
3755static char *
3756/* returns allocated base64 signature */
3757management_query_multiline_flatten(struct management *man, const char *b64_data, const char *prompt,
3758 const char *cmd, int *state, struct buffer_list **input)
3759{
3760 int ok;
3761 char *result = NULL;
3762 struct buffer *buf;
3763
3764 ok = management_query_multiline(man, b64_data, prompt, cmd, state, input);
3765 if (ok && buffer_list_defined(*input))
3766 {
3768 buf = buffer_list_peek(*input);
3769 if (buf && BLEN(buf) > 0)
3770 {
3771 result = (char *)malloc(BLEN(buf) + 1);
3773 memcpy(result, buf->data, BLEN(buf));
3774 result[BLEN(buf)] = '\0';
3775 }
3776 }
3777
3779 *input = NULL;
3780
3781 return result;
3782}
3783
3784char *
3785/* returns allocated base64 signature */
3786management_query_pk_sig(struct management *man, const char *b64_data, const char *algorithm)
3787{
3788 const char *prompt = "PK_SIGN";
3789 const char *desc = "pk-sign";
3791
3792 if (man->connection.client_version <= 1)
3793 {
3794 prompt = "RSA_SIGN";
3795 desc = "rsa-sign";
3796 }
3797
3799 if (man->connection.client_version > 2)
3800 {
3801 buf_write(&buf_data, ",", (int)strlen(","));
3803 }
3804 char *ret = management_query_multiline_flatten(man, (char *)buf_bptr(&buf_data), prompt, desc,
3805 &man->connection.ext_key_state,
3806 &man->connection.ext_key_input);
3808 return ret;
3809}
3810
3811char *
3813{
3814 const char prompt_1[] = "NEED-CERTIFICATE:";
3815 struct buffer buf_prompt = alloc_buf(strlen(cert_name) + 20);
3817 buf_write(&buf_prompt, cert_name, strlen(cert_name) + 1); /* +1 for \0 */
3818
3819 char *result;
3821 management, NULL, (char *)buf_bptr(&buf_prompt), "certificate",
3822 &man->connection.ext_cert_state, &man->connection.ext_cert_input);
3824 return result;
3825}
3826
3827/*
3828 * Return true if management_hold() would block
3829 */
3830bool
3832{
3833 return (man->settings.flags & MF_HOLD) && !man->persist.hold_release && man_standalone_ok(man);
3834}
3835
3836/*
3837 * If the hold flag is enabled, hibernate until a management client releases the hold.
3838 * Return true if the caller should not sleep for an additional time interval.
3839 */
3840bool
3842{
3844 {
3845 volatile int signal_received = 0;
3846 const bool standalone_disabled_save = man->persist.standalone_disabled;
3847 struct gc_arena gc = gc_new();
3848
3850 false; /* This is so M_CLIENT messages will be correctly passed through msg() */
3851 man->persist.special_state_msg = NULL;
3853
3854 man_wait_for_client_connection(man, &signal_received, 0, MWCC_HOLD_WAIT);
3855
3856 if (!signal_received)
3857 {
3858 struct buffer out = alloc_buf_gc(128, &gc);
3859 buf_printf(&out, ">HOLD:Waiting for hold release:%d", holdtime);
3860 man->persist.special_state_msg = BSTR(&out);
3861 msg(M_CLIENT, "%s", man->persist.special_state_msg);
3862
3863 /* run command processing event loop until we get our username/password */
3864 do
3865 {
3866 man_standalone_event_loop(man, &signal_received, 0);
3867 if (!signal_received)
3868 {
3869 man_check_for_signals(&signal_received);
3870 }
3871 if (signal_received)
3872 {
3873 break;
3874 }
3875 } while (!man->persist.hold_release);
3876 }
3877
3878 /* revert state */
3879 man->persist.standalone_disabled = standalone_disabled_save;
3880 man->persist.special_state_msg = NULL;
3881 man->settings.mansig &= ~MANSIG_IGNORE_USR1_HUP;
3882
3883 gc_free(&gc);
3884 return true;
3885 }
3886 return false;
3887}
3888
3889/*
3890 * struct command_line
3891 */
3892
3893struct command_line *
3895{
3896 struct command_line *cl;
3897 ALLOC_OBJ_CLEAR(cl, struct command_line);
3898 cl->buf = alloc_buf(buf_len);
3899 cl->residual = alloc_buf(buf_len);
3900 return cl;
3901}
3902
3903void
3905{
3906 buf_clear(&cl->buf);
3907 buf_clear(&cl->residual);
3908}
3909
3910void
3912{
3913 if (!cl)
3914 {
3915 return;
3916 }
3918 free_buf(&cl->buf);
3919 free_buf(&cl->residual);
3920 free(cl);
3921}
3922
3923void
3924command_line_add(struct command_line *cl, const unsigned char *buf, const size_t len)
3925{
3926 for (size_t i = 0; i < len; ++i)
3927 {
3928 if (buf[i] && char_class(buf[i], (CC_PRINT | CC_NEWLINE)))
3929 {
3930 if (!buf_write_u8(&cl->buf, buf[i]))
3931 {
3932 buf_clear(&cl->buf);
3933 }
3934 }
3935 }
3936}
3937
3938const char *
3940{
3941 const char *ret = NULL;
3942
3943 int i = buf_substring_len(&cl->buf, '\n');
3944 if (i >= 0)
3945 {
3946 buf_copy_excess(&cl->residual, &cl->buf, i);
3947 buf_chomp(&cl->buf);
3948 ret = BSTR(&cl->buf);
3949 }
3950 return ret;
3951}
3952
3953void
3955{
3956 buf_clear(&cl->buf);
3957 buf_copy(&cl->buf, &cl->residual);
3958 buf_clear(&cl->residual);
3959}
3960
3961/*
3962 * struct log_entry
3963 */
3964
3965const char *
3966log_entry_print(const struct log_entry *e, unsigned int flags, struct gc_arena *gc)
3967{
3968 struct buffer out = alloc_buf_gc(ERR_BUF_SIZE, gc);
3969 if (flags & LOG_FATAL_NOTIFY)
3970 {
3971 buf_printf(&out, ">FATAL:");
3972 }
3973 if (flags & LOG_PRINT_LOG_PREFIX)
3974 {
3975 buf_printf(&out, ">LOG:");
3976 }
3977 if (flags & LOG_PRINT_ECHO_PREFIX)
3978 {
3979 buf_printf(&out, ">ECHO:");
3980 }
3981 if (flags & LOG_PRINT_STATE_PREFIX)
3982 {
3983 buf_printf(&out, ">STATE:");
3984 }
3985 if (flags & LOG_PRINT_INT_DATE)
3986 {
3987 buf_printf(&out, "%u,", (unsigned int)e->timestamp);
3988 }
3989 if (flags & LOG_PRINT_MSG_FLAGS)
3990 {
3991 buf_printf(&out, "%s,", msg_flags_string(e->u.msg_flags, gc));
3992 }
3993 if (flags & LOG_PRINT_STATE)
3994 {
3995 buf_printf(&out, "%s,", man_state_name(e->u.state));
3996 }
3997 if (flags & LOG_PRINT_INTVAL)
3998 {
3999 buf_printf(&out, "%d,", e->u.intval);
4000 }
4001 if (e->string)
4002 {
4003 buf_printf(&out, "%s", e->string);
4004 }
4005 if (flags & LOG_PRINT_LOCAL_IP)
4006 {
4007 buf_printf(&out, ",%s", print_in_addr_t(e->local_ip, IA_EMPTY_IF_UNDEF, gc));
4008 }
4009 if (flags & LOG_PRINT_REMOTE_IP)
4010 {
4011 buf_printf(&out, ",%s",
4012 (!addr_defined(&e->remote_sock)
4013 ? ","
4014 : print_sockaddr_ex(&e->remote_sock.addr.sa, ",",
4016 buf_printf(&out, ",%s",
4017 (!addr_defined(&e->local_sock)
4018 ? ","
4019 : print_sockaddr_ex(&e->local_sock.addr.sa, ",",
4021 }
4022 if (flags & LOG_PRINT_LOCAL_IP && !IN6_IS_ADDR_UNSPECIFIED(&e->local_ip6))
4023 {
4024 buf_printf(&out, ",%s", print_in6_addr(e->local_ip6, IA_EMPTY_IF_UNDEF, gc));
4025 }
4026 if (flags & LOG_ECHO_TO_LOG)
4027 {
4028 msg(D_MANAGEMENT, "MANAGEMENT: %s", BSTR(&out));
4029 }
4030 if (flags & LOG_PRINT_CRLF)
4031 {
4032 buf_printf(&out, "\r\n");
4033 }
4034 return BSTR(&out);
4035}
4036
4037static void
4039{
4040 /* Cast away constness of const char* */
4041 free((char *)e->string);
4042 CLEAR(*e);
4043}
4044
4045/*
4046 * struct log_history
4047 */
4048
4049static inline int
4050log_index(const struct log_history *h, int i)
4051{
4052 return modulo_add(h->base, i, h->capacity);
4053}
4054
4055static void
4057{
4058 CLEAR(*h);
4059 h->capacity = capacity;
4061}
4062
4063struct log_history *
4065{
4066 struct log_history *h;
4067 ASSERT(capacity > 0);
4068 ALLOC_OBJ(h, struct log_history);
4070 return h;
4071}
4072
4073static void
4075{
4076 int i;
4077 for (i = 0; i < h->size; ++i)
4078 {
4080 }
4081 free(h->array);
4082}
4083
4084void
4086{
4088 free(h);
4089}
4090
4091void
4092log_history_add(struct log_history *h, const struct log_entry *le)
4093{
4094 struct log_entry *e;
4095 ASSERT(h->size >= 0 && h->size <= h->capacity);
4096 if (h->size == h->capacity)
4097 {
4098 e = &h->array[h->base];
4100 h->base = log_index(h, 1);
4101 }
4102 else
4103 {
4104 e = &h->array[log_index(h, h->size)];
4105 ++h->size;
4106 }
4107
4108 *e = *le;
4109 e->string = string_alloc(le->string, NULL);
4110}
4111
4112void
4113log_history_resize(struct log_history *h, const int capacity)
4114{
4115 if (capacity != h->capacity)
4116 {
4117 struct log_history newlog;
4118 int i;
4119
4120 ASSERT(capacity > 0);
4122
4123 for (i = 0; i < h->size; ++i)
4124 {
4125 log_history_add(&newlog, &h->array[log_index(h, i)]);
4126 }
4127
4129 *h = newlog;
4130 }
4131}
4132
4133const struct log_entry *
4134log_history_ref(const struct log_history *h, const int index)
4135{
4136 if (index >= 0 && index < h->size)
4137 {
4138 return &h->array[log_index(h, (h->size - 1) - index)];
4139 }
4140 else
4141 {
4142 return NULL;
4143 }
4144}
4145
4146void
4148{
4149 if (n < 0)
4150 {
4151 return;
4152 }
4153 else if (management)
4154 {
4156 }
4157 else
4158 {
4159#ifdef _WIN32
4160 win32_sleep(n);
4161#else
4162 if (n > 0)
4163 {
4164 sleep(n);
4165 }
4166#endif
4167 }
4168}
4169
4170void
4171management_check_bytecount_client(struct context *c, struct management *man, struct timeval *timeval)
4172{
4173 if (man->persist.callback.flags & MCF_SERVER)
4174 {
4175 return;
4176 }
4177
4179 {
4180 if (dco_enabled(&c->options))
4181 {
4182 if (dco_get_peer_stats(c, true) < 0)
4183 {
4184 return;
4185 }
4186 }
4187
4190 }
4191}
4192
4193void
4195{
4197 {
4198 return;
4199 }
4200
4201 struct timeval null;
4202 CLEAR(null);
4204 {
4205 /* fetch counters from dco */
4206 if (dco_enabled(&multi->top.options))
4207 {
4208 if (dco_get_peer_stats_multi(&multi->top.c1.tuntap->dco, true) < 0)
4209 {
4210 return;
4211 }
4212 }
4213
4214 /* iterate over peers and report counters for each connected peer */
4215 struct hash_iterator hi;
4216 struct hash_element *he;
4217 hash_iterator_init(multi->hash, &hi);
4218 while ((he = hash_iterator_next(&hi)))
4219 {
4220 struct multi_instance *mi = (struct multi_instance *)he->value;
4221 struct context_2 *c2 = &mi->context.c2;
4222
4224 {
4226 }
4227 }
4228 hash_iterator_free(&hi);
4229 }
4230}
4231
4232/* context_2 stats are reset on reconnect. Since client expects stats
4233 * to be preserved across reconnects, we need to save context_2
4234 * stats before tearing the tunnel down.
4235 */
4236void
4238{
4241
4242 /* no need to raise SIGUSR1 on error since we are already closing the instance */
4243 if (dco_enabled(&c->options) && (dco_get_peer_stats(c, false) == 0))
4244 {
4245 man->persist.bytes_in += c->c2.dco_read_bytes;
4247 }
4248}
4249
4250#else /* ifdef ENABLE_MANAGEMENT */
4251
4252#include "win32.h"
4253void
4254management_sleep(const int n)
4255{
4256#ifdef _WIN32
4257 win32_sleep(n);
4258#else
4259 if (n > 0)
4260 {
4261 sleep(n);
4262 }
4263#endif /* ifdef _WIN32 */
4264}
4265
4266#endif /* ENABLE_MANAGEMENT */
bool buffer_list_defined(const struct buffer_list *ol)
Checks if the list is valid and non-empty.
Definition buffer.c:1168
void buffer_list_advance(struct buffer_list *ol, int n)
Definition buffer.c:1311
void free_buf(struct buffer *buf)
Definition buffer.c:184
void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, const char *sep)
Aggregates as many buffers as possible from bl in a new buffer of maximum length max_len .
Definition buffer.c:1243
void buf_clear(struct buffer *buf)
Definition buffer.c:163
void buffer_list_reset(struct buffer_list *ol)
Empty the list ol and frees all the contained buffers.
Definition buffer.c:1174
void buffer_list_aggregate(struct buffer_list *bl, const size_t max)
Aggregates as many buffers as possible from bl in a new buffer of maximum length max_len .
Definition buffer.c:1288
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
struct buffer_list * buffer_list_new(void)
Allocate an empty buffer list of capacity max_size.
Definition buffer.c:1149
void chomp(char *str)
Definition buffer.c:614
struct buffer * buffer_list_peek(struct buffer_list *ol)
Retrieve the head buffer.
Definition buffer.c:1230
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
Definition buffer.c:1158
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:89
struct buffer alloc_buf(size_t size)
Definition buffer.c:63
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Definition buffer.c:825
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:649
void buffer_list_push(struct buffer_list *ol, const char *str)
Allocates and appends a new buffer containing str as data to ol.
Definition buffer.c:1189
void buf_chomp(struct buffer *buf)
Definition buffer.c:554
bool char_class(const unsigned char c, const unsigned int flags)
Definition buffer.c:876
int buf_substring_len(const struct buffer *buf, int delim)
Definition buffer.c:803
static uint8_t * buf_bptr(const struct buffer *buf)
Definition buffer.h:240
#define ALLOC_OBJ(dptr, type)
Definition buffer.h:1037
#define BSTR(buf)
Definition buffer.h:128
static struct buffer clear_buf(void)
Return an empty struct buffer.
Definition buffer.h:222
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Definition buffer.h:704
#define BPTR(buf)
Definition buffer.h:123
#define ALLOC_ARRAY_CLEAR(dptr, type, n)
Definition buffer.h:1058
static bool buf_copy_excess(struct buffer *dest, struct buffer *src, int len)
Definition buffer.h:739
#define CC_NEWLINE
newline
Definition buffer.h:881
static int buf_len(const struct buffer *buf)
Definition buffer.h:253
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Definition buffer.h:348
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition buffer.h:414
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:660
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition buffer.h:684
#define BLEN(buf)
Definition buffer.h:126
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:361
static void check_malloc_return(void *p)
Definition buffer.h:1085
static void gc_free(struct gc_arena *a)
Definition buffer.h:1015
#define CC_PRINT
printable (>= 32, != 127)
Definition buffer.h:875
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1042
static struct gc_arena gc_new(void)
Definition buffer.h:1007
uint64_t counter_type
Definition common.h:29
#define counter_format
Definition common.h:30
int memcmp_constant_time(const void *a, const void *b, size_t size)
As memcmp(), but constant-time.
static int dco_get_peer_stats_multi(dco_context_t *dco, const bool raise_sigusr1_on_err)
Definition dco.h:371
static int dco_get_peer_stats(struct context *c, const bool raise_sigusr1_on_err)
Definition dco.h:377
void setenv_int(struct env_set *es, const char *name, int value)
Definition env_set.c:291
struct env_set * env_set_create(struct gc_arena *gc)
Definition env_set.c:156
#define D_MANAGEMENT_DEBUG
Definition errlevel.h:137
#define M_INFO
Definition errlevel.h:54
#define D_MANAGEMENT
Definition errlevel.h:87
#define D_LINK_ERRORS
Definition errlevel.h:56
struct event_set * event_set_init(int *maxevents, unsigned int flags)
Definition event.c:1177
#define EVENT_METHOD_FAST
Definition event.h:82
static void event_free(struct event_set *es)
Definition event.h:162
static int event_wait(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
Definition event.h:189
#define EVENT_WRITE
Definition event.h:39
#define EVENT_READ
Definition event.h:38
static void event_reset(struct event_set *es)
Definition event.h:171
static void event_ctl(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
Definition event.h:183
void set_nonblock(socket_descriptor_t fd)
Definition fdmisc.c:68
counter_type link_write_bytes_global
Definition forward.c:50
counter_type link_read_bytes_global
Definition forward.c:49
void reset_coarse_timers(struct context *c)
Definition init.c:1320
static unsigned int min_uint(unsigned int x, unsigned int y)
Definition integer.h:66
static int min_int(int x, int y)
Definition integer.h:105
static int modulo_add(int x, int y, int mod)
Definition integer.h:185
static SERVICE_STATUS status
Definition interactive.c:51
bool event_timeout_trigger(struct event_timeout *et, struct timeval *tv, const int et_const_retry)
This is the principal function for testing and triggering recurring timers.
Definition interval.c:47
#define ETT_DEFAULT
Definition interval.h:222
static void event_timeout_init(struct event_timeout *et, interval_t n, const time_t last)
Initialises a timer struct.
Definition interval.h:172
static void event_timeout_clear(struct event_timeout *et)
Clears the timeout and reset all values to 0.
Definition interval.h:153
void hash_iterator_free(struct hash_iterator *hi)
Definition list.c:270
struct hash_element * hash_iterator_next(struct hash_iterator *hi)
Definition list.c:276
void hash_iterator_init(struct hash *hash, struct hash_iterator *hi)
Definition list.c:234
void management_pre_tunnel_close(struct management *man)
Definition manage.c:3115
void management_auth_failure(struct management *man, const char *type, const char *reason)
Definition manage.c:3124
void log_history_close(struct log_history *h)
Definition manage.c:4085
struct management * management
Definition manage.c:64
static void man_status(struct management *man, const int version, struct status_output *so)
Definition manage.c:503
static void man_up_finalize(struct management *man)
Definition manage.c:736
static bool man_io_error(struct management *man, const char *prefix)
Definition manage.c:2162
static void man_log(struct management *man, const char *parm)
Definition manage.c:715
static void man_reset_client_socket(struct management *man, const bool exiting)
Definition manage.c:2065
static void man_bytecount(struct management *man, const int update_seconds)
Definition manage.c:523
void management_notify_client_close(struct management *management, struct man_def_auth_context *mdac, const struct env_set *es)
Definition manage.c:3033
static void man_connect(struct management *man)
Definition manage.c:1999
#define MWCC_OTHER_WAIT
Definition manage.c:3431
static int man_write(struct management *man)
Definition manage.c:2417
void management_check_bytecount_server(struct multi_context *multi)
Definition manage.c:4194
static bool man_check_for_signals(volatile int *signal_received)
Definition manage.c:3315
static void man_bytecount_output_server(const counter_type bytes_in_total, const counter_type bytes_out_total, struct man_def_auth_context *mdac)
Definition manage.c:573
static void man_output_list_push(struct management *man, const char *str)
Definition manage.c:288
void management_socket_set(struct management *man, struct event_set *es, void *arg, unsigned int *persistent)
Definition manage.c:3159
void command_line_free(struct command_line *cl)
Definition manage.c:3911
static int man_block(struct management *man, volatile int *signal_received, const time_t expire)
Definition manage.c:3332
static void man_certificate(struct management *man)
Definition manage.c:1230
void command_line_next(struct command_line *cl)
Definition manage.c:3954
static void man_net(struct management *man)
Definition manage.c:840
void management_clear_callback(struct management *man)
Definition manage.c:2787
static void man_persist_init(struct management *man, const int log_history_cache, const int echo_buffer_size, const int state_buffer_size)
Definition manage.c:2477
char * management_query_cert(struct management *man, const char *cert_name)
Definition manage.c:3812
struct command_line * command_line_new(const size_t buf_len)
Definition manage.c:3894
static bool man_standalone_ok(const struct management *man)
Definition manage.c:3309
bool management_hold(struct management *man, int holdtime)
Definition manage.c:3841
static void man_settings_init(struct man_settings *ms, const char *addr, const char *port, const char *pass_file, const char *client_user, const char *client_group, const int log_history_cache, const int echo_buffer_size, const int state_buffer_size, const int remap_sigusr1, const unsigned int flags)
Definition manage.c:2535
static int log_index(const struct log_history *h, int i)
Definition manage.c:4050
static void man_connection_clear(struct man_connection *mc)
Definition manage.c:2464
#define AF_DID_RESET
static void man_start_ne32(struct management *man)
Definition manage.c:1753
static void man_connection_settings_reset(struct management *man)
Definition manage.c:1781
static void man_help(void)
Definition manage.c:72
static void man_update_io_state(struct management *man)
Definition manage.c:249
static void man_bytecount_stop(struct management *man)
Definition manage.c:516
static void man_check_password(struct management *man, const char *line)
Definition manage.c:215
static bool man_persist_state(unsigned int *persistent, const int n)
Definition manage.c:3143
static bool man_need(struct management *man, const char **p, const int n, unsigned int flags)
Checks if the correct number of arguments to a management command are present and otherwise prints an...
Definition manage.c:1272
static void man_connection_init(struct management *man)
Definition manage.c:2643
static bool env_filter_match(const char *env_str, const int env_filter_level)
Definition manage.c:2850
static void man_client_pending_auth(struct management *man, const char *cid_str, const char *kid_str, const char *extra, const char *timeout_str)
Will send a notification to the client that succesful authentication will require an additional step ...
Definition manage.c:1089
static void man_connection_close(struct management *man)
Definition manage.c:2688
static void man_query_password(struct management *man, const char *type, const char *string)
Definition manage.c:800
static void man_client_kill(struct management *man, const char *cid_str, const char *kill_msg)
Definition manage.c:1166
struct log_history * log_history_init(const int capacity)
Definition manage.c:4064
static void man_listen(struct management *man)
Definition manage.c:1923
static void man_stop_ne32(struct management *man)
Definition manage.c:1773
static void man_query_username(struct management *man, const char *type, const char *string)
Definition manage.c:791
static void man_push_update(struct management *man, const char **p, const push_update_type type)
Definition manage.c:1348
#define MWCC_PASSWORD_WAIT
Definition manage.c:3429
static void man_dispatch_command(struct management *man, struct status_output *so, const char **p, const int nparms)
Definition manage.c:1390
static void virtual_output_callback_func(void *arg, const unsigned int flags, const char *str)
Definition manage.c:355
static void man_signal(struct management *man, const char *name)
Definition manage.c:469
static void man_prompt(struct management *man)
Definition manage.c:295
static void man_state(struct management *man, const char *parm)
Definition manage.c:729
static void man_client_deny(struct management *man, const char *cid_str, const char *kid_str, const char *reason, const char *client_reason)
Definition manage.c:1138
static void man_echo(struct management *man, const char *parm)
Definition manage.c:722
void management_learn_addr(struct management *management, struct man_def_auth_context *mdac, const struct mroute_addr *addr, const bool primary)
Definition manage.c:3045
static char * management_query_multiline_flatten(struct management *man, const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input)
Definition manage.c:3757
static void man_proxy(struct management *man, const char **p)
Definition manage.c:1289
struct management * management_init(void)
Definition manage.c:2717
static void in_extra_reset(struct man_connection *mc, const int mode)
Definition manage.c:990
void command_line_reset(struct command_line *cl)
Definition manage.c:3904
static void man_query_need_str(struct management *man, const char *type, const char *action)
Definition manage.c:823
bool management_would_hold(struct management *man)
Definition manage.c:3831
static int man_read(struct management *man)
Definition manage.c:2323
static void man_history(struct management *man, const char *parm, const char *type, struct log_history *log, bool *realtime, const unsigned int lep_flags)
Definition manage.c:673
bool management_query_user_pass(struct management *man, struct user_pass *up, const char *type, const unsigned int flags, const char *static_challenge)
Definition manage.c:3523
static void man_bytecount_output_client(counter_type bytes_in_total, counter_type bytes_out_total)
Definition manage.c:561
void log_history_add(struct log_history *h, const struct log_entry *le)
Definition manage.c:4092
static void log_entry_free_contents(struct log_entry *e)
Definition manage.c:4038
static int man_mod_signal(const struct management *man, const int signum)
Definition manage.c:443
#define MN_AT_LEAST
Definition manage.c:1260
void management_event_loop_n_seconds(struct management *man, int sec)
Definition manage.c:3470
static void man_persist_close(struct man_persist *mp)
Definition manage.c:2513
static void man_kill(struct management *man, const char *victim)
Definition manage.c:585
void management_close(struct management *man)
Definition manage.c:2770
static void man_pk_sig(struct management *man, const char *cmd_name)
Definition manage.c:1214
void management_set_state(struct management *man, const int state, const char *detail, const in_addr_t *tun_local_ip, const struct in6_addr *tun_local_ip6, const struct openvpn_sockaddr *local, const struct openvpn_sockaddr *remote)
Definition manage.c:2796
static void man_output_list_push_finalize(struct management *man)
Definition manage.c:265
static void man_load_stats(struct management *man)
Definition manage.c:1246
static bool man_password_needed(struct management *man)
Definition manage.c:204
static void set_client_version(struct management *man, const char *version)
Definition manage.c:1339
const char * log_entry_print(const struct log_entry *e, unsigned int flags, struct gc_arena *gc)
Definition manage.c:3966
void management_auth_token(struct management *man, const char *token)
Definition manage.c:3137
static void man_accept(struct management *man)
Definition manage.c:1883
static void man_client_auth(struct management *man, const char *cid_str, const char *kid_str, const bool extra)
Definition manage.c:1121
static bool parse_cid(const char *str, unsigned long *cid)
Definition manage.c:1050
static void man_send_cc_message(struct management *man, const char *message, const char *parameters)
Definition manage.c:853
static void man_delete_unix_socket(struct management *man)
Definition manage.c:328
void management_io(struct management *man)
Definition manage.c:3197
static void man_wait_for_client_connection(struct management *man, volatile int *signal_received, const time_t expire, unsigned int flags)
Definition manage.c:3437
#define IER_NEW
Definition manage.c:987
static void man_output_peer_info_env(struct management *man, const struct man_def_auth_context *mdac)
Definition manage.c:2953
#define AF_DID_PUSH
bool management_open(struct management *man, const char *addr, const char *port, const char *pass_file, const char *client_user, const char *client_group, const int log_history_cache, const int echo_buffer_size, const int state_buffer_size, const int remap_sigusr1, const unsigned int flags)
Definition manage.c:2731
static void man_welcome(struct management *man)
Definition manage.c:193
void management_notify_generic(struct management *man, const char *str)
Definition manage.c:2947
void management_connection_established(struct management *management, struct man_def_auth_context *mdac, const struct env_set *es)
Definition manage.c:3023
static void man_query_need_ok(struct management *man, const char *type, const char *action)
Definition manage.c:814
static char * management_query_multiline_flatten_newline(struct management *man, const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input)
Definition manage.c:3727
static void man_output_extra_env(struct management *man, const char *prefix)
Definition manage.c:2917
void man_persist_client_stats(struct management *man, struct context *c)
Definition manage.c:4237
static void man_new_connection_post(struct management *man, const char *description)
Definition manage.c:1794
static void log_history_obj_init(struct log_history *h, int capacity)
Definition manage.c:4056
static void report_command_status(const bool status, const char *command)
Small function to report the success or failure of a command to the management interface.
Definition manage.c:315
#define IER_RESET
Definition manage.c:986
static void man_close_socket(struct management *man, const socket_descriptor_t sd)
Definition manage.c:339
static bool parse_uint(const char *str, const char *what, unsigned int *uint)
Definition manage.c:1064
void management_set_callback(struct management *man, const struct management_callback *cb)
Definition manage.c:2780
void management_notify_client_needing_auth(struct management *management, const unsigned int mda_key_id, struct man_def_auth_context *mdac, const struct env_set *es)
Definition manage.c:2981
static void man_client_n_clients(struct management *man)
Definition manage.c:1192
static void man_output_standalone(struct management *man, volatile int *signal_received)
Definition manage.c:3391
void management_notify_client_cr_response(unsigned mda_key_id, const struct man_def_auth_context *mdac, const struct env_set *es, const char *response)
Definition manage.c:3003
void management_echo(struct management *man, const char *string, const bool pull)
Definition manage.c:3058
static const char blank_up[]
Definition manage.c:62
static void man_remote_entry_get(struct management *man, const char *p1, const char *p2)
Definition manage.c:919
const struct log_entry * log_history_ref(const struct log_history *h, const int index)
Definition manage.c:4134
static void man_remote_entry_count(struct management *man)
Definition manage.c:903
static void man_settings_close(struct man_settings *ms)
Definition manage.c:2632
void management_check_bytecount_client(struct context *c, struct management *man, struct timeval *timeval)
Definition manage.c:4171
static void man_env_filter(struct management *man, const int level)
Definition manage.c:1206
#define MANAGEMENT_ECHO_FLAGS
Definition manage.c:58
static void man_output_list_push_str(struct management *man, const char *str)
Definition manage.c:279
void management_up_down(struct management *man, const char *updown, const struct env_set *es)
Definition manage.c:2931
char * management_query_pk_sig(struct management *man, const char *b64_data, const char *algorithm)
Definition manage.c:3786
static void man_remote(struct management *man, const char **p)
Definition manage.c:1303
static void man_forget_passwords(struct management *man)
Definition manage.c:832
void command_line_add(struct command_line *cl, const unsigned char *buf, const size_t len)
Definition manage.c:3924
static int man_standalone_event_loop(struct management *man, volatile int *signal_received, const time_t expire)
Definition manage.c:3414
static void man_process_command(struct management *man, const char *line)
Definition manage.c:2112
static int management_query_multiline(struct management *man, const char *b64_data, const char *prompt, const char *cmd, int *state, struct buffer_list **input)
Definition manage.c:3649
static void man_output_env(const struct env_set *es, const bool tail, const int env_filter_level, const char *prefix)
Definition manage.c:2896
const char * command_line_get(struct command_line *cl)
Definition manage.c:3939
static void log_history_free_contents(struct log_history *h)
Definition manage.c:4074
void management_sleep(const int n)
A sleep function that services the management layer for n seconds rather than doing nothing.
Definition manage.c:4147
static const char * man_state_name(const int state)
Definition manage.c:144
void log_history_resize(struct log_history *h, const int capacity)
Definition manage.c:4113
static void in_extra_dispatch(struct management *man)
Definition manage.c:1013
static void man_command_unsupported(const char *command_name)
Definition manage.c:496
void management_notify(struct management *man, const char *severity, const char *type, const char *text)
Definition manage.c:2941
#define MWCC_HOLD_WAIT
Definition manage.c:3430
void management_post_tunnel_open(struct management *man, const in_addr_t tun_local_ip)
Definition manage.c:3092
static void man_query_user_pass(struct management *man, const char *type, const char *string, const bool needed, const char *prompt, char *dest, int len)
Definition manage.c:766
static void man_hold(struct management *man, const char *cmd)
Definition manage.c:956
#define MANSIG_MAP_USR1_TO_TERM
Definition manage.h:257
#define MS_LISTEN
Definition manage.h:270
#define OPENVPN_STATE_ADD_ROUTES
Definition manage.h:451
#define UP_QUERY_USER_PASS
Definition manage.h:263
#define OPENVPN_STATE_INITIAL
Definition manage.h:448
#define MF_FORGET_DISCONNECT
Definition manage.h:31
#define UP_QUERY_DISABLED
Definition manage.h:262
#define LOG_FATAL_NOTIFY
Definition manage.h:127
#define MS_INITIAL
Definition manage.h:269
#define MANAGEMENT_STATE_BUFFER_SIZE
Definition manage.h:57
#define MANAGEMENT_VERSION
Definition manage.h:53
#define OPENVPN_STATE_CONNECTING
Definition manage.h:449
#define EKS_SOLICIT
Definition manage.h:304
#define MS_CC_WAIT_WRITE
Definition manage.h:272
#define LOG_PRINT_REMOTE_IP
Definition manage.h:131
#define LOG_PRINT_STATE_PREFIX
Definition manage.h:119
#define OPENVPN_STATE_RECONNECTING
Definition manage.h:453
#define LOG_PRINT_INT_DATE
Definition manage.h:121
#define DAF_INITIAL_AUTH
Definition manage.h:68
#define IEC_PK_SIGN
Definition manage.h:298
#define MANSIG_MAP_USR1_TO_HUP
Definition manage.h:256
#define LOG_PRINT_ECHO_PREFIX
Definition manage.h:118
#define LOG_PRINT_LOCAL_IP
Definition manage.h:124
#define MANAGEMENT_ECHO_BUFFER_SIZE
Definition manage.h:56
#define DAF_CONNECTION_CLOSED
Definition manage.h:67
#define MCF_SERVER
Definition manage.h:175
#define OPENVPN_STATE_CLIENT_BASE
Definition manage.h:465
#define MS_CC_WAIT_READ
Definition manage.h:271
#define LOG_PRINT_STATE
Definition manage.h:123
#define OPENVPN_STATE_CONNECTED
Definition manage.h:452
#define OPENVPN_STATE_RESOLVE
Definition manage.h:460
#define LOG_ECHO_TO_LOG
Definition manage.h:133
#define UP_QUERY_NEED_STR
Definition manage.h:266
#define OPENVPN_STATE_EXITING
Definition manage.h:454
static bool management_connected(const struct management *man)
Definition manage.h:413
#define MANAGEMENT_LOG_HISTORY_INITIAL_SIZE
Definition manage.h:55
#define OPENVPN_STATE_AUTH_PENDING
Definition manage.h:462
static int log_history_size(const struct log_history *h)
Definition manage.h:156
#define IEC_UNDEF
Definition manage.h:293
#define IEC_CERTIFICATE
Definition manage.h:297
#define MANSIG_IGNORE_USR1_HUP
Definition manage.h:255
#define OPENVPN_STATE_AUTH
Definition manage.h:458
#define EKS_READY
Definition manage.h:306
#define LOG_PRINT_LOG_PREFIX
Definition manage.h:117
#define OPENVPN_STATE_WAIT
Definition manage.h:457
#define LOG_PRINT_INTVAL
Definition manage.h:129
#define LOG_PRINT_CRLF
Definition manage.h:126
#define DAF_CONNECTION_ESTABLISHED
Definition manage.h:66
#define MF_SERVER
Definition manage.h:27
#define OPENVPN_STATE_ASSIGN_IP
Definition manage.h:450
#define MANAGEMENT_N_PASSWORD_RETRIES
Definition manage.h:54
#define MF_UP_DOWN
Definition manage.h:39
#define UP_QUERY_PASS
Definition manage.h:264
#define EKS_UNDEF
Definition manage.h:303
#define MF_HOLD
Definition manage.h:29
#define IEC_CLIENT_AUTH
Definition manage.h:294
#define MF_SIGNAL
Definition manage.h:30
#define UP_QUERY_NEED_OK
Definition manage.h:265
#define MF_UNIX_SOCK
Definition manage.h:35
#define OPENVPN_STATE_GET_CONFIG
Definition manage.h:459
#define MF_CONNECT_AS_CLIENT
Definition manage.h:32
#define OPENVPN_STATE_TCP_CONNECT
Definition manage.h:461
#define LOG_PRINT_MSG_FLAGS
Definition manage.h:122
#define EKS_INPUT
Definition manage.h:305
bool validate_peer_info_line(char *line)
Definition misc.c:722
#define USER_PASS_LEN
Definition misc.h:64
#define GET_USER_PASS_STATIC_CHALLENGE_CONCAT
indicates password and response should be concatenated
Definition misc.h:125
#define GET_USER_PASS_PASSWORD_ONLY
Definition misc.h:112
#define GET_USER_PASS_STATIC_CHALLENGE_ECHO
SCRV1 protocol – echo response.
Definition misc.h:120
#define GET_USER_PASS_NEED_OK
Definition misc.h:113
static bool get_user_pass(struct user_pass *up, const char *auth_file, const char *prefix, const unsigned int flags)
Retrieves the user credentials from various sources depending on the flags.
Definition misc.h:150
#define GET_USER_PASS_NEED_STR
Definition misc.h:115
const char * mroute_addr_print_ex(const struct mroute_addr *ma, const unsigned int flags, struct gc_arena *gc)
Definition mroute.c:382
#define MAPF_SUBNET
Definition mroute.h:151
Header file for server-mode related structures and functions.
#define BOOL_CAST(x)
Definition basic.h:26
#define CLEAR(x)
Definition basic.h:32
#define SIZE(x)
Definition basic.h:29
msglvl_t get_debug_level(void)
Definition error.c:134
bool set_mute_cutoff(const int cutoff)
Definition error.c:120
int get_mute_cutoff(void)
Definition error.c:140
bool set_debug_level(const int level, const unsigned int flags)
Definition error.c:104
const char * msg_flags_string(const msglvl_t flags, struct gc_arena *gc)
Definition error.c:751
#define M_CLIENT
Definition error.h:108
static void msg_set_virtual_output(const struct virtual_output *vo)
Definition error.h:358
#define ERR_BUF_SIZE
Definition error.h:34
#define M_FATAL
Definition error.h:90
static bool ignore_sys_error(const int err, bool crt_error)
Definition error.h:374
#define M_ERR
Definition error.h:106
#define msg(flags,...)
Definition error.h:152
static int openvpn_errno_maybe_crt(bool *crt_error)
Definition error.h:412
#define ASSERT(x)
Definition error.h:219
#define M_WARN
Definition error.h:92
#define M_ERRNO
Definition error.h:95
int parse_line(const char *line, char *p[], const int n, const char *file, const int line_num, msglvl_t msglevel, struct gc_arena *gc)
Definition options.c:4977
const char * auth_retry_print(void)
Definition options.c:4820
const char title_string[]
Definition options.c:71
bool auth_retry_set(const msglvl_t msglevel, const char *option)
Definition options.c:4797
#define streq(x, y)
Definition options.h:727
static bool dco_enabled(const struct options *o)
Returns whether the current configuration has dco enabled.
Definition options.h:936
#define MAX_PARMS
Definition options.h:51
time_t now
Definition otime.c:33
static void update_time(void)
Definition otime.h:81
unsigned int platform_getpid(void)
Definition platform.c:337
bool platform_user_get(const char *username, struct platform_state_user *state)
Definition platform.c:80
bool platform_group_get(const char *groupname, struct platform_state_group *state)
Definition platform.c:126
static int platform_state_user_uid(const struct platform_state_user *s)
Definition platform.h:97
static int platform_state_group_gid(const struct platform_state_group *s)
Definition platform.h:106
push_update_type
Definition push.h:47
@ UPT_BY_CID
Definition push.h:49
@ UPT_BROADCAST
Definition push.h:48
void throw_signal_soft(const int signum, const char *signal_text)
Throw a soft global signal.
Definition sig.c:204
const char * signal_name(const int sig, const bool upper)
Definition sig.c:91
void throw_signal(const int signum)
Throw a hard signal.
Definition sig.c:175
int parse_signal(const char *signame)
Definition sig.c:64
static void get_signal(volatile int *sig)
Copy the global signal_received (if non-zero) to the passed-in argument sig.
Definition sig.h:109
void sd_close(socket_descriptor_t *sd)
Definition socket.c:2978
socket_descriptor_t socket_do_accept(socket_descriptor_t sd, struct link_socket_actual *act, const bool nowait)
Definition socket.c:782
int openvpn_connect(socket_descriptor_t sd, const struct sockaddr *remote, int connect_timeout, volatile int *signal_received)
Definition socket.c:991
void socket_bind(socket_descriptor_t sd, struct addrinfo *local, int ai_family, const char *prefix, bool ipv6only)
Definition socket.c:941
socket_descriptor_t create_socket_tcp(struct addrinfo *addrinfo)
Definition socket.c:573
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, struct signal_info *sig_info)
Translate an IPv4 addr or hostname from string form to in_addr_t.
Definition socket.c:192
#define MSG_NOSIGNAL
Definition socket.h:242
#define openvpn_close_socket(s)
Definition socket.h:247
const char * proto2ascii(int proto, sa_family_t af, bool display_form)
int openvpn_getaddrinfo(unsigned int flags, const char *hostname, const char *servname, int resolve_retry_seconds, struct signal_info *sig_info, int ai_family, struct addrinfo **res)
const char * print_sockaddr_ex(const struct sockaddr *sa, const char *separator, const unsigned int flags, struct gc_arena *gc)
Definition socket_util.c:38
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
#define IA_EMPTY_IF_UNDEF
Definition socket_util.h:89
static const char * print_sockaddr(const struct sockaddr *addr, struct gc_arena *gc)
Definition socket_util.h:77
#define GETADDR_MSG_VIRT_OUT
#define GETADDR_PASSIVE
#define GETADDR_FATAL
#define PS_SHOW_PORT
Definition socket_util.h:31
@ PROTO_NONE
@ PROTO_UDP
@ PROTO_TCP_SERVER
#define GETADDR_HOST_ORDER
static bool addr_defined(const struct openvpn_sockaddr *addr)
#define GETADDR_RESOLVE
#define PS_DONT_SHOW_FAMILY
Definition socket_util.h:34
#define GETADDR_WARN_ON_SIGNAL
void ssl_purge_auth(const bool auth_user_pass_only)
Definition ssl.c:391
bool ssl_clean_auth_token(void)
Definition ssl.c:380
Control Channel SSL/Data channel negotiation module.
struct status_output * status_open(const char *filename, const int refresh_freq, const int msglevel, const struct virtual_output *vout, const unsigned int flags)
Definition status.c:60
bool status_close(struct status_output *so)
Definition status.c:179
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int capacity
Size in bytes of memory allocated by malloc().
Definition buffer.h:61
uint8_t * data
Pointer to the allocated memory.
Definition buffer.h:67
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
struct buffer residual
Definition manage.h:80
struct buffer buf
Definition manage.h:79
struct tuntap * tuntap
Tun/tap virtual network interface.
Definition openvpn.h:172
Level 2 context containing state that is reset on both SIGHUP and SIGUSR1 restarts.
Definition openvpn.h:224
counter_type link_read_bytes
Definition openvpn.h:266
counter_type link_write_bytes
Definition openvpn.h:269
counter_type dco_read_bytes
Definition openvpn.h:267
struct man_def_auth_context mda_context
Definition openvpn.h:453
counter_type dco_write_bytes
Definition openvpn.h:270
Contains all state information for one tunnel.
Definition openvpn.h:474
struct context_2 c2
Level 2 context.
Definition openvpn.h:517
struct options options
Options loaded from command line or configuration file.
Definition openvpn.h:475
struct context_1 c1
Level 1 context.
Definition openvpn.h:516
char * string
Definition env_set.h:38
struct env_item * next
Definition env_set.h:39
struct env_item * list
Definition env_set.h:45
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
void * value
Definition list.h:41
Definition manage.h:107
struct in6_addr local_ip6
Definition manage.h:111
struct openvpn_sockaddr local_sock
Definition manage.h:112
struct openvpn_sockaddr remote_sock
Definition manage.h:113
time_t timestamp
Definition manage.h:108
const char * string
Definition manage.h:109
in_addr_t local_ip
Definition manage.h:110
union log_entry_union u
Definition manage.h:114
int capacity
Definition manage.h:141
struct log_entry * array
Definition manage.h:142
struct event_set * es
Definition manage.h:311
unsigned long in_extra_cid
Definition manage.h:301
const char * up_query_type
Definition manage.h:320
bool password_verified
Definition manage.h:287
int env_filter_level
Definition manage.h:312
struct user_pass up_query
Definition manage.h:322
socket_descriptor_t sd_top
Definition manage.h:278
struct buffer_list * ext_cert_input
Definition manage.h:310
struct command_line * in
Definition manage.h:290
unsigned int in_extra_kid
Definition manage.h:302
struct openvpn_sockaddr remote
Definition manage.h:280
socket_descriptor_t sd_cli
Definition manage.h:279
struct buffer_list * ext_key_input
Definition manage.h:308
int up_query_mode
Definition manage.h:321
int bytecount_update_seconds
Definition manage.h:317
int in_extra_cmd
Definition manage.h:299
struct buffer_list * in_extra
Definition manage.h:300
bool echo_realtime
Definition manage.h:316
bool state_realtime
Definition manage.h:314
struct event_timeout bytecount_update_interval
Definition manage.h:318
int ext_cert_state
Definition manage.h:309
struct buffer_list * out
Definition manage.h:291
int password_tries
Definition manage.h:288
int client_version
Definition manage.h:328
bool log_realtime
Definition manage.h:315
struct net_event_win32 ne32
Definition manage.h:283
int ext_key_state
Definition manage.h:307
unsigned long cid
Definition manage.h:64
unsigned int flags
Definition manage.h:69
counter_type bytes_in
Definition manage.h:234
struct log_history * state
Definition manage.h:228
struct management_callback callback
Definition manage.h:225
struct log_history * log
Definition manage.h:221
struct virtual_output vout
Definition manage.h:222
bool standalone_disabled
Definition manage.h:224
bool defined
Definition manage.h:219
bool hold_release
Definition manage.h:230
struct log_history * echo
Definition manage.h:227
const char * special_state_msg
Definition manage.h:232
counter_type bytes_out
Definition manage.h:235
bool management_over_tunnel
Definition manage.h:246
struct addrinfo * local
Definition manage.h:242
unsigned int flags
Definition manage.h:241
int echo_buffer_size
Definition manage.h:249
int client_uid
Definition manage.h:251
unsigned int mansig
Definition manage.h:258
int state_buffer_size
Definition manage.h:250
bool defined
Definition manage.h:240
int client_gid
Definition manage.h:252
int log_history_cache
Definition manage.h:248
struct user_pass up
Definition manage.h:247
char *(* get_peer_info)(void *arg, const unsigned long cid)
Definition manage.h:191
bool(* client_auth)(void *arg, const unsigned long cid, const unsigned int mda_key_id, const bool auth, const char *reason, const char *client_reason, struct buffer_list *cc_config)
Definition manage.h:186
void(* delete_event)(void *arg, event_t event)
Definition manage.h:182
bool(* push_update_broadcast)(void *arg, const char *options)
Definition manage.h:199
bool(* push_update_by_cid)(void *arg, unsigned long cid, const char *options)
Definition manage.h:200
int(* kill_by_addr)(void *arg, const in_addr_t addr, const int port, const int proto)
Definition manage.h:181
bool(* client_pending_auth)(void *arg, const unsigned long cid, const unsigned int kid, const char *extra, unsigned int timeout)
Definition manage.h:189
int(* n_clients)(void *arg)
Definition manage.h:183
void(* status)(void *arg, const int version, struct status_output *so)
Definition manage.h:178
bool(* remote_entry_get)(void *arg, unsigned int index, char **remote)
Definition manage.h:198
unsigned int(* remote_entry_count)(void *arg)
Definition manage.h:197
bool(* send_cc_message)(void *arg, const char *message, const char *parameter)
Definition manage.h:184
bool(* proxy_cmd)(void *arg, const char **p)
Definition manage.h:192
void(* show_net)(void *arg, const msglvl_t msglevel)
Definition manage.h:179
unsigned int flags
Definition manage.h:176
bool(* remote_cmd)(void *arg, const char **p)
Definition manage.h:193
int(* kill_by_cn)(void *arg, const char *common_name)
Definition manage.h:180
bool(* kill_by_cid)(void *arg, const unsigned long cid, const char *kill_msg)
Definition manage.h:185
struct man_persist persist
Definition manage.h:333
struct man_connection connection
Definition manage.h:335
struct man_settings settings
Definition manage.h:334
Main OpenVPN server state structure.
Definition multi.h:164
struct hash * hash
VPN tunnel instances indexed by real address of the remote peer.
Definition multi.h:168
struct context top
Storage structure for process-wide configuration.
Definition multi.h:203
Server-mode state structure for one single VPN tunnel.
Definition multi.h:103
struct context context
The context structure storing state for this VPN tunnel.
Definition multi.h:144
dco_context_t dco
Definition tun.h:249
bool defined
Definition misc.h:53
char password[USER_PASS_LEN]
Definition misc.h:68
bool nocache
Definition misc.h:57
char username[USER_PASS_LEN]
Definition misc.h:67
unsigned int flags_default
Definition status.h:34
void * arg
Definition status.h:33
void(* func)(void *arg, const unsigned int flags, const char *str)
Definition status.h:35
#define SOCKET_UNDEFINED
Definition syshead.h:438
SOCKET socket_descriptor_t
Definition syshead.h:440
#define sleep(x)
Definition syshead.h:42
static int socket_defined(const socket_descriptor_t sd)
Definition syshead.h:448
struct env_set * es
char ** res
struct gc_arena gc
Definition test_ssl.c:131
unsigned int msg_flags
Definition manage.h:101
int state
Definition manage.h:102
int intval
Definition manage.h:103
void net_event_win32_init(struct net_event_win32 *ne)
Definition win32.c:323
void net_event_win32_close(struct net_event_win32 *ne)
Definition win32.c:374
void net_event_win32_reset_write(struct net_event_win32 *ne)
Definition win32.c:339
void net_event_win32_start(struct net_event_win32 *ne, long network_events, socket_descriptor_t sd)
Definition win32.c:330
void win32_sleep(const int n)
Definition win32.c:1507
void net_event_win32_reset(struct net_event_win32 *ne)
Definition win32.c:357
void net_event_win32_stop(struct net_event_win32 *ne)
Definition win32.c:363
static long net_event_win32_get_event_mask(const struct net_event_win32 *ne)
Definition win32.h:141
static void net_event_win32_clear_selected_events(struct net_event_win32 *ne, long selected_events)
Definition win32.h:147
static struct rw_handle * net_event_win32_get_event(struct net_event_win32 *ne)
Definition win32.h:135