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
This commit is contained in:
Dan Williams 2007-10-20 20:31:29 +00:00
parent 42a732d9b9
commit 41cb03a3dd
5 changed files with 258 additions and 16 deletions

View file

@ -1,3 +1,24 @@
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
2007-10-19 Dan Williams <dcbw@redhat.com>
Split the GetSecrets() call off to a separate D-Bus interface so that it

View file

@ -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;

View file

@ -45,6 +45,7 @@ typedef struct {
typedef struct
{
GHashTable *config;
GHashTable *blobs;
guint32 ap_scan;
gboolean dispose_has_run;
} NMSupplicantConfigPrivate;
@ -62,6 +63,12 @@ config_option_free (ConfigOption *opt)
g_slice_free (ConfigOption, opt);
}
static void
blob_free (GByteArray *array)
{
g_byte_array_free (array, TRUE);
}
static void
nm_supplicant_config_init (NMSupplicantConfig * 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);

View file

@ -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

View file

@ -1019,6 +1019,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)
{
@ -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);
}
}