diff --git a/clients/cli/Makefile.am b/clients/cli/Makefile.am index 94a249749e..4f4fcf4c6d 100644 --- a/clients/cli/Makefile.am +++ b/clients/cli/Makefile.am @@ -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) \ diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 4d48e2fb60..717945b33d 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -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] ] ...\n\n" #if WITH_WIMAX - " up [[id | uuid | path] ] [ifname ] [ap ] [nsp ]\n\n" + " up [[id | uuid | path] ] [ifname ] [ap ] [nsp ] [passwd-file ]\n\n" #else - " up [[id | uuid | path] ] [ifname ] [ap ]\n\n" + " up [[id | uuid | path] ] [ifname ] [ap ] [passwd-file ]\n\n" #endif " down [id | uuid | path | apath] \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] [ifname ] [ap ] [nsp ]\n" + "ARGUMENTS := [id | uuid | path] [ifname ] [ap ] [nsp ] [passwd-file ]\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 [ap ] [nsp ]\n" + "ARGUMENTS := ifname [ap ] [nsp ] [passwd-file ]\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); diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion index a9dfc41774..1e087f7419 100644 --- a/clients/cli/nmcli-completion +++ b/clients/cli/nmcli-completion @@ -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 diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index b1a810ce7a..8410020fee 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -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); diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index 0a87bd9147..a18de18546 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -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 */ diff --git a/clients/tui/nmt-secret-agent.c b/clients/common/nm-secret-agent-simple.c similarity index 55% rename from clients/tui/nmt-secret-agent.c rename to clients/common/nm-secret-agent-simple.c index 40ab9c14cb..cb1f086016 100644 --- a/clients/tui/nmt-secret-agent.c +++ b/clients/common/nm-secret-agent-simple.c @@ -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 #include -#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 { - /* */ + /* */ 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 value 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 value 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 + * value 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); } diff --git a/clients/common/nm-secret-agent-simple.h b/clients/common/nm-secret-agent-simple.h new file mode 100644 index 0000000000..7e11d2a5c0 --- /dev/null +++ b/clients/common/nm-secret-agent-simple.h @@ -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 . + * + * Copyright 2013 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_SECRET_AGENT_SIMPLE_H__ +#define __NM_SECRET_AGENT_SIMPLE_H__ + +#include + +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__ */ diff --git a/clients/tui/Makefile.am b/clients/tui/Makefile.am index fb5ad8fcf0..290ef155a3 100644 --- a/clients/tui/Makefile.am +++ b/clients/tui/Makefile.am @@ -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 = \ diff --git a/clients/tui/nmt-password-dialog.c b/clients/tui/nmt-password-dialog.c index 22ba85d2c5..aeece1211f 100644 --- a/clients/tui/nmt-password-dialog.c +++ b/clients/tui/nmt-password-dialog.c @@ -29,7 +29,7 @@ #include #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, diff --git a/clients/tui/nmt-secret-agent.h b/clients/tui/nmt-secret-agent.h deleted file mode 100644 index e7f6ef846b..0000000000 --- a/clients/tui/nmt-secret-agent.h +++ /dev/null @@ -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 . - * - * Copyright 2013 Red Hat, Inc. - */ - -#ifndef NMT_SECRET_AGENT_H -#define NMT_SECRET_AGENT_H - -#include - -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 */ diff --git a/clients/tui/nmtui-connect.c b/clients/tui/nmtui-connect.c index be03796986..e2ffeb6495 100644 --- a/clients/tui/nmtui-connect.c +++ b/clients/tui/nmtui-connect.c @@ -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; diff --git a/man/nmcli.1.in b/man/nmcli.1.in index 109317f768..2d142f4eaa 100644 --- a/man/nmcli.1.in +++ b/man/nmcli.1.in @@ -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 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 ] [ifname ] [ap ] [nsp ] +.B up [ id | uuid | path ] [ifname ] [ap ] [nsp ] [passwd ] .RE .RS -.B up ifname [ap ] [nsp ] +.B up ifname [ap ] [nsp ] [passwd ] .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 diff --git a/po/POTFILES.in b/po/POTFILES.in index 0acabd9173..869cd6e7c3 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -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