diff options
author | Dan Williams <dcbw@redhat.com> | 2007-10-20 20:31:29 +0000 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2007-10-20 20:31:29 +0000 |
commit | 41cb03a3ddca5eb200a21c033961ee1f6c2cf750 (patch) | |
tree | 94673c3d4a0f19ab2f5f977db5781d961126a75a /src | |
parent | 42a732d9b921858544004f13fe7054fd1393a468 (diff) | |
download | NetworkManager-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.c | 6 | ||||
-rw-r--r-- | src/supplicant-manager/nm-supplicant-config.c | 122 | ||||
-rw-r--r-- | src/supplicant-manager/nm-supplicant-config.h | 5 | ||||
-rw-r--r-- | src/supplicant-manager/nm-supplicant-interface.c | 120 |
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); } } |