NetworkManager r3790 - in trunk/vpn-daemons/openvpn: . properties
- From: dcbw svn gnome org
- To: svn-commits-list gnome org
- Subject: NetworkManager r3790 - in trunk/vpn-daemons/openvpn: . properties
- Date: Tue, 1 Jul 2008 02:33:51 +0000 (UTC)
Author: dcbw
Date: Tue Jul 1 02:33:50 2008
New Revision: 3790
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3790&view=rev
Log:
2008-06-30 Dan Williams <dcbw redhat com>
* properties/import-export.c
properties/import-export.h
properties/Makefile.am
- Implement import of OpenVPN config files
* properties/nm-openvpn.c
properties/nm-openvpn.h
- Add another error for import
- (import): check file extension; get contents; hand off to importer
Added:
trunk/vpn-daemons/openvpn/properties/import-export.c
trunk/vpn-daemons/openvpn/properties/import-export.h
Modified:
trunk/vpn-daemons/openvpn/ChangeLog
trunk/vpn-daemons/openvpn/properties/Makefile.am
trunk/vpn-daemons/openvpn/properties/nm-openvpn.c
trunk/vpn-daemons/openvpn/properties/nm-openvpn.h
Modified: trunk/vpn-daemons/openvpn/properties/Makefile.am
==============================================================================
--- trunk/vpn-daemons/openvpn/properties/Makefile.am (original)
+++ trunk/vpn-daemons/openvpn/properties/Makefile.am Tue Jul 1 02:33:50 2008
@@ -6,7 +6,9 @@
nm-openvpn.c \
nm-openvpn.h \
auth-helpers.c \
- auth-helpers.h
+ auth-helpers.h \
+ import-export.c \
+ import-export.h
gladedir = $(datadir)/gnome-vpn-properties/openvpn
glade_DATA = nm-openvpn-dialog.glade
Added: trunk/vpn-daemons/openvpn/properties/import-export.c
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/openvpn/properties/import-export.c Tue Jul 1 02:33:50 2008
@@ -0,0 +1,378 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/***************************************************************************
+ *
+ * Copyright (C) 2008 Dan Williams, <dcbw redhat 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 <ctype.h>
+
+#include <glib/gi18n-lib.h>
+
+#include <nm-setting-vpn.h>
+#include <nm-setting-vpn-properties.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-ip4-config.h>
+
+#include "import-export.h"
+#include "nm-openvpn.h"
+#include "../src/nm-openvpn-service.h"
+
+#define CLIENT_TAG "client"
+#define DEV_TAG "dev"
+#define PROTO_TAG "proto"
+#define REMOTE_TAG "remote"
+#define CA_TAG "ca"
+#define CERT_TAG "cert"
+#define KEY_TAG "key"
+#define CIPHER_TAG "cipher"
+#define COMP_TAG "comp-lzo"
+#define IFCONFIG_TAG "ifconfig"
+#define SECRET_TAG "secret"
+#define AUTH_USER_PASS_TAG "auth-user-pass"
+#define TLS_AUTH_TAG "tls-auth"
+
+static gboolean
+handle_path_item (const char *line,
+ const char *tag,
+ const char *key,
+ GHashTable *hash,
+ char **leftover)
+{
+ char *tmp, *file, *unquoted, *p;
+ gboolean quoted = FALSE;
+
+ if (leftover)
+ g_return_val_if_fail (*leftover == NULL, FALSE);
+
+ if (strncmp (line, tag, strlen (tag)))
+ return FALSE;
+
+ tmp = g_strdup (line + strlen (tag));
+ file = g_strstrip (tmp);
+ if (!strlen (file))
+ goto out;
+
+ /* Simple unquote */
+ if ((file[0] == '"') || (file[0] == '\'')) {
+ quoted = TRUE;
+ file++;
+ }
+
+ /* Unquote stuff using openvpn unquoting rules */
+ unquoted = g_malloc0 (strlen (file) + 1);
+ for (p = unquoted; *file; file++, p++) {
+ if (quoted && ((*file == '"') || (*file == '\'')))
+ break;
+ else if (!quoted && isspace (*file))
+ break;
+
+ if (*file == '\\' && *(file+1) == '\\')
+ *p = *(++file);
+ else if (*file == '\\' && *(file+1) == '"')
+ *p = *(++file);
+ else if (*file == '\\' && *(file+1) == ' ')
+ *p = *(++file);
+ else
+ *p = *file;
+ }
+ if (leftover && *file)
+ *leftover = file + 1;
+
+ g_hash_table_insert (hash, g_strdup (key), str_to_gvalue (unquoted));
+ g_free (unquoted);
+
+out:
+ g_free (tmp);
+ return TRUE;
+}
+
+static char **
+get_args (const char *line)
+{
+ char **split, **sanitized, **tmp, **tmp2;
+
+ split = g_strsplit_set (line, " \t", 0);
+ sanitized = g_malloc0 (sizeof (char *) * (g_strv_length (split) + 1));
+
+ for (tmp = split, tmp2 = sanitized; *tmp; tmp++) {
+ if (strlen (*tmp))
+ *tmp2++ = g_strdup (*tmp);
+ }
+
+ g_strfreev (split);
+ return sanitized;
+}
+
+static void
+handle_direction (const char *tag, const char *key, char *leftover, GHashTable *hash)
+{
+ glong direction;
+
+ if (!leftover)
+ return;
+
+ leftover = g_strstrip (leftover);
+ if (!strlen (leftover))
+ return;
+
+ errno = 0;
+ direction = strtol (leftover, NULL, 10);
+ if ((errno == 0) && ((direction == 0) || (direction == 1)))
+ g_hash_table_insert (hash, g_strdup (key), int_to_gvalue (direction));
+ else
+ g_warning ("%s: unknown %s direction '%s'", __func__, tag, leftover);
+}
+
+NMConnection *
+do_import (const char *path, char **lines, GError **error)
+{
+ NMConnection *connection = NULL;
+ NMSettingConnection *s_con;
+ NMSettingVPN *s_vpn;
+ NMSettingVPNProperties *s_vpn_props;
+ char *last_dot;
+ char **line;
+ gboolean have_client = FALSE, have_remote = FALSE;
+ gboolean have_pass = FALSE, have_sk = FALSE;
+ int ctype = NM_OPENVPN_CONTYPE_INVALID;
+
+ connection = nm_connection_new ();
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ s_vpn = NM_SETTING_VPN (nm_setting_vpn_new ());
+ s_vpn->service_type = g_strdup (NM_DBUS_SERVICE_OPENVPN);
+ nm_connection_add_setting (connection, NM_SETTING (s_vpn));
+
+ s_vpn_props = NM_SETTING_VPN_PROPERTIES (nm_setting_vpn_properties_new ());
+ nm_connection_add_setting (connection, NM_SETTING (s_vpn_props));
+
+ s_con->id = g_path_get_basename (path);
+ last_dot = strrchr (s_con->id, '.');
+ if (last_dot)
+ *last_dot = '\0';
+
+ for (line = lines; *line; line++) {
+ char *comment, **items, *leftover = NULL;
+
+ if ((comment = strchr (*line, '#')))
+ *comment = '\0';
+ if ((comment = strchr (*line, ';')))
+ *comment = '\0';
+ if (!strlen (*line))
+ continue;
+
+ if (!strncmp (*line, CLIENT_TAG, strlen (CLIENT_TAG)))
+ have_client = TRUE;
+
+ if (!strncmp (*line, DEV_TAG, strlen (DEV_TAG))) {
+ if (strstr (*line, "tun")) {
+ /* ignore; default is tun */
+ } else if (strstr (*line, "tap")) {
+ g_hash_table_insert (s_vpn_props->data,
+ g_strdup (NM_OPENVPN_KEY_TAP_DEV),
+ bool_to_gvalue (TRUE));
+ } else
+ g_warning ("%s: unknown dev option '%s'", __func__, *line);
+
+ continue;
+ }
+
+ if (!strncmp (*line, PROTO_TAG, strlen (PROTO_TAG))) {
+ if (strstr (*line, "udp")) {
+ /* ignore; udp is default */
+ } else if (strstr (*line, "tcp")) {
+ g_hash_table_insert (s_vpn_props->data,
+ g_strdup (NM_OPENVPN_KEY_PROTO_TCP),
+ bool_to_gvalue (TRUE));
+ } else
+ g_warning ("%s: unknown proto option '%s'", __func__, *line);
+
+ continue;
+ }
+
+ if (!strncmp (*line, COMP_TAG, strlen (COMP_TAG))) {
+ g_hash_table_insert (s_vpn_props->data,
+ g_strdup (NM_OPENVPN_KEY_COMP_LZO),
+ bool_to_gvalue (TRUE));
+ continue;
+ }
+
+ if (!strncmp (*line, REMOTE_TAG, strlen (REMOTE_TAG))) {
+ items = get_args (*line + strlen (REMOTE_TAG));
+ if (!items)
+ continue;
+
+ if (g_strv_length (items) >= 1) {
+ g_hash_table_insert (s_vpn_props->data,
+ g_strdup (NM_OPENVPN_KEY_REMOTE),
+ str_to_gvalue (items[0]));
+ have_remote = TRUE;
+
+ if (g_strv_length (items) >= 2) {
+ glong port;
+
+ errno = 0;
+ port = strtol (items[1], NULL, 10);
+ if ((errno == 0) && (port > 0) && (port < 65536)) {
+ g_hash_table_insert (s_vpn_props->data,
+ g_strdup (NM_OPENVPN_KEY_PORT),
+ int_to_gvalue (port));
+ } else
+ g_warning ("%s: invalid remote port in option '%s'", __func__, *line);
+ }
+ }
+ g_strfreev (items);
+
+ if (!g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_REMOTE))
+ g_warning ("%s: unknown remote option '%s'", __func__, *line);
+ continue;
+ }
+
+ if (handle_path_item (*line, CA_TAG, NM_OPENVPN_KEY_CA, s_vpn_props->data, NULL))
+ continue;
+
+ if (handle_path_item (*line, CERT_TAG, NM_OPENVPN_KEY_CERT, s_vpn_props->data, NULL))
+ continue;
+
+ if (handle_path_item (*line, KEY_TAG, NM_OPENVPN_KEY_KEY, s_vpn_props->data, NULL))
+ continue;
+
+ if (handle_path_item (*line, SECRET_TAG, NM_OPENVPN_KEY_SHARED_KEY,
+ s_vpn_props->data, &leftover)) {
+ handle_direction ("secret",
+ NM_OPENVPN_KEY_SHARED_KEY_DIRECTION,
+ leftover,
+ s_vpn_props->data);
+ continue;
+ }
+
+ if (handle_path_item (*line, TLS_AUTH_TAG, NM_OPENVPN_KEY_TA,
+ s_vpn_props->data, &leftover)) {
+ handle_direction ("tls-auth",
+ NM_OPENVPN_KEY_TA_DIR,
+ leftover,
+ s_vpn_props->data);
+ continue;
+ }
+
+ if (!strncmp (*line, CIPHER_TAG, strlen (CIPHER_TAG))) {
+ items = get_args (*line + strlen (CIPHER_TAG));
+ if (!items)
+ continue;
+
+ if (g_strv_length (items)) {
+ g_hash_table_insert (s_vpn_props->data,
+ g_strdup (NM_OPENVPN_KEY_CIPHER),
+ str_to_gvalue (items[0]));
+ }
+ g_strfreev (items);
+ continue;
+ }
+
+ if (!strncmp (*line, IFCONFIG_TAG, strlen (IFCONFIG_TAG))) {
+ items = get_args (*line + strlen (IFCONFIG_TAG));
+ if (!items)
+ continue;
+
+ if (g_strv_length (items) == 2) {
+ g_hash_table_insert (s_vpn_props->data,
+ g_strdup (NM_OPENVPN_KEY_LOCAL_IP),
+ str_to_gvalue (items[0]));
+ g_hash_table_insert (s_vpn_props->data,
+ g_strdup (NM_OPENVPN_KEY_REMOTE_IP),
+ str_to_gvalue (items[1]));
+ } else
+ g_warning ("%s: unknown ifconfig option '%s'", __func__, *line);
+ g_strfreev (items);
+ continue;
+ }
+
+ if (!strncmp (*line, AUTH_USER_PASS_TAG, strlen (AUTH_USER_PASS_TAG)))
+ have_pass = TRUE;
+ }
+
+ if (g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_SHARED_KEY))
+ have_sk = TRUE;
+
+ if (!have_client && !have_sk) {
+ g_set_error (error,
+ OPENVPN_PLUGIN_UI_ERROR,
+ OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_OPENVPN,
+ "The file to import wasn't a valid OpenVPN client configuration.");
+ g_object_unref (connection);
+ connection = NULL;
+ } else if (!have_remote) {
+ g_set_error (error,
+ OPENVPN_PLUGIN_UI_ERROR,
+ OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_OPENVPN,
+ "The file to import wasn't a valid OpenVPN configure (no remote).");
+ g_object_unref (connection);
+ connection = NULL;
+ } else {
+ gboolean have_certs = FALSE, have_ca = FALSE;
+
+ if (g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_CA))
+ have_ca = TRUE;
+
+ if ( have_ca
+ && g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_CERT)
+ && g_hash_table_lookup (s_vpn_props->data, NM_OPENVPN_KEY_KEY))
+ have_certs = TRUE;
+
+ /* Determine connection type */
+ if (have_pass) {
+ if (have_certs)
+ ctype = NM_OPENVPN_CONTYPE_PASSWORD_TLS;
+ else if (have_ca)
+ ctype = NM_OPENVPN_CONTYPE_PASSWORD;
+ } else if (have_certs) {
+ ctype = NM_OPENVPN_CONTYPE_TLS;
+ } else if (have_sk)
+ ctype = NM_OPENVPN_CONTYPE_STATIC_KEY;
+
+ if (ctype == NM_OPENVPN_CONTYPE_INVALID)
+ ctype = NM_OPENVPN_CONTYPE_TLS;
+
+ g_hash_table_insert (s_vpn_props->data,
+ g_strdup (NM_OPENVPN_KEY_CONNECTION_TYPE),
+ int_to_gvalue (ctype));
+ }
+
+ return connection;
+}
+
+gboolean
+do_export (const char *path, NMConnection *connection, GError **error)
+{
+ return FALSE;
+}
+
+
+
Added: trunk/vpn-daemons/openvpn/properties/import-export.h
==============================================================================
--- (empty file)
+++ trunk/vpn-daemons/openvpn/properties/import-export.h Tue Jul 1 02:33:50 2008
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/***************************************************************************
+ *
+ * Copyright (C) 2008 Dan Williams, <dcbw redhat 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 _IMPORT_EXPORT_H_
+#define _IMPORT_EXPORT_H_
+
+#include <glib.h>
+#include <nm-connection.h>
+
+NMConnection *do_import (const char *path, char **lines, GError **error);
+
+gboolean do_export (const char *path, NMConnection *connection, GError **error);
+
+#endif
Modified: trunk/vpn-daemons/openvpn/properties/nm-openvpn.c
==============================================================================
--- trunk/vpn-daemons/openvpn/properties/nm-openvpn.c (original)
+++ trunk/vpn-daemons/openvpn/properties/nm-openvpn.c Tue Jul 1 02:33:50 2008
@@ -48,6 +48,7 @@
#include "../src/nm-openvpn-service.h"
#include "nm-openvpn.h"
#include "auth-helpers.h"
+#include "import-export.h"
#define OPENVPN_PLUGIN_NAME _("OpenVPN")
#define OPENVPN_PLUGIN_DESC _("Compatible with the OpenVPN server.")
@@ -119,6 +120,10 @@
ENUM_ENTRY (OPENVPN_PLUGIN_UI_ERROR_INVALID_PROPERTY, "InvalidProperty"),
/* The specified property was missing and is required. */
ENUM_ENTRY (OPENVPN_PLUGIN_UI_ERROR_MISSING_PROPERTY, "MissingProperty"),
+ /* The file to import could not be read. */
+ ENUM_ENTRY (OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_READABLE, "FileNotReadable"),
+ /* The file to import could was not an OpenVPN client file. */
+ ENUM_ENTRY (OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_OPENVPN, "FileNotOpenVPN"),
{ 0, 0, 0 }
};
etype = g_enum_register_static ("OpenvpnPluginUiError", values);
@@ -599,7 +604,47 @@
static NMConnection *
import (NMVpnPluginUiInterface *iface, const char *path, GError **error)
{
- return NULL;
+ NMConnection *connection = NULL;
+ char *contents = NULL;
+ char **lines = NULL;
+ char *ext;
+
+ ext = strrchr (path, '.');
+ if (!ext) {
+ g_set_error (error,
+ OPENVPN_PLUGIN_UI_ERROR,
+ OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_OPENVPN,
+ "unknown OpenVPN file extension");
+ goto out;
+ }
+
+ if (strcmp (ext, ".ovpn") && strcmp (ext, ".conf") && strcmp (ext, ".cnf")) {
+ g_set_error (error,
+ OPENVPN_PLUGIN_UI_ERROR,
+ OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_OPENVPN,
+ "unknown OpenVPN file extension");
+ goto out;
+ }
+
+ if (!g_file_get_contents (path, &contents, NULL, error))
+ return NULL;
+
+ lines = g_strsplit_set (contents, "\r\n", 0);
+ if (g_strv_length (lines) <= 1) {
+ g_set_error (error,
+ OPENVPN_PLUGIN_UI_ERROR,
+ OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_READABLE,
+ "not a valid OpenVPN configuration file");
+ goto out;
+ }
+
+ connection = do_import (path, lines, error);
+
+out:
+ if (lines)
+ g_strfreev (lines);
+ g_free (contents);
+ return connection;
}
static gboolean
@@ -608,7 +653,7 @@
NMConnection *connection,
GError **error)
{
- return FALSE;
+ return do_export (path, connection, error);
}
static char *
Modified: trunk/vpn-daemons/openvpn/properties/nm-openvpn.h
==============================================================================
--- trunk/vpn-daemons/openvpn/properties/nm-openvpn.h (original)
+++ trunk/vpn-daemons/openvpn/properties/nm-openvpn.h Tue Jul 1 02:33:50 2008
@@ -29,7 +29,9 @@
{
OPENVPN_PLUGIN_UI_ERROR_UNKNOWN = 0,
OPENVPN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
- OPENVPN_PLUGIN_UI_ERROR_MISSING_PROPERTY
+ OPENVPN_PLUGIN_UI_ERROR_MISSING_PROPERTY,
+ OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_READABLE,
+ OPENVPN_PLUGIN_UI_ERROR_FILE_NOT_OPENVPN
} OpenvpnPluginUiError;
#define OPENVPN_TYPE_PLUGIN_UI_ERROR (openvpn_plugin_ui_error_get_type ())
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]