|
Packit Service |
dff8e4 |
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
Packit Service |
dff8e4 |
/*
|
|
Packit Service |
dff8e4 |
* Copyright (C) 2014 Red Hat, Inc.
|
|
Packit Service |
dff8e4 |
*/
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
#include "libnm-client-aux-extern/nm-default-client.h"
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
#include <stdio.h>
|
|
Packit Service |
dff8e4 |
#include <stdlib.h>
|
|
Packit Service |
dff8e4 |
#include <readline/readline.h>
|
|
Packit Service |
dff8e4 |
#include <readline/history.h>
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
#include "common.h"
|
|
Packit Service |
dff8e4 |
#include "utils.h"
|
|
Packit Service |
dff8e4 |
#include "libnmc-base/nm-secret-agent-simple.h"
|
|
Packit Service |
dff8e4 |
#include "polkit-agent.h"
|
|
Packit Service |
dff8e4 |
#include "libnmc-base/nm-polkit-listener.h"
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
usage(void)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
g_printerr(_("Usage: nmcli agent { COMMAND | help }\n\n"
|
|
Packit Service |
dff8e4 |
"COMMAND := { secret | polkit | all }\n\n"));
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
usage_agent_secret(void)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
g_printerr(_("Usage: nmcli agent secret { help }\n"
|
|
Packit Service |
dff8e4 |
"\n"
|
|
Packit Service |
dff8e4 |
"Runs nmcli as NetworkManager secret agent. When NetworkManager requires\n"
|
|
Packit Service |
dff8e4 |
"a password it asks registered agents for it. This command keeps nmcli running\n"
|
|
Packit Service |
dff8e4 |
"and if a password is required asks the user for it.\n\n"));
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
usage_agent_polkit(void)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
g_printerr(_("Usage: nmcli agent polkit { help }\n"
|
|
Packit Service |
dff8e4 |
"\n"
|
|
Packit Service |
dff8e4 |
"Registers nmcli as a polkit action for the user session.\n"
|
|
Packit Service |
dff8e4 |
"When a polkit daemon requires an authorization, nmcli asks the user and gives\n"
|
|
Packit Service |
dff8e4 |
"the response back to polkit.\n\n"));
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
usage_agent_all(void)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
g_printerr(_("Usage: nmcli agent all { help }\n"
|
|
Packit Service |
dff8e4 |
"\n"
|
|
Packit Service |
dff8e4 |
"Runs nmcli as both NetworkManager secret and a polkit agent.\n\n"));
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
/* for pre-filling a string to readline prompt */
|
|
Packit Service |
dff8e4 |
static char *pre_input_deftext;
|
|
Packit Service |
dff8e4 |
static int
|
|
Packit Service |
dff8e4 |
set_deftext(void)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
if (pre_input_deftext && rl_startup_hook) {
|
|
Packit Service |
dff8e4 |
rl_insert_text(pre_input_deftext);
|
|
Packit Service |
dff8e4 |
g_free(pre_input_deftext);
|
|
Packit Service |
dff8e4 |
pre_input_deftext = NULL;
|
|
Packit Service |
dff8e4 |
rl_startup_hook = NULL;
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
return 0;
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static gboolean
|
|
Packit Service |
dff8e4 |
get_secrets_from_user(const NmcConfig *nmc_config,
|
|
Packit Service |
dff8e4 |
const char * request_id,
|
|
Packit Service |
dff8e4 |
const char * title,
|
|
Packit Service |
dff8e4 |
const char * msg,
|
|
Packit Service |
dff8e4 |
GPtrArray * secrets)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
int i;
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
for (i = 0; i < secrets->len; i++) {
|
|
Packit Service |
dff8e4 |
NMSecretAgentSimpleSecret *secret = secrets->pdata[i];
|
|
Packit Service |
dff8e4 |
char * pwd = NULL;
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
/* Ask user for the password */
|
|
Packit Service |
dff8e4 |
if (msg)
|
|
Packit Service |
dff8e4 |
g_print("%s\n", msg);
|
|
Packit Service |
dff8e4 |
if (secret->value) {
|
|
Packit Service |
dff8e4 |
/* Prefill the password if we have it. */
|
|
Packit Service |
dff8e4 |
rl_startup_hook = set_deftext;
|
|
Packit Service |
dff8e4 |
pre_input_deftext = g_strdup(secret->value);
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
if (secret->no_prompt_entry_id)
|
|
Packit Service |
dff8e4 |
pwd = nmc_readline(nmc_config, "%s: ", secret->pretty_name);
|
|
Packit Service |
dff8e4 |
else
|
|
Packit Service |
dff8e4 |
pwd = nmc_readline(nmc_config, "%s (%s): ", secret->pretty_name, secret->entry_id);
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
/* No password provided, cancel the secrets. */
|
|
Packit Service |
dff8e4 |
if (!pwd)
|
|
Packit Service |
dff8e4 |
return FALSE;
|
|
Packit Service |
dff8e4 |
g_free(secret->value);
|
|
Packit Service |
dff8e4 |
secret->value = pwd;
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
return TRUE;
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
secrets_requested(NMSecretAgentSimple *agent,
|
|
Packit Service |
dff8e4 |
const char * request_id,
|
|
Packit Service |
dff8e4 |
const char * title,
|
|
Packit Service |
dff8e4 |
const char * msg,
|
|
Packit Service |
dff8e4 |
GPtrArray * secrets,
|
|
Packit Service |
dff8e4 |
gpointer user_data)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
NmCli * nmc = user_data;
|
|
Packit Service |
dff8e4 |
gboolean success;
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
if (nmc->nmc_config.print_output == NMC_PRINT_PRETTY)
|
|
Packit Service |
dff8e4 |
nmc_terminal_erase_line();
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
success = get_secrets_from_user(&nmc->nmc_config, request_id, title, msg, secrets);
|
|
Packit Service |
dff8e4 |
nm_secret_agent_simple_response(agent, request_id, success ? secrets : NULL);
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
do_agent_secret(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
next_arg(nmc, &argc, &argv, NULL);
|
|
Packit Service |
dff8e4 |
if (nmc->complete)
|
|
Packit Service |
dff8e4 |
return;
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
/* Create secret agent */
|
|
Packit Service |
dff8e4 |
nmc->secret_agent = nm_secret_agent_simple_new("nmcli-agent");
|
|
Packit Service |
dff8e4 |
if (nmc->secret_agent) {
|
|
Packit Service |
dff8e4 |
/* We keep running */
|
|
Packit Service |
dff8e4 |
nmc->should_wait++;
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
nm_secret_agent_simple_enable(nmc->secret_agent, NULL);
|
|
Packit Service |
dff8e4 |
g_signal_connect(nmc->secret_agent,
|
|
Packit Service |
dff8e4 |
NM_SECRET_AGENT_SIMPLE_REQUEST_SECRETS,
|
|
Packit Service |
dff8e4 |
G_CALLBACK(secrets_requested),
|
|
Packit Service |
dff8e4 |
nmc);
|
|
Packit Service |
dff8e4 |
g_print(_("nmcli successfully registered as a NetworkManager's secret agent.\n"));
|
|
Packit Service |
dff8e4 |
} else {
|
|
Packit Service |
dff8e4 |
g_string_printf(nmc->return_text, _("Error: secret agent initialization failed"));
|
|
Packit Service |
dff8e4 |
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
polkit_registered(gpointer instance, gpointer user_data)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
g_print(_("nmcli successfully registered as a polkit agent.\n"));
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
polkit_error(gpointer instance, const char *error, gpointer user_data)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
g_main_loop_quit(loop);
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
do_agent_polkit(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
gs_free_error GError *error = NULL;
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
next_arg(nmc, &argc, &argv, NULL);
|
|
Packit Service |
dff8e4 |
if (nmc->complete)
|
|
Packit Service |
dff8e4 |
return;
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
if (!nmc_polkit_agent_init(nmc, TRUE, &error)) {
|
|
Packit Service |
dff8e4 |
g_dbus_error_strip_remote_error(error);
|
|
Packit Service |
dff8e4 |
g_string_printf(nmc->return_text,
|
|
Packit Service |
dff8e4 |
_("Error: polkit agent initialization failed: %s"),
|
|
Packit Service |
dff8e4 |
error->message);
|
|
Packit Service |
dff8e4 |
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
|
Packit Service |
dff8e4 |
} else {
|
|
Packit Service |
dff8e4 |
/* We keep running */
|
|
Packit Service |
dff8e4 |
nmc->should_wait++;
|
|
Packit Service |
dff8e4 |
g_signal_connect(nmc->pk_listener,
|
|
Packit Service |
dff8e4 |
NM_POLKIT_LISTENER_SIGNAL_ERROR,
|
|
Packit Service |
dff8e4 |
G_CALLBACK(polkit_error),
|
|
Packit Service |
dff8e4 |
NULL);
|
|
Packit Service |
dff8e4 |
g_signal_connect(nmc->pk_listener,
|
|
Packit Service |
dff8e4 |
NM_POLKIT_LISTENER_SIGNAL_REGISTERED,
|
|
Packit Service |
dff8e4 |
G_CALLBACK(polkit_registered),
|
|
Packit Service |
dff8e4 |
NULL);
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
/* keep running */
|
|
Packit Service |
dff8e4 |
nmc->should_wait++;
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
static void
|
|
Packit Service |
dff8e4 |
do_agent_all(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
NMCResultCode r;
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
next_arg(nmc, &argc, &argv, NULL);
|
|
Packit Service |
dff8e4 |
if (nmc->complete)
|
|
Packit Service |
dff8e4 |
return;
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
/* Run both secret and polkit agent */
|
|
Packit Service |
dff8e4 |
do_agent_secret(cmd, nmc, argc, argv);
|
|
Packit Service |
dff8e4 |
r = nmc->return_value;
|
|
Packit Service |
dff8e4 |
if (r != NMC_RESULT_SUCCESS) {
|
|
Packit Service |
dff8e4 |
g_printerr("%s\n", nmc->return_text->str);
|
|
Packit Service |
dff8e4 |
g_string_truncate(nmc->return_text, 0);
|
|
Packit Service |
dff8e4 |
nmc->return_value = NMC_RESULT_SUCCESS;
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
do_agent_polkit(cmd, nmc, argc, argv);
|
|
Packit Service |
dff8e4 |
if (nmc->return_value != NMC_RESULT_SUCCESS) {
|
|
Packit Service |
dff8e4 |
g_printerr("%s\n", nmc->return_text->str);
|
|
Packit Service |
dff8e4 |
g_string_truncate(nmc->return_text, 0);
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
if (r != NMC_RESULT_SUCCESS)
|
|
Packit Service |
dff8e4 |
nmc->return_value = r;
|
|
Packit Service |
dff8e4 |
}
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
void
|
|
Packit Service |
dff8e4 |
nmc_command_func_agent(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv)
|
|
Packit Service |
dff8e4 |
{
|
|
Packit Service |
dff8e4 |
static const NMCCommand cmds[] = {
|
|
Packit Service |
dff8e4 |
{"secret", do_agent_secret, usage_agent_secret, TRUE, TRUE},
|
|
Packit Service |
dff8e4 |
{"polkit", do_agent_polkit, usage_agent_polkit, TRUE, TRUE},
|
|
Packit Service |
dff8e4 |
{"all", do_agent_all, usage_agent_all, TRUE, TRUE},
|
|
Packit Service |
dff8e4 |
{NULL, do_agent_all, usage, TRUE, TRUE},
|
|
Packit Service |
dff8e4 |
};
|
|
Packit Service |
dff8e4 |
|
|
Packit Service |
dff8e4 |
next_arg(nmc, &argc, &argv, NULL);
|
|
Packit Service |
dff8e4 |
nmc_do_cmd(nmc, cmds, *argv, argc, argv);
|
|
Packit Service |
dff8e4 |
}
|