From fd3cdd56a02bb70481d799667106b8d72171331b Mon Sep 17 00:00:00 2001 From: Brian McGillion Date: Thu, 6 Sep 2012 17:44:00 +0300 Subject: [PATCH] Query Smack context of connection Signed-off-by: Brian McGillion --- bus/Makefile.am | 4 +++ bus/connection.c | 26 +++++++++++++++ bus/connection.h | 1 + bus/driver.c | 9 +++++ bus/smack.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ bus/smack.h | 37 +++++++++++++++++++++ cmake/CMakeLists.txt | 3 ++ cmake/bus/CMakeLists.txt | 6 ++-- configure.ac | 14 ++++++-- doc/dbus-specification.xml | 8 +++++ 10 files changed, 182 insertions(+), 4 deletions(-) create mode 100644 bus/smack.c create mode 100644 bus/smack.h diff --git a/bus/Makefile.am b/bus/Makefile.am index 6cbc09a..7f63d86 100644 --- a/bus/Makefile.am +++ b/bus/Makefile.am @@ -7,6 +7,7 @@ DBUS_BUS_LIBS = \ $(THREAD_LIBS) \ $(ADT_LIBS) \ $(NETWORK_libs) \ + $(LIBSMACK_LIBS) \ $(NULL) DBUS_LAUNCHER_LIBS = \ @@ -21,6 +22,7 @@ AM_CPPFLAGS = \ -DDBUS_SYSTEM_CONFIG_FILE=\""$(configdir)/system.conf"\" \ -DDBUS_COMPILATION \ -DDBUS_STATIC_BUILD \ + $(LIBSMACK_CFLAGS) \ $(NULL) # if assertions are enabled, improve backtraces @@ -93,6 +95,8 @@ BUS_SOURCES= \ services.h \ signals.c \ signals.h \ + smack.c \ + smack.h \ stats.c \ stats.h \ test.c \ diff --git a/bus/connection.c b/bus/connection.c index d69758c..07c711a 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -30,6 +30,7 @@ #include "signals.h" #include "expirelist.h" #include "selinux.h" +#include "smack.h" #include #include #include @@ -98,6 +99,8 @@ typedef struct long connection_tv_usec; /**< Time when we connected (microsec component) */ int stamp; /**< connections->stamp last time we were traversed */ + char *smack_label; + #ifdef DBUS_ENABLE_STATS int peak_match_rules; int peak_bus_names; @@ -409,6 +412,9 @@ free_connection_data (void *data) dbus_free (d->name); + if (d->smack_label) + bus_smack_label_free (d->smack_label); + dbus_free (d); } @@ -626,6 +632,10 @@ bus_connections_setup_connection (BusConnections *connections, dbus_error_init (&error); d->selinux_id = bus_selinux_init_connection_id (connection, &error); + + if (!dbus_error_is_set (&error)) + d->smack_label = bus_smack_get_label(connection, &error); + if (dbus_error_is_set (&error)) { /* This is a bit bogus because we pretend all errors @@ -723,6 +733,10 @@ bus_connections_setup_connection (BusConnections *connections, bus_selinux_id_unref (d->selinux_id); d->selinux_id = NULL; + if (d->smack_label) + bus_smack_label_free (d->smack_label); + d->smack_label = NULL; + if (!dbus_connection_set_watch_functions (connection, NULL, NULL, NULL, connection, @@ -1107,6 +1121,18 @@ bus_connection_get_selinux_id (DBusConnection *connection) return d->selinux_id; } +const char* +bus_connection_get_smack_label (DBusConnection *connection) +{ + BusConnectionData *d; + + d = BUS_CONNECTION_DATA (connection); + + _dbus_assert (d != NULL); + + return d->smack_label; +} + /** * Checks whether the connection is registered with the message bus. * diff --git a/bus/connection.h b/bus/connection.h index c936021..1532074 100644 --- a/bus/connection.h +++ b/bus/connection.h @@ -52,6 +52,7 @@ BusActivation* bus_connection_get_activation (DBusConnection BusMatchmaker* bus_connection_get_matchmaker (DBusConnection *connection); const char * bus_connection_get_loginfo (DBusConnection *connection); BusSELinuxID* bus_connection_get_selinux_id (DBusConnection *connection); +const char * bus_connection_get_smack_label (DBusConnection *connection); dbus_bool_t bus_connections_check_limits (BusConnections *connections, DBusConnection *requesting_completion, DBusError *error); diff --git a/bus/driver.c b/bus/driver.c index 5c4e9a2..ee5ea88 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -30,6 +30,7 @@ #include "services.h" #include "selinux.h" #include "signals.h" +#include "smack.h" #include "stats.h" #include "utils.h" @@ -1536,6 +1537,7 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection, DBusMessageIter array_iter; unsigned long ulong_val; const char *service; + char *smack_ctx; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -1567,6 +1569,13 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection, goto oom; } + smack_ctx = bus_connection_get_smack_label (conn); + if (smack_ctx) + { + if (!_dbus_asv_add_string(&array_iter, "SmackContext", smack_ctx)) + goto oom; + } + if (!_dbus_asv_close (&reply_iter, &array_iter)) goto oom; diff --git a/bus/smack.c b/bus/smack.c new file mode 100644 index 0000000..f487c0c --- /dev/null +++ b/bus/smack.c @@ -0,0 +1,78 @@ +/* smack.c - Provide interface to query smack context + * + * Author: Brian McGillion + * Copyright © 2012 Intel Corporation + * + * Licensed under the Academic Free License version 2.1 + * + * 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 +#include "smack.h" + +#include + +#include "connection.h" +#include "services.h" +#include "utils.h" + +#include + +#ifdef HAVE_ERRNO_H +#include +#endif +#ifdef DBUS_ENABLE_SMACK +#include +#endif + +char * +bus_smack_get_label (DBusConnection *connection, DBusError *error) +{ +#ifdef DBUS_ENABLE_SMACK + char *label; + int sock_fd; + + if (!dbus_connection_get_socket(connection, &sock_fd)) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Failed to get the socket descriptor of the connection.\n"); + _dbus_verbose ("Failed to get socket descriptor of connection for Smack check.%s\n"); + return NULL; + } + + /* retrieve an ascii, null-terminated string that defines the Smack context of the connected socket */ + if (smack_new_label_from_socket(sock_fd, &label) < 0) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Failed to read the Smack context from the connection: %s.\n", + _dbus_strerror (errno)); + _dbus_verbose ("Failed to read the Smack context from the connection: %s.\n", + _dbus_strerror (errno)); + return NULL; + } + return label; +#else + return NULL; +#endif +} + +void +bus_smack_label_free (char *label) +{ + if (label) + free (label); +} diff --git a/bus/smack.h b/bus/smack.h new file mode 100644 index 0000000..51773b9 --- /dev/null +++ b/bus/smack.h @@ -0,0 +1,37 @@ +/* smack.h - Provide interface to query smack context + * + * Author: Brian McGillion + * Copyright © 2012 Intel Corporation + * + * Based on example from Stats interface + * + * Licensed under the Academic Free License version 2.1 + * + * 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 SMACK_H +#define SMACK_H + +#include "bus.h" + +char * +bus_smack_get_label (DBusConnection *connection, DBusError *error); + +void +bus_smack_label_free (char *label); + +#endif // SMACK_H diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 52a48fd..ea5c3d0 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -94,6 +94,8 @@ option (DBUS_ENABLE_STATS "enable bus daemon usage statistics" OFF) option (DBUS_ENABLE_STATS "enable bus daemon usage statistics" OFF) +option (DBUS_ENABLE_SMACK "enable smack checks in the daemon" OFF) + if (DBUS_USE_EXPAT) find_package(LibExpat) else () @@ -564,6 +566,7 @@ message(" Building bus stats API: ${DBUS_ENABLE_STATS} " message(" installing system libs: ${DBUS_INSTALL_SYSTEM_LIBS} ") #message(" Building SELinux support: ${have_selinux} ") #message(" Building dnotify support: ${have_dnotify} ") +message(" Building Smack support: ${DBUS_ENABLE_SMACK} ") message(" Building Doxygen docs: ${DBUS_ENABLE_DOXYGEN_DOCS} ") message(" Building XML docs: ${DBUS_ENABLE_XML_DOCS} ") #message(" Gettext libs (empty OK): ${INTLLIBS} ") diff --git a/cmake/bus/CMakeLists.txt b/cmake/bus/CMakeLists.txt index faf9a8e..c16c309 100644 --- a/cmake/bus/CMakeLists.txt +++ b/cmake/bus/CMakeLists.txt @@ -65,11 +65,13 @@ set (BUS_SOURCES ${BUS_DIR}/services.c ${BUS_DIR}/services.h ${BUS_DIR}/signals.c - ${BUS_DIR}/signals.h + ${BUS_DIR}/signals.h + ${BUS_DIR}/smack.c + ${BUS_DIR}/smack.h ${BUS_DIR}/test.c ${BUS_DIR}/test.h ${BUS_DIR}/utils.c - ${BUS_DIR}/utils.h + ${BUS_DIR}/utils.h ${XML_SOURCES} ${DIR_WATCH_SOURCE} ) diff --git a/configure.ac b/configure.ac index e2c9bdf..7e308c5 100644 --- a/configure.ac +++ b/configure.ac @@ -206,6 +206,9 @@ if test "x$enable_embedded_tests" = xyes; then [Define to build test code into the library and binaries]) fi +# call early to ensure availability +PKG_PROG_PKG_CONFIG + # DBUS_ENABLE_MODULAR_TESTS controls tests that work based on public API. # These use GTest, from GLib, because life's too short. They're enabled by # default (unless you don't have GLib), because they don't bloat the library @@ -901,8 +904,6 @@ fi # unix:path=/foo or unix:abstract=/foo AC_SUBST(DBUS_PATH_OR_ABSTRACT) -PKG_PROG_PKG_CONFIG - #### Sort out XML library # see what we have @@ -1756,6 +1757,14 @@ if test "x$enable_stats" = xyes; then [Define to enable bus daemon usage statistics]) fi +#enable smack label support +AC_ARG_ENABLE([smack], [AS_HELP_STRING([--enable-smack], [enable Smack security checks])], [], [enable_smack=no]) +if test "x$enable_smack" = xyes; then + PKG_CHECK_MODULES([LIBSMACK], [libsmack >= 1.0], + [AC_DEFINE([DBUS_ENABLE_SMACK], [1], [Define to enable Smack security features])], + [AC_MSG_ERROR([libsmack is required to enable smack support])]) +fi + AC_CONFIG_FILES([ Doxyfile dbus/versioninfo.rc @@ -1834,6 +1843,7 @@ echo " Building checks: ${enable_checks} Building bus stats API: ${enable_stats} Building SELinux support: ${have_selinux} + Building Smack support: ${enable_smack} Building inotify support: ${have_inotify} Building dnotify support: ${have_dnotify} Building kqueue support: ${have_kqueue} diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml index e59a5e5..108bd5a 100644 --- a/doc/dbus-specification.xml +++ b/doc/dbus-specification.xml @@ -5645,6 +5645,14 @@ UINT32 The numeric Unix process ID, as defined by POSIX + + SmackContext + STRING + This is a ascii string that defines the Smack context + of the process that owns the connection. Smack is a Manditory + Access Control framework, that is part of the Linux kernel. + + -- 1.7.10.4