OpenVPN
console_systemd.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
9 * Copyright (C) 2016 David Sommerseth <dazo@privateinternetaccess.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, see <https://www.gnu.org/licenses/>.
22 */
23
30#include "config.h"
31
32#ifdef ENABLE_SYSTEMD
33#include "syshead.h"
34#include "console.h"
35#include "misc.h"
36#include "run_command.h"
37
38#include <systemd/sd-daemon.h>
39
40/*
41 * is systemd running
42 */
43
44static bool
45check_systemd_running(void)
46{
47 struct stat c;
48
49 /* We simply test whether the systemd cgroup hierarchy is
50 * mounted, as well as the systemd-ask-password executable
51 * being available */
52
53 return (sd_booted() > 0) && (stat(SYSTEMD_ASK_PASSWORD_PATH, &c) == 0);
54}
55
56static bool
57get_console_input_systemd(const char *prompt, const bool echo, char *input, const int capacity)
58{
59 int std_out;
60 bool ret = false;
61 struct argv argv = argv_new();
62
63 argv_printf(&argv, SYSTEMD_ASK_PASSWORD_PATH);
64#ifdef SYSTEMD_NEWER_THAN_216
65 /* the --echo support arrived in upstream systemd 217 */
66 if (echo)
67 {
68 argv_printf_cat(&argv, "--echo");
69 }
70#endif
71 argv_printf_cat(&argv, "--icon network-vpn");
72 argv_printf_cat(&argv, "--timeout=0");
73 argv_printf_cat(&argv, "%s", prompt);
74
75 if ((std_out = openvpn_popen(&argv, NULL)) < 0)
76 {
77 return false;
78 }
79 memset(input, 0, capacity);
80 if (read(std_out, input, capacity - 1) != 0)
81 {
82 chomp(input);
83 ret = true;
84 }
85 close(std_out);
86
88
89 return ret;
90}
91
97bool
98query_user_exec_systemd(void)
99{
100 bool ret = true; /* Presume everything goes okay */
101 int i;
102
103 /* If systemd is not available, use the default built-in mechanism */
104 if (!check_systemd_running())
105 {
107 }
108
109 /* Loop through the complete query setup and when needed, collect the information */
110 for (i = 0; i < QUERY_USER_NUMSLOTS && query_user[i].response != NULL; i++)
111 {
112 if (!get_console_input_systemd(query_user[i].prompt, query_user[i].echo,
113 query_user[i].response, query_user[i].response_len))
114 {
115 /* Force the final result state to failed on failure */
116 ret = false;
117 }
118 }
119
120 return ret;
121}
122
123#endif /* ENABLE_SYSTEMD */
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition argv.c:101
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition argv.c:438
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
Definition argv.c:462
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition argv.c:87
void chomp(char *str)
Definition buffer.c:614
struct _query_user query_user[QUERY_USER_NUMSLOTS]
Global variable, declared in console.c.
Definition console.c:40
bool query_user_exec_builtin(void)
Loop through configured query_user slots, using the built-in method for querying the user.
#define QUERY_USER_NUMSLOTS
Definition console.h:42
@ read
int openvpn_popen(const struct argv *a, const struct env_set *es)
char * response
The user's response.
Definition console.h:37
Definition argv.h:35
size_t capacity
Definition argv.h:37