cli: add support for secret agent to 'nmcli dev connect' too
And move secrets getting code to common.c (without changes).
This commit is contained in:
@@ -900,6 +900,93 @@ nmc_find_connection (const GPtrArray *connections,
|
||||
return found;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_secrets_from_user (const char *request_id,
|
||||
const char *title,
|
||||
const char *msg,
|
||||
gboolean ask,
|
||||
GHashTable *pwds_hash,
|
||||
GPtrArray *secrets)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < secrets->len; i++) {
|
||||
NMSecretAgentSimpleSecret *secret = secrets->pdata[i];
|
||||
char *pwd = NULL;
|
||||
|
||||
/* First try to find the password in provided passwords file,
|
||||
* then ask user. */
|
||||
if (pwds_hash && (pwd = g_hash_table_lookup (pwds_hash, secret->prop_name))) {
|
||||
pwd = g_strdup (pwd);
|
||||
} else {
|
||||
g_print ("%s\n", msg);
|
||||
if (ask) {
|
||||
if (secret->value) {
|
||||
/* Prefill the password if we have it. */
|
||||
rl_startup_hook = nmc_rl_set_deftext;
|
||||
nmc_rl_pre_input_deftext = g_strdup (secret->value);
|
||||
}
|
||||
pwd = nmc_readline ("%s (%s): ", secret->name, secret->prop_name);
|
||||
if (!pwd)
|
||||
pwd = g_strdup ("");
|
||||
} else {
|
||||
g_printerr (_("Warning: password for '%s' not given in 'passwd-file' "
|
||||
"and nmcli cannot ask without '--ask' option.\n"),
|
||||
secret->prop_name);
|
||||
}
|
||||
}
|
||||
/* No password provided, cancel the secrets. */
|
||||
if (!pwd)
|
||||
return FALSE;
|
||||
g_free (secret->value);
|
||||
secret->value = pwd;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nmc_secrets_requested:
|
||||
* @agent: the #NMSecretAgentSimple
|
||||
* @request_id: request ID, to eventually pass to
|
||||
* nm_secret_agent_simple_response()
|
||||
* @title: a title for the password request
|
||||
* @msg: a prompt message for the password request
|
||||
* @secrets: (element-type #NMSecretAgentSimpleSecret): array of secrets
|
||||
* being requested.
|
||||
* @user_data: user data passed to the function
|
||||
*
|
||||
* This function is used as a callback for "request-secrets" signal of
|
||||
* NMSecretAgentSimpleSecret.
|
||||
*/
|
||||
void
|
||||
nmc_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 ();
|
||||
|
||||
success = get_secrets_from_user (request_id, title, msg, nmc->in_editor || nmc->ask,
|
||||
nmc->pwds_hash, secrets);
|
||||
if (success)
|
||||
nm_secret_agent_simple_response (agent, request_id, secrets);
|
||||
else {
|
||||
/* Unregister our secret agent on failure, so that another agent
|
||||
* may be tried */
|
||||
if (nmc->secret_agent) {
|
||||
nm_secret_agent_unregister (nmc->secret_agent, NULL, NULL);
|
||||
g_clear_object (&nmc->secret_agent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nmc_cleanup_readline:
|
||||
*
|
||||
@@ -1042,3 +1129,18 @@ nmc_rl_gen_func_basic (const char *text, int state, const char **words)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* for pre-filling a string to readline prompt */
|
||||
char *nmc_rl_pre_input_deftext;
|
||||
|
||||
int
|
||||
nmc_rl_set_deftext (void)
|
||||
{
|
||||
if (nmc_rl_pre_input_deftext && rl_startup_hook) {
|
||||
rl_insert_text (nmc_rl_pre_input_deftext);
|
||||
g_free (nmc_rl_pre_input_deftext);
|
||||
nmc_rl_pre_input_deftext = NULL;
|
||||
rl_startup_hook = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -16,13 +16,14 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2012 - 2014 Red Hat, Inc.
|
||||
* Copyright 2012 - 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NMC_COMMON_H
|
||||
#define NMC_COMMON_H
|
||||
|
||||
#include "nmcli.h"
|
||||
#include "nm-secret-agent-simple.h"
|
||||
|
||||
gboolean print_ip4_config (NMIPConfig *cfg4, NmCli *nmc, const char *group_prefix, const char *one_field);
|
||||
gboolean print_ip6_config (NMIPConfig *cfg6, NmCli *nmc, const char *group_prefix, const char *one_field);
|
||||
@@ -48,10 +49,21 @@ NMConnection *nmc_find_connection (const GPtrArray *connections,
|
||||
const char *filter_val,
|
||||
int *start);
|
||||
|
||||
void nmc_secrets_requested (NMSecretAgentSimple *agent,
|
||||
const char *request_id,
|
||||
const char *title,
|
||||
const char *msg,
|
||||
GPtrArray *secrets,
|
||||
gpointer user_data);
|
||||
|
||||
void nmc_cleanup_readline (void);
|
||||
char *nmc_readline (const char *prompt_fmt, ...) G_GNUC_PRINTF (1, 2);
|
||||
char *nmc_rl_gen_func_basic (const char *text, int state, const char **words);
|
||||
gboolean nmc_get_in_readline (void);
|
||||
void nmc_set_in_readline (gboolean in_readline);
|
||||
|
||||
/* for pre-filling a string to readline prompt */
|
||||
extern char *nmc_rl_pre_input_deftext;
|
||||
int nmc_rl_set_deftext (void);
|
||||
|
||||
#endif /* NMC_COMMON_H */
|
||||
|
@@ -510,20 +510,6 @@ 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)
|
||||
{
|
||||
@@ -2044,77 +2030,7 @@ failure:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_secrets_from_user (const char *request_id,
|
||||
const char *title,
|
||||
const char *msg,
|
||||
gboolean ask,
|
||||
GHashTable *pwds_hash,
|
||||
GPtrArray *secrets)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < secrets->len; i++) {
|
||||
NMSecretAgentSimpleSecret *secret = secrets->pdata[i];
|
||||
char *pwd = NULL;
|
||||
|
||||
/* First try to find the password in provided passwords file,
|
||||
* then ask user. */
|
||||
if (pwds_hash && (pwd = g_hash_table_lookup (pwds_hash, secret->prop_name))) {
|
||||
pwd = g_strdup (pwd);
|
||||
} else {
|
||||
g_print ("%s\n", msg);
|
||||
if (ask) {
|
||||
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);
|
||||
if (!pwd)
|
||||
pwd = g_strdup ("");
|
||||
} else {
|
||||
g_printerr (_("Warning: password for '%s' not given in 'passwd-file' "
|
||||
"and nmcli cannot ask without '--ask' option.\n"),
|
||||
secret->prop_name);
|
||||
}
|
||||
}
|
||||
/* No password provided, cancel the secrets. */
|
||||
if (!pwd)
|
||||
return FALSE;
|
||||
g_free (secret->value);
|
||||
secret->value = pwd;
|
||||
}
|
||||
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 ();
|
||||
|
||||
success = get_secrets_from_user (request_id, title, msg, nmc->in_editor || nmc->ask,
|
||||
nmc->pwds_hash, secrets);
|
||||
if (success)
|
||||
nm_secret_agent_simple_response (agent, request_id, secrets);
|
||||
else {
|
||||
/* Unregister our secret agent on failure, so that another agent
|
||||
* may be tried */
|
||||
if (nmc->secret_agent) {
|
||||
nm_secret_agent_unregister (nmc->secret_agent, NULL, NULL);
|
||||
g_clear_object (&nmc->secret_agent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nmc_activate_connection (NmCli *nmc,
|
||||
@@ -2174,7 +2090,7 @@ nmc_activate_connection (NmCli *nmc,
|
||||
/* 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);
|
||||
g_signal_connect (nmc->secret_agent, "request-secrets", G_CALLBACK (nmc_secrets_requested), nmc);
|
||||
if (connection) {
|
||||
const gchar *path = nm_object_get_path (NM_OBJECT (connection));
|
||||
|
||||
@@ -7062,8 +6978,8 @@ property_edit_submenu (NmCli *nmc,
|
||||
break;
|
||||
|
||||
case NMC_EDITOR_SUB_CMD_CHANGE:
|
||||
rl_startup_hook = set_deftext;
|
||||
pre_input_deftext = nmc_setting_get_property_out2in (curr_setting, prop_name, NULL);
|
||||
rl_startup_hook = nmc_rl_set_deftext;
|
||||
nmc_rl_pre_input_deftext = nmc_setting_get_property_out2in (curr_setting, prop_name, NULL);
|
||||
prop_val_user = nmc_readline (_("Edit '%s' value: "), prop_name);
|
||||
|
||||
nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value);
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "nm-secret-agent-simple.h"
|
||||
#include "polkit-agent.h"
|
||||
#include "utils.h"
|
||||
#include "common.h"
|
||||
@@ -1517,6 +1518,14 @@ connect_device_cb (GObject *client, GAsyncResult *result, gpointer user_data)
|
||||
g_object_unref (active);
|
||||
quit ();
|
||||
} else {
|
||||
if (nmc->secret_agent) {
|
||||
NMRemoteConnection *connection = nm_active_connection_get_connection (active);
|
||||
const char *path = nm_connection_get_path (NM_CONNECTION (connection));
|
||||
|
||||
nm_secret_agent_simple_set_connection_path (nmc->secret_agent, path);
|
||||
nm_secret_agent_simple_enable (nmc->secret_agent);
|
||||
}
|
||||
|
||||
g_object_ref (device);
|
||||
g_signal_connect (device, "notify::state", G_CALLBACK (device_state_cb), active);
|
||||
g_signal_connect (active, "notify::state", G_CALLBACK (active_state_cb), device);
|
||||
@@ -1589,6 +1598,11 @@ do_device_connect (NmCli *nmc, int argc, char **argv)
|
||||
nmc->nowait_flag = (nmc->timeout == 0);
|
||||
nmc->should_wait = TRUE;
|
||||
|
||||
/* 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 (nmc_secrets_requested), nmc);
|
||||
|
||||
info = g_malloc0 (sizeof (AddAndActivateInfo));
|
||||
info->nmc = nmc;
|
||||
info->device = device;
|
||||
|
Reference in New Issue
Block a user