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