3280d8c8 |
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
* Copyright (C) 2016 David Sommerseth <dazo@privateinternetaccess.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* |
caa54ac3 |
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
3280d8c8 |
*/
/**
* @file Alternative method to query for user input, using systemd
*
*/
#include "config.h"
#ifdef ENABLE_SYSTEMD
#include "syshead.h"
#include "console.h"
#include "misc.h" |
02b392a2 |
#include "run_command.h" |
3280d8c8 |
#include <systemd/sd-daemon.h>
/*
* is systemd running
*/
static bool |
e2a0cad4 |
check_systemd_running(void) |
3280d8c8 |
{
struct stat c;
/* We simply test whether the systemd cgroup hierarchy is
* mounted, as well as the systemd-ask-password executable
* being available */
return (sd_booted() > 0) |
81d882d5 |
&& (stat(SYSTEMD_ASK_PASSWORD_PATH, &c) == 0); |
3280d8c8 |
}
static bool |
81d882d5 |
get_console_input_systemd(const char *prompt, const bool echo, char *input, const int capacity) |
3280d8c8 |
{
int std_out;
bool ret = false; |
81d882d5 |
struct argv argv = argv_new(); |
3280d8c8 |
|
81d882d5 |
argv_printf(&argv, SYSTEMD_ASK_PASSWORD_PATH); |
8ba3e258 |
#ifdef SYSTEMD_NEWER_THAN_216
/* the --echo support arrived in upstream systemd 217 */ |
81d882d5 |
if (echo) |
8ba3e258 |
{ |
81d882d5 |
argv_printf_cat(&argv, "--echo"); |
8ba3e258 |
}
#endif |
81d882d5 |
argv_printf_cat(&argv, "--icon network-vpn");
argv_printf_cat(&argv, "%s", prompt); |
3280d8c8 |
|
81d882d5 |
if ((std_out = openvpn_popen(&argv, NULL)) < 0)
{
return false; |
3280d8c8 |
} |
81d882d5 |
memset(input, 0, capacity);
if (read(std_out, input, capacity-1) != 0) |
3280d8c8 |
{ |
81d882d5 |
chomp(input);
ret = true; |
3280d8c8 |
} |
81d882d5 |
close(std_out); |
3280d8c8 |
|
81d882d5 |
argv_reset(&argv); |
3280d8c8 |
return ret;
}
/**
* Systemd aware implementation of query_user_exec(). If systemd is not running
* it will fall back to use query_user_exec_builtin() instead.
*
*/ |
81d882d5 |
bool |
e2a0cad4 |
query_user_exec(void) |
3280d8c8 |
{
bool ret = true; /* Presume everything goes okay */
int i;
/* If systemd is not available, use the default built-in mechanism */
if (!check_systemd_running())
{
return query_user_exec_builtin();
}
/* Loop through the complete query setup and when needed, collect the information */
for (i = 0; i < QUERY_USER_NUMSLOTS && query_user[i].response != NULL; i++)
{ |
81d882d5 |
if (!get_console_input_systemd(query_user[i].prompt, query_user[i].echo,
query_user[i].response, query_user[i].response_len) )
{
/* Force the final result state to failed on failure */
ret = false;
} |
3280d8c8 |
}
return ret;
}
#endif /* ENABLE_SYSTEMD */ |