Commit f655c2fc authored by Geo Carncross's avatar Geo Carncross

Add some rudamentary ipsec support

parent a1234ad8
......@@ -4,6 +4,8 @@ plugin_LTLIBRARIES = libnm-l2tp-properties.la
libnm_l2tp_properties_la_SOURCES = \
nm-l2tp.c \
nm-l2tp.h \
ipsec-dialog.c \
ipsec-dialog.h \
advanced-dialog.c \
advanced-dialog.h \
import-export.c \
......
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/***************************************************************************
*
* Copyright (C) 2011 Geo Carncross, <geocar@gmail.com>
*
* 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.
*
* 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.
*
* 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.
*
**************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <nm-connection.h>
#include <nm-setting-vpn.h>
#include "ipsec-dialog.h"
#include "nm-l2tp.h"
#include "../src/nm-l2tp-service.h"
static const char *ipsec_keys[] = {
NM_L2TP_KEY_IPSEC_ENABLE,
NM_L2TP_KEY_IPSEC_GROUP_NAME,
NM_L2TP_KEY_IPSEC_GATEWAY_ID,
NM_L2TP_KEY_IPSEC_PSK,
NULL
};
static void
copy_values (const char *key, const char *value, gpointer user_data)
{
GHashTable *hash = (GHashTable *) user_data;
const char **i;
for (i = &ipsec_keys[0]; *i; i++) {
if (strcmp (key, *i))
continue;
g_hash_table_insert (hash, g_strdup (key), g_strdup (value));
}
}
GHashTable *
ipsec_dialog_new_hash_from_connection (NMConnection *connection,
GError **error)
{
GHashTable *hash;
NMSettingVPN *s_vpn;
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
nm_setting_vpn_foreach_data_item (s_vpn, copy_values, hash);
return hash;
}
static void
handle_enable_changed (GtkWidget *check, gboolean is_init, GtkBuilder *builder)
{
GtkWidget *widget;
gboolean enabledp;
GtkTreeModel *model;
GtkTreeIter iter;
gboolean valid;
enabledp = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check));
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_psk"));
gtk_widget_set_sensitive (widget, enabledp);
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_gateway_id"));
gtk_widget_set_sensitive (widget, enabledp);
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_group_name"));
gtk_widget_set_sensitive (widget, enabledp);
}
static void
enable_toggled_cb (GtkWidget *check, gpointer user_data)
{
handle_enable_changed (check, FALSE, (GtkBuilder *) user_data);
}
GtkWidget *
ipsec_dialog_new (GHashTable *hash)
{
GtkBuilder *builder;
GtkWidget *dialog = NULL;
char *ui_file = NULL;
GtkWidget *widget;
const char *value;
GError *error = NULL;
g_return_val_if_fail (hash != NULL, NULL);
ui_file = g_strdup_printf ("%s/%s", UIDIR, "nm-l2tp-dialog.ui");
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file(builder, ui_file, &error)) {
g_warning("Couldn't load builder file: %s", error ? error->message
: "(unknown)");
g_clear_error(&error);
g_object_unref(G_OBJECT(builder));
goto out;
}
gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE);
dialog = GTK_WIDGET (gtk_builder_get_object (builder, "l2tp-ipsec-dialog"));
if (!dialog) {
g_object_unref (G_OBJECT (builder));
goto out;
}
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
g_object_set_data_full (G_OBJECT (dialog), "gtkbuilder-xml",
builder, (GDestroyNotify) g_object_unref);
value = g_hash_table_lookup (hash, NM_L2TP_KEY_IPSEC_ENABLE);
if (value && !strcmp (value, "yes")) {
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_enable"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
}
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_group_name"));
value = g_hash_table_lookup (hash, NM_L2TP_KEY_IPSEC_GROUP_NAME);
if (!value) value="GroupVPN";
gtk_entry_set_text(GTK_ENTRY(widget), value);
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_gateway_id"));
if((value = g_hash_table_lookup (hash, NM_L2TP_KEY_IPSEC_GATEWAY_ID)))
gtk_entry_set_text(GTK_ENTRY(widget), value);
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_psk"));
if((value = g_hash_table_lookup (hash, NM_L2TP_KEY_IPSEC_PSK)))
gtk_entry_set_text(GTK_ENTRY(widget), value);
widget = GTK_WIDGET (gtk_builder_get_object (builder,"ipsec_enable"));
handle_enable_changed (widget, TRUE, builder);
g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (enable_toggled_cb), builder);
out:
g_free (ui_file);
return dialog;
}
GHashTable *
ipsec_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error)
{
GHashTable *hash;
GtkWidget *widget;
GtkBuilder *builder;
GtkTreeModel *model;
GtkTreeIter iter;
gboolean valid;
g_return_val_if_fail (dialog != NULL, NULL);
if (error)
g_return_val_if_fail (*error == NULL, NULL);
builder = g_object_get_data (G_OBJECT (dialog), "gtkbuilder-xml");
g_return_val_if_fail (builder != NULL, NULL);
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_enable"));
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
g_hash_table_insert(hash, g_strdup(NM_L2TP_KEY_IPSEC_ENABLE), g_strdup("yes"));
} else {
g_hash_table_insert(hash, g_strdup(NM_L2TP_KEY_IPSEC_ENABLE), g_strdup("no"));
}
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_gateway_id"));
g_hash_table_insert(hash, g_strdup(NM_L2TP_KEY_IPSEC_GATEWAY_ID),
g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))));
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_group_name"));
g_hash_table_insert(hash, g_strdup(NM_L2TP_KEY_IPSEC_GROUP_NAME),
g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))));
widget = GTK_WIDGET (gtk_builder_get_object (builder, "ipsec_psk"));
g_hash_table_insert(hash, g_strdup(NM_L2TP_KEY_IPSEC_PSK),
g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))));
return hash;
}
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/***************************************************************************
*
* Copyright (C) 2011 Geo Carncross, <geocar@gmail.com>
*
* 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.
*
* 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.
*
* 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.
*
**************************************************************************/
#ifndef _IPSEC_DIALOG_H_
#define _IPSEC_DIALOG_H_
#include <glib.h>
#include <gtk/gtk.h>
#include <nm-connection.h>
GtkWidget *ipsec_dialog_new (GHashTable *hash);
GHashTable *ipsec_dialog_new_hash_from_connection (NMConnection *connection, GError **error);
GHashTable *ipsec_dialog_new_hash_from_dialog (GtkWidget *dialog, GError **error);
#endif
<?xml version="1.0"?>
<!--Generated with glade3 3.4.4 on Sun Oct 12 10:59:11 2008 -->
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkListStore" id="model1">
<columns>
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Default</col>
</row>
</data>
</object>
<object class="GtkWindow" id="l2tp-widget">
<property name="title" translatable="yes">window1</property>
<child>
<object class="GtkVBox" id="l2tp-vbox">
<property name="visible">True</property>
<property name="border_width">12</property>
<property name="spacing">16</property>
<child>
<object class="GtkVBox" id="vbox8">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label22">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;General&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment8">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkTable" id="table2">
<property name="visible">True</property>
<property name="n_columns">2</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkEntry" id="gateway_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Gateway:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">gateway_entry</property>
</object>
<packing>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox11">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label25">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Optional&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment9">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkTable" id="table3">
<property name="visible">True</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkEntry" id="domain_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label27">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">NT Domain:</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show_passwords_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Show password</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="user_password_entry">
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkDialog" id="l2tp-advanced-dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">L2TP PPP Options</property>
<property name="window_position">center-on-parent</property>
<property name="destroy_with_parent">True</property>
<property name="icon_name">stock-preferences</property>
<property name="type_hint">dialog</property>
<property name="skip_pager_hint">True</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area3">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Password:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkEntry" id="user_entry">
<object class="GtkButton" id="cancel_button1">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label26">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">User name:</property>
</object>
<packing>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="xscale">0</property>
<child>
<object class="GtkButton" id="advanced_button">
<object class="GtkButton" id="ok_button1">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-preferences</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Ad_vanced...</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
......@@ -251,45 +52,28 @@
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="position">2</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkDialog" id="l2tp-advanced-dialog">
<property name="border_width">5</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="title" translatable="yes">L2TP Advanced Options</property>
<property name="destroy_with_parent">True</property>
<property name="icon_name">stock-preferences</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="skip_pager_hint">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox3">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<object class="GtkVBox" id="PppPage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="spacing">18</property>
<child>
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label28">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Authentication&lt;/b&gt;</property>
<property name="use_markup">True</property>
......@@ -297,30 +81,39 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="auth_methods_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Allow the following authentication methods:</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="hscrollbar_policy">never</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="ppp_auth_methods">
<property name="visible">True</property>
......@@ -330,6 +123,8 @@
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
......@@ -338,21 +133,26 @@
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label29">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Security and Compression&lt;/b&gt;</property>
<property name="use_markup">True</property>
......@@ -360,49 +160,60 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkVBox" id="vbox7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkCheckButton" id="ppp_use_mppe">
<property name="label" translatable="yes">Use _Point-to-Point encryption (MPPE)</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use _Point-to-Point encryption (MPPE)</property>
<property name="tooltip-text" translatable="yes">Note: MPPE encryption is only available with MSCHAP authentication methods. To enable this checkbox, select one or more of the MSCHAP authentication methods: MSCHAP or MSCHAPv2.</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Note: MPPE encryption is only available with MSCHAP authentication methods. To enable this checkbox, select one or more of the MSCHAP authentication methods: MSCHAP or MSCHAPv2.</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkHBox" id="hbox1">
<object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="ppp_mppe_security_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Security:</property>
<property name="use_underline">True</property>
......@@ -410,11 +221,14 @@
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="ppp_mppe_security_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model1</property>
<child>
<object class="GtkCellRendererText" id="renderer1"/>
......@@ -425,16 +239,24 @@
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="ppp_allow_stateful_mppe">
<property name="label" translatable="yes">Allow st_ateful encryption</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Allow st_ateful encryption</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
......@@ -448,6 +270,8 @@
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
......@@ -455,13 +279,16 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="ppp_allow_bsdcomp">
<property name="label" translatable="yes">Allow _BSD data compression</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Allow _BSD data compression</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
......@@ -473,9 +300,11 @@
</child>
<child>
<object class="GtkCheckButton" id="ppp_allow_deflate">
<property name="label" translatable="yes">Allow _Deflate data compression</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Allow _Deflate data compression</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
......@@ -487,9 +316,11 @@
</child>
<child>
<object class="GtkCheckButton" id="ppp_usevj">
<property name="label" translatable="yes">Use TCP _header compression</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use TCP _header compression</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
......@@ -501,9 +332,11 @@
</child>
<child>
<object class="GtkCheckButton" id="ppp_usepcomp">
<property name="label" translatable="yes">Use protocol _field compression negotiation</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use protocol _field compression negotiation</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
......@@ -515,9 +348,11 @@
</child>
<child>
<object class="GtkCheckButton" id="ppp_useaccomp">
<property name="label" translatable="yes">Use _Address/Control compression</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use _Address/Control compression</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
......@@ -532,22 +367,26 @@
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label31">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Echo&lt;/b&gt;</property>
<property name="use_markup">True</property>
......@@ -555,79 +394,602 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkCheckButton" id="ppp_send_echo_packets">
<property name="label" translatable="yes">Send PPP _echo packets</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Send PPP _echo packets</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">cancel_button1</action-widget>
<action-widget response="-5">ok_button1</action-widget>
</action-widgets>
</object>
<object class="GtkDialog" id="l2tp-ipsec-dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">L2TP IPSEC Options</property>
<property name="window_position">center-on-parent</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<property name="skip_pager_hint">True</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area3">
<object class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cancel_button">
<object class="GtkButton" id="ipsec_cancel_button">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ok_button">
<object class="GtkButton" id="ipsec_ok_button">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="ipsec_enable">
<property name="label" translatable="yes">_Enable IPsec tunnel to L2TP host</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Group Name:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Gateway ID:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Pre-shared key:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="ipsec_group_name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char"></property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="ipsec_gateway_id">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char"></property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="ipsec_psk">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="invisible_char"></property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">ppp_use_mppe</action-widget>
<action-widget response="0">ppp_allow_stateful_mppe</action-widget>
<action-widget response="0">ppp_allow_bsdcomp</action-widget>
<action-widget response="0">ppp_allow_deflate</action-widget>
<action-widget response="0">ppp_usevj</action-widget>
<action-widget response="0">ppp_usepcomp</action-widget>
<action-widget response="0">ppp_useaccomp</action-widget>
<action-widget response="0">ppp_send_echo_packets</action-widget>
<action-widget response="-6">cancel_button</action-widget>
<action-widget response="-5">ok_button</action-widget>
<action-widget response="-6">ipsec_cancel_button</action-widget>
<action-widget response="-5">ipsec_ok_button</action-widget>
</action-widgets>
</object>
<object class="GtkWindow" id="l2tp-widget">
<property name="can_focus">False</property>
<property name="title" translatable="yes">window1</property>
<child>
<object class="GtkVBox" id="l2tp-vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="spacing">16</property>
<child>
<object class="GtkVBox" id="vbox8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label22">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;General&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkTable" id="table2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_columns">2</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkEntry" id="gateway_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Gateway:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">gateway_entry</property>
</object>
<packing>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox11">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label25">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Optional&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkTable" id="table3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkEntry" id="domain_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label27">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">NT Domain:</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show_passwords_checkbutton">
<property name="label" translatable="yes">Show password</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="user_password_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Password:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="user_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label26">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">User name:</property>
</object>
<packing>
<property name="x_options">GTK_SHRINK | GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="xscale">0</property>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="ipsec_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<child>
<object class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-preferences</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_IPsec Settings...</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="advanced_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<child>
<object class="GtkHBox" id="hbox4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-preferences</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">PPP Se_ttings...</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkListStore" id="model1">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Default</col>
</row>
</data>
</object>
</interface>
......@@ -45,6 +45,7 @@
#include "nm-l2tp.h"
#include "import-export.h"
#include "advanced-dialog.h"
#include "ipsec-dialog.h"
#define L2TP_PLUGIN_NAME _("Layer 2 Tunneling Protocol (L2TP)")
#define L2TP_PLUGIN_DESC _("Compatible with L2TP VPN servers.")
......@@ -78,6 +79,7 @@ typedef struct {
GtkWindowGroup *window_group;
gboolean window_added;
GHashTable *advanced;
GHashTable *ipsec;
} L2tpPluginUiWidgetPrivate;
......@@ -155,6 +157,14 @@ advanced_dialog_close_cb (GtkWidget *dialog, gpointer user_data)
gtk_widget_destroy (dialog);
}
static void
ipsec_dialog_close_cb (GtkWidget *dialog, gpointer user_data)
{
gtk_widget_hide (dialog);
/* gtk_widget_destroy() will remove the window from the window group */
gtk_widget_destroy (dialog);
}
static void
advanced_dialog_response_cb (GtkWidget *dialog, gint response, gpointer user_data)
{
......@@ -179,6 +189,30 @@ advanced_dialog_response_cb (GtkWidget *dialog, gint response, gpointer user_dat
stuff_changed_cb (NULL, self);
}
static void
ipsec_dialog_response_cb (GtkWidget *dialog, gint response, gpointer user_data)
{
L2tpPluginUiWidget *self = L2TP_PLUGIN_UI_WIDGET (user_data);
L2tpPluginUiWidgetPrivate *priv = L2TP_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
GError *error = NULL;
if (response != GTK_RESPONSE_OK) {
ipsec_dialog_close_cb (dialog, self);
return;
}
if (priv->ipsec)
g_hash_table_destroy (priv->ipsec);
priv->ipsec = ipsec_dialog_new_hash_from_dialog (dialog, &error);
if (!priv->ipsec) {
g_message ("%s: error reading ipsec settings: %s", __func__, error->message);
g_error_free (error);
}
ipsec_dialog_close_cb (dialog, self);
stuff_changed_cb (NULL, self);
}
static void
advanced_button_clicked_cb (GtkWidget *button, gpointer user_data)
{
......@@ -208,6 +242,36 @@ advanced_button_clicked_cb (GtkWidget *button, gpointer user_data)
gtk_widget_show_all (dialog);
}
static void
ipsec_button_clicked_cb (GtkWidget *button, gpointer user_data)
{
L2tpPluginUiWidget *self = L2TP_PLUGIN_UI_WIDGET (user_data);
L2tpPluginUiWidgetPrivate *priv = L2TP_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
GtkWidget *dialog, *toplevel;
toplevel = gtk_widget_get_toplevel (priv->widget);
g_return_if_fail (GTK_WIDGET_TOPLEVEL (toplevel));
dialog = ipsec_dialog_new (priv->ipsec);
if (!dialog) {
g_warning ("%s: failed to create the IPSEC dialog!", __func__);
return;
}
gtk_window_group_add_window (priv->window_group, GTK_WINDOW (dialog));
if (!priv->window_added) {
gtk_window_group_add_window (priv->window_group, GTK_WINDOW (toplevel));
priv->window_added = TRUE;
}
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (ipsec_dialog_response_cb), self);
g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (ipsec_dialog_close_cb), self);
gtk_widget_show_all (dialog);
}
static void
show_toggled_cb (GtkCheckButton *button, L2tpPluginUiWidget *self)
{
......@@ -330,6 +394,9 @@ init_plugin_ui (L2tpPluginUiWidget *self, NMConnection *connection, GError **err
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "advanced_button"));
g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (advanced_button_clicked_cb), self);
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "ipsec_button"));
g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (ipsec_button_clicked_cb), self);
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "show_passwords_checkbutton"));
g_return_val_if_fail (widget != NULL, FALSE);
g_signal_connect (G_OBJECT (widget), "toggled",
......@@ -351,7 +418,7 @@ get_widget (NMVpnPluginUiWidgetInterface *iface)
}
static void
hash_copy_advanced (gpointer key, gpointer data, gpointer user_data)
hash_copy_pair (gpointer key, gpointer data, gpointer user_data)
{
NMSettingVPN *s_vpn = NM_SETTING_VPN (user_data);
......@@ -395,7 +462,9 @@ update_connection (NMVpnPluginUiWidgetInterface *iface,
nm_setting_vpn_add_data_item (s_vpn, NM_L2TP_KEY_DOMAIN, str);
if (priv->advanced)
g_hash_table_foreach (priv->advanced, hash_copy_advanced, s_vpn);
g_hash_table_foreach (priv->advanced, hash_copy_pair, s_vpn);
if (priv->ipsec)
g_hash_table_foreach (priv->ipsec, hash_copy_pair, s_vpn);
nm_connection_add_setting (connection, NM_SETTING (s_vpn));
valid = TRUE;
......@@ -497,6 +566,11 @@ nm_vpn_plugin_ui_widget_interface_new (NMConnection *connection, GError **error)
g_object_unref (object);
return NULL;
}
priv->ipsec = ipsec_dialog_new_hash_from_connection (connection, error);
if (!priv->ipsec) {
g_object_unref (object);
return NULL;
}
return object;
}
......@@ -522,6 +596,9 @@ dispose (GObject *object)
if (priv->advanced)
g_hash_table_destroy (priv->advanced);
if (priv->ipsec)
g_hash_table_destroy (priv->ipsec);
G_OBJECT_CLASS (l2tp_plugin_ui_widget_parent_class)->dispose (object);
}
......
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* nm-l2tp-service - L2TP VPN integration with NetworkManager
*
* Geo Carncross <geocar@gmail.com>
* Alexey Torkhov <atorkhov@gmail.com>
* Based on work by Dan Williams <dcbw@redhat.com>
*
......@@ -20,6 +21,7 @@
*
* (C) Copyright 2008 - 2009 Red Hat, Inc.
* (C) Copyright 2011 Alexey Torkhov <atorkhov@gmail.com>
* (C) Copyright 2011 Geo Carncross <geocar@gmail.com>
*/
#include <stdio.h>
......@@ -114,6 +116,18 @@ enum {
};
static guint signals[LAST_SIGNAL] = { 0 };
static gboolean
ensure_killed (gpointer data)
{
int pid = GPOINTER_TO_INT (data);
if (kill (pid, 0) == 0)
kill (pid, SIGKILL);
return FALSE;
}
static NML2tpPppService *
nm_l2tp_ppp_service_new (void)
{
......@@ -352,7 +366,8 @@ impl_l2tp_service_set_ip4_config (NML2tpPppService *self,
G_DEFINE_TYPE (NML2tpPlugin, nm_l2tp_plugin, NM_TYPE_VPN_PLUGIN);
typedef struct {
GPid pid;
GPid pid_l2tpd;
gboolean ipsec_up;
guint32 ppp_timeout_handler;
NML2tpPppService *service;
NMConnection *connection;
......@@ -390,6 +405,10 @@ static ValidProperty valid_properties[] = {
{ NM_L2TP_KEY_USE_ACCOMP, G_TYPE_BOOLEAN, FALSE },
{ NM_L2TP_KEY_LCP_ECHO_FAILURE, G_TYPE_UINT, FALSE },
{ NM_L2TP_KEY_LCP_ECHO_INTERVAL, G_TYPE_UINT, FALSE },
{ NM_L2TP_KEY_IPSEC_ENABLE, G_TYPE_BOOLEAN, FALSE },
{ NM_L2TP_KEY_IPSEC_GATEWAY_ID, G_TYPE_STRING, FALSE },
{ NM_L2TP_KEY_IPSEC_GROUP_NAME, G_TYPE_STRING, FALSE },
{ NM_L2TP_KEY_IPSEC_PSK, G_TYPE_STRING, FALSE },
{ NULL, G_TYPE_NONE, FALSE }
};
......@@ -416,6 +435,24 @@ validate_gateway (const char *gateway)
return TRUE;
}
static gboolean
validate_ipsec_id (const char *id)
{
const char *p = id;
if (!id || !strlen (id))
return TRUE;
/* Ensure it's a valid id-name */
p = id;
while (*p) {
if (!isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.'))
return FALSE;
p++;
}
return TRUE;
}
typedef struct ValidateInfo {
ValidProperty *table;
GError **error;
......@@ -446,6 +483,9 @@ validate_one_property (const char *key, const char *value, gpointer user_data)
switch (prop.type) {
case G_TYPE_STRING:
if (!strcmp (prop.name, NM_L2TP_KEY_IPSEC_PSK))
return; /* valid */
if ( !strcmp (prop.name, NM_L2TP_KEY_GATEWAY)
&& !validate_gateway (value)) {
g_set_error (info->error,
......@@ -455,7 +495,24 @@ validate_one_property (const char *key, const char *value, gpointer user_data)
key);
return;
}
return; /* valid */
if ( !strcmp (prop.name, NM_L2TP_KEY_IPSEC_GROUP_NAME)
&& !validate_ipsec_id (value)) {
g_set_error (info->error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
"invalid ipsec-group-name '%s'",
key);
return;
}
if ( !strcmp (prop.name, NM_L2TP_KEY_IPSEC_GATEWAY_ID)
&& !validate_ipsec_id (value)) {
g_set_error (info->error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
"invalid ipsec-gateway-id '%s'",
key);
return;
}
case G_TYPE_UINT:
errno = 0;
tmp = strtol (value, NULL, 10);
......@@ -493,7 +550,7 @@ validate_one_property (const char *key, const char *value, gpointer user_data)
g_set_error (info->error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
"property '%s' invalid or not supported",
"property '%s' invalid or not supportedx",
key);
}
}
......@@ -558,6 +615,9 @@ nm_l2tp_secrets_validate (NMSettingVPN *s_vpn, GError **error)
return *error ? FALSE : TRUE;
}
static void
nm_l2tp_stop_ipsec(NML2tpPlugin *plugin);
static void
l2tpd_watch_cb (GPid pid, gint status, gpointer user_data)
{
......@@ -580,8 +640,12 @@ l2tpd_watch_cb (GPid pid, gint status, gpointer user_data)
g_warning ("xl2tpd died from an unknown cause");
/* Reap child if needed. */
waitpid (priv->pid, NULL, WNOHANG);
priv->pid = 0;
waitpid (priv->pid_l2tpd, NULL, WNOHANG);
priv->pid_l2tpd = 0;
if(priv->ipsec_up) {
nm_l2tp_stop_ipsec(plugin);
}
/* Cleaning up config files */
filename = g_strdup_printf ("/var/run/nm-xl2tpd.conf.%d", my_pid);
......@@ -592,6 +656,18 @@ l2tpd_watch_cb (GPid pid, gint status, gpointer user_data)
unlink(filename);
g_free(filename);
filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d/ipsec.conf", my_pid);
unlink(filename);
g_free(filename);
filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d/ipsec.secrets", my_pid);
unlink(filename);
g_free(filename);
filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d", my_pid);
rmdir(filename);
g_free(filename);
/* Must be after data->state is set since signals use data->state */
switch (error) {
case 16:
......@@ -614,6 +690,28 @@ l2tpd_watch_cb (GPid pid, gint status, gpointer user_data)
nm_vpn_plugin_set_state (NM_VPN_PLUGIN (plugin), NM_VPN_SERVICE_STATE_STOPPED);
}
static inline const char *
nm_find_ipsec (void)
{
static const char *ipsec_binary_paths[] =
{
"/sbin/ipsec",
"/usr/sbin/ipsec",
"/usr/local/sbin/ipsec",
NULL
};
const char **ipsec_binary = ipsec_binary_paths;
while (*ipsec_binary != NULL) {
if (g_file_test (*ipsec_binary, G_FILE_TEST_EXISTS))
break;
ipsec_binary++;
}
return *ipsec_binary;
}
static inline const char *
nm_find_l2tpd (void)
{
......@@ -813,7 +911,7 @@ service_ip4_config_cb (NML2tpPppService *service,
}
static void
free_l2tpd_args (GPtrArray *args)
free_args (GPtrArray *args)
{
int i;
......@@ -826,6 +924,65 @@ free_l2tpd_args (GPtrArray *args)
}
static void
nm_l2tp_stop_ipsec(NML2tpPlugin *plugin)
{
NML2tpPluginPrivate *priv = NM_L2TP_PLUGIN_GET_PRIVATE (plugin);
(void)system("PATH=/sbin:/usr/sbin:/usr/local/sbin ipsec auto --down nm-ipsec-l2tp");
(void)system("PATH=/sbin:/usr/sbin:/usr/local/sbin ipsec setup stop");
g_message("ipsec shut down");
}
static gboolean
nm_l2tp_start_ipsec(NML2tpPlugin *plugin,
NMSettingVPN *s_vpn,
GError **error)
{
NML2tpPluginPrivate *priv = NM_L2TP_PLUGIN_GET_PRIVATE (plugin);
const char *ipsec_binary;
ipsec_binary = nm_find_ipsec ();
if (!ipsec_binary) {
g_set_error (error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
"%s",
"Could not find the ipsec binary.");
return FALSE;
}
/* cram into environment */
putenv(g_strdup_printf ("IPSEC_CONFS=/var/run/nm-ipsec-l2tp.%d", getpid()));
if(system("PATH=/sbin:/usr/sbin:/usr/local/sbin ipsec setup start")) {
g_set_error (error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
"%s",
"IPSEC setup failed.");
return FALSE;
}
if(system("PATH=/sbin:/usr/sbin:/usr/local/sbin ipsec auto --add nm-ipsec-l2tp")) {
g_set_error (error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
"%s",
"IPSEC auto add failed.");
return FALSE;
}
if(system("PATH=/sbin:/usr/sbin:/usr/local/sbin ipsec auto --up nm-ipsec-l2tp")) {
g_set_error (error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
"%s",
"IPSEC auto up failed.");
return FALSE;
}
g_message("ipsec ready for action");
return TRUE;
}
static gboolean
nm_l2tp_start_l2tpd_binary (NML2tpPlugin *plugin,
NMSettingVPN *s_vpn,
......@@ -856,14 +1013,14 @@ nm_l2tp_start_l2tpd_binary (NML2tpPlugin *plugin,
if (!g_spawn_async (NULL, (char **) l2tpd_argv->pdata, NULL,
G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, error)) {
free_l2tpd_args (l2tpd_argv);
free_args (l2tpd_argv);
return FALSE;
}
free_l2tpd_args (l2tpd_argv);
free_args (l2tpd_argv);
g_message("xl2tpd started with pid %d",pid);
NM_L2TP_PLUGIN_GET_PRIVATE (plugin)->pid = pid;
NM_L2TP_PLUGIN_GET_PRIVATE (plugin)->pid_l2tpd = pid;
g_child_watch_add (pid, l2tpd_watch_cb, plugin);
priv->ppp_timeout_handler = g_timeout_add (NM_L2TP_WAIT_PPPD, pppd_timed_out, plugin);
......@@ -897,15 +1054,85 @@ nm_l2tp_config_write (NML2tpPlugin *plugin,
pid_t pid = getpid ();
const char *value;
const char *username;
gint fdtmp1 = -1;
gint conf_fd = -1;
gint ipsec_fd = -1;
gint ipsec_secret_fd = -1;
gint pppopt_fd = -1;
filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d", pid);
mkdir(filename,0700);
g_free (filename);
filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d/ipsec.conf", pid);
ipsec_fd = open (filename, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
g_free (filename);
if (ipsec_fd == -1) {
g_set_error (error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
"%s",
"Could not write ipsec config.");
return FALSE;
}
write_config_option (ipsec_fd, "version 2.0\n"
"config setup\n"
" nat_traversal=yes\n"
" force_keepalive=yes\n"
" protostack=netkey\n"
" keep_alive=60\n"
"\n"
"conn nm-ipsec-l2tp\n"
" auto=start\n"
" type=transport\n"
" auth=esp\n"
" pfs=no\n"
" authby=secret\n"
" keyingtries=0\n"
" left=%%defaultroute\n");
value = nm_setting_vpn_get_data_item (s_vpn, NM_L2TP_KEY_IPSEC_GROUP_NAME);
if(value)write_config_option (ipsec_fd, " leftid=@%s\n", value);
value = nm_setting_vpn_get_data_item (s_vpn, NM_L2TP_KEY_GATEWAY);
write_config_option (ipsec_fd, " right=%s\n", value);
value = nm_setting_vpn_get_data_item (s_vpn, NM_L2TP_KEY_IPSEC_GATEWAY_ID);
if(value)write_config_option (ipsec_fd, " rightid=@%s\n", value);
write_config_option (ipsec_fd,
" esp=3des-sha1\n"
" keyexchange=ike\n"
" ike=3des-sha1-modp1024\n"
" aggrmode=yes\n"
" forceencaps=yes\n");
filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d/ipsec.secrets", pid);
ipsec_secret_fd = open (filename, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
g_free (filename);
if (ipsec_secret_fd == -1) {
close(ipsec_fd);
g_set_error (error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
"%s",
"Could not write ipsec config.");
return FALSE;
}
value = nm_setting_vpn_get_data_item (s_vpn, NM_L2TP_KEY_IPSEC_GROUP_NAME);
write_config_option(ipsec_secret_fd, "%s%s ",value?"@":"", value?value:"%any");
value = nm_setting_vpn_get_data_item (s_vpn, NM_L2TP_KEY_IPSEC_GATEWAY_ID);
write_config_option(ipsec_secret_fd, "%s%s ",value?"@":"", value?value:"%any");
value = nm_setting_vpn_get_data_item (s_vpn, NM_L2TP_KEY_IPSEC_PSK);
if(!value)value="";
write_config_option(ipsec_secret_fd, ": PSK \"%s\"\n",value);
filename = g_strdup_printf ("/var/run/nm-xl2tpd.conf.%d", pid);
conf_fd = open (filename, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
g_free (filename);
if (conf_fd == -1) {
close(ipsec_fd);
close(ipsec_secret_fd);
g_set_error (error,
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
......@@ -919,6 +1146,8 @@ nm_l2tp_config_write (NML2tpPlugin *plugin,
g_free (filename);
if (pppopt_fd == -1) {
close(ipsec_fd);
close(ipsec_secret_fd);
close(conf_fd);
g_set_error (error,
NM_VPN_PLUGIN_ERROR,
......@@ -1067,6 +1296,7 @@ nm_l2tp_config_write (NML2tpPlugin *plugin,
write_config_option (pppopt_fd, "plugin %s\n", NM_L2TP_PPPD_PLUGIN);
close(ipsec_fd);
close(conf_fd);
close(pppopt_fd);
......@@ -1080,6 +1310,7 @@ real_connect (NMVPNPlugin *plugin,
{
NML2tpPluginPrivate *priv = NM_L2TP_PLUGIN_GET_PRIVATE (plugin);
NMSettingVPN *s_vpn;
const char *value;
s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
g_assert (s_vpn);
......@@ -1123,6 +1354,14 @@ real_connect (NMVPNPlugin *plugin,
if (!nm_l2tp_config_write (NM_L2TP_PLUGIN (plugin), s_vpn, error))
return FALSE;
value = nm_setting_vpn_get_data_item (s_vpn, NM_L2TP_KEY_IPSEC_ENABLE);
g_message("ipsec enable flag: %s",value?value:"(null)");
if(value && !strcmp(value,"yes")) {
g_message("starting ipsec");
if (!nm_l2tp_start_ipsec(NM_L2TP_PLUGIN (plugin), s_vpn, error))
return FALSE;
}
if (!nm_l2tp_start_l2tpd_binary (NM_L2TP_PLUGIN (plugin), s_vpn, error))
return FALSE;
......@@ -1150,31 +1389,24 @@ real_need_secrets (NMVPNPlugin *plugin,
return FALSE;
}
static gboolean
ensure_killed (gpointer data)
{
int pid = GPOINTER_TO_INT (data);
if (kill (pid, 0) == 0)
kill (pid, SIGKILL);
return FALSE;
}
static gboolean
real_disconnect (NMVPNPlugin *plugin,
GError **err)
{
NML2tpPluginPrivate *priv = NM_L2TP_PLUGIN_GET_PRIVATE (plugin);
if (priv->pid) {
if (kill (priv->pid, SIGTERM) == 0)
g_timeout_add (2000, ensure_killed, GINT_TO_POINTER (priv->pid));
if (priv->pid_l2tpd) {
if (kill (priv->pid_l2tpd, SIGTERM) == 0)
g_timeout_add (2000, ensure_killed, GINT_TO_POINTER (priv->pid_l2tpd));
else
kill (priv->pid, SIGKILL);
kill (priv->pid_l2tpd, SIGKILL);
g_message("Terminated ppp daemon with PID %d.", priv->pid_l2tpd);
priv->pid_l2tpd = 0;
}
g_message("Terminated ppp daemon with PID %d.", priv->pid);
priv->pid = 0;
if(priv->ipsec_up) {
nm_l2tp_stop_ipsec(plugin);
}
if (priv->connection) {
......@@ -1278,6 +1510,7 @@ main (int argc, char *argv[])
{
NML2tpPlugin *plugin;
GMainLoop *main_loop;
char *filename;
g_type_init ();
......
......@@ -68,6 +68,11 @@
#define NM_L2TP_KEY_LCP_ECHO_FAILURE "lcp-echo-failure"
#define NM_L2TP_KEY_LCP_ECHO_INTERVAL "lcp-echo-interval"
#define NM_L2TP_KEY_IPSEC_ENABLE "ipsec-enabled"
#define NM_L2TP_KEY_IPSEC_GATEWAY_ID "ipsec-gateway-id"
#define NM_L2TP_KEY_IPSEC_GROUP_NAME "ipsec-group-name"
#define NM_L2TP_KEY_IPSEC_PSK "ipsec-psk"
typedef struct {
NMVPNPlugin parent;
......
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