Esempio n. 1
0
static gboolean
impl_vpn_plugin_need_secrets (NMVPNPlugin *plugin,
                              GHashTable *properties,
                              char **setting_name,
                              GError **err)
{
	gboolean ret = FALSE;
	NMConnection *connection;
	char *sn = NULL;
	GError *ns_err = NULL;
	gboolean needed = FALSE;
	GError *cnfh_err = NULL;

	g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);
	g_return_val_if_fail (properties != NULL, FALSE);

	connection = nm_connection_new_from_hash (properties, &cnfh_err);
	if (!connection) {
		g_set_error (err,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
		             "The connection was invalid: '%s' / '%s' invalid: %d.",
		             g_type_name (nm_connection_lookup_setting_type_by_quark (cnfh_err->domain)),
		             cnfh_err->message, cnfh_err->code);
		g_error_free (cnfh_err);
		return FALSE;
	}

	if (!NM_VPN_PLUGIN_GET_CLASS (plugin)->need_secrets) {
		*setting_name = "";
		ret = TRUE;
		goto out;
	}

	needed = NM_VPN_PLUGIN_GET_CLASS (plugin)->need_secrets (plugin, connection, &sn, &ns_err);
	if (ns_err) {
		*err = g_error_copy (ns_err);
		g_error_free (ns_err);
		goto out;
	}

	ret = TRUE;
	if (needed) {
		/* Push back the quit timer so the VPN plugin doesn't quit in the
		 * middle of asking the user for secrets.
		 */
		schedule_quit_timer (plugin);

		g_assert (sn);
		*setting_name = g_strdup (sn);
	} else {
		/* No secrets required */
		*setting_name = g_strdup ("");
	}

out:
	return ret;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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);
}