2008-03-17 Dan Williams <dcbw@redhat.com>

Split the 802.1x bits out of the wireless-security setting so they are
	generalized enough for wired 802.1x to use too.

	* introspection/nm-exported-connection.xml
		- GetSecrets now returns 'a{sa{sv}}' (a hash of settings hashes) instead
			of just a hash of the secrets for one setting

	* libnm-util/nm-setting-wireless-security.c
	  libnm-util/nm-setting-wireless-security.h
		- Remove 802.1x-specific stuff
		- Added leap-username and leap-password properties for old-school LEAP

	* src/nm-device.c
	  src/nm-device.h
		- (connection_secrets_updated_cb): take a list of updated settings names,
			not just one

	* src/supplicant-manager/nm-supplicant-config.c
	  src/supplicant-manager/nm-supplicant-config.h
		- (nm_supplicant_config_add_setting_wireless_security): remove 802.1x
			specific stuff; fix for updated LEAP bits; punt 802.1x stuff
			to nm_supplicant_config_add_setting_8021x()
		- (nm_supplicant_config_add_setting_8021x): add an 802-1x setting to
			the supplicant config

	* src/nm-device-802-11-wireless.c
		- (build_supplicant_config): pass in the 802.1x setting too, if any
		- (real_connection_secrets_updated): take a list of updated settings
			names, not just one

	* src/nm-device-802-3-ethernet.c
	  src/nm-cdma-device.c
	  src/nm-gsm-device.c
		- (real_connection_secrets_updated_cb): take a list of updated settings
			names, not just one

	* src/nm-activation-request.c
	  src/nm-activation-request.h
		- (nm_act_request_class_init): the 'connection-secrets-updated' signal
			now passes a list of updated settings names, not just one
		- (update_one_setting): new function; handle one updated setting
		- (get_secrets_cb): handle multiple settings returned from the
			settings service; have to be careful of ordering here as there are
			some dependencies between settings (ex. wireless-security and 802.1x
			in some cases)

	* src/marshallers/nm-marshal.list
		- new marshaller for connection-secrets-updated signal

	* libnm-util/nm-setting-8021x.c
		- Add back the 'pin' and 'psk' settings, for EAP-SIM and EAP-PSK auth
			methods
		- (verify): a valid 'eap' property is now required

	* libnm-util/nm-connection.c
		- (register_default_settings): add priorities to settings; there are
			some dependencies between settings, and during the need_secrets
			calls this priority needs to be respected.  For example, only the
			wireless-security setting knows whether or not the connection is
			going to use 802.1x or now, so it must be asked for secrets before
			any existing 802.1x setting is
		- (nm_connection_lookup_setting_type): expose

	* libnm-util/nm-setting-wireless.c
		- (verify): should verify even if all_settings is NULL; otherwise won't
			catch the case where there is missing security

	* libnm-util/nm-setting-wireless-security.c
		- Remove everything to do with 802.1x
		- Add old-school LEAP specific properties for username and password
		- (need_secrets): rework LEAP secrets checking
		- (verify): rework for LEAP and 802.1x verification



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3470 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2008-03-17 19:37:23 +00:00
parent 50fb976d6a
commit 70e79d60dd
20 changed files with 556 additions and 811 deletions

View File

@@ -1,3 +1,78 @@
2008-03-17 Dan Williams <dcbw@redhat.com>
Split the 802.1x bits out of the wireless-security setting so they are
generalized enough for wired 802.1x to use too.
* introspection/nm-exported-connection.xml
- GetSecrets now returns 'a{sa{sv}}' (a hash of settings hashes) instead
of just a hash of the secrets for one setting
* libnm-util/nm-setting-wireless-security.c
libnm-util/nm-setting-wireless-security.h
- Remove 802.1x-specific stuff
- Added leap-username and leap-password properties for old-school LEAP
* src/nm-device.c
src/nm-device.h
- (connection_secrets_updated_cb): take a list of updated settings names,
not just one
* src/supplicant-manager/nm-supplicant-config.c
src/supplicant-manager/nm-supplicant-config.h
- (nm_supplicant_config_add_setting_wireless_security): remove 802.1x
specific stuff; fix for updated LEAP bits; punt 802.1x stuff
to nm_supplicant_config_add_setting_8021x()
- (nm_supplicant_config_add_setting_8021x): add an 802-1x setting to
the supplicant config
* src/nm-device-802-11-wireless.c
- (build_supplicant_config): pass in the 802.1x setting too, if any
- (real_connection_secrets_updated): take a list of updated settings
names, not just one
* src/nm-device-802-3-ethernet.c
src/nm-cdma-device.c
src/nm-gsm-device.c
- (real_connection_secrets_updated_cb): take a list of updated settings
names, not just one
* src/nm-activation-request.c
src/nm-activation-request.h
- (nm_act_request_class_init): the 'connection-secrets-updated' signal
now passes a list of updated settings names, not just one
- (update_one_setting): new function; handle one updated setting
- (get_secrets_cb): handle multiple settings returned from the
settings service; have to be careful of ordering here as there are
some dependencies between settings (ex. wireless-security and 802.1x
in some cases)
* src/marshallers/nm-marshal.list
- new marshaller for connection-secrets-updated signal
* libnm-util/nm-setting-8021x.c
- Add back the 'pin' and 'psk' settings, for EAP-SIM and EAP-PSK auth
methods
- (verify): a valid 'eap' property is now required
* libnm-util/nm-connection.c
- (register_default_settings): add priorities to settings; there are
some dependencies between settings, and during the need_secrets
calls this priority needs to be respected. For example, only the
wireless-security setting knows whether or not the connection is
going to use 802.1x or now, so it must be asked for secrets before
any existing 802.1x setting is
- (nm_connection_lookup_setting_type): expose
* libnm-util/nm-setting-wireless.c
- (verify): should verify even if all_settings is NULL; otherwise won't
catch the case where there is missing security
* libnm-util/nm-setting-wireless-security.c
- Remove everything to do with 802.1x
- Add old-school LEAP specific properties for username and password
- (need_secrets): rework LEAP secrets checking
- (verify): rework for LEAP and 802.1x verification
2008-03-17 Dan Williams <dcbw@redhat.com> 2008-03-17 Dan Williams <dcbw@redhat.com>
* src/NetworkManagerPolicy.c * src/NetworkManagerPolicy.c

View File

@@ -68,7 +68,7 @@
<arg name="hints" type="as" direction="in"> <arg name="hints" type="as" direction="in">
<tp:docstring> <tp:docstring>
Array of strings of key names in the Setting for which NM thinks Array of strings of key names in the Setting for which NM thinks
a secrets may be required.A a secrets may be required.
</tp:docstring> </tp:docstring>
</arg> </arg>
<arg name="request_new" type="b" direction="in"> <arg name="request_new" type="b" direction="in">
@@ -77,9 +77,9 @@
</tp:docstring> </tp:docstring>
</arg> </arg>
<arg name="secrets" type="a{sv}" direction="out" tp:type="String_Variant_Map"> <arg name="secrets" type="a{sa{sv}}" direction="out" tp:type="String_String_Variant_Map_Map">
<tp:docstring> <tp:docstring>
Map of secrets. Nested settings maps containing secrets. Each setting MUST contain at least the 'name' field, containing the name of the setting, and one or more secrets.
</tp:docstring> </tp:docstring>
</arg> </arg>
</method> </method>

View File

@@ -53,34 +53,63 @@ static guint signals[LAST_SIGNAL] = { 0 };
static GHashTable *registered_settings = NULL; static GHashTable *registered_settings = NULL;
#define DEFAULT_MAP_SIZE 13
static struct SettingInfo {
const char *name;
GType type;
guint32 priority;
} default_map[DEFAULT_MAP_SIZE] = { { NULL } };
static void
register_one_setting (int i, const char *name, GType type, guint32 priority)
{
g_return_if_fail (i >= 0);
g_return_if_fail (i < DEFAULT_MAP_SIZE);
g_return_if_fail (default_map[i].name == NULL);
default_map[i].name = name;
default_map[i].type = type;
default_map[i].priority = priority;
nm_setting_register (name, type);
}
static void static void
register_default_settings (void) register_default_settings (void)
{ {
int i; int i = 0;
const struct {
const char *name;
GType type;
} default_map[] = {
{ NM_SETTING_CONNECTION_SETTING_NAME, NM_TYPE_SETTING_CONNECTION },
{ NM_SETTING_802_1X_SETTING_NAME, NM_TYPE_SETTING_802_1X },
{ NM_SETTING_WIRED_SETTING_NAME, NM_TYPE_SETTING_WIRED },
{ NM_SETTING_WIRELESS_SETTING_NAME, NM_TYPE_SETTING_WIRELESS },
{ NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_TYPE_SETTING_IP4_CONFIG },
{ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_TYPE_SETTING_WIRELESS_SECURITY },
{ NM_SETTING_SERIAL_SETTING_NAME, NM_TYPE_SETTING_SERIAL },
{ NM_SETTING_GSM_SETTING_NAME, NM_TYPE_SETTING_GSM },
{ NM_SETTING_CDMA_SETTING_NAME, NM_TYPE_SETTING_CDMA },
{ NM_SETTING_PPP_SETTING_NAME, NM_TYPE_SETTING_PPP },
{ NM_SETTING_PPPOE_SETTING_NAME, NM_TYPE_SETTING_PPPOE },
{ NM_SETTING_VPN_SETTING_NAME, NM_TYPE_SETTING_VPN },
{ NM_SETTING_VPN_PROPERTIES_SETTING_NAME, NM_TYPE_SETTING_VPN_PROPERTIES },
{ NULL }
};
nm_utils_register_value_transformations (); nm_utils_register_value_transformations ();
for (i = 0; default_map[i].name; i++) if (G_LIKELY (default_map[0].name))
nm_setting_register (default_map[i].name, default_map[i].type); return;
register_one_setting (i++, NM_SETTING_CONNECTION_SETTING_NAME, NM_TYPE_SETTING_CONNECTION, 0);
register_one_setting (i++, NM_SETTING_WIRED_SETTING_NAME, NM_TYPE_SETTING_WIRED, 1);
register_one_setting (i++, NM_SETTING_WIRELESS_SETTING_NAME, NM_TYPE_SETTING_WIRELESS, 1);
register_one_setting (i++, NM_SETTING_GSM_SETTING_NAME, NM_TYPE_SETTING_GSM, 1);
register_one_setting (i++, NM_SETTING_CDMA_SETTING_NAME, NM_TYPE_SETTING_CDMA, 1);
register_one_setting (i++, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_TYPE_SETTING_WIRELESS_SECURITY, 2);
register_one_setting (i++, NM_SETTING_SERIAL_SETTING_NAME, NM_TYPE_SETTING_SERIAL, 2);
register_one_setting (i++, NM_SETTING_PPP_SETTING_NAME, NM_TYPE_SETTING_PPP, 3);
register_one_setting (i++, NM_SETTING_PPPOE_SETTING_NAME, NM_TYPE_SETTING_PPPOE, 3);
register_one_setting (i++, NM_SETTING_802_1X_SETTING_NAME, NM_TYPE_SETTING_802_1X, 3);
register_one_setting (i++, NM_SETTING_VPN_SETTING_NAME, NM_TYPE_SETTING_VPN, 4);
register_one_setting (i++, NM_SETTING_VPN_PROPERTIES_SETTING_NAME, NM_TYPE_SETTING_VPN_PROPERTIES, 5);
register_one_setting (i++, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_TYPE_SETTING_IP4_CONFIG, 6);
}
static guint32
get_priority_for_setting_type (GType type)
{
int i;
for (i = 0; default_map[i].name; i++) {
if (default_map[i].type == type)
return default_map[i].priority;
}
return G_MAXUINT32;
} }
void void
@@ -107,7 +136,7 @@ nm_setting_unregister (const char *name)
g_hash_table_remove (registered_settings, name); g_hash_table_remove (registered_settings, name);
} }
static GType GType
nm_connection_lookup_setting_type (const char *name) nm_connection_lookup_setting_type (const char *name)
{ {
char *type_name; char *type_name;
@@ -331,24 +360,27 @@ nm_connection_update_secrets (NMConnection *connection,
g_signal_emit (connection, signals[SECRETS_UPDATED], 0, setting_name); g_signal_emit (connection, signals[SECRETS_UPDATED], 0, setting_name);
} }
typedef struct NeedSecretsInfo { static gint
GPtrArray *secrets; setting_priority_compare (gconstpointer a, gconstpointer b)
NMSetting *setting; {
} NeedSecretsInfo; guint32 prio_a, prio_b;
prio_a = get_priority_for_setting_type (G_OBJECT_TYPE (NM_SETTING (a)));
prio_b = get_priority_for_setting_type (G_OBJECT_TYPE (NM_SETTING (b)));
if (prio_a < prio_b)
return -1;
else if (prio_a == prio_b)
return 0;
return 1;
}
static void static void
need_secrets_check (gpointer key, gpointer data, gpointer user_data) add_setting_to_list (gpointer key, gpointer data, gpointer user_data)
{ {
NMSetting *setting = NM_SETTING (data); GSList **list = (GSList **) user_data;
NeedSecretsInfo *info = (NeedSecretsInfo *) user_data;
// FIXME: allow more than one setting to say it needs secrets *list = g_slist_insert_sorted (*list, NM_SETTING (data), setting_priority_compare);
if (info->secrets)
return;
info->secrets = nm_setting_need_secrets (setting);
if (info->secrets)
info->setting = setting;
} }
const char * const char *
@@ -356,26 +388,38 @@ nm_connection_need_secrets (NMConnection *connection,
GPtrArray **hints) GPtrArray **hints)
{ {
NMConnectionPrivate *priv; NMConnectionPrivate *priv;
NeedSecretsInfo info = { NULL, NULL }; GSList *settings = NULL;
GSList *iter;
char *name = NULL;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
priv = NM_CONNECTION_GET_PRIVATE (connection); priv = NM_CONNECTION_GET_PRIVATE (connection);
g_hash_table_foreach (priv->settings, need_secrets_check, &info);
// FIXME: do something with requested secrets rather than asking for /* Get list of settings in priority order */
// all of them. Maybe make info.secrets a hash table mapping g_hash_table_foreach (priv->settings, add_setting_to_list, &settings);
// settings name :: [list of secrets key names].
if (info.secrets) {
if (hints)
*hints = info.secrets;
else
g_ptr_array_free (info.secrets, TRUE);
return nm_setting_get_name (info.setting); for (iter = settings; iter; iter = g_slist_next (iter)) {
NMSetting *setting = NM_SETTING (iter->data);
GPtrArray *secrets;
// FIXME: do something with requested secrets rather than asking for
// all of them. Maybe make secrets a hash table mapping
// settings name :: [list of secrets key names].
secrets = nm_setting_need_secrets (setting);
if (secrets) {
if (hints)
*hints = secrets;
else
g_ptr_array_free (secrets, TRUE);
name = (char *) nm_setting_get_name (setting);
break;
}
} }
return NULL; g_slist_free (settings);
return name;
} }
static void static void

View File

@@ -92,6 +92,8 @@ void nm_setting_register (const char *name,
void nm_setting_unregister (const char *name); void nm_setting_unregister (const char *name);
GType nm_connection_lookup_setting_type (const char *name);
G_END_DECLS G_END_DECLS
#endif /* NM_CONNECTION_H */ #endif /* NM_CONNECTION_H */

View File

@@ -28,6 +28,8 @@ enum {
PROP_PASSWORD, PROP_PASSWORD,
PROP_PRIVATE_KEY, PROP_PRIVATE_KEY,
PROP_PHASE2_PRIVATE_KEY, PROP_PHASE2_PRIVATE_KEY,
PROP_PIN,
PROP_PSK,
LAST_PROP LAST_PROP
}; };
@@ -47,6 +49,15 @@ need_secrets_password (NMSetting8021x *self,
g_ptr_array_add (secrets, NM_SETTING_802_1X_PASSWORD); g_ptr_array_add (secrets, NM_SETTING_802_1X_PASSWORD);
} }
static void
need_secrets_sim (NMSetting8021x *self,
GPtrArray *secrets,
gboolean phase2)
{
if (!self->pin || !strlen (self->pin))
g_ptr_array_add (secrets, NM_SETTING_802_1X_PIN);
}
static void static void
need_secrets_tls (NMSetting8021x *self, need_secrets_tls (NMSetting8021x *self,
GPtrArray *secrets, GPtrArray *secrets,
@@ -125,6 +136,7 @@ static EAPMethodsTable eap_methods_table[] = {
{ "tls", need_secrets_tls, verify_tls }, { "tls", need_secrets_tls, verify_tls },
{ "peap", need_secrets_phase2, NULL }, { "peap", need_secrets_phase2, NULL },
{ "ttls", need_secrets_phase2, verify_ttls }, { "ttls", need_secrets_phase2, verify_ttls },
{ "sim", need_secrets_sim, NULL },
{ "gtc", NULL, NULL }, // FIXME: implement { "gtc", NULL, NULL }, // FIXME: implement
{ "otp", NULL, NULL }, // FIXME: implement { "otp", NULL, NULL }, // FIXME: implement
{ NULL, NULL, NULL } { NULL, NULL, NULL }
@@ -206,32 +218,34 @@ static gboolean
verify (NMSetting *setting, GSList *all_settings) verify (NMSetting *setting, GSList *all_settings)
{ {
NMSetting8021x *self = NM_SETTING_802_1X (setting); NMSetting8021x *self = NM_SETTING_802_1X (setting);
const char *valid_eap[] = { "leap", "md5", "tls", "peap", "ttls", "fast", NULL }; const char *valid_eap[] = { "leap", "md5", "tls", "peap", "ttls", "sim", "fast", NULL };
const char *valid_phase1_peapver[] = { "0", "1", NULL }; const char *valid_phase1_peapver[] = { "0", "1", NULL };
const char *valid_phase2_auth[] = { "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", "tls", NULL }; const char *valid_phase2_auth[] = { "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", "tls", NULL };
const char *valid_phase2_autheap[] = { "md5", "mschapv2", "otp", "gtc", "tls", NULL }; const char *valid_phase2_autheap[] = { "md5", "mschapv2", "otp", "gtc", "tls", NULL };
GSList *iter;
if (self->eap) { if (!self->eap) {
GSList *iter; g_warning ("Missing eap method");
return FALSE;
}
if (!nm_utils_string_slist_validate (self->eap, valid_eap)) { if (!nm_utils_string_slist_validate (self->eap, valid_eap)) {
g_warning ("Invalid eap"); g_warning ("Invalid eap");
return FALSE; return FALSE;
} }
/* Ask each configured EAP method if its valid */ /* Ask each configured EAP method if its valid */
for (iter = self->eap; iter; iter = g_slist_next (iter)) { for (iter = self->eap; iter; iter = g_slist_next (iter)) {
const char *method = (const char *) iter->data; const char *method = (const char *) iter->data;
int i; int i;
for (i = 0; eap_methods_table[i].method; i++) { for (i = 0; eap_methods_table[i].method; i++) {
if (eap_methods_table[i].v_func == NULL) if (eap_methods_table[i].v_func == NULL)
continue; continue;
if (!strcmp (eap_methods_table[i].method, method)) { if (!strcmp (eap_methods_table[i].method, method)) {
if (!(*eap_methods_table[i].v_func) (self, FALSE)) if (!(*eap_methods_table[i].v_func) (self, FALSE))
return FALSE; return FALSE;
break; break;
}
} }
} }
} }

View File

@@ -14,7 +14,7 @@ G_BEGIN_DECLS
#define NM_IS_SETTING_802_1X_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_802_1X)) #define NM_IS_SETTING_802_1X_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_802_1X))
#define NM_SETTING_802_1X_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_802_1X, NMSetting8021xClass)) #define NM_SETTING_802_1X_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_802_1X, NMSetting8021xClass))
#define NM_SETTING_802_1X_SETTING_NAME "802.1X" #define NM_SETTING_802_1X_SETTING_NAME "802-1x"
#define NM_SETTING_802_1X_EAP "eap" #define NM_SETTING_802_1X_EAP "eap"
#define NM_SETTING_802_1X_IDENTITY "identity" #define NM_SETTING_802_1X_IDENTITY "identity"
@@ -33,6 +33,8 @@ G_BEGIN_DECLS
#define NM_SETTING_802_1X_PASSWORD "password" #define NM_SETTING_802_1X_PASSWORD "password"
#define NM_SETTING_802_1X_PRIVATE_KEY "private-key" #define NM_SETTING_802_1X_PRIVATE_KEY "private-key"
#define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY "phase2-private-key" #define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY "phase2-private-key"
#define NM_SETTING_802_1X_PIN "pin"
#define NM_SETTING_802_1X_PSK "psk"
typedef struct { typedef struct {
NMSetting parent; NMSetting parent;
@@ -52,6 +54,8 @@ typedef struct {
char *phase2_ca_path; char *phase2_ca_path;
GByteArray *phase2_client_cert; GByteArray *phase2_client_cert;
char *password; char *password;
char *pin;
char *psk;
GByteArray *private_key; GByteArray *private_key;
GByteArray *phase2_private_key; GByteArray *phase2_private_key;
} NMSetting8021x; } NMSetting8021x;

View File

@@ -4,6 +4,7 @@
#include <ctype.h> #include <ctype.h>
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
#include "nm-setting-wireless-security.h" #include "nm-setting-wireless-security.h"
#include "nm-setting-8021x.h"
#include "nm-param-spec-specialized.h" #include "nm-param-spec-specialized.h"
#include "nm-utils.h" #include "nm-utils.h"
@@ -17,31 +18,13 @@ enum {
PROP_PROTO, PROP_PROTO,
PROP_PAIRWISE, PROP_PAIRWISE,
PROP_GROUP, PROP_GROUP,
PROP_EAP, PROP_LEAP_USERNAME,
PROP_IDENTITY,
PROP_ANONYMOUS_IDENTITY,
PROP_CA_CERT,
PROP_CA_PATH,
PROP_CLIENT_CERT,
PROP_PHASE1_PEAPVER,
PROP_PHASE1_PEAPLABEL,
PROP_PHASE1_FAST_PROVISIONING,
PROP_PHASE2_AUTH,
PROP_PHASE2_AUTHEAP,
PROP_PHASE2_CA_CERT,
PROP_PHASE2_CA_PATH,
PROP_PHASE2_CLIENT_CERT,
PROP_NAI,
PROP_WEP_KEY0, PROP_WEP_KEY0,
PROP_WEP_KEY1, PROP_WEP_KEY1,
PROP_WEP_KEY2, PROP_WEP_KEY2,
PROP_WEP_KEY3, PROP_WEP_KEY3,
PROP_PSK, PROP_PSK,
PROP_PASSWORD, PROP_LEAP_PASSWORD,
PROP_PIN,
PROP_EAPPSK,
PROP_PRIVATE_KEY,
PROP_PHASE2_PRIVATE_KEY,
LAST_PROP LAST_PROP
}; };
@@ -92,159 +75,6 @@ verify_wpa_psk (const char *psk)
return TRUE; return TRUE;
} }
static void
need_secrets_password (NMSettingWirelessSecurity *self,
GPtrArray *secrets,
gboolean phase2)
{
if (!self->password || !strlen (self->password))
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_PASSWORD);
}
static void
need_secrets_eappsk (NMSettingWirelessSecurity *self,
GPtrArray *secrets,
gboolean phase2)
{
if (!self->eappsk || !strlen (self->eappsk))
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_EAPPSK);
}
static void
need_secrets_sim (NMSettingWirelessSecurity *self,
GPtrArray *secrets,
gboolean phase2)
{
if (!self->pin || !strlen (self->pin))
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_PIN);
}
static void
need_secrets_tls (NMSettingWirelessSecurity *self,
GPtrArray *secrets,
gboolean phase2)
{
if (phase2) {
if ( self->phase2_client_cert
&& (!self->phase2_private_key || !self->phase2_private_key->len))
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_PHASE2_PRIVATE_KEY);
} else {
if (self->client_cert
&& (!self->private_key || !self->private_key->len))
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_PRIVATE_KEY);
}
}
static gboolean
verify_tls (NMSettingWirelessSecurity *self, gboolean phase2)
{
if (phase2) {
if (!self->phase2_client_cert || !self->phase2_client_cert->len)
return FALSE;
} else {
if (!self->client_cert || !self->client_cert->len)
return FALSE;
}
return TRUE;
}
static gboolean
verify_ttls (NMSettingWirelessSecurity *self, gboolean phase2)
{
if (!self->identity && !self->anonymous_identity)
return FALSE;
if (!self->phase2_auth && !self->phase2_autheap)
return FALSE;
return TRUE;
}
static gboolean
verify_identity (NMSettingWirelessSecurity *self, gboolean phase2)
{
return self->identity ? TRUE : FALSE;
}
static gboolean
verify_nai (NMSettingWirelessSecurity *self, gboolean phase2)
{
return self->nai ? TRUE : FALSE;
}
/* Implemented below... */
static void need_secrets_phase2 (NMSettingWirelessSecurity *self,
GPtrArray *secrets,
gboolean phase2);
typedef void (*EAPMethodNeedSecretsFunc) (NMSettingWirelessSecurity *self,
GPtrArray *secrets,
gboolean phase2);
typedef gboolean (*EAPMethodValidateFunc)(NMSettingWirelessSecurity *self,
gboolean phase2);
typedef struct {
const char *method;
EAPMethodNeedSecretsFunc ns_func;
EAPMethodValidateFunc v_func;
} EAPMethodsTable;
static EAPMethodsTable eap_methods_table[] = {
{ "leap", need_secrets_password, verify_identity },
{ "md5", need_secrets_password, verify_identity },
{ "pap", need_secrets_password, verify_identity },
{ "chap", need_secrets_password, verify_identity },
{ "mschap", need_secrets_password, verify_identity },
{ "mschapv2", need_secrets_password, verify_identity },
{ "fast", need_secrets_password, verify_identity },
{ "psk", need_secrets_eappsk, verify_nai },
{ "pax", need_secrets_eappsk, NULL },
{ "sake", need_secrets_eappsk, verify_nai },
{ "gpsk", need_secrets_eappsk, verify_nai },
{ "tls", need_secrets_tls, verify_tls },
{ "peap", need_secrets_phase2, NULL },
{ "ttls", need_secrets_phase2, verify_ttls },
{ "sim", need_secrets_sim, NULL },
{ "gtc", NULL, NULL }, // FIXME: implement
{ "otp", NULL, NULL }, // FIXME: implement
{ NULL, NULL, NULL }
};
static void
need_secrets_phase2 (NMSettingWirelessSecurity *self,
GPtrArray *secrets,
gboolean phase2)
{
char *method = NULL;
int i;
g_return_if_fail (phase2 == FALSE);
/* Check phase2_auth and phase2_autheap */
method = self->phase2_auth;
if (!method && self->phase2_autheap)
method = self->phase2_autheap;
if (!method) {
g_warning ("Couldn't find EAP method.");
g_assert_not_reached();
return;
}
/* Ask the configured phase2 method if it needs secrets */
for (i = 0; eap_methods_table[i].method; i++) {
if (eap_methods_table[i].ns_func == NULL)
continue;
if (strcmp (eap_methods_table[i].method, method)) {
(*eap_methods_table[i].ns_func) (self, secrets, TRUE);
break;
}
}
}
static GPtrArray * static GPtrArray *
need_secrets (NMSetting *setting) need_secrets (NMSetting *setting)
@@ -292,12 +122,11 @@ need_secrets (NMSetting *setting)
} }
/* LEAP */ /* LEAP */
if ( (strcmp (self->key_mgmt, "ieee8021x") == 0) if ( self->auth_alg
&& self->auth_alg && !strcmp (self->auth_alg, "leap")
&& (strcmp (self->auth_alg, "leap") == 0) && !strcmp (self->key_mgmt, "ieee8021x")) {
&& (nm_utils_string_list_contains (self->eap, "leap"))) { if (!self->leap_password || !strlen (self->leap_password)) {
if (!self->password || !strlen (self->password)) { g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD);
g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_PASSWORD);
return secrets; return secrets;
} }
goto no_secrets; goto no_secrets;
@@ -305,32 +134,7 @@ need_secrets (NMSetting *setting)
if ( (strcmp (self->key_mgmt, "ieee8021x") == 0) if ( (strcmp (self->key_mgmt, "ieee8021x") == 0)
|| (strcmp (self->key_mgmt, "wpa-eap") == 0)) { || (strcmp (self->key_mgmt, "wpa-eap") == 0)) {
GSList *iter; /* Let caller check the 802.1x setting for secrets */
gboolean eap_method_found = FALSE;
/* Ask each configured EAP method if it needs secrets */
for (iter = self->eap; iter && !eap_method_found; iter = g_slist_next (iter)) {
const char *method = (const char *) iter->data;
int i;
for (i = 0; eap_methods_table[i].method; i++) {
if (eap_methods_table[i].ns_func == NULL)
continue;
if (!strcmp (eap_methods_table[i].method, method)) {
(*eap_methods_table[i].ns_func) (self, secrets, FALSE);
/* Only break out of the outer loop if this EAP method
* needed secrets.
*/
if (secrets->len > 0)
eap_method_found = TRUE;
break;
}
}
}
if (secrets->len)
return secrets;
goto no_secrets; goto no_secrets;
} }
@@ -343,6 +147,15 @@ no_secrets:
return NULL; return NULL;
} }
static gint
find_setting_by_name (gconstpointer a, gconstpointer b)
{
NMSetting *setting = NM_SETTING (a);
const char *str = (const char *) b;
return strcmp (nm_setting_get_name (setting), str);
}
static gboolean static gboolean
verify (NMSetting *setting, GSList *all_settings) verify (NMSetting *setting, GSList *all_settings)
{ {
@@ -352,18 +165,33 @@ verify (NMSetting *setting, GSList *all_settings)
const char *valid_protos[] = { "wpa", "rsn", NULL }; const char *valid_protos[] = { "wpa", "rsn", NULL };
const char *valid_pairwise[] = { "wep40", "wep104", "tkip", "ccmp", NULL }; const char *valid_pairwise[] = { "wep40", "wep104", "tkip", "ccmp", NULL };
const char *valid_groups[] = { "wep40", "wep104", "tkip", "ccmp", NULL }; const char *valid_groups[] = { "wep40", "wep104", "tkip", "ccmp", NULL };
const char *valid_phase1_peapver[] = { "0", "1", NULL };
/* Every time a method gets added to the following, add one to EAPMethodNeedSecretsTable */
const char *valid_eap[] = { "leap", "md5", "tls", "peap", "ttls", "sim", "psk", "fast", NULL };
const char *valid_phase2_auth[] = { "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", "tls", NULL };
const char *valid_phase2_autheap[] = { "md5", "mschapv2", "otp", "gtc", "tls", NULL };
if (!self->key_mgmt || !nm_utils_string_in_list (self->key_mgmt, valid_key_mgmt)) { if (!self->key_mgmt || !nm_utils_string_in_list (self->key_mgmt, valid_key_mgmt)) {
g_warning ("Missing or invalid key management"); g_warning ("Missing or invalid key management");
return FALSE; return FALSE;
} }
if (self->auth_alg && !strcmp (self->auth_alg, "leap")) {
/* LEAP must use ieee8021x key management */
if (strcmp (self->key_mgmt, "ieee8021x")) {
g_warning ("LEAP requires IEEE8021X key management.");
return FALSE;
}
if (!self->leap_username) {
g_warning ("LEAP requires a username.");
return FALSE;
}
} else {
if ( (strcmp (self->key_mgmt, "ieee8021x") == 0)
|| (strcmp (self->key_mgmt, "wpa-eap") == 0)) {
/* Need an 802.1x setting too */
if (!g_slist_find_custom (all_settings, NM_SETTING_802_1X_SETTING_NAME, find_setting_by_name)) {
g_warning ("Invalid or missing 802.1x setting");
return FALSE;
}
}
}
if (self->wep_tx_keyidx > 3) { if (self->wep_tx_keyidx > 3) {
g_warning ("Invalid WEP key index"); g_warning ("Invalid WEP key index");
return FALSE; return FALSE;
@@ -389,58 +217,14 @@ verify (NMSetting *setting, GSList *all_settings)
return FALSE; return FALSE;
} }
if (self->eap) { /* Shared Key auth can only be used with WEP */
GSList *iter; if (self->auth_alg && !strcmp (self->auth_alg, "shared")) {
if (self->key_mgmt && strcmp (self->key_mgmt, "none")) {
if (!nm_utils_string_slist_validate (self->eap, valid_eap)) { g_warning ("Shared Key authentication can only be used with WEP.");
g_warning ("Invalid eap");
return FALSE; return FALSE;
} }
/* Ask each configured EAP method if its valid */
for (iter = self->eap; iter; iter = g_slist_next (iter)) {
const char *method = (const char *) iter->data;
int i;
for (i = 0; eap_methods_table[i].method; i++) {
if (eap_methods_table[i].v_func == NULL)
continue;
if (!strcmp (eap_methods_table[i].method, method)) {
if (!(*eap_methods_table[i].v_func) (self, FALSE))
return FALSE;
break;
}
}
}
} }
if (self->phase1_peapver && !nm_utils_string_in_list (self->phase1_peapver, valid_phase1_peapver)) {
g_warning ("Invalid phase1 peapver");
return FALSE;
}
if (self->phase1_peaplabel && strcmp (self->phase1_peaplabel, "1")) {
g_warning ("Invalid phase1 peaplabel");
return FALSE;
}
if (self->phase1_fast_provisioning && strcmp (self->phase1_fast_provisioning, "1")) {
g_warning ("Invalid phase1 fast provisioning");
return FALSE;
}
if (self->phase2_auth && !nm_utils_string_in_list (self->phase2_auth, valid_phase2_auth)) {
g_warning ("Invalid phase2 authentication");
return FALSE;
}
if (self->phase2_autheap && !nm_utils_string_in_list (self->phase2_autheap, valid_phase2_autheap)) {
g_warning ("Invalid phase2 autheap");
return FALSE;
}
/* FIXME: finish */
return TRUE; return TRUE;
} }
@@ -459,42 +243,17 @@ finalize (GObject *object)
g_free (self->key_mgmt); g_free (self->key_mgmt);
g_free (self->auth_alg); g_free (self->auth_alg);
g_free (self->identity); g_free (self->leap_username);
g_free (self->anonymous_identity);
g_free (self->ca_path);
g_free (self->phase1_peapver);
g_free (self->phase1_peaplabel);
g_free (self->phase1_fast_provisioning);
g_free (self->phase2_auth);
g_free (self->phase2_autheap);
g_free (self->phase2_ca_path);
g_free (self->nai);
g_free (self->wep_key0); g_free (self->wep_key0);
g_free (self->wep_key1); g_free (self->wep_key1);
g_free (self->wep_key2); g_free (self->wep_key2);
g_free (self->wep_key3); g_free (self->wep_key3);
g_free (self->psk); g_free (self->psk);
g_free (self->password); g_free (self->leap_password);
g_free (self->pin);
g_free (self->eappsk);
nm_utils_slist_free (self->proto, g_free); nm_utils_slist_free (self->proto, g_free);
nm_utils_slist_free (self->pairwise, g_free); nm_utils_slist_free (self->pairwise, g_free);
nm_utils_slist_free (self->group, g_free); nm_utils_slist_free (self->group, g_free);
nm_utils_slist_free (self->eap, g_free);
if (self->ca_cert)
g_byte_array_free (self->ca_cert, TRUE);
if (self->client_cert)
g_byte_array_free (self->client_cert, TRUE);
if (self->private_key)
g_byte_array_free (self->private_key, TRUE);
if (self->phase2_ca_cert)
g_byte_array_free (self->phase2_ca_cert, TRUE);
if (self->phase2_client_cert)
g_byte_array_free (self->phase2_client_cert, TRUE);
if (self->phase2_private_key)
g_byte_array_free (self->phase2_private_key, TRUE);
G_OBJECT_CLASS (nm_setting_wireless_security_parent_class)->finalize (object); G_OBJECT_CLASS (nm_setting_wireless_security_parent_class)->finalize (object);
} }
@@ -529,69 +288,9 @@ set_property (GObject *object, guint prop_id,
nm_utils_slist_free (setting->group, g_free); nm_utils_slist_free (setting->group, g_free);
setting->group = g_value_dup_boxed (value); setting->group = g_value_dup_boxed (value);
break; break;
case PROP_EAP: case PROP_LEAP_USERNAME:
nm_utils_slist_free (setting->eap, g_free); g_free (setting->leap_username);
setting->eap = g_value_dup_boxed (value); setting->leap_username = g_value_dup_string (value);
break;
case PROP_IDENTITY:
g_free (setting->identity);
setting->identity = g_value_dup_string (value);
break;
case PROP_ANONYMOUS_IDENTITY:
g_free (setting->anonymous_identity);
setting->anonymous_identity = g_value_dup_string (value);
break;
case PROP_CA_CERT:
if (setting->ca_cert)
g_byte_array_free (setting->ca_cert, TRUE);
setting->ca_cert = g_value_dup_boxed (value);
break;
case PROP_CA_PATH:
g_free (setting->ca_path);
setting->ca_path = g_value_dup_string (value);
break;
case PROP_CLIENT_CERT:
if (setting->client_cert)
g_byte_array_free (setting->client_cert, TRUE);
setting->client_cert = g_value_dup_boxed (value);
break;
case PROP_PHASE1_PEAPVER:
g_free (setting->phase1_peapver);
setting->phase1_peapver = g_value_dup_string (value);
break;
case PROP_PHASE1_PEAPLABEL:
g_free (setting->phase1_peaplabel);
setting->phase1_peaplabel = g_value_dup_string (value);
break;
case PROP_PHASE1_FAST_PROVISIONING:
g_free (setting->phase1_fast_provisioning);
setting->phase1_fast_provisioning = g_value_dup_string (value);
break;
case PROP_PHASE2_AUTH:
g_free (setting->phase2_auth);
setting->phase2_auth = g_value_dup_string (value);
break;
case PROP_PHASE2_AUTHEAP:
g_free (setting->phase2_autheap);
setting->phase2_autheap = g_value_dup_string (value);
break;
case PROP_PHASE2_CA_CERT:
if (setting->phase2_ca_cert)
g_byte_array_free (setting->phase2_ca_cert, TRUE);
setting->phase2_ca_cert = g_value_dup_boxed (value);
break;
case PROP_PHASE2_CA_PATH:
g_free (setting->phase2_ca_path);
setting->phase2_ca_path = g_value_dup_string (value);
break;
case PROP_PHASE2_CLIENT_CERT:
if (setting->phase2_client_cert)
g_byte_array_free (setting->phase2_client_cert, TRUE);
setting->phase2_client_cert = g_value_dup_boxed (value);
break;
case PROP_NAI:
g_free (setting->nai);
setting->nai = g_value_dup_string (value);
break; break;
case PROP_WEP_KEY0: case PROP_WEP_KEY0:
g_free (setting->wep_key0); g_free (setting->wep_key0);
@@ -613,27 +312,9 @@ set_property (GObject *object, guint prop_id,
g_free (setting->psk); g_free (setting->psk);
setting->psk = g_value_dup_string (value); setting->psk = g_value_dup_string (value);
break; break;
case PROP_PASSWORD: case PROP_LEAP_PASSWORD:
g_free (setting->password); g_free (setting->leap_password);
setting->password = g_value_dup_string (value); setting->leap_password = g_value_dup_string (value);
break;
case PROP_PIN:
g_free (setting->pin);
setting->pin = g_value_dup_string (value);
break;
case PROP_EAPPSK:
g_free (setting->eappsk);
setting->eappsk = g_value_dup_string (value);
break;
case PROP_PRIVATE_KEY:
if (setting->private_key)
g_byte_array_free (setting->private_key, TRUE);
setting->private_key = g_value_dup_boxed (value);
break;
case PROP_PHASE2_PRIVATE_KEY:
if (setting->phase2_private_key)
g_byte_array_free (setting->phase2_private_key, TRUE);
setting->phase2_private_key = g_value_dup_boxed (value);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -666,50 +347,8 @@ get_property (GObject *object, guint prop_id,
case PROP_GROUP: case PROP_GROUP:
g_value_set_boxed (value, setting->group); g_value_set_boxed (value, setting->group);
break; break;
case PROP_EAP: case PROP_LEAP_USERNAME:
g_value_set_boxed (value, setting->eap); g_value_set_string (value, setting->leap_username);
break;
case PROP_IDENTITY:
g_value_set_string (value, setting->identity);
break;
case PROP_ANONYMOUS_IDENTITY:
g_value_set_string (value, setting->anonymous_identity);
break;
case PROP_CA_CERT:
g_value_set_boxed (value, setting->ca_cert);
break;
case PROP_CA_PATH:
g_value_set_string (value, setting->ca_path);
break;
case PROP_CLIENT_CERT:
g_value_set_boxed (value, setting->client_cert);
break;
case PROP_PHASE1_PEAPVER:
g_value_set_string (value, setting->phase1_peapver);
break;
case PROP_PHASE1_PEAPLABEL:
g_value_set_string (value, setting->phase1_peaplabel);
break;
case PROP_PHASE1_FAST_PROVISIONING:
g_value_set_string (value, setting->phase1_fast_provisioning);
break;
case PROP_PHASE2_AUTH:
g_value_set_string (value, setting->phase2_auth);
break;
case PROP_PHASE2_AUTHEAP:
g_value_set_string (value, setting->phase2_autheap);
break;
case PROP_PHASE2_CA_CERT:
g_value_set_boxed (value, setting->phase2_ca_cert);
break;
case PROP_PHASE2_CA_PATH:
g_value_set_string (value, setting->phase2_ca_path);
break;
case PROP_PHASE2_CLIENT_CERT:
g_value_set_boxed (value, setting->phase2_client_cert);
break;
case PROP_NAI:
g_value_set_string (value, setting->nai);
break; break;
case PROP_WEP_KEY0: case PROP_WEP_KEY0:
g_value_set_string (value, setting->wep_key0); g_value_set_string (value, setting->wep_key0);
@@ -726,20 +365,8 @@ get_property (GObject *object, guint prop_id,
case PROP_PSK: case PROP_PSK:
g_value_set_string (value, setting->psk); g_value_set_string (value, setting->psk);
break; break;
case PROP_PASSWORD: case PROP_LEAP_PASSWORD:
g_value_set_string (value, setting->password); g_value_set_string (value, setting->leap_password);
break;
case PROP_PIN:
g_value_set_string (value, setting->pin);
break;
case PROP_EAPPSK:
g_value_set_string (value, setting->eappsk);
break;
case PROP_PRIVATE_KEY:
g_value_set_boxed (value, setting->private_key);
break;
case PROP_PHASE2_PRIVATE_KEY:
g_value_set_boxed (value, setting->phase2_private_key);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -811,122 +438,10 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property g_object_class_install_property
(object_class, PROP_EAP, (object_class, PROP_LEAP_USERNAME,
nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_EAP, g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME,
"EAP", "LEAP Username",
"EAP", "LEAP Username",
dbus_g_type_get_collection ("GSList", G_TYPE_STRING),
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_IDENTITY,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_IDENTITY,
"Identity",
"Identity",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_ANONYMOUS_IDENTITY,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_ANONYMOUS_IDENTITY,
"Anonymous identity",
"Anonymous identity",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_CA_CERT,
nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_CA_CERT,
"CA certificate",
"CA certificate",
DBUS_TYPE_G_UCHAR_ARRAY,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_CA_PATH,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_CA_PATH,
"CA path",
"CA path",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_CLIENT_CERT,
nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_CLIENT_CERT,
"Client certificate",
"Client certificate",
DBUS_TYPE_G_UCHAR_ARRAY,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_PHASE1_PEAPVER,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE1_PEAPVER,
"Phase1 PEAPVER",
"Phase1 PEAPVER",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_PHASE1_PEAPLABEL,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE1_PEAPLABEL,
"Phase1 PEAP label",
"Phase1 PEAP label",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_PHASE1_FAST_PROVISIONING,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE1_FAST_PROVISIONING,
"Phase1 fast provisioning",
"Phase1 fast provisioning",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_PHASE2_AUTH,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE2_AUTH,
"Phase2 auth",
"Phase2 auth",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_PHASE2_AUTHEAP,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE2_AUTHEAP,
"Phase2 autheap",
"Phase2 autheap",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_PHASE2_CA_CERT,
nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PHASE2_CA_CERT,
"Phase2 CA certificate",
"Phase2 CA certificate",
DBUS_TYPE_G_UCHAR_ARRAY,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_PHASE2_CA_PATH,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PHASE2_CA_PATH,
"Phase2 auth CA path",
"Phase2 auth CA path",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_PHASE2_CLIENT_CERT,
nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PHASE2_CLIENT_CERT,
"Phase2 client certificate",
"Phase2 client certificate",
DBUS_TYPE_G_UCHAR_ARRAY,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
g_object_class_install_property
(object_class, PROP_NAI,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_NAI,
"NAI",
"NAI",
NULL, NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
@@ -971,42 +486,10 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
g_object_class_install_property g_object_class_install_property
(object_class, PROP_PASSWORD, (object_class, PROP_LEAP_PASSWORD,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PASSWORD, g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD,
"Password", "LEAP Password",
"Password", "LEAP Password",
NULL, NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
g_object_class_install_property
(object_class, PROP_PIN,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PIN,
"PIN",
"PIN",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
g_object_class_install_property
(object_class, PROP_EAPPSK,
g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_EAPPSK,
"EAPPSK",
"EAPPSK",
NULL,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
g_object_class_install_property
(object_class, PROP_PRIVATE_KEY,
nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PRIVATE_KEY,
"Private key",
"Private key",
DBUS_TYPE_G_UCHAR_ARRAY,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
g_object_class_install_property
(object_class, PROP_PHASE2_PRIVATE_KEY,
nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PHASE2_PRIVATE_KEY,
"Phase2 private key",
"Phase2 private key",
DBUS_TYPE_G_UCHAR_ARRAY,
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
} }

View File

@@ -22,31 +22,13 @@ G_BEGIN_DECLS
#define NM_SETTING_WIRELESS_SECURITY_PROTO "proto" #define NM_SETTING_WIRELESS_SECURITY_PROTO "proto"
#define NM_SETTING_WIRELESS_SECURITY_PAIRWISE "pairwise" #define NM_SETTING_WIRELESS_SECURITY_PAIRWISE "pairwise"
#define NM_SETTING_WIRELESS_SECURITY_GROUP "group" #define NM_SETTING_WIRELESS_SECURITY_GROUP "group"
#define NM_SETTING_WIRELESS_SECURITY_EAP "eap" #define NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME "leap-username"
#define NM_SETTING_WIRELESS_SECURITY_IDENTITY "identity"
#define NM_SETTING_WIRELESS_SECURITY_ANONYMOUS_IDENTITY "anonymous-identity"
#define NM_SETTING_WIRELESS_SECURITY_CA_CERT "ca-cert"
#define NM_SETTING_WIRELESS_SECURITY_CA_PATH "ca-path"
#define NM_SETTING_WIRELESS_SECURITY_CLIENT_CERT "client-cert"
#define NM_SETTING_WIRELESS_SECURITY_PHASE1_PEAPVER "phase1-peapver"
#define NM_SETTING_WIRELESS_SECURITY_PHASE1_PEAPLABEL "phase1-peaplabel"
#define NM_SETTING_WIRELESS_SECURITY_PHASE1_FAST_PROVISIONING "phase1-fast-provisioning"
#define NM_SETTING_WIRELESS_SECURITY_PHASE2_AUTH "phase2-auth"
#define NM_SETTING_WIRELESS_SECURITY_PHASE2_AUTHEAP "phase2-autheap"
#define NM_SETTING_WIRELESS_SECURITY_PHASE2_CA_CERT "phase2-ca-cert"
#define NM_SETTING_WIRELESS_SECURITY_PHASE2_CA_PATH "phase2-ca-path"
#define NM_SETTING_WIRELESS_SECURITY_PHASE2_CLIENT_CERT "phase2-client-cert"
#define NM_SETTING_WIRELESS_SECURITY_NAI "nai"
#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY0 "wep-key0" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY0 "wep-key0"
#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY1 "wep-key1" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY1 "wep-key1"
#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY2 "wep-key2" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY2 "wep-key2"
#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY3 "wep-key3" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY3 "wep-key3"
#define NM_SETTING_WIRELESS_SECURITY_PSK "psk" #define NM_SETTING_WIRELESS_SECURITY_PSK "psk"
#define NM_SETTING_WIRELESS_SECURITY_PASSWORD "password" #define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD "leap-password"
#define NM_SETTING_WIRELESS_SECURITY_PIN "pin"
#define NM_SETTING_WIRELESS_SECURITY_EAPPSK "eappsk"
#define NM_SETTING_WIRELESS_SECURITY_PRIVATE_KEY "private-key"
#define NM_SETTING_WIRELESS_SECURITY_PHASE2_PRIVATE_KEY "phase2-private-key"
typedef struct { typedef struct {
NMSetting parent; NMSetting parent;
@@ -57,31 +39,13 @@ typedef struct {
GSList *proto; /* GSList of strings */ GSList *proto; /* GSList of strings */
GSList *pairwise; /* GSList of strings */ GSList *pairwise; /* GSList of strings */
GSList *group; /* GSList of strings */ GSList *group; /* GSList of strings */
GSList *eap; /* GSList of strings */ char *leap_username;
char *identity;
char *anonymous_identity;
GByteArray *ca_cert;
char *ca_path;
GByteArray *client_cert;
char *phase1_peapver;
char *phase1_peaplabel;
char *phase1_fast_provisioning;
char *phase2_auth;
char *phase2_autheap;
GByteArray *phase2_ca_cert;
char *phase2_ca_path;
GByteArray *phase2_client_cert;
char *nai;
char *wep_key0; char *wep_key0;
char *wep_key1; char *wep_key1;
char *wep_key2; char *wep_key2;
char *wep_key3; char *wep_key3;
char *psk; char *psk;
char *password; char *leap_password;
char *pin;
char *eappsk;
GByteArray *private_key;
GByteArray *phase2_private_key;
} NMSettingWirelessSecurity; } NMSettingWirelessSecurity;
typedef struct { typedef struct {

View File

@@ -279,9 +279,8 @@ verify (NMSetting *setting, GSList *all_settings)
} }
} }
if (self->security && if ( self->security
all_settings && && !g_slist_find_custom (all_settings, self->security, find_setting_by_name)) {
!g_slist_find_custom (all_settings, self->security, find_setting_by_name)) {
g_warning ("Invalid or missing security"); g_warning ("Invalid or missing security");
return FALSE; return FALSE;
} }

View File

@@ -1,6 +1,7 @@
VOID:OBJECT VOID:OBJECT
VOID:OBJECT,STRING VOID:OBJECT,STRING
VOID:OBJECT,UINT VOID:OBJECT,UINT
VOID:OBJECT,POINTER
VOID:POINTER VOID:POINTER
VOID:STRING,STRING,STRING VOID:STRING,STRING,STRING
VOID:UINT,UINT VOID:UINT,UINT

View File

@@ -21,10 +21,12 @@
#include <string.h> #include <string.h>
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
#include "nm-activation-request.h" #include "nm-activation-request.h"
#include "nm-marshal.h" #include "nm-marshal.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h"
#include "nm-setting-8021x.h"
#include "nm-manager.h" /* FIXME! */ #include "nm-manager.h" /* FIXME! */
@@ -108,9 +110,9 @@ nm_act_request_class_init (NMActRequestClass *req_class)
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMActRequestClass, connection_secrets_updated), G_STRUCT_OFFSET (NMActRequestClass, connection_secrets_updated),
NULL, NULL, NULL, NULL,
nm_marshal_VOID__OBJECT_STRING, nm_marshal_VOID__OBJECT_POINTER,
G_TYPE_NONE, 2, G_TYPE_NONE, 2,
G_TYPE_OBJECT, G_TYPE_STRING); G_TYPE_OBJECT, G_TYPE_POINTER);
signals[CONNECTION_SECRETS_FAILED] = signals[CONNECTION_SECRETS_FAILED] =
g_signal_new ("connection-secrets-failed", g_signal_new ("connection-secrets-failed",
@@ -158,17 +160,93 @@ free_get_secrets_info (gpointer data)
GetSecretsInfo *info = (GetSecretsInfo *) data; GetSecretsInfo *info = (GetSecretsInfo *) data;
g_free (info->setting_name); g_free (info->setting_name);
g_slice_free (GetSecretsInfo, info); g_free (info);
} }
static void
update_one_setting (const char* key,
GHashTable *setting_hash,
NMConnection *connection,
GSList **updated)
{
GType type;
NMSetting *setting = NULL;
/* Check whether a complete & valid NMSetting object was returned. If
* yes, replace the setting object in the connection. If not, just try
* updating the secrets.
*/
type = nm_connection_lookup_setting_type (key);
if (type == 0)
return;
setting = nm_setting_from_hash (type, setting_hash);
if (setting) {
NMSetting *s_8021x = NULL;
GSList *all_settings = NULL;
/* The wireless-security setting might need the 802.1x setting in
* the all_settings argument of the verify function. Ugh.
*/
s_8021x = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
if (s_8021x)
all_settings = g_slist_append (all_settings, s_8021x);
if (!nm_setting_verify (setting, all_settings)) {
/* Just try updating secrets */
g_object_unref (setting);
setting = NULL;
}
g_slist_free (all_settings);
}
if (setting)
nm_connection_add_setting (connection, setting);
else
nm_connection_update_secrets (connection, key, setting_hash);
*updated = g_slist_append (*updated, (gpointer) key);
}
static void
add_one_key_to_list (gpointer key, gpointer data, gpointer user_data)
{
GSList **list = (GSList **) user_data;
*list = g_slist_append (*list, key);
}
static gint
settings_order_func (gconstpointer a, gconstpointer b)
{
/* Just ensure the 802.1x setting gets processed _before_ the
* wireless-security one.
*/
if ( !strcmp (a, NM_SETTING_802_1X_SETTING_NAME)
&& !strcmp (b, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME))
return -1;
if ( !strcmp (a, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)
&& !strcmp (b, NM_SETTING_802_1X_SETTING_NAME))
return 1;
return 0;
}
#define DBUS_TYPE_G_STRING_VARIANT_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
#define DBUS_TYPE_G_DICT_OF_DICTS (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE))
static void static void
get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
{ {
GetSecretsInfo *info = (GetSecretsInfo *) user_data; GetSecretsInfo *info = (GetSecretsInfo *) user_data;
GError *err = NULL; GError *err = NULL;
GHashTable *secrets = NULL; GHashTable *settings = NULL;
NMActRequestPrivate *priv = NULL; NMActRequestPrivate *priv = NULL;
NMSetting *setting = NULL; GSList *keys = NULL, *iter;
GSList *updated = NULL;
g_return_if_fail (info != NULL); g_return_if_fail (info != NULL);
g_return_if_fail (info->req); g_return_if_fail (info->req);
@@ -178,7 +256,7 @@ get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
g_object_set_data (G_OBJECT (priv->connection), CONNECTION_GET_SECRETS_CALL_TAG, NULL); g_object_set_data (G_OBJECT (priv->connection), CONNECTION_GET_SECRETS_CALL_TAG, NULL);
if (!dbus_g_proxy_end_call (proxy, call, &err, if (!dbus_g_proxy_end_call (proxy, call, &err,
dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &secrets, DBUS_TYPE_G_DICT_OF_DICTS, &settings,
G_TYPE_INVALID)) { G_TYPE_INVALID)) {
nm_warning ("Couldn't get connection secrets: %s.", err->message); nm_warning ("Couldn't get connection secrets: %s.", err->message);
g_error_free (err); g_error_free (err);
@@ -190,39 +268,41 @@ get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
return; return;
} }
if (g_hash_table_size (secrets) == 0) { if (g_hash_table_size (settings) == 0) {
// FIXME: some better way to handle invalid message? // FIXME: some better way to handle invalid message?
nm_warning ("GetSecrets call returned but no secrets were found."); nm_warning ("GetSecrets call returned but no secrets were found.");
goto out; goto out;
} }
/* Check whether a complete & valid NMSetting object was returned. If g_hash_table_foreach (settings, add_one_key_to_list, &keys);
* yes, replace the setting object in the connection. If not, just try keys = g_slist_sort (keys, settings_order_func);
* updating the secrets. for (iter = keys; iter; iter = g_slist_next (iter)) {
*/ GHashTable *setting_hash;
if (!strcmp (info->setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME))
setting = nm_setting_from_hash (NM_TYPE_SETTING_WIRELESS_SECURITY, secrets);
if (setting) { setting_hash = g_hash_table_lookup (settings, iter->data);
if (!nm_setting_verify (setting, NULL)) { if (setting_hash) {
g_object_unref (setting); update_one_setting ((const char *) iter->data,
setting = NULL; setting_hash,
} priv->connection,
&updated);
} else
nm_warning ("Couldn't get setting secrets for '%s'", (const char *) iter->data);
}
g_slist_free (keys);
if (g_slist_length (updated)) {
g_signal_emit (info->req,
signals[CONNECTION_SECRETS_UPDATED],
0,
priv->connection,
updated);
} else {
nm_warning ("No secrets updated because not valid settings were received!");
} }
if (setting)
nm_connection_add_setting (priv->connection, setting);
else
nm_connection_update_secrets (priv->connection, info->setting_name, secrets);
g_signal_emit (info->req,
signals[CONNECTION_SECRETS_UPDATED],
0,
priv->connection,
info->setting_name);
out: out:
g_hash_table_destroy (secrets); g_slist_free (updated);
g_hash_table_destroy (settings);
} }
#define DBUS_TYPE_STRING_ARRAY (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING)) #define DBUS_TYPE_STRING_ARRAY (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING))
@@ -248,7 +328,7 @@ nm_act_request_request_connection_secrets (NMActRequest *req,
goto error; goto error;
} }
info = g_slice_new0 (GetSecretsInfo); info = g_malloc0 (sizeof (GetSecretsInfo));
if (!info) { if (!info) {
nm_warning ("Not enough memory to get secrets"); nm_warning ("Not enough memory to get secrets");
goto error; goto error;

View File

@@ -43,7 +43,7 @@ typedef struct {
/* Signals */ /* Signals */
void (*connection_secrets_updated) (NMActRequest *req, void (*connection_secrets_updated) (NMActRequest *req,
NMConnection *connection, NMConnection *connection,
const char * setting); GSList *updated_settings);
void (*connection_secrets_failed) (NMActRequest *req, void (*connection_secrets_failed) (NMActRequest *req,
NMConnection *connection, NMConnection *connection,
const char * setting); const char * setting);

View File

@@ -198,18 +198,27 @@ real_get_generic_capabilities (NMDevice *dev)
static void static void
real_connection_secrets_updated (NMDevice *dev, real_connection_secrets_updated (NMDevice *dev,
NMConnection *connection, NMConnection *connection,
const char *setting_name) GSList *updated_settings)
{ {
NMActRequest *req; NMActRequest *req;
gboolean found = FALSE;
GSList *iter;
if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH) if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH)
return; return;
if (strcmp (setting_name, NM_SETTING_CDMA_SETTING_NAME) != 0) { for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name); const char *setting_name = (const char *) iter->data;
return;
if (!strcmp (setting_name, NM_SETTING_CDMA_SETTING_NAME))
found = TRUE;
else
nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name);
} }
if (!found)
return;
req = nm_device_get_act_request (dev); req = nm_device_get_act_request (dev);
g_assert (req); g_assert (req);

View File

@@ -46,6 +46,8 @@
#include "nm-properties-changed-signal.h" #include "nm-properties-changed-signal.h"
#include "nm-setting-connection.h" #include "nm-setting-connection.h"
#include "nm-setting-wireless.h" #include "nm-setting-wireless.h"
#include "nm-setting-wireless-security.h"
#include "nm-setting-8021x.h"
static gboolean impl_device_get_access_points (NMDevice80211Wireless *device, static gboolean impl_device_get_access_points (NMDevice80211Wireless *device,
GPtrArray **aps, GPtrArray **aps,
@@ -2454,9 +2456,12 @@ build_supplicant_config (NMDevice80211Wireless *self,
if (s_wireless_sec) { if (s_wireless_sec) {
DBusGProxy *proxy = g_object_get_data (G_OBJECT (connection), NM_MANAGER_CONNECTION_PROXY_TAG); DBusGProxy *proxy = g_object_get_data (G_OBJECT (connection), NM_MANAGER_CONNECTION_PROXY_TAG);
const char *con_path = dbus_g_proxy_get_path (proxy); const char *con_path = dbus_g_proxy_get_path (proxy);
NMSetting8021x *s_8021x;
s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
if (!nm_supplicant_config_add_setting_wireless_security (config, if (!nm_supplicant_config_add_setting_wireless_security (config,
s_wireless_sec, s_wireless_sec,
s_8021x,
con_path)) { con_path)) {
nm_warning ("Couldn't add 802-11-wireless-security setting to " nm_warning ("Couldn't add 802-11-wireless-security setting to "
"supplicant config."); "supplicant config.");
@@ -2582,16 +2587,24 @@ real_act_stage1_prepare (NMDevice *dev)
static void static void
real_connection_secrets_updated (NMDevice *dev, real_connection_secrets_updated (NMDevice *dev,
NMConnection *connection, NMConnection *connection,
const char *setting_name) GSList *updated_settings)
{ {
NMActRequest *req; NMActRequest *req;
gboolean valid = FALSE;
GSList *iter;
if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH) if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH)
return; return;
if (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != 0) { for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name); const char *setting_name = (const char *) iter->data;
return;
if ( !strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)
|| !strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME)) {
valid = TRUE;
} else {
nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name);
}
} }
req = nm_device_get_act_request (dev); req = nm_device_get_act_request (dev);

View File

@@ -484,8 +484,8 @@ real_get_best_auto_connection (NMDevice *dev,
static void static void
real_connection_secrets_updated (NMDevice *dev, real_connection_secrets_updated (NMDevice *dev,
NMConnection *connection, NMConnection *connection,
const char *setting_name) GSList *updated_settings)
{ {
NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (dev); NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (dev);

View File

@@ -1119,13 +1119,13 @@ nm_device_check_connection_conflicts (NMDeviceInterface *dev_iface,
static void static void
connection_secrets_updated_cb (NMActRequest *req, connection_secrets_updated_cb (NMActRequest *req,
NMConnection *connection, NMConnection *connection,
const char *setting_name, GSList *updated_settings,
gpointer user_data) gpointer user_data)
{ {
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
if (NM_DEVICE_GET_CLASS (self)->connection_secrets_updated) if (NM_DEVICE_GET_CLASS (self)->connection_secrets_updated)
NM_DEVICE_GET_CLASS (self)->connection_secrets_updated (self, connection, setting_name); NM_DEVICE_GET_CLASS (self)->connection_secrets_updated (self, connection, updated_settings);
} }
static void static void

View File

@@ -83,7 +83,7 @@ struct _NMDeviceClass
void (* connection_secrets_updated) (NMDevice *self, void (* connection_secrets_updated) (NMDevice *self,
NMConnection *connection, NMConnection *connection,
const char *setting_name); GSList *updated_settings);
gboolean (* check_connection_conflicts) (NMDevice *self, gboolean (* check_connection_conflicts) (NMDevice *self,
NMConnection *connection, NMConnection *connection,

View File

@@ -506,18 +506,27 @@ real_get_generic_capabilities (NMDevice *dev)
static void static void
real_connection_secrets_updated (NMDevice *dev, real_connection_secrets_updated (NMDevice *dev,
NMConnection *connection, NMConnection *connection,
const char *setting_name) GSList *updated_settings)
{ {
NMActRequest *req; NMActRequest *req;
gboolean found = FALSE;
GSList *iter;
if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH) if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH)
return; return;
if (strcmp (setting_name, NM_SETTING_GSM_SETTING_NAME) != 0) { for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name); const char *setting_name = (const char *) iter->data;
return;
if (!strcmp (setting_name, NM_SETTING_GSM_SETTING_NAME))
found = TRUE;
else
nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name);
} }
if (!found)
return;
req = nm_device_get_act_request (dev); req = nm_device_get_act_request (dev);
g_assert (req); g_assert (req);

View File

@@ -464,8 +464,9 @@ get_blob_id (const char *name, const char *seed_uid)
} }
gboolean gboolean
nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig * self, nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
NMSettingWirelessSecurity * setting, NMSettingWirelessSecurity *setting,
NMSetting8021x *setting_8021x,
const char *connection_uid) const char *connection_uid)
{ {
NMSupplicantConfigPrivate *priv; NMSupplicantConfigPrivate *priv;
@@ -480,20 +481,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig * self,
ADD_STRING_VAL (setting->key_mgmt, "key_mgmt", TRUE, FALSE, FALSE); ADD_STRING_VAL (setting->key_mgmt, "key_mgmt", TRUE, FALSE, FALSE);
ADD_STRING_VAL (setting->auth_alg, "auth_alg", TRUE, FALSE, FALSE); ADD_STRING_VAL (setting->auth_alg, "auth_alg", TRUE, FALSE, FALSE);
ADD_STRING_VAL (setting->nai, "nai", FALSE, FALSE, FALSE);
ADD_STRING_VAL (setting->psk, "psk", FALSE, TRUE, TRUE); ADD_STRING_VAL (setting->psk, "psk", FALSE, TRUE, TRUE);
ADD_STRING_VAL (setting->password, "password", FALSE, FALSE, TRUE);
ADD_STRING_VAL (setting->pin, "pin", FALSE, FALSE, TRUE);
ADD_STRING_VAL (setting->eappsk, "eappsk", FALSE, TRUE, TRUE);
/* Private key passwords are never passed to wpa_supplicant because the
* user agent is responsible for decoding and decrypting the private key,
* and file paths are never passed to wpa_supplicant to ensure that
* the supplicant can be locked down and doesn't try to read stuff from
* all over the drive.
*/
ADD_STRING_LIST_VAL (setting->eap, "eap", TRUE, FALSE);
/* Only WPA-specific things when using WPA */ /* Only WPA-specific things when using WPA */
if ( !strcmp (setting->key_mgmt, "wpa-none") if ( !strcmp (setting->key_mgmt, "wpa-none")
@@ -522,60 +510,112 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig * self,
} }
} }
/* 802.1 stuff for Dynamic WEP and WPA-Enterprise */ if (setting->auth_alg && !strcmp (setting->auth_alg, "leap")) {
if ( (strcmp (setting->key_mgmt, "ieee8021x") == 0) /* LEAP */
|| (strcmp (setting->key_mgmt, "wpa-eap") == 0)) { if (!strcmp (setting->key_mgmt, "ieee8021x")) {
GString *phase1, *phase2; ADD_STRING_VAL (setting->leap_username, "identity", FALSE, FALSE, FALSE);
char *tmp; ADD_STRING_VAL (setting->leap_password, "password", FALSE, FALSE, TRUE);
ADD_STRING_VAL ("leap", "eap", TRUE, FALSE, FALSE);
/* Drop the fragment size a bit for better compatibility */ } else {
if (!nm_supplicant_config_add_option (self, "fragment_size", "1300", -1, FALSE))
return FALSE; return FALSE;
phase1 = g_string_new (NULL);
if (setting->phase1_peapver)
g_string_append_printf (phase1, "peapver=%s", setting->phase1_peapver);
if (setting->phase1_peaplabel) {
if (phase1->len)
g_string_append_c (phase1, ' ');
g_string_append_printf (phase1, "peaplabel=%s", setting->phase1_peaplabel);
} }
} else {
if (phase1->len) /* 802.1x for Dynamic WEP and WPA-Enterprise */
ADD_STRING_VAL (phase1->str, "phase1", FALSE, FALSE, FALSE); if ( !strcmp (setting->key_mgmt, "ieee8021x")
g_string_free (phase1, TRUE); || !strcmp (setting->key_mgmt, "wpa-eap")) {
if (!setting_8021x)
phase2 = g_string_new (NULL); return FALSE;
if (setting->phase2_auth) { if (!nm_supplicant_config_add_setting_8021x (self, setting_8021x, connection_uid, FALSE))
tmp = g_ascii_strup (setting->phase2_auth, -1); return FALSE;
g_string_append_printf (phase2, "auth=%s", tmp);
g_free (tmp);
} }
if (setting->phase2_autheap) {
if (phase2->len)
g_string_append_c (phase2, ' ');
tmp = g_ascii_strup (setting->phase2_autheap, -1);
g_string_append_printf (phase2, "autheap=%s", tmp);
g_free (tmp);
}
if (phase2->len)
ADD_STRING_VAL (phase2->str, "phase2", FALSE, FALSE, FALSE);
g_string_free (phase2, TRUE);
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);
ADD_STRING_VAL (setting->identity, "identity", FALSE, FALSE, FALSE);
ADD_STRING_VAL (setting->anonymous_identity, "anonymous_identity", FALSE, FALSE, FALSE);
} }
return TRUE; return TRUE;
} }
gboolean
nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
NMSetting8021x *setting,
const char *connection_uid,
gboolean wired)
{
NMSupplicantConfigPrivate *priv;
char * value;
gboolean success;
GString *phase1, *phase2;
char *tmp;
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);
ADD_STRING_VAL (setting->password, "password", FALSE, FALSE, TRUE);
ADD_STRING_VAL (setting->pin, "pin", FALSE, FALSE, TRUE);
if (wired) {
ADD_STRING_VAL ("IEEE8021X", "key_mgmt", TRUE, FALSE, FALSE);
/* Wired 802.1x must always use eapol_flags=0 */
ADD_STRING_VAL ("0", "eapol_flags", FALSE, FALSE, FALSE);
}
/* Private key passwords are never passed to wpa_supplicant because the
* user agent is responsible for decoding and decrypting the private key,
* and file paths are never passed to wpa_supplicant to ensure that
* the supplicant can be locked down and doesn't try to read stuff from
* all over the drive.
*/
ADD_STRING_LIST_VAL (setting->eap, "eap", TRUE, FALSE);
/* Drop the fragment size a bit for better compatibility */
if (!nm_supplicant_config_add_option (self, "fragment_size", "1300", -1, FALSE))
return FALSE;
phase1 = g_string_new (NULL);
if (setting->phase1_peapver)
g_string_append_printf (phase1, "peapver=%s", setting->phase1_peapver);
if (setting->phase1_peaplabel) {
if (phase1->len)
g_string_append_c (phase1, ' ');
g_string_append_printf (phase1, "peaplabel=%s", setting->phase1_peaplabel);
}
if (phase1->len)
ADD_STRING_VAL (phase1->str, "phase1", FALSE, FALSE, FALSE);
g_string_free (phase1, TRUE);
phase2 = g_string_new (NULL);
if (setting->phase2_auth) {
tmp = g_ascii_strup (setting->phase2_auth, -1);
g_string_append_printf (phase2, "auth=%s", tmp);
g_free (tmp);
}
if (setting->phase2_autheap) {
if (phase2->len)
g_string_append_c (phase2, ' ');
tmp = g_ascii_strup (setting->phase2_autheap, -1);
g_string_append_printf (phase2, "autheap=%s", tmp);
g_free (tmp);
}
if (phase2->len)
ADD_STRING_VAL (phase2->str, "phase2", FALSE, FALSE, FALSE);
g_string_free (phase2, TRUE);
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);
ADD_STRING_VAL (setting->identity, "identity", FALSE, FALSE, FALSE);
ADD_STRING_VAL (setting->anonymous_identity, "anonymous_identity", FALSE, FALSE, FALSE);
return TRUE;
}

View File

@@ -24,6 +24,8 @@
#include <glib-object.h> #include <glib-object.h>
#include <nm-setting-wireless.h> #include <nm-setting-wireless.h>
#include <nm-setting-wireless-security.h>
#include <nm-setting-8021x.h>
#include "nm-supplicant-types.h" #include "nm-supplicant-types.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -71,10 +73,16 @@ gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
guint32 adhoc_freq, guint32 adhoc_freq,
gboolean has_scan_capa_ssid); gboolean has_scan_capa_ssid);
gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig * self, gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
NMSettingWirelessSecurity * setting, NMSettingWirelessSecurity *setting,
NMSetting8021x *setting_8021x,
const char *connection_uid); const char *connection_uid);
gboolean nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
NMSetting8021x *setting,
const char *connection_uid,
gboolean wired);
G_END_DECLS G_END_DECLS
#endif /* NM_SUPPLICANT_CONFIG_H */ #endif /* NM_SUPPLICANT_CONFIG_H */