diff options
Diffstat (limited to 'src/vpn-manager/nm-vpn-manager.c')
-rw-r--r-- | src/vpn-manager/nm-vpn-manager.c | 202 |
1 files changed, 62 insertions, 140 deletions
diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 7743fddd7..5550d4d6c 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -28,17 +28,16 @@ #include "nm-setting-vpn.h" #include "nm-dbus-manager.h" #include "NetworkManagerVPN.h" -#include "nm-marshal.h" #include "nm-enum-types.h" #include "nm-logging.h" +#define VPN_NAME_FILES_DIR NMCONFDIR "/VPN" + G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT) #define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate)) typedef struct { - gboolean disposed; - GHashTable *services; GFileMonitor *monitor; guint monitor_id; @@ -76,93 +75,47 @@ get_service_by_namefile (NMVPNManager *self, const char *namefile) return NULL; } -static NMVPNConnection * -find_active_vpn_connection_by_connection (NMVPNManager *self, NMConnection *connection) -{ - NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); - GHashTableIter iter; - gpointer data; - const GSList *active, *aiter; - NMVPNConnection *found = NULL; - - g_return_val_if_fail (connection, NULL); - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - - g_hash_table_iter_init (&iter, priv->services); - while (g_hash_table_iter_next (&iter, NULL, &data) && (found == NULL)) { - active = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (data)); - for (aiter = active; aiter; aiter = g_slist_next (aiter)) { - NMVPNConnection *vpn = NM_VPN_CONNECTION (aiter->data); - - if (nm_vpn_connection_get_connection (vpn) == connection) { - found = vpn; - break; - } - } - } - return found; -} - -NMActiveConnection * +gboolean nm_vpn_manager_activate_connection (NMVPNManager *manager, - NMConnection *connection, - NMDevice *device, - const char *specific_object, - gboolean user_requested, - gulong user_uid, + NMVPNConnection *vpn, GError **error) { - NMSettingVPN *vpn_setting; + NMConnection *connection; + NMSettingVPN *s_vpn; NMVPNService *service; - NMVPNConnection *vpn = NULL; const char *service_name; + NMDevice *device; - g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - g_return_val_if_fail (error != NULL, NULL); - g_return_val_if_fail (*error == NULL, NULL); + g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), FALSE); + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE); + g_return_val_if_fail (error != NULL, FALSE); + g_return_val_if_fail (*error == NULL, FALSE); + device = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); + g_assert (device); if ( nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED && nm_device_get_state (device) != NM_DEVICE_STATE_SECONDARIES) { - g_set_error (error, - NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, - "%s", "The base device for the VPN connection was not active."); - return NULL; - } - - vpn_setting = nm_connection_get_setting_vpn (connection); - if (!vpn_setting) { - g_set_error (error, - NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, - "%s", "The connection was not a VPN connection."); - return NULL; + g_set_error_literal (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, + "The base device for the VPN connection was not active."); + return FALSE; } - vpn = find_active_vpn_connection_by_connection (manager, connection); - if (vpn) { - nm_vpn_connection_disconnect (vpn, NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED); - vpn = NULL; - } + connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (vpn)); + g_assert (connection); + s_vpn = nm_connection_get_setting_vpn (connection); + g_assert (s_vpn); - service_name = nm_setting_vpn_get_service_type (vpn_setting); + service_name = nm_setting_vpn_get_service_type (s_vpn); g_assert (service_name); service = g_hash_table_lookup (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, service_name); if (!service) { - g_set_error (error, - NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_INVALID, + g_set_error (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_INVALID, "The VPN service '%s' was not installed.", service_name); - return NULL; + return FALSE; } - return (NMActiveConnection *) nm_vpn_service_activate (service, - connection, - device, - specific_object, - user_requested, - user_uid, - error); + return nm_vpn_service_activate (service, vpn, error); } gboolean @@ -170,51 +123,7 @@ nm_vpn_manager_deactivate_connection (NMVPNManager *self, NMVPNConnection *connection, NMVPNConnectionStateReason reason) { - NMVPNManagerPrivate *priv; - GHashTableIter iter; - gpointer data; - const GSList *active, *aiter; - gboolean success = FALSE; - - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (NM_IS_VPN_MANAGER (self), FALSE); - g_return_val_if_fail (connection != NULL, FALSE); - - priv = NM_VPN_MANAGER_GET_PRIVATE (self); - g_hash_table_iter_init (&iter, priv->services); - while (g_hash_table_iter_next (&iter, NULL, &data) && (success == FALSE)) { - active = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (data)); - for (aiter = active; aiter; aiter = g_slist_next (aiter)) { - NMVPNConnection *candidate = aiter->data; - - if (connection == candidate) { - nm_vpn_connection_disconnect (connection, reason); - success = TRUE; - break; - } - } - } - - return success; -} - -static char * -service_name_from_file (const char *path) -{ - GKeyFile *kf = NULL; - char *service_name = NULL; - - g_return_val_if_fail (g_path_is_absolute (path), NULL); - - if (!g_str_has_suffix (path, ".name")) - return NULL; - - kf = g_key_file_new (); - if (g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, NULL)) - service_name = g_key_file_get_string (kf, VPN_CONNECTION_GROUP, "service", NULL); - - g_key_file_free (kf); - return service_name; + return nm_vpn_connection_deactivate (connection, reason, FALSE); } static void @@ -222,34 +131,32 @@ try_add_service (NMVPNManager *self, const char *namefile) { NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); NMVPNService *service = NULL; + GHashTableIter iter; GError *error = NULL; const char *service_name; - char *tmp; g_return_if_fail (g_path_is_absolute (namefile)); /* Make sure we don't add dupes */ - tmp = service_name_from_file (namefile); - if (tmp) - service = g_hash_table_lookup (priv->services, tmp); - g_free (tmp); - if (service) - return; + g_hash_table_iter_init (&iter, priv->services); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &service)) { + if (g_strcmp0 (namefile, nm_vpn_service_get_name_file (service)) == 0) + return; + } - /* New service, add it */ + /* New service */ service = nm_vpn_service_new (namefile, &error); - if (!service) { + if (service) { + service_name = nm_vpn_service_get_dbus_service (service); + g_hash_table_insert (priv->services, (char *) service_name, service); + nm_log_info (LOGD_VPN, "VPN: loaded %s", service_name); + } else { nm_log_warn (LOGD_VPN, "failed to load VPN service file %s: (%d) %s", namefile, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_clear_error (&error); - return; } - - service_name = nm_vpn_service_get_dbus_service (service); - g_hash_table_insert (priv->services, (char *) service_name, service); - nm_log_info (LOGD_VPN, "VPN: loaded %s", service_name); } static void @@ -279,7 +186,7 @@ vpn_dir_changed (GFileMonitor *monitor, const char *service_name = nm_vpn_service_get_dbus_service (service); /* Stop active VPN connections and destroy the service */ - nm_vpn_service_connections_stop (service, TRUE, + nm_vpn_service_stop_connections (service, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); nm_log_info (LOGD_VPN, "VPN: unloaded %s", service_name); g_hash_table_remove (priv->services, service_name); @@ -351,21 +258,36 @@ nm_vpn_manager_init (NMVPNManager *self) } static void +stop_all_services (NMVPNManager *self) +{ + NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); + GHashTableIter iter; + NMVPNService *service; + + g_hash_table_iter_init (&iter, priv->services); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &service)) { + nm_vpn_service_stop_connections (service, + TRUE, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); + } +} + +static void dispose (GObject *object) { NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object); - if (!priv->disposed) { - priv->disposed = TRUE; - - if (priv->monitor) { - if (priv->monitor_id) - g_signal_handler_disconnect (priv->monitor, priv->monitor_id); - g_file_monitor_cancel (priv->monitor); - g_object_unref (priv->monitor); - } + if (priv->monitor) { + if (priv->monitor_id) + g_signal_handler_disconnect (priv->monitor, priv->monitor_id); + g_file_monitor_cancel (priv->monitor); + g_clear_object (&priv->monitor); + } + if (priv->services) { + stop_all_services (NM_VPN_MANAGER (object)); g_hash_table_destroy (priv->services); + priv->services = NULL; } G_OBJECT_CLASS (nm_vpn_manager_parent_class)->dispose (object); |