From: Daniel Wagner <daniel.wag...@bmw-carit.de>

---
 Makefile.am     |   2 +-
 gdbus/gdbus.h   |   9 +++
 gdbus/selinux.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 177 insertions(+), 1 deletion(-)
 create mode 100644 gdbus/selinux.c

diff --git a/Makefile.am b/Makefile.am
index b845d6e..dbcfd86 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,7 +23,7 @@ local_headers = $(foreach file,$(include_HEADERS) 
$(nodist_include_HEADERS) \
 
 
 gdbus_sources = gdbus/gdbus.h gdbus/mainloop.c gdbus/watch.c \
-                                       gdbus/object.c gdbus/polkit.c
+                       gdbus/object.c gdbus/polkit.c gdbus/selinux.c
 
 gdhcp_sources = gdhcp/gdhcp.h gdhcp/common.h gdhcp/common.c gdhcp/client.c \
                gdhcp/server.c gdhcp/ipv4ll.h gdhcp/ipv4ll.c gdhcp/unaligned.h
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 0a8a27c..c7a7e6f 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -62,6 +62,10 @@ typedef void (* GDBusSecurityFunction) (DBusConnection 
*connection,
                                                gboolean interaction,
                                                GDBusPendingReply pending);
 
+typedef void (* GDBusSELinuxFunction) (unsigned char *context,
+                                       unsigned int size,
+                                       void *user_data);
+
 typedef enum {
        G_DBUS_METHOD_FLAG_DEPRECATED = (1 << 0),
        G_DBUS_METHOD_FLAG_NOREPLY    = (1 << 1),
@@ -160,6 +164,11 @@ typedef struct {
        .args = _args, \
        .flags = G_DBUS_SIGNAL_FLAG_DEPRECATED
 
+gboolean g_dbus_selinux_get_context(DBusConnection *connection,
+                                       const char *service,
+                                       GDBusSELinuxFunction func,
+                                       void *user_data);
+
 gboolean g_dbus_register_interface(DBusConnection *connection,
                                        const char *path, const char *name,
                                        const GDBusMethodTable *methods,
diff --git a/gdbus/selinux.c b/gdbus/selinux.c
new file mode 100644
index 0000000..f7d932f
--- /dev/null
+++ b/gdbus/selinux.c
@@ -0,0 +1,167 @@
+/*
+ *
+ *  D-Bus helper library
+ *
+ *  Copyright (C) 2012  BMW Car IT GmbH. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+
+#include <dbus/dbus.h>
+
+#include <glib.h>
+
+#include "gdbus.h"
+
+#define info(fmt...)
+#define error(fmt...)
+#define debug(fmt...)
+
+struct selinux_data {
+       GDBusSELinuxFunction func;
+       void *user_data;
+};
+
+static int parse_context(DBusMessage *msg, unsigned char **context,
+                               unsigned int *size)
+{
+       DBusMessageIter iter, array;
+       unsigned char *ctx;
+       int i = 0;
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_recurse(&iter, &array);
+       while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_BYTE) {
+               i++;
+
+               dbus_message_iter_next(&array);
+       }
+
+       *size = i;
+       if (i == 0)
+               return 0;
+
+       ctx = g_try_malloc((gsize) *size);
+       if (ctx == NULL)
+               return -ENOMEM;
+
+       i = 0;
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_recurse(&iter, &array);
+       while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_BYTE) {
+               dbus_message_iter_get_basic(&array, &ctx[i]);
+
+               i++;
+               dbus_message_iter_next(&array);
+       }
+
+       *context = ctx;
+
+       return 0;
+}
+
+static void selinux_get_context_reply(DBusPendingCall *call, void *user_data)
+{
+       struct selinux_data *data = user_data;
+       DBusMessage *reply;
+       unsigned char *context = NULL;
+       unsigned int size;
+
+       reply = dbus_pending_call_steal_reply(call);
+
+       if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+               goto fail;
+
+       if (dbus_message_has_signature(reply, "ay") == FALSE)
+               goto fail;
+
+       if (parse_context(reply, &context, &size) < 0) {
+               error("Can't parse context");
+               goto fail;
+       }
+
+       if (data->func != NULL)
+               (*data->func)(context, size, data->user_data);
+
+       g_free(context);
+
+fail:
+       dbus_message_unref(reply);
+
+       dbus_pending_call_unref(call);
+}
+
+gboolean g_dbus_selinux_get_context(DBusConnection *connection,
+                       const char *service,
+                       GDBusSELinuxFunction func,
+                       void *user_data)
+{
+       struct selinux_data *data;
+       DBusPendingCall *call;
+       DBusMessage *msg = NULL;
+
+       data = g_try_new0(struct selinux_data, 1);
+       if (data == NULL) {
+               error("Can't allocate data structure");
+               goto fail;
+       }
+
+       msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+                                       DBUS_INTERFACE_DBUS,
+                                       "GetConnectionSELinuxSecurityContext");
+       if (msg == NULL) {
+               error("Can't allocate new message");
+               goto fail;
+       }
+
+       dbus_message_append_args(msg, DBUS_TYPE_STRING, &service,
+                                       DBUS_TYPE_INVALID);
+
+       if (dbus_connection_send_with_reply(connection, msg,
+                                               &call, -1) == FALSE) {
+               error("Failed to execute method call");
+               goto fail;
+       }
+
+       if (call == NULL) {
+               error("D-Bus connection not available");
+               goto fail;
+       }
+
+       data->func = func;
+       data->user_data = user_data;
+
+       dbus_pending_call_set_notify(call, selinux_get_context_reply,
+                                                       data, g_free);
+
+       dbus_message_unref(msg);
+
+       return TRUE;
+
+fail:
+       if (msg != NULL)
+               dbus_message_unref(msg);
+       g_free(data);
+
+       return FALSE;
+}
-- 
1.7.11.4

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to