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 d09fbf958f 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
This commit is contained in:
David Sommerseth 2016-08-12 12:57:25 +02:00
parent 430ce8bd03
commit 3280d8c8f3
4 changed files with 120 additions and 5 deletions

View File

@ -1017,7 +1017,7 @@ fi
dnl
dnl Check for systemd
dnl
AM_CONDITIONAL([ENABLE_SYSTEMD], [test "${enable_systemd}" = "yes"])
if test "$enable_systemd" = "yes" ; then
PKG_CHECK_MODULES([libsystemd], [systemd libsystemd],
[],

View File

@ -68,7 +68,7 @@ openvpn_SOURCES = \
memdbg.h \
misc.c misc.h \
platform.c platform.h \
console.c console.h console_builtin.c \
console.c console.h console_builtin.c console_systemd.c \
mroute.c mroute.h \
mss.c mss.h \
mstats.c mstats.h \

View File

@ -76,7 +76,7 @@ void query_user_add (char *prompt, size_t prompt_len,
bool query_user_exec_builtin ();
#ifdef QUERY_USER_EXEC_ALTERNATIVE
#if defined(ENABLE_SYSTEMD)
/**
* Executes a configured setup, using the compiled method for querying the user
*
@ -86,7 +86,7 @@ bool query_user_exec_builtin ();
*/
bool query_user_exec ();
#else /* QUERY_USER_EXEC_ALTERNATIVE not defined*/
#else /* ENABLE_SYSTEMD not defined*/
/**
* Wrapper function enabling query_user_exec() if no alternative methods have
* been enabled
@ -96,7 +96,7 @@ static bool query_user_exec ()
{
return query_user_exec_builtin();
}
#endif /* QUERY_USER_EXEC_ALTERNATIVE */
#endif /* defined(ENABLE_SYSTEMD) */
/**

View File

@ -0,0 +1,115 @@
/*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* @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"
#include <systemd/sd-daemon.h>
/*
* is systemd running
*/
static bool
check_systemd_running ()
{
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)
&& (stat(SYSTEMD_ASK_PASSWORD_PATH, &c) == 0);
}
static bool
get_console_input_systemd (const char *prompt, const bool echo, char *input, const int capacity)
{
int std_out;
bool ret = false;
struct argv argv;
argv_init (&argv);
argv_printf (&argv, SYSTEMD_ASK_PASSWORD_PATH);
argv_printf_cat (&argv, "%s", prompt);
if ((std_out = openvpn_popen (&argv, NULL)) < 0) {
return false;
}
memset (input, 0, capacity);
if (read (std_out, input, capacity-1) != 0)
{
chomp (input);
ret = true;
}
close (std_out);
argv_reset (&argv);
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.
*
*/
bool query_user_exec()
{
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++)
{
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;
}
}
return ret;
}
#endif /* ENABLE_SYSTEMD */