Update auth-dialog like in network-manager-pptp (master 8b5c8b6ca3d24f7b5f736b8a7a29956f0bce35f3)

parent 06c2ffd8
...@@ -18,9 +18,9 @@ nm_l2tp_auth_dialog_CPPFLAGS = \ ...@@ -18,9 +18,9 @@ nm_l2tp_auth_dialog_CPPFLAGS = \
-DVERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\"
nm_l2tp_auth_dialog_SOURCES = \ nm_l2tp_auth_dialog_SOURCES = \
main.c \ main.c \
gnome-two-password-dialog.c \ vpn-password-dialog.c \
gnome-two-password-dialog.h vpn-password-dialog.h
nm_l2tp_auth_dialog_LDADD = \ nm_l2tp_auth_dialog_LDADD = \
$(GTK_LIBS) \ $(GTK_LIBS) \
......
This diff is collapsed.
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* gnome-two-password-dialog.h - A use password prompting dialog widget
asking for two passwords. Based of
gnome-password-dialog.[ch] from libgnomeui
Copyright (C) 1999, 2000 Eazel, Inc.
Copyright (C) 2005, Red Hat, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library 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
Library General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Authors: Ramiro Estrugo <ramiro@eazel.com>
*/
#ifndef GNOME_TWO_PASSWORD_DIALOG_H
#define GNOME_TWO_PASSWORD_DIALOG_H
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GNOME_TYPE_TWO_PASSWORD_DIALOG (gnome_two_password_dialog_get_type ())
#define GNOME_TWO_PASSWORD_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_TWO_PASSWORD_DIALOG, GnomeTwoPasswordDialog))
#define GNOME_TWO_PASSWORD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_TWO_PASSWORD_DIALOG, GnomeTwoPasswordDialogClass))
#define GNOME_IS_TWO_PASSWORD_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_TWO_PASSWORD_DIALOG))
#define GNOME_IS_TWO_PASSWORD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_TWO_PASSWORD_DIALOG))
typedef struct GnomeTwoPasswordDialog GnomeTwoPasswordDialog;
typedef struct GnomeTwoPasswordDialogClass GnomeTwoPasswordDialogClass;
typedef struct GnomeTwoPasswordDialogDetails GnomeTwoPasswordDialogDetails;
struct GnomeTwoPasswordDialog
{
GtkDialog gtk_dialog;
GnomeTwoPasswordDialogDetails *details;
};
struct GnomeTwoPasswordDialogClass
{
GtkDialogClass parent_class;
};
typedef enum {
GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING,
GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION,
GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER
} GnomeTwoPasswordDialogRemember;
GType gnome_two_password_dialog_get_type (void);
GtkWidget* gnome_two_password_dialog_new (const char *dialog_title,
const char *message,
const char *username,
const char *password,
gboolean readonly_username);
gboolean gnome_two_password_dialog_run_and_block (GnomeTwoPasswordDialog *password_dialog);
/* Attribute mutators */
void gnome_two_password_dialog_set_show_username (GnomeTwoPasswordDialog *password_dialog,
gboolean show);
void gnome_two_password_dialog_set_show_domain (GnomeTwoPasswordDialog *password_dialog,
gboolean show);
void gnome_two_password_dialog_set_show_password (GnomeTwoPasswordDialog *password_dialog,
gboolean show);
void gnome_two_password_dialog_set_show_password_secondary (GnomeTwoPasswordDialog *password_dialog,
gboolean show);
void gnome_two_password_dialog_set_username (GnomeTwoPasswordDialog *password_dialog,
const char *username);
void gnome_two_password_dialog_set_domain (GnomeTwoPasswordDialog *password_dialog,
const char *domain);
void gnome_two_password_dialog_set_password (GnomeTwoPasswordDialog *password_dialog,
const char *password);
void gnome_two_password_dialog_set_password_secondary (GnomeTwoPasswordDialog *password_dialog,
const char *password_secondary);
void gnome_two_password_dialog_set_readonly_username (GnomeTwoPasswordDialog *password_dialog,
gboolean readonly);
void gnome_two_password_dialog_set_readonly_domain (GnomeTwoPasswordDialog *password_dialog,
gboolean readonly);
void gnome_two_password_dialog_set_password_secondary_label (GnomeTwoPasswordDialog *password_dialog,
const char *password_secondary_description);
void gnome_two_password_dialog_set_show_remember (GnomeTwoPasswordDialog *password_dialog,
gboolean show_remember);
void gnome_two_password_dialog_set_remember (GnomeTwoPasswordDialog *password_dialog,
GnomeTwoPasswordDialogRemember remember);
GnomeTwoPasswordDialogRemember gnome_two_password_dialog_get_remember (GnomeTwoPasswordDialog *password_dialog);
void gnome_two_password_dialog_set_show_userpass_buttons (GnomeTwoPasswordDialog *password_dialog,
gboolean show_userpass_buttons);
/* Attribute accessors */
char * gnome_two_password_dialog_get_username (GnomeTwoPasswordDialog *password_dialog);
char * gnome_two_password_dialog_get_domain (GnomeTwoPasswordDialog *password_dialog);
char * gnome_two_password_dialog_get_password (GnomeTwoPasswordDialog *password_dialog);
char * gnome_two_password_dialog_get_password_secondary (GnomeTwoPasswordDialog *password_dialog);
gboolean gnome_two_password_dialog_anon_selected (GnomeTwoPasswordDialog *password_dialog);
G_END_DECLS
#endif /* GNOME_TWO_PASSWORD_DIALOG_H */
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* (C) Copyright 2008 Red Hat, Inc. * (C) Copyright 2008 - 2011 Red Hat, Inc.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
...@@ -26,91 +26,121 @@ ...@@ -26,91 +26,121 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gnome-keyring.h>
#include <gnome-keyring-memory.h>
#include <nm-setting-vpn.h> #include <nm-setting-vpn.h>
#include <nm-vpn-plugin-utils.h>
#include "src/nm-l2tp-service.h" #include "src/nm-l2tp-service.h"
#include "common-gnome/keyring-helpers.h" #include "vpn-password-dialog.h"
#include "gnome-two-password-dialog.h"
#define KEYRING_UUID_TAG "connection-uuid" #define KEYRING_UUID_TAG "connection-uuid"
#define KEYRING_SN_TAG "setting-name" #define KEYRING_SN_TAG "setting-name"
#define KEYRING_SK_TAG "setting-key" #define KEYRING_SK_TAG "setting-key"
static char *
keyring_lookup_secret (const char *uuid, const char *secret_name)
{
GList *found_list = NULL;
GnomeKeyringResult ret;
GnomeKeyringFound *found;
char *secret = NULL;
ret = gnome_keyring_find_itemsv_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
&found_list,
KEYRING_UUID_TAG,
GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
uuid,
KEYRING_SN_TAG,
GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
NM_SETTING_VPN_SETTING_NAME,
KEYRING_SK_TAG,
GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
secret_name,
NULL);
if (ret == GNOME_KEYRING_RESULT_OK && found_list) {
found = g_list_nth_data (found_list, 0);
secret = gnome_keyring_memory_strdup (found->secret);
}
gnome_keyring_found_list_free (found_list);
return secret;
}
static gboolean static gboolean
get_secrets (const char *vpn_uuid, get_secrets (const char *vpn_uuid,
const char *vpn_name, const char *vpn_name,
const char *vpn_service,
gboolean retry, gboolean retry,
char **password) gboolean allow_interaction,
const char *in_pw,
char **out_pw,
NMSettingSecretFlags pw_flags)
{ {
GnomeTwoPasswordDialog *dialog; VpnPasswordDialog *dialog;
gboolean is_session = TRUE; char *prompt, *pw = NULL;
char *prompt; const char *new_password = NULL;
g_return_val_if_fail (vpn_uuid != NULL, FALSE); g_return_val_if_fail (vpn_uuid != NULL, FALSE);
g_return_val_if_fail (vpn_name != NULL, FALSE); g_return_val_if_fail (vpn_name != NULL, FALSE);
g_return_val_if_fail (password != NULL, FALSE); g_return_val_if_fail (out_pw != NULL, FALSE);
g_return_val_if_fail (*password == NULL, FALSE); g_return_val_if_fail (*out_pw == NULL, FALSE);
/* Get the existing secret, if any */
if ( !(pw_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)
&& !(pw_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) {
if (in_pw)
pw = gnome_keyring_memory_strdup (in_pw);
else
pw = keyring_lookup_secret (vpn_uuid, NM_L2TP_KEY_PASSWORD);
}
*password = keyring_helpers_lookup_secret (vpn_uuid, NM_L2TP_KEY_PASSWORD, &is_session); /* Don't ask if the passwords is unused */
if (!retry && *password) if (pw_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) {
gnome_keyring_memory_free (pw);
return TRUE; return TRUE;
}
prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network '%s'."), vpn_name); if (!retry) {
dialog = GNOME_TWO_PASSWORD_DIALOG (gnome_two_password_dialog_new (_("Authenticate VPN"), prompt, NULL, NULL, FALSE)); /* Don't ask the user if we don't need a new password (ie, !retry),
g_free (prompt); * we have an existing PW, and the password is saved.
*/
if (pw && !(pw_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) {
*out_pw = pw;
return TRUE;
}
}
gnome_two_password_dialog_set_show_username (dialog, FALSE); /* If interaction isn't allowed, just return existing secrets */
gnome_two_password_dialog_set_show_userpass_buttons (dialog, FALSE); if (allow_interaction == FALSE) {
gnome_two_password_dialog_set_show_domain (dialog, FALSE); *out_pw = pw;
gnome_two_password_dialog_set_show_remember (dialog, TRUE); return TRUE;
gnome_two_password_dialog_set_show_password_secondary (dialog, FALSE);
/* If nothing was found in the keyring, default to not remembering any secrets */
if (*password) {
/* Otherwise set default remember based on which keyring the secrets were found in */
if (is_session)
gnome_two_password_dialog_set_remember (dialog, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION);
else
gnome_two_password_dialog_set_remember (dialog, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER);
} else
gnome_two_password_dialog_set_remember (dialog, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING);
/* if retrying, pre-fill dialog with the password */
if (*password) {
gnome_two_password_dialog_set_password (dialog, *password);
g_free (*password);
*password = NULL;
} }
gtk_widget_show (GTK_WIDGET (dialog)); /* Otherwise, we have no saved password, or the password flags indicated
* that the password should never be saved.
*/
prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network '%s'."), vpn_name);
dialog = (VpnPasswordDialog *) vpn_password_dialog_new (_("Authenticate VPN"), prompt, NULL);
g_free (prompt);
if (gnome_two_password_dialog_run_and_block (dialog)) { vpn_password_dialog_set_show_password_secondary (dialog, FALSE);
const char *keyring = NULL;
gboolean save = FALSE;
*password = gnome_two_password_dialog_get_password (dialog); /* pre-fill dialog with the password */
if (pw && !(pw_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
vpn_password_dialog_set_password (dialog, pw);
switch (gnome_two_password_dialog_get_remember (dialog)) { gtk_widget_show (GTK_WIDGET (dialog));
case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION:
keyring = "session";
/* Fall through */
case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER:
save = TRUE;
break;
default:
break;
}
if (save) { if (vpn_password_dialog_run_and_block (dialog)) {
if (*password) {
keyring_helpers_save_secret (vpn_uuid, vpn_name, keyring, new_password = vpn_password_dialog_get_password (dialog);
NM_L2TP_KEY_PASSWORD, *password); if (new_password)
} *out_pw = gnome_keyring_memory_strdup (new_password);
}
} }
gtk_widget_hide (GTK_WIDGET (dialog)); gtk_widget_hide (GTK_WIDGET (dialog));
...@@ -119,22 +149,45 @@ get_secrets (const char *vpn_uuid, ...@@ -119,22 +149,45 @@ get_secrets (const char *vpn_uuid,
return TRUE; return TRUE;
} }
static void
wait_for_quit (void)
{
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);
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
gboolean retry = FALSE; gboolean retry = FALSE, allow_interaction = FALSE;
gchar *vpn_name = NULL; char *vpn_name = NULL, *vpn_uuid = NULL, *vpn_service = NULL, *password = NULL;
gchar *vpn_uuid = NULL; GHashTable *data = NULL, *secrets = NULL;
gchar *vpn_service = NULL; NMSettingSecretFlags pw_flags = NM_SETTING_SECRET_FLAG_NONE;
char *password = NULL;
char buf[1];
int ret;
GOptionContext *context; GOptionContext *context;
GOptionEntry entries[] = { GOptionEntry entries[] = {
{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL}, { "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
{ "uuid", 'u', 0, G_OPTION_ARG_STRING, &vpn_uuid, "UUID of VPN connection", NULL}, { "uuid", 'u', 0, G_OPTION_ARG_STRING, &vpn_uuid, "UUID of VPN connection", NULL},
{ "name", 'n', 0, G_OPTION_ARG_STRING, &vpn_name, "Name of VPN connection", NULL}, { "name", 'n', 0, G_OPTION_ARG_STRING, &vpn_name, "Name of VPN connection", NULL},
{ "service", 's', 0, G_OPTION_ARG_STRING, &vpn_service, "VPN service type", NULL}, { "service", 's', 0, G_OPTION_ARG_STRING, &vpn_service, "VPN service type", NULL},
{ "allow-interaction", 'i', 0, G_OPTION_ARG_NONE, &allow_interaction, "Allow user interaction", NULL},
{ NULL } { NULL }
}; };
...@@ -149,34 +202,47 @@ main (int argc, char *argv[]) ...@@ -149,34 +202,47 @@ main (int argc, char *argv[])
g_option_context_parse (context, &argc, &argv, NULL); g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free (context); g_option_context_free (context);
if (!vpn_uuid || !vpn_service || !vpn_name) {
if (vpn_uuid == NULL || vpn_name == NULL || vpn_service == NULL) { fprintf (stderr, "A connection UUID, name, and VPN plugin service name are required.\n");
fprintf (stderr, "Have to supply UUID, name, and service\n"); return 1;
return EXIT_FAILURE;
} }
if (strcmp (vpn_service, NM_DBUS_SERVICE_L2TP) != 0) { if (strcmp (vpn_service, NM_DBUS_SERVICE_L2TP) != 0) {
fprintf (stderr, "This dialog only works with the '%s' service\n", NM_DBUS_SERVICE_L2TP); fprintf (stderr, "This dialog only works with the '%s' service\n", NM_DBUS_SERVICE_L2TP);
return EXIT_FAILURE; return 1;
} }
if (!get_secrets (vpn_uuid, vpn_name, vpn_service, retry, &password)) if (!nm_vpn_plugin_utils_read_vpn_details (0, &data, &secrets)) {
return EXIT_FAILURE; fprintf (stderr, "Failed to read '%s' (%s) data and secrets from stdin.\n",
vpn_name, vpn_uuid);
return 1;
}
nm_vpn_plugin_utils_get_secret_flags (secrets, NM_L2TP_KEY_PASSWORD, &pw_flags);
if (!get_secrets (vpn_uuid, vpn_name, retry, allow_interaction,
g_hash_table_lookup (secrets, NM_L2TP_KEY_PASSWORD),
&password,
pw_flags))
return 1;
/* dump the passwords to stdout */ /* dump the passwords to stdout */
printf ("%s\n%s\n", NM_L2TP_KEY_PASSWORD, password); if (password)
printf ("%s\n%s\n", NM_L2TP_KEY_PASSWORD, password);
printf ("\n\n"); printf ("\n\n");
if (password) { if (password)
memset (password, 0, strlen (password));
gnome_keyring_memory_free (password); gnome_keyring_memory_free (password);
}
/* for good measure, flush stdout since Kansas is going Bye-Bye */ /* for good measure, flush stdout since Kansas is going Bye-Bye */
fflush (stdout); fflush (stdout);
/* wait for data on stdin */ /* Wait for quit signal */
ret = fread (buf, sizeof (char), sizeof (buf), stdin); wait_for_quit ();
return EXIT_SUCCESS; if (data)
g_hash_table_unref (data);
if (secrets)
g_hash_table_unref (secrets);
return 0;
} }
This diff is collapsed.
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* vpn-password-dialog.c - A use password prompting dialog widget.
*
* The Gnome Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the ree Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* The Gnome Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999, 2000 Eazel, Inc.
* Copyright (C) 2011 Red Hat, Inc.
*
* Authors: Ramiro Estrugo <ramiro@eazel.com>
* Dan Williams <dcbw@redhat.com>
*/
#ifndef VPN_PASSWORD_DIALOG_H
#define VPN_PASSWORD_DIALOG_H
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define VPN_TYPE_PASSWORD_DIALOG (vpn_password_dialog_get_type ())
#define VPN_PASSWORD_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VPN_TYPE_PASSWORD_DIALOG, VpnPasswordDialog))
#define VPN_PASSWORD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VPN_TYPE_PASSWORD_DIALOG, VpnPasswordDialogClass))
#define VPN_IS_PASSWORD_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VPN_TYPE_PASSWORD_DIALOG))
#define VPN_IS_PASSWORD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VPN_TYPE_PASSWORD_DIALOG))
typedef struct VpnPasswordDialog VpnPasswordDialog;
typedef struct VpnPasswordDialogClass VpnPasswordDialogClass;
struct VpnPasswordDialog {
GtkDialog parent;
};
struct VpnPasswordDialogClass {
GtkDialogClass parent_class;
};
GType vpn_password_dialog_get_type (void);
GtkWidget* vpn_password_dialog_new (const char *title,
const char *message,
const char *password);
gboolean vpn_password_dialog_run_and_block (VpnPasswordDialog *dialog);
/* Attribute mutators */
void vpn_password_dialog_set_show_password (VpnPasswordDialog *dialog,
gboolean show);
void vpn_password_dialog_focus_password (VpnPasswordDialog *dialog);
void vpn_password_dialog_set_password (VpnPasswordDialog *dialog,
const char *password);
void vpn_password_dialog_set_password_label (VpnPasswordDialog *dialog,
const char *label);
void vpn_password_dialog_set_show_password_secondary (VpnPasswordDialog *dialog,
gboolean show);
void vpn_password_dialog_focus_password_secondary (VpnPasswordDialog *dialog);
void vpn_password_dialog_set_password_secondary (VpnPasswordDialog *dialog,
const char *password_secondary);
void vpn_password_dialog_set_password_secondary_label (VpnPasswordDialog *dialog,
const char *label);
/* Attribute accessors */
const char *vpn_password_dialog_get_password (VpnPasswordDialog *dialog);
const char *vpn_password_dialog_get_password_secondary (VpnPasswordDialog *dialog);
G_END_DECLS
#endif /* VPN_PASSWORD_DIALOG_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment