Hi Patrik,

On 19.10.2012 21:35, Patrik Flykt wrote:

        Hi,

gdbus/ should be kept in sync between Bluez, ConnMan, oFono and neard.
Any other code should be added elsewhere.

Maybe we should move this part into a plugin for LSM, so that we can support more than SELinux.

On Wed, 2012-10-17 at 14:42 +0200, Daniel Wagner wrote:
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]);
+

What are we fetching here, individual bytes or something else? Should
something be strdup'ed if it's not bytes?

The specification is missing that part. From the code we have following:

bus/driver.c

{ "GetConnectionSELinuxSecurityContext",
    DBUS_TYPE_STRING_AS_STRING,
    DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
    bus_driver_handle_get_connection_selinux_security_context },

which eventually ends in bus/selinux.c:bus_selinux_append_context()

  if (!dbus_message_append_args (message,
                                 DBUS_TYPE_ARRAY,
                                 DBUS_TYPE_BYTE,
                                 &context,
                                 strlen (context),
                                 DBUS_TYPE_INVALID))

So it's an array of bytes including a NULL byte as it seems.

+               i++;
+               dbus_message_iter_next(&array);
+       }
+
+       *context = ctx;
+
+       return 0;
+}
+

Perhaps the parsed char ** could be returned here?

What do you mean with 'parsed char **'? parse_context(ctx)?

Also, is ctx long enough to end in a NULL?

I think so. Unless I understand the above code wrongly.


+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;
+

If func is NULL, there is no point in doing the method call in the first
place?

If func is NULL why does the callee call this function at all? The programmer must be very confused then :) I'll add a test...


+       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;
+}


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


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

Reply via email to