All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vincent Sanders <vincent.sanders@collabora.co.uk>
To: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	"David S. Miller" <davem@davemloft.net>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>,
	Alban Crequy <alban.crequy@collabora.co.uk>
Subject: [PATCH net-next 13/15] netfilter: nfdbus: Add D-bus message parsing
Date: Fri, 29 Jun 2012 17:45:52 +0100	[thread overview]
Message-ID: <1340988354-26981-14-git-send-email-vincent.sanders@collabora.co.uk> (raw)
In-Reply-To: <1340988354-26981-1-git-send-email-vincent.sanders@collabora.co.uk>

From: Javier Martinez Canillas <javier.martinez@collabora.co.uk>

The netfilter D-Bus module needs to parse D-bus messages sent by
applications to decide whether a peer can receive or not a D-Bus
message. Add D-bus message parsing logic to be able to analyze.

Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Signed-off-by: Alban Crequy <alban.crequy@collabora.co.uk>
---
 net/netfilter/nfdbus/message.c |  194 ++++++++++++++++++++++++++++++++++++++++
 net/netfilter/nfdbus/message.h |   71 +++++++++++++++
 2 files changed, 265 insertions(+)
 create mode 100644 net/netfilter/nfdbus/message.c
 create mode 100644 net/netfilter/nfdbus/message.h

diff --git a/net/netfilter/nfdbus/message.c b/net/netfilter/nfdbus/message.c
new file mode 100644
index 0000000..93c409c
--- /dev/null
+++ b/net/netfilter/nfdbus/message.c
@@ -0,0 +1,194 @@
+/*
+ * message.c  Basic D-Bus message parsing
+ *
+ * Copyright (C) 2010-2012  Collabora Ltd
+ * Authors:	Alban Crequy <alban.crequy@collabora.co.uk>
+ * Copyright (C) 2002, 2003, 2004, 2005  Red Hat Inc.
+ * Copyright (C) 2002, 2003  CodeFactory AB
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <linux/slab.h>
+
+#include "message.h"
+
+int dbus_message_type_from_string(const char *type_str)
+{
+	if (strcmp(type_str, "method_call") == 0)
+		return DBUS_MESSAGE_TYPE_METHOD_CALL;
+	if (strcmp(type_str, "method_return") == 0)
+		return DBUS_MESSAGE_TYPE_METHOD_RETURN;
+	else if (strcmp(type_str, "signal") == 0)
+		return DBUS_MESSAGE_TYPE_SIGNAL;
+	else if (strcmp(type_str, "error") == 0)
+		return DBUS_MESSAGE_TYPE_ERROR;
+	else
+		return DBUS_MESSAGE_TYPE_INVALID;
+}
+
+int dbus_message_parse(unsigned char *message, size_t len,
+		       struct dbus_message *dbus_message)
+{
+	unsigned char *cur;
+	int array_header_len;
+
+	dbus_message->message = message;
+
+	if (len < 4 + 4 + 4 + 4 || message[1] == 0 || message[1] > 4)
+		return -EINVAL;
+
+	dbus_message->type = message[1];
+	dbus_message->body_length = *((u32 *)(message + 4));
+	cur = message + 12;
+	array_header_len = *(u32 *)cur;
+	dbus_message->len_offset = 12;
+	cur += 4;
+	while (cur < message + len
+	       && cur < message + 12 + 4 + array_header_len) {
+		int header_code;
+		int signature_len;
+		unsigned char *signature;
+		int str_len;
+		unsigned char *str;
+
+		/* D-Bus alignment craziness */
+		if ((cur - message) % 8 != 0)
+			cur += 8 - (cur - message) % 8;
+
+		header_code = *(char *)cur;
+		cur++;
+		signature_len = *(char *)cur;
+		/* All header fields of the current D-Bus spec have a simple
+		 * type, either o, s, g, or u */
+		if (signature_len != 1)
+			return -EINVAL;
+		cur++;
+		signature = cur;
+		cur += signature_len + 1;
+		if (signature[0] != 'o' &&
+		    signature[0] != 's' &&
+		    signature[0] != 'g' &&
+		    signature[0] != 'u')
+			return -EINVAL;
+
+		if (signature[0] == 'u') {
+			cur += 4;
+			continue;
+		}
+
+		if (signature[0] != 'g') {
+			str_len = *(u32 *)cur;
+			cur += 4;
+		} else {
+			str_len = *(char *)cur;
+			cur += 1;
+		}
+
+		str = cur;
+		switch (header_code) {
+		case 1:
+			dbus_message->path = str;
+			break;
+		case 2:
+			dbus_message->interface = str;
+			break;
+		case 3:
+			dbus_message->member = str;
+			break;
+		case 6:
+			dbus_message->destination = str;
+			break;
+		case 7:
+			dbus_message->sender = str;
+			break;
+		case 8:
+			dbus_message->body_signature = str;
+			break;
+		}
+		cur += str_len + 1;
+	}
+
+	dbus_message->padding_end = (8 - (cur - message) % 8) % 8;
+
+	/* Jump to body D-Bus alignment craziness */
+	if ((cur - message) % 8 != 0)
+		cur += 8 - (cur - message) % 8;
+	dbus_message->new_header_offset = cur - message;
+
+	if (dbus_message->new_header_offset
+	    + dbus_message->body_length != len) {
+		pr_warn("Message truncated? " \
+			"Header %d + Body %d != Length %zd\n",
+			dbus_message->new_header_offset,
+			dbus_message->body_length, len);
+		return -EINVAL;
+	}
+
+	if (dbus_message->body_signature &&
+	    dbus_message->body_signature[0] == 's') {
+		int str_len;
+		str_len = *(u32 *)cur;
+		cur += 4;
+		dbus_message->arg0 = cur;
+		cur += str_len + 1;
+	}
+
+	if ((cur - message) % 4 != 0)
+		cur += 4 - (cur - message) % 4;
+
+	if (dbus_message->body_signature &&
+	    dbus_message->body_signature[0] == 's' &&
+	    dbus_message->body_signature[1] == 's') {
+		int str_len;
+		str_len = *(u32 *)cur;
+		cur += 4;
+		dbus_message->arg1 = cur;
+		cur += str_len + 1;
+	}
+
+	if ((cur - message) % 4 != 0)
+		cur += 4 - (cur - message) % 4;
+
+	if (dbus_message->body_signature &&
+	    dbus_message->body_signature[0] == 's' &&
+	    dbus_message->body_signature[1] == 's' &&
+	    dbus_message->body_signature[2] == 's') {
+		int str_len;
+		str_len = *(u32 *)cur;
+		cur += 4;
+		dbus_message->arg2 = cur;
+		cur += str_len + 1;
+	}
+
+	if ((cur - message) % 4 != 0)
+		cur += 4 - (cur - message) % 4;
+
+	if (dbus_message->type == DBUS_MESSAGE_TYPE_SIGNAL &&
+	    dbus_message->sender && dbus_message->path &&
+	    dbus_message->interface && dbus_message->member &&
+	    dbus_message->arg0 &&
+	    strcmp(dbus_message->sender, "org.freedesktop.DBus") == 0 &&
+	    strcmp(dbus_message->interface, "org.freedesktop.DBus") == 0 &&
+	    strcmp(dbus_message->path, "/org/freedesktop/DBus") == 0) {
+		if (strcmp(dbus_message->member, "NameAcquired") == 0)
+			dbus_message->name_acquired = dbus_message->arg0;
+		else if (strcmp(dbus_message->member, "NameLost") == 0)
+			dbus_message->name_lost = dbus_message->arg0;
+	}
+
+	return 0;
+}
diff --git a/net/netfilter/nfdbus/message.h b/net/netfilter/nfdbus/message.h
new file mode 100644
index 0000000..e3ea4d3
--- /dev/null
+++ b/net/netfilter/nfdbus/message.h
@@ -0,0 +1,71 @@
+/*
+ * message.h  Basic D-Bus message parsing
+ *
+ * Copyright (C) 2010  Collabora Ltd
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DBUS_MESSAGE_H
+#define DBUS_MESSAGE_H
+
+#include <linux/list.h>
+
+#define DBUS_MAXIMUM_MATCH_RULE_LENGTH 1024
+
+/* Types of message */
+
+#define DBUS_MESSAGE_TYPE_INVALID       0
+#define DBUS_MESSAGE_TYPE_METHOD_CALL   1
+#define DBUS_MESSAGE_TYPE_METHOD_RETURN 2
+#define DBUS_MESSAGE_TYPE_ERROR         3
+#define DBUS_MESSAGE_TYPE_SIGNAL        4
+#define DBUS_NUM_MESSAGE_TYPES          5
+
+/* No need to implement a feature-complete parser. It only implement what is
+ * needed by the bus. */
+struct dbus_message {
+	char *message;
+	size_t len;
+	size_t new_len;
+
+	/* direct pointers to the fields */
+	int type;
+	char *path;
+	char *interface;
+	char *member;
+	char *destination;
+	char *sender;
+	char *body_signature;
+	int body_length;
+	char *arg0;
+	char *arg1;
+	char *arg2;
+	char *name_acquired;
+	char *name_lost;
+
+	/* How to add the 'sender' field in the headers */
+	int new_header_offset;
+	int len_offset;
+	int padding_end;
+};
+
+int dbus_message_type_from_string(const char *type_str);
+
+int dbus_message_parse(unsigned char *message, size_t len,
+		       struct dbus_message *dbus_message);
+
+#endif /* DBUS_MESSAGE_H */
-- 
1.7.10


  parent reply	other threads:[~2012-06-29 16:49 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-29 16:45 AF_BUS socket address family Vincent Sanders
2012-06-29 16:45 ` [PATCH net-next 01/15] net: bus: Add " Vincent Sanders
2012-06-29 16:45 ` [PATCH net-next 02/15] net: bus: Add documentation for AF_BUS Vincent Sanders
2012-06-29 16:45 ` [PATCH net-next 03/15] net: bus: Add AF_BUS socket and address definitions Vincent Sanders
2012-06-29 16:45 ` [PATCH net-next 04/15] security: Add Linux Security Modules hook for AF_BUS sockets Vincent Sanders
2012-07-09  3:32   ` James Morris
2012-07-09 18:02   ` Paul Moore
2012-06-29 16:45 ` [PATCH net-next 05/15] security: selinux: Add AF_BUS socket SELinux hooks Vincent Sanders
2012-07-09 18:38   ` Paul Moore
2012-06-29 16:45 ` [PATCH net-next 06/15] netfilter: Add NFPROTO_BUS hook constant for AF_BUS socket family Vincent Sanders
2012-07-01  2:15   ` Jan Engelhardt
2012-06-29 16:45 ` [PATCH net-next 07/15] scm: allow AF_BUS sockets to send ancillary data Vincent Sanders
2012-06-29 16:45 ` [PATCH net-next 08/15] net: bus: Add implementation of Bus domain sockets Vincent Sanders
2012-06-29 16:45 ` [PATCH net-next 09/15] net: bus: Add garbage collector for AF_BUS sockets Vincent Sanders
2012-07-02 17:44   ` Ben Hutchings
2012-07-03 12:11     ` Alban Crequy
2012-06-29 16:45 ` [PATCH net-next 10/15] net: bus: Add the AF_BUS socket address family to KBuild Vincent Sanders
2012-06-29 16:45 ` [PATCH net-next 11/15] netlink: connector: implement cn_netlink_reply Vincent Sanders
2012-06-29 16:45 ` [PATCH net-next 12/15] netlink: connector: Add idx and val identifiers for netfilter D-Bus Vincent Sanders
2012-06-29 16:45 ` Vincent Sanders [this message]
2012-06-29 17:11   ` [PATCH net-next 13/15] netfilter: nfdbus: Add D-bus message parsing Pablo Neira Ayuso
2012-07-02 15:43     ` Javier Martinez Canillas
2012-07-04 17:30       ` Pablo Neira Ayuso
2012-07-05 17:54         ` Javier Martinez Canillas
2012-06-29 16:45 ` [PATCH net-next 14/15] netfilter: nfdbus: Add D-bus match rule implementation Vincent Sanders
2012-06-29 16:45 ` [PATCH net-next 15/15] netfilter: add netfilter D-Bus module Vincent Sanders
2012-06-29 18:16 ` AF_BUS socket address family Chris Friesen
2012-06-29 19:33   ` Ben Hutchings
2012-06-29 18:45 ` Casey Schaufler
2012-06-29 23:22   ` Vincent Sanders
2012-06-29 22:36 ` David Miller
2012-06-29 23:12   ` Vincent Sanders
2012-06-29 23:18     ` David Miller
2012-06-29 23:42       ` Vincent Sanders
2012-06-29 23:50         ` David Miller
2012-06-30  0:09           ` Vincent Sanders
2012-06-30 13:12           ` Alan Cox
2012-07-01  0:33             ` David Miller
2012-07-01 14:16               ` Alan Cox
2012-07-01 21:45                 ` David Miller
2012-06-30  0:13         ` Benjamin LaHaise
2012-06-30 12:52           ` Alan Cox
2012-07-02 14:51             ` Vincent Sanders
2012-07-02  4:49       ` Chris Friesen
2012-07-05 21:06     ` Jan Engelhardt
2012-07-06 18:27       ` Chris Friesen
2012-06-30 20:41 ` Hans-Peter Jansen
2012-07-02 16:46   ` Alban Crequy
2012-07-05  7:59 ` Linus Walleij
2012-07-05 16:01   ` Daniel Walker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1340988354-26981-14-git-send-email-vincent.sanders@collabora.co.uk \
    --to=vincent.sanders@collabora.co.uk \
    --cc=alban.crequy@collabora.co.uk \
    --cc=davem@davemloft.net \
    --cc=javier.martinez@collabora.co.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.