This provides exactly the same systemd functionality which existed
before the query user infrastructure got implemented.
[v5 - Ensure NULL termination fix in d09fbf958f1c is included ]
[v4 - change disapproved &= syntax ]
[v3 - Remove QUERY_USER_EXEC_ALTERNATIVE macro, simplify
alternatives definition directly in console.h. For
now only depend on ENABLE_SYSTEMD]
[v2 - Removed the QUERY_USER_FOREACH macro]
Signed-off-by: David Sommerseth <davids@openvpn.net>
Acked-by: Selva Nair <selva.nair@gmail.com>
Message-Id: 1470999445-4288-1-git-send-email-davids@openvpn.net
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg12424.html
| ... | ... |
@@ -1017,7 +1017,7 @@ fi |
| 1017 | 1017 |
dnl |
| 1018 | 1018 |
dnl Check for systemd |
| 1019 | 1019 |
dnl |
| 1020 |
- |
|
| 1020 |
+AM_CONDITIONAL([ENABLE_SYSTEMD], [test "${enable_systemd}" = "yes"])
|
|
| 1021 | 1021 |
if test "$enable_systemd" = "yes" ; then |
| 1022 | 1022 |
PKG_CHECK_MODULES([libsystemd], [systemd libsystemd], |
| 1023 | 1023 |
[], |
| ... | ... |
@@ -76,7 +76,7 @@ void query_user_add (char *prompt, size_t prompt_len, |
| 76 | 76 |
bool query_user_exec_builtin (); |
| 77 | 77 |
|
| 78 | 78 |
|
| 79 |
-#ifdef QUERY_USER_EXEC_ALTERNATIVE |
|
| 79 |
+#if defined(ENABLE_SYSTEMD) |
|
| 80 | 80 |
/** |
| 81 | 81 |
* Executes a configured setup, using the compiled method for querying the user |
| 82 | 82 |
* |
| ... | ... |
@@ -86,7 +86,7 @@ bool query_user_exec_builtin (); |
| 86 | 86 |
*/ |
| 87 | 87 |
bool query_user_exec (); |
| 88 | 88 |
|
| 89 |
-#else /* QUERY_USER_EXEC_ALTERNATIVE not defined*/ |
|
| 89 |
+#else /* ENABLE_SYSTEMD not defined*/ |
|
| 90 | 90 |
/** |
| 91 | 91 |
* Wrapper function enabling query_user_exec() if no alternative methods have |
| 92 | 92 |
* been enabled |
| ... | ... |
@@ -96,7 +96,7 @@ static bool query_user_exec () |
| 96 | 96 |
{
|
| 97 | 97 |
return query_user_exec_builtin(); |
| 98 | 98 |
} |
| 99 |
-#endif /* QUERY_USER_EXEC_ALTERNATIVE */ |
|
| 99 |
+#endif /* defined(ENABLE_SYSTEMD) */ |
|
| 100 | 100 |
|
| 101 | 101 |
|
| 102 | 102 |
/** |
| 103 | 103 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,115 @@ |
| 0 |
+/* |
|
| 1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
| 2 |
+ * over a single UDP port, with support for SSL/TLS-based |
|
| 3 |
+ * session authentication and key exchange, |
|
| 4 |
+ * packet encryption, packet authentication, and |
|
| 5 |
+ * packet compression. |
|
| 6 |
+ * |
|
| 7 |
+ * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com> |
|
| 8 |
+ * Copyright (C) 2016 David Sommerseth <dazo@privateinternetaccess.com> |
|
| 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 |
|
| 20 |
+ * along with this program (see the file COPYING included with this |
|
| 21 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
| 22 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 23 |
+ */ |
|
| 24 |
+ |
|
| 25 |
+/** |
|
| 26 |
+ * @file Alternative method to query for user input, using systemd |
|
| 27 |
+ * |
|
| 28 |
+ */ |
|
| 29 |
+ |
|
| 30 |
+#include "config.h" |
|
| 31 |
+ |
|
| 32 |
+#ifdef ENABLE_SYSTEMD |
|
| 33 |
+#include "syshead.h" |
|
| 34 |
+#include "console.h" |
|
| 35 |
+#include "misc.h" |
|
| 36 |
+ |
|
| 37 |
+#include <systemd/sd-daemon.h> |
|
| 38 |
+ |
|
| 39 |
+/* |
|
| 40 |
+ * is systemd running |
|
| 41 |
+ */ |
|
| 42 |
+ |
|
| 43 |
+static bool |
|
| 44 |
+check_systemd_running () |
|
| 45 |
+{
|
|
| 46 |
+ struct stat c; |
|
| 47 |
+ |
|
| 48 |
+ /* We simply test whether the systemd cgroup hierarchy is |
|
| 49 |
+ * mounted, as well as the systemd-ask-password executable |
|
| 50 |
+ * being available */ |
|
| 51 |
+ |
|
| 52 |
+ return (sd_booted() > 0) |
|
| 53 |
+ && (stat(SYSTEMD_ASK_PASSWORD_PATH, &c) == 0); |
|
| 54 |
+ |
|
| 55 |
+} |
|
| 56 |
+ |
|
| 57 |
+static bool |
|
| 58 |
+get_console_input_systemd (const char *prompt, const bool echo, char *input, const int capacity) |
|
| 59 |
+{
|
|
| 60 |
+ int std_out; |
|
| 61 |
+ bool ret = false; |
|
| 62 |
+ struct argv argv; |
|
| 63 |
+ |
|
| 64 |
+ argv_init (&argv); |
|
| 65 |
+ argv_printf (&argv, SYSTEMD_ASK_PASSWORD_PATH); |
|
| 66 |
+ argv_printf_cat (&argv, "%s", prompt); |
|
| 67 |
+ |
|
| 68 |
+ if ((std_out = openvpn_popen (&argv, NULL)) < 0) {
|
|
| 69 |
+ return false; |
|
| 70 |
+ } |
|
| 71 |
+ memset (input, 0, capacity); |
|
| 72 |
+ if (read (std_out, input, capacity-1) != 0) |
|
| 73 |
+ {
|
|
| 74 |
+ chomp (input); |
|
| 75 |
+ ret = true; |
|
| 76 |
+ } |
|
| 77 |
+ close (std_out); |
|
| 78 |
+ |
|
| 79 |
+ argv_reset (&argv); |
|
| 80 |
+ |
|
| 81 |
+ return ret; |
|
| 82 |
+} |
|
| 83 |
+ |
|
| 84 |
+/** |
|
| 85 |
+ * Systemd aware implementation of query_user_exec(). If systemd is not running |
|
| 86 |
+ * it will fall back to use query_user_exec_builtin() instead. |
|
| 87 |
+ * |
|
| 88 |
+ */ |
|
| 89 |
+bool query_user_exec() |
|
| 90 |
+{
|
|
| 91 |
+ bool ret = true; /* Presume everything goes okay */ |
|
| 92 |
+ int i; |
|
| 93 |
+ |
|
| 94 |
+ /* If systemd is not available, use the default built-in mechanism */ |
|
| 95 |
+ if (!check_systemd_running()) |
|
| 96 |
+ {
|
|
| 97 |
+ return query_user_exec_builtin(); |
|
| 98 |
+ } |
|
| 99 |
+ |
|
| 100 |
+ /* Loop through the complete query setup and when needed, collect the information */ |
|
| 101 |
+ for (i = 0; i < QUERY_USER_NUMSLOTS && query_user[i].response != NULL; i++) |
|
| 102 |
+ {
|
|
| 103 |
+ if (!get_console_input_systemd(query_user[i].prompt, query_user[i].echo, |
|
| 104 |
+ query_user[i].response, query_user[i].response_len) ) |
|
| 105 |
+ {
|
|
| 106 |
+ /* Force the final result state to failed on failure */ |
|
| 107 |
+ ret = false; |
|
| 108 |
+ } |
|
| 109 |
+ } |
|
| 110 |
+ |
|
| 111 |
+ return ret; |
|
| 112 |
+} |
|
| 113 |
+ |
|
| 114 |
+#endif /* ENABLE_SYSTEMD */ |