diff --git a/ChangeLog b/ChangeLog index 2222642be9..609532d40b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2008-04-02 Dan Williams + + * 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 * system-settings/plugins/ifcfg-fedora/parser.c diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index 22362d33cb..97275078dd 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -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) diff --git a/src/nm-device-802-3-ethernet.c b/src/nm-device-802-3-ethernet.c index eb753b15a4..fb5f31ecfc 100644 --- a/src/nm-device-802-3-ethernet.c +++ b/src/nm-device-802-3-ethernet.c @@ -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); } diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index f6315cb3a2..f6cf31a569 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -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 diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h index 0cf8c644f8..514ab77174 100644 --- a/src/nm-device-interface.h +++ b/src/nm-device-interface.h @@ -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, diff --git a/src/nm-device.c b/src/nm-device.c index d2d130eb3b..ae638e2e08 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -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 diff --git a/src/nm-device.h b/src/nm-device.h index 27cca58ee9..f7b1ba785d 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -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); diff --git a/src/nm-manager.c b/src/nm-manager.c index a12ca8b127..6a0fd80b8d 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -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