diff options
author | Vsevolod Buzinov <ext-vsevolod.buzinov@nokia.com> | 2010-08-31 15:30:51 +0300 |
---|---|---|
committer | Vsevolod Buzinov <ext-vsevolod.buzinov@nokia.com> | 2010-08-31 15:30:51 +0300 |
commit | d4ab18eb979dd83d34a731fc5b22b1be60a82548 (patch) | |
tree | ad1bda4810599ac8c2f34ad0c43ea3c1a9e149af | |
parent | 2c1caabc3ffbc6a4cbf2ca0a3a144a4562031fed (diff) |
Added protection for the call application class via security token
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/dbus-proto.c | 86 | ||||
-rw-r--r-- | src/resource.c | 23 | ||||
-rw-r--r-- | src/resource.h | 10 | ||||
-rw-r--r-- | tests/Makefile.am | 6 | ||||
-rw-r--r-- | tests/security-test.c | 93 | ||||
-rw-r--r-- | tests/tests.xml | 3 |
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> |