summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-10-20 20:31:29 +0000
committerDan Williams <dcbw@redhat.com>2007-10-20 20:31:29 +0000
commit41cb03a3ddca5eb200a21c033961ee1f6c2cf750 (patch)
tree94673c3d4a0f19ab2f5f977db5781d961126a75a /src
parent42a732d9b921858544004f13fe7054fd1393a468 (diff)
downloadNetworkManager-41cb03a3ddca5eb200a21c033961ee1f6c2cf750.tar.gz
2007-10-20 Dan Williams <dcbw@redhat.com>
* src/supplicant-manager/nm-supplicant-config.h src/supplicant-manager/nm-supplicant-config.c - (nm_supplicant_config_init, nm_supplicant_config_finalize): add a hash table to store blobs - (nm_supplicant_config_add_blob): new function; add blob to internal blob hash table - (nm_supplicant_config_get_blobs): new function; get stored blobs - (nm_supplicant_config_add_setting_wireless_security): handle options that use certificates (ie, blobs) * src/nm-device-802-11-wireless.c - (build_supplicant_config): pass a UID (just use the connection path) to the supplicant config as now required * src/supplicant-manager/nm-supplicant-interface.c - (add_network_cb, call_set_blobs, set_blobs_cb, call_set_network): if there are any blobs to send to wpa_supplicant, send those first before sending the network configuration git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2990 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
Diffstat (limited to 'src')
-rw-r--r--src/nm-device-802-11-wireless.c6
-rw-r--r--src/supplicant-manager/nm-supplicant-config.c122
-rw-r--r--src/supplicant-manager/nm-supplicant-config.h5
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.c120
4 files changed, 237 insertions, 16 deletions
diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c
index 9eafdf5fa2..b858f7c937 100644
--- a/src/nm-device-802-11-wireless.c
+++ b/src/nm-device-802-11-wireless.c
@@ -2338,8 +2338,12 @@ build_supplicant_config (NMDevice80211Wireless *self,
s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, "802-11-wireless-security");
if (s_wireless_sec) {
+ DBusGProxy *proxy = g_object_get_data (G_OBJECT (connection), NM_MANAGER_CONNECTION_PROXY_TAG);
+ const char *con_path = dbus_g_proxy_get_path (proxy);
+
if (!nm_supplicant_config_add_setting_wireless_security (config,
- s_wireless_sec)) {
+ s_wireless_sec,
+ con_path)) {
nm_warning ("Couldn't add 802-11-wireless-security setting to "
"supplicant config.");
goto error;
diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c
index 40227db019..2362a26ff6 100644
--- a/src/supplicant-manager/nm-supplicant-config.c
+++ b/src/supplicant-manager/nm-supplicant-config.c
@@ -45,6 +45,7 @@ typedef struct {
typedef struct
{
GHashTable *config;
+ GHashTable *blobs;
guint32 ap_scan;
gboolean dispose_has_run;
} NMSupplicantConfigPrivate;
@@ -63,6 +64,12 @@ config_option_free (ConfigOption *opt)
}
static void
+blob_free (GByteArray *array)
+{
+ g_byte_array_free (array, TRUE);
+}
+
+static void
nm_supplicant_config_init (NMSupplicantConfig * self)
{
NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
@@ -70,7 +77,11 @@ nm_supplicant_config_init (NMSupplicantConfig * self)
priv->config = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) config_option_free);
-
+
+ priv->blobs = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) blob_free);
+
priv->ap_scan = 1;
priv->dispose_has_run = FALSE;
}
@@ -139,11 +150,78 @@ nm_info ("Config: added '%s' value '%s'", key, secret ? "<omitted>" : &buf[0]);
return TRUE;
}
+
+static gboolean
+nm_supplicant_config_add_blob (NMSupplicantConfig *self,
+ const char *key,
+ const GByteArray *value,
+ const char *blobid)
+{
+ NMSupplicantConfigPrivate *priv;
+ ConfigOption *old_opt;
+ ConfigOption *opt;
+ OptType type;
+ GByteArray *blob;
+
+ g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (value->len > 0, FALSE);
+ g_return_val_if_fail (blobid != NULL, FALSE);
+
+ priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
+
+ type = nm_supplicant_settings_verify_setting (key, NULL, 0);
+ if (type == TYPE_INVALID) {
+ nm_debug ("Key '%s' and/or it's contained value is invalid.", key);
+ return FALSE;
+ }
+
+ old_opt = (ConfigOption *) g_hash_table_lookup (priv->config, key);
+ if (old_opt) {
+ nm_debug ("Key '%s' already in table.", key);
+ return FALSE;
+ }
+
+ blob = g_byte_array_sized_new (value->len);
+ if (!blob) {
+ nm_debug ("Couldn't allocate memory for new config blob.");
+ return FALSE;
+ }
+ g_byte_array_append (blob, value->data, value->len);
+
+ opt = g_slice_new0 (ConfigOption);
+ if (opt == NULL) {
+ nm_debug ("Couldn't allocate memory for new config option.");
+ g_byte_array_free (blob, TRUE);
+ return FALSE;
+ }
+
+ opt->value = g_strdup_printf ("blob://%s", blobid);
+ if (opt->value == NULL) {
+ nm_debug ("Couldn't allocate memory for new config option value.");
+ g_byte_array_free (blob, TRUE);
+ g_slice_free (ConfigOption, opt);
+ return FALSE;
+ }
+
+ opt->len = strlen (opt->value);
+ opt->type = type;
+
+nm_info ("Config: added '%s' value '%s'", key, opt->value);
+
+ g_hash_table_insert (priv->config, g_strdup (key), opt);
+ g_hash_table_insert (priv->blobs, g_strdup (blobid), blob);
+
+ return TRUE;
+}
+
static void
nm_supplicant_config_finalize (GObject *object)
{
/* Complete object destruction */
g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->config);
+ g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->blobs);
/* Chain up to the parent class */
G_OBJECT_CLASS (nm_supplicant_config_parent_class)->finalize (object);
@@ -236,6 +314,14 @@ nm_supplicant_config_get_hash (NMSupplicantConfig * self)
return hash;
}
+GHashTable *
+nm_supplicant_config_get_blobs (NMSupplicantConfig * self)
+{
+ g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL);
+
+ return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->blobs;
+}
+
gboolean
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
NMSettingWireless * setting,
@@ -331,9 +417,33 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
} \
}
+static char *
+get_blob_id (const char *name, const char *seed_uid)
+{
+ char *uid = g_strdup_printf ("%s-%s", seed_uid, name);
+ char *p = uid;
+ while (*p) {
+ if (*p == '/') *p = '-';
+ p++;
+ }
+ return uid;
+}
+
+#define ADD_BLOB_VAL(field, name, con_uid) \
+ if (field && field->len) { \
+ char *uid = get_blob_id (name, con_uid); \
+ success = nm_supplicant_config_add_blob (self, name, field, uid); \
+ g_free (uid); \
+ if (!success) { \
+ nm_warning ("Error adding %s to supplicant config.", name); \
+ return FALSE; \
+ } \
+ }
+
gboolean
nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig * self,
- NMSettingWirelessSecurity * setting)
+ NMSettingWirelessSecurity * setting,
+ const char *connection_uid)
{
NMSupplicantConfigPrivate *priv;
char * value;
@@ -341,6 +451,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig * self,
g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
g_return_val_if_fail (setting != NULL, FALSE);
+ g_return_val_if_fail (connection_uid != NULL, FALSE);
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
@@ -365,6 +476,13 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig * self,
ADD_STRING_LIST_VAL (setting->group, "group", TRUE, FALSE);
ADD_STRING_LIST_VAL (setting->eap, "eap", TRUE, FALSE);
+ ADD_BLOB_VAL (setting->ca_cert, "ca_cert", connection_uid);
+ ADD_BLOB_VAL (setting->client_cert, "client_cert", connection_uid);
+ ADD_BLOB_VAL (setting->private_key, "private_key", connection_uid);
+ ADD_BLOB_VAL (setting->phase2_ca_cert, "ca_cert2", connection_uid);
+ ADD_BLOB_VAL (setting->phase2_client_cert, "client_cert2", connection_uid);
+ ADD_BLOB_VAL (setting->phase2_private_key, "private_key2", connection_uid);
+
if (setting->wep_key0 || setting->wep_key1 || setting->wep_key2 || setting->wep_key3) {
value = g_strdup_printf ("%d", setting->wep_tx_keyidx);
success = nm_supplicant_config_add_option (self, "wep_tx_keyidx", value, -1, FALSE);
diff --git a/src/supplicant-manager/nm-supplicant-config.h b/src/supplicant-manager/nm-supplicant-config.h
index a049424498..e8997f6201 100644
--- a/src/supplicant-manager/nm-supplicant-config.h
+++ b/src/supplicant-manager/nm-supplicant-config.h
@@ -63,12 +63,15 @@ gboolean nm_supplicant_config_add_option (NMSupplicantConfig *self,
GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig * self);
+GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig * self);
+
gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
NMSettingWireless * setting,
gboolean is_broadcast);
gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig * self,
- NMSettingWirelessSecurity * setting);
+ NMSettingWirelessSecurity * setting,
+ const char *connection_uid);
G_END_DECLS
diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c
index 9a9c1a48a2..22bf80d633 100644
--- a/src/supplicant-manager/nm-supplicant-interface.c
+++ b/src/supplicant-manager/nm-supplicant-interface.c
@@ -1020,6 +1020,102 @@ set_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
}
static void
+call_set_network (NMSupplicantInfo *info)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
+ GHashTable *config_hash;
+ DBusGProxyCall *call;
+
+ config_hash = nm_supplicant_config_get_hash (priv->cfg);
+ call = dbus_g_proxy_begin_call (priv->net_proxy, "set", set_network_cb,
+ info,
+ nm_supplicant_info_destroy,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), config_hash,
+ G_TYPE_INVALID);
+ nm_supplicant_info_set_call (info, call);
+ g_hash_table_destroy (config_hash);
+}
+
+static void
+set_blobs_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+{
+ NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+ GError *err = NULL;
+ guint tmp;
+
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+ nm_warning ("Couldn't set network blobs: %s.", err->message);
+ emit_error_helper (info->interface, err);
+ g_error_free (err);
+ } else {
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
+
+ info = nm_supplicant_info_new (info->interface, priv->iface_proxy,
+ NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface)->assoc_pcalls);
+ call_set_network (info);
+ }
+}
+
+static GValue *
+byte_array_to_gvalue (const GByteArray *array)
+{
+ GValue *val;
+
+ val = g_slice_new0 (GValue);
+ g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY);
+ g_value_set_boxed (val, array);
+
+ return val;
+}
+
+static void
+blob_free (GByteArray *array)
+{
+ g_byte_array_free (array, TRUE);
+}
+
+static void
+convert_blob (const char *key, const GByteArray *value, GHashTable *hash)
+{
+ GValue *val;
+
+ val = byte_array_to_gvalue (value);
+ g_hash_table_insert (hash, g_strdup (key), val);
+}
+
+#define DBUS_TYPE_G_STRING_VARIANT_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
+
+static void
+call_set_blobs (NMSupplicantInfo *info, GHashTable *orig_blobs)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
+ DBusGProxyCall *call;
+ GHashTable *blobs;
+
+ blobs = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) blob_free);
+ if (!blobs) {
+ const char *msg = "Not enough memory to create blob table.";
+ nm_warning ("%s", msg);
+ g_signal_emit (info->interface,
+ nm_supplicant_interface_signals[CONNECTION_ERROR],
+ 0, "SendBlobError", msg);
+ return;
+ }
+
+ g_hash_table_foreach (orig_blobs, (GHFunc) convert_blob, blobs);
+
+ call = dbus_g_proxy_begin_call (priv->net_proxy, "setBlobs", set_blobs_cb,
+ info,
+ nm_supplicant_info_destroy,
+ DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, blobs,
+ G_TYPE_INVALID);
+ nm_supplicant_info_set_call (info, call);
+ g_hash_table_destroy (blobs);
+}
+
+static void
add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
@@ -1034,25 +1130,25 @@ add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
g_error_free (err);
} else {
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- GHashTable *config_hash;
DBusGProxyCall *call;
-
- config_hash = nm_supplicant_config_get_hash (priv->cfg);
+ GHashTable *blobs;
priv->net_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
WPAS_DBUS_SERVICE,
path,
WPAS_DBUS_IFACE_NETWORK);
- info = nm_supplicant_info_new (info->interface, priv->net_proxy, priv->assoc_pcalls);
- call = dbus_g_proxy_begin_call (priv->net_proxy, "set", set_network_cb,
- info,
- nm_supplicant_info_destroy,
- dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), config_hash,
- G_TYPE_INVALID);
- nm_supplicant_info_set_call (info, call);
-
- g_hash_table_destroy (config_hash);
+ info = nm_supplicant_info_new (info->interface,
+ priv->net_proxy,
+ priv->assoc_pcalls);
+ /* Send any blobs first; if there aren't any jump to sending the
+ * config settings.
+ */
+ blobs = nm_supplicant_config_get_blobs (priv->cfg);
+ if (g_hash_table_size (blobs) > 0)
+ call_set_blobs (info, blobs);
+ else
+ call_set_network (info);
}
}