[gupnp/wip/acl] wip: Add device/service information to ACL
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gupnp/wip/acl] wip: Add device/service information to ACL
- Date: Sun, 23 Feb 2014 16:20:35 +0000 (UTC)
commit 5b06231d7cd0ce158c631dbaeb2b1ec82f465993
Author: Jens Georg <mail jensge org>
Date: Sun Feb 23 16:33:01 2014 +0100
wip: Add device/service information to ACL
Signed-off-by: Jens Georg <mail jensge org>
libgupnp/gupnp-acl-private.h | 77 +++++++++++++++++++++++++
libgupnp/gupnp-acl.c | 93 ++++++++++++++++++++++++++++++-
libgupnp/gupnp-acl.h | 24 +++++++-
libgupnp/gupnp-context-private.h | 7 ++
libgupnp/gupnp-context.c | 114 ++++++++++---------------------------
libgupnp/gupnp-service.c | 15 +++--
6 files changed, 234 insertions(+), 96 deletions(-)
---
diff --git a/libgupnp/gupnp-acl-private.h b/libgupnp/gupnp-acl-private.h
new file mode 100644
index 0000000..9d8f992
--- /dev/null
+++ b/libgupnp/gupnp-acl-private.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 Jens Georg <mail jensge org>
+ *
+ * Author: Jens Georg <mail jensge org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_ACL_PRIVATE_H__
+#define __GUPNP_ACL_PRIVATE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libsoup/soup-session.h>
+
+#include "gupnp-acl.h"
+#include "gupnp-context.h"
+
+G_BEGIN_DECLS
+
+typedef struct _AclServerHandler
+{
+ GUPnPService *service;
+ GUPnPContext *context;
+ SoupServerCallback callback;
+ gpointer user_data;
+ GDestroyNotify notify;
+} AclServerHandler;
+
+typedef struct _AsyncAclHandler
+{
+ SoupServer *server;
+ SoupMessage *message;
+ char *path;
+ GHashTable *query;
+ SoupClientContext *client;
+ AclServerHandler *handler;
+} AsyncAclHandler;
+
+G_GNUC_INTERNAL AclServerHandler *
+acl_server_handler_new (GUPnPService *service,
+ GUPnPContext *context,
+ SoupServerCallback callback,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+G_GNUC_INTERNAL void
+acl_server_handler_free (AclServerHandler *handler);
+
+G_GNUC_INTERNAL AsyncAclHandler *
+async_acl_handler_new (SoupServer *server,
+ SoupMessage *message,
+ const char *path,
+ GHashTable *query,
+ SoupClientContext *client,
+ AclServerHandler *handler);
+
+G_GNUC_INTERNAL void
+async_acl_handler_free (AsyncAclHandler *handler);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libgupnp/gupnp-acl.c b/libgupnp/gupnp-acl.c
index 4a5abbf..8118965 100644
--- a/libgupnp/gupnp-acl.c
+++ b/libgupnp/gupnp-acl.c
@@ -20,6 +20,7 @@
*/
#include "gupnp-acl.h"
+#include "gupnp-acl-private.h"
G_DEFINE_INTERFACE(GUPnPAcl, gupnp_acl, G_TYPE_OBJECT)
@@ -31,6 +32,11 @@ gupnp_acl_default_init (GUPnPAclInterface *klass)
/**
* gupnp_acl_is_allowed:
* @self: an instance of #GUPnPAcl
+ * @device: (allow-none): The #GUPnPDevice associated with @path or %NULL if
+ * unknown.
+ * @service: (allow-none): The #GUPnPService associated with @path or %NULL if
+ * unknown.
+ * @path: The path being served.
* @address: IP address of the peer.
* @returns: %TRUE if the peer is allowed, %FALSE otherwise
*
@@ -39,16 +45,29 @@ gupnp_acl_default_init (GUPnPAclInterface *klass)
* Since: 0.21.0
*/
gboolean
-gupnp_acl_is_allowed (GUPnPAcl *self, const char *address)
+gupnp_acl_is_allowed (GUPnPAcl *self,
+ GUPnPDevice *device,
+ GUPnPService *service,
+ const char *path,
+ const char *address)
{
g_return_val_if_fail (GUPNP_IS_ACL (self), FALSE);
- return GUPNP_ACL_GET_INTERFACE (self)->is_allowed (self, address);
+ return GUPNP_ACL_GET_INTERFACE (self)->is_allowed (self,
+ device,
+ service,
+ path,
+ address);
}
/**
* gupnp_acl_is_allowed_async:
* @self: a #GUPnPAcl
+ * @device: (allow-none): The #GUPnPDevice associated with @path or %NULL if
+ * unknown.
+ * @service: (allow-none): The #GUPnPService associated with @path or %NULL if
+ * unknown.
+ * @path: The path being served.
* @address: IP address of the peer
* @cancellable: (allow-none): A #GCancellable which can be used to cancel the
* operation.
@@ -67,6 +86,9 @@ gupnp_acl_is_allowed (GUPnPAcl *self, const char *address)
*/
void
gupnp_acl_is_allowed_async (GUPnPAcl *self,
+ GUPnPDevice *device,
+ GUPnPService *service,
+ const char *path,
const char *address,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -75,6 +97,9 @@ gupnp_acl_is_allowed_async (GUPnPAcl *self,
g_return_if_fail (GUPNP_IS_ACL (self));
GUPNP_ACL_GET_INTERFACE (self)->is_allowed_async (self,
+ device,
+ service,
+ path,
address,
cancellable,
callback,
@@ -120,3 +145,67 @@ gupnp_acl_can_sync (GUPnPAcl *self)
return GUPNP_ACL_GET_INTERFACE (self)->can_sync (self);
}
+
+AclServerHandler *
+acl_server_handler_new (GUPnPService *service,
+ GUPnPContext *context,
+ SoupServerCallback callback,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ AclServerHandler *handler = g_new0 (AclServerHandler, 1);
+
+ handler->service = service ? g_object_ref (service) : NULL;
+ handler->context = g_object_ref (context);
+ handler->callback = callback;
+ handler->user_data = user_data;
+ handler->notify = notify;
+
+ return handler;
+}
+
+void
+acl_server_handler_free (AclServerHandler *handler)
+{
+ g_clear_object (&handler->service);
+ g_clear_object (&handler->context);
+
+ if (handler->notify != NULL)
+ handler->notify (handler->user_data);
+
+ g_free (handler);
+}
+
+AsyncAclHandler *
+async_acl_handler_new (SoupServer *server,
+ SoupMessage *message,
+ const char *path,
+ GHashTable *query,
+ SoupClientContext *client,
+ AclServerHandler *handler)
+{
+ AsyncAclHandler *data = g_slice_new0 (AsyncAclHandler);
+
+ data->server = g_object_ref (server);
+ data->message = g_object_ref (message);
+ data->path = g_strdup (path);
+ if (query != NULL)
+ data->query = g_hash_table_ref (query);
+ data->client = g_boxed_copy (SOUP_TYPE_CLIENT_CONTEXT, client);
+ data->handler = handler;
+
+ return data;
+}
+
+void
+async_acl_handler_free (AsyncAclHandler *handler)
+{
+ g_object_unref (handler->server);
+ g_object_unref (handler->message);
+ g_free (handler->path);
+ if (handler->query != NULL)
+ g_hash_table_unref (handler->query);
+ g_boxed_free (SOUP_TYPE_CLIENT_CONTEXT, handler->client);
+
+ g_slice_free (AsyncAclHandler, handler);
+}
diff --git a/libgupnp/gupnp-acl.h b/libgupnp/gupnp-acl.h
index 619b22d..7aef20c 100644
--- a/libgupnp/gupnp-acl.h
+++ b/libgupnp/gupnp-acl.h
@@ -49,13 +49,23 @@ gupnp_acl_get_type (void) G_GNUC_CONST;
typedef struct _GUPnPAcl GUPnPAcl;
typedef struct _GUPnPAclInterface GUPnPAclInterface;
+/* Forward declarations to avoid recursive includes */
+typedef struct _GUPnPDevice GUPnPDevice;
+typedef struct _GUPnPService GUPnPService;
+
struct _GUPnPAclInterface {
GTypeInterface parent;
- gboolean (*is_allowed) (GUPnPAcl *self,
- const char *address);
+ gboolean (*is_allowed) (GUPnPAcl *self,
+ GUPnPDevice *device,
+ GUPnPService *service,
+ const char *path,
+ const char *address);
void (*is_allowed_async) (GUPnPAcl *self,
+ GUPnPDevice *device,
+ GUPnPService *service,
+ const char *path,
const char *address,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -75,11 +85,17 @@ struct _GUPnPAclInterface {
};
gboolean
-gupnp_acl_is_allowed (GUPnPAcl *self,
- const char *address);
+gupnp_acl_is_allowed (GUPnPAcl *self,
+ GUPnPDevice *device,
+ GUPnPService *service,
+ const char *path,
+ const char *address);
void
gupnp_acl_is_allowed_async (GUPnPAcl *self,
+ GUPnPDevice *device,
+ GUPnPService *service,
+ const char *path,
const char *address,
GCancellable *cancellable,
GAsyncReadyCallback callback,
diff --git a/libgupnp/gupnp-context-private.h b/libgupnp/gupnp-context-private.h
index 18c4813..212d5e0 100644
--- a/libgupnp/gupnp-context-private.h
+++ b/libgupnp/gupnp-context-private.h
@@ -24,11 +24,18 @@
#include <libsoup/soup.h>
+#include "gupnp-acl-private.h"
+
G_BEGIN_DECLS
G_GNUC_INTERNAL const char *
_gupnp_context_get_server_url (GUPnPContext *context);
+G_GNUC_INTERNAL void
+_gupnp_context_add_server_handler_with_data (GUPnPContext *context,
+ const char *path,
+ AclServerHandler *data);
+
G_END_DECLS
#endif /* __GUPNP_CONTEXT_PRIVATE_H__ */
diff --git a/libgupnp/gupnp-context.c b/libgupnp/gupnp-context.c
index c906175..6aca2eb 100644
--- a/libgupnp/gupnp-context.c
+++ b/libgupnp/gupnp-context.c
@@ -50,6 +50,7 @@
#include <glib/gstdio.h>
#include "gupnp-acl.h"
+#include "gupnp-acl-private.h"
#include "gupnp-context.h"
#include "gupnp-context-private.h"
#include "gupnp-error.h"
@@ -59,41 +60,6 @@
#define GUPNP_CONTEXT_DEFAULT_LANGUAGE "en"
-typedef struct _GUPnPContextAclServerHandler
-{
- GUPnPContext *context;
- SoupServerCallback callback;
- gpointer user_data;
- GDestroyNotify notify;
-} GUPnPContextAclServerHandler;
-
-static GUPnPContextAclServerHandler *
-gupnp_acl_server_handler_new (GUPnPContext *context,
- SoupServerCallback callback,
- gpointer user_data,
- GDestroyNotify notify)
-{
- GUPnPContextAclServerHandler *handler = g_new0 (GUPnPContextAclServerHandler, 1);
-
- handler->context = g_object_ref (context);
- handler->callback = callback;
- handler->user_data = user_data;
- handler->notify = notify;
-
- return handler;
-}
-
-static void
-gupnp_acl_server_handler_free (GUPnPContextAclServerHandler *handler)
-{
- g_clear_object (&handler->context);
-
- if (handler->notify != NULL)
- handler->notify (handler->user_data);
-
- g_free (handler);
-}
-
static void
gupnp_acl_server_handler (SoupServer *server,
SoupMessage *msg,
@@ -1384,50 +1350,6 @@ gupnp_context_set_acl (GUPnPContext *context, GUPnPAcl *acl)
g_object_notify (G_OBJECT (context), "acl");
}
-typedef struct _AsyncAclHandler
-{
- SoupServer *server;
- SoupMessage *message;
- char *path;
- GHashTable *query;
- SoupClientContext *client;
- GUPnPContextAclServerHandler *handler;
-} AsyncAclHandler;
-
-static AsyncAclHandler *
-async_acl_handler_new (SoupServer *server,
- SoupMessage *message,
- const char *path,
- GHashTable *query,
- SoupClientContext *client,
- GUPnPContextAclServerHandler *handler)
-{
- AsyncAclHandler *data = g_slice_new0 (AsyncAclHandler);
-
- data->server = g_object_ref (server);
- data->message = g_object_ref (message);
- data->path = g_strdup (path);
- if (query != NULL)
- data->query = g_hash_table_ref (query);
- data->client = g_boxed_copy (SOUP_TYPE_CLIENT_CONTEXT, client);
- data->handler = handler;
-
- return data;
-}
-
-void
-async_acl_handler_free (AsyncAclHandler *handler)
-{
- g_object_unref (handler->server);
- g_object_unref (handler->message);
- g_free (handler->path);
- if (handler->query != NULL)
- g_hash_table_unref (handler->query);
- g_boxed_free (SOUP_TYPE_CLIENT_CONTEXT, handler->client);
-
- g_slice_free (AsyncAclHandler, handler);
-}
-
static void
gupnp_acl_async_callback (GUPnPAcl *acl,
GAsyncResult *res,
@@ -1459,10 +1381,19 @@ gupnp_acl_server_handler (SoupServer *server,
SoupClientContext *client,
gpointer user_data)
{
- GUPnPContextAclServerHandler *handler = (GUPnPContextAclServerHandler *) user_data;
+ AclServerHandler *handler = (AclServerHandler *) user_data;
+ GUPnPDevice *device = NULL;
+ if (handler->service) {
+ g_object_get (handler->service,
+ "root-device", &device,
+ NULL);
+ }
if (gupnp_acl_can_sync (handler->context->priv->acl)) {
if (!gupnp_acl_is_allowed (handler->context->priv->acl,
+ device,
+ handler->service,
+ path,
soup_client_context_get_host (client))) {
soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
@@ -1475,6 +1406,9 @@ gupnp_acl_server_handler (SoupServer *server,
soup_server_pause_message (server, msg);
gupnp_acl_is_allowed_async (handler->context->priv->acl,
+ device,
+ handler->service,
+ path,
soup_client_context_get_host (client),
NULL,
(GAsyncReadyCallback) gupnp_acl_async_callback,
@@ -1511,13 +1445,13 @@ gupnp_context_add_server_handler (GUPnPContext *context,
g_return_if_fail (GUPNP_IS_CONTEXT (context));
if (use_acl) {
- GUPnPContextAclServerHandler *handler;
- handler = gupnp_acl_server_handler_new (context, callback, user_data, destroy);
+ AclServerHandler *handler;
+ handler = acl_server_handler_new (NULL, context, callback, user_data, destroy);
soup_server_add_handler (context->priv->server,
path,
gupnp_acl_server_handler,
handler,
- (GDestroyNotify) gupnp_acl_server_handler_free);
+ (GDestroyNotify) acl_server_handler_free);
} else
soup_server_add_handler (context->priv->server,
path,
@@ -1526,6 +1460,20 @@ gupnp_context_add_server_handler (GUPnPContext *context,
destroy);
}
+void
+_gupnp_context_add_server_handler_with_data (GUPnPContext *context,
+ const char *path,
+ AclServerHandler *handler)
+{
+ g_return_if_fail (GUPNP_IS_CONTEXT (context));
+
+ soup_server_add_handler (context->priv->server,
+ path,
+ gupnp_acl_server_handler,
+ handler,
+ (GDestroyNotify) acl_server_handler_free);
+}
+
/**
* gupnp_context_remove_server_handler:
* @context:
diff --git a/libgupnp/gupnp-service.c b/libgupnp/gupnp-service.c
index f904cbe..a6ff31a 100644
--- a/libgupnp/gupnp-service.c
+++ b/libgupnp/gupnp-service.c
@@ -31,6 +31,7 @@
#include <gmodule.h>
#include <libsoup/soup-date.h>
#include <string.h>
+
#include "gupnp-service.h"
#include "gupnp-root-device.h"
#include "gupnp-context-private.h"
@@ -915,7 +916,6 @@ control_server_handler (SoupServer *server,
char *action_name;
char *end;
GUPnPServiceAction *action;
- GUPnPAcl *acl;
service = GUPNP_SERVICE (user_data);
@@ -1436,6 +1436,7 @@ gupnp_service_constructor (GType type,
GObject *object;
GUPnPServiceInfo *info;
GUPnPContext *context;
+ AclServerHandler *handler;
char *url;
char *path;
@@ -1459,24 +1460,24 @@ gupnp_service_constructor (GType type,
/* Run listener on controlURL */
url = gupnp_service_info_get_control_url (info);
path = path_from_url (url);
- gupnp_context_add_server_handler (context,
- TRUE,
- path,
+ handler = acl_server_handler_new (GUPNP_SERVICE (object),
+ context,
control_server_handler,
object,
NULL);
+ _gupnp_context_add_server_handler_with_data (context, path, handler);
g_free (path);
g_free (url);
/* Run listener on eventSubscriptionURL */
url = gupnp_service_info_get_event_subscription_url (info);
path = path_from_url (url);
- gupnp_context_add_server_handler (context,
- TRUE,
- path,
+ handler = acl_server_handler_new (GUPNP_SERVICE (object),
+ context,
subscription_server_handler,
object,
NULL);
+ _gupnp_context_add_server_handler_with_data (context, path, handler);
g_free (path);
g_free (url);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]