--- NetworkManager-vpnc-0.7.0/auth-dialog/main.c.orig 2007-11-07 19:05:57.000000000 +0100 +++ NetworkManager-vpnc-0.7.0/auth-dialog/main.c 2007-11-27 09:24:17.000000000 +0100 @@ -35,6 +35,32 @@ #include "../src/nm-vpnc-service.h" #include "gnome-two-password-dialog.h" +typedef struct { + const char *password; + const char *group_password; + gboolean is_session; +} KeyringData; + +void keyring_data_init(KeyringData* d) +{ + memset(d, 0, sizeof(KeyringData)); +} + +void keyring_data_free(KeyringData* d) +{ + /* For security reasons, Make sure to clear the data before freeing */ + if (d->password) { + memset((void*)d->password, 0, strlen(d->password)); + g_free((void*)d->password); + d->password = NULL; + } + if (d->group_password) { + memset((void*)d->group_password, 0, strlen(d->group_password)); + g_free((void*)d->group_password); + d->group_password = NULL; + } +} + static char * find_one_password (const char *vpn_name, const char *vpn_service, @@ -74,27 +100,14 @@ return secret; } -static GSList * -lookup_pass (const char *vpn_id, const char *vpn_name, const char *vpn_service, gboolean *is_session) +void +lookup_pass (const char *vpn_id, const char *vpn_name, const char *vpn_service, KeyringData *kdata) { - GSList *passwords = NULL; - char *password; - char *group_password; - - password = find_one_password (vpn_id, vpn_name, vpn_service, "password", is_session); - if (!password) - return NULL; - - group_password = find_one_password (vpn_id, vpn_name, vpn_service, "group-password", is_session); - if (!group_password) { - g_free (password); - return NULL; - } + keyring_data_init(kdata); - /* Group password first */ - passwords = g_slist_append (passwords, group_password); - passwords = g_slist_append (passwords, password); - return passwords; + kdata->password = find_one_password (vpn_id, vpn_name, vpn_service, "password", &(kdata->is_session)); + kdata->group_password = find_one_password (vpn_id, vpn_name, vpn_service, "group-password", + &(kdata->is_session)); } static void @@ -136,42 +149,29 @@ g_free (display_name); } -static GSList * -get_passwords (const char *vpn_id, - const char *vpn_name, - const char *vpn_service, - gboolean retry) +gboolean +get_passwords (const char *vpn_id, + const char *vpn_name, + const char *vpn_service, + gboolean retry, + KeyringData *kdata) { GSList *result; char *prompt; GtkWidget *dialog; - char *keyring_password; - char *keyring_group_password; - gboolean keyring_is_session; - GSList *keyring_result; GnomeTwoPasswordDialogRemember remember; result = NULL; - keyring_password = NULL; - keyring_group_password = NULL; - keyring_result = NULL; - - g_return_val_if_fail (vpn_id != NULL, NULL); - g_return_val_if_fail (vpn_name != NULL, NULL); - - /* Use the system user name, since the VPN might have a different user name */ - if (!retry) { - if ((result = lookup_pass (vpn_id, vpn_name, vpn_service, &keyring_is_session)) != NULL) { - return result; - } - } else { - if ((keyring_result = lookup_pass (vpn_id, vpn_name, vpn_service, &keyring_is_session)) != NULL) { - keyring_group_password = g_strdup ((char *) keyring_result->data); - keyring_password = g_strdup ((char *) (g_slist_next (keyring_result))->data); - } - g_slist_foreach (keyring_result, (GFunc)g_free, NULL); - g_slist_free (keyring_result); - } + + g_return_val_if_fail (vpn_id != NULL, FALSE); + g_return_val_if_fail (vpn_name != NULL, FALSE); + + lookup_pass (vpn_id, vpn_name, vpn_service, kdata); + + /* If this is not a retry and we have a keyring password, + don't prompt and attempt to connect */ + if (!retry && kdata->password) + return TRUE; prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network '%s'."), vpn_name); dialog = gnome_two_password_dialog_new (_("Authenticate VPN"), prompt, NULL, NULL, FALSE); @@ -180,21 +179,23 @@ gnome_two_password_dialog_set_password_secondary_label (GNOME_TWO_PASSWORD_DIALOG (dialog), _("_Group Password:")); /* use the same keyring storage options as from the items we put in the entry boxes */ remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING; - if (keyring_result != NULL) { - if (keyring_is_session) - remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION; - else - remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER; - } + if (kdata->group_password) + remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_GROUP; + else if (kdata->is_session) + remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION; + else if (kdata->password) + remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER; + gnome_two_password_dialog_set_remember (GNOME_TWO_PASSWORD_DIALOG (dialog), remember); /* if retrying, put in the passwords from the keyring */ - if (keyring_password != NULL) { - gnome_two_password_dialog_set_password (GNOME_TWO_PASSWORD_DIALOG (dialog), keyring_password); - } - if (keyring_group_password != NULL) { - gnome_two_password_dialog_set_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog), keyring_group_password); - } + if (kdata->password) + gnome_two_password_dialog_set_password (GNOME_TWO_PASSWORD_DIALOG (dialog), + kdata->password); + + if (kdata->group_password) + gnome_two_password_dialog_set_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog), + kdata->group_password); gtk_widget_show (dialog); @@ -205,11 +206,16 @@ password = gnome_two_password_dialog_get_password (GNOME_TWO_PASSWORD_DIALOG (dialog)); group_password = gnome_two_password_dialog_get_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog)); - result = g_slist_append (result, group_password); - result = g_slist_append (result, password); + keyring_data_free(kdata); + kdata->password = g_strdup(password); + kdata->group_password = g_strdup(group_password); + switch (gnome_two_password_dialog_get_remember (GNOME_TWO_PASSWORD_DIALOG (dialog))) { + case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_GROUP: + save_vpn_password (vpn_id, vpn_name, vpn_service, NULL, "group-password", group_password); + break; case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION: save_vpn_password (vpn_id, vpn_name, vpn_service, "session", "password", password); save_vpn_password (vpn_id, vpn_name, vpn_service, "session", "group-password", group_password); @@ -224,18 +230,14 @@ } - g_free (keyring_password); - g_free (keyring_group_password); - gtk_widget_destroy (dialog); - return result; + return TRUE; } int main (int argc, char *argv[]) { - GSList *passwords; static gboolean retry = FALSE; static gchar *vpn_name = NULL; static gchar *vpn_id = NULL; @@ -249,13 +251,13 @@ { NULL } }; char buf[1]; + KeyringData keyring_data; + gboolean success = FALSE; bindtextdomain (GETTEXT_PACKAGE, NULL); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); - passwords = NULL; - context = g_option_context_new ("- vpnc auth dialog"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); @@ -265,7 +267,6 @@ GNOME_PARAM_GOPTION_CONTEXT, context, GNOME_PARAM_NONE); - if (vpn_id == NULL || vpn_name == NULL || vpn_service == NULL) { fprintf (stderr, "Have to supply ID, name, and service\n"); goto out; @@ -276,21 +277,22 @@ goto out; } - passwords = get_passwords (vpn_id, vpn_name, vpn_service, retry); - if (passwords == NULL) + keyring_data_init(&keyring_data); + + if (!get_passwords (vpn_id, vpn_name, vpn_service, retry, &keyring_data)) goto out; + success = TRUE; /* dump the passwords to stdout */ - printf ("%s\n%s\n", NM_VPNC_KEY_SECRET, (char *) passwords->data); - printf ("%s\n%s\n", NM_VPNC_KEY_XAUTH_PASSWORD, (char *) passwords->next->data); + printf ("%s\n%s\n", NM_VPNC_KEY_SECRET, keyring_data.group_password); + printf ("%s\n%s\n", NM_VPNC_KEY_XAUTH_PASSWORD, keyring_data.password); printf ("\n\n"); /* for good measure, flush stdout since Kansas is going Bye-Bye */ fflush (stdout); - g_slist_foreach (passwords, (GFunc)g_free, NULL); - g_slist_free (passwords); + keyring_data_free(&keyring_data); /* wait for data on stdin */ fread (buf, sizeof (char), sizeof (buf), stdin); @@ -298,5 +300,5 @@ out: g_object_unref (program); - return passwords != NULL ? 0 : 1; + return (success ? 0 : 1); } --- NetworkManager-vpnc-0.7.0/auth-dialog/gnome-two-password-dialog.c.orig 2007-11-27 09:23:30.000000000 +0100 +++ NetworkManager-vpnc-0.7.0/auth-dialog/gnome-two-password-dialog.c 2007-11-27 09:24:17.000000000 +0100 @@ -69,6 +69,7 @@ GtkWidget *remember_session_button; GtkWidget *remember_forever_button; + GtkWidget *remember_group_button; GtkWidget *radio_vbox; GtkWidget *connect_with_no_userpass_button; @@ -462,14 +463,18 @@ gtk_widget_show_all (GTK_DIALOG (password_dialog)->vbox); password_dialog->details->remember_session_button = - gtk_check_button_new_with_mnemonic (_("_Remember passwords for this session")); + gtk_radio_button_new_with_mnemonic (NULL, _("_Remember passwords for this session")); password_dialog->details->remember_forever_button = - gtk_check_button_new_with_mnemonic (_("_Save passwords in keyring")); + gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (password_dialog->details->remember_session_button), _("_Save passwords in keyring")); + password_dialog->details->remember_group_button = + gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (password_dialog->details->remember_session_button), _("S_ave group password in keyring")); gtk_box_pack_start (GTK_BOX (vbox), password_dialog->details->remember_session_button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), password_dialog->details->remember_forever_button, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), password_dialog->details->remember_group_button, + FALSE, FALSE, 0); gnome_two_password_dialog_set_username (password_dialog, username); gnome_two_password_dialog_set_password (password_dialog, password); @@ -688,9 +693,11 @@ if (show_remember) { gtk_widget_show (password_dialog->details->remember_session_button); gtk_widget_show (password_dialog->details->remember_forever_button); + gtk_widget_show (password_dialog->details->remember_group_button); } else { gtk_widget_hide (password_dialog->details->remember_session_button); gtk_widget_hide (password_dialog->details->remember_forever_button); + gtk_widget_hide (password_dialog->details->remember_group_button); } } @@ -698,32 +705,46 @@ gnome_two_password_dialog_set_remember (GnomeTwoPasswordDialog *password_dialog, GnomeTwoPasswordDialogRemember remember) { - gboolean session, forever; + gboolean session, forever, group; session = FALSE; forever = FALSE; - if (remember == GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION) { + group = FALSE; + + switch (remember) { + case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION: session = TRUE; - } else if (remember == GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER){ + break; + case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER: forever = TRUE; + break; + case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_GROUP: + group = TRUE; + break; } + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (password_dialog->details->remember_session_button), session); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (password_dialog->details->remember_forever_button), forever); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (password_dialog->details->remember_group_button), + group); } GnomeTwoPasswordDialogRemember gnome_two_password_dialog_get_remember (GnomeTwoPasswordDialog *password_dialog) { - gboolean session, forever; + gboolean session, forever, group; session = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (password_dialog->details->remember_session_button)); forever = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (password_dialog->details->remember_forever_button)); + group = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (password_dialog->details->remember_group_button)); if (forever) { return GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER; } else if (session) { return GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION; + } else if (group) { + return GNOME_TWO_PASSWORD_DIALOG_REMEMBER_GROUP; } return GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING; } --- NetworkManager-vpnc-0.7.0/auth-dialog/gnome-two-password-dialog.h.orig 2007-11-27 09:23:26.000000000 +0100 +++ NetworkManager-vpnc-0.7.0/auth-dialog/gnome-two-password-dialog.h 2007-11-27 09:24:17.000000000 +0100 @@ -57,6 +57,7 @@ typedef enum { GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION, + GNOME_TWO_PASSWORD_DIALOG_REMEMBER_GROUP, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER } GnomeTwoPasswordDialogRemember;