[Openvpn-devel,v2,06/11] Add S_EXITCODE flag for openvpn_run_script to report exit code

Message ID 20210125125628.30364-7-arne@rfc2549.org
State Accepted
Headers show
Series Pending authentication improvements | expand

Commit Message

Arne Schwabe Jan. 25, 2021, 1:56 a.m. UTC
This allows to use script that have more than just fail/sucess but
also deferred as status

Patch v2: minor style fixes, improve doxygen comments

Signed-off-by: Arne Schwabe <arne@rfc2549.org>
---
 src/openvpn/platform.c    | 34 ++++++++++++++++++++++++++++++++++
 src/openvpn/platform.h    |  5 ++++-
 src/openvpn/run_command.c | 25 ++++++++++++++++---------
 src/openvpn/run_command.h | 15 +++++++++++----
 4 files changed, 65 insertions(+), 14 deletions(-)

Comments

Lev Stipakov Jan. 28, 2021, 9:47 p.m. UTC | #1
Hi,

V1 has been acked and this has minor style/comment fixes. No other
changes compared to V1.
Compiled with MSVC.

Acked-by: Lev Stipakov <lstipakov@gmail.com>
Gert Doering Feb. 14, 2021, 5:31 a.m. UTC | #2
Your patch has been applied to the master branch.

Again, out of sequence, as this does not depend on 03/11 or 05/11.

Lightly tested and stared at the code a bit.  Added a line break before
a "{"...

commit 04876274b5059f4c27b1f481fd92ff5e8ab15f1c
Author: Arne Schwabe
Date:   Mon Jan 25 13:56:23 2021 +0100

     Add S_EXITCODE flag for openvpn_run_script to report exit code

     Signed-off-by: Arne Schwabe <arne@rfc2549.org>
     Acked-by: Lev Stipakov <lstipakov@gmail.com>
     Message-Id: <20210125125628.30364-7-arne@rfc2549.org>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg21487.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c
index 53d07f9c..ef688c23 100644
--- a/src/openvpn/platform.c
+++ b/src/openvpn/platform.c
@@ -240,6 +240,40 @@  platform_system_ok(int stat)
 #endif
 }
 
+#ifdef _WIN32
+int
+platform_ret_code(int stat)
+{
+    if (stat >= 0 && stat < 255)
+    {
+        return stat;
+    }
+    else
+    {
+        return -1;
+    }
+}
+#else
+int
+platform_ret_code(int stat)
+{
+    if (!WIFEXITED(stat) || stat == -1)
+    {
+        return -1;
+    }
+
+    int status = WEXITSTATUS(stat);
+    if (status >= 0 && status < 255)
+    {
+        return status;
+    }
+    else
+    {
+        return -1;
+    }
+}
+#endif
+
 int
 platform_access(const char *path, int mode)
 {
diff --git a/src/openvpn/platform.h b/src/openvpn/platform.h
index 091fc9c4..01f3200c 100644
--- a/src/openvpn/platform.h
+++ b/src/openvpn/platform.h
@@ -119,9 +119,12 @@  void platform_mlockall(bool print_msg);  /* Disable paging */
 
 int platform_chdir(const char *dir);
 
-/* interpret the status code returned by execve() */
+/** interpret the status code returned by execve() */
 bool platform_system_ok(int stat);
 
+/** Return an exit code if valid and between 0 and 255, -1 otherwise */
+int platform_ret_code(int stat);
+
 int platform_access(const char *path, int mode);
 
 void platform_sleep_milliseconds(unsigned int n);
diff --git a/src/openvpn/run_command.c b/src/openvpn/run_command.c
index 4c4adf97..8f99ec88 100644
--- a/src/openvpn/run_command.c
+++ b/src/openvpn/run_command.c
@@ -191,27 +191,34 @@  openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned in
 /*
  * Wrapper around openvpn_execve
  */
-bool
+int
 openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
 {
     struct gc_arena gc = gc_new();
     const int stat = openvpn_execve(a, es, flags);
     int ret = false;
 
-    if (platform_system_ok(stat))
+    if (flags & S_EXITCODE)
+    {
+        ret = platform_ret_code(stat);
+        if (ret != -1) {
+            goto done;
+        }
+    }
+    else if (platform_system_ok(stat))
     {
         ret = true;
+        goto done;
     }
-    else
+    if (error_message)
     {
-        if (error_message)
-        {
-            msg(((flags & S_FATAL) ? M_FATAL : M_WARN), "%s: %s",
-                error_message,
-                system_error_message(stat, &gc));
-        }
+        msg(((flags & S_FATAL) ? M_FATAL : M_WARN), "%s: %s",
+            error_message,
+            system_error_message(stat, &gc));
     }
+done:
     gc_free(&gc);
+
     return ret;
 }
 
diff --git a/src/openvpn/run_command.h b/src/openvpn/run_command.h
index 7ccb13c6..da33d92b 100644
--- a/src/openvpn/run_command.h
+++ b/src/openvpn/run_command.h
@@ -42,18 +42,25 @@  int script_security(void);
 void script_security_set(int level);
 
 /* openvpn_execve flags */
-#define S_SCRIPT (1<<0)
-#define S_FATAL  (1<<1)
+#define S_SCRIPT    (1<<0)
+#define S_FATAL     (1<<1)
+/** Instead of returning 1/0 for success/fail,
+ * return exit code when between 0 and 255 and -1 otherwise */
+#define S_EXITCODE  (1<<2)
 
 /* wrapper around the execve() call */
 int openvpn_popen(const struct argv *a,  const struct env_set *es);
 
 bool openvpn_execve_allowed(const unsigned int flags);
 
-bool openvpn_execve_check(const struct argv *a, const struct env_set *es,
+int openvpn_execve_check(const struct argv *a, const struct env_set *es,
                           const unsigned int flags, const char *error_message);
 
-static inline bool
+/**
+ * Will run a script and return the exit code of the script if between
+ * 0 and 255, -1 otherwise
+ */
+static inline int
 openvpn_run_script(const struct argv *a, const struct env_set *es,
                    const unsigned int flags, const char *hook)
 {