2008-04-02 Dan Williams <dcbw@redhat.com>

* src/nm-device-interface.c
	  src/nm-device-interface.h
	  src/nm-device.c
	  src/nm-device.h
		- Rename check_connection_conflicts() to check_connection_compatible()

	* src/nm-device-802-11-wireless.c
		- (real_check_connection_conflicts): remove
		- (real_check_connection_compatible): implement; match MAC address

	* src/nm-device-802-3-ethernet.c
		- (real_check_connection_conflicts): remove
		- (real_check_connection_compatible): implement; match MAC address
		- (real_get_best_auto_connection): correctly handle PPPoE cases

	* src/nm-manager.c
		- (check_connection_allowed): remove; unused until PolicyKit integration
		- (internal_activate_device): check whether the connection is compatible
			with the device before trying to activate it



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3527 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2008-04-02 17:44:52 +00:00
parent ebccea23f9
commit 85eb6bd5c3
8 changed files with 230 additions and 106 deletions

View file

@ -1,3 +1,25 @@
2008-04-02 Dan Williams <dcbw@redhat.com>
* src/nm-device-interface.c
src/nm-device-interface.h
src/nm-device.c
src/nm-device.h
- Rename check_connection_conflicts() to check_connection_compatible()
* src/nm-device-802-11-wireless.c
- (real_check_connection_conflicts): remove
- (real_check_connection_compatible): implement; match MAC address
* src/nm-device-802-3-ethernet.c
- (real_check_connection_conflicts): remove
- (real_check_connection_compatible): implement; match MAC address
- (real_get_best_auto_connection): correctly handle PPPoE cases
* src/nm-manager.c
- (check_connection_allowed): remove; unused until PolicyKit integration
- (internal_activate_device): check whether the connection is compatible
with the device before trying to activate it
2008-04-02 Dan Williams <dcbw@redhat.com>
* system-settings/plugins/ifcfg-fedora/parser.c

View file

@ -99,6 +99,17 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
typedef enum
{
NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0,
NM_WIFI_ERROR_CONNECTION_INVALID,
NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE,
} NMWifiError;
#define NM_WIFI_ERROR (nm_wifi_error_quark ())
#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ())
typedef struct Supplicant {
NMSupplicantManager * mgr;
NMSupplicantInterface * iface;
@ -195,6 +206,38 @@ static void device_cleanup (NMDevice80211Wireless *self);
static guint32 nm_device_802_11_wireless_get_bitrate (NMDevice80211Wireless *self);
static GQuark
nm_wifi_error_quark (void)
{
static GQuark quark = 0;
if (!quark)
quark = g_quark_from_static_string ("nm-wifi-error");
return quark;
}
/* This should really be standard. */
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
static GType
nm_wifi_error_get_type (void)
{
static GType etype = 0;
if (etype == 0) {
static const GEnumValue values[] = {
/* Connection was not a wireless connection. */
ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS, "ConnectionNotWireless"),
/* Connection was not a valid wireless connection. */
ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INVALID, "ConnectionInvalid"),
/* Connection does not apply to this device. */
ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"),
{ 0, 0, 0 }
};
etype = g_enum_register_static ("NMWifiError", values);
}
return etype;
}
static void
access_point_removed (NMDevice80211Wireless *device, NMAccessPoint *ap)
{
@ -788,52 +831,46 @@ real_deactivate (NMDevice *dev)
}
static gboolean
real_check_connection_conflicts (NMDevice *device,
NMConnection *connection,
NMConnection *system_connection)
real_check_connection_compatible (NMDevice *device,
NMConnection *connection,
GError **error)
{
NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (device);
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
NMSettingConnection *s_con;
NMSettingConnection *system_s_con;
NMSettingWireless *s_wireless;
NMSettingWireless *system_s_wireless;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
system_s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (system_connection, NM_TYPE_SETTING_CONNECTION));
g_assert (system_s_con);
s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
if (!s_wireless)
if (strcmp (s_con->type, NM_SETTING_WIRELESS_SETTING_NAME)) {
g_set_error (error,
NM_WIFI_ERROR, NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS,
"The connection was not a WiFi connection.");
return FALSE;
system_s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (system_connection, NM_TYPE_SETTING_WIRELESS));
if (!system_s_wireless)
return FALSE;
if (!system_s_con->lockdown)
return FALSE;
if (!strcmp (system_s_con->lockdown, "device")) {
/* If the system connection has a MAC address and the MAC address
* matches this device, the activation request conflicts.
*/
if ( system_s_wireless->mac_address
&& !memcmp (system_s_wireless->mac_address->data, &(priv->hw_addr.ether_addr_octet), ETH_ALEN))
return TRUE;
} else if (!strcmp (system_s_con->lockdown, "connection")) {
/* If the system connection has an SSID and it matches the SSID of the
* connection being activated, the connection being activated conflicts.
*/
g_assert (system_s_wireless->ssid);
g_assert (s_wireless->ssid);
if (nm_utils_same_ssid (system_s_wireless->ssid, s_wireless->ssid, TRUE))
return TRUE;
}
return FALSE;
s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
if (!s_wireless) {
g_set_error (error,
NM_WIFI_ERROR, NM_WIFI_ERROR_CONNECTION_INVALID,
"The connection was not a valid WiFi connection.");
return FALSE;
}
if ( s_wireless->mac_address
&& memcmp (s_wireless->mac_address->data, &(priv->hw_addr.ether_addr_octet), ETH_ALEN)) {
g_set_error (error,
NM_WIFI_ERROR, NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE,
"The connection's MAC address did not match this device.");
return FALSE;
}
// FIXME: check channel/freq/band against bands the hardware supports
// FIXME: check encryption against device capabilities
// FIXME: check bitrate against device capabilities
return TRUE;
}
static gboolean
@ -2996,7 +3033,7 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass)
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->can_activate = real_can_activate;
parent_class->connection_secrets_updated = real_connection_secrets_updated;
parent_class->check_connection_conflicts = real_check_connection_conflicts;
parent_class->check_connection_compatible = real_check_connection_compatible;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;
@ -3080,8 +3117,9 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass)
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
&dbus_glib_nm_device_802_11_wireless_object_info);
}
dbus_g_error_domain_register (NM_WIFI_ERROR, NULL, NM_TYPE_WIFI_ERROR);
}
static void
state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data)

View file

@ -61,6 +61,16 @@ G_DEFINE_TYPE (NMDevice8023Ethernet, nm_device_802_3_ethernet, NM_TYPE_DEVICE)
#define WIRED_SECRETS_TRIES "wired-secrets-tries"
typedef enum
{
NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED = 0,
NM_ETHERNET_ERROR_CONNECTION_INVALID,
NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE,
} NMEthernetError;
#define NM_ETHERNET_ERROR (nm_ethernet_error_quark ())
#define NM_TYPE_ETHERNET_ERROR (nm_ethernet_error_get_type ())
typedef struct Supplicant {
NMSupplicantManager *mgr;
NMSupplicantInterface *iface;
@ -115,6 +125,38 @@ static void set_carrier (NMDevice8023Ethernet *self, const gboolean carrier);
static gboolean supports_mii_carrier_detect (NMDevice8023Ethernet *dev);
static gboolean supports_ethtool_carrier_detect (NMDevice8023Ethernet *dev);
static GQuark
nm_ethernet_error_quark (void)
{
static GQuark quark = 0;
if (!quark)
quark = g_quark_from_static_string ("nm-ethernet-error");
return quark;
}
/* This should really be standard. */
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
static GType
nm_ethernet_error_get_type (void)
{
static GType etype = 0;
if (etype == 0) {
static const GEnumValue values[] = {
/* Connection was not a wired connection. */
ENUM_ENTRY (NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED, "ConnectionNotWired"),
/* Connection was not a valid wired connection. */
ENUM_ENTRY (NM_ETHERNET_ERROR_CONNECTION_INVALID, "ConnectionInvalid"),
/* Connection does not apply to this device. */
ENUM_ENTRY (NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"),
{ 0, 0, 0 }
};
etype = g_enum_register_static ("NMEthernetError", values);
}
return etype;
}
static void
nm_device_802_3_ethernet_carrier_on (NMNetlinkMonitor *monitor,
int idx,
@ -443,22 +485,27 @@ real_get_best_auto_connection (NMDevice *dev,
NMConnection *connection = NM_CONNECTION (iter->data);
NMSettingConnection *s_con;
NMSettingWired *s_wired;
gboolean is_pppoe = FALSE;
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
if ( strcmp (s_con->type, NM_SETTING_WIRED_SETTING_NAME)
&& strcmp (s_con->type, NM_SETTING_PPPOE_SETTING_NAME))
if (!strcmp (s_con->type, NM_SETTING_PPPOE_SETTING_NAME))
is_pppoe = TRUE;
if (!is_pppoe && strcmp (s_con->type, NM_SETTING_WIRED_SETTING_NAME))
continue;
if (!s_con->autoconnect)
continue;
s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
if (!s_wired)
/* Wired setting optional for PPPoE */
if (!is_pppoe && !s_wired)
continue;
if (s_wired->mac_address) {
if (memcmp (s_wired->mac_address->data, priv->hw_addr.ether_addr_octet, ETH_ALEN))
if (s_wired) {
if ( s_wired->mac_address
&& memcmp (s_wired->mac_address->data, priv->hw_addr.ether_addr_octet, ETH_ALEN))
continue;
}
@ -1160,6 +1207,55 @@ real_deactivate_quickly (NMDevice *device)
supplicant_interface_clean (NM_DEVICE_802_3_ETHERNET (device));
}
static gboolean
real_check_connection_compatible (NMDevice *device,
NMConnection *connection,
GError **error)
{
NMDevice8023Ethernet *self = NM_DEVICE_802_3_ETHERNET (device);
NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self);
NMSettingConnection *s_con;
NMSettingWired *s_wired;
gboolean is_pppoe = FALSE;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
if ( strcmp (s_con->type, NM_SETTING_WIRED_SETTING_NAME)
&& strcmp (s_con->type, NM_SETTING_PPPOE_SETTING_NAME)) {
g_set_error (error,
NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED,
"The connection was not a wired or PPPoE connection.");
return FALSE;
}
if (!strcmp (s_con->type, NM_SETTING_PPPOE_SETTING_NAME))
is_pppoe = TRUE;
s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
/* Wired setting is optional for PPPoE */
if (!is_pppoe && !s_wired) {
g_set_error (error,
NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INVALID,
"The connection was not a valid wired connection.");
return FALSE;
}
if (s_wired) {
if ( s_wired->mac_address
&& memcmp (s_wired->mac_address->data, &(priv->hw_addr.ether_addr_octet), ETH_ALEN)) {
g_set_error (error,
NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE,
"The connection's MAC address did not match this device.");
return FALSE;
}
}
// FIXME: check bitrate against device capabilities
return TRUE;
}
static void
nm_device_802_3_ethernet_dispose (GObject *object)
{
@ -1245,6 +1341,7 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass)
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->can_activate = real_can_activate;
parent_class->connection_secrets_updated = real_connection_secrets_updated;
parent_class->check_connection_compatible = real_check_connection_compatible;
parent_class->act_stage2_config = real_act_stage2_config;
parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
@ -1282,6 +1379,8 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass)
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
&dbus_glib_nm_device_802_3_ethernet_object_info);
dbus_g_error_domain_register (NM_ETHERNET_ERROR, NULL, NM_TYPE_ETHERNET_ERROR);
}

View file

@ -175,18 +175,18 @@ nm_device_interface_get_iface (NMDeviceInterface *device)
}
gboolean
nm_device_interface_check_connection_conflicts (NMDeviceInterface *device,
NMConnection *connection,
NMConnection *system_connection)
nm_device_interface_check_connection_compatible (NMDeviceInterface *device,
NMConnection *connection,
GError **error)
{
g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (system_connection), FALSE);
g_return_val_if_fail (error != NULL, FALSE);
g_return_val_if_fail (*error == NULL, FALSE);
if (!NM_DEVICE_INTERFACE_GET_INTERFACE (device)->check_connection_conflicts)
return FALSE;
return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->check_connection_conflicts (device, connection, system_connection);
if (NM_DEVICE_INTERFACE_GET_INTERFACE (device)->check_connection_compatible)
return NM_DEVICE_INTERFACE_GET_INTERFACE (device)->check_connection_compatible (device, connection, error);
return TRUE;
}
gboolean

View file

@ -50,9 +50,9 @@ struct _NMDeviceInterface {
GTypeInterface g_iface;
/* Methods */
gboolean (*check_connection_conflicts) (NMDeviceInterface *device,
NMConnection *connection,
NMConnection *system_connection);
gboolean (*check_connection_compatible) (NMDeviceInterface *device,
NMConnection *connection,
GError **error);
gboolean (*activate) (NMDeviceInterface *device,
NMActRequest *req,
@ -69,9 +69,9 @@ GType nm_device_interface_error_get_type (void);
GType nm_device_interface_get_type (void);
gboolean nm_device_interface_check_connection_conflicts (NMDeviceInterface *device,
NMConnection *connection,
NMConnection *system_connection);
gboolean nm_device_interface_check_connection_compatible (NMDeviceInterface *device,
NMConnection *connection,
GError **error);
gboolean nm_device_interface_activate (NMDeviceInterface *device,
NMActRequest *req,

View file

@ -86,9 +86,9 @@ struct _NMDevicePrivate
gulong dhcp_timeout_sigid;
};
static gboolean nm_device_check_connection_conflicts (NMDeviceInterface *device,
NMConnection *connection,
NMConnection *system_connection);
static gboolean check_connection_compatible (NMDeviceInterface *device,
NMConnection *connection,
GError **error);
static gboolean nm_device_activate (NMDeviceInterface *device,
NMActRequest *req,
@ -108,7 +108,7 @@ static void
device_interface_init (NMDeviceInterface *device_interface_class)
{
/* interface implementation */
device_interface_class->check_connection_conflicts = nm_device_check_connection_conflicts;
device_interface_class->check_connection_compatible = check_connection_compatible;
device_interface_class->activate = nm_device_activate;
device_interface_class->deactivate = nm_device_deactivate;
}
@ -1063,16 +1063,16 @@ nm_device_deactivate (NMDeviceInterface *device)
}
static gboolean
nm_device_check_connection_conflicts (NMDeviceInterface *dev_iface,
NMConnection *connection,
NMConnection *system_connection)
check_connection_compatible (NMDeviceInterface *dev_iface,
NMConnection *connection,
GError **error)
{
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (NM_DEVICE (dev_iface));
if (klass->check_connection_conflicts)
return klass->check_connection_conflicts (NM_DEVICE (dev_iface), connection, system_connection);
if (klass->check_connection_compatible)
return klass->check_connection_compatible (NM_DEVICE (dev_iface), connection, error);
return FALSE;
return TRUE;
}
static void

View file

@ -85,9 +85,9 @@ struct _NMDeviceClass
NMConnection *connection,
GSList *updated_settings);
gboolean (* check_connection_conflicts) (NMDevice *self,
NMConnection *connection,
NMConnection *system_connection);
gboolean (* check_connection_compatible) (NMDevice *self,
NMConnection *connection,
GError **error);
NMActStageReturn (* act_stage1_prepare) (NMDevice *self);
NMActStageReturn (* act_stage2_config) (NMDevice *self);

View file

@ -1340,41 +1340,6 @@ nm_manager_get_act_request_by_path (NMManager *manager,
return NULL;
}
static gboolean
check_connection_allowed (NMManager *manager,
NMDeviceInterface *dev_iface,
NMConnection *connection,
const char *specific_object,
GError **error)
{
NMSettingConnection *s_con;
GSList *system_connections;
GSList *iter;
gboolean allowed = TRUE;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
g_return_val_if_fail (s_con != NULL, FALSE);
system_connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM);
for (iter = system_connections; iter; iter = g_slist_next (iter)) {
NMConnection *system_connection = NM_CONNECTION (iter->data);
if (connection == system_connection)
continue;
if (nm_device_interface_check_connection_conflicts (dev_iface,
connection,
system_connection)) {
allowed = FALSE;
break;
}
}
g_slist_foreach (system_connections, (GFunc) g_object_unref, NULL);
return allowed;
}
static const char *
internal_activate_device (NMManager *manager,
NMDevice *device,
@ -1393,8 +1358,8 @@ internal_activate_device (NMManager *manager,
dev_iface = NM_DEVICE_INTERFACE (device);
/* Ensure the requested connection is allowed to be activated */
if (!check_connection_allowed (manager, dev_iface, connection, specific_object, error))
/* Ensure the requested connection is compatible with the device */
if (!nm_device_interface_check_connection_compatible (dev_iface, connection, error))
return NULL;
if (nm_device_get_act_request (device)) {
@ -1406,7 +1371,7 @@ internal_activate_device (NMManager *manager,
success = nm_device_interface_activate (dev_iface, req, error);
g_object_unref (req);
return nm_act_request_get_active_connection_path (req);
return success ? nm_act_request_get_active_connection_path (req) : NULL;
}
gboolean