Esempio n. 1
0
static void
_name_owner_changed (GObject *object,
                     GParamSpec *pspec,
                     gpointer user_data)
{
	NMVpnService *service = NM_VPN_SERVICE (user_data);
	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
	gboolean success;
	char *owner;

	owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (object));

	/* Service changed, no need to wait for the timeout any longer */
	if (priv->start_timeout) {
		g_source_remove (priv->start_timeout);
		priv->start_timeout = 0;
	}

	if (owner && !priv->service_running) {
		/* service appeared */
		priv->service_running = TRUE;
		nm_log_info (LOGD_VPN, "VPN service '%s' appeared; activating connections", nm_vpn_plugin_info_get_name (priv->plugin_info));
		/* Expect success because the VPN service has already appeared */
		success = start_active_vpn (service, NULL);
		g_warn_if_fail (success);
	} else if (!owner && priv->service_running) {
		/* service went away */
		priv->service_running = FALSE;
		nm_log_info (LOGD_VPN, "VPN service '%s' disappeared", nm_vpn_plugin_info_get_name (priv->plugin_info));
		nm_vpn_service_stop_connections (service, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
	}

	g_free (owner);
}
GSList *
vpn_get_plugin_infos (void)
{
	static gboolean plugins_loaded = FALSE;
	static GSList *plugins = NULL;
	GSList *p;

	if (G_LIKELY (plugins_loaded))
		return plugins;
	plugins_loaded = TRUE;

	p = nm_vpn_plugin_info_list_load ();
	plugins = NULL;
	while (p) {
		NMVpnPluginInfo *plugin_info = NM_VPN_PLUGIN_INFO (p->data);
		GError *error = NULL;

		/* load the editor plugin, and preserve only those NMVpnPluginInfo that can
		 * successfully load the plugin. */
		if (nm_vpn_plugin_info_load_editor_plugin (plugin_info, &error)) {
			plugins = g_slist_prepend (plugins, plugin_info);
			g_info ("vpn: (%s,%s) loaded",
			        nm_vpn_plugin_info_get_name (plugin_info),
			        nm_vpn_plugin_info_get_filename (plugin_info));
		} else {
			if (   !nm_vpn_plugin_info_get_plugin (plugin_info)
			    && nm_vpn_plugin_info_lookup_property (plugin_info, NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "properties")) {
				g_message ("vpn: (%s,%s) cannot load legacy-only plugin",
				           nm_vpn_plugin_info_get_name (plugin_info),
				           nm_vpn_plugin_info_get_filename (plugin_info));
			} else if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
				g_message ("vpn: (%s,%s) file \"%s\" not found. Did you install the client package?",
				           nm_vpn_plugin_info_get_name (plugin_info),
				           nm_vpn_plugin_info_get_filename (plugin_info),
				           nm_vpn_plugin_info_get_plugin (plugin_info));
			} else {
				g_warning ("vpn: (%s,%s) could not load plugin: %s",
				           nm_vpn_plugin_info_get_name (plugin_info),
				           nm_vpn_plugin_info_get_filename (plugin_info),
				           error->message);
			}
			g_clear_error (&error);
			g_object_unref (plugin_info);
		}
		p = g_slist_delete_link (p, p);
	}

	/* sort the list of plugins alphabetically. */
	plugins = g_slist_sort (plugins, (GCompareFunc) _sort_vpn_plugins);
	return plugins;
}
Esempio n. 3
0
gboolean
nm_vpn_manager_activate_connection (NMVpnManager *manager,
                                    NMVpnConnection *vpn,
                                    GError **error)
{
	NMVpnManagerPrivate *priv;
	NMVpnPluginInfo *plugin_info;
	const char *service_name;
	NMDevice *device;

	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 || !*error, FALSE);

	priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
	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_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
		                     "The base device for the VPN connection was not active.");
		return FALSE;
	}

	service_name = nm_vpn_connection_get_service (vpn);

	plugin_info = nm_vpn_plugin_info_list_find_by_service (priv->plugins, service_name);
	if (!plugin_info) {
		g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
		             "The VPN service '%s' was not installed.",
		             service_name);
		return FALSE;
	}

	if (   !nm_vpn_plugin_info_supports_multiple (plugin_info)
	    && g_hash_table_contains (priv->active_services, service_name)) {
		g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
		             "The '%s' plugin only supports a single active connection.",
		             nm_vpn_plugin_info_get_name (plugin_info));
		return FALSE;
	}

	nm_vpn_connection_activate (vpn, plugin_info);

	if (!nm_vpn_plugin_info_supports_multiple (plugin_info)) {
		/* Block activations of the connections of the same service type. */
		g_hash_table_add (priv->active_services, g_strdup (service_name));
		g_signal_connect (vpn, "notify::" NM_ACTIVE_CONNECTION_STATE,
		                  G_CALLBACK (vpn_state_changed),
		                  g_object_ref (manager));
	}

	return TRUE;
}
Esempio n. 4
0
static gboolean
_daemon_exec_timeout (gpointer data)
{
	NMVpnService *self = NM_VPN_SERVICE (data);
	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);

	nm_log_warn (LOGD_VPN, "VPN service '%s' start timed out", nm_vpn_plugin_info_get_name (priv->plugin_info));
	priv->start_timeout = 0;
	nm_vpn_service_stop_connections (self, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT);
	return G_SOURCE_REMOVE;
}
Esempio n. 5
0
static gboolean
nm_vpn_service_daemon_exec (NMVpnService *service, GError **error)
{
	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
	GPid pid;
	char *vpn_argv[2];
	gboolean success = FALSE;
	GError *spawn_error = NULL;

	g_return_val_if_fail (NM_IS_VPN_SERVICE (service), FALSE);

	vpn_argv[0] = (char *) nm_vpn_plugin_info_get_program (priv->plugin_info);
	vpn_argv[1] = NULL;

	g_assert (vpn_argv[0]);

	success = g_spawn_async (NULL, vpn_argv, NULL, 0, nm_utils_setpgid, NULL, &pid, &spawn_error);
	if (success) {
		nm_log_info (LOGD_VPN, "VPN service '%s' started (%s), PID %ld",
		             nm_vpn_plugin_info_get_name (priv->plugin_info),
		             nm_vpn_service_get_dbus_service (service),
		             (long int) pid);
		priv->start_timeout = g_timeout_add_seconds (5, _daemon_exec_timeout, service);
	} else {
		nm_log_warn (LOGD_VPN, "VPN service '%s': could not launch the VPN service. error: (%d) %s.",
		             nm_vpn_plugin_info_get_name (priv->plugin_info),
		             spawn_error ? spawn_error->code : -1,
		             spawn_error && spawn_error->message ? spawn_error->message : "(unknown)");

		g_set_error (error,
		             NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
		             "%s", spawn_error ? spawn_error->message : "unknown g_spawn_async() error");

		nm_vpn_service_stop_connections (service, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED);
		if (spawn_error)
			g_error_free (spawn_error);
	}

	return success;
}
Esempio n. 6
0
static gboolean
start_active_vpn (NMVpnService *self, GError **error)
{
	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);

	if (!priv->active)
		return TRUE;

	if (priv->service_running) {
		/* Just activate the VPN */
		nm_vpn_connection_activate (priv->active);
		return TRUE;
	} else if (priv->start_timeout == 0) {
		/* VPN service not running, start it */
		nm_log_info (LOGD_VPN, "Starting VPN service '%s'...", nm_vpn_plugin_info_get_name (priv->plugin_info));
		return nm_vpn_service_daemon_exec (self, error);
	}

	/* Already started VPN service, waiting for it to appear on D-Bus */
	return TRUE;
}
static gint
_sort_vpn_plugins (NMVpnPluginInfo *aa, NMVpnPluginInfo *bb)
{
	return strcmp (nm_vpn_plugin_info_get_name (aa), nm_vpn_plugin_info_get_name (bb));
}