From 6944d137c08620a08b142a7c3dbb40d25fb64552 Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Wed, 16 Dec 2015 18:35:09 -0600 Subject: [PATCH] binutils: Add aa-enabled program to check AppArmor status The new aa-enabled program can be used as a barebones replacement for `aa-status --enabled`. It is written in C, rather than Python, which keeps its dependencies to a minimum. By default, aa-enabled prints a human-readable status of AppArmor's availability to stdout. It supports a --quiet option which allows for functionality equivalent to `aa-status --enabled`, which does not print any messages. The aa-enabled exit statuses mimic the behavior documented in the aa-status(8) man page. Signed-off-by: John Johansen [tyhicks: Incorporated feedback from the code review process] Signed-off-by: Tyler Hicks --- Makefile | 1 + README | 10 +- binutils/Makefile | 197 +++++++++++++++++++++++++++++++++++++ binutils/aa-enabled.pod | 93 +++++++++++++++++ binutils/aa_enabled.c | 92 +++++++++++++++++ binutils/po/Makefile | 19 ++++ binutils/po/aa-enabled.pot | 66 +++++++++++++ common/Make-po.rules | 4 +- 8 files changed, 479 insertions(+), 3 deletions(-) create mode 100644 binutils/Makefile create mode 100644 binutils/aa-enabled.pod create mode 100644 binutils/aa_enabled.c create mode 100644 binutils/po/Makefile create mode 100644 binutils/po/aa-enabled.pot diff --git a/Makefile b/Makefile index 134db43b3..f7907cd9e 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ include ${COMMONDIR}/Make.rules DIRS=parser \ profiles \ utils \ + binutils \ libraries/libapparmor \ changehat/mod_apparmor \ changehat/pam_apparmor \ diff --git a/README b/README index 4ebd25d9b..279f5966f 100644 --- a/README +++ b/README @@ -27,6 +27,7 @@ Source Layout AppArmor consists of several different parts: +binutils/ source for basic utilities written in compiled languages changehat/ source for using changehat with Apache, PAM and Tomcat common/ common makefile rules desktop/ empty @@ -71,6 +72,13 @@ $ make install generate Ruby bindings to libapparmor.] +Binary Utilities: +$ cd binutils +$ make +$ make check +$ make install + + Utilities: $ cd utils $ make @@ -104,7 +112,7 @@ $ make check # depends on the parser having been built first $ make install -[Note that for the parser and the utils, if you only with to build/use +[Note that for the parser, binutils, and utils, if you only wish to build/use some of the locale languages, you can override the default by passing the LANGS arguments to make; e.g. make all install "LANGS=en_US fr".] diff --git a/binutils/Makefile b/binutils/Makefile new file mode 100644 index 000000000..614686c37 --- /dev/null +++ b/binutils/Makefile @@ -0,0 +1,197 @@ +# ---------------------------------------------------------------------- +# Copyright (c) 2015 +# Canonical Ltd. (All rights reserved) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License published by the Free Software Foundation. +# +# 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. +# ---------------------------------------------------------------------- +NAME=aa-binutils +all: +COMMONDIR=../common/ + +include $(COMMONDIR)/Make.rules + +DESTDIR=/ +LOCALEDIR=/usr/share/locale +MANPAGES=aa-enabled.8 + +WARNINGS = -Wall +EXTRA_WARNINGS = -Wsign-compare -Wmissing-field-initializers -Wformat-security -Wunused-parameter +CPP_WARNINGS = +ifndef CFLAGS +CFLAGS = -g -O2 -pipe + +ifdef DEBUG +CFLAGS += -pg -D DEBUG +endif +ifdef COVERAGE +CFLAGS = -g -pg -fprofile-arcs -ftest-coverage +endif +endif #CFLAGS + +EXTRA_CFLAGS = ${EXTRA_CXXFLAGS} ${CPP_WARNINGS} + +#INCLUDEDIR = /usr/src/linux/include +INCLUDEDIR = + +ifdef INCLUDEDIR + CFLAGS += -I$(INCLUDEDIR) +endif + +# Internationalization support. Define a package and a LOCALEDIR +EXTRA_CFLAGS+=-DPACKAGE=\"${NAME}\" -DLOCALEDIR=\"${LOCALEDIR}\" + +SRCS = aa_enabled.c +HDRS = +TOOLS = aa-enabled + +AALIB = -Wl,-Bstatic -lapparmor -Wl,-Bdynamic -lpthread + +ifdef USE_SYSTEM + # Using the system libapparmor so Makefile dependencies can't be used + LIBAPPARMOR_A = + INCLUDE_APPARMOR = + APPARMOR_H = + LIBAPPARMOR_LDFLAGS = +else + LIBAPPARMOR_SRC = ../libraries/libapparmor/ + LOCAL_LIBAPPARMOR_INCLUDE = $(LIBAPPARMOR_SRC)/include + LOCAL_LIBAPPARMOR_LDPATH = $(LIBAPPARMOR_SRC)/src/.libs + + LIBAPPARMOR_A = $(LOCAL_LIBAPPARMOR_LDPATH)/libapparmor.a + INCLUDE_APPARMOR = -I$(LOCAL_LIBAPPARMOR_INCLUDE) + APPARMOR_H = $(LOCAL_LIBAPPARMOR_INCLUDE)/sys/apparmor.h + LIBAPPARMOR_LDFLAGS = -L$(LOCAL_LIBAPPARMOR_LDPATH) +endif +EXTRA_CFLAGS += $(INCLUDE_APPARMOR) +LDFLAGS += $(LIBAPPARMOR_LDFLAGS) + +ifdef V + VERBOSE = 1 +endif +ifndef VERBOSE + VERBOSE = 0 +endif +ifeq ($(VERBOSE),1) + BUILD_OUTPUT = + Q = +else + BUILD_OUTPUT = > /dev/null 2>&1 + Q = @ +endif +export Q VERBOSE BUILD_OUTPUT + +po/%.pot: %.c + $(MAKE) -C po $(@F) NAME=$* SOURCES=$*.c + +# targets arranged this way so that people who don't want full docs can +# pick specific targets they want. +arch: $(TOOLS) + +manpages: $(MANPAGES) + +docs: manpages + +indep: docs + $(Q)$(MAKE) -C po all + +all: arch indep + +.PHONY: coverage +coverage: + $(MAKE) clean aa-enabled COVERAGE=1 + +ifndef USE_SYSTEM +$(LIBAPPARMOR_A): + @if [ ! -f $@ ]; then \ + echo "error: $@ is missing. Pick one of these possible solutions:" 1>&2; \ + echo " 1) Build against the in-tree libapparmor by building it first and then trying again. See the top-level README for help." 1>&2; \ + echo " 2) Build against the system libapparmor by adding USE_SYSTEM=1 to your make command." 1>&2;\ + return 1; \ + fi +endif + +aa-enabled: aa_enabled.c $(LIBAPPARMOR_A) + $(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB) + +.SILENT: check +.PHONY: check +check: check_pod_files tests + +.SILENT: tests +tests: aa-enabled $(TESTS) + echo "no tests atm" + +.PHONY: install-rhel4 +install-rhel4: install-redhat + +.PHONY: install-redhat +install-redhat: + +.PHONY: install-suse +install-suse: + +.PHONY: install-slackware +install-slackware: + +.PHONY: install-debian +install-debian: + +.PHONY: install-unknown +install-unknown: + +INSTALLDEPS=arch + +ifndef DISTRO +DISTRO=$(shell if [ -f /etc/slackware-version ] ; then \ + echo slackware ; \ + elif [ -f /etc/debian_version ] ; then \ + echo debian ;\ + elif which rpm > /dev/null ; then \ + if [ "$(rpm --eval '0%{?suse_version}')" != "0" ] ; then \ + echo suse ;\ + elif [ "$(rpm --eval '%{_host_vendor}')" = redhat ] ; then \ + echo rhel4 ;\ + elif [ "$(rpm --eval '0%{?fedora}')" != "0" ] ; then \ + echo rhel4 ;\ + else \ + echo unknown ;\ + fi ;\ + else \ + echo unknown ;\ + fi) +endif + +ifdef DISTRO +INSTALLDEPS+=install-$(DISTRO) +endif + +.PHONY: install +install: install-indep install-arch + +.PHONY: install-arch +install-arch: $(INSTALLDEPS) + install -m 755 -d $(DESTDIR)/sbin + install -m 755 ${TOOLS} $(DESTDIR)/sbin + +.PHONY: install-indep +install-indep: + $(MAKE) -C po install NAME=${NAME} DESTDIR=${DESTDIR} + $(MAKE) install_manpages DESTDIR=${DESTDIR} + +ifndef VERBOSE +.SILENT: clean +endif +.PHONY: clean +clean: pod_clean + rm -f core core.* *.o *.s *.a *~ *.gcda *.gcno + rm -f gmon.out + rm -f $(TOOLS) $(TESTS) + $(MAKE) -s -C po clean + diff --git a/binutils/aa-enabled.pod b/binutils/aa-enabled.pod new file mode 100644 index 000000000..050eb72fa --- /dev/null +++ b/binutils/aa-enabled.pod @@ -0,0 +1,93 @@ +# This publication is intellectual property of Canonical Ltd. Its contents +# can be duplicated, either in part or in whole, provided that a copyright +# label is visibly located on each copy. +# +# All information found in this book has been compiled with utmost +# attention to detail. However, this does not guarantee complete accuracy. +# Neither Canonical Ltd, the authors, nor the translators shall be held +# liable for possible errors or the consequences thereof. +# +# Many of the software and hardware descriptions cited in this book +# are registered trademarks. All trade names are subject to copyright +# restrictions and may be registered trade marks. Canonical Ltd +# essentially adheres to the manufacturer's spelling. +# +# Names of products and trademarks appearing in this book (with or without +# specific notation) are likewise subject to trademark and trade protection +# laws and may thus fall under copyright restrictions. +# + + +=pod + +=head1 NAME + +aa-enabled - test whether AppArmor is enabled + +=head1 SYNOPSIS + +B [options] + +=head1 DESCRIPTION + +B is used to determine if AppArmor is enabled. + +=head1 OPTIONS +B accepts the following arguments: + +=over 4 + +=item -h, --help + +Display a brief usage guide. + +=item -q, --quiet + +Do not output anything to stdout. This option is intended to be used by +scripts that simply want to use the exit code to determine if AppArmor is +enabled. + +=back + +=head1 EXIT STATUS + +Upon exiting, B will set its exit status to the following values: + +=over 4 + +=item 0: + +if AppArmor is enabled. + +=item 1: + +if AppArmor is not enabled/loaded. + +=item 2: + +intentionally not used as an B exit status. + +=item 3: + +if the AppArmor control files aren't available under /sys/kernel/security/. + +=item 4: + +if B doesn't have enough privileges to read the apparmor control files. + +=item 64: + +if any unexpected error or condition is encountered. + +=back + +=head1 BUGS + +If you find any bugs, please report them at +L. + +=head1 SEE ALSO + +apparmor(7), apparmor.d(5), aa_is_enabled(2), and L. + +=cut diff --git a/binutils/aa_enabled.c b/binutils/aa_enabled.c new file mode 100644 index 000000000..3ca84b0c2 --- /dev/null +++ b/binutils/aa_enabled.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2015 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#define _(s) gettext(s) + +#include + +void print_help(const char *command) +{ + printf(_("%s: [options]\n" + " options:\n" + " -q | --quiet Don't print out any messages\n" + " -h | --help Print help\n"), + command); + exit(1); +} + + +/* Exit statuses and meanings are documented in the aa-enabled.pod file */ +static void exit_with_error(int saved_errno, int quiet) +{ + int err; + + switch(saved_errno) { + case ENOSYS: + if (!quiet) + printf(_("No - not available on this system.\n")); + exit(1); + case ECANCELED: + if (!quiet) + printf(_("No - disabled at boot.\n")); + exit(1); + case ENOENT: + if (!quiet) + printf(_("Maybe - policy interface not available.\n")); + exit(3); + case EPERM: + case EACCES: + if (!quiet) + printf(_("Maybe - insufficient permissions to determine availability.\n")); + exit(4); + } + + if (!quiet) + printf(_("Error - %s\n"), strerror(saved_errno)); + exit(64); +} + +int main(int argc, char **argv) +{ + int enabled; + int quiet = 0; + + setlocale(LC_MESSAGES, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (argc > 2) { + printf(_("unknown or incompatible options\n")); + print_help(argv[0]); + } else if (argc == 2) { + if (strcmp(argv[1], "--quiet") == 0 || + strcmp(argv[1], "-q") == 0) { + quiet = 1; + } else if (strcmp(argv[1], "--help") == 0 || + strcmp(argv[1], "-h") == 0) { + print_help(argv[0]); + } else { + printf(_("unknown option '%s'\n"), argv[1]); + print_help(argv[0]); + } + } + + enabled = aa_is_enabled(); + if (!enabled) + exit_with_error(errno, quiet); + + if (!quiet) + printf(_("Yes\n")); + exit(0); +} diff --git a/binutils/po/Makefile b/binutils/po/Makefile new file mode 100644 index 000000000..8216ec53d --- /dev/null +++ b/binutils/po/Makefile @@ -0,0 +1,19 @@ +# ---------------------------------------------------------------------- +# Copyright (C) 2015 Canonical Ltd. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License published by the Free Software Foundation. +# ---------------------------------------------------------------------- +all: + +# As translations get added, they will automatically be included, unless +# the lang is explicitly added to DISABLED_LANGS; e.g. DISABLED_LANGS=en es + +DISABLED_LANGS= + +COMMONDIR=../../common +include $(COMMONDIR)/Make-po.rules + +XGETTEXT_ARGS+=--language=C --keyword=_ $(shell if [ -f ${NAME}.pot ] ; then echo -n -j ; fi) + diff --git a/binutils/po/aa-enabled.pot b/binutils/po/aa-enabled.pot new file mode 100644 index 000000000..bb2b69e78 --- /dev/null +++ b/binutils/po/aa-enabled.pot @@ -0,0 +1,66 @@ +# Copyright (C) 2015 Canonical Ltd +# This file is distributed under the same license as the AppArmor package. +# John Johansen , 2015. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" +"POT-Creation-Date: 2015-11-28 10:23-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../aa_enabled.c:26 +#, c-format +msgid "" +"%s: [options]\n" +" options:\n" +" -q | --quiet Don't print out any messages\n" +" -h | --help Print help\n" +msgstr "" + +#: ../aa_enabled.c:45 +#, c-format +msgid "unknown or incompatible options\n" +msgstr "" + +#: ../aa_enabled.c:55 +#, c-format +msgid "unknown option '%s'\n" +msgstr "" + +#: ../aa_enabled.c:64 +#, c-format +msgid "Yes\n" +msgstr "" + +#: ../aa_enabled.c:71 +#, c-format +msgid "No - not available on this system.\n" +msgstr "" + +#: ../aa_enabled.c:74 +#, c-format +msgid "No - disabled at boot.\n" +msgstr "" + +#: ../aa_enabled.c:77 +#, c-format +msgid "Maybe - policy interface not available.\n" +msgstr "" + +#: ../aa_enabled.c:81 +#, c-format +msgid "Maybe - insufficient permissions to determine availability.\n" +msgstr "" + +#: ../aa_enabled.c:84 +#, c-format +msgid "Error - '%s'\n" +msgstr "" diff --git a/common/Make-po.rules b/common/Make-po.rules index 4bfdb4f42..6fa852bfc 100644 --- a/common/Make-po.rules +++ b/common/Make-po.rules @@ -1,7 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (c) 1999-2008 NOVELL (All rights reserved) -# Copyright 2009-2010 Canonical Ltd. +# Copyright 2009-2015 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -21,7 +21,7 @@ # exist LOCALEDIR=/usr/share/locale -XGETTEXT_ARGS=--copyright-holder="NOVELL, Inc." --msgid-bugs-address=apparmor@lists.ubuntu.com -d ${NAME} +XGETTEXT_ARGS=--copyright-holder="Canonical Ltd" --msgid-bugs-address=apparmor@lists.ubuntu.com -d ${NAME} # When making the .pot file, it's expected that the parent Makefile will # pass in the list of sources in the SOURCES variable