Example #1
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);
}
Example #2
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);
}
Example #3
0
static gboolean
connect_timer_expired (gpointer data)
{
	NMVPNPlugin *plugin = NM_VPN_PLUGIN (data);
	GError *err = NULL;

	NM_VPN_PLUGIN_GET_PRIVATE (plugin)->connect_timer = 0;
	g_message ("Connect timer expired, disconnecting.");
	nm_vpn_plugin_disconnect (plugin, &err);
	if (err) {
		g_warning ("Disconnect failed: %s", err->message);
		g_error_free (err);
	}

	return G_SOURCE_REMOVE;
}
Example #4
0
static gboolean
impl_vpn_plugin_new_secrets (NMVPNPlugin *plugin,
                             GHashTable *properties,
                             GError **error)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
	NMConnection *connection;
	GError *local = NULL;
	gboolean success;

	if (priv->state != NM_VPN_SERVICE_STATE_STARTING) {
		g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_WRONG_STATE,
		             "Could not accept new secrets: 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;
	}

	if (!NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets) {
		g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED,
		                     "Could not accept new secrets: plugin cannot process interactive secrets");
		g_object_unref (connection);
		return FALSE;
	}

	success = NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets (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 and idle handler so that the NewSecrets
		 * method return gets sent before the STOP StateChanged signal.
		 */
		schedule_fail_stop (plugin);
	}

	g_object_unref (connection);
	return success;
}
Example #5
0
void
nm_vpn_plugin_set_config (NMVPNPlugin *plugin,
                          GHashTable *config)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
	GValue *val;

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

	priv->got_config = TRUE;

	val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP4);
	if (val && g_value_get_boolean (val))
		priv->has_ip4 = TRUE;
	val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP6);
	if (val && g_value_get_boolean (val))
		priv->has_ip6 = TRUE;

	g_warn_if_fail (priv->has_ip4 || priv->has_ip6);

	/* Record the items that need to also be inserted into the
	 * ip4config, for compatibility with older daemons.
	 */
	val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_BANNER);
	if (val) {
		g_value_init (&priv->banner, G_VALUE_TYPE (val));
		g_value_copy (val, &priv->banner);
	}
	val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_TUNDEV);
	if (val) {
		g_value_init (&priv->tundev, G_VALUE_TYPE (val));
		g_value_copy (val, &priv->tundev);
	}
	val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY);
	if (val) {
		g_value_init (&priv->gateway, G_VALUE_TYPE (val));
		g_value_copy (val, &priv->gateway);
	}
	val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_MTU);
	if (val) {
		g_value_init (&priv->mtu, G_VALUE_TYPE (val));
		g_value_copy (val, &priv->mtu);
	}

	g_signal_emit (plugin, signals[CONFIG], 0, config);
}
Example #6
0
static void
state_changed (NMVPNPlugin *plugin, NMVPNServiceState state)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);

	switch (state) {
	case NM_VPN_SERVICE_STATE_STARTING:
		/* Remove the quit timer. */
		if (priv->quit_timer)
			g_source_remove (priv->quit_timer);

		if (priv->fail_stop_id) {
			g_source_remove (priv->fail_stop_id);
			priv->fail_stop_id = 0;
		}

		/* Add a timer to make sure we do not wait indefinitely for the successful connect. */
		priv->connect_timer = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
		                                                  NM_VPN_PLUGIN_CONNECT_TIMER,
		                                                  connect_timer_expired,
		                                                  plugin,
		                                                  connect_timer_removed);
		break;
	case NM_VPN_SERVICE_STATE_STOPPED:
		priv->quit_timer = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
		                                               NM_VPN_PLUGIN_QUIT_TIMER,
		                                               quit_timer_expired,
		                                               plugin,
		                                               quit_timer_removed);
		break;
	default:
		/* Clean up all timers we might have set up. */
		if (priv->connect_timer)
			g_source_remove (priv->connect_timer);

		if (priv->quit_timer)
			g_source_remove (priv->quit_timer);

		if (priv->fail_stop_id) {
			g_source_remove (priv->fail_stop_id);
			priv->fail_stop_id = 0;
		}
		break;
	}
}
Example #7
0
static void
get_property (GObject *object, guint prop_id,
			  GValue *value, GParamSpec *pspec)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (object);

	switch (prop_id) {
	case PROP_DBUS_SERVICE_NAME:
		g_value_set_string (value, priv->dbus_service_name);
		break;
	case PROP_STATE:
		g_value_set_uint (value, nm_vpn_plugin_get_state (NM_VPN_PLUGIN (object)));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
Example #8
0
static void
finalize (GObject *object)
{
	NMVPNPlugin *plugin = NM_VPN_PLUGIN (object);
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);

	nm_vpn_plugin_set_connection (plugin, NULL);
	g_free (priv->dbus_service_name);

	if (G_IS_VALUE (&priv->banner))
		g_value_unset (&priv->banner);
	if (G_IS_VALUE (&priv->tundev))
		g_value_unset (&priv->tundev);
	if (G_IS_VALUE (&priv->gateway))
		g_value_unset (&priv->gateway);
	if (G_IS_VALUE (&priv->mtu))
		g_value_unset (&priv->mtu);

	G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->finalize (object);
}
Example #9
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;
	}
}
Example #10
0
static void
state_changed (NMVPNPlugin *plugin, NMVPNServiceState state)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);

	switch (state) {
	case NM_VPN_SERVICE_STATE_STARTING:
		nm_clear_g_source (&priv->quit_timer);
		nm_clear_g_source (&priv->fail_stop_id);
		break;
	case NM_VPN_SERVICE_STATE_STOPPED:
		schedule_quit_timer (plugin);
		break;
	default:
		/* Clean up all timers we might have set up. */
		nm_clear_g_source (&priv->connect_timer);
		nm_clear_g_source (&priv->quit_timer);
		nm_clear_g_source (&priv->fail_stop_id);
		break;
	}
}
Example #11
0
/**
 * nm_vpn_plugin_secrets_required:
 * @plugin: the #NMVPNPlugin
 * @message: an information message about why secrets are required, if any
 * @hints: VPN specific secret names for required new secrets
 *
 * Called by VPN plugin implementations to signal to NetworkManager that secrets
 * are required during the connection process.  This signal may be used to
 * request new secrets when the secrets originally provided by NetworkManager
 * are insufficient, or the VPN process indicates that it needs additional
 * information to complete the request.
 *
 * Since: 0.9.10
 */
void
nm_vpn_plugin_secrets_required (NMVPNPlugin *plugin,
                                const char *message,
                                const char **hints)
{
	NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);

	/* Plugin must be able to accept the new secrets if it calls this method */
	g_return_if_fail (NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets);

	/* Plugin cannot call this method if NetworkManager didn't originally call
	 * ConnectInteractive().
	 */
	g_return_if_fail (priv->interactive == TRUE);

	/* Cancel the connect timer since secrets might take a while.  It'll
	 * get restarted when the secrets come back via NewSecrets().
	 */
	nm_clear_g_source (&priv->connect_timer);

	g_signal_emit (plugin, signals[SECRETS_REQUIRED], 0, message, hints);
}
Example #12
0
static void
quit_timer_removed (gpointer data)
{
	NM_VPN_PLUGIN_GET_PRIVATE (data)->quit_timer = 0;
}
Example #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;
}