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

Reply via email to