From: Daniel Wagner <[email protected]>
ConnMan needs to identify application in a secure way when they are
using the Session API. The current D-Bus server implemention supports
two types of LSM, POSIX and SELinux. In order to support SMACK or
TOMOYO the D-Bus code base needs to be patch. This is the initial work
to support at least POSIX and SELinux. Maybe in the future we are able
to support also the other LSMs.
The idea behind gsec is to keep the LSM related code together in one
directory. The API introduces in this patch is not any way final. It
will need some more time figuring out how are able to intregrate this
in a nice way.
The current API introduces g_sec_get_selinux_label() which will return
the SELinux context. The function will issuing a
GetConnectionSELinuxSecurityContext method call.
Note, that this function is not documented in the D-Bus
specification. See for more details the source code dbus/bus/drivers.c
and dbus/bus/selinux.c in the D-Bus reference implementation.
---
Makefile.am | 3 +
gsec/gsec.h | 36 ++++++++++++
gsec/selinux.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 210 insertions(+)
create mode 100644 gsec/gsec.h
create mode 100644 gsec/selinux.c
diff --git a/Makefile.am b/Makefile.am
index 4cb6ad2..23e7ec9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -25,6 +25,8 @@ 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
+gsec_sources = gsec/gsec.h gsec/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
@@ -71,6 +73,7 @@ MANUAL_PAGES =
sbin_PROGRAMS = src/connmand
src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) $(gweb_sources) \
+ $(gsec_sources) \
$(builtin_sources) src/connman.ver \
src/main.c src/connman.h src/log.c \
src/error.c src/plugin.c src/task.c \
diff --git a/gsec/gsec.h b/gsec/gsec.h
new file mode 100644
index 0000000..7fb5845
--- /dev/null
+++ b/gsec/gsec.h
@@ -0,0 +1,36 @@
+/*
+ *
+ * D-Bus security helper library
+ *
+ * Copyright (C) 2012 BWM CarIT 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ *
+ */
+
+#ifndef __GSEC_H
+#define __GSEC_H
+
+#include <dbus/dbus.h>
+
+typedef void (* GSecGetContextCallback) (const unsigned char *context,
+ void *user_data);
+
+int g_sec_get_selinux_context(DBusConnection *connection,
+ const char *service,
+ GSecGetContextCallback func,
+ void *user_data);
+
+
+#endif /* __GSEC_H */
diff --git a/gsec/selinux.c b/gsec/selinux.c
new file mode 100644
index 0000000..e2f06a9
--- /dev/null
+++ b/gsec/selinux.c
@@ -0,0 +1,171 @@
+/*
+ *
+ * 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 <gdbus.h>
+
+#include <glib.h>
+
+#include "gsec.h"
+
+#define info(fmt...)
+#define error(fmt...)
+#define debug(fmt...)
+
+struct selinux_data {
+ GSecGetContextCallback func;
+ void *user_data;
+};
+
+static unsigned char *parse_context(DBusMessage *msg)
+{
+ DBusMessageIter iter, array;
+ unsigned char *ctx, *p;
+ int size = 0;
+
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_recurse(&iter, &array);
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_BYTE) {
+ size++;
+
+ dbus_message_iter_next(&array);
+ }
+
+ if (size == 0)
+ return NULL;
+
+ ctx = g_try_malloc0(size + 1);
+ if (ctx == NULL)
+ return NULL;
+
+ p = ctx;
+
+ 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, p);
+
+ p++;
+ dbus_message_iter_next(&array);
+ }
+
+ return ctx;
+}
+
+static void selinux_get_context_reply(DBusPendingCall *call, void *user_data)
+{
+ struct selinux_data *data = user_data;
+ DBusMessage *reply;
+ unsigned char *context = NULL;
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+ error("Failed to retrieve SELinux context");
+ goto done;
+ }
+
+ if (dbus_message_has_signature(reply, "ay") == FALSE) {
+ error("Message signature is wrong");
+ goto done;
+ }
+
+ context = parse_context(reply);
+
+ (*data->func)(context, data->user_data);
+
+ g_free(context);
+
+done:
+ dbus_message_unref(reply);
+
+ dbus_pending_call_unref(call);
+}
+
+int g_sec_get_selinux_context(DBusConnection *connection,
+ const char *service,
+ GSecGetContextCallback func,
+ void *user_data)
+{
+ struct selinux_data *data;
+ DBusPendingCall *call;
+ DBusMessage *msg = NULL;
+ int err;
+
+ if (func == NULL)
+ return -EINVAL;
+
+ data = g_try_new0(struct selinux_data, 1);
+ if (data == NULL) {
+ error("Can't allocate data structure");
+ return -ENOMEM;
+ }
+
+ 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");
+ err = -ENOMEM;
+ goto err;
+ }
+
+ 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");
+ err = -EINVAL;
+ goto err;
+ }
+
+ if (call == NULL) {
+ error("D-Bus connection not available");
+ err = -EINVAL;
+ goto err;
+ }
+
+ 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 0;
+
+err:
+ dbus_message_unref(msg);
+ g_free(data);
+
+ return err;
+}
--
1.8.0.rc0
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman