[Openvpn-devel] [M] Change in openvpn[master]: Add unix-script functionality to the --management feature
"plaisthos \(Code Review\) via Openvpn-devel" <[email protected]>
| Newsgroups | net.sourceforge.lists.openvpn-devel |
|---|---|
| Message-ID | <107edf4906f17a00112a83549d303befef47fe16-EmailReplacePatchSet-HTML@gerrit.openvpn.net> |
plaisthos has uploaded a new patch set (#2). ( http://gerrit.openvpn.net/c/openvpn/+/1852?usp=email ) Change subject: Add unix-script functionality to the --management feature ...................................................................... Add unix-script functionality to the --management feature This allows a script that handles management input/output to be started alongside OpenVPN simpler in small deployments. Change-Id: I307e64079f436aa782f7e24bfff665a545ad2fa0 Signed-off-by: Arne Schwabe <[email protected]> --- M doc/man-sections/management-options.rst M doc/management-notes.txt M src/openvpn/init.c M src/openvpn/manage.c M src/openvpn/manage.h M src/openvpn/options.c M src/openvpn/options.h 7 files changed, 100 insertions(+), 9 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/52/1852/2 diff --git a/doc/man-sections/management-options.rst b/doc/man-sections/management-options.rst index 8dad52b..d7ece8b 100644 --- a/doc/man-sections/management-options.rst +++ b/doc/man-sections/management-options.rst @@ -14,6 +14,7 @@ management socket-name unix pw-file # (recommended) management IP port # (INSECURE) management IP port pw-file # + management script unix-script ``pw-file``, if specified, is a password file where the password must be on first line. Instead of a filename it can use the keyword stdin @@ -25,6 +26,14 @@ ``--management-client-user`` and ``--management-client-group`` directives to restrict access. + When the variant :code:`unix-script` is used, OpenVPN will start the + specified script on startup and enable ``--management-hold``. + OpenVPN will generate a random path for the unix socket + and also management user and password. These are passed as environment + variables :code:`MANAGEMENT_SOCKET`, :code:`MANAGEMENT_PASSWORD` + to the script when being started. When OpenVPN terminates it sends + a :code:`SIGINT` signal to the running script. + The management interface provides a special mode where the TCP management link can operate over the tunnel itself. To enable this mode, set IP to ``tunnel``. Tunnel mode will cause the management interface to @@ -129,8 +138,9 @@ --management-signal Send SIGUSR1 signal to OpenVPN if management session disconnects. This is useful when you wish to disconnect an OpenVPN session on user logoff. - For ``--management-client`` this option is not needed since a disconnect - will always generate a :code:`SIGTERM`. + For ``--management-client`` or ``--management`` with :code:`unixscript` + this option is not needed since a disconnect will always generate a + :code:`SIGTERM`. --management-up-down Report tunnel up/down events to management interface. diff --git a/doc/management-notes.txt b/doc/management-notes.txt index 1126468..d6b3fbb 100644 --- a/doc/management-notes.txt +++ b/doc/management-notes.txt @@ -35,6 +35,10 @@ you can telnet to the management port (make sure to use a telnet client which understands "raw" mode). +When password authentication is enabled, the management interface +will require sending the password on its own line after establishing +the connection. + Once connected to the management port, you can use the "help" command to list all commands. diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 66bae34..101fa64 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -4337,19 +4337,59 @@ } } +void +run_management_script(struct context *c) +{ +#ifdef UNIX_SOCK_SUPPORT + struct gc_arena gc = gc_new(); + struct argv argv = argv_new(); + struct env_set *env = env_set_create(&gc); + + setenv_str(env, "MANAGEMENT_USER", management->settings.up.username); + setenv_str(env, "MANAGEMENT_PASSWORD", management->settings.up.password); + setenv_str(env, "MANAGEMENT_SOCKET", c->options.management_addr); + + argv_printf(&argv, "%s", c->options.management_script); + + int flags = S_NOWAITPID | S_SCRIPT | S_FATAL; + int *pid = &management->connection.unix_script_pid; + const char *msg_prefix = "WARNING: Failed running management unix-script"; + *pid = openvpn_execve_check(&argv, env, flags, msg_prefix); + + if (!openvpn_waitpid_check(*pid, msg_prefix, M_FATAL)) + { + *pid = 0; + } + + argv_free(&argv); + gc_free(&gc); +#else + msg(M_FATAL, "ERROR: Management unix-socket support is not available on this platform ); +#endif +} + bool open_management(struct context *c) { /* initialize management layer */ if (management) { + unsigned int flags = c->options.management_flags; + if (flags & MF_UNIX_SOCK_SCRIPT) + { + /* This creates a file but our management codes deletes the + * file before opening a socket with the name */ + c->options.management_addr = platform_create_temp_file( + platform_get_tmp_dir(), "omi", &c->gc); + } + if (c->options.management_addr) { - unsigned int flags = c->options.management_flags; if (c->options.mode == MODE_SERVER) { flags |= MF_SERVER; } + if (management_open( management, c->options.management_addr, c->options.management_port, c->options.management_user_pass, c->options.management_client_user, @@ -4361,6 +4401,11 @@ NULL); } + if (flags & MF_UNIX_SOCK_SCRIPT) + { + run_management_script(c); + } + /* initial management hold, called early, before first context initialization */ do_hold(0); if (IS_SIG(c)) diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c index 95ff246..bfc2aa2 100644 --- a/src/openvpn/manage.c +++ b/src/openvpn/manage.c @@ -333,10 +333,12 @@ man_delete_unix_socket(struct management *man) { #if UNIX_SOCK_SUPPORT - if ((man->settings.flags & (MF_UNIX_SOCK | MF_CONNECT_AS_CLIENT)) == MF_UNIX_SOCK) + if ((man->settings.flags & (MF_UNIX_SOCK | MF_CONNECT_AS_CLIENT)) == MF_UNIX_SOCK + || man->settings.flags & MF_UNIX_SOCK_SCRIPT) { socket_delete_unix(&man->settings.local_unix); } + #endif } @@ -2197,7 +2199,7 @@ } } - if (man->settings.flags & MF_CONNECT_AS_CLIENT) + if (man->settings.flags & (MF_CONNECT_AS_CLIENT | MF_UNIX_SOCK_SCRIPT)) { msg(D_MANAGEMENT, "MANAGEMENT: Triggering management exit"); throw_signal_soft(SIGTERM, "management-exit"); @@ -2644,6 +2646,15 @@ { get_user_pass(&ms->up, pass_file, "Management", GET_USER_PASS_PASSWORD_ONLY); } + else if (ms->flags & MF_UNIX_SOCK_SCRIPT) + { + /* Set random password. The password is only + * alphanumerical [0-9a-f] but still has 128 bit of randomness, + * which is more than enough */ + snprintf(ms->up.password, sizeof(ms->up.password), + "%" PRIx64 "%" PRIx64, get_random(), get_random()); + ms->up.defined = true; + } #if UNIX_SOCK_SUPPORT /* @@ -2789,6 +2800,11 @@ man_close_socket(man, mc->sd_cli); } + if (mc->unix_script_pid) + { + kill(mc->unix_script_pid, SIGINT); + } + command_line_free(mc->in); buffer_list_free(mc->out); diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h index 27d3b60..71e88d0 100644 --- a/src/openvpn/manage.h +++ b/src/openvpn/manage.h @@ -42,6 +42,7 @@ #define MF_EXTERNAL_CERT (1u << 15) #define MF_EXTERNAL_KEY_PSSPAD (1u << 16) #define MF_EXTERNAL_KEY_DIGEST (1u << 17) +#define MF_UNIX_SOCK_SCRIPT (1u << 18) #ifdef ENABLE_MANAGEMENT @@ -327,6 +328,9 @@ int fdtosend; int lastfdreceived; #endif +#ifdef UNIX_SOCK_SUPPORT + pid_t unix_script_pid; +#endif int client_version; }; diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 9bd6f01..4391434 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -1739,7 +1739,7 @@ * Check for consistency of management options */ #ifdef ENABLE_MANAGEMENT - if (!options->management_addr + if (!options->management_addr && !(options->management_flags & MF_UNIX_SOCK_SCRIPT) && (options->management_flags || options->management_log_history_cache != defaults.management_log_history_cache)) { @@ -4333,7 +4333,7 @@ else if (streq(p[0], "management") && p[1] && p[2] && !p[4]) { VERIFY_PERMISSION(OPT_P_GENERAL); - if (streq(p[2], "unix")) + if (streq(p[2], "unix") || streq(p[2], "unix-script")) { #if UNIX_SOCK_SUPPORT options->management_flags |= MF_UNIX_SOCK; @@ -4343,7 +4343,16 @@ #endif } - options->management_addr = p[1]; + if (streq(p[2], "unix-script")) + { + options->management_flags |= MF_UNIX_SOCK_SCRIPT | MF_HOLD; + set_user_script(options, &options->management_script, p[1], + "management unix-script", false); + } + else + { + options->management_addr = p[1]; + } options->management_port = p[2]; if (p[3]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index e93b05b..e92a5cd 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -446,6 +446,8 @@ const char *management_addr; const char *management_port; const char *management_user_pass; + /** Script executed to talk to the management interface */ + const char *management_script; int management_log_history_cache; int management_echo_buffer_size; int management_state_buffer_size; @@ -761,7 +763,8 @@ #define OPT_P_PUSH_MTU (1u << 30) #define OPT_P_ROUTE_TABLE (1u << 31) -#define OPT_P_DEFAULT (~(OPT_P_INSTANCE | OPT_P_PULL_MODE | OPT_P_PEER_ID | 0x0ull)) +/* Options allowed in the normal configuration file */ +#define OPT_P_DEFAULT (~(OPT_P_INSTANCE | OPT_P_PULL_MODE | OPT_P_PEER_ID | 0x0ull))) #define PULL_DEFINED(opt) ((opt)->pull) -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1852?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: newpatchset Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I307e64079f436aa782f7e24bfff665a545ad2fa0 Gerrit-Change-Number: 1852 Gerrit-PatchSet: 2 Gerrit-Owner: plaisthos <[email protected]> Gerrit-CC: openvpn-devel <[email protected]> _______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel