Browse code

Re-implement the systemd support using the new query user API

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

David Sommerseth authored on 2016/08/12 19:57:25
Showing 4 changed files
... ...
@@ -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
                       [],
... ...
@@ -68,7 +68,7 @@ openvpn_SOURCES = \
68 68
 	memdbg.h \
69 69
 	misc.c misc.h \
70 70
 	platform.c platform.h \
71
-	console.c console.h console_builtin.c \
71
+	console.c console.h console_builtin.c console_systemd.c \
72 72
 	mroute.c mroute.h \
73 73
 	mss.c mss.h \
74 74
 	mstats.c mstats.h \
... ...
@@ -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 */