cli: use secret agent for getting passwords from user

--ask option has to be used, so that nmcli can be interactive.
This commit is contained in:
Jiří Klimeš 2014-10-06 15:25:53 +02:00
parent b41cb60b45
commit de7f85bdec
4 changed files with 85 additions and 14 deletions

View file

@ -9,6 +9,7 @@ AM_CPPFLAGS = \
-I${top_builddir}/libnm-core \
-I${top_srcdir}/libnm \
-I${top_builddir}/libnm \
-I${top_srcdir}/clients/common \
$(GLIB_CFLAGS) \
-DG_LOG_DOMAIN=\""nmcli"\" \
-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
@ -28,7 +29,11 @@ nmcli_SOURCES = \
nmcli.c \
nmcli.h \
utils.c \
utils.h
utils.h \
\
$(srcdir)/../common/nm-secret-agent-simple.c \
$(srcdir)/../common/nm-secret-agent-simple.h \
$(NULL)
nmcli_LDADD = \
$(GLIB_LIBS) \

View file

@ -35,6 +35,7 @@
#include "common.h"
#include "settings.h"
#include "connections.h"
#include "nm-secret-agent-simple.h"
/* define some prompts for connection editor */
#define EDITOR_PROMPT_SETTING _("Setting name? ")
@ -507,6 +508,20 @@ quit (void)
g_main_loop_quit (loop); /* quit main loop */
}
/* for pre-filling a string to readline prompt */
static char *pre_input_deftext;
static int
set_deftext (void)
{
if (pre_input_deftext && rl_startup_hook) {
rl_insert_text (pre_input_deftext);
g_free (pre_input_deftext);
pre_input_deftext = NULL;
rl_startup_hook = NULL;
}
return 0;
}
static const char *
construct_header_name (const char *base, const char *spec)
{
@ -1926,6 +1941,57 @@ activate_connection_cb (GObject *client, GAsyncResult *result, gpointer user_dat
g_free (info);
}
static gboolean
get_secrets_from_user (const char *request_id,
const char *title,
const char *msg,
GPtrArray *secrets)
{
int i;
char *pwd;
g_print ("%s\n", msg);
for (i = 0; i < secrets->len; i++) {
NMSecretAgentSimpleSecret *secret = secrets->pdata[i];
if (secret->value) {
/* Prefill the password if we have it. */
rl_startup_hook = set_deftext;
pre_input_deftext = g_strdup (secret->value);
}
pwd = nmc_readline ("%s (%s): ", secret->name, secret->prop_name);
g_free (secret->value);
secret->value = pwd ? pwd : g_strdup ("");
}
return TRUE;
}
static void
secrets_requested (NMSecretAgentSimple *agent,
const char *request_id,
const char *title,
const char *msg,
GPtrArray *secrets,
gpointer user_data)
{
NmCli *nmc = (NmCli *) user_data;
gboolean success = FALSE;
if (nmc->print_output == NMC_PRINT_PRETTY)
nmc_terminal_erase_line ();
if (nmc->ask) {
success = get_secrets_from_user (request_id, title, msg, secrets);
} else {
g_print ("%s\n", msg);
g_print ("%s\n", _("Warning: nmcli does not ask for password without '--ask' argument."));
}
if (success)
nm_secret_agent_simple_response (agent, request_id, secrets);
else
nm_secret_agent_simple_response (agent, request_id, NULL);
}
static gboolean
nmc_activate_connection (NmCli *nmc,
NMConnection *connection,
@ -1967,6 +2033,11 @@ nmc_activate_connection (NmCli *nmc,
return FALSE;
}
/* Create secret agent */
nmc->secret_agent = nm_secret_agent_simple_new ("nmcli-connect");
if (nmc->secret_agent)
g_signal_connect (nmc->secret_agent, "request-secrets", G_CALLBACK (secrets_requested), nmc);
info = g_malloc0 (sizeof (ActivateConnectionInfo));
info->nmc = nmc;
info->device = device;
@ -5426,19 +5497,6 @@ uuid_display_hook (char **array, int len, int max_len)
rl_forced_update_display ();
}
static char *pre_input_deftext;
static int
set_deftext (void)
{
if (pre_input_deftext && rl_startup_hook) {
rl_insert_text (pre_input_deftext);
g_free (pre_input_deftext);
pre_input_deftext = NULL;
rl_startup_hook = NULL;
}
return 0;
}
static char *
gen_nmcli_cmds_menu (const char *text, int state)
{

View file

@ -499,6 +499,7 @@ nmc_init (NmCli *nmc)
nmc->timeout = -1;
nmc->connections = NULL;
nmc->secret_agent = NULL;
nmc->should_wait = FALSE;
nmc->nowait_flag = TRUE;
@ -525,6 +526,12 @@ nmc_cleanup (NmCli *nmc)
g_string_free (nmc->return_text, TRUE);
if (nmc->secret_agent) {
/* Destroy secret agent if we have one. */
nm_secret_agent_unregister (nmc->secret_agent, NULL, NULL);
g_object_unref (nmc->secret_agent);
}
g_free (nmc->required_fields);
nmc_empty_output_fields (nmc);
g_ptr_array_unref (nmc->output_data);

View file

@ -111,6 +111,7 @@ typedef struct _NmCli {
int timeout; /* Operation timeout */
const GPtrArray *connections; /* List of connections */
NMSecretAgent *secret_agent; /* Secret agent */
gboolean should_wait; /* Indication that nmcli should not end yet */
gboolean nowait_flag; /* '--nowait' option; used for passing to callbacks */