[network-manager-openvpn/dcbw/need-secrets: 4/4] auth-dialog: better splitting of standard vs. external-ui-mode logic
- From: Dan Williams <dcbw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openvpn/dcbw/need-secrets: 4/4] auth-dialog: better splitting of standard vs. external-ui-mode logic
- Date: Fri, 26 Jul 2013 04:27:11 +0000 (UTC)
commit baf59a2eebb703c3677a5821bc6faf478c41ffb2
Author: Dan Williams <dcbw redhat com>
Date: Tue Jul 16 15:12:35 2013 -0500
auth-dialog: better splitting of standard vs. external-ui-mode logic
Use function pointers and populate them with the right functions for
each mode instead of interleaving confusing code everywhere.
auth-dialog/main.c | 427 +++++++++++++++++++++++++++++++---------------------
1 files changed, 255 insertions(+), 172 deletions(-)
---
diff --git a/auth-dialog/main.c b/auth-dialog/main.c
index b457a79..ca330c1 100644
--- a/auth-dialog/main.c
+++ b/auth-dialog/main.c
@@ -90,6 +90,31 @@ keyring_lookup_secret (const char *uuid, const char *secret_name)
return secret;
}
+/*****************************************************************/
+
+typedef void (*NoSecretsRequiredFunc) (void);
+
+/* Returns TRUE on success, FALSE on cancel */
+typedef gboolean (*AskUserFunc) (const char *vpn_name,
+ const char *prompt,
+ gboolean need_password,
+ const char *existing_password,
+ char **out_new_password,
+ gboolean need_certpass,
+ const char *existing_certpass,
+ char **out_new_certpass);
+
+typedef void (*FinishFunc) (const char *vpn_name,
+ const char *prompt,
+ gboolean allow_interaction,
+ gboolean need_password,
+ const char *password,
+ gboolean need_certpass,
+ const char *certpass);
+
+/*****************************************************************/
+/* External UI mode stuff */
+
static void
keyfile_add_entry_info (GKeyFile *keyfile,
const gchar *key,
@@ -117,137 +142,207 @@ keyfile_print_stdout (GKeyFile *keyfile)
g_free (data);
}
-static gboolean
-get_secrets (const char *vpn_name,
- const char *vpn_uuid,
- gboolean need_password,
- gboolean need_certpass,
- gboolean retry,
- gboolean allow_interaction,
- gboolean external_ui_mode,
- const char *in_pass,
- NMSettingSecretFlags pw_flags,
- char **out_password,
- const char *in_certpass,
- NMSettingSecretFlags cp_flags,
- char **out_certpass)
+static void
+eui_no_secrets_required (void)
{
- NMAVpnPasswordDialog *dialog;
- char *prompt, *password = NULL, *certpass = NULL;
- gboolean success = FALSE, need_secret = FALSE;
+ GKeyFile *keyfile;
- g_return_val_if_fail (vpn_name != NULL, FALSE);
- g_return_val_if_fail (vpn_uuid != NULL, FALSE);
- g_return_val_if_fail (out_password != NULL, FALSE);
- g_return_val_if_fail (out_certpass != NULL, FALSE);
+ keyfile = g_key_file_new ();
+
+ g_key_file_set_integer (keyfile, UI_KEYFILE_GROUP, "Version", 2);
+ keyfile_add_entry_info (keyfile, NM_OPENVPN_KEY_NOSECRET, "true", "", TRUE, FALSE);
+ keyfile_print_stdout (keyfile);
+ g_key_file_unref (keyfile);
+}
+
+static void
+eui_finish (const char *vpn_name,
+ const char *prompt,
+ gboolean allow_interaction,
+ gboolean need_password,
+ const char *existing_password,
+ gboolean need_certpass,
+ const char *existing_certpass)
+{
+ GKeyFile *keyfile;
+ char *title;
+
+ keyfile = g_key_file_new ();
+
+ g_key_file_set_integer (keyfile, UI_KEYFILE_GROUP, "Version", 2);
+ g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Description", prompt);
+
+ title = g_strdup_printf (_("Authenticate VPN %s"), vpn_name);
+ g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", title);
+ g_free (title);
if (need_password) {
- if (!(pw_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) {
- if (in_pass)
- password = g_strdup (in_pass);
- else
- password = keyring_lookup_secret (vpn_uuid, NM_OPENVPN_KEY_PASSWORD);
- }
- if (!password && !(pw_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED))
- need_secret = TRUE;
+ keyfile_add_entry_info (keyfile,
+ NM_OPENVPN_KEY_PASSWORD,
+ existing_password ? existing_password : "",
+ _("Password:"),
+ TRUE,
+ allow_interaction);
}
if (need_certpass) {
- if (!(cp_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) {
- if (in_certpass)
- certpass = g_strdup (in_certpass);
- else
- certpass = keyring_lookup_secret (vpn_uuid, NM_OPENVPN_KEY_CERTPASS);
- }
- if (!certpass && !(cp_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED))
- need_secret = TRUE;
+ keyfile_add_entry_info (keyfile,
+ NM_OPENVPN_KEY_CERTPASS,
+ existing_certpass ? existing_certpass : "",
+ _("Certificate password:"),
+ TRUE,
+ allow_interaction);
}
- /* In other_ui mode, we don't actually show the dialog. Instead we pass back everything
- that is needed to build it */
- prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network '%s'."),
vpn_name);
+ keyfile_print_stdout (keyfile);
+ g_key_file_unref (keyfile);
+}
- if (external_ui_mode) {
- GKeyFile *keyfile;
+/*****************************************************************/
- keyfile = g_key_file_new ();
+static void
+std_no_secrets_required (void)
+{
+ printf ("%s\n%s\n\n\n", NM_OPENVPN_KEY_NOSECRET, "true");
+}
- g_key_file_set_integer (keyfile, UI_KEYFILE_GROUP, "Version", 2);
- g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Description", prompt);
- g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", _("Authenticate VPN"));
+static gboolean
+std_ask_user (const char *vpn_name,
+ const char *prompt,
+ gboolean need_password,
+ const char *existing_password,
+ char **out_new_password,
+ gboolean need_certpass,
+ const char *existing_certpass,
+ char **out_new_certpass)
+{
+ NMAVpnPasswordDialog *dialog;
- if (need_password)
- keyfile_add_entry_info (keyfile, NM_OPENVPN_KEY_PASSWORD, password ? password : "",
_("Password:"), TRUE, allow_interaction);
- if (need_certpass)
- keyfile_add_entry_info (keyfile, NM_OPENVPN_KEY_CERTPASS, certpass ? certpass : "",
_("Certificate password:"), TRUE, allow_interaction);
-
- keyfile_print_stdout (keyfile);
- g_key_file_unref (keyfile);
-
- success = TRUE;
- goto out;
- } else if (allow_interaction == FALSE || (!need_secret && !retry)) {
- /* Either interaction is not allowed so pass back any passwords we have
- * without asking the user, or we've got all the passwords we need already.
- */
- if (need_password)
- *out_password = password;
- if (need_certpass)
- *out_certpass = certpass;
- g_free (prompt);
- return TRUE;
- }
+ g_return_val_if_fail (vpn_name != NULL, FALSE);
+ g_return_val_if_fail (prompt != NULL, FALSE);
+ g_return_val_if_fail (out_new_password != NULL, FALSE);
+ g_return_val_if_fail (out_new_certpass != NULL, FALSE);
dialog = NMA_VPN_PASSWORD_DIALOG (nma_vpn_password_dialog_new (_("Authenticate VPN"), prompt, NULL));
- /* pre-fill dialog with the password */
+ /* pre-fill dialog with existing passwords */
if (need_password && need_certpass) {
nma_vpn_password_dialog_set_show_password_secondary (dialog, TRUE);
nma_vpn_password_dialog_set_password_secondary_label (dialog, _("Certificate pass_word:") );
- /* if retrying, put in the passwords from the keyring */
- if (password)
- nma_vpn_password_dialog_set_password (dialog, password);
- if (certpass)
- nma_vpn_password_dialog_set_password_secondary (dialog, certpass);
+ nma_vpn_password_dialog_set_password (dialog, existing_password);
+ nma_vpn_password_dialog_set_password_secondary (dialog, existing_certpass);
} else {
nma_vpn_password_dialog_set_show_password_secondary (dialog, FALSE);
- if (need_password) {
- /* if retrying, put in the passwords from the keyring */
- if (password)
- nma_vpn_password_dialog_set_password (dialog, password);
- } else if (need_certpass) {
+ if (need_password)
+ nma_vpn_password_dialog_set_password (dialog, existing_password);
+ else if (need_certpass) {
nma_vpn_password_dialog_set_password_label (dialog, _("Certificate password:"));
- /* if retrying, put in the passwords from the keyring */
- if (certpass)
- nma_vpn_password_dialog_set_password (dialog, certpass);
+ nma_vpn_password_dialog_set_password (dialog, existing_certpass);
}
}
gtk_widget_show (GTK_WIDGET (dialog));
- if (nma_vpn_password_dialog_run_and_block (dialog)) {
- if (need_password)
- *out_password = g_strdup (nma_vpn_password_dialog_get_password (dialog));
- if (need_certpass) {
- if (need_password)
- *out_certpass = g_strdup (nma_vpn_password_dialog_get_password_secondary
(dialog));
- else
- *out_certpass = g_strdup (nma_vpn_password_dialog_get_password (dialog));
- }
+ if (!nma_vpn_password_dialog_run_and_block (dialog))
+ return FALSE;
+
+ if (need_password)
+ *out_new_password = g_strdup (nma_vpn_password_dialog_get_password (dialog));
- success = TRUE;
+ if (need_certpass) {
+ if (need_password)
+ *out_new_certpass = g_strdup (nma_vpn_password_dialog_get_password_secondary
(dialog));
+ else
+ *out_new_certpass = g_strdup (nma_vpn_password_dialog_get_password (dialog));
}
gtk_widget_destroy (GTK_WIDGET (dialog));
+ return TRUE;
+}
- out:
- g_free (password);
- g_free (certpass);
+static void
+wait_for_quit (void)
+{
+ GString *str;
+ char c;
+ ssize_t n;
+ time_t start;
- g_free (prompt);
+ str = g_string_sized_new (10);
+ start = time (NULL);
+ do {
+ errno = 0;
+ n = read (0, &c, 1);
+ if (n == 0 || (n < 0 && errno == EAGAIN))
+ g_usleep (G_USEC_PER_SEC / 10);
+ else if (n == 1) {
+ g_string_append_c (str, c);
+ if (strstr (str->str, "QUIT") || (str->len > 10))
+ break;
+ } else
+ break;
+ } while (time (NULL) < start + 20);
+ g_string_free (str, TRUE);
+}
- return success;
+static void
+std_finish (const char *vpn_name,
+ const char *prompt,
+ gboolean allow_interaction,
+ gboolean need_password,
+ const char *password,
+ gboolean need_certpass,
+ const char *certpass)
+{
+ /* Send the passwords back to our parent */
+ if (need_password && password)
+ printf ("%s\n%s\n", NM_OPENVPN_KEY_PASSWORD, password);
+ if (need_certpass && certpass)
+ printf ("%s\n%s\n", NM_OPENVPN_KEY_CERTPASS, certpass);
+ printf ("\n\n");
+
+ /* for good measure, flush stdout since Kansas is going Bye-Bye */
+ fflush (stdout);
+
+ /* Wait for quit signal */
+ wait_for_quit ();
+}
+
+/*****************************************************************/
+
+static void
+get_existing_passwords (GHashTable *vpn_data,
+ GHashTable *existing_secrets,
+ const char *vpn_uuid,
+ gboolean need_password,
+ gboolean need_certpass,
+ char **out_password,
+ char **out_certpass)
+{
+ NMSettingSecretFlags pw_flags = NM_SETTING_SECRET_FLAG_NONE;
+ NMSettingSecretFlags cp_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ g_return_if_fail (out_password != NULL);
+ g_return_if_fail (out_certpass != NULL);
+
+ nm_vpn_plugin_utils_get_secret_flags (vpn_data, NM_OPENVPN_KEY_PASSWORD, &pw_flags);
+ if (need_password) {
+ if (!(pw_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) {
+ *out_password = g_strdup (g_hash_table_lookup (existing_secrets,
NM_OPENVPN_KEY_PASSWORD));
+ if (!*out_password)
+ *out_password = keyring_lookup_secret (vpn_uuid, NM_OPENVPN_KEY_PASSWORD);
+ }
+ }
+
+ nm_vpn_plugin_utils_get_secret_flags (vpn_data, NM_OPENVPN_KEY_CERTPASS, &cp_flags);
+ if (need_certpass) {
+ if (!(cp_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) {
+ *out_certpass = g_strdup (g_hash_table_lookup (existing_secrets,
NM_OPENVPN_KEY_CERTPASS));
+ if (!*out_certpass)
+ *out_certpass = keyring_lookup_secret (vpn_uuid, NM_OPENVPN_KEY_CERTPASS);
+ }
+ }
}
#define VPN_MSG_TAG "x-vpn-message:"
@@ -300,28 +395,12 @@ get_passwords_required (GHashTable *data,
}
static void
-wait_for_quit (void)
+free_secret (char *p)
{
- GString *str;
- char c;
- ssize_t n;
- time_t start;
-
- str = g_string_sized_new (10);
- start = time (NULL);
- do {
- errno = 0;
- n = read (0, &c, 1);
- if (n == 0 || (n < 0 && errno == EAGAIN))
- g_usleep (G_USEC_PER_SEC / 10);
- else if (n == 1) {
- g_string_append_c (str, c);
- if (strstr (str->str, "QUIT") || (str->len > 10))
- break;
- } else
- break;
- } while (time (NULL) < start + 20);
- g_string_free (str, TRUE);
+ if (p) {
+ memset (p, 0, strlen (p));
+ g_free (p);
+ }
}
int
@@ -333,12 +412,16 @@ main (int argc, char *argv[])
gchar *vpn_service = NULL;
GHashTable *data = NULL, *secrets = NULL;
gboolean need_password = FALSE, need_certpass = FALSE;
+ char *existing_password = NULL, *existing_certpass = NULL;
char *new_password = NULL, *new_certpass = NULL;
char **hints = NULL;
char *prompt = NULL;
- gboolean external_ui_mode = FALSE;
- NMSettingSecretFlags pw_flags = NM_SETTING_SECRET_FLAG_NONE;
- NMSettingSecretFlags cp_flags = NM_SETTING_SECRET_FLAG_NONE;
+ gboolean external_ui_mode = FALSE, canceled = FALSE, ask_user = FALSE;
+
+ NoSecretsRequiredFunc no_secrets_required_func = NULL;
+ AskUserFunc ask_user_func = NULL;
+ FinishFunc finish_func = NULL;
+
GOptionContext *context;
GOptionEntry entries[] = {
{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
@@ -378,66 +461,66 @@ main (int argc, char *argv[])
return 1;
}
+ if (external_ui_mode) {
+ no_secrets_required_func = eui_no_secrets_required;
+ finish_func = eui_finish;
+ } else {
+ no_secrets_required_func = std_no_secrets_required;
+ ask_user_func = std_ask_user;
+ finish_func = std_finish;
+ }
+
/* Determine which passwords are actually required, either from hints or
* from looking at the VPN configuration.
*/
prompt = get_passwords_required (data, hints, &need_password, &need_certpass);
+ if (!prompt)
+ prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network
'%s'."), vpn_name);
/* Exit early if we don't need any passwords */
- if (!need_password && !need_certpass) {
- if (external_ui_mode) {
- GKeyFile *keyfile;
-
- keyfile = g_key_file_new ();
-
- g_key_file_set_integer (keyfile, UI_KEYFILE_GROUP, "Version", 2);
- keyfile_add_entry_info (keyfile, NM_OPENVPN_KEY_NOSECRET, "true", "", TRUE, FALSE);
- keyfile_print_stdout (keyfile);
-
- g_key_file_unref (keyfile);
- } else {
- /* The older protocol */
- printf ("%s\n%s\n\n\n", NM_OPENVPN_KEY_NOSECRET, "true");
+ if (!need_password && !need_certpass)
+ no_secrets_required_func ();
+ else {
+ get_existing_passwords (data,
+ secrets,
+ vpn_uuid,
+ need_password,
+ need_certpass,
+ &existing_password,
+ &existing_certpass);
+ if (need_password && !existing_password)
+ ask_user = TRUE;
+ if (need_certpass && !existing_certpass)
+ ask_user = TRUE;
+
+ /* If interaction is allowed then ask the user, otherwise pass back
+ * whatever existing secrets we can find.
+ */
+ if (ask_user_func && allow_interaction && (ask_user || retry)) {
+ canceled = !ask_user_func (vpn_name,
+ prompt,
+ need_password,
+ existing_password,
+ &new_password,
+ need_certpass,
+ existing_certpass,
+ &new_certpass);
}
- g_free (prompt);
- return 0;
- }
+ if (!canceled) {
+ finish_func (vpn_name,
+ prompt,
+ allow_interaction,
+ need_password,
+ new_password ? new_password : existing_password,
+ need_certpass,
+ new_certpass ? new_certpass : existing_certpass);
+ }
- nm_vpn_plugin_utils_get_secret_flags (data, NM_OPENVPN_KEY_PASSWORD, &pw_flags);
- nm_vpn_plugin_utils_get_secret_flags (data, NM_OPENVPN_KEY_CERTPASS, &cp_flags);
- if (!get_secrets (vpn_name,
- vpn_uuid,
- need_password,
- need_certpass,
- retry,
- allow_interaction,
- external_ui_mode,
- g_hash_table_lookup (secrets, NM_OPENVPN_KEY_PASSWORD),
- pw_flags,
- &new_password,
- g_hash_table_lookup (secrets, NM_OPENVPN_KEY_CERTPASS),
- cp_flags,
- &new_certpass))
- return 1; /* canceled */
-
- if (!external_ui_mode) {
- if (need_password && new_password)
- printf ("%s\n%s\n", NM_OPENVPN_KEY_PASSWORD, new_password);
- if (need_certpass && new_certpass)
- printf ("%s\n%s\n", NM_OPENVPN_KEY_CERTPASS, new_certpass);
- printf ("\n\n");
-
- if (new_password)
- g_free (new_password);
- if (new_certpass)
- g_free (new_certpass);
-
- /* for good measure, flush stdout since Kansas is going Bye-Bye */
- fflush (stdout);
-
- /* Wait for quit signal */
- wait_for_quit ();
+ free_secret (existing_password);
+ free_secret (existing_certpass);
+ free_secret (new_password);
+ free_secret (new_certpass);
}
if (data)
@@ -447,5 +530,5 @@ main (int argc, char *argv[])
if (hints)
g_strfreev (hints);
g_free (prompt);
- return 0;
+ return canceled ? 1 : 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]