NetworkManager r3644 - in trunk: . system-settings/plugins/ifcfg-suse system-settings/src



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]