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, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
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 
44 static bool
45 check_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)
54  && (stat(SYSTEMD_ASK_PASSWORD_PATH, &c) == 0);
55 
56 }
57 
58 static bool
59 get_console_input_systemd(const char *prompt, const bool echo, char *input, const int capacity)
60 {
61  int std_out;
62  bool ret = false;
63  struct argv argv = argv_new();
64 
66 #ifdef SYSTEMD_NEWER_THAN_216
67  /* the --echo support arrived in upstream systemd 217 */
68  if (echo)
69  {
70  argv_printf_cat(&argv, "--echo");
71  }
72 #endif
73  argv_printf_cat(&argv, "--icon network-vpn");
74  argv_printf_cat(&argv, "%s", prompt);
75 
76  if ((std_out = openvpn_popen(&argv, NULL)) < 0)
77  {
78  return false;
79  }
80  memset(input, 0, capacity);
81  if (read(std_out, input, capacity-1) != 0)
82  {
83  chomp(input);
84  ret = true;
85  }
86  close(std_out);
87 
88  argv_free(&argv);
89 
90  return ret;
91 }
92 
98 bool
99 query_user_exec(void)
100 {
101  bool ret = true; /* Presume everything goes okay */
102  int i;
103 
104  /* If systemd is not available, use the default built-in mechanism */
105  if (!check_systemd_running())
106  {
107  return query_user_exec_builtin();
108  }
109 
110  /* Loop through the complete query setup and when needed, collect the information */
111  for (i = 0; i < QUERY_USER_NUMSLOTS && query_user[i].response != NULL; i++)
112  {
113  if (!get_console_input_systemd(query_user[i].prompt, query_user[i].echo,
114  query_user[i].response, query_user[i].response_len) )
115  {
116  /* Force the final result state to failed on failure */
117  ret = false;
118  }
119  }
120 
121  return ret;
122 }
123 
124 #endif /* ENABLE_SYSTEMD */
run_command.h
argv
Definition: argv.h:35
argv_printf_cat
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
Definition: argv.c:464
query_user
struct _query_user query_user[QUERY_USER_NUMSLOTS]
Global variable, declared in console.c.
Definition: console.c:41
argv_free
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition: argv.c:102
console.h
query_user_exec_builtin
bool query_user_exec_builtin(void)
Executes a configured setup, using the built-in method for querying the user.
Definition: console_builtin.c:281
read
@ read
Definition: interactive.c:218
query_user_exec
static bool query_user_exec(void)
Wrapper function enabling query_user_exec() if no alternative methods have been enabled.
Definition: console.h:95
misc.h
argv::capacity
size_t capacity
Definition: argv.h:37
QUERY_USER_NUMSLOTS
#define QUERY_USER_NUMSLOTS
Definition: console.h:42
syshead.h
argv_new
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition: argv.c:88
argv_printf
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition: argv.c:440
chomp
void chomp(char *str)
Definition: buffer.c:632
_query_user::response
char * response
The user's response.
Definition: console.h:37
SYSTEMD_ASK_PASSWORD_PATH
#define SYSTEMD_ASK_PASSWORD_PATH
Definition: config.h:540
openvpn_popen
int openvpn_popen(const struct argv *a, const struct env_set *es)
Definition: run_command.c:230
config.h