diff --git a/ChangeLog b/ChangeLog index 8cbbaa5fe..8dfe98a81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2007-12-31 Dan Williams + + * src/nm-device-interface.c + src/nm-device-interface.h + - (nm_device_interface_check_connection_conflicts): new function + + * src/nm-device.c + src/nm-device.h + - (nm_device_check_connection_conflicts): new function + - (device_activation_precheck): don't require subclasses to implement + check_connection_complete() + - check_connection() -> check_connection_complete() + + * src/nm-device-802-11-wireless.c + - (real_check_connection): remove; unused + - (real_check_connection_conflicts): implement, handle lockdown for + system connections + + * src/nm-device-802-3-ethernet.c + - (real_check_connection): remove; unused + + * src/nm-manager.c + - (check_connection_allowed): new function + - (nm_manager_activate_device): ensure the connection being requested + is allowed to be activated + + * src/nm-serial-device.c + src/nm-gsm-device.c + - real_check_connection() -> real_check_connection_complete() + 2007-12-27 Dan Williams * src/nm-device-interface.c diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index c771add78..fc5b4e92a 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -744,9 +744,50 @@ real_deactivate (NMDevice *dev) } static gboolean -real_check_connection (NMDevice *dev, NMConnection *connection, GError **error) +real_check_connection_conflicts (NMDevice *device, + NMConnection *connection, + NMConnection *system_connection) { - return TRUE; + 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)); + g_assert (s_wireless); + + system_s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (system_connection, NM_TYPE_SETTING_WIRELESS)); + g_assert (system_s_wireless); + + 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; } typedef struct BestConnectionInfo { @@ -3003,9 +3044,9 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass) parent_class->bring_down = real_bring_down; parent_class->update_link = real_update_link; parent_class->set_hw_address = real_set_hw_address; - parent_class->check_connection = real_check_connection; parent_class->get_best_connection = real_get_best_connection; parent_class->connection_secrets_updated = real_connection_secrets_updated; + parent_class->check_connection_conflicts = real_check_connection_conflicts; parent_class->act_stage1_prepare = real_act_stage1_prepare; parent_class->act_stage2_config = real_act_stage2_config; diff --git a/src/nm-device-802-3-ethernet.c b/src/nm-device-802-3-ethernet.c index 3c30e0ec0..c52fa52af 100644 --- a/src/nm-device-802-3-ethernet.c +++ b/src/nm-device-802-3-ethernet.c @@ -327,12 +327,6 @@ real_can_interrupt_activation (NMDevice *dev) return interrupt; } -static gboolean -real_check_connection (NMDevice *dev, NMConnection *connection, GError **error) -{ - return TRUE; -} - typedef struct BestConnectionInfo { NMDevice8023Ethernet * self; NMConnection * found; @@ -472,7 +466,6 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass) parent_class->update_link = real_update_link; parent_class->can_interrupt_activation = real_can_interrupt_activation; parent_class->set_hw_address = real_set_hw_address; - parent_class->check_connection = real_check_connection; parent_class->get_best_connection = real_get_best_connection; /* properties */ diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index d2e948bab..a9ba1949b 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -192,6 +192,21 @@ nm_device_interface_get_iface (NMDeviceInterface *device) return iface; } +gboolean +nm_device_interface_check_connection_conflicts (NMDeviceInterface *device, + NMConnection *connection, + NMConnection *system_connection) +{ + 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); + + if (!device->check_connection_conflicts) + return FALSE; + + return device->check_connection_conflicts (device, connection, system_connection); +} + gboolean nm_device_interface_activate (NMDeviceInterface *device, NMActRequest *req, diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h index a7bb1d313..41c7ccc82 100644 --- a/src/nm-device-interface.h +++ b/src/nm-device-interface.h @@ -52,6 +52,10 @@ struct _NMDeviceInterface { GTypeInterface g_iface; /* Methods */ + gboolean (*check_connection_conflicts) (NMDeviceInterface *device, + NMConnection *connection, + NMConnection *system_connection); + gboolean (*activate) (NMDeviceInterface *device, NMActRequest *req, GError **error); @@ -68,6 +72,10 @@ 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_activate (NMDeviceInterface *device, NMActRequest *req, GError **error); diff --git a/src/nm-device.c b/src/nm-device.c index f42c37938..920017f7f 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -39,6 +39,7 @@ #include "autoip.h" #include "nm-netlink.h" #include "nm-setting-ip4-config.h" +#include "nm-setting-connection.h" #define NM_ACT_REQUEST_IP4_CONFIG "nm-act-request-ip4-config" @@ -82,6 +83,10 @@ struct _NMDevicePrivate gulong dhcp_timeout_sigid; }; +static gboolean nm_device_check_connection_conflicts (NMDeviceInterface *device, + NMConnection *connection, + NMConnection *system_connection); + static gboolean nm_device_activate (NMDeviceInterface *device, NMActRequest *req, GError **error); @@ -100,6 +105,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->activate = nm_device_activate; device_interface_class->deactivate = nm_device_deactivate; } @@ -1105,6 +1111,19 @@ nm_device_deactivate (NMDeviceInterface *device) nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED); } +static gboolean +nm_device_check_connection_conflicts (NMDeviceInterface *device, + NMConnection *connection, + NMConnection *system_connection) +{ + NMDeviceClass *klass = NM_DEVICE_CLASS (NM_DEVICE (device)); + + if (klass->check_connection_conflicts) + return klass->check_connection_conflicts (NM_DEVICE (device), connection, system_connection); + + return FALSE; +} + static void connection_secrets_updated_cb (NMActRequest *req, NMConnection *connection, @@ -1136,7 +1155,8 @@ device_activation_precheck (NMDevice *self, NMConnection *connection, GError **e g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - if (!NM_DEVICE_GET_CLASS (self)->check_connection (self, connection, error)) { + if ( NM_DEVICE_GET_CLASS (self)->check_connection_complete + && !NM_DEVICE_GET_CLASS (self)->check_connection_complete (self, connection, error)) { /* connection is invalid */ g_assert (*error); return FALSE; diff --git a/src/nm-device.h b/src/nm-device.h index dc9036f15..935ac30ea 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -91,14 +91,20 @@ struct _NMDeviceClass guint32 (* get_generic_capabilities) (NMDevice *self); NMConnection * (* get_best_connection) (NMDevice *self, - GSList *connections, + GSList *connections, char **specific_object); void (* connection_secrets_updated) (NMDevice *self, NMConnection *connection, const char *setting_name); - gboolean (* check_connection) (NMDevice *self, NMConnection *connection, GError **error); + gboolean (* check_connection_conflicts) (NMDevice *self, + NMConnection *connection, + NMConnection *system_connection); + + gboolean (* check_connection_complete) (NMDevice *self, + NMConnection *connection, + GError **error); NMActStageReturn (* act_stage1_prepare) (NMDevice *self); NMActStageReturn (* act_stage2_config) (NMDevice *self); diff --git a/src/nm-gsm-device.c b/src/nm-gsm-device.c index 982055981..3ab4378c0 100644 --- a/src/nm-gsm-device.c +++ b/src/nm-gsm-device.c @@ -459,7 +459,7 @@ real_get_generic_capabilities (NMDevice *dev) } static gboolean -real_check_connection (NMDevice *dev, NMConnection *connection, GError **error) +real_check_connection_complete (NMDevice *dev, NMConnection *connection, GError **error) { NMSettingGsm *gsm; @@ -480,7 +480,7 @@ real_check_connection (NMDevice *dev, NMConnection *connection, GError **error) return FALSE; } - return NM_DEVICE_CLASS (nm_gsm_device_parent_class)->check_connection (dev, connection, error); + return NM_DEVICE_CLASS (nm_gsm_device_parent_class)->check_connection_complete (dev, connection, error); } static void @@ -536,7 +536,7 @@ nm_gsm_device_class_init (NMGsmDeviceClass *klass) g_type_class_add_private (object_class, sizeof (NMGsmDevicePrivate)); device_class->get_generic_capabilities = real_get_generic_capabilities; - device_class->check_connection = real_check_connection; + device_class->check_connection_complete = real_check_connection_complete; device_class->act_stage1_prepare = real_act_stage1_prepare; device_class->connection_secrets_updated = real_connection_secrets_updated; device_class->deactivate_quickly = real_deactivate_quickly; diff --git a/src/nm-manager.c b/src/nm-manager.c index 12ace795a..335a8f419 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1155,6 +1155,41 @@ nm_manager_get_device_by_udi (NMManager *manager, const char *udi) return NULL; } +static gboolean +check_connection_allowed (NMManager *manager, + NMDevice *device, + 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_TYPE_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 (NM_DEVICE_INTERFACE (device), + connection, + system_connection)) { + allowed = FALSE; + break; + } + } + + g_slist_foreach (system_connections, (GFunc) g_object_unref, NULL); + + return allowed; +} + gboolean nm_manager_activate_device (NMManager *manager, NMDevice *device, @@ -1171,6 +1206,8 @@ nm_manager_activate_device (NMManager *manager, g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); /* Ensure the requested connection is allowed to be activated */ + if (!check_connection_allowed (manager, device, connection, specific_object, error)) + return FALSE; req = nm_act_request_new (connection, specific_object, user_requested); success = nm_device_interface_activate (NM_DEVICE_INTERFACE (device), req, error); diff --git a/src/nm-serial-device.c b/src/nm-serial-device.c index dc9767e4d..d72ec0103 100644 --- a/src/nm-serial-device.c +++ b/src/nm-serial-device.c @@ -868,7 +868,7 @@ real_deactivate_quickly (NMDevice *device) } static gboolean -real_check_connection (NMDevice *dev, NMConnection *connection, GError **error) +real_check_connection_complete (NMDevice *dev, NMConnection *connection, GError **error) { NMSettingSerial *serial; NMSettingPPP *ppp; @@ -891,7 +891,7 @@ real_check_connection (NMDevice *dev, NMConnection *connection, GError **error) return FALSE; } - return TRUE; + return NM_DEVICE_CLASS (nm_serial_device_parent_class)->check_connection_complete (dev, connection, error); } static gboolean @@ -930,7 +930,7 @@ nm_serial_device_class_init (NMSerialDeviceClass *klass) object_class->finalize = finalize; parent_class->is_up = real_is_up; - parent_class->check_connection = real_check_connection; + parent_class->check_connection_complete = real_check_connection_complete; parent_class->act_stage2_config = real_act_stage2_config; parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; parent_class->deactivate_quickly = real_deactivate_quickly;