NetworkManager r3644 - in trunk: . system-settings/plugins/ifcfg-suse system-settings/src
- From: tambeti svn gnome org
- To: svn-commits-list gnome org
- Subject: NetworkManager r3644 - in trunk: . system-settings/plugins/ifcfg-suse system-settings/src
- Date: Thu, 8 May 2008 08:20:02 +0100 (BST)
Author: tambeti
Date: Thu May 8 07:20:02 2008
New Revision: 3644
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3644&view=rev
Log:
2008-05-08 Tambet Ingo <tambet gmail com>
Rewrite the suse system settings plugin.
* system-settings/plugins/ifcfg-suse/plugin.c: Rewrite.
* system-settings/plugins/ifcfg-suse/parser.c: Rewrite.
* system-settings/plugins/ifcfg-suse/nm-suse-connection.[ch]: Implement.
* system-settings/plugins/ifcfg-suse/Makefile.am: Add new files to build.
* system-settings/src/dbus-settings.c: Fix connection reference counting.
* system-settings/src/main.c (load_plugins): Improve error reporting.
* system-settings/src/sha1.[ch] Add.
* system-settings/src/Makefile.am: Add sha1[ch] to build.
Added:
trunk/system-settings/plugins/ifcfg-suse/nm-suse-connection.c
trunk/system-settings/plugins/ifcfg-suse/nm-suse-connection.h
trunk/system-settings/src/sha1.c
trunk/system-settings/src/sha1.h
Modified:
trunk/ChangeLog
trunk/system-settings/plugins/ifcfg-suse/Makefile.am
trunk/system-settings/plugins/ifcfg-suse/parser.c
trunk/system-settings/plugins/ifcfg-suse/parser.h
trunk/system-settings/plugins/ifcfg-suse/plugin.c
trunk/system-settings/src/Makefile.am
trunk/system-settings/src/dbus-settings.c
trunk/system-settings/src/main.c
Modified: trunk/system-settings/plugins/ifcfg-suse/Makefile.am
==============================================================================
--- trunk/system-settings/plugins/ifcfg-suse/Makefile.am (original)
+++ trunk/system-settings/plugins/ifcfg-suse/Makefile.am Thu May 8 07:20:02 2008
@@ -2,6 +2,8 @@
pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-suse.la
libnm_settings_plugin_ifcfg_suse_la_SOURCES = \
+ nm-suse-connection.c \
+ nm-suse-connection.h \
shvar.c \
shvar.h \
parser.c \
@@ -17,7 +19,7 @@
-I${top_srcdir}/system-settings/src \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-util \
- -I${top_srcdir}/libnm-glib \
+ -I$(top_srcdir)/libnm-glib \
-DSYSCONFDIR=\"$(sysconfdir)\"
libnm_settings_plugin_ifcfg_suse_la_LDFLAGS = -module -avoid-version
Added: trunk/system-settings/plugins/ifcfg-suse/nm-suse-connection.c
==============================================================================
--- (empty file)
+++ trunk/system-settings/plugins/ifcfg-suse/nm-suse-connection.c Thu May 8 07:20:02 2008
@@ -0,0 +1,144 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#include <string.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+#include <NetworkManager.h>
+#include "nm-suse-connection.h"
+#include "parser.h"
+
+G_DEFINE_TYPE (NMSuseConnection, nm_suse_connection, NM_TYPE_EXPORTED_CONNECTION)
+
+#define NM_SUSE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SUSE_CONNECTION, NMSuseConnectionPrivate))
+
+typedef struct {
+ GFileMonitor *monitor;
+ guint monitor_id;
+
+ const char *iface;
+ NMDeviceType dev_type;
+ char *filename;
+} NMSuseConnectionPrivate;
+
+static void
+file_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ NMExportedConnection *exported = NM_EXPORTED_CONNECTION (user_data);
+ NMSuseConnectionPrivate *priv = NM_SUSE_CONNECTION_GET_PRIVATE (exported);
+ NMConnection *new_connection;
+ GHashTable *new_settings;
+
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ new_connection = parse_ifcfg (priv->iface, priv->dev_type);
+ if (new_connection) {
+ new_settings = nm_connection_to_hash (new_connection);
+ nm_exported_connection_update (exported, new_settings);
+ g_hash_table_destroy (new_settings);
+ g_object_unref (new_connection);
+ } else
+ nm_exported_connection_delete (exported);
+ break;
+ case G_FILE_MONITOR_EVENT_DELETED:
+ nm_exported_connection_delete (exported);
+ break;
+ default:
+ break;
+ }
+}
+
+NMSuseConnection *
+nm_suse_connection_new (const char *iface, NMDeviceType dev_type)
+{
+ NMConnection *connection;
+ GFile *file;
+ GFileMonitor *monitor;
+ NMSuseConnection *exported;
+ NMSuseConnectionPrivate *priv;
+
+ g_return_val_if_fail (iface != NULL, NULL);
+
+ connection = parse_ifcfg (iface, dev_type);
+ if (!connection)
+ return NULL;
+
+ exported = (NMSuseConnection *) g_object_new (NM_TYPE_SUSE_CONNECTION,
+ NM_EXPORTED_CONNECTION_CONNECTION, connection,
+ NULL);
+ g_object_unref (connection);
+ if (!exported)
+ return NULL;
+
+ priv = NM_SUSE_CONNECTION_GET_PRIVATE (exported);
+
+ priv->iface = g_strdup (iface);
+ priv->dev_type = dev_type;
+ priv->filename = g_strdup_printf (SYSCONFDIR "/sysconfig/network/ifcfg-%s", iface);
+
+ file = g_file_new_for_path (priv->filename);
+ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+
+ if (monitor) {
+ priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), exported);
+ priv->monitor = monitor;
+ }
+
+ return exported;
+}
+
+static GHashTable *
+get_settings (NMExportedConnection *exported)
+{
+ return nm_connection_to_hash (nm_exported_connection_get_connection (exported));
+}
+
+static const char *
+get_id (NMExportedConnection *exported)
+{
+ return NM_SUSE_CONNECTION_GET_PRIVATE (exported)->filename;
+}
+
+/* GObject */
+
+static void
+nm_suse_connection_init (NMSuseConnection *connection)
+{
+}
+
+static void
+finalize (GObject *object)
+{
+ NMSuseConnectionPrivate *priv = NM_SUSE_CONNECTION_GET_PRIVATE (object);
+
+ if (priv->monitor) {
+ if (priv->monitor_id)
+ g_signal_handler_disconnect (priv->monitor, priv->monitor_id);
+
+ g_file_monitor_cancel (priv->monitor);
+ g_object_unref (priv->monitor);
+ }
+
+ g_free (priv->filename);
+
+ G_OBJECT_CLASS (nm_suse_connection_parent_class)->finalize (object);
+}
+
+static void
+nm_suse_connection_class_init (NMSuseConnectionClass *suse_connection_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (suse_connection_class);
+ NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (suse_connection_class);
+
+ g_type_class_add_private (suse_connection_class, sizeof (NMSuseConnectionPrivate));
+
+ /* Virtual methods */
+ object_class->finalize = finalize;
+
+ connection_class->get_settings = get_settings;
+ connection_class->get_id = get_id;
+}
Added: trunk/system-settings/plugins/ifcfg-suse/nm-suse-connection.h
==============================================================================
--- (empty file)
+++ trunk/system-settings/plugins/ifcfg-suse/nm-suse-connection.h Thu May 8 07:20:02 2008
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#ifndef NM_SUSE_CONNECTION_H
+#define NM_SUSE_CONNECTION_H
+
+#include <NetworkManager.h>
+#include <nm-settings.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_SUSE_CONNECTION (nm_suse_connection_get_type ())
+#define NM_SUSE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUSE_CONNECTION, NMSuseConnection))
+#define NM_SUSE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUSE_CONNECTION, NMSuseConnectionClass))
+#define NM_IS_SUSE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SUSE_CONNECTION))
+#define NM_IS_SUSE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SUSE_CONNECTION))
+#define NM_SUSE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUSE_CONNECTION, NMSuseConnectionClass))
+
+typedef struct {
+ NMExportedConnection parent;
+} NMSuseConnection;
+
+typedef struct {
+ NMExportedConnectionClass parent;
+} NMSuseConnectionClass;
+
+GType nm_suse_connection_get_type (void);
+
+NMSuseConnection *nm_suse_connection_new (const char *iface,
+ NMDeviceType dev_type);
+
+G_END_DECLS
+
+#endif /* NM_SUSE_CONNECTION_H */
Modified: trunk/system-settings/plugins/ifcfg-suse/parser.c
==============================================================================
--- trunk/system-settings/plugins/ifcfg-suse/parser.c (original)
+++ trunk/system-settings/plugins/ifcfg-suse/parser.c Thu May 8 07:20:02 2008
@@ -38,12 +38,17 @@
#include <nm-setting-ip4-config.h>
#include <nm-setting-wired.h>
#include <nm-setting-wireless.h>
+#include <nm-setting-8021x.h>
#include <nm-utils.h>
#include "shvar.h"
#include "parser.h"
#include "plugin.h"
+#include "sha1.h"
+#define WPA_PMK_LEN 32
+
+/* Common */
static gboolean
get_int (const char *str, int *value)
@@ -57,81 +62,37 @@
return TRUE;
}
-#if 0
-static gboolean
-read_startmode (shvarFile *file)
-{
- char *value;
- gboolean automatic = TRUE;
-
- value = svGetValue (file, "STARTMODE");
- if (value) {
- if (!g_ascii_strcasecmp (value, "manual"))
- automatic = FALSE;
- else if (!g_ascii_strcasecmp (value, "off")) {
- // FIXME: actually ignore the device, not the connection
- g_message ("Ignoring connection '%s' because NM_CONTROLLED was false", file);
- automatic = FALSE;
- }
-
- g_free (value);
- }
-
- return automatic;
-}
-#endif
-
static NMSetting *
-make_connection_setting (const char *file,
- shvarFile *ifcfg,
+make_connection_setting (shvarFile *file,
+ const char *iface,
const char *type,
const char *suggested)
{
NMSettingConnection *s_con;
- char *basename = NULL;
- int len;
- char *ifcfg_name;
-
- basename = g_path_get_basename (file);
- if (!basename)
- goto error;
- len = strlen (basename);
-
- if (len < strlen (IFCFG_TAG) + 1)
- goto error;
-
- if (strncmp (basename, IFCFG_TAG, strlen (IFCFG_TAG)))
- goto error;
-
- /* ignore .bak files */
- if ((len > 4) && !strcmp (basename + len - 4, BAK_TAG))
- goto error;
+ char *str;
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
-
- ifcfg_name = (char *) (basename + strlen (IFCFG_TAG));
-
if (suggested) {
/* For cosmetic reasons, if the suggested name is the same as
* the ifcfg files name, don't use it.
*/
- if (strcmp (ifcfg_name, suggested)) {
- s_con->id = g_strdup_printf ("System %s (%s)", suggested, ifcfg_name);
- ifcfg_name = NULL;
- }
+ if (strcmp (iface, suggested))
+ s_con->id = g_strdup_printf ("System %s (%s)", suggested, iface);
}
- if (ifcfg_name)
- s_con->id = g_strdup_printf ("System %s", ifcfg_name);
+ if (!s_con->id)
+ s_con->id = g_strdup_printf ("System %s", iface);
s_con->type = g_strdup (type);
- s_con->autoconnect = TRUE;
- return (NMSetting *) s_con;
+ str = svGetValue (file, "STARTMODE");
+ if (str && !g_ascii_strcasecmp (str, "manual"))
+ s_con->autoconnect = FALSE;
+ else
+ s_con->autoconnect = TRUE;
+ g_free (str);
-error:
- g_free (basename);
- return NULL;
+ return (NMSetting *) s_con;
}
static guint32
@@ -150,70 +111,73 @@
}
static NMSetting *
-make_ip4_setting (shvarFile *ifcfg, GError **error)
+make_ip4_setting (shvarFile *ifcfg)
{
- NMSettingIP4Config *s_ip4 = NULL;
- char *value = NULL;
+ NMSettingIP4Config *s_ip4;
+ char *str;
NMSettingIP4Address tmp = { 0, 0, 0 };
- char *method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
- value = svGetValue (ifcfg, "BOOTPROTO");
- if (!value)
- return NULL;
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
- if (!g_ascii_strcasecmp (value, "bootp") || !g_ascii_strcasecmp (value, "dhcp")) {
- method = NM_SETTING_IP4_CONFIG_METHOD_DHCP;
- return NULL;
+ str = svGetValue (ifcfg, "BOOTPROTO");
+ if (str) {
+ if (!g_ascii_strcasecmp (str, "bootp") || !g_ascii_strcasecmp (str, "dhcp"))
+ s_ip4->method = g_strdup (NM_SETTING_IP4_CONFIG_METHOD_DHCP);
+ else if (!g_ascii_strcasecmp (str, "static"))
+ s_ip4->method = g_strdup (NM_SETTING_IP4_CONFIG_METHOD_MANUAL);
+ else if (!g_ascii_strcasecmp (str, "autoip"))
+ s_ip4->method = g_strdup (NM_SETTING_IP4_CONFIG_METHOD_AUTOIP);
+
+ g_free (str);
}
- value = svGetValue (ifcfg, "IPADDR");
- if (value) {
+ if (!s_ip4->method)
+ s_ip4->method = g_strdup (NM_SETTING_IP4_CONFIG_METHOD_DHCP);
+
+ str = svGetValue (ifcfg, "IPADDR");
+ if (str) {
char **pieces;
struct in_addr ip4_addr;
- pieces = g_strsplit (value, "/", 2);
+ pieces = g_strsplit (str, "/", 2);
- if (inet_pton (AF_INET, pieces[0], &ip4_addr))
+ if (inet_pton (AF_INET, pieces[0], &ip4_addr)) {
tmp.address = ip4_addr.s_addr;
- else {
- g_strfreev (pieces);
- g_set_error (error, ifcfg_plugin_error_quark (), 0, "Invalid IP4 address '%s'", value);
- goto error;
- }
- if (g_strv_length (pieces) == 2)
- tmp.netmask = ip4_prefix_to_netmask (atoi (pieces[1]));
+ if (g_strv_length (pieces) == 2)
+ tmp.netmask = ip4_prefix_to_netmask (atoi (pieces[1]));
+ } else
+ g_warning ("Ignoring invalid IP4 address '%s'", str);
g_strfreev (pieces);
- g_free (value);
+ g_free (str);
}
- if (tmp.netmask == 0) {
- value = svGetValue (ifcfg, "PREFIXLEN");
- if (value) {
- tmp.netmask = ip4_prefix_to_netmask (atoi (value));
- g_free (value);
+ if (tmp.address && tmp.netmask == 0) {
+ str = svGetValue (ifcfg, "PREFIXLEN");
+ if (str) {
+ tmp.netmask = ip4_prefix_to_netmask (atoi (str));
+ g_free (str);
}
}
- if (tmp.netmask == 0) {
- value = svGetValue (ifcfg, "NETMASK");
- if (value) {
+ if (tmp.address && tmp.netmask == 0) {
+ str = svGetValue (ifcfg, "NETMASK");
+ if (str) {
struct in_addr mask_addr;
- if (inet_pton (AF_INET, value, &mask_addr))
+ if (inet_pton (AF_INET, str, &mask_addr))
tmp.netmask = mask_addr.s_addr;
else {
- g_set_error (error, ifcfg_plugin_error_quark (), 0, "Invalid IP4 netmask '%s'", value);
- goto error;
+ g_warning ("Ignoring invalid IP4 addres: invalid netmask: '%s'", str);
+ tmp.address = 0;
+ tmp.netmask = 0;
}
- g_free (value);
+ g_free (str);
}
}
- s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
- s_ip4->method = g_strdup (method);
- if (tmp.address || tmp.netmask || tmp.gateway) {
+ if (tmp.address || tmp.netmask) {
NMSettingIP4Address *addr;
addr = g_new0 (NMSettingIP4Address, 1);
memcpy (addr, &tmp, sizeof (NMSettingIP4Address));
@@ -221,48 +185,51 @@
}
return NM_SETTING (s_ip4);
-
-error:
- g_free (value);
- if (s_ip4)
- g_object_unref (s_ip4);
- return NULL;
}
-#if 0
-/*
- * utils_bin2hexstr
- *
- * Convert a byte-array into a hexadecimal string.
- *
- * Code originally by Alex Larsson <alexl redhat com> and
- * copyright Red Hat, Inc. under terms of the LGPL.
- *
- */
-static char *
-utils_bin2hexstr (const char *bytes, int len, int final_len)
+/* Ethernet */
+
+static NMSetting *
+make_wired_setting (shvarFile *ifcfg)
{
- static char hex_digits[] = "0123456789abcdef";
- char * result;
- int i;
+ NMSettingWired *s_wired;
+ char *str;
+ int mtu;
- g_return_val_if_fail (bytes != NULL, NULL);
- g_return_val_if_fail (len > 0, NULL);
- g_return_val_if_fail (len < 256, NULL); /* Arbitrary limit */
+ s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
- result = g_malloc0 (len * 2 + 1);
- for (i = 0; i < len; i++)
- {
- result[2*i] = hex_digits[(bytes[i] >> 4) & 0xf];
- result[2*i+1] = hex_digits[bytes[i] & 0xf];
+ str = svGetValue (ifcfg, "MTU");
+ if (str) {
+ if (strlen (str) < 1)
+ /* Ignore empty MTU */
+ ;
+ else if (get_int (str, &mtu)) {
+ if (mtu >= 0 && mtu < G_MAXINT)
+ s_wired->mtu = mtu;
+ } else
+ g_warning ("Ignoring invalid MTU: '%s'", str);
+ g_free (str);
}
- /* Cut converted key off at the correct length for this cipher type */
- if (final_len > -1)
- result[final_len] = '\0';
- return result;
+ return (NMSetting *) s_wired;
}
-#endif
+
+static void
+parse_ethernet (NMConnection *connection, shvarFile *file, const char *iface)
+{
+ NMSetting *setting;
+
+ setting = make_connection_setting (file, iface, NM_SETTING_WIRED_SETTING_NAME, NULL);
+ nm_connection_add_setting (connection, setting);
+
+ setting = make_wired_setting (file);
+ nm_connection_add_setting (connection, setting);
+
+ setting = make_ip4_setting (file);
+ nm_connection_add_setting (connection, setting);
+}
+
+/* Wireless */
static char *
get_one_wep_key (shvarFile *ifcfg, guint8 idx, GError **err)
@@ -342,23 +309,23 @@
#define READ_WEP_KEY(idx) \
{ \
- char *key = get_one_wep_key (ifcfg, idx, err); \
- if (*err) \
+ char *key = get_one_wep_key (ifcfg, idx, &err); \
+ if (err) \
goto error; \
if (key) { \
- g_object_set_data_full (G_OBJECT (security), \
- NM_SETTING_WIRELESS_SECURITY_WEP_KEY##idx, \
- key, \
- g_free); \
+ g_object_set (G_OBJECT (security), \
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY##idx, \
+ key, \
+ NULL); \
have_key = TRUE; \
} \
}
-
static void
-read_wep_settings (shvarFile *ifcfg, NMSettingWirelessSecurity *security, GError **err)
+read_wep_settings (shvarFile *ifcfg, NMSettingWirelessSecurity *security)
{
char *value;
+ GError *err = NULL;
gboolean have_key = FALSE;
READ_WEP_KEY(0)
@@ -378,13 +345,16 @@
if (success && (key_idx >= 0) && (key_idx <= 3))
security->wep_tx_keyidx = key_idx;
else
- g_set_error (err, ifcfg_plugin_error_quark (), 0, "Invalid defualt WEP key '%s'", value);
+ g_warning ("Invalid default WEP key: '%s'", value);
g_free (value);
}
error:
- return;
+ if (err) {
+ g_warning ("%s", err->message);
+ g_error_free (err);
+ }
}
/* Copied from applet/src/wireless-secuirty/wireless-security.c */
@@ -406,384 +376,320 @@
s_wireless_sec->group = g_slist_append (s_wireless_sec->group, g_strdup ("ccmp"));
}
+/*
+ * utils_bin2hexstr
+ *
+ * Convert a byte-array into a hexadecimal string.
+ *
+ * Code originally by Alex Larsson <alexl redhat com> and
+ * copyright Red Hat, Inc. under terms of the LGPL.
+ *
+ */
+static char *
+utils_bin2hexstr (const char *bytes, int len, int final_len)
+{
+ static char hex_digits[] = "0123456789abcdef";
+ char * result;
+ int i;
+
+ g_return_val_if_fail (bytes != NULL, NULL);
+ g_return_val_if_fail (len > 0, NULL);
+ g_return_val_if_fail (len < 256, NULL); /* Arbitrary limit */
+
+ result = g_malloc0 (len * 2 + 1);
+ for (i = 0; i < len; i++)
+ {
+ result[2*i] = hex_digits[(bytes[i] >> 4) & 0xf];
+ result[2*i+1] = hex_digits[bytes[i] & 0xf];
+ }
+ /* Cut converted key off at the correct length for this cipher type */
+ if (final_len > -1)
+ result[final_len] = '\0';
+
+ return result;
+}
+
static void
-read_wpa_psk_settings (shvarFile *ifcfg, NMSettingWirelessSecurity *security, GError **err)
+read_wpa_psk_settings (shvarFile *ifcfg,
+ NMSettingWirelessSecurity *security,
+ NMSettingWireless *s_wireless)
{
char *value;
value = svGetValue (ifcfg, "WIRELESS_WPA_PSK");
if (value) {
if (strlen (value) == 64) {
- /* HEX key */
- security->psk = value;
+ /* Hex PSK */
+ security->psk = g_strdup (value);
} else {
/* passphrase */
-
- /* FIXME: */
-/* unsigned char *buf = g_malloc0 (WPA_PMK_LEN * 2); */
-/* pbkdf2_sha1 (value, (char *) s_wireless->ssid->data, s_wireless->ssid->len, 4096, buf, WPA_PMK_LEN); */
-/* security->psk = utils_bin2hexstr ((const char *) buf, WPA_PMK_LEN, WPA_PMK_LEN * 2); */
-/* g_free (buf); */
- g_free (value);
+ unsigned char *buf = g_malloc0 (WPA_PMK_LEN * 2);
+ pbkdf2_sha1 (value, (char *) s_wireless->ssid->data, s_wireless->ssid->len, 4096, buf, WPA_PMK_LEN);
+ security->psk = utils_bin2hexstr ((const char *) buf, WPA_PMK_LEN, WPA_PMK_LEN * 2);
+ g_free (buf);
}
+ g_free (value);
+
ws_wpa_fill_default_ciphers (security);
} else
- g_set_error (err, ifcfg_plugin_error_quark (), 0, "Missing WPA-PSK key.");
+ g_warning ("Missing WPA-PSK key");
}
#if 0
+
static void
-read_wpa_eap_settings (shvarFile *ifcfg, NMSettingWirelessSecurity *security, GError **err)
+read_wpa_eap_settings (shvarFile *ifcfg, NMSettingWirelessSecurity *security)
{
- char *value;
+ char *str;
- value = svGetValue (ifcfg, "WIRELESS_EAP_AUTH");
- if (value) {
- /* valid values are TLS PEAP TTLS */
- security->eap = g_slist_append (NULL, value);
- }
+ str = svGetValue (ifcfg, "WIRELESS_EAP_MODE");
+ if (str) {
+ char **pieces;
+ int i;
- value = svGetValue (ifcfg, "WIRELESS_WPA_PROTO");
- if (value) {
- /* valid values are WPA RSN (WPA2) */
- security->proto = g_slist_append (NULL, value);
+ pieces = g_strsplit (str, " ", 0);
+ for (i = 0; pieces[i]; i++)
+ s_8021x->eap = g_slist_append (s_8021x->eap, pieces[i]);
+
+ g_free (pieces);
+ g_free (str);
}
- security->identity = svGetValue (ifcfg, "WIRELESS_WPA_IDENTITY");
+ s_802_1x->anonymous_identity = svGetValue (ifcfg, "WIRELESS_WPA_ANONID");
- /* FIXME: This should be in get_secrets? */
- value = svGetValue (ifcfg, "WIRELESS_WPA_PASSWORD");
- if (value) {
- g_free (value);
- }
+ char *ca_path;
- security->anonymous_identity = svGetValue (ifcfg, "WIRELESS_WPA_ANONID");
+ GByteArray *ca_cert;
+ "WIRELESS_CA_CERT";
- value = svGetValue (ifcfg, "WIRELESS_CA_CERT");
- if (value) {
- g_free (value);
- }
+ GByteArray *client_cert;
+ "WIRELESS_CLIENT_CERT";
- value = svGetValue (ifcfg, "WIRELESS_CLIENT_CERT");
- if (value) {
- g_free (value);
- }
+ GByteArray *private_key;
+ "WIRELESS_CLIENT_KEY";
- /* FIXME: This should be in get_secrets? */
- value = svGetValue (ifcfg, "WIRELESS_CLIENT_KEY");
- if (value) {
- g_free (value);
- }
+ private_key_passwd
+ "WIRELESS_CLIENT_KEY_PASSWORD";
- /* FIXME: This should be in get_secrets? */
- value = svGetValue (ifcfg, "WIRELESS_CLIENT_KEY_PASSWORD");
- if (value) {
- g_free (value);
- }
- ws_wpa_fill_default_ciphers (security);
+ s_802_1x->phase1_peapver = svGetValue (ifcfg, "WIRELESS_PEAP_VERSION");
+ s_802_1x->phase2_auth = svGetValue (ifcfg, "WIRELESS_EAP_AUTH");
+ s_802_1x->identity = svGetValue (ifcfg, "WIRELESS_WPA_IDENTITY");
+ s_802_1x->password = svGetValue (ifcfg, "WIRELESS_WPA_PASSWORD");
}
#endif
static NMSetting *
-make_wireless_security_setting (shvarFile *ifcfg, GError **err)
+make_wireless_security_setting (shvarFile *ifcfg, NMSettingWireless *s_wireless)
{
- NMSettingWirelessSecurity *s_wireless_sec = NULL;
- char *value;
-
- value = svGetValue (ifcfg, "WIRELESS_AUTH_MODE");
- if (!value)
- return NULL;
+ NMSettingWirelessSecurity *security;
+ char *str;
- if (!g_ascii_strcasecmp (value, "no-encryption")) {
- g_free (value);
+ str = svGetValue (ifcfg, "WIRELESS_AUTH_MODE");
+ if (!str || !g_ascii_strcasecmp (str, "no-encryption")) {
+ g_free (str);
return NULL;
}
- s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
+ security = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
- if (!g_ascii_strcasecmp (value, "open")) {
- s_wireless_sec->auth_alg = g_strdup ("open");
- read_wep_settings (ifcfg, s_wireless_sec, err);
- } else if (!g_ascii_strcasecmp (value, "sharedkey")) {
- s_wireless_sec->auth_alg = g_strdup ("shared");
- read_wep_settings (ifcfg, s_wireless_sec, err);
- }
-
- else if (!g_ascii_strcasecmp (value, "psk")) {
- s_wireless_sec->key_mgmt = g_strdup ("wpa-psk");
- read_wpa_psk_settings (ifcfg, s_wireless_sec, err);
- } else if (!g_ascii_strcasecmp (value, "eap")) {
- s_wireless_sec->key_mgmt = g_strdup ("wps-eap");
- /* read_wpa_eap_settings (ifcfg, s_wireless_sec, err); */
+ if (!g_ascii_strcasecmp (str, "open")) {
+ security->auth_alg = g_strdup ("open");
+ read_wep_settings (ifcfg, security);
+ } else if (!g_ascii_strcasecmp (str, "sharedkey")) {
+ security->auth_alg = g_strdup ("shared");
+ read_wep_settings (ifcfg, security);
+ }
+
+ else if (!g_ascii_strcasecmp (str, "psk")) {
+ security->key_mgmt = g_strdup ("wpa-psk");
+ read_wpa_psk_settings (ifcfg, security, s_wireless);
+ } else if (!g_ascii_strcasecmp (str, "eap")) {
+ /* FIXME */
+/* security->key_mgmt = g_strdup ("wps-eap"); */
+/* read_wpa_eap_settings (ifcfg, security); */
+ g_warning ("WPA-EAP is currently not supported.");
+ g_object_unref (security);
+ security = NULL;
} else
- g_set_error (err, ifcfg_plugin_error_quark (), 0, "Invalid authentication algoritm '%s'", value);
-
- g_free (value);
+ g_warning ("Invalid authentication algorithm: '%s'", str);
- if (*err == NULL)
- return NM_SETTING (s_wireless_sec);
+ g_free (str);
- if (s_wireless_sec)
- g_object_unref (s_wireless_sec);
- return NULL;
+ return (NMSetting *) security;
}
static NMSetting *
-make_wireless_setting (shvarFile *ifcfg,
- NMSetting *security,
- GError **err)
+make_wireless_setting (shvarFile *ifcfg)
{
NMSettingWireless *s_wireless;
- char *value;
+ char *str;
s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
- value = svGetValue (ifcfg, "WIRELESS_ESSID");
- if (value) {
- gsize len = strlen (value);
-
- if (len > 32 || len == 0) {
- g_set_error (err, ifcfg_plugin_error_quark (), 0,
- "Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)",
- value, len);
- goto error;
- }
-
- s_wireless->ssid = g_byte_array_sized_new (strlen (value));
- g_byte_array_append (s_wireless->ssid, (const guint8 *) value, len);
- g_free (value);
- }
-
- value = svGetValue (ifcfg, "WIRLESS_MODE");
- if (value) {
- if (!g_ascii_strcasecmp (value, "ad-hoc")) {
+ str = svGetValue (ifcfg, "WIRELESS_ESSID");
+ if (str) {
+ gsize len = strlen (str);
+
+ if (len > 0 && len <= 32) {
+ s_wireless->ssid = g_byte_array_sized_new (len);
+ g_byte_array_append (s_wireless->ssid, (const guint8 *) str, len);
+ } else
+ g_warning ("Ignoring invalid ESSID '%s', (size %zu not between 1 and 32 inclusive)", str, len);
+
+ g_free (str);
+ }
+
+ str = svGetValue (ifcfg, "WIRLESS_MODE");
+ if (str) {
+ if (!g_ascii_strcasecmp (str, "ad-hoc"))
s_wireless->mode = g_strdup ("adhoc");
- } else if (!g_ascii_strcasecmp (value, "managed")) {
+ else if (!g_ascii_strcasecmp (str, "managed"))
s_wireless->mode = g_strdup ("infrastructure");
- } else {
- g_set_error (err, ifcfg_plugin_error_quark (), 0,
- "Invalid mode '%s' (not ad-hoc or managed)", value);
- g_free (value);
- goto error;
- }
- g_free (value);
- }
- if (security)
- s_wireless->security = g_strdup (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ g_free (str);
+ }
// FIXME: channel/freq, other L2 parameters like RTS
return NM_SETTING (s_wireless);
-
-error:
- if (s_wireless)
- g_object_unref (s_wireless);
- return NULL;
}
-static NMConnection *
-wireless_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **err)
-{
- NMConnection *connection = NULL;
- NMSetting *con_setting = NULL;
- NMSetting *wireless_setting = NULL;
- NMSettingWireless *tmp;
- NMSetting *security_setting = NULL;
+static char *
+get_printable_ssid (NMSetting *setting)
+{
+ NMSettingWireless *s_wireless = NM_SETTING_WIRELESS (setting);
char *printable_ssid = NULL;
- connection = nm_connection_new ();
- if (!connection) {
- g_set_error (err, ifcfg_plugin_error_quark (), 0,
- "Failed to allocate new connection for %s.", file);
- return NULL;
- }
+ if (s_wireless->ssid)
+ printable_ssid = nm_utils_ssid_to_utf8 ((const char *) s_wireless->ssid->data,
+ (guint32) s_wireless->ssid->len);
- /* Wireless security */
- security_setting = make_wireless_security_setting (ifcfg, err);
- if (*err)
- goto error;
- if (security_setting)
- nm_connection_add_setting (connection, security_setting);
-
- /* Wireless */
- wireless_setting = make_wireless_setting (ifcfg, security_setting, err);
- if (!wireless_setting)
- goto error;
-
- nm_connection_add_setting (connection, wireless_setting);
-
- tmp = NM_SETTING_WIRELESS (wireless_setting);
- printable_ssid = nm_utils_ssid_to_utf8 ((const char *) tmp->ssid->data,
- (guint32) tmp->ssid->len);
-
- con_setting = make_connection_setting (file, ifcfg,
- NM_SETTING_WIRELESS_SETTING_NAME,
- printable_ssid);
- g_free (printable_ssid);
+ return printable_ssid;
+}
- if (!con_setting) {
- g_set_error (err, ifcfg_plugin_error_quark (), 0,
- "Failed to create connection setting.");
- goto error;
- }
- nm_connection_add_setting (connection, con_setting);
+static void
+parse_wireless (NMConnection *connection, shvarFile *file, const char *iface)
+{
+ NMSetting *setting;
+ NMSetting *security;
+ char *printable_ssid;
+
+ setting = make_wireless_setting (file);
+ nm_connection_add_setting (connection, setting);
+
+ security = make_wireless_security_setting (file, NM_SETTING_WIRELESS (setting));
+ if (security) {
+ const char *security_str;
+
+ if (NM_IS_SETTING_802_1X (security))
+ security_str = NM_SETTING_802_1X_SETTING_NAME;
+ else if (NM_IS_SETTING_WIRELESS_SECURITY (security))
+ security_str = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
+ else {
+ security_str = NULL;
+ g_warning ("Invalid security type: '%s'", G_OBJECT_TYPE_NAME (security));
+ }
- if (!nm_connection_verify (connection)) {
- g_set_error (err, ifcfg_plugin_error_quark (), 0,
- "Connection from %s was invalid.", file);
- goto error;
+ g_object_set (G_OBJECT (setting), NM_SETTING_WIRELESS_SEC, security_str, NULL);
+ nm_connection_add_setting (connection, security);
}
- return connection;
+ printable_ssid = get_printable_ssid (setting);
+ setting = make_connection_setting (file, iface, NM_SETTING_WIRELESS_SETTING_NAME, printable_ssid);
+ nm_connection_add_setting (connection, setting);
+ g_free (printable_ssid);
-error:
- g_object_unref (connection);
- if (con_setting)
- g_object_unref (con_setting);
- if (wireless_setting)
- g_object_unref (wireless_setting);
- return NULL;
+ setting = make_ip4_setting (file);
+ nm_connection_add_setting (connection, setting);
}
-static NMSetting *
-make_wired_setting (shvarFile *ifcfg, GError **err)
+static shvarFile *
+parser_get_ifcfg_for_iface (const char *iface)
{
- NMSettingWired *s_wired;
- char *value;
- int mtu;
+ char *filename;
+ shvarFile *file = NULL;
- s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
+ filename = g_strdup_printf (SYSCONFDIR "/sysconfig/network/ifcfg-%s", iface);
+ if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
+ file = svNewFile (filename);
- value = svGetValue (ifcfg, "MTU");
- if (value) {
- if (strlen (value) < 1)
- /* Ignore empty MTU */
- ;
- else if (get_int (value, &mtu)) {
- if (mtu >= 0 && mtu < 65536)
- s_wired->mtu = mtu;
- } else {
- g_set_error (err, ifcfg_plugin_error_quark (), 0, "Invalid MTU '%s'", value);
- g_object_unref (s_wired);
- s_wired = NULL;
- }
- g_free (value);
- }
+ g_free (filename);
- return (NMSetting *) s_wired;
+ return file;
}
-static NMConnection *
-wired_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **err)
+NMConnection *
+parse_ifcfg (const char *iface, NMDeviceType type)
{
- NMConnection *connection = NULL;
- NMSetting *con_setting = NULL;
- NMSetting *wired_setting = NULL;
+ shvarFile *file;
+ NMConnection *connection;
+
+ g_return_val_if_fail (iface != NULL, NULL);
+
+ file = parser_get_ifcfg_for_iface (iface);
+ if (!file)
+ return NULL;
connection = nm_connection_new ();
- con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL);
- if (!con_setting) {
- g_set_error (err, ifcfg_plugin_error_quark (), 0,
- "Failed to create connection setting.");
- goto error;
- }
- nm_connection_add_setting (connection, con_setting);
-
- wired_setting = make_wired_setting (ifcfg, err);
- if (!wired_setting)
- goto error;
- nm_connection_add_setting (connection, wired_setting);
+ switch (type) {
+ case DEVICE_TYPE_802_3_ETHERNET:
+ parse_ethernet (connection, file, iface);
+ break;
+ case DEVICE_TYPE_802_11_WIRELESS:
+ parse_wireless (connection, file, iface);
+ break;
+ default:
+ break;
+ }
+
+ svCloseFile (file);
if (!nm_connection_verify (connection)) {
- g_set_error (err, ifcfg_plugin_error_quark (), 0,
- "Connection from %s was invalid.", file);
- goto error;
+ g_object_unref (connection);
+ connection = NULL;
}
return connection;
-
-error:
- g_object_unref (connection);
- if (con_setting)
- g_object_unref (con_setting);
- if (wired_setting)
- g_object_unref (wired_setting);
- return NULL;
}
-
-NMConnection *
-parser_parse_ifcfg (const char *file, GError **err)
+
+gboolean
+parser_ignore_device (const char *iface)
{
- NMConnection *connection = NULL;
- shvarFile *parsed;
- char *type;
- char *nmc = NULL;
- NMSetting *s_ip4;
-
- g_return_val_if_fail (file != NULL, NULL);
-
- parsed = svNewFile (file);
- if (!parsed) {
- g_set_error (err, ifcfg_plugin_error_quark (), 0,
- "Couldn't parse file '%s'", file);
- return NULL;
- }
+ shvarFile *file;
+ gboolean ignore = FALSE;
- nmc = svGetValue (parsed, "NM_CONTROLLED");
- if (nmc) {
- if (!svTrueValue (parsed, nmc, 1)) {
- g_free (nmc);
- // FIXME: actually ignore the device, not the connection
- g_message ("Ignoring connection '%s' because NM_CONTROLLED was false", file);
- goto done;
- }
- g_free (nmc);
- }
-
- type = svGetValue (parsed, "WIRELESS_ESSID");
- if (type) {
- g_free (type);
- connection = wireless_connection_from_ifcfg (file, parsed, err);
- } else
- connection = wired_connection_from_ifcfg (file, parsed, err);
+ file = parser_get_ifcfg_for_iface (iface);
+ if (file) {
+ char *str;
- if (!connection)
- goto done;
+ if (!svTrueValue (file, "NM_CONTROLLED", 1))
+ ignore = TRUE;
- s_ip4 = make_ip4_setting (parsed, err);
- if (*err) {
- g_object_unref (connection);
- connection = NULL;
- goto done;
- } else if (s_ip4) {
- nm_connection_add_setting (connection, s_ip4);
- }
+ str = svGetValue (file, "STARTMODE");
+ if (str && !g_ascii_strcasecmp (str, "off"))
+ ignore = TRUE;
+ g_free (str);
- if (!nm_connection_verify (connection)) {
- g_object_unref (connection);
- connection = NULL;
- g_set_error (err, ifcfg_plugin_error_quark (), 0,
- "Connection was invalid");
+ svCloseFile (file);
}
-done:
- svCloseFile (parsed);
- return connection;
+ return ignore;
}
guint32
-parser_parse_routes (const char *file, GError **err)
+parser_parse_routes (const char *filename)
{
FILE *f;
char *buf;
char buffer[512];
guint route = 0;
- if ((f = fopen (SYSCONFDIR"/sysconfig/network/routes", "r"))) {
+ g_return_val_if_fail (filename != NULL, 0);
+
+ if ((f = fopen (filename, "r"))) {
while (fgets (buffer, 512, f) && !feof (f)) {
buf = strtok (buffer, " ");
if (strcmp (buf, "default") == 0) {
Modified: trunk/system-settings/plugins/ifcfg-suse/parser.h
==============================================================================
--- trunk/system-settings/plugins/ifcfg-suse/parser.h (original)
+++ trunk/system-settings/plugins/ifcfg-suse/parser.h Thu May 8 07:20:02 2008
@@ -23,13 +23,15 @@
#define _PARSER_H_
#include <glib.h>
+#include <NetworkManager.h>
#include <nm-connection.h>
#define IFCFG_TAG "ifcfg-"
#define BAK_TAG ".bak"
-NMConnection * parser_parse_ifcfg (const char *file, GError **error);
-guint32 parser_parse_routes (const char *file, GError **err);
+NMConnection *parse_ifcfg (const char *iface, NMDeviceType type);
+gboolean parser_ignore_device (const char *iface);
+guint32 parser_parse_routes (const char *filename);
#endif /* _PARSER_H_ */
Modified: trunk/system-settings/plugins/ifcfg-suse/plugin.c
==============================================================================
--- trunk/system-settings/plugins/ifcfg-suse/plugin.c (original)
+++ trunk/system-settings/plugins/ifcfg-suse/plugin.c Thu May 8 07:20:02 2008
@@ -34,6 +34,7 @@
#include "plugin.h"
#include "parser.h"
+#include "nm-suse-connection.h"
#include "nm-system-config-interface.h"
#define IFCFG_PLUGIN_NAME "ifcfg-suse"
@@ -52,14 +53,18 @@
#define IFCFG_FILE_PATH_TAG "ifcfg-file-path"
typedef struct {
+ DBusGConnection *dbus_connection;
+ NMSystemConfigHalManager *hal_manager;
+
gboolean initialized;
- GSList *connections;
+ GHashTable *connections;
+ GHashTable *unmanaged_devices;
- GFileMonitor *monitor;
- guint monitor_id;
+ guint32 default_gw;
+ GFileMonitor *default_gw_monitor;
+ guint default_gw_monitor_id;
} SCPluginIfcfgPrivate;
-
GQuark
ifcfg_plugin_error_quark (void)
{
@@ -71,118 +76,74 @@
return error_quark;
}
-struct FindInfo {
- const char *path;
- gboolean found;
-};
-
-static gboolean
-is_ifcfg_file (const char *file)
-{
- return g_str_has_prefix (file, IFCFG_TAG) && strcmp (file, IFCFG_TAG "lo");
-}
-
-static NMConnection *
-build_one_connection (const char *ifcfg_file)
+static void
+update_one_connection (gpointer key, gpointer val, gpointer user_data)
{
+ NMExportedConnection *exported = NM_EXPORTED_CONNECTION (val);
NMConnection *connection;
- GError *err = NULL;
+ NMSettingIP4Config *ip4_config;
- PLUGIN_PRINT (PLUGIN_NAME, "parsing %s ... ", ifcfg_file);
-
- connection = parser_parse_ifcfg (ifcfg_file, &err);
- if (connection) {
- NMSettingConnection *s_con;
-
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
- g_assert (s_con);
- g_assert (s_con->id);
- PLUGIN_PRINT (PLUGIN_NAME, " found connection '%s'", s_con->id);
- } else
- PLUGIN_PRINT (PLUGIN_NAME, " error: %s", err->message ? err->message : "(unknown)");
+ connection = nm_exported_connection_get_connection (exported);
+ ip4_config = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+ if (!ip4_config)
+ return;
- return connection;
+ if (ip4_config->addresses) {
+ /* suse only has one address per device */
+ NMSettingIP4Address *ip4_address = (NMSettingIP4Address *) ip4_config->addresses->data;
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (user_data);
+ GHashTable *settings;
+
+ if (ip4_address->gateway != priv->default_gw) {
+ ip4_address->gateway = priv->default_gw;
+ settings = nm_connection_to_hash (connection);
+ nm_exported_connection_signal_updated (exported, settings);
+ g_hash_table_destroy (settings);
+ }
+ }
}
-typedef struct {
- SCPluginIfcfg *plugin;
- NMConnection *connection;
- GFileMonitor *monitor;
- guint monitor_id;
-} ConnectionMonitor;
-
static void
-connection_monitor_destroy (gpointer data)
+update_connections (SCPluginIfcfg *self)
{
- ConnectionMonitor *monitor = (ConnectionMonitor *) data;
-
- g_signal_handler_disconnect (monitor->monitor, monitor->monitor_id);
- g_file_monitor_cancel (monitor->monitor);
- g_object_unref (monitor->monitor);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
- g_free (monitor);
+ g_hash_table_foreach (priv->connections, update_one_connection, self);
}
static void
-connection_file_changed (GFileMonitor *monitor,
- GFile *file,
- GFile *other_file,
- GFileMonitorEvent event_type,
- gpointer user_data)
+routes_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
{
- ConnectionMonitor *cm = (ConnectionMonitor *) user_data;
- gboolean remove_connection = FALSE;
+ SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
+ char *filename;
+ guint32 new_gw;
switch (event_type) {
- case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: {
- NMConnection *new_connection;
- GHashTable *new_settings;
- char *filename;
- char *ifcfg_file;
-
- /* In case anything goes wrong */
- remove_connection = TRUE;
-
- filename = g_file_get_basename (file);
- ifcfg_file = g_build_filename (IFCFG_DIR, filename, NULL);
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ case G_FILE_MONITOR_EVENT_DELETED:
+ filename = g_file_get_path (file);
+ new_gw = parser_parse_routes (filename);
g_free (filename);
- new_connection = build_one_connection (ifcfg_file);
- g_free (ifcfg_file);
-
- if (new_connection) {
- new_settings = nm_connection_to_hash (new_connection);
- if (nm_connection_replace_settings (cm->connection, new_settings)) {
- /* Nothing went wrong */
- remove_connection = FALSE;
- g_signal_emit_by_name (cm->plugin, "connection-updated", cm->connection);
- }
-
- g_object_unref (new_connection);
+ if (priv->default_gw != new_gw) {
+ priv->default_gw = new_gw;
+ update_connections (self);
}
-
- break;
- }
- case G_FILE_MONITOR_EVENT_DELETED:
- remove_connection = TRUE;
break;
default:
break;
}
-
- if (remove_connection) {
- SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (cm->plugin);
-
- priv->connections = g_slist_remove (priv->connections, cm->connection);
- g_signal_emit_by_name (cm->plugin, "connection-removed", cm->connection);
- g_object_unref (cm->connection);
- PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " removed connection");
- }
}
static void
-monitor_connection (NMSystemConfigInterface *config, NMConnection *connection, const char *filename)
+monitor_routes (SCPluginIfcfg *self, const char *filename)
{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
GFile *file;
GFileMonitor *monitor;
@@ -191,170 +152,190 @@
g_object_unref (file);
if (monitor) {
- ConnectionMonitor *cm;
-
- cm = g_new (ConnectionMonitor, 1);
- cm->plugin = SC_PLUGIN_IFCFG (config);
- cm->connection = connection;
- cm->monitor = monitor;
- cm->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (connection_file_changed), cm);
- g_object_set_data_full (G_OBJECT (connection), "file-monitor", cm, connection_monitor_destroy);
+ priv->default_gw_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (routes_changed), self);
+ priv->default_gw_monitor = monitor;
}
}
-static void
-add_one_connection (NMSystemConfigInterface *config, const char *filename, gboolean emit_added)
+static char *
+get_iface_by_udi (SCPluginIfcfg *self, const char *udi)
{
- char *ifcfg_file;
- NMConnection *connection;
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
+ DBusGProxy *proxy;
+ char *iface = NULL;
- if (!is_ifcfg_file (filename))
- return;
-
- ifcfg_file = g_build_filename (IFCFG_DIR, filename, NULL);
- connection = build_one_connection (ifcfg_file);
- if (connection) {
- SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
+ proxy = dbus_g_proxy_new_for_name (priv->dbus_connection,
+ "org.freedesktop.Hal",
+ udi,
+ "org.freedesktop.Hal.Device");
- monitor_connection (config, connection, ifcfg_file);
- priv->connections = g_slist_append (priv->connections, connection);
+ dbus_g_proxy_call_with_timeout (proxy, "GetPropertyString", 10000, NULL,
+ G_TYPE_STRING, "net.interface", G_TYPE_INVALID,
+ G_TYPE_STRING, &iface, G_TYPE_INVALID);
+ g_object_unref (proxy);
- if (emit_added)
- g_signal_emit_by_name (config, "connection-added", connection);
+ return iface;
+}
+
+static void
+read_connection (SCPluginIfcfg *self, const char *udi, NMDeviceType dev_type)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
+ char *iface;
+
+ iface = get_iface_by_udi (self, udi);
+ if (iface) {
+ if (parser_ignore_device (iface)) {
+ g_hash_table_insert (priv->unmanaged_devices, g_strdup (udi), GINT_TO_POINTER (1));
+ g_signal_emit_by_name (self, "unmanaged-devices-changed");
+ } else {
+ NMSuseConnection *connection;
+
+ connection = nm_suse_connection_new (iface, dev_type);
+ if (connection) {
+ g_hash_table_insert (priv->connections, g_strdup (udi), connection);
+ g_signal_emit_by_name (self, "connection-added", connection);
+ }
+ }
}
- g_free (ifcfg_file);
+ g_free (iface);
}
static void
-update_default_routes (NMSystemConfigInterface *config, gboolean emit_updated)
+read_connections_by_type (SCPluginIfcfg *self, NMDeviceType dev_type)
{
- SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
+ GSList *list;
GSList *iter;
- NMConnection *connection;
- NMSettingIP4Config *ip4_setting;
- gboolean got_manual = FALSE;
- guint32 default_route;
-
- /* First, make sure we have any non-DHCP connections */
- for (iter = priv->connections; iter; iter = iter->next) {
- connection = NM_CONNECTION (iter->data);
- ip4_setting = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
- if (ip4_setting && !strcmp (ip4_setting->method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
- got_manual = TRUE;
- break;
- }
+
+ list = nm_system_config_hal_manager_get_devices_of_type (priv->hal_manager, dev_type);
+ for (iter = list; iter; iter = iter->next) {
+ read_connection (self, (char *) iter->data, dev_type);
+ g_free (iter->data);
}
- if (!got_manual)
- return;
+ g_slist_free (list);
+}
+
+static void
+device_added_cb (NMSystemConfigHalManager *hal_mgr,
+ const char *udi,
+ NMDeviceType dev_type,
+ gpointer user_data)
+{
+ SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
- default_route = parser_parse_routes (IFCFG_DIR "/routes", NULL);
- if (!default_route)
+ if (dev_type != DEVICE_TYPE_802_3_ETHERNET && dev_type != DEVICE_TYPE_802_11_WIRELESS)
return;
- for (iter = priv->connections; iter; iter = iter->next) {
- connection = NM_CONNECTION (iter->data);
- ip4_setting = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
- if (ip4_setting && !strcmp (ip4_setting->method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
- GSList *address_iter;
-
- for (address_iter = ip4_setting->addresses; address_iter; address_iter = address_iter->next) {
- NMSettingIP4Address *addr = (NMSettingIP4Address *) address_iter->data;
-
- addr->gateway = default_route;
- if (emit_updated)
- g_signal_emit_by_name (config, "connection-updated", connection);
- }
- }
- }
+ read_connection (self, udi, dev_type);
}
-static GSList *
-get_connections (NMSystemConfigInterface *config)
+static void
+device_removed_cb (NMSystemConfigHalManager *hal_mgr,
+ const char *udi,
+ NMDeviceType dev_type,
+ gpointer user_data)
{
- SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
+ SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
+ NMExportedConnection *exported;
- if (!priv->initialized) {
- GDir *dir;
- const char *item;
- GError *err = NULL;
-
- dir = g_dir_open (IFCFG_DIR, 0, &err);
- if (!dir) {
- PLUGIN_WARN (PLUGIN_NAME, "couldn't access network directory '%s': %s.", IFCFG_DIR, err->message);
- g_error_free (err);
- return NULL;
- }
+ if (dev_type != DEVICE_TYPE_802_3_ETHERNET && dev_type != DEVICE_TYPE_802_11_WIRELESS)
+ return;
- while ((item = g_dir_read_name (dir)))
- add_one_connection (config, item, FALSE);
+ if (g_hash_table_remove (priv->unmanaged_devices, udi))
+ g_signal_emit_by_name (self, "unmanaged-devices-changed");
- g_dir_close (dir);
- priv->initialized = TRUE;
+ exported = (NMExportedConnection *) g_hash_table_lookup (priv->connections, udi);
+ if (exported) {
+ nm_exported_connection_signal_removed (exported);
+ g_hash_table_remove (priv->connections, udi);
}
+}
- if (!priv->connections)
- /* No need to do any futher work, we have nothing. */
- return priv->connections;
+static void
+init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager)
+{
+ SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
- update_default_routes (config, FALSE);
+ priv->hal_manager = g_object_ref (hal_manager);
- return priv->connections;
+ g_signal_connect (priv->hal_manager, "device-added", G_CALLBACK (device_added_cb), self);
+ g_signal_connect (priv->hal_manager, "device-removed", G_CALLBACK (device_removed_cb), self);
}
static void
-ifcfg_dir_changed (GFileMonitor *monitor,
- GFile *file,
- GFile *other_file,
- GFileMonitorEvent event_type,
- gpointer user_data)
+get_connections_cb (gpointer key, gpointer val, gpointer user_data)
+{
+ GSList **list = (GSList **) user_data;
+
+ *list = g_slist_prepend (*list, val);
+}
+
+static GSList *
+get_connections (NMSystemConfigInterface *config)
{
- NMSystemConfigInterface *config = NM_SYSTEM_CONFIG_INTERFACE (user_data);
- char *name;
+ SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
+ GSList *list = NULL;
+
+ if (!priv->initialized) {
+ const char *filename;
+
+ read_connections_by_type (self, DEVICE_TYPE_802_3_ETHERNET);
+ read_connections_by_type (self, DEVICE_TYPE_802_11_WIRELESS);
- name = g_file_get_basename (file);
+ filename = SYSCONFDIR"/sysconfig/network/routes";
+ monitor_routes (self, filename);
+ priv->default_gw = parser_parse_routes (filename);
+ if (priv->default_gw)
+ update_connections (self);
- if (event_type == G_FILE_MONITOR_EVENT_CREATED) {
- add_one_connection (config, name, TRUE);
+ priv->initialized = TRUE;
}
- if (!strcmp (name, "routes"))
- update_default_routes (config, TRUE);
+ g_hash_table_foreach (priv->connections, get_connections_cb, &list);
- g_free (name);
+ return list;
}
static void
-init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager)
+get_unamanged_devices_cb (gpointer key, gpointer val, gpointer user_data)
{
- GFile *file;
- GFileMonitor *monitor;
- SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
+ GSList **list = (GSList **) key;
- file = g_file_new_for_path (IFCFG_DIR);
- monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
- g_object_unref (file);
-
- if (monitor) {
- priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (ifcfg_dir_changed), config);
- priv->monitor = monitor;
- }
+ *list = g_slist_prepend (*list, g_strdup ((char *) val));
}
-static void
-release_one_connection (gpointer item, gpointer user_data)
+static GSList *
+get_unmanaged_devices (NMSystemConfigInterface *config)
{
- NMConnection *connection = NM_CONNECTION (item);
- SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
+ GSList *list = NULL;
- g_signal_emit_by_name (plugin, "connection-removed", connection);
- g_object_unref (connection);
+ g_hash_table_foreach (SC_PLUGIN_IFCFG_GET_PRIVATE (config)->unmanaged_devices,
+ get_unamanged_devices_cb, &list);
+
+ return list;
}
static void
-sc_plugin_ifcfg_init (SCPluginIfcfg *plugin)
+sc_plugin_ifcfg_init (SCPluginIfcfg *self)
{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
+ GError *err = NULL;
+
+ priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ priv->unmanaged_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+ if (!priv->dbus_connection) {
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " dbus-glib error: %s",
+ err->message ? err->message : "(unknown)");
+ g_error_free (err);
+ }
}
static void
@@ -362,19 +343,22 @@
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object);
- if (priv->connections) {
- g_slist_foreach (priv->connections, release_one_connection, object);
- g_slist_free (priv->connections);
- }
+ g_hash_table_destroy (priv->connections);
+ g_hash_table_destroy (priv->unmanaged_devices);
- if (priv->monitor) {
- if (priv->monitor_id)
- g_signal_handler_disconnect (priv->monitor, priv->monitor_id);
+ if (priv->default_gw_monitor) {
+ if (priv->default_gw_monitor_id)
+ g_signal_handler_disconnect (priv->default_gw_monitor, priv->default_gw_monitor_id);
- g_file_monitor_cancel (priv->monitor);
- g_object_unref (priv->monitor);
+ g_file_monitor_cancel (priv->default_gw_monitor);
+ g_object_unref (priv->default_gw_monitor);
}
+ if (priv->hal_manager)
+ g_object_unref (priv->hal_manager);
+
+ dbus_g_connection_unref (priv->dbus_connection);
+
G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
}
@@ -419,6 +403,7 @@
{
/* interface implementation */
system_config_interface_class->get_connections = get_connections;
+ system_config_interface_class->get_unmanaged_devices = get_unmanaged_devices;
system_config_interface_class->init = init;
}
Modified: trunk/system-settings/src/Makefile.am
==============================================================================
--- trunk/system-settings/src/Makefile.am (original)
+++ trunk/system-settings/src/Makefile.am Thu May 8 07:20:02 2008
@@ -17,7 +17,9 @@
nm-system-config-interface.h \
nm-system-config-hal-manager.c \
nm-system-config-hal-manager.h \
- nm-system-config-hal-manager-private.h
+ nm-system-config-hal-manager-private.h \
+ sha1.c \
+ sha1.h
nm_system_settings_CPPFLAGS = \
$(DBUS_CFLAGS) \
Modified: trunk/system-settings/src/dbus-settings.c
==============================================================================
--- trunk/system-settings/src/dbus-settings.c (original)
+++ trunk/system-settings/src/dbus-settings.c Thu May 8 07:20:02 2008
@@ -363,13 +363,11 @@
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection));
- if (g_hash_table_lookup (priv->connections, connection)) {
- /* A plugin is lying to us */
- g_message ("Connection is already added, ignoring");
+ if (g_hash_table_lookup (priv->connections, connection))
+ /* A plugin is lying to us. */
return;
- }
- g_hash_table_insert (priv->connections, connection, GINT_TO_POINTER (1));
+ g_hash_table_insert (priv->connections, g_object_ref (connection), GINT_TO_POINTER (1));
g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self);
nm_exported_connection_register_object (connection, NM_CONNECTION_SCOPE_SYSTEM, priv->g_connection);
Modified: trunk/system-settings/src/main.c
==============================================================================
--- trunk/system-settings/src/main.c (original)
+++ trunk/system-settings/src/main.c Thu May 8 07:20:02 2008
@@ -130,8 +130,8 @@
plugin = g_module_open (path, G_MODULE_BIND_LOCAL);
if (!plugin) {
g_set_error (error, plugins_error_quark (), 0,
- "Could not find plugin '%s' as %s!",
- *pname, path);
+ "Could not load plugin '%s': %s",
+ *pname, g_module_error ());
g_free (full_name);
g_free (path);
break;
Added: trunk/system-settings/src/sha1.c
==============================================================================
--- (empty file)
+++ trunk/system-settings/src/sha1.c Thu May 8 07:20:02 2008
@@ -0,0 +1,692 @@
+/*
+ * SHA1 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline cc hut fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "sha1.h"
+
+
+/* Define types for stupid code. Userspace should
+ * be using u_*_t rather than kernel-space u* types.
+ */
+typedef u_int8_t u8;
+typedef u_int16_t u16;
+typedef u_int32_t u32;
+typedef u_int64_t u64;
+
+void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
+void sha1_transform(u8 *state, const u8 data[64]);
+
+void sha1_mac(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
+ u8 *mac)
+{
+ const u8 *addr[3];
+ size_t len[3];
+ addr[0] = key;
+ len[0] = key_len;
+ addr[1] = data;
+ len[1] = data_len;
+ addr[2] = key;
+ len[2] = key_len;
+ sha1_vector(3, addr, len, mac);
+}
+
+
+/* HMAC code is based on RFC 2104 */
+void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac)
+{
+ unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
+ unsigned char tk[20];
+ const u8 *_addr[6];
+ size_t _len[6], i;
+
+ if (num_elem > 5) {
+ /*
+ * Fixed limit on the number of fragments to avoid having to
+ * allocate memory (which could fail).
+ */
+ return;
+ }
+
+ /* if key is longer than 64 bytes reset it to key = SHA1(key) */
+ if (key_len > 64) {
+ sha1_vector(1, &key, &key_len, tk);
+ key = tk;
+ key_len = 20;
+ }
+
+ /* the HMAC_SHA1 transform looks like:
+ *
+ * SHA1(K XOR opad, SHA1(K XOR ipad, text))
+ *
+ * where K is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected */
+
+ /* start out by storing key in ipad */
+ memset(k_pad, 0, sizeof(k_pad));
+ memcpy(k_pad, key, key_len);
+ /* XOR key with ipad values */
+ for (i = 0; i < 64; i++)
+ k_pad[i] ^= 0x36;
+
+ /* perform inner SHA1 */
+ _addr[0] = k_pad;
+ _len[0] = 64;
+ for (i = 0; i < num_elem; i++) {
+ _addr[i + 1] = addr[i];
+ _len[i + 1] = len[i];
+ }
+ sha1_vector(1 + num_elem, _addr, _len, mac);
+
+ memset(k_pad, 0, sizeof(k_pad));
+ memcpy(k_pad, key, key_len);
+ /* XOR key with opad values */
+ for (i = 0; i < 64; i++)
+ k_pad[i] ^= 0x5c;
+
+ /* perform outer SHA1 */
+ _addr[0] = k_pad;
+ _len[0] = 64;
+ _addr[1] = mac;
+ _len[1] = SHA1_MAC_LEN;
+ sha1_vector(2, _addr, _len, mac);
+}
+
+
+void hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
+ u8 *mac)
+{
+ hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
+}
+
+
+void sha1_prf(const u8 *key, size_t key_len, const char *label,
+ const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
+{
+ u8 zero = 0, counter = 0;
+ size_t pos, plen;
+ u8 hash[SHA1_MAC_LEN];
+ size_t label_len = strlen(label);
+ const unsigned char *addr[4];
+ size_t len[4];
+
+ addr[0] = (u8 *) label;
+ len[0] = label_len;
+ addr[1] = &zero;
+ len[1] = 1;
+ addr[2] = data;
+ len[2] = data_len;
+ addr[3] = &counter;
+ len[3] = 1;
+
+ pos = 0;
+ while (pos < buf_len) {
+ plen = buf_len - pos;
+ if (plen >= SHA1_MAC_LEN) {
+ hmac_sha1_vector(key, key_len, 4, addr, len,
+ &buf[pos]);
+ pos += SHA1_MAC_LEN;
+ } else {
+ hmac_sha1_vector(key, key_len, 4, addr, len,
+ hash);
+ memcpy(&buf[pos], hash, plen);
+ break;
+ }
+ counter++;
+ }
+}
+
+
+static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
+ size_t ssid_len, int iterations, int count,
+ u8 *digest)
+{
+ unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
+ int i, j;
+ unsigned char count_buf[4];
+ const u8 *addr[2];
+ size_t len[2];
+ size_t passphrase_len = strlen(passphrase);
+
+ addr[0] = (u8 *) ssid;
+ len[0] = ssid_len;
+ addr[1] = count_buf;
+ len[1] = 4;
+
+ /* F(P, S, c, i) = U1 xor U2 xor ... Uc
+ * U1 = PRF(P, S || i)
+ * U2 = PRF(P, U1)
+ * Uc = PRF(P, Uc-1)
+ */
+
+ count_buf[0] = (count >> 24) & 0xff;
+ count_buf[1] = (count >> 16) & 0xff;
+ count_buf[2] = (count >> 8) & 0xff;
+ count_buf[3] = count & 0xff;
+ hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, tmp);
+ memcpy(digest, tmp, SHA1_MAC_LEN);
+
+ for (i = 1; i < iterations; i++) {
+ hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN,
+ tmp2);
+ memcpy(tmp, tmp2, SHA1_MAC_LEN);
+ for (j = 0; j < SHA1_MAC_LEN; j++)
+ digest[j] ^= tmp2[j];
+ }
+}
+
+
+void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
+ int iterations, u8 *buf, size_t buflen)
+{
+ int count = 0;
+ unsigned char *pos = buf;
+ size_t left = buflen;
+ size_t plen;
+ unsigned char digest[SHA1_MAC_LEN];
+
+ while (left > 0) {
+ count++;
+ pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count,
+ digest);
+ plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
+ memcpy(pos, digest, plen);
+ pos += plen;
+ left -= plen;
+ }
+}
+
+
+#ifndef EAP_TLS_FUNCS
+
+typedef struct {
+ u32 state[5];
+ u32 count[2];
+ unsigned char buffer[64];
+} SHA1_CTX;
+
+static void SHA1Init(SHA1_CTX *context);
+static void SHA1Update(SHA1_CTX *context, const void *data, u32 len);
+static void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+static void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
+
+
+/**
+ * sha1_vector - SHA-1 hash for data vector
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
+ * @mac: Buffer for the hash
+ */
+void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
+ u8 *mac)
+{
+ SHA1_CTX ctx;
+ size_t i;
+
+ SHA1Init(&ctx);
+ for (i = 0; i < num_elem; i++)
+ SHA1Update(&ctx, addr[i], len[i]);
+ SHA1Final(mac, &ctx);
+}
+
+
+/**
+ * sha1_transform - Perform one SHA-1 transform step
+ * @state: SHA-1 state
+ * @data: Input data for the SHA-1 transform
+ *
+ * This function is used to implement random number generation specified in
+ * NIST FIPS Publication 186-2 for EAP-SIM. This PRF uses a function that is
+ * similar to SHA-1, but has different message padding and as such, access to
+ * just part of the SHA-1 is needed.
+ */
+void sha1_transform(u8 *state, const u8 data[64])
+{
+ SHA1Transform((u32 *) state, data);
+}
+
+
+/* ===== start - public domain SHA1 implementation ===== */
+
+/*
+SHA-1 in C
+By Steve Reid <sreid sea-to-sky net>
+100% Public Domain
+
+-----------------
+Modified 7/98
+By James H. Brown <jbrown burgoyne com>
+Still 100% Public Domain
+
+Corrected a problem which generated improper hash values on 16 bit machines
+Routine SHA1Update changed from
+ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
+len)
+to
+ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
+long len)
+
+The 'len' parameter was declared an int which works fine on 32 bit machines.
+However, on 16 bit machines an int is too small for the shifts being done
+against
+it. This caused the hash function to generate incorrect values if len was
+greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
+
+Since the file IO in main() reads 16K at a time, any file 8K or larger would
+be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
+"a"s).
+
+I also changed the declaration of variables i & j in SHA1Update to
+unsigned long from unsigned int for the same reason.
+
+These changes should make no difference to any 32 bit implementations since
+an
+int and a long are the same size in those environments.
+
+--
+I also corrected a few compiler warnings generated by Borland C.
+1. Added #include <process.h> for exit() prototype
+2. Removed unused variable 'j' in SHA1Final
+3. Changed exit(0) to return(0) at end of main.
+
+ALL changes I made can be located by searching for comments containing 'JHB'
+-----------------
+Modified 8/98
+By Steve Reid <sreid sea-to-sky net>
+Still 100% public domain
+
+1- Removed #include <process.h> and used return() instead of exit()
+2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
+3- Changed email address from steve edmweb com to sreid sea-to-sky net
+
+-----------------
+Modified 4/01
+By Saul Kravitz <Saul Kravitz celera com>
+Still 100% PD
+Modified to run on Compaq Alpha hardware.
+
+-----------------
+Modified 4/01
+By Jouni Malinen <jkmaline cc hut fi>
+Minor changes to match the coding style used in Dynamics.
+
+Modified September 24, 2004
+By Jouni Malinen <jkmaline cc hut fi>
+Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
+
+*/
+
+/*
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+#define SHA1HANDSOFF
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifndef WORDS_BIGENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
+ (rol(block->l[i], 8) & 0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
+ block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) \
+ z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
+ w = rol(w, 30);
+#define R1(v,w,x,y,z,i) \
+ z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
+ w = rol(w, 30);
+#define R2(v,w,x,y,z,i) \
+ z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
+#define R3(v,w,x,y,z,i) \
+ z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
+ w = rol(w, 30);
+#define R4(v,w,x,y,z,i) \
+ z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
+ w=rol(w, 30);
+
+
+#ifdef VERBOSE /* SAK */
+void SHAPrintContext(SHA1_CTX *context, char *msg)
+{
+ printf("%s (%d,%d) %x %x %x %x %x\n",
+ msg,
+ context->count[0], context->count[1],
+ context->state[0],
+ context->state[1],
+ context->state[2],
+ context->state[3],
+ context->state[4]);
+}
+#endif
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(u32 state[5], const unsigned char buffer[64])
+{
+ u32 a, b, c, d, e;
+ typedef union {
+ unsigned char c[64];
+ u32 l[16];
+ } CHAR64LONG16;
+ CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+ u32 workspace[16];
+ block = (CHAR64LONG16 *) workspace;
+ memcpy(block, buffer, 64);
+#else
+ block = (CHAR64LONG16 *) buffer;
+#endif
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+#ifdef SHA1HANDSOFF
+ memset(block, 0, 64);
+#endif
+}
+
+
+/* SHA1Init - Initialize new context */
+
+static void SHA1Init(SHA1_CTX* context)
+{
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+static void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
+{
+ u32 i, j;
+ const unsigned char *data = _data;
+
+#ifdef VERBOSE
+ SHAPrintContext(context, "before");
+#endif
+ j = (context->count[0] >> 3) & 63;
+ if ((context->count[0] += len << 3) < (len << 3))
+ context->count[1]++;
+ context->count[1] += (len >> 29);
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64-j));
+ SHA1Transform(context->state, context->buffer);
+ for ( ; i + 63 < len; i += 64) {
+ SHA1Transform(context->state, &data[i]);
+ }
+ j = 0;
+ }
+ else i = 0;
+ memcpy(&context->buffer[j], &data[i], len - i);
+#ifdef VERBOSE
+ SHAPrintContext(context, "after ");
+#endif
+}
+
+
+/* Add padding and return the message digest. */
+
+static void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+{
+ u32 i;
+ unsigned char finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (unsigned char)
+ ((context->count[(i >= 4 ? 0 : 1)] >>
+ ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
+ }
+ SHA1Update(context, (unsigned char *) "\200", 1);
+ while ((context->count[0] & 504) != 448) {
+ SHA1Update(context, (unsigned char *) "\0", 1);
+ }
+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform()
+ */
+ for (i = 0; i < 20; i++) {
+ digest[i] = (unsigned char)
+ ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
+ 255);
+ }
+ /* Wipe variables */
+ i = 0;
+ memset(context->buffer, 0, 64);
+ memset(context->state, 0, 20);
+ memset(context->count, 0, 8);
+ memset(finalcount, 0, 8);
+}
+
+/* ===== end - public domain SHA1 implementation ===== */
+
+#endif /* EAP_TLS_FUNCS */
+
+
+#ifdef TEST_MAIN
+
+static u8 key0[] =
+{
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b
+};
+static u8 data0[] = "Hi There";
+static u8 prf0[] =
+{
+ 0xbc, 0xd4, 0xc6, 0x50, 0xb3, 0x0b, 0x96, 0x84,
+ 0x95, 0x18, 0x29, 0xe0, 0xd7, 0x5f, 0x9d, 0x54,
+ 0xb8, 0x62, 0x17, 0x5e, 0xd9, 0xf0, 0x06, 0x06,
+ 0xe1, 0x7d, 0x8d, 0xa3, 0x54, 0x02, 0xff, 0xee,
+ 0x75, 0xdf, 0x78, 0xc3, 0xd3, 0x1e, 0x0f, 0x88,
+ 0x9f, 0x01, 0x21, 0x20, 0xc0, 0x86, 0x2b, 0xeb,
+ 0x67, 0x75, 0x3e, 0x74, 0x39, 0xae, 0x24, 0x2e,
+ 0xdb, 0x83, 0x73, 0x69, 0x83, 0x56, 0xcf, 0x5a
+};
+
+static u8 key1[] = "Jefe";
+static u8 data1[] = "what do ya want for nothing?";
+static u8 prf1[] =
+{
+ 0x51, 0xf4, 0xde, 0x5b, 0x33, 0xf2, 0x49, 0xad,
+ 0xf8, 0x1a, 0xeb, 0x71, 0x3a, 0x3c, 0x20, 0xf4,
+ 0xfe, 0x63, 0x14, 0x46, 0xfa, 0xbd, 0xfa, 0x58,
+ 0x24, 0x47, 0x59, 0xae, 0x58, 0xef, 0x90, 0x09,
+ 0xa9, 0x9a, 0xbf, 0x4e, 0xac, 0x2c, 0xa5, 0xfa,
+ 0x87, 0xe6, 0x92, 0xc4, 0x40, 0xeb, 0x40, 0x02,
+ 0x3e, 0x7b, 0xab, 0xb2, 0x06, 0xd6, 0x1d, 0xe7,
+ 0xb9, 0x2f, 0x41, 0x52, 0x90, 0x92, 0xb8, 0xfc
+};
+
+
+static u8 key2[] =
+{
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa
+};
+static u8 data2[] =
+{
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd
+};
+static u8 prf2[] =
+{
+ 0xe1, 0xac, 0x54, 0x6e, 0xc4, 0xcb, 0x63, 0x6f,
+ 0x99, 0x76, 0x48, 0x7b, 0xe5, 0xc8, 0x6b, 0xe1,
+ 0x7a, 0x02, 0x52, 0xca, 0x5d, 0x8d, 0x8d, 0xf1,
+ 0x2c, 0xfb, 0x04, 0x73, 0x52, 0x52, 0x49, 0xce,
+ 0x9d, 0xd8, 0xd1, 0x77, 0xea, 0xd7, 0x10, 0xbc,
+ 0x9b, 0x59, 0x05, 0x47, 0x23, 0x91, 0x07, 0xae,
+ 0xf7, 0xb4, 0xab, 0xd4, 0x3d, 0x87, 0xf0, 0xa6,
+ 0x8f, 0x1c, 0xbd, 0x9e, 0x2b, 0x6f, 0x76, 0x07
+};
+
+
+struct passphrase_test {
+ char *passphrase;
+ char *ssid;
+ char psk[32];
+};
+
+static struct passphrase_test passphrase_tests[] =
+{
+ {
+ "password",
+ "IEEE",
+ {
+ 0xf4, 0x2c, 0x6f, 0xc5, 0x2d, 0xf0, 0xeb, 0xef,
+ 0x9e, 0xbb, 0x4b, 0x90, 0xb3, 0x8a, 0x5f, 0x90,
+ 0x2e, 0x83, 0xfe, 0x1b, 0x13, 0x5a, 0x70, 0xe2,
+ 0x3a, 0xed, 0x76, 0x2e, 0x97, 0x10, 0xa1, 0x2e
+ }
+ },
+ {
+ "ThisIsAPassword",
+ "ThisIsASSID",
+ {
+ 0x0d, 0xc0, 0xd6, 0xeb, 0x90, 0x55, 0x5e, 0xd6,
+ 0x41, 0x97, 0x56, 0xb9, 0xa1, 0x5e, 0xc3, 0xe3,
+ 0x20, 0x9b, 0x63, 0xdf, 0x70, 0x7d, 0xd5, 0x08,
+ 0xd1, 0x45, 0x81, 0xf8, 0x98, 0x27, 0x21, 0xaf
+ }
+ },
+ {
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
+ {
+ 0xbe, 0xcb, 0x93, 0x86, 0x6b, 0xb8, 0xc3, 0x83,
+ 0x2c, 0xb7, 0x77, 0xc2, 0xf5, 0x59, 0x80, 0x7c,
+ 0x8c, 0x59, 0xaf, 0xcb, 0x6e, 0xae, 0x73, 0x48,
+ 0x85, 0x00, 0x13, 0x00, 0xa9, 0x81, 0xcc, 0x62
+ }
+ },
+};
+
+#define NUM_PASSPHRASE_TESTS \
+(sizeof(passphrase_tests) / sizeof(passphrase_tests[0]))
+
+
+int main(int argc, char *argv[])
+{
+ u8 res[512];
+ int ret = 0, i;
+
+ printf("PRF-SHA1 test cases:\n");
+
+ sha1_prf(key0, sizeof(key0), "prefix", data0, sizeof(data0) - 1,
+ res, sizeof(prf0));
+ if (memcmp(res, prf0, sizeof(prf0)) == 0)
+ printf("Test case 0 - OK\n");
+ else {
+ printf("Test case 0 - FAILED!\n");
+ ret++;
+ }
+
+ sha1_prf(key1, sizeof(key1) - 1, "prefix", data1, sizeof(data1) - 1,
+ res, sizeof(prf1));
+ if (memcmp(res, prf1, sizeof(prf1)) == 0)
+ printf("Test case 1 - OK\n");
+ else {
+ printf("Test case 1 - FAILED!\n");
+ ret++;
+ }
+
+ sha1_prf(key2, sizeof(key2), "prefix", data2, sizeof(data2),
+ res, sizeof(prf2));
+ if (memcmp(res, prf2, sizeof(prf2)) == 0)
+ printf("Test case 2 - OK\n");
+ else {
+ printf("Test case 2 - FAILED!\n");
+ ret++;
+ }
+
+ ret += test_eap_fast();
+
+ printf("PBKDF2-SHA1 Passphrase test cases:\n");
+ for (i = 0; i < NUM_PASSPHRASE_TESTS; i++) {
+ u8 psk[32];
+ struct passphrase_test *test = &passphrase_tests[i];
+ pbkdf2_sha1(test->passphrase,
+ test->ssid, strlen(test->ssid),
+ 4096, psk, 32);
+ if (memcmp(psk, test->psk, 32) == 0)
+ printf("Test case %d - OK\n", i);
+ else {
+ printf("Test case %d - FAILED!\n", i);
+ ret++;
+ }
+ }
+
+ return ret;
+}
+#endif /* TEST_MAIN */
Added: trunk/system-settings/src/sha1.h
==============================================================================
--- (empty file)
+++ trunk/system-settings/src/sha1.h Thu May 8 07:20:02 2008
@@ -0,0 +1,34 @@
+/*
+ * SHA1 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline cc hut fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef SHA1_H
+#define SHA1_H
+
+#include <sys/types.h>
+
+
+#define SHA1_MAC_LEN 20
+
+void sha1_mac(const u_int8_t *key, size_t key_len, const u_int8_t *data, size_t data_len,
+ u_int8_t *mac);
+void hmac_sha1_vector(const u_int8_t *key, size_t key_len, size_t num_elem,
+ const u_int8_t *addr[], const size_t *len, u_int8_t *mac);
+void hmac_sha1(const u_int8_t *key, size_t key_len, const u_int8_t *data, size_t data_len,
+ u_int8_t *mac);
+void sha1_prf(const u_int8_t *key, size_t key_len, const char *label,
+ const u_int8_t *data, size_t data_len, u_int8_t *buf, size_t buf_len);
+void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
+ int iterations, u_int8_t *buf, size_t buflen);
+
+#endif /* SHA1_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]