merge: use NM secret agent in nmcli when connecting to networks (bgo #705998)

The secret agent code is shared between nmcli and nmtui.

https://bugzilla.gnome.org/show_bug.cgi?id=705998
https://bugzilla.redhat.com/show_bug.cgi?id=990111
This commit is contained in:
Jiří Klimeš 2014-11-07 11:32:38 +01:00
commit 847e2a405b
13 changed files with 505 additions and 280 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? ")
@ -250,9 +251,9 @@ usage (void)
"COMMAND := { show | up | down | add | modify | edit | delete | reload | load }\n\n"
" show [--active] [[--show-secrets] [id | uuid | path | apath] <ID>] ...\n\n"
#if WITH_WIMAX
" up [[id | uuid | path] <ID>] [ifname <ifname>] [ap <BSSID>] [nsp <name>]\n\n"
" up [[id | uuid | path] <ID>] [ifname <ifname>] [ap <BSSID>] [nsp <name>] [passwd-file <file with passwords>]\n\n"
#else
" up [[id | uuid | path] <ID>] [ifname <ifname>] [ap <BSSID>]\n\n"
" up [[id | uuid | path] <ID>] [ifname <ifname>] [ap <BSSID>] [passwd-file <file with passwords>]\n\n"
#endif
" down [id | uuid | path | apath] <ID>\n\n"
" add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n"
@ -290,19 +291,20 @@ usage_connection_up (void)
{
g_printerr (_("Usage: nmcli connection up { ARGUMENTS | help }\n"
"\n"
"ARGUMENTS := [id | uuid | path] <ID> [ifname <ifname>] [ap <BSSID>] [nsp <name>]\n"
"ARGUMENTS := [id | uuid | path] <ID> [ifname <ifname>] [ap <BSSID>] [nsp <name>] [passwd-file <file with passwords>]\n"
"\n"
"Activate a connection on a device. The profile to activate is identified by its\n"
"name, UUID or D-Bus path.\n"
"\n"
"ARGUMENTS := ifname <ifname> [ap <BSSID>] [nsp <name>]\n"
"ARGUMENTS := ifname <ifname> [ap <BSSID>] [nsp <name>] [passwd-file <file with passwords>]\n"
"\n"
"Activate a device with a connection. The connection profile is selected\n"
"automatically by NetworkManager.\n"
"\n"
"ifname - specifies the device to active the connection on\n"
"ap - specifies AP to connect to (only valid for Wi-Fi)\n"
"nsp - specifies NSP to connect to (only valid for WiMAX)\n\n"));
"ifname - specifies the device to active the connection on\n"
"ap - specifies AP to connect to (only valid for Wi-Fi)\n"
"nsp - specifies NSP to connect to (only valid for WiMAX)\n"
"passwd-file - file with password(s) required to activate the connection\n\n"));
}
static void
@ -507,6 +509,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,16 +1942,173 @@ activate_connection_cb (GObject *client, GAsyncResult *result, gpointer user_dat
g_free (info);
}
/**
* parse_passwords:
* @passwd_file: file with passwords to parse
* @error: location to store error, or %NULL
*
* Parse passwords given in @passwd_file and insert them into a hash table.
* Example of @passwd_file contents:
* wifi.psk:tajne heslo
* 802-1x.password:krakonos
* 802-11-wireless-security:leap-password:my leap password
*
* Returns: hash table with parsed passwords, or %NULL on an error
*/
static GHashTable *
parse_passwords (const char *passwd_file, GError **error)
{
GHashTable *pwds_hash;
char *contents = NULL;
gsize len = 0;
GError *local_err = NULL;
char **lines, **iter;
char *pwd_spec, *pwd, *prop;
const char *setting;
pwds_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
if (!passwd_file)
return pwds_hash;
/* Read the passwords file */
if (!g_file_get_contents (passwd_file, &contents, &len, &local_err)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("failed to read passwd-file '%s': %s"),
passwd_file, local_err->message);
g_error_free (local_err);
g_hash_table_destroy (pwds_hash);
return NULL;
}
lines = nmc_strsplit_set (contents, "\r\n", -1);
for (iter = lines; *iter; iter++) {
pwd = strchr (*iter, ':');
if (!pwd) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("missing colon in 'password' entry '%s'"), *iter);
goto failure;
}
*(pwd++) = '\0';
prop = strchr (*iter, '.');
if (!prop) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("missing dot in 'password' entry '%s'"), *iter);
goto failure;
}
*(prop++) = '\0';
setting = *iter;
while (g_ascii_isspace (*setting))
setting++;
/* Accept wifi-sec or wifi instead of cumbersome '802-11-wireless-security' */
if (!strcmp (setting, "wifi-sec") || !strcmp (setting, "wifi"))
setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
if (nm_setting_lookup_type (setting) == G_TYPE_INVALID) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("invalid setting name in 'password' entry '%s'"), setting);
goto failure;
}
pwd_spec = g_strdup_printf ("%s.%s", setting, prop);
g_hash_table_insert (pwds_hash, pwd_spec, g_strdup (pwd));
}
g_strfreev (lines);
g_free (contents);
return pwds_hash;
failure:
g_strfreev (lines);
g_free (contents);
g_hash_table_destroy (pwds_hash);
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,
NMConnection *connection,
const char *ifname,
const char *ap,
const char *nsp,
const char *pwds,
GAsyncReadyCallback callback,
GError **error)
{
ActivateConnectionInfo *info;
GHashTable *pwds_hash;
NMDevice *device = NULL;
const char *spec_object = NULL;
gboolean device_found;
@ -1967,6 +2140,21 @@ nmc_activate_connection (NmCli *nmc,
return FALSE;
}
/* Parse passwords given in passwords file */
pwds_hash = parse_passwords (pwds, &local);
if (local) {
g_propagate_error (error, local);
return FALSE;
}
if (nmc->pwds_hash)
g_hash_table_destroy (nmc->pwds_hash);
nmc->pwds_hash = pwds_hash;
/* 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;
@ -1988,6 +2176,7 @@ do_connection_up (NmCli *nmc, int argc, char **argv)
const char *ifname = NULL;
const char *ap = NULL;
const char *nsp = NULL;
const char *pwds = NULL;
GError *error = NULL;
const char *selector = NULL;
const char *name = NULL;
@ -2055,6 +2244,15 @@ do_connection_up (NmCli *nmc, int argc, char **argv)
nsp = *argv;
}
#endif
else if (strcmp (*argv, "passwd-file") == 0) {
if (next_arg (&argc, &argv) != 0) {
g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1));
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
goto error;
}
pwds = *argv;
}
else {
g_printerr (_("Unknown parameter: %s\n"), *argv);
}
@ -2070,7 +2268,7 @@ do_connection_up (NmCli *nmc, int argc, char **argv)
nmc->nowait_flag = (nmc->timeout == 0);
nmc->should_wait = TRUE;
if (!nmc_activate_connection (nmc, connection, ifname, ap, nsp, activate_connection_cb, &error)) {
if (!nmc_activate_connection (nmc, connection, ifname, ap, nsp, pwds, activate_connection_cb, &error)) {
g_string_printf (nmc->return_text, _("Error: %s."),
error ? error->message : _("unknown error"));
nmc->return_value = error ? error->code : NMC_RESULT_ERROR_CON_ACTIVATION;
@ -5426,19 +5624,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)
{
@ -7654,7 +7839,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
nmc->nowait_flag = FALSE;
nmc->should_wait = TRUE;
nmc->print_output = NMC_PRINT_PRETTY;
if (!nmc_activate_connection (nmc, NM_CONNECTION (rem_con), ifname, ap_nsp, ap_nsp,
if (!nmc_activate_connection (nmc, NM_CONNECTION (rem_con), ifname, ap_nsp, ap_nsp, NULL,
activate_connection_editor_cb, &tmp_err)) {
g_print (_("Error: Cannot activate connection: %s.\n"), tmp_err->message);
g_clear_error (&tmp_err);

View file

@ -502,7 +502,8 @@ _nmcli_compl_ARGS()
user| \
username| \
service| \
password)
password| \
passwd-file)
if [[ "${#words[@]}" -eq 2 ]]; then
return 0
fi
@ -845,9 +846,9 @@ _nmcli()
_nmcli_compl_ARGS_CONNECTION && return 0
if [[ "$COMMAND_CONNECTION_TYPE" = "ifname" ]]; then
OPTIONS=(ap nsp)
OPTIONS=(ap nsp passwd-file)
else
OPTIONS=(ifname ap nsp)
OPTIONS=(ifname ap nsp passwd-file)
fi
_nmcli_compl_ARGS
fi

View file

@ -500,6 +500,9 @@ nmc_init (NmCli *nmc)
nmc->connections = NULL;
nmc->secret_agent = NULL;
nmc->pwds_hash = NULL;
nmc->should_wait = FALSE;
nmc->nowait_flag = TRUE;
nmc->print_output = NMC_PRINT_NORMAL;
@ -525,6 +528,14 @@ 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);
}
if (nmc->pwds_hash)
g_hash_table_destroy (nmc->pwds_hash);
g_free (nmc->required_fields);
nmc_empty_output_fields (nmc);
g_ptr_array_unref (nmc->output_data);

View file

@ -112,6 +112,9 @@ typedef struct _NmCli {
const GPtrArray *connections; /* List of connections */
NMSecretAgent *secret_agent; /* Secret agent */
GHashTable *pwds_hash; /* Hash table with passwords in passwd-file */
gboolean should_wait; /* Indication that nmcli should not end yet */
gboolean nowait_flag; /* '--nowait' option; used for passing to callbacks */
NMCPrintOutput print_output; /* Output mode */

View file

@ -18,10 +18,10 @@
*/
/**
* SECTION:nmt-secret-agent
* @short_description: A secret agent
* SECTION:nm-secret-agent-simple
* @short_description: A simple secret agent for NetworkManager
*
* #NmtSecretAgent is the secret agent used by nmtui-connect.
* #NMSecretAgentSimple is the secret agent used by nmtui-connect and nmcli.
*
* This is a stripped-down version of gnome-shell's ShellNetworkAgent,
* with bits of the corresponding JavaScript code squished down into
@ -34,12 +34,11 @@
#include <string.h>
#include <glib/gi18n-lib.h>
#include "nmt-secret-agent.h"
#include "nmt-newt.h"
#include "nm-secret-agent-simple.h"
G_DEFINE_TYPE (NmtSecretAgent, nmt_secret_agent, NM_TYPE_SECRET_AGENT)
G_DEFINE_TYPE (NMSecretAgentSimple, nm_secret_agent_simple, NM_TYPE_SECRET_AGENT)
#define NMT_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_SECRET_AGENT, NmtSecretAgentPrivate))
#define NM_SECRET_AGENT_SIMPLE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT_SIMPLE, NMSecretAgentSimplePrivate))
enum {
REQUEST_SECRETS,
@ -50,45 +49,45 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
NmtSecretAgent *self;
NMSecretAgentSimple *self;
gchar *request_id;
NMConnection *connection;
gchar **hints;
NMSecretAgentGetSecretsFunc callback;
gpointer callback_data;
} NmtSecretAgentRequest;
} NMSecretAgentSimpleRequest;
typedef struct {
/* <char *request_id, NmtSecretAgentRequest *request> */
/* <char *request_id, NMSecretAgentSimpleRequest *request> */
GHashTable *requests;
} NmtSecretAgentPrivate;
} NMSecretAgentSimplePrivate;
static void
nmt_secret_agent_request_free (gpointer data)
nm_secret_agent_simple_request_free (gpointer data)
{
NmtSecretAgentRequest *request = data;
NMSecretAgentSimpleRequest *request = data;
g_object_unref (request->self);
g_object_unref (request->connection);
g_strfreev (request->hints);
g_slice_free (NmtSecretAgentRequest, request);
g_slice_free (NMSecretAgentSimpleRequest, request);
}
static void
nmt_secret_agent_init (NmtSecretAgent *agent)
nm_secret_agent_simple_init (NMSecretAgentSimple *agent)
{
NmtSecretAgentPrivate *priv = NMT_SECRET_AGENT_GET_PRIVATE (agent);
NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (agent);
priv->requests = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, nmt_secret_agent_request_free);
g_free, nm_secret_agent_simple_request_free);
}
static void
nmt_secret_agent_finalize (GObject *object)
nm_secret_agent_simple_finalize (GObject *object)
{
NmtSecretAgentPrivate *priv = NMT_SECRET_AGENT_GET_PRIVATE (object);
NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (object);
GError *error;
GHashTableIter iter;
gpointer key;
@ -100,7 +99,7 @@ nmt_secret_agent_finalize (GObject *object)
g_hash_table_iter_init (&iter, priv->requests);
while (g_hash_table_iter_next (&iter, &key, &value)) {
NmtSecretAgentRequest *request = value;
NMSecretAgentSimpleRequest *request = value;
request->callback (NM_SECRET_AGENT (object),
request->connection,
@ -111,7 +110,7 @@ nmt_secret_agent_finalize (GObject *object)
g_hash_table_destroy (priv->requests);
g_error_free (error);
G_OBJECT_CLASS (nmt_secret_agent_parent_class)->finalize (object);
G_OBJECT_CLASS (nm_secret_agent_simple_parent_class)->finalize (object);
}
static gboolean
@ -129,7 +128,7 @@ strv_has (gchar **haystack,
}
/**
* NmtSecretAgentSecret:
* NMSecretAgentSimpleSecret:
* @name: the user-visible name of the secret. Eg, "WEP Passphrase".
* @value: the value of the secret
* @password: %TRUE if this secret represents a password, %FALSE
@ -139,38 +138,37 @@ strv_has (gchar **haystack,
*/
typedef struct {
NmtSecretAgentSecret base;
NMSecretAgentSimpleSecret base;
NMSetting *setting;
char *property;
NmtNewtEntryValidator validator;
gpointer validator_data;
} NmtSecretAgentSecretReal;
} NMSecretAgentSimpleSecretReal;
static void
nmt_secret_agent_secret_free (NmtSecretAgentSecret *secret)
nm_secret_agent_simple_secret_free (NMSecretAgentSimpleSecret *secret)
{
NmtSecretAgentSecretReal *real = (NmtSecretAgentSecretReal *)secret;
NMSecretAgentSimpleSecretReal *real = (NMSecretAgentSimpleSecretReal *)secret;
g_free (secret->name);
g_free (secret->prop_name);
g_free (secret->value);
g_free (real->property);
g_clear_object (&real->setting);
g_slice_free (NmtSecretAgentSecretReal, real);
g_slice_free (NMSecretAgentSimpleSecretReal, real);
}
static NmtSecretAgentSecret *
nmt_secret_agent_secret_new (const char *name,
NMSetting *setting,
const char *property,
gboolean password)
static NMSecretAgentSimpleSecret *
nm_secret_agent_simple_secret_new (const char *name,
NMSetting *setting,
const char *property,
gboolean password)
{
NmtSecretAgentSecretReal *real;
NMSecretAgentSimpleSecretReal *real;
real = g_slice_new0 (NmtSecretAgentSecretReal);
real = g_slice_new0 (NMSecretAgentSimpleSecretReal);
real->base.name = g_strdup (name);
real->base.prop_name = g_strdup_printf ("%s.%s", nm_setting_get_name (setting), property);
real->base.password = password;
if (setting) {
@ -184,12 +182,12 @@ nmt_secret_agent_secret_new (const char *name,
}
static gboolean
add_8021x_secrets (NmtSecretAgentRequest *request,
GPtrArray *secrets)
add_8021x_secrets (NMSecretAgentSimpleRequest *request,
GPtrArray *secrets)
{
NMSetting8021x *s_8021x = nm_connection_get_setting_802_1x (request->connection);
const char *eap_method;
NmtSecretAgentSecret *secret;
NMSecretAgentSimpleSecret *secret;
eap_method = nm_setting_802_1x_get_eap_method (s_8021x, 0);
if (!eap_method)
@ -203,29 +201,29 @@ add_8021x_secrets (NmtSecretAgentRequest *request,
* is not visible here since we only care about phase2 authentication
* (and don't even care of which one)
*/
secret = nmt_secret_agent_secret_new (_("Username"),
NM_SETTING (s_8021x),
NM_SETTING_802_1X_IDENTITY,
FALSE);
secret = nm_secret_agent_simple_secret_new (_("Username"),
NM_SETTING (s_8021x),
NM_SETTING_802_1X_IDENTITY,
FALSE);
g_ptr_array_add (secrets, secret);
secret = nmt_secret_agent_secret_new (_("Password"),
NM_SETTING (s_8021x),
NM_SETTING_802_1X_PASSWORD,
TRUE);
secret = nm_secret_agent_simple_secret_new (_("Password"),
NM_SETTING (s_8021x),
NM_SETTING_802_1X_PASSWORD,
TRUE);
g_ptr_array_add (secrets, secret);
return TRUE;
}
if (!strcmp (eap_method, "tls")) {
secret = nmt_secret_agent_secret_new (_("Identity"),
NM_SETTING (s_8021x),
NM_SETTING_802_1X_IDENTITY,
FALSE);
secret = nm_secret_agent_simple_secret_new (_("Identity"),
NM_SETTING (s_8021x),
NM_SETTING_802_1X_IDENTITY,
FALSE);
g_ptr_array_add (secrets, secret);
secret = nmt_secret_agent_secret_new (_("Private key password"),
NM_SETTING (s_8021x),
NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD,
TRUE);
secret = nm_secret_agent_simple_secret_new (_("Private key password"),
NM_SETTING (s_8021x),
NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD,
TRUE);
g_ptr_array_add (secrets, secret);
return TRUE;
}
@ -234,21 +232,21 @@ add_8021x_secrets (NmtSecretAgentRequest *request,
}
static gboolean
add_wireless_secrets (NmtSecretAgentRequest *request,
GPtrArray *secrets)
add_wireless_secrets (NMSecretAgentSimpleRequest *request,
GPtrArray *secrets)
{
NMSettingWirelessSecurity *s_wsec = nm_connection_get_setting_wireless_security (request->connection);
const char *key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
NmtSecretAgentSecret *secret;
NMSecretAgentSimpleSecret *secret;
if (!key_mgmt)
return FALSE;
if (!strcmp (key_mgmt, "wpa-none") || !strcmp (key_mgmt, "wpa-psk")) {
secret = nmt_secret_agent_secret_new (_("Password"),
NM_SETTING (s_wsec),
NM_SETTING_WIRELESS_SECURITY_PSK,
TRUE);
secret = nm_secret_agent_simple_secret_new (_("Password"),
NM_SETTING (s_wsec),
NM_SETTING_WIRELESS_SECURITY_PSK,
TRUE);
g_ptr_array_add (secrets, secret);
return TRUE;
}
@ -259,26 +257,22 @@ add_wireless_secrets (NmtSecretAgentRequest *request,
index = nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec);
key = g_strdup_printf ("wep-key%d", index);
secret = nmt_secret_agent_secret_new (_("Key"),
NM_SETTING (s_wsec),
key,
TRUE);
secret = nm_secret_agent_simple_secret_new (_("Key"),
NM_SETTING (s_wsec),
key,
TRUE);
g_free (key);
#if 0
nmt_secret_agent_secret_set_validator (secret, static_wep_key_validate,
nm_setting_wireless_security_get_wep_key_type (s_wsec));
#endif
g_ptr_array_add (secrets, secret);
return TRUE;
}
if (!strcmp (key_mgmt, "iee8021x")) {
if (!g_strcmp0 (nm_setting_wireless_security_get_auth_alg (s_wsec), "leap")) {
secret = nmt_secret_agent_secret_new (_("Password"),
NM_SETTING (s_wsec),
NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD,
TRUE);
secret = nm_secret_agent_simple_secret_new (_("Password"),
NM_SETTING (s_wsec),
NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD,
TRUE);
g_ptr_array_add (secrets, secret);
return TRUE;
} else
@ -292,40 +286,40 @@ add_wireless_secrets (NmtSecretAgentRequest *request,
}
static gboolean
add_pppoe_secrets (NmtSecretAgentRequest *request,
GPtrArray *secrets)
add_pppoe_secrets (NMSecretAgentSimpleRequest *request,
GPtrArray *secrets)
{
NMSettingPppoe *s_pppoe = nm_connection_get_setting_pppoe (request->connection);
NmtSecretAgentSecret *secret;
NMSecretAgentSimpleSecret *secret;
secret = nmt_secret_agent_secret_new (_("Username"),
NM_SETTING (s_pppoe),
NM_SETTING_PPPOE_USERNAME,
FALSE);
secret = nm_secret_agent_simple_secret_new (_("Username"),
NM_SETTING (s_pppoe),
NM_SETTING_PPPOE_USERNAME,
FALSE);
g_ptr_array_add (secrets, secret);
secret = nmt_secret_agent_secret_new (_("Service"),
NM_SETTING (s_pppoe),
NM_SETTING_PPPOE_SERVICE,
FALSE);
secret = nm_secret_agent_simple_secret_new (_("Service"),
NM_SETTING (s_pppoe),
NM_SETTING_PPPOE_SERVICE,
FALSE);
g_ptr_array_add (secrets, secret);
secret = nmt_secret_agent_secret_new (_("Password"),
NM_SETTING (s_pppoe),
NM_SETTING_PPPOE_PASSWORD,
TRUE);
secret = nm_secret_agent_simple_secret_new (_("Password"),
NM_SETTING (s_pppoe),
NM_SETTING_PPPOE_PASSWORD,
TRUE);
g_ptr_array_add (secrets, secret);
return TRUE;
}
static void
request_secrets_from_ui (NmtSecretAgentRequest *request)
request_secrets_from_ui (NMSecretAgentSimpleRequest *request)
{
GPtrArray *secrets;
NmtSecretAgentSecret *secret;
NMSecretAgentSimpleSecret *secret;
const char *title;
char *msg;
gboolean ok = TRUE;
secrets = g_ptr_array_new_with_free_func ((GDestroyNotify) nmt_secret_agent_secret_free);
secrets = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_secret_agent_simple_secret_free);
if (nm_connection_is_type (request->connection, NM_SETTING_WIRELESS_SETTING_NAME)) {
NMSettingWireless *s_wireless;
@ -349,10 +343,10 @@ request_secrets_from_ui (NmtSecretAgentRequest *request)
title = _("Wired 802.1X authentication");
msg = NULL;
secret = nmt_secret_agent_secret_new (_("Network name"),
NM_SETTING (s_con),
NM_SETTING_CONNECTION_ID,
FALSE);
secret = nm_secret_agent_simple_secret_new (_("Network name"),
NM_SETTING (s_con),
NM_SETTING_CONNECTION_ID,
FALSE);
g_ptr_array_add (secrets, secret);
ok = add_8021x_secrets (request, secrets);
} else if (nm_connection_is_type (request->connection, NM_SETTING_PPPOE_SETTING_NAME)) {
@ -367,20 +361,20 @@ request_secrets_from_ui (NmtSecretAgentRequest *request)
title = _("PIN code required");
msg = g_strdup (_("PIN code is needed for the mobile broadband device"));
secret = nmt_secret_agent_secret_new (_("PIN"),
NM_SETTING (s_gsm),
NM_SETTING_GSM_PIN,
FALSE);
secret = nm_secret_agent_simple_secret_new (_("PIN"),
NM_SETTING (s_gsm),
NM_SETTING_GSM_PIN,
FALSE);
g_ptr_array_add (secrets, secret);
} else {
title = _("Mobile broadband network password");
msg = g_strdup_printf (_("A password is required to connect to '%s'."),
nm_connection_get_id (request->connection));
secret = nmt_secret_agent_secret_new (_("Password"),
NM_SETTING (s_gsm),
NM_SETTING_GSM_PASSWORD,
TRUE);
secret = nm_secret_agent_simple_secret_new (_("Password"),
NM_SETTING (s_gsm),
NM_SETTING_GSM_PASSWORD,
TRUE);
g_ptr_array_add (secrets, secret);
}
} else if (nm_connection_is_type (request->connection, NM_SETTING_CDMA_SETTING_NAME)) {
@ -390,10 +384,10 @@ request_secrets_from_ui (NmtSecretAgentRequest *request)
msg = g_strdup_printf (_("A password is required to connect to '%s'."),
nm_connection_get_id (request->connection));
secret = nmt_secret_agent_secret_new (_("Password"),
NM_SETTING (s_cdma),
NM_SETTING_CDMA_PASSWORD,
TRUE);
secret = nm_secret_agent_simple_secret_new (_("Password"),
NM_SETTING (s_cdma),
NM_SETTING_CDMA_PASSWORD,
TRUE);
g_ptr_array_add (secrets, secret);
} else if (nm_connection_is_type (request->connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) {
NMSetting *setting;
@ -406,10 +400,10 @@ request_secrets_from_ui (NmtSecretAgentRequest *request)
msg = g_strdup_printf (_("A password is required to connect to '%s'."),
nm_connection_get_id (request->connection));
secret = nmt_secret_agent_secret_new (_("Password"),
setting,
"password",
TRUE);
secret = nm_secret_agent_simple_secret_new (_("Password"),
setting,
"password",
TRUE);
g_ptr_array_add (secrets, secret);
} else
ok = FALSE;
@ -424,18 +418,18 @@ request_secrets_from_ui (NmtSecretAgentRequest *request)
}
static void
nmt_secret_agent_get_secrets (NMSecretAgent *agent,
NMConnection *connection,
const gchar *connection_path,
const gchar *setting_name,
const gchar **hints,
NMSecretAgentGetSecretsFlags flags,
NMSecretAgentGetSecretsFunc callback,
gpointer callback_data)
nm_secret_agent_simple_get_secrets (NMSecretAgent *agent,
NMConnection *connection,
const gchar *connection_path,
const gchar *setting_name,
const gchar **hints,
NMSecretAgentGetSecretsFlags flags,
NMSecretAgentGetSecretsFunc callback,
gpointer callback_data)
{
NmtSecretAgent *self = NMT_SECRET_AGENT (agent);
NmtSecretAgentPrivate *priv = NMT_SECRET_AGENT_GET_PRIVATE (self);
NmtSecretAgentRequest *request;
NMSecretAgentSimple *self = NM_SECRET_AGENT_SIMPLE (agent);
NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (self);
NMSecretAgentSimpleRequest *request;
NMSettingConnection *s_con;
const char *connection_type;
char *request_id;
@ -470,7 +464,7 @@ nmt_secret_agent_get_secrets (NMSecretAgent *agent,
goto nope;
}
request = g_slice_new (NmtSecretAgentRequest);
request = g_slice_new (NMSecretAgentSimpleRequest);
request->self = g_object_ref (self);
request->connection = g_object_ref (connection);
request->hints = g_strdupv ((gchar **)hints);
@ -483,33 +477,33 @@ nmt_secret_agent_get_secrets (NMSecretAgent *agent,
}
/**
* nmt_secret_agent_response:
* @self: the #NmtSecretAgent
* nm_secret_agent_simple_response:
* @self: the #NMSecretAgentSimple
* @request_id: the request ID being responded to
* @secrets: (allow-none): the array of secrets, or %NULL
*
* Response to a #NmtSecretAgent::get-secrets signal.
* Response to a #NMSecretAgentSimple::get-secrets signal.
*
* If the user provided secrets, the caller should set the
* corresponding <literal>value</literal> fields in the
* #NmtSecretAgentSecrets (freeing any initial values they had), and
* pass the array to nmt_secret_agent_response(). If the user
* #NMSecretAgentSimpleSecrets (freeing any initial values they had), and
* pass the array to nm_secret_agent_simple_response(). If the user
* cancelled the request, @secrets should be NULL.
*/
void
nmt_secret_agent_response (NmtSecretAgent *self,
const char *request_id,
GPtrArray *secrets)
nm_secret_agent_simple_response (NMSecretAgentSimple *self,
const char *request_id,
GPtrArray *secrets)
{
NmtSecretAgentPrivate *priv;
NmtSecretAgentRequest *request;
NMSecretAgentSimplePrivate *priv;
NMSecretAgentSimpleRequest *request;
GVariant *dict = NULL;
GError *error = NULL;
int i;
g_return_if_fail (NMT_IS_SECRET_AGENT (self));
g_return_if_fail (NM_IS_SECRET_AGENT_SIMPLE (self));
priv = NMT_SECRET_AGENT_GET_PRIVATE (self);
priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (self);
request = g_hash_table_lookup (priv->requests, request_id);
g_return_if_fail (request != NULL);
@ -521,7 +515,7 @@ nmt_secret_agent_response (NmtSecretAgent *self,
settings = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 0; i < secrets->len; i++) {
NmtSecretAgentSecretReal *secret = secrets->pdata[i];
NMSecretAgentSimpleSecretReal *secret = secrets->pdata[i];
setting_builder = g_hash_table_lookup (settings, nm_setting_get_name (secret->setting));
if (!setting_builder) {
@ -553,69 +547,71 @@ nmt_secret_agent_response (NmtSecretAgent *self,
}
static void
nmt_secret_agent_cancel_get_secrets (NMSecretAgent *agent,
const gchar *connection_path,
const gchar *setting_name)
nm_secret_agent_simple_cancel_get_secrets (NMSecretAgent *agent,
const gchar *connection_path,
const gchar *setting_name)
{
/* We don't support cancellation. Sorry! */
}
static void
nmt_secret_agent_save_secrets (NMSecretAgent *agent,
NMConnection *connection,
const gchar *connection_path,
NMSecretAgentSaveSecretsFunc callback,
gpointer callback_data)
nm_secret_agent_simple_save_secrets (NMSecretAgent *agent,
NMConnection *connection,
const gchar *connection_path,
NMSecretAgentSaveSecretsFunc callback,
gpointer callback_data)
{
/* We don't support secret storage */
callback (agent, connection, NULL, callback_data);}
callback (agent, connection, NULL, callback_data);
}
static void
nmt_secret_agent_delete_secrets (NMSecretAgent *agent,
NMConnection *connection,
const gchar *connection_path,
NMSecretAgentDeleteSecretsFunc callback,
gpointer callback_data)
nm_secret_agent_simple_delete_secrets (NMSecretAgent *agent,
NMConnection *connection,
const gchar *connection_path,
NMSecretAgentDeleteSecretsFunc callback,
gpointer callback_data)
{
/* We don't support secret storage, so there's nothing to delete. */
callback (agent, connection, NULL, callback_data);
}
void
nmt_secret_agent_class_init (NmtSecretAgentClass *klass)
nm_secret_agent_simple_class_init (NMSecretAgentSimpleClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
NMSecretAgentClass *agent_class = NM_SECRET_AGENT_CLASS (klass);
g_type_class_add_private (klass, sizeof (NmtSecretAgentPrivate));
g_type_class_add_private (klass, sizeof (NMSecretAgentSimplePrivate));
gobject_class->finalize = nmt_secret_agent_finalize;
gobject_class->finalize = nm_secret_agent_simple_finalize;
agent_class->get_secrets = nmt_secret_agent_get_secrets;
agent_class->cancel_get_secrets = nmt_secret_agent_cancel_get_secrets;
agent_class->save_secrets = nmt_secret_agent_save_secrets;
agent_class->delete_secrets = nmt_secret_agent_delete_secrets;
agent_class->get_secrets = nm_secret_agent_simple_get_secrets;
agent_class->cancel_get_secrets = nm_secret_agent_simple_cancel_get_secrets;
agent_class->save_secrets = nm_secret_agent_simple_save_secrets;
agent_class->delete_secrets = nm_secret_agent_simple_delete_secrets;
/**
* NmtSecretAgent::request-secrets:
* @agent: the #NmtSecretAgent
* NMSecretAgentSimple::request-secrets:
* @agent: the #NMSecretAgentSimple
* @request_id: request ID, to eventually pass to
* nmt_secret_agent_response().
* nm_secret_agent_simple_response().
* @title: a title for the password dialog
* @prompt: a prompt message for the password dialog
* @secrets: (element-type #NmtSecretAgentSecret): array of secrets
* @secrets: (element-type #NMSecretAgentSimpleSecret): array of secrets
* being requested.
*
* Emitted when the agent requires secrets from the user.
*
* The application should create a password dialog (eg,
* #NmtPasswordDialog) with the given title and prompt, and an
* entry for each element of @secrets. If any of the secrets
* already have a <literal>value</literal> filled in, the
* corresponding entry should be initialized to that value.
* The application should ask user for the secrets. For example,
* nmtui should create a password dialog (#NmtPasswordDialog)
* with the given title and prompt, and an entry for each
* element of @secrets. If any of the secrets already have a
* <literal>value</literal> filled in, the corresponding entry
* should be initialized to that value.
*
* When the dialog is complete, the app must call
* nmt_secret_agent_response() with the results.
* nm_secret_agent_simple_response() with the results.
*/
signals[REQUEST_SECRETS] = g_signal_new ("request-secrets",
G_TYPE_FROM_CLASS (klass),
@ -629,16 +625,17 @@ nmt_secret_agent_class_init (NmtSecretAgentClass *klass)
}
/**
* nmt_secret_agent_new:
* nm_secret_agent_simple_new:
* @name: the identifier of secret agent
*
* Creates a new #NmtSecretAgent.
* Creates a new #NMSecretAgentSimple.
*
* Returns: a new #NmtSecretAgent
* Returns: a new #NMSecretAgentSimple
*/
NMSecretAgent *
nmt_secret_agent_new (void)
nm_secret_agent_simple_new (const char *name)
{
return g_initable_new (NMT_TYPE_SECRET_AGENT, NULL, NULL,
NM_SECRET_AGENT_IDENTIFIER, "nmtui",
return g_initable_new (NM_TYPE_SECRET_AGENT_SIMPLE, NULL, NULL,
NM_SECRET_AGENT_IDENTIFIER, name,
NULL);
}

View file

@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2013 - 2014 Red Hat, Inc.
*/
#ifndef __NM_SECRET_AGENT_SIMPLE_H__
#define __NM_SECRET_AGENT_SIMPLE_H__
#include <NetworkManager.h>
G_BEGIN_DECLS
#define NM_TYPE_SECRET_AGENT_SIMPLE (nm_secret_agent_simple_get_type ())
#define NM_SECRET_AGENT_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentSimple))
#define NM_SECRET_AGENT_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentSimpleClass))
#define NM_IS_SECRET_AGENT_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT))
#define NM_IS_SECRET_AGENT_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SECRET_AGENT))
#define NM_SECRET_AGENT_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentSimpleClass))
typedef struct {
NMSecretAgent parent;
} NMSecretAgentSimple;
typedef struct {
NMSecretAgentClass parent;
} NMSecretAgentSimpleClass;
typedef struct {
char *name, *prop_name, *value;
gboolean password;
} NMSecretAgentSimpleSecret;
GType nm_secret_agent_simple_get_type (void);
NMSecretAgent *nm_secret_agent_simple_new (const char *name);
void nm_secret_agent_simple_response (NMSecretAgentSimple *self,
const char *request_id,
GPtrArray *secrets);
G_END_DECLS
#endif /* __NM_SECRET_AGENT_SIMPLE_H__ */

View file

@ -10,6 +10,7 @@ AM_CPPFLAGS= \
-I$(top_srcdir)/libnm \
-I$(top_builddir)/libnm \
-I$(srcdir)/newt \
-I$(top_srcdir)/clients/common \
$(GLIB_CFLAGS) \
$(NEWT_CFLAGS) \
$(GUDEV_CFLAGS) \
@ -106,14 +107,14 @@ nmtui_SOURCES = \
nmt-route-entry.h \
nmt-route-table.c \
nmt-route-table.h \
nmt-secret-agent.c \
nmt-secret-agent.h \
nmt-slave-list.c \
nmt-slave-list.h \
nmt-utils.c \
nmt-utils.h \
nmt-widget-list.c \
nmt-widget-list.h \
$(srcdir)/../common/nm-secret-agent-simple.c \
$(srcdir)/../common/nm-secret-agent-simple.h \
$(NULL)
nmtui_LDADD = \

View file

@ -29,7 +29,7 @@
#include <glib/gi18n-lib.h>
#include "nmt-password-dialog.h"
#include "nmt-secret-agent.h"
#include "nm-secret-agent-simple.h"
#include "nmtui.h"
G_DEFINE_TYPE (NmtPasswordDialog, nmt_password_dialog, NMT_TYPE_NEWT_FORM)
@ -60,10 +60,10 @@ enum {
/**
* nmt_password_dialog_new:
* @request_id: the request ID from the #NmtSecretAgent
* @request_id: the request ID from the #NMSecretAgentSimple
* @title: the dialog title
* @prompt: the prompt text to display
* @secrets: (element-type #NmtSecretAgentSecret): the secrets requested
* @secrets: (element-type #NMSecretAgentSimpleSecret): the secrets requested
*
* Creates a new #NmtPasswordDialog to request passwords from
* the user.
@ -109,7 +109,7 @@ maybe_save_input_and_exit (NmtNewtWidget *widget,
priv->succeeded = TRUE;
for (i = 0; i < priv->secrets->len; i++) {
NmtSecretAgentSecret *secret = priv->secrets->pdata[i];
NMSecretAgentSimpleSecret *secret = priv->secrets->pdata[i];
g_free (secret->value);
g_object_get (priv->entries->pdata[i], "text", &secret->value, NULL);
@ -143,7 +143,7 @@ nmt_password_dialog_constructed (GObject *object)
secret_grid = NMT_NEWT_GRID (widget);
for (i = 0; i < priv->secrets->len; i++) {
NmtSecretAgentSecret *secret = priv->secrets->pdata[i];
NMSecretAgentSimpleSecret *secret = priv->secrets->pdata[i];
NmtNewtEntryFlags flags;
widget = nmt_newt_label_new (secret->name);
@ -258,7 +258,7 @@ nmt_password_dialog_class_init (NmtPasswordDialogClass *dialog_class)
/**
* NmtPasswordDialog:request-id:
*
* The request ID from the #NmtSecretAgent
* The request ID from the #NMSecretAgentSimple
*/
g_object_class_install_property
(object_class, PROP_REQUEST_ID,
@ -284,7 +284,7 @@ nmt_password_dialog_class_init (NmtPasswordDialogClass *dialog_class)
*
* The array of request secrets
*
* Element-Type: #NmtSecretAgentSecret.
* Element-Type: #NMSecretAgentSimpleSecret.
*/
g_object_class_install_property
(object_class, PROP_SECRETS,

View file

@ -1,57 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2013 Red Hat, Inc.
*/
#ifndef NMT_SECRET_AGENT_H
#define NMT_SECRET_AGENT_H
#include <NetworkManager.h>
G_BEGIN_DECLS
#define NMT_TYPE_SECRET_AGENT (nmt_secret_agent_get_type ())
#define NMT_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_SECRET_AGENT, NmtSecretAgent))
#define NMT_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_SECRET_AGENT, NmtSecretAgentClass))
#define NMT_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMT_TYPE_SECRET_AGENT))
#define NMT_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMT_TYPE_SECRET_AGENT))
#define NMT_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMT_TYPE_SECRET_AGENT, NmtSecretAgentClass))
typedef struct {
NMSecretAgent parent;
} NmtSecretAgent;
typedef struct {
NMSecretAgentClass parent;
} NmtSecretAgentClass;
typedef struct {
char *name, *value;
gboolean password;
} NmtSecretAgentSecret;
GType nmt_secret_agent_get_type (void);
NMSecretAgent *nmt_secret_agent_new (void);
void nmt_secret_agent_response (NmtSecretAgent *self,
const char *request_id,
GPtrArray *secrets);
G_END_DECLS
#endif /* NMT_SECRET_AGENT_H */

View file

@ -36,16 +36,16 @@
#include "nmtui-connect.h"
#include "nmt-connect-connection-list.h"
#include "nmt-password-dialog.h"
#include "nmt-secret-agent.h"
#include "nm-secret-agent-simple.h"
#include "nmt-utils.h"
static void
secrets_requested (NmtSecretAgent *agent,
const char *request_id,
const char *title,
const char *msg,
GPtrArray *secrets,
gpointer user_data)
secrets_requested (NMSecretAgentSimple *agent,
const char *request_id,
const char *title,
const char *msg,
GPtrArray *secrets,
gpointer user_data)
{
NmtNewtForm *form;
@ -53,9 +53,9 @@ secrets_requested (NmtSecretAgent *agent,
nmt_newt_form_run_sync (form);
if (nmt_password_dialog_succeeded (NMT_PASSWORD_DIALOG (form)))
nmt_secret_agent_response (agent, request_id, secrets);
nm_secret_agent_simple_response (agent, request_id, secrets);
else
nmt_secret_agent_response (agent, request_id, NULL);
nm_secret_agent_simple_response (agent, request_id, NULL);
g_object_unref (form);
}
@ -145,7 +145,7 @@ activate_connection (NMConnection *connection,
label = nmt_newt_label_new (_("Connecting..."));
nmt_newt_form_set_content (form, label);
agent = nmt_secret_agent_new ();
agent = nm_secret_agent_simple_new ("nmtui");
g_signal_connect (agent, "request-secrets", G_CALLBACK (secrets_requested), NULL);
specific_object_path = specific_object ? nm_object_get_path (specific_object) : NULL;

View file

@ -131,6 +131,8 @@ incompatible versions may produce incorrect results.
.B \-a, \-\-ask
When using this option \fInmcli\fP will stop and ask for any missing required
arguments, so do not use this option for non-interactive purposes like scripts.
This option controls, for example, whether you will be prompted for a password
if it is required for connecting to a network.
.TP
.B \-w, \-\-wait <seconds>
This option sets a timeout period for which \fInmcli\fP will wait for \fINetworkManager\fP
@ -327,10 +329,10 @@ When no command is given to the \fIconnection\fP object, the default action
is 'nmcli connection show'.
.RE
.TP
.B up [ id | uuid | path ] <ID> [ifname <ifname>] [ap <BSSID>] [nsp <name>]
.B up [ id | uuid | path ] <ID> [ifname <ifname>] [ap <BSSID>] [nsp <name>] [passwd <file with passwords>]
.RE
.RS
.B up ifname <ifname> [ap <BSSID>] [nsp <name>]
.B up ifname <ifname> [ap <BSSID>] [nsp <name>] [passwd <file with passwords>]
.RS
.br
Activate a connection. The connection is identified by its name, UUID or D-Bus
@ -355,6 +357,26 @@ Available options are:
\(en BSSID of the AP which the command should connect to (for Wi\(hyFi connections)
.IP \fInsp\fP 13
\(en NSP (Network Service Provider) which the command should connect to (for WiMAX connections)
.IP \fIpasswd-file\fP 13
\(en some networks may require credentials during activation. You can give these
credentials using this option.
Each line of the file should contain one password in the form of
.br
\fBsetting_name.property_name:the password\fP
.br
For example, for WPA Wi-Fi with PSK, the line would be
.br
\fI802-11-wireless-security.psk:secret12345\fP
.br
For 802.1X password, the line would be
.br
\fI802-1x.password:my 1X password\fP
.br
nmcli also accepts "wifi-sec" and "wifi" strings instead of "802-11-wireless-security".
When NetworkManager requires a password and it is not given, nmcli will ask for it
when run with --ask. If --ask was not passed, NetworkManager can ask another secret
agent that may be running (typically a GUI secret agent, such as nm-applet or
gnome-shell).
.RE
.RE
.TP

View file

@ -8,6 +8,7 @@ clients/cli/general.c
clients/cli/nmcli.c
clients/cli/settings.c
clients/cli/utils.c
clients/common/nm-secret-agent-simple.c
clients/nm-online.c
clients/tui/newt/nmt-newt-utils.c
clients/tui/nm-editor-utils.c
@ -34,7 +35,6 @@ clients/tui/nmt-password-dialog.c
clients/tui/nmt-password-fields.c
clients/tui/nmt-route-editor.c
clients/tui/nmt-route-table.c
clients/tui/nmt-secret-agent.c
clients/tui/nmt-slave-list.c
clients/tui/nmt-widget-list.c
clients/tui/nmtui-connect.c