From 31653cd4f700a40e3bb91ad2331d8972ed3e3786 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 12 Dec 2020 19:17:07 +0100 Subject: libtracker-sparql: Add signal to control access to HTTP endpoint This signal is meant for simple access control, and receives the GSocketAddress corresponding to the remote connection. Users may connect a signal handler to block the connection based on that data (e.g. allowing different scopes, loopback connections, local networks, ...). --- src/libtracker-sparql/tracker-endpoint-http.c | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/libtracker-sparql/tracker-endpoint-http.c b/src/libtracker-sparql/tracker-endpoint-http.c index c2b643c3a..de231ca59 100644 --- a/src/libtracker-sparql/tracker-endpoint-http.c +++ b/src/libtracker-sparql/tracker-endpoint-http.c @@ -47,6 +47,11 @@ typedef struct { TrackerSerializerFormat format; } Request; +enum { + BLOCK_REMOTE_ADDRESS, + N_SIGNALS +}; + enum { PROP_0, PROP_HTTP_PORT, @@ -58,6 +63,7 @@ enum { #define JSON_TYPE "application/sparql-results+json" static GParamSpec *props[N_PROPS]; +static guint signals[N_SIGNALS]; static void tracker_endpoint_http_initable_iface_init (GInitableIface *iface); @@ -198,9 +204,22 @@ server_callback (SoupServer *server, TrackerEndpoint *endpoint = user_data; TrackerSparqlConnection *conn; TrackerSerializerFormat format; + GSocketAddress *remote_address; + gboolean block = FALSE; const gchar *sparql; Request *request; + remote_address = soup_client_context_get_remote_address (client); + if (remote_address) { + g_signal_emit (endpoint, signals[BLOCK_REMOTE_ADDRESS], 0, + remote_address, &block); + } + + if (block) { + soup_message_set_status_full (message, 500, "Remote address disallowed"); + return; + } + sparql = g_hash_table_lookup (query, "query"); if (!sparql) { soup_message_set_status_full (message, 500, "No query given"); @@ -321,6 +340,24 @@ tracker_endpoint_http_class_init (TrackerEndpointHttpClass *klass) object_class->set_property = tracker_endpoint_http_set_property; object_class->get_property = tracker_endpoint_http_get_property; + /** + * TrackerEndpointHttp::block-remote-address: + * @self: The #TrackerNotifier + * @address: The socket address of the remote connection + * + * Allows control over the connections stablished. The given + * address is that of the requesting peer. + * + * Returning %FALSE in this handler allows the connection, + * returning %TRUE blocks it. The default with no signal + * handlers connected is %FALSE. + */ + signals[BLOCK_REMOTE_ADDRESS] = + g_signal_new ("block-remote-address", + TRACKER_TYPE_ENDPOINT_HTTP, 0, 0, + g_signal_accumulator_first_wins, NULL, NULL, + G_TYPE_BOOLEAN, 1, G_TYPE_SOCKET_ADDRESS); + props[PROP_HTTP_PORT] = g_param_spec_uint ("http-port", "HTTP Port", -- cgit v1.2.1