[network-manager-openvpn/dcbw/need-secrets: 5/5] auth-dialog: more clearly separate external-ui-mode and normal mode



commit 747c1f1f0376a212f89975f6f3cc6fdc0fa2b231
Author: Dan Williams <dcbw redhat com>
Date:   Wed Jul 17 14:39:28 2013 -0500

    auth-dialog: more clearly separate external-ui-mode and normal mode
    
    Split the various logical bits out into separate functions that we
    can select from based on whether external-ui-mode is being used or
    not.  Reduces confusing codepaths.

 auth-dialog/main.c |  373 +++++++++++++++++++++++++++++-----------------------
 1 files changed, 206 insertions(+), 167 deletions(-)
---
diff --git a/auth-dialog/main.c b/auth-dialog/main.c
index 3b71f36..ca330c1 100644
--- a/auth-dialog/main.c
+++ b/auth-dialog/main.c
@@ -93,10 +93,24 @@ keyring_lookup_secret (const char *uuid, const char *secret_name)
 /*****************************************************************/
 
 typedef void (*NoSecretsRequiredFunc) (void);
-typedef void (*FinishFunc) (gboolean need_password,
-                            const char *new_password,
+
+/* 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 *new_certpass);
+                            const char *certpass);
 
 /*****************************************************************/
 /* External UI mode stuff */
@@ -141,6 +155,49 @@ eui_no_secrets_required (void)
        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) {
+               keyfile_add_entry_info (keyfile,
+                                       NM_OPENVPN_KEY_PASSWORD,
+                                       existing_password ? existing_password : "",
+                                       _("Password:"),
+                                       TRUE,
+                                       allow_interaction);
+       }
+
+       if (need_certpass) {
+               keyfile_add_entry_info (keyfile,
+                                       NM_OPENVPN_KEY_CERTPASS,
+                                       existing_certpass ? existing_certpass : "",
+                                       _("Certificate password:"),
+                                       TRUE,
+                                       allow_interaction);
+       }
+
+       keyfile_print_stdout (keyfile);
+       g_key_file_unref (keyfile);
+}
+
 /*****************************************************************/
 
 static void
@@ -149,6 +206,61 @@ std_no_secrets_required (void)
        printf ("%s\n%s\n\n\n", NM_OPENVPN_KEY_NOSECRET, "true");
 }
 
+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;
+
+       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 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:") );
+
+               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)
+                       nma_vpn_password_dialog_set_password (dialog, existing_password);
+               else if (need_certpass) {
+                       nma_vpn_password_dialog_set_password_label (dialog, _("Certificate password:"));
+                       nma_vpn_password_dialog_set_password (dialog, existing_certpass);
+               }
+       }
+
+       gtk_widget_show (GTK_WIDGET (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));
+
+       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;
+}
+
 static void
 wait_for_quit (void)
 {
@@ -175,15 +287,19 @@ wait_for_quit (void)
 }
 
 static void
-std_finish (gboolean need_password,
-            const char *new_password,
+std_finish (const char *vpn_name,
+            const char *prompt,
+            gboolean allow_interaction,
+            gboolean need_password,
+            const char *password,
             gboolean need_certpass,
-            const char *new_certpass)
+            const char *certpass)
 {
-       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);
+       /* 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 */
@@ -195,137 +311,38 @@ std_finish (gboolean need_password,
 
 /*****************************************************************/
 
-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
+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)
 {
-       NMAVpnPasswordDialog *dialog;
-       char *prompt, *password = NULL, *certpass = NULL;
-       gboolean success = FALSE, need_secret = FALSE;
+       NMSettingSecretFlags pw_flags = NM_SETTING_SECRET_FLAG_NONE;
+       NMSettingSecretFlags cp_flags = NM_SETTING_SECRET_FLAG_NONE;
 
-       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);
+       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)) {
-                       if (in_pass)
-                               password = g_strdup (in_pass);
-                       else
-                               password = keyring_lookup_secret (vpn_uuid, NM_OPENVPN_KEY_PASSWORD);
+                       *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);
                }
-               if (!password && !(pw_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED))
-                       need_secret = TRUE;
        }
 
+       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)) {
-                       if (in_certpass)
-                               certpass = g_strdup (in_certpass);
-                       else
-                               certpass = keyring_lookup_secret (vpn_uuid, NM_OPENVPN_KEY_CERTPASS);
+                       *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);
                }
-               if (!certpass && !(cp_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED))
-                       need_secret = TRUE;
-       }
-
-       /* 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);
-
-       if (external_ui_mode) {
-               GKeyFile *keyfile;
-
-               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);
-               g_key_file_set_string (keyfile, UI_KEYFILE_GROUP, "Title", _("Authenticate VPN"));
-
-               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;
        }
-
-       dialog = NMA_VPN_PASSWORD_DIALOG (nma_vpn_password_dialog_new (_("Authenticate VPN"), prompt, NULL));
-
-       /* pre-fill dialog with the password */
-       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);
-       } 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) {
-                       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);
-               }
-       }
-
-       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));
-               }
-
-               success = TRUE;
-       }
-
-       gtk_widget_destroy (GTK_WIDGET (dialog));
-
- out:
-       g_free (password);
-       g_free (certpass);
-
-       g_free (prompt);
-
-       return success;
 }
 
 #define VPN_MSG_TAG "x-vpn-message:"
@@ -377,6 +394,15 @@ get_passwords_required (GHashTable *data,
        return NULL;
 }
 
+static void
+free_secret (char *p)
+{
+       if (p) {
+               memset (p, 0, strlen (p));
+               g_free (p);
+       }
+}
+
 int 
 main (int argc, char *argv[])
 {
@@ -386,15 +412,15 @@ 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;
 
-       FinishFunc finish_func = NULL;
        NoSecretsRequiredFunc no_secrets_required_func = NULL;
+       AskUserFunc ask_user_func = NULL;
+       FinishFunc finish_func = NULL;
 
        GOptionContext *context;
        GOptionEntry entries[] = {
@@ -437,8 +463,10 @@ main (int argc, char *argv[])
 
        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;
        }
 
@@ -446,44 +474,55 @@ main (int argc, char *argv[])
         * 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 (no_secrets_required_func)
-                       no_secrets_required_func ();
-               goto done;
-       }
+       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);
+               }
 
-       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 (finish_func)
-               finish_func (need_password, new_password, need_certpass, new_certpass);
-
-       if (new_password) {
-               memset (new_password, 0, strlen (new_password));
-               g_free (new_password);
-       }
-       if (new_certpass) {
-               memset (new_certpass, 0, strlen (new_certpass));
-               g_free (new_certpass);
+               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);
+               }
+
+               free_secret (existing_password);
+               free_secret (existing_certpass);
+               free_secret (new_password);
+               free_secret (new_certpass);
        }
 
-done:
        if (data)
                g_hash_table_unref (data);
        if (secrets)
@@ -491,5 +530,5 @@ done:
        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]