clients: polkit-agent: implement polkit agent without using libpolkit
This commit is contained in:
10
Makefile.am
10
Makefile.am
@@ -4255,6 +4255,8 @@ clients_common_libnmc_base_la_SOURCES = \
|
||||
clients/common/nm-vpn-helpers.h \
|
||||
clients/common/nm-client-utils.c \
|
||||
clients/common/nm-client-utils.h \
|
||||
clients/common/nm-polkit-listener.c \
|
||||
clients/common/nm-polkit-listener.h \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST += \
|
||||
@@ -4446,14 +4448,6 @@ clients_cli_nmcli_LDADD = \
|
||||
$(GLIB_LIBS) \
|
||||
$(READLINE_LIBS)
|
||||
|
||||
if WITH_POLKIT_AGENT
|
||||
clients_cli_nmcli_CPPFLAGS += $(POLKIT_CFLAGS)
|
||||
clients_cli_nmcli_SOURCES += \
|
||||
clients/common/nm-polkit-listener.c \
|
||||
clients/common/nm-polkit-listener.h
|
||||
clients_cli_nmcli_LDADD += $(POLKIT_LIBS)
|
||||
endif
|
||||
|
||||
clients_cli_nmcli_LDFLAGS = \
|
||||
-Wl,--version-script="$(srcdir)/linker-script-binary.ver" \
|
||||
$(SANITIZER_EXEC_LDFLAGS)
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "utils.h"
|
||||
#include "nm-secret-agent-simple.h"
|
||||
#include "polkit-agent.h"
|
||||
#include "nm-polkit-listener.h"
|
||||
|
||||
static void
|
||||
usage (void)
|
||||
@@ -149,27 +150,50 @@ do_agent_secret (NmCli *nmc, int argc, char **argv)
|
||||
return nmc->return_value;
|
||||
}
|
||||
|
||||
static void
|
||||
polkit_registered (gpointer instance,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_print (_("nmcli successfully registered as a polkit agent.\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
polkit_error (gpointer instance,
|
||||
const char *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
static NMCResultCode
|
||||
do_agent_polkit (NmCli *nmc, int argc, char **argv)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
next_arg (nmc, &argc, &argv, NULL);
|
||||
if (nmc->complete)
|
||||
return nmc->return_value;
|
||||
|
||||
/* Initialize polkit agent */
|
||||
if (!nmc_polkit_agent_init (nmc, TRUE, &error)) {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
g_string_printf (nmc->return_text, _("Error: polkit agent initialization failed: %s"),
|
||||
g_string_printf (nmc->return_text,
|
||||
_("Error: polkit agent initialization failed: %s"),
|
||||
error->message);
|
||||
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
||||
g_error_free (error);
|
||||
} else {
|
||||
/* We keep running */
|
||||
nmc->should_wait++;
|
||||
g_signal_connect (nmc->pk_listener,
|
||||
NM_POLKIT_LISTENER_SIGNAL_ERROR,
|
||||
G_CALLBACK (polkit_error),
|
||||
NULL);
|
||||
g_signal_connect (nmc->pk_listener,
|
||||
NM_POLKIT_LISTENER_SIGNAL_REGISTERED,
|
||||
G_CALLBACK (polkit_registered),
|
||||
NULL);
|
||||
|
||||
g_print (_("nmcli successfully registered as a polkit agent.\n"));
|
||||
/* keep running */
|
||||
nmc->should_wait++;
|
||||
}
|
||||
|
||||
return nmc->return_value;
|
||||
|
@@ -6,18 +6,6 @@ install_data(
|
||||
install_dir: join_paths(nm_datadir, 'bash-completion', 'completions'),
|
||||
)
|
||||
|
||||
sources = files(
|
||||
'agent.c',
|
||||
'common.c',
|
||||
'connections.c',
|
||||
'devices.c',
|
||||
'general.c',
|
||||
'nmcli.c',
|
||||
'polkit-agent.c',
|
||||
'settings.c',
|
||||
'utils.c',
|
||||
)
|
||||
|
||||
deps = [
|
||||
libnmc_base_dep,
|
||||
libnmc_dep,
|
||||
@@ -25,14 +13,19 @@ deps = [
|
||||
libnm_libnm_aux_dep,
|
||||
]
|
||||
|
||||
if enable_polkit_agent
|
||||
sources += nm_polkit_listener
|
||||
deps += polkit_agent_dep
|
||||
endif
|
||||
|
||||
executable(
|
||||
name,
|
||||
sources,
|
||||
files(
|
||||
'agent.c',
|
||||
'common.c',
|
||||
'connections.c',
|
||||
'devices.c',
|
||||
'general.c',
|
||||
'nmcli.c',
|
||||
'polkit-agent.c',
|
||||
'settings.c',
|
||||
'utils.c',
|
||||
),
|
||||
dependencies: deps,
|
||||
c_args: clients_c_flags + ['-DG_LOG_DOMAIN="@0@"'.format(name)],
|
||||
link_args: ldflags_linker_script_binary,
|
||||
|
@@ -14,15 +14,11 @@
|
||||
#include "nm-polkit-listener.h"
|
||||
#include "common.h"
|
||||
|
||||
#if WITH_POLKIT_AGENT
|
||||
static char *
|
||||
polkit_request (NMPolkitListener *listener,
|
||||
const char *request,
|
||||
polkit_read_passwd (gpointer instance,
|
||||
const char *action_id,
|
||||
const char *message,
|
||||
const char *icon_name,
|
||||
const char *user,
|
||||
gboolean echo_on,
|
||||
gpointer user_data)
|
||||
{
|
||||
NmCli *nmc = user_data;
|
||||
@@ -32,87 +28,68 @@ polkit_request (NMPolkitListener *listener,
|
||||
|
||||
/* Ask user for polkit authorization password */
|
||||
if (user) {
|
||||
gs_free char *tmp = NULL;
|
||||
char *p;
|
||||
|
||||
/* chop of ": " if present */
|
||||
tmp = g_strdup (request);
|
||||
p = strrchr (tmp, ':');
|
||||
if (p && nm_streq (p, ": "))
|
||||
*p = '\0';
|
||||
return nmc_readline_echo (&nmc->nmc_config, echo_on, "%s (%s): ", tmp, user);
|
||||
return nmc_readline_echo (&nmc->nmc_config, FALSE, "password (%s): ", user);
|
||||
}
|
||||
|
||||
return nmc_readline_echo (&nmc->nmc_config, echo_on, "%s", request);
|
||||
return nmc_readline_echo (&nmc->nmc_config, FALSE, "password: ");
|
||||
}
|
||||
|
||||
static void
|
||||
polkit_show_info (NMPolkitListener *listener,
|
||||
const char *text,
|
||||
polkit_error (gpointer instance,
|
||||
const char *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_print (_("Authentication message: %s\n"), text);
|
||||
g_printerr (_("Error: polkit agent failed: %s\n"), error);
|
||||
}
|
||||
|
||||
static void
|
||||
polkit_show_error (NMPolkitListener *listener,
|
||||
const char *text,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_print (_("Authentication error: %s\n"), text);
|
||||
}
|
||||
|
||||
static void
|
||||
polkit_completed (NMPolkitListener *listener,
|
||||
gboolean gained_authorization,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* We don't print anything here. The outcome will be evident from
|
||||
* the operation result anyway. */
|
||||
}
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
nmc_polkit_agent_init (NmCli* nmc, gboolean for_session, GError **error)
|
||||
{
|
||||
#if WITH_POLKIT_AGENT
|
||||
static const NMPolkitListenVtable vtable = {
|
||||
.on_request = polkit_request,
|
||||
.on_show_info = polkit_show_info,
|
||||
.on_show_error = polkit_show_error,
|
||||
.on_completed = polkit_completed,
|
||||
};
|
||||
NMPolkitListener *listener;
|
||||
GDBusConnection *dbus_connection = NULL;
|
||||
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
listener = nm_polkit_listener_new (for_session, error);
|
||||
if (!listener)
|
||||
return FALSE;
|
||||
if (nmc->client && nm_client_get_dbus_connection (nmc->client)) {
|
||||
dbus_connection = nm_client_get_dbus_connection (nmc->client);
|
||||
listener = nm_polkit_listener_new (dbus_connection, for_session);
|
||||
} else {
|
||||
dbus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM,
|
||||
NULL,
|
||||
error);
|
||||
|
||||
nm_polkit_listener_set_vtable (listener, &vtable, nmc);
|
||||
if (!dbus_connection) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
listener = nm_polkit_listener_new (dbus_connection, for_session);
|
||||
g_object_unref (dbus_connection);
|
||||
}
|
||||
|
||||
g_signal_connect (listener,
|
||||
NM_POLKIT_LISTENER_SIGNAL_REQUEST,
|
||||
G_CALLBACK (polkit_read_passwd),
|
||||
nmc);
|
||||
g_signal_connect (listener,
|
||||
NM_POLKIT_LISTENER_SIGNAL_ERROR,
|
||||
G_CALLBACK (polkit_error),
|
||||
NULL);
|
||||
|
||||
nmc->pk_listener = listener;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nmc_polkit_agent_fini (NmCli* nmc)
|
||||
{
|
||||
#if WITH_POLKIT_AGENT
|
||||
if (nmc->pk_listener) {
|
||||
nm_polkit_listener_set_vtable (nmc->pk_listener, NULL, NULL);
|
||||
g_clear_object (&nmc->pk_listener);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmc_start_polkit_agent_start_try (NmCli *nmc)
|
||||
{
|
||||
#if WITH_POLKIT_AGENT
|
||||
GError *error = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
/* We don't register polkit agent at all when running non-interactively */
|
||||
if (!nmc->ask)
|
||||
@@ -121,9 +98,7 @@ nmc_start_polkit_agent_start_try (NmCli *nmc)
|
||||
if (!nmc_polkit_agent_init (nmc, FALSE, &error)) {
|
||||
g_printerr (_("Warning: polkit agent initialization failed: %s\n"),
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -1,7 +1,5 @@
|
||||
common_inc = include_directories('.')
|
||||
|
||||
nm_polkit_listener = files('nm-polkit-listener.c')
|
||||
|
||||
common_deps = [
|
||||
libnm_dep,
|
||||
libnm_nm_default_dep,
|
||||
@@ -13,6 +11,7 @@ sources = files(
|
||||
'nm-client-utils.c',
|
||||
'nm-secret-agent-simple.c',
|
||||
'nm-vpn-helpers.c',
|
||||
'nm-polkit-listener.c',
|
||||
)
|
||||
|
||||
libnmc_base = static_library(
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -6,133 +6,16 @@
|
||||
#ifndef __NM_POLKIT_LISTENER_H__
|
||||
#define __NM_POLKIT_LISTENER_H__
|
||||
|
||||
#if WITH_POLKIT_AGENT
|
||||
|
||||
typedef struct _NMPolkitListener NMPolkitListener;
|
||||
typedef struct _NMPolkitListenerClass NMPolkitListenerClass;
|
||||
|
||||
typedef struct {
|
||||
|
||||
/*
|
||||
* @request: the request asked by polkit agent
|
||||
* @action_id: the action_id of the polkit request
|
||||
* @message: the message of the polkit request
|
||||
* @icon_name: the icon name of the polkit request
|
||||
* @user: user name
|
||||
* @echo_on: whether the response to the request should be echoed to the screen
|
||||
* @user_data: user data for the callback
|
||||
*
|
||||
* Called as a result of a request by polkit. The function should obtain response
|
||||
* to the request from user, i.e. get the password required.
|
||||
*/
|
||||
char *(*on_request) (NMPolkitListener *self,
|
||||
const char *request,
|
||||
const char *action_id,
|
||||
const char *message,
|
||||
const char *icon_name,
|
||||
const char *user,
|
||||
gboolean echo_on,
|
||||
gpointer user_data);
|
||||
|
||||
/*
|
||||
* @text: the info text from polkit
|
||||
*
|
||||
* Called as a result of show-info signal by polkit.
|
||||
*/
|
||||
void (*on_show_info) (NMPolkitListener *self,
|
||||
const char *text,
|
||||
gpointer user_data);
|
||||
|
||||
/*
|
||||
* @text: the error text from polkit
|
||||
*
|
||||
* Called as a result of show-error signal by polkit.
|
||||
*/
|
||||
void (*on_show_error) (NMPolkitListener *self,
|
||||
const char *text,
|
||||
gpointer user_data);
|
||||
|
||||
/*
|
||||
* @gained_authorization: whether the authorization was successful
|
||||
*
|
||||
* Called as a result of completed signal by polkit.
|
||||
*/
|
||||
void (*on_completed) (NMPolkitListener *self,
|
||||
gboolean gained_authorization,
|
||||
gpointer user_data);
|
||||
} NMPolkitListenVtable;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE
|
||||
#include <polkitagent/polkitagent.h>
|
||||
|
||||
#define NM_TYPE_POLKIT_LISTENER (nm_polkit_listener_get_type ())
|
||||
#define NM_POLKIT_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_POLKIT_LISTENER, NMPolkitListener))
|
||||
#define NM_POLKIT_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_POLKIT_LISTENER, NMPolkitListenerClass))
|
||||
#define NM_IS_POLKIT_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_POLKIT_LISTENER))
|
||||
#define NM_IS_POLKIT_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_POLKIT_LISTENER))
|
||||
#define NM_POLKIT_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_POLKIT_LISTENER, NMPolkitListenerClass))
|
||||
G_DECLARE_FINAL_TYPE (NMPolkitListener, nm_polkit_listener, NM, POLKIT_LISTENER, GObject)
|
||||
|
||||
/**
|
||||
* NMPolkitListenerOnRequestFunc:
|
||||
* @request: the request asked by polkit agent
|
||||
* @action_id: the action_id of the polkit request
|
||||
* @message: the message of the polkit request
|
||||
* @icon_name: the icon name of the polkit request
|
||||
* @user: user name
|
||||
* @echo_on: whether the response to the request should be echoed to the screen
|
||||
* @user_data: user data for the callback
|
||||
*
|
||||
* Called as a result of a request by polkit. The function should obtain response
|
||||
* to the request from user, i.e. get the password required.
|
||||
*/
|
||||
typedef char * (*NMPolkitListenerOnRequestFunc) (const char *request,
|
||||
const char *action_id,
|
||||
const char *message,
|
||||
const char *icon_name,
|
||||
const char *user,
|
||||
gboolean echo_on,
|
||||
gpointer user_data);
|
||||
/**
|
||||
* NMPolkitListenerOnShowInfoFunc:
|
||||
* @text: the info text from polkit
|
||||
*
|
||||
* Called as a result of show-info signal by polkit.
|
||||
*/
|
||||
typedef void (*NMPolkitListenerOnShowInfoFunc) (const char *text);
|
||||
/**
|
||||
* NMPolkitListenerOnShowErrorFunc:
|
||||
* @text: the error text from polkit
|
||||
*
|
||||
* Called as a result of show-error signal by polkit.
|
||||
*/
|
||||
typedef void (*NMPolkitListenerOnShowErrorFunc) (const char *text);
|
||||
/**
|
||||
* NMPolkitListenerCompletedFunc:
|
||||
* @gained_authorization: whether the authorization was successful
|
||||
*
|
||||
* Called as a result of completed signal by polkit.
|
||||
*/
|
||||
typedef void (*NMPolkitListenerOnCompletedFunc) (gboolean gained_authorization);
|
||||
NMPolkitListener *nm_polkit_listener_new (GDBusConnection *dbus_connection, gboolean session_agent);
|
||||
|
||||
struct _NMPolkitListener {
|
||||
PolkitAgentListener parent;
|
||||
};
|
||||
|
||||
struct _NMPolkitListenerClass {
|
||||
PolkitAgentListenerClass parent;
|
||||
};
|
||||
|
||||
GType nm_polkit_listener_get_type (void);
|
||||
|
||||
NMPolkitListener *nm_polkit_listener_new (gboolean for_session,
|
||||
GError **error);
|
||||
|
||||
void nm_polkit_listener_set_vtable (NMPolkitListener *self,
|
||||
const NMPolkitListenVtable *vtable,
|
||||
gpointer user_data);
|
||||
|
||||
#endif
|
||||
/* Signals */
|
||||
#define NM_POLKIT_LISTENER_SIGNAL_REGISTERED "registered"
|
||||
#define NM_POLKIT_LISTENER_SIGNAL_REQUEST "secret-request"
|
||||
#define NM_POLKIT_LISTENER_SIGNAL_AUTH_SUCCESS "auth-success"
|
||||
#define NM_POLKIT_LISTENER_SIGNAL_AUTH_FAILURE "auth-failure"
|
||||
#define NM_POLKIT_LISTENER_SIGNAL_ERROR "error"
|
||||
|
||||
#endif /* __NM_POLKIT_LISTENER_H__ */
|
||||
|
@@ -221,8 +221,8 @@
|
||||
/* Define if you have oFono support (experimental) */
|
||||
#mesondefine WITH_OFONO
|
||||
|
||||
/* Define if you have polkit agent */
|
||||
#mesondefine WITH_POLKIT_AGENT
|
||||
/* Define the polkit agent package prefix */
|
||||
#mesondefine POLKIT_PACKAGE_PREFIX
|
||||
|
||||
/* Define if you have PPP support */
|
||||
#mesondefine WITH_PPP
|
||||
|
16
configure.ac
16
configure.ac
@@ -655,18 +655,13 @@ AC_DEFINE_UNQUOTED(NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT, "$enable_polkit", [The de
|
||||
AC_SUBST(NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT_TEXT, "$enable_polkit")
|
||||
|
||||
PKG_CHECK_MODULES(POLKIT, [polkit-agent-1 >= 0.97], [have_pk_agent=yes],[have_pk_agent=no])
|
||||
AC_ARG_ENABLE(polkit-agent,
|
||||
AS_HELP_STRING([--enable-polkit-agent], [enable polkit agent for clients]),
|
||||
[enable_polkit_agent=${enableval}], [enable_polkit_agent=${have_pk_agent}])
|
||||
if (test "${enable_polkit_agent}" = "yes"); then
|
||||
if test x"$have_pk_agent" = x"no"; then
|
||||
if test x"$have_pk_agent" = x"no"; then
|
||||
AC_MSG_ERROR(Polkit agent is required)
|
||||
fi
|
||||
AC_DEFINE(WITH_POLKIT_AGENT, 1, [Define if you have polkit agent])
|
||||
else
|
||||
AC_DEFINE(WITH_POLKIT_AGENT, 0, [Define if you have polkit agent])
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_POLKIT_AGENT, test "${enable_polkit_agent}" = "yes")
|
||||
POLKIT_PACKAGE_PREFIX=`$PKG_CONFIG --variable=prefix polkit-agent-1`
|
||||
AC_DEFINE_UNQUOTED([POLKIT_PACKAGE_PREFIX],
|
||||
["$POLKIT_PACKAGE_PREFIX"],
|
||||
[polkit-agent package prefix])
|
||||
|
||||
AC_ARG_ENABLE(modify-system, AS_HELP_STRING([--enable-modify-system], [Allow users to modify system connections]))
|
||||
if test "${enable_modify_system}" = "yes"; then
|
||||
@@ -1323,7 +1318,6 @@ if test "${enable_modify_system}" = "yes"; then
|
||||
else
|
||||
echo " policykit: main.auth-polkit=${enable_polkit} (restrictive modify.system)"
|
||||
fi
|
||||
echo " polkit agent: ${enable_polkit_agent}"
|
||||
echo " selinux: $have_selinux"
|
||||
echo " systemd-journald: $have_systemd_journal (default: logging.backend=${nm_config_logging_backend_default})"
|
||||
echo " hostname persist: ${hostname_persist}"
|
||||
|
@@ -586,7 +586,6 @@ This tool is still experimental.
|
||||
-Dselinux=true \
|
||||
-Dpolkit=true \
|
||||
-Dconfig_auth_polkit_default=true \
|
||||
-Dpolkit_agent=true \
|
||||
-Dmodify_system=true \
|
||||
-Dconcheck=true \
|
||||
%if 0%{?fedora}
|
||||
@@ -717,7 +716,6 @@ intltoolize --automake --copy --force
|
||||
%endif
|
||||
--with-selinux=yes \
|
||||
--enable-polkit=yes \
|
||||
--enable-polkit-agent \
|
||||
--enable-modify-system=yes \
|
||||
--enable-concheck \
|
||||
%if 0%{?fedora}
|
||||
|
10
meson.build
10
meson.build
@@ -494,11 +494,12 @@ config_h.set_quoted('NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT', config_auth_polkit_def
|
||||
|
||||
enable_modify_system = get_option('modify_system')
|
||||
|
||||
enable_polkit_agent = get_option('polkit_agent')
|
||||
if enable_polkit_agent
|
||||
polkit_agent_dep = dependency('polkit-agent-1', version: '>= 0.97')
|
||||
polkit_agent_dep = dependency('polkit-agent-1', version: '>= 0.97', required : false)
|
||||
if polkit_agent_dep.found()
|
||||
config_h.set_quoted('POLKIT_PACKAGE_PREFIX', polkit_agent_dep.get_pkgconfig_variable('prefix'))
|
||||
else
|
||||
config_h.set_quoted('POLKIT_PACKAGE_PREFIX', '/usr')
|
||||
endif
|
||||
config_h.set10('WITH_POLKIT_AGENT', enable_polkit_agent)
|
||||
|
||||
|
||||
crypto = get_option('crypto')
|
||||
@@ -971,7 +972,6 @@ if enable_polkit
|
||||
output += ' modify.system)'
|
||||
endif
|
||||
output += '\n'
|
||||
output += ' polkit agent: ' + enable_polkit_agent.to_string() + '\n'
|
||||
output += ' selinux: ' + enable_selinux.to_string() + '\n'
|
||||
output += ' systemd-journald: ' + enable_systemd_journal.to_string() + ' (default: logging.backend=' + config_logging_backend_default + ')\n'
|
||||
output += ' hostname persist: ' + hostname_persist + '\n'
|
||||
|
Reference in New Issue
Block a user