示例#1
0
static gboolean
fail_stop (gpointer data)
{
	NMVPNPlugin *plugin = NM_VPN_PLUGIN (data);

	nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
	return FALSE;
}
示例#2
0
static gboolean
_connect_generic (NMVPNPlugin *plugin,
                  GHashTable *properties,
                  GHashTable *details,
                  GError **error)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
	NMVPNPluginClass *vpn_class = NM_VPN_PLUGIN_GET_CLASS (plugin);
	NMConnection *connection;
	gboolean success = FALSE;
	GError *local = NULL;

	if (priv->state != NM_VPN_SERVICE_STATE_STOPPED &&
	    priv->state != NM_VPN_SERVICE_STATE_INIT) {
		g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_WRONG_STATE,
		             "Could not start connection: wrong plugin state %d",
		             priv->state);
		return FALSE;
	}

	connection = nm_connection_new_from_hash (properties, &local);
	if (!connection) {
		g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
		             "Invalid connection: (%d) %s",
		             local->code, local->message);
		g_clear_error (&local);
		return FALSE;
	}


	priv->interactive = FALSE;
	if (details && !vpn_class->connect_interactive) {
		g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED,
		                     "Plugin does not implement ConnectInteractive()");
		return FALSE;
	}

	nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING);

	if (details) {
		priv->interactive = TRUE;
		success = vpn_class->connect_interactive (plugin, connection, details, error);
	} else
		success = vpn_class->connect (plugin, connection, error);

	if (success) {
		/* Add a timer to make sure we do not wait indefinitely for the successful connect. */
		connect_timer_start (plugin);
	} else {
		/* Stop the plugin from an idle handler so that the Connect
		 * method return gets sent before the STOP StateChanged signal.
		 */
		schedule_fail_stop (plugin);
	}

	g_object_unref (connection);
	return success;
}
示例#3
0
static gboolean
fail_stop (gpointer data)
{
	NMVPNPlugin *self = NM_VPN_PLUGIN (data);

	NM_VPN_PLUGIN_GET_PRIVATE (self)->fail_stop_id = 0;
	nm_vpn_plugin_set_state (self, NM_VPN_SERVICE_STATE_STOPPED);
	return G_SOURCE_REMOVE;
}
示例#4
0
/**
 * signal failure to NM, connecting failed
 */
static void signal_failure(NMVPNPlugin *plugin, NMVPNPluginFailure failure)
{
	nm_handler_t *handler = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler;

	handler->reset(handler);

	/* TODO: NM does not handle this failure!? */
	nm_vpn_plugin_failure(plugin, failure);
	nm_vpn_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPED);
}
示例#5
0
static gboolean
nm_vpn_plugin_connect (NMVPNPlugin *plugin,
				   NMConnection *connection,
				   GError **err)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
	gboolean ret = FALSE;
	NMVPNServiceState state;

	g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);

	state = nm_vpn_plugin_get_state (plugin);
	switch (state) {
	case NM_VPN_SERVICE_STATE_STARTING:
		g_set_error (err,
				   NM_VPN_PLUGIN_ERROR,
				   NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS,
				   "%s",
				   "Could not process the request because the VPN connection is already being started.");
		break;
	case NM_VPN_SERVICE_STATE_STARTED:
		g_set_error (err,
				   NM_VPN_PLUGIN_ERROR,
				   NM_VPN_PLUGIN_ERROR_ALREADY_STARTED,
				   "%s",
				   "Could not process the request because a VPN connection was already active.");
		break;
	case NM_VPN_SERVICE_STATE_STOPPING:
		g_set_error (err,
				   NM_VPN_PLUGIN_ERROR,
				   NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS,
				   "%s",
				   "Could not process the request because the VPN connection is being stopped.");
		break;
	case NM_VPN_SERVICE_STATE_STOPPED:
	case NM_VPN_SERVICE_STATE_INIT:
		nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING);
		ret = NM_VPN_PLUGIN_GET_CLASS (plugin)->connect (plugin, connection, err);
		if (!ret) {
			/* Stop the plugin from and idle handler so that the Connect
			 * method return gets sent before the STOP StateChanged signal.
			 */
			if (priv->fail_stop_id)
				g_source_remove (priv->fail_stop_id);
			priv->fail_stop_id = g_idle_add (fail_stop, plugin);
		}
		break;

	default:
		g_assert_not_reached ();
		break;
	}

	return ret;
}
示例#6
0
gboolean
nm_vpn_plugin_disconnect (NMVPNPlugin *plugin, GError **err)
{
	gboolean ret = FALSE;
	NMVPNServiceState state;

	g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);

	state = nm_vpn_plugin_get_state (plugin);
	switch (state) {
	case NM_VPN_SERVICE_STATE_STOPPING:
		g_set_error (err,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS,
		             "%s",
		             "Could not process the request because the VPN connection is already being stopped.");
		break;
	case NM_VPN_SERVICE_STATE_STOPPED:
		g_set_error (err,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED,
		             "%s",
		             "Could not process the request because no VPN connection was active.");
		break;
	case NM_VPN_SERVICE_STATE_STARTING:
	case NM_VPN_SERVICE_STATE_STARTED:
		nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPING);
		ret = NM_VPN_PLUGIN_GET_CLASS (plugin)->disconnect (plugin, err);
		nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
		break;
	case NM_VPN_SERVICE_STATE_INIT:
		ret = TRUE;
		break;

	default:
		g_warning ("Unhandled VPN service state %d", state);
		g_assert_not_reached ();
		break;
	}

	return ret;
}
示例#7
0
void
nm_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
						GHashTable *ip4_config)
{
	g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
	g_return_if_fail (ip4_config != NULL);

	g_signal_emit (plugin, signals[IP4_CONFIG], 0, ip4_config);

	nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED);
}
示例#8
0
void
nm_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
                              GHashTable *ip4_config)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
	GHashTable *combined_config;
	GHashTableIter iter;
	gpointer key, value;

	g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
	g_return_if_fail (ip4_config != NULL);

	priv->got_ip4 = TRUE;

	/* Old plugins won't send the "config" signal and thus can't send
	 * NM_VPN_PLUGIN_CONFIG_HAS_IP4 either.  But since they don't support IPv6,
	 * we can safely assume that, if we don't receive a "config" signal but do
	 * receive an "ip4-config" signal, the old plugin supports IPv4.
	 */
	if (!priv->got_config)
		priv->has_ip4 = TRUE;

	/* Older NetworkManager daemons expect all config info to be in
	 * the ip4 config, so they won't even notice the "config" signal
	 * being emitted. So just copy all of that data into the ip4
	 * config too.
	 */
	combined_config = g_hash_table_new (g_str_hash, g_str_equal);
	g_hash_table_iter_init (&iter, ip4_config);
	while (g_hash_table_iter_next (&iter, &key, &value))
		g_hash_table_insert (combined_config, key, value);

	if (G_VALUE_TYPE (&priv->banner) != G_TYPE_INVALID)
		g_hash_table_insert (combined_config, NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner);
	if (G_VALUE_TYPE (&priv->tundev) != G_TYPE_INVALID)
		g_hash_table_insert (combined_config, NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev);
	if (G_VALUE_TYPE (&priv->gateway) != G_TYPE_INVALID)
		g_hash_table_insert (combined_config, NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, &priv->gateway);
	if (G_VALUE_TYPE (&priv->mtu) != G_TYPE_INVALID)
		g_hash_table_insert (combined_config, NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu);

	g_signal_emit (plugin, signals[IP4_CONFIG], 0, combined_config);
	g_hash_table_destroy (combined_config);

	if (   priv->has_ip4 == priv->got_ip4
	    && priv->has_ip6 == priv->got_ip6)
		nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED);
}
示例#9
0
void
nm_vpn_plugin_set_ip6_config (NMVPNPlugin *plugin,
                              GHashTable *ip6_config)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);

	g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
	g_return_if_fail (ip6_config != NULL);

	priv->got_ip6 = TRUE;
	g_signal_emit (plugin, signals[IP6_CONFIG], 0, ip6_config);

	if (   priv->has_ip4 == priv->got_ip4
	    && priv->has_ip6 == priv->got_ip6)
		nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED);
}
static void
openconnect_watch_cb (GPid pid, gint status, gpointer user_data)
{
	NMOPENCONNECTPlugin *plugin = NM_OPENCONNECT_PLUGIN (user_data);
	NMOPENCONNECTPluginPrivate *priv = NM_OPENCONNECT_PLUGIN_GET_PRIVATE (plugin);
	guint error = 0;

	if (WIFEXITED (status)) {
		error = WEXITSTATUS (status);
		if (error != 0)
			g_warning ("openconnect exited with error code %d", error);
	}
	else if (WIFSTOPPED (status))
		g_warning ("openconnect stopped unexpectedly with signal %d", WSTOPSIG (status));
	else if (WIFSIGNALED (status))
		g_warning ("openconnect died with signal %d", WTERMSIG (status));
	else
		g_warning ("openconnect died from an unknown cause");

	/* Reap child if needed. */
	waitpid (priv->pid, NULL, WNOHANG);
	priv->pid = 0;

	if (priv->tun_name) {
		destroy_persistent_tundev (priv->tun_name);
		g_free (priv->tun_name);
		priv->tun_name = NULL;
	}

	/* Must be after data->state is set since signals use data->state */
	switch (error) {
	case 2:
		/* Couldn't log in due to bad user/pass */
		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
		break;
	case 1:
		/* Other error (couldn't bind to address, etc) */
		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
		break;
	default:
		break;
	}

	nm_vpn_plugin_set_state (NM_VPN_PLUGIN (plugin), NM_VPN_SERVICE_STATE_STOPPED);
}
示例#11
0
static void
set_property (GObject *object, guint prop_id,
              const GValue *value, GParamSpec *pspec)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (object);

	switch (prop_id) {
	case PROP_DBUS_SERVICE_NAME:
		/* Construct-only */
		priv->dbus_service_name = g_strdup (g_value_get_string (value));
		break;
	case PROP_STATE:
		nm_vpn_plugin_set_state (NM_VPN_PLUGIN (object),
		                         (NMVPNServiceState) g_value_get_uint (value));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
static void
child_watch_cb (GPid pid, gint status, gpointer user_data)
{
	NMVPNPlugin *plugin = NM_VPN_PLUGIN (user_data);
	NMOpensshPluginPrivate *priv = NM_OPENSSH_PLUGIN_GET_PRIVATE (plugin);
	NMVPNPluginFailure failure = NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED;
	guint error = 0;
	gboolean good_exit = FALSE;

	if (WIFEXITED (status)) {
		error = WEXITSTATUS (status);
		if (error != 0)
			nm_warning ("sshtun exited with error code %d", error);
    }
	else if (WIFSTOPPED (status))
		nm_warning ("sshtun stopped unexpectedly with signal %d", WSTOPSIG (status));
	else if (WIFSIGNALED (status))
		nm_warning ("sshtun died with signal %d", WTERMSIG (status));
	else
		nm_warning ("sshtun died from an unknown cause");
  
	sshtun_stop (priv->handle);
	sshtun_del (priv->handle);
	priv->handle = NULL;

	switch (error) {
	case 0:
		good_exit = TRUE;
		break;
	default:
		failure = NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED;
		break;
	}

	if (!good_exit)
		nm_vpn_plugin_failure (plugin, failure);

	nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
}
示例#13
0
static GObject *
constructor (GType type,
             guint n_construct_params,
             GObjectConstructParam *construct_params)
{
	GObject *object;
	NMVPNPlugin *plugin;
	NMVPNPluginPrivate *priv;
	DBusGConnection *connection;
	DBusGProxy *proxy;
	guint request_name_result;
	GError *err = NULL;

	object = G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->constructor (type,
														  n_construct_params,
														  construct_params);
	if (!object)
		return NULL;

	priv = NM_VPN_PLUGIN_GET_PRIVATE (object);
	if (!priv->dbus_service_name)
		goto err;

	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
	if (!connection)
		goto err;

	proxy = dbus_g_proxy_new_for_name (connection,
	                                   "org.freedesktop.DBus",
	                                   "/org/freedesktop/DBus",
	                                   "org.freedesktop.DBus");

	if (!dbus_g_proxy_call (proxy, "RequestName", &err,
	                        G_TYPE_STRING, priv->dbus_service_name,
	                        G_TYPE_UINT, 0,
	                        G_TYPE_INVALID,
	                        G_TYPE_UINT, &request_name_result,
	                        G_TYPE_INVALID)) {
		g_object_unref (proxy);
		goto err;
	}

	g_object_unref (proxy);

	dbus_g_connection_register_g_object (connection,
	                                     NM_VPN_DBUS_PLUGIN_PATH,
	                                     object);

	plugin = NM_VPN_PLUGIN (object);

	nm_vpn_plugin_set_connection (plugin, connection);
	nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_INIT);

	return object;

 err:
	if (err) {
		g_warning ("Failed to initialize VPN plugin: %s", err->message);
		g_error_free (err);
	}

	if (object)
		g_object_unref (object);

	return NULL;
}
static void
l2tpd_watch_cb (GPid pid, gint status, gpointer user_data)
{
	NML2tpPlugin *plugin = NM_L2TP_PLUGIN (user_data);
	NML2tpPluginPrivate *priv = NM_L2TP_PLUGIN_GET_PRIVATE (plugin);
	guint error = 0;
	pid_t my_pid = getpid ();
	char *filename;

	if (WIFEXITED (status)) {
		error = WEXITSTATUS (status);
		if (error != 0)
			g_warning (_("xl2tpd exited with error code %d"), error);
	}
	else if (WIFSTOPPED (status))
		g_warning (_("xl2tpd stopped unexpectedly with signal %d"), WSTOPSIG (status));
	else if (WIFSIGNALED (status))
		g_warning (_("xl2tpd died with signal %d"), WTERMSIG (status));
	else
		g_warning (_("xl2tpd died from an unknown cause"));

	/* Reap child if needed. */
	waitpid (priv->pid_l2tpd, NULL, WNOHANG);
	priv->pid_l2tpd = 0;

	if(priv->ipsec_up) {
		nm_l2tp_stop_ipsec();
	}

	/* Cleaning up config files */
	filename = g_strdup_printf ("/var/run/nm-xl2tpd.conf.%d", my_pid);
	unlink(filename);
	g_free(filename);

	filename = g_strdup_printf ("/var/run/nm-ppp-options.xl2tpd.%d", my_pid);
	unlink(filename);
	g_free(filename);

	filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d/ipsec.conf", my_pid);
//	unlink(filename);
	g_free(filename);

	filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d/ipsec.secrets", my_pid);
//	unlink(filename);
	g_free(filename);

	filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d", my_pid);
	rmdir(filename);
	g_free(filename);

	/* Must be after data->state is set since signals use data->state */
	switch (error) {
	case 16:
		/* hangup */
		// FIXME: better failure reason
		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
		break;
	case 2:
		/* Couldn't log in due to bad user/pass */
		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
		break;
	case 1:
		/* Other error (couldn't bind to address, etc) */
		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
		break;
	default:
		break;
	}

	nm_vpn_plugin_set_state (NM_VPN_PLUGIN (plugin), NM_VPN_SERVICE_STATE_STOPPED);
}