From: Daniel Wagner <[email protected]>
---
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 8693752..4bb1194 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
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.12.1.382.gb0576a6
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman