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