certificate based gateway authentication
prototype PSK user authentication with auth-dialog
This commit is contained in:
@@ -5,7 +5,7 @@ AM_CFLAGS = -rdynamic
|
|||||||
|
|
||||||
plugin_LTLIBRARIES = libstrongswan-nm.la
|
plugin_LTLIBRARIES = libstrongswan-nm.la
|
||||||
libstrongswan_nm_la_SOURCES = \
|
libstrongswan_nm_la_SOURCES = \
|
||||||
nm_plugin.h nm_plugin.c nm_service.h nm_service.c
|
nm_plugin.h nm_plugin.c nm_service.h nm_service.c nm_creds.h nm_creds.c
|
||||||
libstrongswan_nm_la_LDFLAGS = -module
|
libstrongswan_nm_la_LDFLAGS = -module
|
||||||
libstrongswan_nm_la_LIBADD = ${nm_LIBS}
|
libstrongswan_nm_la_LIBADD = ${nm_LIBS}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
AUTOMAKE_OPTIONS = foreign
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
|
||||||
SUBDIRS = properties po
|
SUBDIRS = properties auth-dialog po
|
||||||
|
|
||||||
dbusservicedir = $(sysconfdir)/dbus-1/system.d
|
dbusservicedir = $(sysconfdir)/dbus-1/system.d
|
||||||
dbusservice_DATA = nm-strongswan-service.conf
|
dbusservice_DATA = nm-strongswan-service.conf
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
libexec_PROGRAMS = nm-strongswan-auth-dialog
|
||||||
|
|
||||||
|
nm_strongswan_auth_dialog_CPPFLAGS = \
|
||||||
|
$(GTHREAD_CFLAGS) \
|
||||||
|
$(GTK_CFLAGS) \
|
||||||
|
$(LIBGNOMEUI_CFLAGS) \
|
||||||
|
$(GNOMEKEYRING_CFLAGS) \
|
||||||
|
$(NETWORK_MANAGER_CFLAGS) \
|
||||||
|
-DICONDIR=\""$(datadir)/pixmaps"\" \
|
||||||
|
-DGLADEDIR=\""$(gladedir)"\" \
|
||||||
|
-DBINDIR=\""$(bindir)"\" \
|
||||||
|
-DDBUS_API_SUBJECT_TO_CHANGE \
|
||||||
|
-DG_DISABLE_DEPRECATED \
|
||||||
|
-DGDK_DISABLE_DEPRECATED \
|
||||||
|
-DGNOME_DISABLE_DEPRECATED \
|
||||||
|
-DGNOMELOCALEDIR=\"$(datadir)/locale\" \
|
||||||
|
-DVERSION=\"$(VERSION)\"
|
||||||
|
|
||||||
|
nm_strongswan_auth_dialog_SOURCES = \
|
||||||
|
main.c
|
||||||
|
|
||||||
|
nm_strongswan_auth_dialog_LDADD = \
|
||||||
|
$(GTK_LIBS) \
|
||||||
|
$(LIBGNOMEUI_LIBS) \
|
||||||
|
$(GNOMEKEYRING_LIBS)
|
||||||
|
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Martin Willi
|
||||||
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
#define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan"
|
||||||
|
|
||||||
|
static char *lookup(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
static gboolean retry = FALSE;
|
||||||
|
static gchar *name = NULL, *id = NULL, *service = NULL, *keyring = NULL, *pass;
|
||||||
|
GOptionContext *context;
|
||||||
|
GnomeProgram *program = NULL;
|
||||||
|
int exit_status = 1;
|
||||||
|
guint32 itemid;
|
||||||
|
GtkWidget *dialog;
|
||||||
|
GOptionEntry entries[] = {
|
||||||
|
{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
|
||||||
|
{ "id", 'i', 0, G_OPTION_ARG_STRING, &id, "ID 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 (id == NULL || name == NULL || service == NULL)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Have to supply ID, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
pass = lookup(name, service);
|
||||||
|
if (!pass || retry)
|
||||||
|
{
|
||||||
|
dialog = gnome_password_dialog_new(_("VPN password required"),
|
||||||
|
_("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\n\n", pass);
|
||||||
|
g_object_unref(program);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -116,5 +116,6 @@ fi
|
|||||||
AC_OUTPUT([
|
AC_OUTPUT([
|
||||||
Makefile
|
Makefile
|
||||||
properties/Makefile
|
properties/Makefile
|
||||||
|
auth-dialog/Makefile
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -78,21 +78,14 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="certificate-button">
|
<widget class="GtkFileChooserButton" id="certificate-button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<property name="has_tooltip">True</property>
|
|
||||||
<property name="tooltip_text">A trusted certificate to use to authenticate the Gateway.</property>
|
|
||||||
<property name="label" translatable="yes">(none)</property>
|
|
||||||
<property name="response_id">0</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
<property name="right_attach">2</property>
|
<property name="right_attach">2</property>
|
||||||
<property name="top_attach">1</property>
|
<property name="top_attach">1</property>
|
||||||
<property name="bottom_attach">2</property>
|
<property name="bottom_attach">2</property>
|
||||||
<property name="y_options"></property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -165,7 +158,6 @@
|
|||||||
<child>
|
<child>
|
||||||
<widget class="GtkComboBox" id="method-combo">
|
<widget class="GtkComboBox" id="method-combo">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="has_tooltip">True</property>
|
<property name="has_tooltip">True</property>
|
||||||
<property name="tooltip_text">Authentication Method to use for authentication against the Gateway. </property>
|
<property name="tooltip_text">Authentication Method to use for authentication against the Gateway. </property>
|
||||||
<property name="items"></property>
|
<property name="items"></property>
|
||||||
|
|||||||
@@ -159,6 +159,14 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
|
|||||||
gtk_entry_set_text (GTK_ENTRY (widget), value);
|
gtk_entry_set_text (GTK_ENTRY (widget), value);
|
||||||
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
|
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
|
||||||
|
|
||||||
|
widget = glade_xml_get_widget (priv->xml, "certificate-button");
|
||||||
|
if (!widget)
|
||||||
|
return FALSE;
|
||||||
|
value = g_hash_table_lookup (settings->data, "certificate");
|
||||||
|
if (value)
|
||||||
|
gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
|
||||||
|
g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (stuff_changed_cb), self);
|
||||||
|
|
||||||
widget = glade_xml_get_widget (priv->xml, "user-entry");
|
widget = glade_xml_get_widget (priv->xml, "user-entry");
|
||||||
if (!widget)
|
if (!widget)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -166,6 +174,22 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError
|
|||||||
if (value)
|
if (value)
|
||||||
gtk_entry_set_text (GTK_ENTRY (widget), value);
|
gtk_entry_set_text (GTK_ENTRY (widget), value);
|
||||||
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
|
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
|
||||||
|
|
||||||
|
widget = glade_xml_get_widget (priv->xml, "method-combo");
|
||||||
|
if (!widget)
|
||||||
|
return FALSE;
|
||||||
|
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "EAP");
|
||||||
|
value = g_hash_table_lookup (settings->data, "method");
|
||||||
|
if (value) {
|
||||||
|
if (g_strcasecmp (value, "EAP") == 0) {
|
||||||
|
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
|
||||||
|
if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
|
||||||
|
{ /* default to EAP */
|
||||||
|
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
|
||||||
|
}
|
||||||
|
|
||||||
widget = glade_xml_get_widget (priv->xml, "virtual-check");
|
widget = glade_xml_get_widget (priv->xml, "virtual-check");
|
||||||
if (!widget)
|
if (!widget)
|
||||||
@@ -235,12 +259,24 @@ update_connection (NMVpnPluginUiWidgetInterface *iface,
|
|||||||
g_hash_table_insert (settings->data, g_strdup ("address"), g_strdup(str));
|
g_hash_table_insert (settings->data, g_strdup ("address"), g_strdup(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
widget = glade_xml_get_widget (priv->xml, "certificate-button");
|
||||||
|
str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
|
||||||
|
if (str) {
|
||||||
|
g_hash_table_insert (settings->data, g_strdup ("certificate"), g_strdup(str));
|
||||||
|
}
|
||||||
|
|
||||||
widget = glade_xml_get_widget (priv->xml, "user-entry");
|
widget = glade_xml_get_widget (priv->xml, "user-entry");
|
||||||
str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
|
str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
|
||||||
if (str && strlen (str)) {
|
if (str && strlen (str)) {
|
||||||
g_hash_table_insert (settings->data, g_strdup ("user"), g_strdup(str));
|
g_hash_table_insert (settings->data, g_strdup ("user"), g_strdup(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
widget = glade_xml_get_widget (priv->xml, "method-combo");
|
||||||
|
str = (char *) gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget));
|
||||||
|
if (str) {
|
||||||
|
g_hash_table_insert (settings->data, g_strdup ("method"), g_strdup(str));
|
||||||
|
}
|
||||||
|
|
||||||
widget = glade_xml_get_widget (priv->xml, "virtual-check");
|
widget = glade_xml_get_widget (priv->xml, "virtual-check");
|
||||||
active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
|
active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
|
||||||
g_hash_table_insert (settings->data, g_strdup ("virtual"),
|
g_hash_table_insert (settings->data, g_strdup ("virtual"),
|
||||||
|
|||||||
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Martin Willi
|
||||||
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
|
* 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$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "nm_creds.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
|
||||||
|
typedef struct private_nm_creds_t private_nm_creds_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private data of nm_creds
|
||||||
|
*/
|
||||||
|
struct private_nm_creds_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public functions
|
||||||
|
*/
|
||||||
|
nm_creds_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gateway certificate
|
||||||
|
*/
|
||||||
|
certificate_t *cert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User password
|
||||||
|
*/
|
||||||
|
char *pass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read/write lock
|
||||||
|
*/
|
||||||
|
pthread_rwlock_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements credential_set_t.create_cert_enumerator
|
||||||
|
*/
|
||||||
|
static enumerator_t* create_cert_enumerator(private_nm_creds_t *this,
|
||||||
|
certificate_type_t cert, key_type_t key,
|
||||||
|
identification_t *id, bool trusted)
|
||||||
|
{
|
||||||
|
if (!this->cert ||
|
||||||
|
(cert != CERT_ANY && cert != this->cert->get_type(this->cert)))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return enumerator_create_cleaner(enumerator_create_single(this->cert, NULL),
|
||||||
|
(void*)pthread_rwlock_unlock, &this->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements credential_set_t.create_cert_enumerator
|
||||||
|
*/
|
||||||
|
static enumerator_t* create_shared_enumerator(private_nm_creds_t *this,
|
||||||
|
shared_key_type_t type, identification_t *me,
|
||||||
|
identification_t *other)
|
||||||
|
{
|
||||||
|
shared_key_t *key;
|
||||||
|
|
||||||
|
if (!this->pass || (type != SHARED_EAP && type != SHARED_IKE))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
key = shared_key_create(type, chunk_clone(
|
||||||
|
chunk_create(this->pass, strlen(this->pass))));
|
||||||
|
return enumerator_create_cleaner(
|
||||||
|
enumerator_create_single(key, (void*)key->destroy),
|
||||||
|
(void*)pthread_rwlock_unlock, &this->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of nm_creds_t.set_certificate
|
||||||
|
*/
|
||||||
|
static void set_certificate(private_nm_creds_t *this, certificate_t *cert)
|
||||||
|
{
|
||||||
|
pthread_rwlock_wrlock(&this->lock);
|
||||||
|
DESTROY_IF(this->cert);
|
||||||
|
this->cert = cert;
|
||||||
|
pthread_rwlock_unlock(&this->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of nm_creds_t.set_password
|
||||||
|
*/
|
||||||
|
static void set_password(private_nm_creds_t *this, char *password)
|
||||||
|
{
|
||||||
|
pthread_rwlock_wrlock(&this->lock);
|
||||||
|
free(this->pass);
|
||||||
|
this->pass = strdup(password);
|
||||||
|
pthread_rwlock_unlock(&this->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of nm_creds_t.destroy
|
||||||
|
*/
|
||||||
|
static void destroy(private_nm_creds_t *this)
|
||||||
|
{
|
||||||
|
DESTROY_IF(this->cert);
|
||||||
|
free(this->pass);
|
||||||
|
pthread_rwlock_destroy(&this->lock);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* see header file
|
||||||
|
*/
|
||||||
|
nm_creds_t *nm_creds_create()
|
||||||
|
{
|
||||||
|
private_nm_creds_t *this = malloc_thing(private_nm_creds_t);
|
||||||
|
|
||||||
|
this->public.set.create_private_enumerator = (void*)return_null;
|
||||||
|
this->public.set.create_cert_enumerator = (void*)create_cert_enumerator;
|
||||||
|
this->public.set.create_shared_enumerator = (void*)create_shared_enumerator;
|
||||||
|
this->public.set.create_cdp_enumerator = (void*)return_null;
|
||||||
|
this->public.set.cache_cert = (void*)nop;
|
||||||
|
this->public.set_certificate = (void(*)(nm_creds_t*, certificate_t *cert))set_certificate;
|
||||||
|
this->public.set_password = (void(*)(nm_creds_t*, char *password))set_password;
|
||||||
|
this->public.destroy = (void(*)(nm_creds_t*))destroy;
|
||||||
|
|
||||||
|
pthread_rwlock_init(&this->lock, NULL);
|
||||||
|
|
||||||
|
this->cert = NULL;
|
||||||
|
this->pass = NULL;
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Martin Willi
|
||||||
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
|
* 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$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup nm_creds nm_creds
|
||||||
|
* @{ @ingroup nm
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NM_CREDS_H_
|
||||||
|
#define NM_CREDS_H_
|
||||||
|
|
||||||
|
#include <credentials/credential_set.h>
|
||||||
|
|
||||||
|
typedef struct nm_creds_t nm_creds_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NetworkManager credentials helper.
|
||||||
|
*/
|
||||||
|
struct nm_creds_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements credential_set_t
|
||||||
|
*/
|
||||||
|
credential_set_t set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the trusted gateway certificate to serve by this set.
|
||||||
|
*
|
||||||
|
* @param cert certificate to serve
|
||||||
|
*/
|
||||||
|
void (*set_certificate)(nm_creds_t *this, certificate_t *cert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the users password for authentication.
|
||||||
|
*
|
||||||
|
* @param password password to use for authentication
|
||||||
|
*/
|
||||||
|
void (*set_password)(nm_creds_t *this, char *password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a nm_creds instance.
|
||||||
|
*/
|
||||||
|
void (*destroy)(nm_creds_t *this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a nm_creds instance.
|
||||||
|
*/
|
||||||
|
nm_creds_t *nm_creds_create();
|
||||||
|
|
||||||
|
#endif /* NM_CREDS_H_ @}*/
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "nm_plugin.h"
|
#include "nm_plugin.h"
|
||||||
#include "nm_service.h"
|
#include "nm_service.h"
|
||||||
|
#include "nm_creds.h"
|
||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
#include <processing/jobs/callback_job.h>
|
#include <processing/jobs/callback_job.h>
|
||||||
@@ -33,7 +34,15 @@ struct private_nm_plugin_t {
|
|||||||
*/
|
*/
|
||||||
nm_plugin_t public;
|
nm_plugin_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Glib main loop for a thread, handles DBUS calls
|
||||||
|
*/
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* credential set registered at the daemon
|
||||||
|
*/
|
||||||
|
nm_creds_t *creds;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +53,7 @@ static job_requeue_t run(private_nm_plugin_t *this)
|
|||||||
NMStrongswanPlugin *plugin;
|
NMStrongswanPlugin *plugin;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
|
|
||||||
plugin = nm_strongswan_plugin_new();
|
plugin = nm_strongswan_plugin_new(this->creds);
|
||||||
|
|
||||||
this->loop = loop = g_main_loop_new(NULL, FALSE);
|
this->loop = loop = g_main_loop_new(NULL, FALSE);
|
||||||
g_main_loop_run(loop);
|
g_main_loop_run(loop);
|
||||||
@@ -64,6 +73,8 @@ static void destroy(private_nm_plugin_t *this)
|
|||||||
{
|
{
|
||||||
g_main_loop_quit(this->loop);
|
g_main_loop_quit(this->loop);
|
||||||
}
|
}
|
||||||
|
charon->credentials->remove_set(charon->credentials, &this->creds->set);
|
||||||
|
this->creds->destroy(this->creds);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +94,9 @@ plugin_t *plugin_create()
|
|||||||
g_thread_init(NULL);
|
g_thread_init(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->creds = nm_creds_create();
|
||||||
|
charon->credentials->add_set(charon->credentials, &this->creds->set);
|
||||||
|
|
||||||
charon->processor->queue_job(charon->processor,
|
charon->processor->queue_job(charon->processor,
|
||||||
(job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL));
|
(job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL));
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ typedef struct {
|
|||||||
bus_listener_t listener;
|
bus_listener_t listener;
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
NMVPNPlugin *plugin;
|
NMVPNPlugin *plugin;
|
||||||
|
nm_creds_t *creds;
|
||||||
} NMStrongswanPluginPrivate;
|
} NMStrongswanPluginPrivate;
|
||||||
|
|
||||||
#define NM_STRONGSWAN_PLUGIN_GET_PRIVATE(o) \
|
#define NM_STRONGSWAN_PLUGIN_GET_PRIVATE(o) \
|
||||||
@@ -161,6 +162,7 @@ bool listen_bus(bus_listener_t *listener, signal_t signal, level_t level,
|
|||||||
static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
|
nm_creds_t *creds;
|
||||||
NMSettingVPN *settings;
|
NMSettingVPN *settings;
|
||||||
identification_t *user = NULL;
|
identification_t *user = NULL;
|
||||||
char *address, *str;
|
char *address, *str;
|
||||||
@@ -177,7 +179,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
settings = NM_SETTING_VPN(nm_connection_get_setting(connection,
|
settings = NM_SETTING_VPN(nm_connection_get_setting(connection,
|
||||||
NM_TYPE_SETTING_VPN));
|
NM_TYPE_SETTING_VPN));
|
||||||
|
|
||||||
DBG2(DBG_CFG, "received NetworkManager connection: %s",
|
DBG1(DBG_CFG, "received NetworkManager connection: %s",
|
||||||
nm_setting_to_string(NM_SETTING(settings)));
|
nm_setting_to_string(NM_SETTING(settings)));
|
||||||
str = g_hash_table_lookup(settings->data, "user");
|
str = g_hash_table_lookup(settings->data, "user");
|
||||||
if (!str)
|
if (!str)
|
||||||
@@ -206,6 +208,26 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
str = g_hash_table_lookup(settings->data, "ipcomp");
|
str = g_hash_table_lookup(settings->data, "ipcomp");
|
||||||
ipcomp = str && streq(str, "yes");
|
ipcomp = str && streq(str, "yes");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register credentials
|
||||||
|
*/
|
||||||
|
creds = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->creds;
|
||||||
|
|
||||||
|
str = g_hash_table_lookup(settings->data, "certificate");
|
||||||
|
if (str)
|
||||||
|
{
|
||||||
|
certificate_t *cert;
|
||||||
|
|
||||||
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||||
|
BUILD_FROM_FILE, str, BUILD_END);
|
||||||
|
creds->set_certificate(creds, cert);
|
||||||
|
}
|
||||||
|
str = g_hash_table_lookup(settings->data, "password");
|
||||||
|
if (str)
|
||||||
|
{
|
||||||
|
creds->set_password(creds, str);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up configurations
|
* Set up configurations
|
||||||
*/
|
*/
|
||||||
@@ -213,7 +235,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||||
peer_cfg = peer_cfg_create(CONFIG_NAME, 2, ike_cfg, user,
|
peer_cfg = peer_cfg_create(CONFIG_NAME, 2, ike_cfg, user,
|
||||||
identification_create_from_encoding(ID_ANY, chunk_empty),
|
identification_create_from_encoding(ID_ANY, chunk_empty),
|
||||||
CERT_SEND_IF_ASKED, UNIQUE_REPLACE, CONF_AUTH_PUBKEY,
|
CERT_SEND_IF_ASKED, UNIQUE_REPLACE, CONF_AUTH_PSK,
|
||||||
0, 0, 1, /* EAP method, vendor, keyingtries */
|
0, 0, 1, /* EAP method, vendor, keyingtries */
|
||||||
18000, 0, /* rekey 5h, reauth none */
|
18000, 0, /* rekey 5h, reauth none */
|
||||||
600, 600, /* jitter, over 10min */
|
600, 600, /* jitter, over 10min */
|
||||||
@@ -272,6 +294,15 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
|
static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
|
||||||
char **setting_name, GError **error)
|
char **setting_name, GError **error)
|
||||||
{
|
{
|
||||||
|
NMSettingVPN *settings;
|
||||||
|
|
||||||
|
settings = NM_SETTING_VPN(nm_connection_get_setting(connection,
|
||||||
|
NM_TYPE_SETTING_VPN));
|
||||||
|
if (!g_hash_table_lookup(settings->data, "password"))
|
||||||
|
{
|
||||||
|
*setting_name = NM_SETTING_VPN_SETTING_NAME;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,10 +358,15 @@ static void nm_strongswan_plugin_class_init(
|
|||||||
/**
|
/**
|
||||||
* Object constructor
|
* Object constructor
|
||||||
*/
|
*/
|
||||||
NMStrongswanPlugin *nm_strongswan_plugin_new(void)
|
NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds)
|
||||||
{
|
{
|
||||||
return (NMStrongswanPlugin *)g_object_new (
|
NMStrongswanPlugin *plugin = (NMStrongswanPlugin *)g_object_new (
|
||||||
NM_TYPE_STRONGSWAN_PLUGIN, NM_VPN_PLUGIN_DBUS_SERVICE_NAME,
|
NM_TYPE_STRONGSWAN_PLUGIN,
|
||||||
NM_DBUS_SERVICE_STRONGSWAN, NULL);
|
NM_VPN_PLUGIN_DBUS_SERVICE_NAME, NM_DBUS_SERVICE_STRONGSWAN,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->creds = creds;
|
||||||
|
|
||||||
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <nm-vpn-plugin.h>
|
#include <nm-vpn-plugin.h>
|
||||||
|
|
||||||
|
#include "nm_creds.h"
|
||||||
|
|
||||||
#define NM_TYPE_STRONGSWAN_PLUGIN (nm_strongswan_plugin_get_type ())
|
#define NM_TYPE_STRONGSWAN_PLUGIN (nm_strongswan_plugin_get_type ())
|
||||||
#define NM_STRONGSWAN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPlugin))
|
#define NM_STRONGSWAN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPlugin))
|
||||||
#define NM_STRONGSWAN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPluginClass))
|
#define NM_STRONGSWAN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPluginClass))
|
||||||
@@ -48,6 +50,6 @@ typedef struct {
|
|||||||
|
|
||||||
GType nm_strongswan_plugin_get_type(void);
|
GType nm_strongswan_plugin_get_type(void);
|
||||||
|
|
||||||
NMStrongswanPlugin *nm_strongswan_plugin_new(void);
|
NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds);
|
||||||
|
|
||||||
#endif /* NM_SERVICE_H_ */
|
#endif /* NM_SERVICE_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user