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;
|
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:
|
* nmc_cleanup_readline:
|
||||||
*
|
*
|
||||||
@@ -1042,3 +1129,18 @@ nmc_rl_gen_func_basic (const char *text, int state, const char **words)
|
|||||||
return NULL;
|
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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 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
|
#ifndef NMC_COMMON_H
|
||||||
#define NMC_COMMON_H
|
#define NMC_COMMON_H
|
||||||
|
|
||||||
#include "nmcli.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_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);
|
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,
|
const char *filter_val,
|
||||||
int *start);
|
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);
|
void nmc_cleanup_readline (void);
|
||||||
char *nmc_readline (const char *prompt_fmt, ...) G_GNUC_PRINTF (1, 2);
|
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);
|
char *nmc_rl_gen_func_basic (const char *text, int state, const char **words);
|
||||||
gboolean nmc_get_in_readline (void);
|
gboolean nmc_get_in_readline (void);
|
||||||
void nmc_set_in_readline (gboolean in_readline);
|
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 */
|
#endif /* NMC_COMMON_H */
|
||||||
|
@@ -510,20 +510,6 @@ quit (void)
|
|||||||
g_main_loop_quit (loop); /* quit main loop */
|
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 *
|
static const char *
|
||||||
construct_header_name (const char *base, const char *spec)
|
construct_header_name (const char *base, const char *spec)
|
||||||
{
|
{
|
||||||
@@ -2044,77 +2030,7 @@ failure:
|
|||||||
return NULL;
|
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
|
static gboolean
|
||||||
nmc_activate_connection (NmCli *nmc,
|
nmc_activate_connection (NmCli *nmc,
|
||||||
@@ -2174,7 +2090,7 @@ nmc_activate_connection (NmCli *nmc,
|
|||||||
/* Create secret agent */
|
/* Create secret agent */
|
||||||
nmc->secret_agent = nm_secret_agent_simple_new ("nmcli-connect");
|
nmc->secret_agent = nm_secret_agent_simple_new ("nmcli-connect");
|
||||||
if (nmc->secret_agent) {
|
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) {
|
if (connection) {
|
||||||
const gchar *path = nm_object_get_path (NM_OBJECT (connection));
|
const gchar *path = nm_object_get_path (NM_OBJECT (connection));
|
||||||
|
|
||||||
@@ -7062,8 +6978,8 @@ property_edit_submenu (NmCli *nmc,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NMC_EDITOR_SUB_CMD_CHANGE:
|
case NMC_EDITOR_SUB_CMD_CHANGE:
|
||||||
rl_startup_hook = set_deftext;
|
rl_startup_hook = nmc_rl_set_deftext;
|
||||||
pre_input_deftext = nmc_setting_get_property_out2in (curr_setting, prop_name, NULL);
|
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);
|
prop_val_user = nmc_readline (_("Edit '%s' value: "), prop_name);
|
||||||
|
|
||||||
nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value);
|
nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value);
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#include "nm-secret-agent-simple.h"
|
||||||
#include "polkit-agent.h"
|
#include "polkit-agent.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -1517,6 +1518,14 @@ connect_device_cb (GObject *client, GAsyncResult *result, gpointer user_data)
|
|||||||
g_object_unref (active);
|
g_object_unref (active);
|
||||||
quit ();
|
quit ();
|
||||||
} else {
|
} 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_object_ref (device);
|
||||||
g_signal_connect (device, "notify::state", G_CALLBACK (device_state_cb), active);
|
g_signal_connect (device, "notify::state", G_CALLBACK (device_state_cb), active);
|
||||||
g_signal_connect (active, "notify::state", G_CALLBACK (active_state_cb), device);
|
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->nowait_flag = (nmc->timeout == 0);
|
||||||
nmc->should_wait = TRUE;
|
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 = g_malloc0 (sizeof (AddAndActivateInfo));
|
||||||
info->nmc = nmc;
|
info->nmc = nmc;
|
||||||
info->device = device;
|
info->device = device;
|
||||||
|
Reference in New Issue
Block a user