summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Hua <william.hua@canonical.com>2017-02-16 10:27:22 -0500
committerWilliam Hua <william.hua@canonical.com>2017-02-17 09:45:14 -0500
commit9f1b5bdb8b23b2cbf7d1a8700296e3f7ba0a9647 (patch)
tree96ab62af31bce877d8f7c0d5483995b08e66aab8
parentdd29098c739544917b28a12f71507233f983826d (diff)
downloaddconf-wip/apparmor.tar.gz
add apparmor confinement checkwip/apparmor
-rw-r--r--configure.ac4
-rw-r--r--proxy/Makefile.am7
-rw-r--r--proxy/confinement-apparmor.c90
-rw-r--r--proxy/confinement.c4
-rw-r--r--proxy/confinement.h5
5 files changed, 108 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 8fbff08..f908a9a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,6 +47,10 @@ GTK_DOC_CHECK([1.15])
# Dependencies
PKG_CHECK_MODULES(glib, glib-2.0 >= 2.44.0)
PKG_CHECK_MODULES(gio, gio-unix-2.0)
+PKG_CHECK_MODULES(apparmor, libapparmor, enable_apparmor=yes, enable_apparmor=no)
+AM_CONDITIONAL(ENABLE_APPARMOR, test "$enable_apparmor" = "yes")
+AC_SUBST(apparmor_CFLAGS)
+AC_SUBST(apparmor_LIBS)
AC_ARG_WITH(gio_modules_dir, [ --with-gio-modules-dir=PATH choose directory for the GIO module, [default=LIBDIR/gio/modules]], giomodulesdir="$withval", giomodulesdir=${libdir}/gio/modules)
AC_SUBST(giomodulesdir)
diff --git a/proxy/Makefile.am b/proxy/Makefile.am
index 7faa269..ad3e30a 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -14,12 +14,19 @@ dconf_proxy_LDADD = \
dconf_proxy_SOURCES = \
../gvdb/gvdb-builder.c \
confinement.c \
+ confinement-apparmor.c \
confinement-flatpak.c \
confinement.h \
permissions.c \
permissions.h \
proxy.c
+if ENABLE_APPARMOR
+dconf_proxy_CPPFLAGS = -DHAVE_APPARMOR
+dconf_proxy_CFLAGS += $(apparmor_CFLAGS)
+dconf_proxy_LDADD += $(apparmor_LIBS)
+endif
+
DISTCLEANFILES = ca.desrt.dconf.service
ca.desrt.dconf.Proxy.service: Makefile
diff --git a/proxy/confinement-apparmor.c b/proxy/confinement-apparmor.c
new file mode 100644
index 0000000..92eca60
--- /dev/null
+++ b/proxy/confinement-apparmor.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2017 Canonical Limited
+ *
+ * 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; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: William Hua <william.hua@canonical.com>
+ */
+
+#define _GNU_SOURCE
+
+#include "confinement.h"
+
+#ifdef HAVE_APPARMOR
+#include <sys/apparmor.h>
+#endif /* HAVE_APPARMOR */
+
+gboolean
+confinement_check_apparmor (GVariant *credentials,
+ gboolean *out_is_confined,
+ Permissions *out_permissions)
+{
+#ifdef HAVE_APPARMOR
+ g_autofree gchar *context = NULL;
+ const gchar *label;
+ aa_dconf_info info;
+ gchar **readable;
+ gchar **writable;
+ gint i;
+
+ if (!g_variant_lookup (credentials, "LinuxSecurityLabel", "^ay", &context))
+ {
+ g_warning ("Caller credentials are missing LinuxSecurityLabel field");
+ return FALSE;
+ }
+
+ label = aa_splitcon (context, NULL);
+
+ if (!g_strcmp0 (label, "unconfined"))
+ {
+ *out_is_confined = FALSE;
+ return TRUE;
+ }
+
+ if (aa_query_dconf_info (label, &info))
+ {
+ g_warning ("Kernel has no dconf data for %s", label);
+ return FALSE;
+ }
+
+ /* Merge the readable path lists */
+ readable = g_new (gchar *, info.r_n + info.ar_n + 1);
+ for (i = 0; i < info.r_n; i++)
+ readable[i] = g_strdup (info.r_paths[i]);
+ for (i = 0; i < info.ar_n; i++)
+ readable[info.r_n + i] = g_strdup (info.ar_paths[i]);
+ readable[info.r_n + info.ar_n] = NULL;
+
+ /* Merge the writable path lists */
+ writable = g_new (gchar *, info.rw_n + info.arw_n + 1);
+ for (i = 0; i < info.rw_n; i++)
+ writable[i] = g_strdup (info.rw_paths[i]);
+ for (i = 0; i < info.arw_n; i++)
+ writable[info.rw_n + i] = g_strdup (info.arw_paths[i]);
+ writable[info.rw_n + info.arw_n] = NULL;
+
+ aa_clear_dconf_info (&info);
+
+ permission_list_init (&out_permissions->readable, readable);
+ permission_list_init (&out_permissions->writable, writable);
+ out_permissions->ipc_dir = g_build_filename (g_get_user_runtime_dir (), label, NULL);
+ out_permissions->app_id = g_strdup (label);
+
+ *out_is_confined = TRUE;
+#else
+ *out_is_confined = FALSE;
+#endif /* HAVE_APPARMOR */
+
+ return TRUE;
+}
diff --git a/proxy/confinement.c b/proxy/confinement.c
index 2f1e295..21d5f32 100644
--- a/proxy/confinement.c
+++ b/proxy/confinement.c
@@ -30,8 +30,8 @@ confinement_check (GVariant *credentials,
if (!confinement_check_flatpak (credentials, &is_confined, &permissions))
return FALSE;
- if (!is_confined)
- /* snap goes here */;
+ if (!is_confined && !confinement_check_apparmor (credentials, &is_confined, &permissions))
+ return FALSE;
*out_is_confined = is_confined;
diff --git a/proxy/confinement.h b/proxy/confinement.h
index 9b6b625..04034a2 100644
--- a/proxy/confinement.h
+++ b/proxy/confinement.h
@@ -30,3 +30,8 @@ gboolean
confinement_check_flatpak (GVariant *credentials,
gboolean *out_is_confined,
Permissions *out_permissions);
+
+gboolean
+confinement_check_apparmor (GVariant *credentials,
+ gboolean *out_is_confined,
+ Permissions *out_permissions);