diff options
Diffstat (limited to 'src/charon/plugins/nm/gnome/auth-dialog/main.c')
-rw-r--r-- | src/charon/plugins/nm/gnome/auth-dialog/main.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/src/charon/plugins/nm/gnome/auth-dialog/main.c b/src/charon/plugins/nm/gnome/auth-dialog/main.c new file mode 100644 index 000000000..6f2095527 --- /dev/null +++ b/src/charon/plugins/nm/gnome/auth-dialog/main.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2008 Martin Willi + * Hochschule fuer Technik Rapperswil + * Copyright (C) 2004 Dan Williams + * Red Hat, Inc. + * + * 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <glib/gi18n.h> +#include <gtk/gtk.h> +#include <gnome-keyring.h> +#include <libgnomeui/libgnomeui.h> +#include <gconf/gconf-client.h> +#include <nm-vpn-plugin.h> +#include <nm-setting-vpn.h> +#include <nm-setting-connection.h> + +#define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan" + +/** + * lookup a password in the keyring + */ +static char *lookup_password(char *name, char *service) +{ + GList *list; + GList *iter; + char *pass = NULL; + + if (gnome_keyring_find_network_password_sync(g_get_user_name(), NULL, name, + NULL, service, NULL, 0, &list) != GNOME_KEYRING_RESULT_OK) + { + return NULL; + } + + for (iter = list; iter; iter = iter->next) + { + GnomeKeyringNetworkPasswordData *data = iter->data; + + if (strcmp(data->object, "password") == 0 && data->password) + { + pass = g_strdup(data->password); + break; + } + } + gnome_keyring_network_password_list_free(list); + return pass; +} + +/** + * get the connection type + */ +static char* get_connection_type(char *uuid) +{ + GConfClient *client = NULL; + GSList *list; + GSList *iter; + char *key, *str, *path, *found = NULL, *method = NULL; + + client = gconf_client_get_default(); + + list = gconf_client_all_dirs(client, "/system/networking/connections", NULL); + g_return_val_if_fail(list, NULL); + + for (iter = list; iter; iter = iter->next) + { + path = (char *) iter->data; + + key = g_strdup_printf("%s/%s/%s", path, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_UUID); + str = gconf_client_get_string(client, key, NULL); + g_free (key); + + if (str && !strcmp(str, uuid)) + { + found = g_strdup(path); + } + g_free (str); + if (found) + { + break; + } + } + g_slist_foreach(list, (GFunc)g_free, NULL); + g_slist_free(list); + + if (found) + { + key = g_strdup_printf ("%s/%s/%s", found, + NM_SETTING_VPN_SETTING_NAME, "method"); + method = gconf_client_get_string(client, key, NULL); + g_free(found); + g_free(key); + } + g_object_unref(client); + return method; +} + +int main (int argc, char *argv[]) +{ + gboolean retry = FALSE; + gchar *name = NULL, *uuid = NULL, *service = NULL, *keyring = NULL, *pass; + GOptionContext *context; + GnomeProgram *program = NULL; + int exit_status = 1; + char buf, *agent, *type; + guint32 itemid; + GtkWidget *dialog; + GOptionEntry entries[] = { + { "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL}, + { "uuid", 'u', 0, G_OPTION_ARG_STRING, &uuid, "UUID of VPN connection", NULL}, + { "name", 'n', 0, G_OPTION_ARG_STRING, &name, "Name of VPN connection", NULL}, + { "service", 's', 0, G_OPTION_ARG_STRING, &service, "VPN service type", NULL}, + { NULL } + }; + + bindtextdomain(GETTEXT_PACKAGE, NULL); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + textdomain(GETTEXT_PACKAGE); + + context = g_option_context_new ("- strongswan auth dialog"); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + program = gnome_program_init ("nm-strongswan-auth-dialog", VERSION, + LIBGNOMEUI_MODULE, + argc, argv, + GNOME_PARAM_GOPTION_CONTEXT, context, + GNOME_PARAM_NONE); + + if (uuid == NULL || name == NULL || service == NULL) + { + fprintf (stderr, "Have to supply UUID, name, and service\n"); + g_object_unref (program); + return 1; + } + + if (strcmp(service, NM_DBUS_SERVICE_STRONGSWAN) != 0) + { + fprintf(stderr, "This dialog only works with the '%s' service\n", + NM_DBUS_SERVICE_STRONGSWAN); + g_object_unref (program); + return 1; + } + + type = get_connection_type(uuid); + if (!type) + { + fprintf(stderr, "Connection lookup failed\n"); + g_object_unref (program); + return 1; + } + if (!strcmp(type, "eap") || !strcmp(type, "key")) + { + pass = lookup_password(name, service); + if (!pass || retry) + { + if (!strcmp(type, "eap")) + { + dialog = gnome_password_dialog_new(_("VPN password required"), + _("EAP password required to establish VPN connection:"), + NULL, NULL, TRUE); + } + else + { + dialog = gnome_password_dialog_new(_("VPN password required"), + _("Private key decryption password required to establish VPN connection:"), + NULL, NULL, TRUE); + } + gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE); + gnome_password_dialog_set_show_username(GNOME_PASSWORD_DIALOG(dialog), FALSE); + if (pass) + { + gnome_password_dialog_set_password(GNOME_PASSWORD_DIALOG(dialog), pass); + } + if (!gnome_password_dialog_run_and_block(GNOME_PASSWORD_DIALOG(dialog))) + { + g_object_unref (program); + return 1; + } + + pass = gnome_password_dialog_get_password(GNOME_PASSWORD_DIALOG(dialog)); + switch (gnome_password_dialog_get_remember(GNOME_PASSWORD_DIALOG(dialog))) + { + case GNOME_PASSWORD_DIALOG_REMEMBER_NOTHING: + break; + case GNOME_PASSWORD_DIALOG_REMEMBER_SESSION: + keyring = "session"; + /* FALL */ + case GNOME_PASSWORD_DIALOG_REMEMBER_FOREVER: + if (gnome_keyring_set_network_password_sync(keyring, + g_get_user_name(), NULL, name, "password", service, NULL, 0, + pass, &itemid) != GNOME_KEYRING_RESULT_OK) + { + g_warning ("storing password in keyring failed"); + } + break; + } + } + printf("password\n%s\n", pass); + } + else + { + agent = getenv("SSH_AUTH_SOCK"); + if (agent) + { + printf("agent\n%s\n", agent); + } + else + { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Configuration uses ssh-agent for authentication, " + "but ssh-agent is not running!")); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + return 1; + } + } + printf("\n\n"); + /* flush output, wait for input */ + fflush(stdout); + fread(&buf, 1, sizeof(buf), stdin); + g_object_unref(program); + return 0; +} + |