aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVsevolod Buzinov <ext-vsevolod.buzinov@nokia.com>2010-08-31 15:30:51 +0300
committerVsevolod Buzinov <ext-vsevolod.buzinov@nokia.com>2010-08-31 15:30:51 +0300
commitd4ab18eb979dd83d34a731fc5b22b1be60a82548 (patch)
treead1bda4810599ac8c2f34ad0c43ea3c1a9e149af
parent2c1caabc3ffbc6a4cbf2ca0a3a144a4562031fed (diff)
Added protection for the call application class via security token
-rw-r--r--src/Makefile.am2
-rw-r--r--src/dbus-proto.c86
-rw-r--r--src/resource.c23
-rw-r--r--src/resource.h10
-rw-r--r--tests/Makefile.am6
-rw-r--r--tests/security-test.c93
-rw-r--r--tests/tests.xml3
7 files changed, 220 insertions, 3 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 86e6d91..1577265 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,7 @@ libresource_la_CFLAGS = @DBUS_CFLAGS@ -I$(top_srcdir) -fvisibility=hidden
if DEBUG
libresource_la_CFLAGS += -D__DEBUG__
endif
-libresource_la_LDFLAGS = /usr/lib -version-info $(subst .,:,$(VERSION))
+libresource_la_LDFLAGS = /usr/lib -version-info $(subst .,:,$(VERSION)) -lcreds
libresource_la_LIBADD = @DBUS_LIBS@
libresource_glib_la_SOURCES = resource.c resource-glib-glue.c
diff --git a/src/dbus-proto.c b/src/dbus-proto.c
index f1fd314..511b8df 100644
--- a/src/dbus-proto.c
+++ b/src/dbus-proto.c
@@ -8,6 +8,8 @@
#include "dbus-proto.h"
#include "dbus-msg.h"
+#include <sys/creds.h>
+
/*
* local function prototypes
@@ -579,6 +581,16 @@ static DBusHandlerResult manager_method(DBusConnection *dcon,
resset_t *rset;
char *method;
+ char creds_buf[200];
+ int has_creds = 1;
+ int pid;
+ creds_t creds;
+ int res;
+ const char *security_token = "Cellular";
+ const char *name;
+ resmsg_t reply;
+ int success;
+
if (!strcmp(interface, RESPROTO_DBUS_MANAGER_INTERFACE) &&
type == DBUS_MESSAGE_TYPE_METHOD_CALL &&
@@ -604,6 +616,7 @@ static DBusHandlerResult manager_method(DBusConnection *dcon,
if (resmsg.type == RESMSG_REGISTER) {
+
rset = resset_create(rcon, sender, resmsg.any.id,
RESPROTO_RSET_STATE_CONNECTED,
resmsg.record.klass,
@@ -613,16 +626,85 @@ static DBusHandlerResult manager_method(DBusConnection *dcon,
resmsg.record.rset.share,
resmsg.record.rset.mask);
+
+ printf("resmsg.record.klass: %s\n", resmsg.record.klass);
+ if (!strcmp(resmsg.record.klass, "call")) {
+
+ printf("checking credentials\n");
+
+
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+
+ message = dbus_message_new_method_call ("org.freedesktop.DBus",
+ "/org/freedesktop/DBus/Bus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID");
+ dbus_message_iter_init_append (message, &iter);
+ name = dbus_message_get_sender(dbusmsg);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name);
+ dbus_error_init (&error);
+ reply = dbus_connection_send_with_reply_and_block (dcon, message, -1, &error);
+ if (reply == NULL || dbus_error_is_set (&error)) {
+ printf("Error doing GetConnectionUnixProcessID on Bus: %s: %s\n", error.name, error.message);
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto error;
+ }
+ dbus_message_iter_init (reply, &iter);
+ dbus_message_iter_get_basic (&iter, &pid);
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+
+ printf("pid is %d\n", pid);
+
+ creds = creds_gettask(pid);
+
+ res = creds_find(creds, security_token, creds_buf, sizeof(creds_buf));
+ if (res < 0) {
+ printf("creds_find failed %d with match %s\n", res, security_token);
+ has_creds = 0;
+ } else if (res >= sizeof(creds_buf)) {
+ printf("creds_find failed -- buf too short for %.*s\n", sizeof(creds_buf), creds_buf);
+ } else {
+ printf("creds_find matched: %s\n", creds_buf);
+ }
+
+ creds_free(creds);
+ }
+
+
+
if (rset != NULL && watch_client(&rcon->dbus, sender, TRUE)) {
dbus_message_ref(dbusmsg);
- rcon->dbus.receive(&resmsg, rset, dbusmsg);
+
+ if (has_creds) {
+ rcon->dbus.receive(&resmsg, rset, dbusmsg);
+ } else {
+
+ memset(&reply, 0, sizeof(reply));
+ reply.status.type = RESMSG_STATUS;
+ reply.status.id = rset->id;
+ reply.status.reqno = resmsg.any.reqno;
+ reply.status.errcod = 401;
+ reply.status.errmsg = "Access denied";
+
+ success = rcon->dbus.error(rset, &reply, dbusmsg);
+ printf("3\n");
+ }
}
-
+
return DBUS_HANDLER_RESULT_HANDLED;
}
}
}
+error:
+
return DBUS_HANDLER_RESULT_HANDLED;
}
diff --git a/src/resource.c b/src/resource.c
index 1cfea8d..bce37f9 100644
--- a/src/resource.c
+++ b/src/resource.c
@@ -58,6 +58,11 @@ typedef struct {
void *data;
} callback_t;
+typedef struct {
+ error_callback_function_t function;
+ void *data;
+} error_callback_t;
+
struct resource_set_s {
struct resource_set_s *next;
DBusConnection *dbus; /* D-Bus connection */
@@ -73,6 +78,7 @@ struct resource_set_s {
int acquire;
callback_t grantcb;
callback_t advicecb;
+ error_callback_t errorcb;
resource_config_t *configs;
resset_t *resset;
request_t *reqlist;
@@ -179,6 +185,19 @@ EXPORT int resource_set_configure_advice_callback(resource_set_t *rs,
return TRUE;
}
+EXPORT int resource_set_configure_error_callback(resource_set_t *rs,
+ error_callback_function_t errorcb,
+ void *errordata)
+{
+ if (rs != NULL) {
+ rs->errorcb.function = errorcb;
+ rs->errorcb.data = errordata;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
EXPORT int resource_set_configure_resources(resource_set_t *rs,
uint32_t mandatory,
@@ -535,6 +554,10 @@ static void connect_complete_cb(resource_set_t *rs, uint32_t rn, void *data,
resource_log("failed to connect resource manager: %d %s",
errcod, errmsg);
rs->client = client_created;
+
+ if (rs->errorcb.function != NULL)
+ rs->errorcb.function(rs, errcod, errmsg, rs->errorcb.data);
+
}
else {
resource_log("resource set %u is ready", rs->id);
diff --git a/src/resource.h b/src/resource.h
index 3b994c1..c177023 100644
--- a/src/resource.h
+++ b/src/resource.h
@@ -17,6 +17,12 @@ typedef void (*resource_callback_t)(resource_set_t *resource_set,
uint32_t resources,
void *userdata);
+typedef void (*error_callback_function_t)(resource_set_t *resource_set,
+ uint32_t errcod,
+ const char *errmsg,
+ void *userdata);
+
+int resource_set_use_dbus(DBusConnection *conn);
resource_set_t *resource_set_create(const char *klass,
uint32_t mandatory,
@@ -31,6 +37,10 @@ int resource_set_configure_advice_callback(resource_set_t *resource_set,
resource_callback_t advicecb,
void *advicedata);
+int resource_set_configure_error_callback(resource_set_t *rs,
+ error_callback_function_t errorcb,
+ void *errordata);
+
int resource_set_configure_resources(resource_set_t *resource_set,
uint32_t mandatory,
uint32_t optional);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e7fe19d..fbf68fd 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -7,6 +7,12 @@ resource_test_LDADD = -lcheck \
@DBUS_LIBS@
memory_leak_test_SOURCES = memory-leak-test.c
+security_test_SOURCES = security-test.c
+
+security_test_CFLAGS = -I../src/ @DBUS_CFLAGS@
+security_test_LDADD = -L../src/.libs/ -lresource -lresource-glib
+
+noinst_PROGRAMS = resource_test security_test
memory_leak_test_CFLAGS = -I$(top_srcdir)/src @DBUS_CFLAGS@
memory_leak_test_LDADD = $(top_builddir)/src/libresource-glib.la \
diff --git a/tests/security-test.c b/tests/security-test.c
new file mode 100644
index 0000000..2a76325
--- /dev/null
+++ b/tests/security-test.c
@@ -0,0 +1,93 @@
+/*************************************************************************
+This file is part of libresource
+
+Copyright (C) 2010 Nokia Corporation.
+
+This library is free software; you can redistribute
+it and/or modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation
+version 2.1 of the License.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+USA.
+*************************************************************************/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+
+#include "../src/resource.h"
+
+static void grant_callback (resource_set_t *resource_set,
+ uint32_t resources,
+ void *userdata)
+{
+ char buf[512];
+
+ (void)resource_set;
+ (void)userdata;
+
+ printf("*** %s(): granted resources %s\n", __FUNCTION__,
+ resmsg_res_str (resources, buf, sizeof(buf)));
+
+ exit(0);
+}
+
+static void advice_callback (resource_set_t *resource_set,
+ uint32_t resources,
+ void *userdata)
+{
+ char buf[512];
+
+ (void)resource_set;
+ (void)userdata;
+
+ printf("*** %s(): adviced resources %s\n", __FUNCTION__,
+ resmsg_res_str (resources, buf, sizeof(buf)));
+}
+
+static void error_callback (resource_set_t *resource_set,
+ uint32_t errcod,
+ const char* errmsg,
+ void *userdata)
+{
+ (void)resource_set;
+ (void)userdata;
+
+ printf("*** %s(): error callback code: %d msg: %s\n", __FUNCTION__,
+ errcod, errmsg);
+
+ exit(1);
+}
+
+int
+main(int argc, char* argv[]) {
+
+ resource_set_t *rs;
+ GMainLoop *main_loop;
+
+ rs = resource_set_create("call", RESOURCE_AUDIO_PLAYBACK, 0, 0, grant_callback, 0);
+ resource_set_configure_advice_callback (rs, advice_callback, NULL);
+ resource_set_configure_error_callback (rs, error_callback, NULL);
+
+ resource_set_acquire(rs);
+
+
+ if ((main_loop = g_main_loop_new (NULL, FALSE)) == NULL) {
+ printf("Can't create G-MainLoop\n");
+ }
+
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
+
+
diff --git a/tests/tests.xml b/tests/tests.xml
index cbbfc8e..b994855 100644
--- a/tests/tests.xml
+++ b/tests/tests.xml
@@ -9,6 +9,9 @@
<case name="resource_set_acquire_and_release" type="Functional" level="Component" subfeature="High-level C API" description="resource_set_acquire_and_release" timeout="15"><step expected_result="0">/usr/lib/libresource-tests/resource_test 4</step></case>
<case name="resource_set_configure_audio" type="Functional" level="Component" subfeature="High-level C API" description="resource_set_configure_audio" timeout="15"><step expected_result="0">/usr/lib/libresource-tests/resource_test 5</step></case>
+ <case name="security_test_with_token" type="Functional" level="Component" subfeature="High-level C API" description="security_test_with_token" timeout="15"><step expected_result="0">/usr/lib/libresource-tests/test-security-with-aegis-token</step></case>
+ <case name="security_test_without_token" type="Functional" level="Component" subfeature="High-level C API" description="security_test_without_token" timeout="15"><step expected_result="1">/usr/lib/libresource-tests/test-security-without-aegis-token</step></case>
+
<environments>
<scratchbox>true</scratchbox>
<hardware>true</hardware>