2007-09-25 Dan Williams <dcbw@redhat.com>

Properly re-query secrets from the settings daemon when stuff fails.

	* src/nm-device-802-11-wireless.c
		- (ap_auth_enforced): handle static WEP correctly here by differentiating
			between Shared Key and Open System auth modes
		- (link_timeout_cb, supplicant_connection_timeout_cb,
		   real_act_stage4_ip_config_timeout): clear existing secrets and
			request new ones when something fails due to a suspected wrong key
		- (real_act_stage2_config): fix for new request_new argument to
			nm_manager_get_connection_secrets()

	* src/nm-manager.c
	  src/nm-manager.h
		- (nm_manager_get_connection_secrets): return error status; pass
			new request_new argument on to the settings daemon

	* introspection/nm-settings-connection.xml
		- New 'request_new' argument to the GetSecrets call that hints to the
			settings daemon to ask the user for completely new secrets

	* libnm-glib/nm-settings.c
	  libnm-glib/nm-settings.h
		- (impl_connection_settings_get_secrets): handle new 'request_new'
			argument



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2872 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2007-09-25 06:21:38 +00:00
parent 008bab498f
commit 1817c62082
7 changed files with 137 additions and 35 deletions

View File

@@ -1,3 +1,30 @@
2007-09-25 Dan Williams <dcbw@redhat.com>
Properly re-query secrets from the settings daemon when stuff fails.
* src/nm-device-802-11-wireless.c
- (ap_auth_enforced): handle static WEP correctly here by differentiating
between Shared Key and Open System auth modes
- (link_timeout_cb, supplicant_connection_timeout_cb,
real_act_stage4_ip_config_timeout): clear existing secrets and
request new ones when something fails due to a suspected wrong key
- (real_act_stage2_config): fix for new request_new argument to
nm_manager_get_connection_secrets()
* src/nm-manager.c
src/nm-manager.h
- (nm_manager_get_connection_secrets): return error status; pass
new request_new argument on to the settings daemon
* introspection/nm-settings-connection.xml
- New 'request_new' argument to the GetSecrets call that hints to the
settings daemon to ask the user for completely new secrets
* libnm-glib/nm-settings.c
libnm-glib/nm-settings.h
- (impl_connection_settings_get_secrets): handle new 'request_new'
argument
2007-09-25 Dan Williams <dcbw@redhat.com>
* libnm-util/nm-connection.c

View File

@@ -18,6 +18,7 @@
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_connection_settings_get_secrets"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="setting_name" type="s" direction="in"/>
<arg name="request_new" type="b" direction="in"/>
<arg name="secrets" type="a{sv}" direction="out"/>
</method>

View File

@@ -117,6 +117,7 @@ static gboolean impl_connection_settings_get_settings (NMConnectionSettings *con
GError **error);
static void impl_connection_settings_get_secrets (NMConnectionSettings *connection,
const gchar *setting_name,
gboolean request_new,
DBusGMethodInvocation *context);
#include "nm-settings-connection-glue.h"
@@ -171,6 +172,7 @@ impl_connection_settings_get_settings (NMConnectionSettings *connection,
static void
impl_connection_settings_get_secrets (NMConnectionSettings *connection,
const gchar *setting_name,
gboolean request_new,
DBusGMethodInvocation *context)
{
GError *error = NULL;
@@ -189,7 +191,7 @@ impl_connection_settings_get_secrets (NMConnectionSettings *connection,
return;
}
CONNECTION_SETTINGS_CLASS (connection)->get_secrets (connection, setting_name, context);
CONNECTION_SETTINGS_CLASS (connection)->get_secrets (connection, setting_name, request_new, context);
}
static void

View File

@@ -29,6 +29,7 @@ typedef struct {
GHashTable * (* get_settings) (NMConnectionSettings *connection);
void (* get_secrets) (NMConnectionSettings *connection,
const gchar *setting_name,
gboolean request_new,
DBusGMethodInvocation *context);
/* signals */

View File

@@ -1605,11 +1605,12 @@ out:
*
*/
static gboolean
ap_auth_enforced (NMAccessPoint *ap)
ap_auth_enforced (NMConnection *connection, NMAccessPoint *ap)
{
guint32 flags, wpa_flags, rsn_flags;
g_return_val_if_fail (ap != NULL, FALSE);
g_return_val_if_fail (NM_IS_AP (ap), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
if (nm_ap_get_mode (ap) == IW_MODE_ADHOC)
return FALSE;
@@ -1618,15 +1619,33 @@ ap_auth_enforced (NMAccessPoint *ap)
wpa_flags = nm_ap_get_wpa_flags (ap);
rsn_flags = nm_ap_get_rsn_flags (ap);
if (flags & NM_802_11_AP_FLAGS_PRIVACY)
return TRUE;
/* Static WEP */
if ( (flags & NM_802_11_AP_FLAGS_PRIVACY)
&& (wpa_flags == NM_802_11_AP_SEC_NONE)
&& (rsn_flags == NM_802_11_AP_SEC_NONE)) {
NMSettingWirelessSecurity *s_wireless_sec;
/* No way to tell if the key is wrong with Open System
* auth mode in WEP. Auth is not enforced like Shared Key.
*/
s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS_SECURITY);
if (s_wireless_sec &&
(!s_wireless_sec->auth_alg ||
!strcmp (s_wireless_sec->auth_alg, "open")))
return FALSE;
return TRUE;
}
/* WPA */
if (wpa_flags != NM_802_11_AP_SEC_NONE)
return TRUE;
/* WPA2 */
if (rsn_flags != NM_802_11_AP_SEC_NONE)
return TRUE;
/* No encryption */
return FALSE;
}
@@ -1883,12 +1902,14 @@ link_timeout_cb (gpointer user_data)
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
NMActRequest * req = NULL;
NMAccessPoint * ap = NULL;
NMConnection * connection;
NMManager * manager;
const char * setting_name;
g_assert (dev);
if (self->priv->link_timeout_id) {
if (self->priv->link_timeout_id)
self->priv->link_timeout_id = 0;
}
req = nm_device_get_act_request (dev);
ap = nm_device_802_11_wireless_get_activation_ap (self);
@@ -1906,19 +1927,42 @@ link_timeout_cb (gpointer user_data)
* ARE checked - we are likely to have wrong key. Ask the user for
* another one.
*/
if ((nm_device_get_state (dev) == NM_DEVICE_STATE_CONFIG)
&& ap_auth_enforced (ap)) {
/* Association/authentication failed, we must have bad encryption key */
nm_info ("Activation (%s/wireless): disconnected during association,"
" asking for new key.", nm_device_get_iface (dev));
cleanup_association_attempt (self, TRUE);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
// FIXME: get secrets from the info-daemon
} else {
nm_info ("%s: link timed out.", nm_device_get_iface (dev));
nm_device_set_active_link (dev, FALSE);
}
if (nm_device_get_state (dev) != NM_DEVICE_STATE_CONFIG)
goto time_out;
connection = nm_act_request_get_connection (req);
if (!connection)
goto time_out;
if (!ap_auth_enforced (connection, ap))
goto time_out;
nm_connection_clear_secrets (connection);
setting_name = nm_connection_need_secrets (connection);
if (!setting_name)
goto time_out;
/* Association/authentication failed during association, probably have a
* bad encryption key and the authenticating entity (AP, RADIUS server, etc)
* denied the association due to bad credentials.
*/
nm_info ("Activation (%s/wireless): disconnected during association,"
" asking for new key.", nm_device_get_iface (dev));
cleanup_association_attempt (self, TRUE);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
manager = nm_manager_get ();
nm_manager_get_connection_secrets (manager,
NM_DEVICE_INTERFACE (self),
connection,
setting_name,
TRUE);
g_object_unref (manager);
return FALSE;
time_out:
nm_info ("%s: link timed out.", nm_device_get_iface (dev));
nm_device_set_active_link (dev, FALSE);
return FALSE;
}
@@ -2268,6 +2312,8 @@ supplicant_connection_timeout_cb (gpointer user_data)
NMDevice * dev = NM_DEVICE (user_data);
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
NMAccessPoint * ap = nm_device_802_11_wireless_get_activation_ap (self);
NMActRequest * req = nm_device_get_act_request (dev);
NMConnection * connection = NULL;
cleanup_association_attempt (self, TRUE);
@@ -2276,7 +2322,10 @@ supplicant_connection_timeout_cb (gpointer user_data)
* WEP, for example) then we are likely using the wrong authentication
* algorithm or key. Request new one from the user.
*/
if (ap_auth_enforced (ap)) {
if (req)
connection = nm_act_request_get_connection (req);
if (!connection || ap_auth_enforced (connection, ap)) {
if (nm_device_is_activating (dev)) {
/* Kicked off by the authenticator most likely */
nm_info ("Activation (%s/wireless): association took too long, "
@@ -2286,13 +2335,20 @@ supplicant_connection_timeout_cb (gpointer user_data)
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED);
}
} else {
NMManager *manager = nm_manager_get ();
/* Activation failed, encryption key is probably bad */
nm_info ("Activation (%s/wireless): association took too long, "
"asking for new key.",
nm_device_get_iface (dev));
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
// FIXME: get secrets from the info-daemon
nm_manager_get_connection_secrets (manager,
NM_DEVICE_INTERFACE (self),
connection,
NM_SETTING_WIRELESS_SECURITY,
TRUE);
g_object_unref (manager);
}
return FALSE;
@@ -2484,7 +2540,8 @@ real_act_stage2_config (NMDevice *dev)
nm_manager_get_connection_secrets (manager,
NM_DEVICE_INTERFACE (self),
connection,
setting_name);
setting_name,
FALSE);
return NM_ACT_STAGE_RETURN_POSTPONE;
} else {
NMSettingWireless *s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS);
@@ -2612,6 +2669,8 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
NMAccessPoint * ap = nm_device_802_11_wireless_get_activation_ap (self);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
NMIP4Config * real_config = NULL;
NMActRequest * req = nm_device_get_act_request (dev);
NMConnection * connection;
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
@@ -2622,15 +2681,23 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
* Open System WEP for example), and DHCP times out, then
* the encryption key is likely wrong. Ask the user for a new one.
*/
if (!ap_auth_enforced (ap)) {
connection = nm_act_request_get_connection (req);
if (!ap_auth_enforced (connection, ap)) {
NMManager *manager = nm_manager_get ();
const GByteArray * ssid = nm_ap_get_ssid (ap);
/* Activation failed, we must have bad encryption key */
nm_debug ("Activation (%s/wireless): could not get IP configuration info for '%s', asking for new key.",
nm_debug ("Activation (%s/wireless): could not get IP configuration "
"info for '%s', asking for new key.",
nm_device_get_iface (dev),
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
// FIXME: request new secrets from info-daemon
nm_manager_get_connection_secrets (manager,
NM_DEVICE_INTERFACE (self),
connection,
NM_SETTING_WIRELESS_SECURITY,
TRUE);
g_object_unref (manager);
ret = NM_ACT_STAGE_RETURN_POSTPONE;
} else if (nm_ap_get_mode (ap) == IW_MODE_ADHOC) {
NMDevice80211WirelessClass * klass;

View File

@@ -1046,17 +1046,18 @@ get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
g_hash_table_destroy (secrets);
}
void
gboolean
nm_manager_get_connection_secrets (NMManager *manager,
NMDeviceInterface *device,
NMConnection *connection,
const char *setting_name)
const char *setting_name,
gboolean request_new)
{
DBusGProxy *proxy;
GetSecretsInfo *info = NULL;
g_return_if_fail (NM_IS_MANAGER (manager));
g_return_if_fail (NM_IS_CONNECTION (connection));
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
proxy = g_object_get_data (G_OBJECT (connection), CONNECTION_PROXY_TAG);
if (!DBUS_IS_G_PROXY (proxy)) {
@@ -1086,14 +1087,16 @@ nm_manager_get_connection_secrets (NMManager *manager,
free_get_secrets_info,
G_MAXINT32,
G_TYPE_STRING, setting_name,
G_TYPE_BOOLEAN, request_new,
G_TYPE_INVALID)) {
nm_warning ("Could not call GetSecrets");
goto error;
}
return;
return TRUE;
error:
if (info)
free_get_secrets_info (info);
return FALSE;
}

View File

@@ -77,9 +77,10 @@ const char * nm_manager_get_connection_service_name (NMManager *manager,
const char * nm_manager_get_connection_dbus_path (NMManager *manager,
NMConnection *connection);
void nm_manager_get_connection_secrets (NMManager *manager,
NMDeviceInterface *device,
NMConnection *connection,
const char * setting_name);
gboolean nm_manager_get_connection_secrets (NMManager *manager,
NMDeviceInterface *device,
NMConnection *connection,
const char * setting_name,
gboolean request_new);
#endif /* NM_MANAGER_H */