2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-31 14:25:52 +00:00

Compare commits

..

34 Commits

Author SHA1 Message Date
John Johansen
022a988e4e 2.7.1 Release 2012-01-30 07:30:25 -08:00
Christian Boltz
95f9b1d07c Update abstractios for KDE4
(At least) openSUSE uses ~/.kde4 to store KDE4 settings.
This patch changes ~/.kde/ to ~/.kde{,4} in all abstractions.

The patch is mostly from Velery Valery, I only fixed a merge conflict 
and added the kmail{,2} part in private-files-strict.

References: https://bugzilla.novell.com/show_bug.cgi?id=741592

Acked-By: Steve Beattie <sbeattie@ubuntu.com> for both trunk and 2.7.
2012-01-19 15:21:56 +01:00
Jamie Strandboge
4258749515 update p11-kit to allow mmap of libraries in pkcs directories
Acked-by: Jamie Strandboge <jamie@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-01-18 16:23:12 -06:00
Steve Beattie
62b2a00331 Merge from trunk rev 1930: A bug in Ubuntu reported that the aspell
abstraction does not allow write access to the user customizable
dictionaries, the personal dictionary (~/.aspell.$LANG.pws) and the
personal replacement dictionary (~/.aspell.$LANG.prepl). It also
adjusts the abstraction to add the owner modifier to the personal
dictionaries.

Bug: https://bugs.launchpad.net/bugs/917859

Signed-off-by: Steve Beattie <sbeattie@ubuntu.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2012-01-18 11:06:21 -08:00
Steve Beattie
463415347d Merge from trunk rev 1908: utils/Immunix/AppArmor.pm: fixes the profile
autogeneration code to include read access to the script itself for
interpreted scripts.

Nominated-By: Steve Beattie <sbeattie@ubuntu.com>
Acked-by: Christian Boltz <apparmor@cboltz.de> for the 2.7 branch
2012-01-12 10:39:48 +01:00
Steve Beattie
a52313485f Merge from trunk rev 1907: utils/Immunix/AppArmor.pm: update the
initial profile generation for python and ruby scripts to include
the respective abstractions.

Nominated-By: Steve Beattie <sbeattie@ubuntu.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
2012-01-12 10:38:41 +01:00
Christian Boltz
67b440a019 when using smbldap-useradd using this smb.conf entry
add machine script = /usr/sbin/smbldap-useradd -t 5 -w "%u"
smbd obviously needs x permissions for smbldap-useradd.

The commit also adds a new profile for usr.sbin.smbldap-useradd (based on 
the audit.log from Alexis Pellicier).

Additionally, I moved the "/etc/samba/* rwk" rule next to the other 
/etc-related rules in the smbd profile.

References: https://bugzilla.novell.com/show_bug.cgi?id=738041

Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-01-10 19:08:48 +01:00
Steve Beattie
da1bb2f219 Trunk revision 1910: Fix from Felix Geyer: block write access to
~/.kde/env because KDE automatically sources scripts in that folder
on startup.

Bug: https://bugs.launchpad.net/bugs/914190

Nominated-By: Steve Beattie <sbeattie@ubuntu.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2012-01-10 12:59:54 +01:00
Steve Beattie
0badfb7816 Trunk revision 1909: Fix from Felix Geyer: in the enchant abstraction,
allow the creation of enchant .config directory.

Bug: https://bugs.launchpad.net/bugs/914184

Nominated-By: Steve Beattie <sbeattie@ubuntu.com>
Acked-By: John Johansen <john.johansen@canonical.com>
2012-01-10 12:58:33 +01:00
Christian Boltz
87bf30b6d0 read-only TFTP access for dnsmasq
This is a backport of r1870 to the 2.7 branch.

Acked-By: Steve Beattie <sbeattie@ubuntu.com> for 2.7


Original commit message for trunk r1870:
  Merge from Simon Deziel for TFTP read-only access for dnsmasq. Fixes
  LP: #905412

  Acked-by: Jamie Strandboge <jamie@canonical.com>
2012-01-09 21:08:19 +01:00
Christian Boltz
51369a0c3e according to Peter Czanik, the openSUSE syslog-ng maintainer, syslog-ng
needs capability dac_read_search.

References: https://bugzilla.novell.com/show_bug.cgi?id=731876

ACKed-by: Steve Beattie <steve@nxnw.org>
2012-01-09 13:29:43 +01:00
Jamie Strandboge
6ae5a71ea2 merge from trunk:
add p11-kit abstraction (LP: #912754, LP: #912752)
  
  From the README in the toplevel source:
  "[P11-KIT] Provides a way to load and enumerate PKCS#11 modules. Provides a
  standard configuration setup for installing PKCS#11 modules in such a way that
  they're discoverable."
  
  File locatations are described in [1]. There is a global configuration file in
  /etc/pkcs11/pkcs11.conf. Per module configuration happens in
  /etc/pkcs11/<module name>. There is also user configuration in ~/.pkcs11, but
  IMO this should not be allowed in the abstraction. Example configuration can b
e
  seen in the upstream documentation[2].
  
  This will likely need to be refined as more applications use p11-kit.
  
  [1]http://p11-glue.freedesktop.org/doc/p11-kit/config-locations.html
  [2]http://p11-glue.freedesktop.org/doc/p11-kit/config-example.html
  
  Acked-by: Jamie Strandboge <jamie@canonical.com>
  Acked-By: Steve Beattie <sbeattie@ubuntu.com>
  
  
  Also add p11-kit to authentication abstraction
  
  Acked-by: Jamie Strandboge <jamie@canonical.com>
  Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-01-09 10:51:06 +01:00
Jamie Strandboge
850a565dce merge from trunk:
add audacity to the ubuntu-media-players abstraction (LP: #899963)
2012-01-09 10:49:07 +01:00
Jamie Strandboge
a0cf904972 merge from trunk:
allow software-center in the ubuntu-integration abstraction for
  apt: URLs (LP: #662906)
2012-01-09 10:48:36 +01:00
Jamie Strandboge
8760451216 merge from trunk:
allow fireclam plugin to work in Ubuntu multimedia abstraction
  (LP: #562831)
2012-01-09 10:48:11 +01:00
Jamie Strandboge
d096f8f7a5 merge trunk:
Author: James Troup
  Description: fix typo when adding multiarch lines for gconv
  Bug-Ubuntu: https://launchpad.net/bugs/904548
  
  Acked-by: Jamie Strandboge <jamie@canonical.com>
2012-01-09 10:47:42 +01:00
Jamie Strandboge
beb695f7b0 merge from trunk:
Author: Felix Geyer
  Description: allow avahi to do dbus introspection
  Bug-Ubuntu: https://launchpad.net/bugs/769148
  
  Acked-by: Jamie Strandboge <jamie@canonical.com>
2012-01-09 10:47:12 +01:00
Jamie Strandboge
ac80b7ca03 merge from trunk:
Author: Felix Geyer
  Description: abstractions/fonts should allow access to ~/.fonts.conf.d
  Bug-Ubuntu: https://launchpad.net/bugs/870992
  
  Acked-by: Jamie Strandboge <jamie@canonical.com>
2012-01-09 10:46:27 +01:00
Jamie Strandboge
a729e8fd75 merge from trunk:
Nvidia users need access to /dev/nvidia* files for various plugins
  to work right. Since these are all focused around multimedia, add the
  accesses to ubuntu-browsers.d/multimedia
2012-01-09 10:45:40 +01:00
Jamie Strandboge
f4c661e070 merge from trunk:
allow access to Thunar as well as thunar in ubuntu-integration abstraction
  (LP: #890894)
2012-01-09 10:44:45 +01:00
Jamie Strandboge
15e636a329 merge from trunk:
allow ixr access to exo-open in Ubuntu integration abstraction
  (LP: #890894)
2012-01-09 10:44:11 +01:00
Jamie Strandboge
49b9a83d9e Merge from trunk:
update binaries for for transmission in ubuntu-bittorrent-clients
  (LP: #852062)
2012-01-09 10:43:34 +01:00
Jamie Strandboge
069d98d007 merge from trunk:
add kate to Ubuntu text editors browser abstraction
  fix for LP: #884748
2012-01-09 10:42:54 +01:00
Jamie Strandboge
8c82eec301 Cherrypick from trunk:
Description: allow read of @{HOME}/.cups/client.conf and
   @{HOME}/.cups/lpoptions
  Bug-Ubuntu: https://launchpad.net/bugs/887992

  Added owner match per Steve Beattie and lpoptions per Steve and Christian Bolt
z
2012-01-06 10:53:14 -06:00
Jamie Strandboge
455d8a5140 Cherrypick from trunk:
Description: allow read access of /etc/python{2,3}.[0-7]*/sitecustomize.py
   in python abstraction. This script is used by apport aware python application
s
  Bug-Ubuntu: https://launchpad.net/bugs/860856

  Acked-by: Jamie Strandboge <jamie@canonical.com>
  Acked-by: Kees Cook <kees@ubuntu.com>
2012-01-06 10:52:34 -06:00
Jamie Strandboge
efd20f879c Cherrypick from trunk:
Description: update dovecot deliver profile to access various .conf files for
   dovecot
  Bug-Ubuntu: https://launchpad.net/bugs/458922

  Acked-by: Jamie Strandboge <jamie@canonical.com>
  Acked-by: Kees Cook <kees@ubuntu.com>
2012-01-06 10:51:58 -06:00
Jamie Strandboge
977929f558 Cherrypick from trunk:
Description: updates for usr.bin.sshd example profile to work with zsh4, dash
   and systems where /var/run moved to /run. Also allows read of
   /etc/default/locale.
  Bug-Ubuntu: https://launchpad.net/bugs/817956

  Acked-by: Jamie Strandboge <jamie@canonical.com>
  Acked-by: Kees Cook <kees@ubuntu.com>
2012-01-06 10:51:09 -06:00
Jamie Strandboge
cb60e9b3df Cherrypick from upstream:
Description: Disallow writing and linking to @{HOME}/.pki/nssdb/ .so files
  Bug-Ubuntu: https://launchpad.net/bugs/911847

  Acked-by: Jamie Strandboge <jamie@canonical.com>
  Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-01-06 10:50:19 -06:00
Christian Boltz
f57d90d935 lesson of the day: it's not a good idea to edit a file while the
"bzr commit" editor is open because bzr caches the modified file 
and doesn't include last-minute changes in the commit :-/

In other words: the rule for /.htaccess didn't contain the audit
keyword in my last commit.
2012-01-05 23:53:51 +01:00
Christian Boltz
f66a2e2e66 according to Lars Müller (a samba developer) smbd needs access to some
more files in /usr/lib*/samba/ in some cases.

References: https://bugzilla.novell.com/show_bug.cgi?id=725967#c5


Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-01-05 23:50:13 +01:00
Christian Boltz
d1281c4988 Split off various permissions from the httpd2-prefork profile to
abstractions/apache2-common. Additionally, add read permissions
for /**/.htaccess and /dev/urandom to apache2-common.

The patch is based on a profile abstraction from darix. I made some 
things more strict (compared to darix' profile), and OTOH added some 
things that are needed on my servers.

*** BACKWARDS-INCOMPATIBLE CHANGES ***

^HANDLING_UNTRUSTED_INPUT
- don't allow *.htaccess files (the old /**.htaccess rule was too generous)


Note: this is slightly different to trunk r1895 regarding /.htaccess:
/.htaccess is still allowed in the 2.7 branch, but logged ("audit") and 
has a comment saying that it will be disallowed in future versions.
2012-01-05 23:38:48 +01:00
Christian Boltz
c93fc7c758 Create /etc/apparmor.d/tunables/multiarch.d directory in profiles/Makefile
(otherwise it's created as a file, which is wrong)

Acked-by: John Johansen <john.johansen@canonical.com>
2012-01-03 23:45:00 +01:00
Christian Boltz
e2c5ecafce Fix a syntax error in abstractions/python introduced in r1854.
According to https://launchpad.net/bugs/840734 pyconfig.h should have r 
permissions.

Acked-by: John Johansen <john.johansen@canonical.com>
2012-01-03 21:23:30 +01:00
Christian Boltz
888ef7b0e2 smbd needs read access to /etc/netgroup.
References: https://bugzilla.novell.com/show_bug.cgi?id=738041

Acked-by: John Johansen <john.johansen@canonical.com>
2011-12-30 21:55:58 +01:00
3542 changed files with 122663 additions and 230459 deletions

View File

@@ -1,22 +1,7 @@
apparmor-*
cscope.*
binutils/aa-enabled
binutils/aa-enabled.1
binutils/aa-exec
binutils/aa-exec.1
binutils/aa-features-abi
binutils/aa-features-abi.1
binutils/aa-load
binutils/aa-status
binutils/aa-status.8
binutils/cJSON.o
binutils/po/*.mo
parser/po/*.mo
parser/af_names.h
parser/cap_names.h
parser/generated_cap_names.h
parser/generated_af_names.h
parser/tst_lib
parser/tst_misc
parser/tst_regex
parser/tst_symtab
@@ -27,57 +12,19 @@ parser/parser_version.h
parser/parser_yacc.c
parser/parser_yacc.h
parser/pod2htm*.tmp
parser/af_rule.o
parser/af_unix.o
parser/all_rule.o
parser/common_optarg.o
parser/dbus.o
parser/default_features.o
parser/lib.o
parser/libapparmor_re/aare_rules.o
parser/libapparmor_re/chfa.o
parser/libapparmor_re/expr-tree.o
parser/libapparmor_re/hfa.o
parser/libapparmor_re/libapparmor_re.a
parser/libapparmor_re/parse.o
parser/mount.o
parser/mqueue.o
parser/network.o
parser/parser_alias.o
parser/parser_common.o
parser/parser_include.o
parser/parser_interface.o
parser/parser_lex.o
parser/parser_main.o
parser/parser_merge.o
parser/parser_misc.o
parser/parser_policy.o
parser/parser_regex.o
parser/parser_symtab.o
parser/parser_variable.o
parser/parser_yacc.o
parser/policy_cache.o
parser/profile.o
parser/ptrace.o
parser/rule.o
parser/signal.o
parser/userns.o
parser/io_uring.o
parser/*.7
parser/*.5
parser/*.8
parser/*.7.html
parser/*.5.html
parser/*.8.html
parser/common
parser/apparmor_parser
parser/libapparmor_re/parse.cc
parser/libapparmor_re/regexp.cc
parser/techdoc.aux
parser/techdoc.log
parser/techdoc.pdf
parser/techdoc.toc
profiles/apparmor.d/local/*
!profiles/apparmor.d/local/README
libraries/libapparmor/Makefile
libraries/libapparmor/Makefile.in
libraries/libapparmor/aclocal.m4
@@ -94,61 +41,27 @@ libraries/libapparmor/install-sh
libraries/libapparmor/libtool
libraries/libapparmor/ltmain.sh
libraries/libapparmor/missing
libraries/libapparmor/test-driver
libraries/libapparmor/ylwrap
libraries/libapparmor/doc/Makefile
libraries/libapparmor/doc/Makefile.in
libraries/libapparmor/doc/*.2
libraries/libapparmor/doc/aa_*.3
libraries/libapparmor/include/Makefile
libraries/libapparmor/include/Makefile.in
libraries/libapparmor/include/sys/Makefile
libraries/libapparmor/include/sys/Makefile.in
libraries/libapparmor/src/.deps
libraries/libapparmor/src/.libs
libraries/libapparmor/src/Makefile
libraries/libapparmor/src/Makefile.in
libraries/libapparmor/src/PMurHash.lo
libraries/libapparmor/src/PMurHash.o
libraries/libapparmor/src/af_protos.h
libraries/libapparmor/src/change_hat.lo
libraries/libapparmor/src/features.lo
libraries/libapparmor/src/features.o
libraries/libapparmor/src/grammar.lo
libraries/libapparmor/src/grammar.o
libraries/libapparmor/src/kernel.lo
libraries/libapparmor/src/kernel.o
libraries/libapparmor/src/kernel_interface.lo
libraries/libapparmor/src/kernel_interface.o
libraries/libapparmor/src/libaalogparse.lo
libraries/libapparmor/src/libaalogparse.o
libraries/libapparmor/src/libimmunix_warning.lo
libraries/libapparmor/src/policy_cache.lo
libraries/libapparmor/src/policy_cache.o
libraries/libapparmor/src/private.lo
libraries/libapparmor/src/private.o
libraries/libapparmor/src/scanner.lo
libraries/libapparmor/src/scanner.o
libraries/libapparmor/src/libapparmor.pc
libraries/libapparmor/src/libapparmor.la
libraries/libapparmor/src/libimmunix.la
libraries/libapparmor/src/grammar.c
libraries/libapparmor/src/grammar.h
libraries/libapparmor/src/scanner.c
libraries/libapparmor/src/scanner.h
libraries/libapparmor/src/test-suite.log
libraries/libapparmor/src/tst_aalogmisc
libraries/libapparmor/src/tst_aalogmisc.log
libraries/libapparmor/src/tst_aalogmisc.o
libraries/libapparmor/src/tst_aalogmisc.trs
libraries/libapparmor/src/tst_features
libraries/libapparmor/src/tst_features.log
libraries/libapparmor/src/tst_features.o
libraries/libapparmor/src/tst_features.trs
libraries/libapparmor/src/tst_kernel
libraries/libapparmor/src/tst_kernel.log
libraries/libapparmor/src/tst_kernel.o
libraries/libapparmor/src/tst_kernel.trs
libraries/libapparmor/swig/Makefile
libraries/libapparmor/swig/Makefile.in
libraries/libapparmor/swig/perl/LibAppArmor.bs
@@ -157,34 +70,14 @@ libraries/libapparmor/swig/perl/Makefile
libraries/libapparmor/swig/perl/Makefile.PL
libraries/libapparmor/swig/perl/Makefile.in
libraries/libapparmor/swig/perl/Makefile.perl
libraries/libapparmor/swig/perl/Makefile.perle
libraries/libapparmor/swig/perl/MYMETA.json
libraries/libapparmor/swig/perl/MYMETA.yml
libraries/libapparmor/swig/perl/blib
libraries/libapparmor/swig/perl/libapparmor_wrap.c
libraries/libapparmor/swig/perl/libapparmor_wrap.o
libraries/libapparmor/swig/perl/pm_to_blib
libraries/libapparmor/swig/python/LibAppArmor.py
libraries/libapparmor/swig/python/LibAppArmor.egg-info/
libraries/libapparmor/swig/python/build/
libraries/libapparmor/swig/python/libapparmor_wrap.c
libraries/libapparmor/swig/python/Makefile
libraries/libapparmor/swig/python/Makefile.in
libraries/libapparmor/swig/python/setup.py
libraries/libapparmor/swig/python/test/Makefile
libraries/libapparmor/swig/python/test/Makefile.in
libraries/libapparmor/swig/python/test/test-suite.log
libraries/libapparmor/swig/python/test/test_python.py
libraries/libapparmor/swig/python/test/test_python.py.log
libraries/libapparmor/swig/python/test/test_python.py.trs
libraries/libapparmor/swig/ruby/LibAppArmor.so
libraries/libapparmor/swig/ruby/LibAppArmor_wrap.c
libraries/libapparmor/swig/ruby/LibAppArmor_wrap.o
libraries/libapparmor/swig/ruby/Makefile
libraries/libapparmor/swig/ruby/Makefile.in
libraries/libapparmor/swig/ruby/Makefile.bak
libraries/libapparmor/swig/ruby/Makefile.ruby
libraries/libapparmor/swig/ruby/mkmf.log
libraries/libapparmor/testsuite/.deps
libraries/libapparmor/testsuite/.libs
libraries/libapparmor/testsuite/Makefile
@@ -200,32 +93,18 @@ libraries/libapparmor/testsuite/lib/Makefile.in
libraries/libapparmor/testsuite/libaalogparse.test/Makefile
libraries/libapparmor/testsuite/libaalogparse.test/Makefile.in
libraries/libapparmor/testsuite/test_multi/out
libraries/libapparmor/testsuite/test_multi_multi-test_multi.o
changehat/mod_apparmor/.libs
changehat/mod_apparmor/common
changehat/pam_apparmor/common
changehat/tomcat_apparmor/common
utils/common
utils/*.8
utils/*.8.html
utils/*.5
utils/*.5.html
utils/*.tmp
utils/po/*.mo
utils/apparmor/*.pyc
utils/apparmor/rule/*.pyc
utils/apparmor.egg-info/
utils/build/
utils/htmlcov/
utils/test/common_test.pyc
utils/test/.coverage
utils/test/coverage-report.txt
utils/test/htmlcov/
utils/vim/apparmor.vim
utils/vim/apparmor.vim.5
utils/vim/apparmor.vim.5.html
utils/vim/pod2htmd.tmp
tests/regression/apparmor/*.o
tests/regression/apparmor/aa_policy_cache
tests/regression/apparmor/access
tests/regression/apparmor/at_secure
tests/regression/apparmor/attach_disconnected
tests/regression/apparmor/changehat
tests/regression/apparmor/changehat_fail
tests/regression/apparmor/changehat_fork
@@ -240,10 +119,6 @@ tests/regression/apparmor/chgrp
tests/regression/apparmor/chmod
tests/regression/apparmor/chown
tests/regression/apparmor/clone
tests/regression/apparmor/dbus_eavesdrop
tests/regression/apparmor/dbus_message
tests/regression/apparmor/dbus_service
tests/regression/apparmor/dbus_unrequested_reply
tests/regression/apparmor/deleted
tests/regression/apparmor/env_check
tests/regression/apparmor/environ
@@ -254,40 +129,26 @@ tests/regression/apparmor/fchdir
tests/regression/apparmor/fchgrp
tests/regression/apparmor/fchmod
tests/regression/apparmor/fchown
tests/regression/apparmor/fd_inheritance
tests/regression/apparmor/fd_inheritor
tests/regression/apparmor/fork
tests/regression/apparmor/introspect
tests/regression/apparmor/io_uring
tests/regression/apparmor/link
tests/regression/apparmor/link_subset
tests/regression/apparmor/mkdir
tests/regression/apparmor/mmap
tests/regression/apparmor/mount
tests/regression/apparmor/move_mount
tests/regression/apparmor/named_pipe
tests/regression/apparmor/net_inet_rcv
tests/regression/apparmor/net_inet_snd
tests/regression/apparmor/net_raw
tests/regression/apparmor/open
tests/regression/apparmor/openat
tests/regression/apparmor/pipe
tests/regression/apparmor/pivot_root
tests/regression/apparmor/posix_mq_rcv
tests/regression/apparmor/posix_mq_snd
tests/regression/apparmor/ptrace
tests/regression/apparmor/ptrace_helper
tests/regression/apparmor/pwrite
tests/regression/apparmor/query_label
tests/regression/apparmor/readdir
tests/regression/apparmor/rename
tests/regression/apparmor/rw
tests/regression/apparmor/socketpair
tests/regression/apparmor/swap
tests/regression/apparmor/symlink
tests/regression/apparmor/syscall_chroot
tests/regression/apparmor/syscall_ioperm
tests/regression/apparmor/syscall_iopl
tests/regression/apparmor/syscall_mknod
tests/regression/apparmor/syscall_mlockall
tests/regression/apparmor/syscall_ptrace
@@ -298,20 +159,9 @@ tests/regression/apparmor/syscall_setpriority
tests/regression/apparmor/syscall_setscheduler
tests/regression/apparmor/syscall_sysctl
tests/regression/apparmor/sysctl_proc
tests/regression/apparmor/sysv_mq_rcv
tests/regression/apparmor/sysv_mq_snd
tests/regression/apparmor/tcp
tests/regression/apparmor/transition
tests/regression/apparmor/unix_fd_client
tests/regression/apparmor/unix_fd_server
tests/regression/apparmor/unix_socket
tests/regression/apparmor/unix_socket_client
tests/regression/apparmor/unlink
tests/regression/apparmor/userns
tests/regression/apparmor/userns_setns
tests/regression/apparmor/uservars.inc
tests/regression/apparmor/xattrs
tests/regression/apparmor/xattrs_profile
tests/regression/apparmor/coredump
**/__pycache__/
*.orig

View File

@@ -1,166 +0,0 @@
---
image: ubuntu:latest
# XXX - add a deploy stage to publish man pages, docs, and coverage
# reports
stages:
- build
- test
.ubuntu-before_script:
before_script:
- export DEBIAN_FRONTEND=noninteractive
- apt-get update -qq
- apt-get install --no-install-recommends -y gcc perl liblocale-gettext-perl linux-libc-dev lsb-release make
- lsb_release -a
- uname -a
.install-c-build-deps: &install-c-build-deps
- apt-get install --no-install-recommends -y build-essential apache2-dev autoconf autoconf-archive automake bison dejagnu flex libpam-dev libtool pkg-config python3-all-dev python3-setuptools ruby-dev swig zlib1g-dev
build-all:
stage: build
extends:
- .ubuntu-before_script
artifacts:
name: ${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
expire_in: 30 days
untracked: true
paths:
- libraries/libapparmor/
- parser/
- binutils/
- utils/
- changehat/mod_apparmor/
- changehat/pam_apparmor/
- profiles/
script:
- *install-c-build-deps
- cd libraries/libapparmor && ./autogen.sh && ./configure --with-perl --with-python --prefix=/usr && make && cd ../.. || { cat config.log ; exit 1 ; }
- make -C parser
- make -C binutils
- make -C utils
- make -C changehat/mod_apparmor
- make -C changehat/pam_apparmor
- make -C profiles
test-libapparmor:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-before_script
script:
- *install-c-build-deps
- make -C libraries/libapparmor check
test-parser:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-before_script
script:
- *install-c-build-deps
- make -C parser check
test-binutils:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-before_script
script:
- make -C binutils check
test-utils:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-before_script
script:
- apt-get install --no-install-recommends -y libc6-dev libjs-jquery libjs-jquery-throttle-debounce libjs-jquery-isonscreen libjs-jquery-tablesorter pyflakes3 python3-coverage python3-notify2 python3-psutil python3-setuptools
# See apparmor/apparmor#221
- make -C parser/tst gen_dbus
- make -C parser/tst gen_xtrans
- make -C utils check
- make -C utils/test coverage-regression
artifacts:
paths:
- utils/test/htmlcov/
when: always
test-mod-apparmor:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-before_script
script:
- make -C changehat/mod_apparmor check
test-profiles:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-before_script
script:
- make -C profiles check-parser
- make -C profiles check-abstractions.d
- make -C profiles check-extras
shellcheck:
stage: test
needs: []
extends:
- .ubuntu-before_script
script:
- apt-get install --no-install-recommends -y python3-minimal file shellcheck xmlstarlet
- shellcheck --version
- './tests/bin/shellcheck-tree --format=checkstyle
| xmlstarlet tr tests/checkstyle2junit.xslt
> shellcheck.xml'
artifacts:
when: always
reports:
junit: shellcheck.xml
# Disabled due to aa-logprof dependency on /sbin/apparmor_parser existing
# - make -C profiles check-profiles
# test-pam_apparmor:
# - stage: test
# - script:
# - cd changehat/pam_apparmor && make check
include:
- template: SAST.gitlab-ci.yml
- template: Secret-Detection.gitlab-ci.yml
variables:
SAST_EXCLUDED_ANALYZERS: "eslint,flawfinder,semgrep,spotbugs"
SAST_BANDIT_EXCLUDED_PATHS: "*/tst/*, */test/*"
.send-to-coverity: &send-to-coverity
- curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
--form file=@$(ls apparmor-*-cov-int.tar.gz) --form version="$(git describe --tags)"
--form description="$(git describe --tags) / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
coverity:
stage: .post
extends:
- .ubuntu-before_script
only:
refs:
- master
script:
- apt-get install --no-install-recommends -y curl git texlive-latex-recommended
- *install-c-build-deps
- curl -o /tmp/cov-analysis-linux64.tgz https://scan.coverity.com/download/linux64
--form project=$COVERITY_SCAN_PROJECT_NAME --form token=$COVERITY_SCAN_TOKEN
- tar xfz /tmp/cov-analysis-linux64.tgz
- COV_VERSION=$(ls -dt cov-analysis-linux64-* | head -1)
- PATH=$PATH:$(pwd)/$COV_VERSION/bin
- make coverity
- *send-to-coverity
artifacts:
paths:
- "apparmor-*.tar.gz"

View File

@@ -1,10 +0,0 @@
# Don't follow source'd scripts
disable=SC1090
disable=SC1091
# dash supports 'local'
disable=SC2039
disable=SC3043
# dash supports 'echo -n'
disable=SC3037

View File

@@ -1,90 +1,64 @@
#
#
.PHONY: all
all:
@echo "*** See README for information how to build AppArmor ***"
exit 1
OVERRIDE_TARBALL=yes
COMMONDIR=common
include ${COMMONDIR}/Make.rules
include common/Make.rules
DIRS=libraries/libapparmor \
binutils \
parser \
DIRS=parser \
profiles \
utils \
changehat/libapparmor \
changehat/mod_apparmor \
changehat/pam_apparmor \
profiles \
tests
# with conversion to git, we don't export from the remote
REPO_URL?=git@gitlab.com:apparmor/apparmor.git
REPO_BRANCH?=master
REPO_URL?=lp:apparmor
# alternate possibilities to export from
#REPO_URL=.
#REPO_URL="bzr+ssh://bazaar.launchpad.net/~sbeattie/+junk/apparmor-dev/"
COVERITY_DIR=cov-int
RELEASE_DIR=apparmor-${VERSION}
__SETUP_DIR?=.
# We create a separate version for tags because git can't handle tags
# with embedded ~s in them. No spaces around '-' or they'll get
# embedded in ${VERSION}
# apparmor version tag format 'vX.Y.ZZ'
# apparmor branch name format 'apparmor-X.Y'
TAG_VERSION="v$(subst ~,-,${VERSION})"
# Add exclusion entries arguments for tar here, of the form:
# --exclude dir_to_exclude --exclude other_dir
TAR_EXCLUSIONS=
TAG_VERSION=$(subst ~,-,${VERSION})
.PHONY: tarball
tarball: clean
REPO_VERSION=`$(value REPO_VERSION_CMD)` && \
$(MAKE) export_dir __EXPORT_DIR=${RELEASE_DIR} __REPO_VERSION=$${REPO_VERSION} && \
$(MAKE) setup __SETUP_DIR=${RELEASE_DIR} && \
tar ${TAR_EXCLUSIONS} -cvzf ${RELEASE_DIR}.tar.gz ${RELEASE_DIR}
REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
make export_dir __EXPORT_DIR=${RELEASE_DIR} __REPO_VERSION=$${REPO_VERSION} ; \
make setup __SETUP_DIR=${RELEASE_DIR} ; \
tar --exclude deprecated -cvzf ${RELEASE_DIR}.tar.gz ${RELEASE_DIR}
.PHONY: snapshot
snapshot: clean
$(eval REPO_VERSION:=$(shell $(value REPO_VERSION_CMD)))
$(eval SNAPSHOT_NAME=apparmor-$(VERSION)~$(shell echo $(REPO_VERSION) | cut -d '-' -f 2-))
$(MAKE) export_dir __EXPORT_DIR=${SNAPSHOT_NAME} __REPO_VERSION=${REPO_VERSION} && \
$(MAKE) setup __SETUP_DIR=${SNAPSHOT_NAME} && \
tar ${TAR_EXCLUSIONS} -cvzf ${SNAPSHOT_NAME}.tar.gz ${SNAPSHOT_NAME}
REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
SNAPSHOT_DIR=apparmor-${VERSION}~$${REPO_VERSION} ;\
make export_dir __EXPORT_DIR=$${SNAPSHOT_DIR} __REPO_VERSION=$${REPO_VERSION} ; \
make setup __SETUP_DIR=$${SNAPSHOT_DIR} ; \
tar --exclude deprecated -cvzf $${SNAPSHOT_DIR}.tar.gz $${SNAPSHOT_DIR} ;
.PHONY: coverity
coverity: snapshot
cd $(SNAPSHOT_NAME)/libraries/libapparmor && ./configure --with-python
$(foreach dir, libraries/libapparmor utils, \
cov-build --dir $(COVERITY_DIR) --no-command --fs-capture-search $(SNAPSHOT_NAME)/$(dir); \
mv $(COVERITY_DIR)/build-log.txt $(COVERITY_DIR)/build-log-python-$(subst /,.,$(dir)).txt ;)
cov-build --dir $(COVERITY_DIR) -- sh -c \
"$(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \
$(MAKE) -C $(SNAPSHOT_NAME)/$(dir);) "
tar -cvzf $(SNAPSHOT_NAME)-$(COVERITY_DIR).tar.gz $(COVERITY_DIR)
.PHONY: export_dir
export_dir:
mkdir $(__EXPORT_DIR)
/usr/bin/git archive --prefix=$(__EXPORT_DIR)/ --format tar $(__REPO_VERSION) | tar xv
echo "$(REPO_URL) $(REPO_BRANCH) $(__REPO_VERSION)" > $(__EXPORT_DIR)/common/.stamp_rev
/usr/bin/bzr export --per-file-timestamps -r $(__REPO_VERSION) $(__EXPORT_DIR) $(REPO_URL)
echo "$(REPO_URL) $(__REPO_VERSION)" > $(__EXPORT_DIR)/common/.stamp_rev
.PHONY: clean
clean:
-rm -rf ${RELEASE_DIR} ./apparmor-${VERSION}~* ${COVERITY_DIR}
-rm -rf ${RELEASE_DIR} ./apparmor-${VERSION}~*
for dir in $(DIRS); do \
$(MAKE) -C $$dir clean; \
make -C $$dir clean; \
done
.PHONY: setup
setup:
cd $(__SETUP_DIR)/libraries/libapparmor && ./autogen.sh
# parser has an extra doc to build
$(MAKE) -C $(__SETUP_DIR)/parser extra_docs
# libraries/libapparmor needs configure to have run before
# building docs
$(foreach dir, $(filter-out libraries/libapparmor tests, $(DIRS)), \
$(MAKE) -C $(__SETUP_DIR)/$(dir) docs;)
.PHONY: tag
tag:
git tag -m 'AppArmor $(VERSION)' -s $(TAG_VERSION)
bzr tag apparmor_${TAG_VERSION}

186
README Normal file
View File

@@ -0,0 +1,186 @@
------------
Introduction
------------
AppArmor protects systems from insecure or untrusted processes by
running them in restricted confinement, while still allowing processes
to share files, exercise privilege and communicate with other processes.
AppArmor is a Mandatory Access Control (MAC) mechanism which uses the
Linux Security Module (LSM) framework. The confinement's restrictions
are mandatory and are not bound to identity, group membership, or object
ownership. The protections provided are in addition to the kernel's
regular access control mechanisms (including DAC) and can be used to
restrict the superuser.
The AppArmor kernel module and accompanying user-space tools are
available under the GPL license (the exception is the libapparmor
library, available under the LGPL license, which allows change_hat(2)
and change_profile(2) to be used by non-GPL binaries).
For more information, you can read the techdoc.pdf (available after
building the parser) and by visiting the http://apparmor.net/ web
site.
-------------
Source Layout
-------------
AppArmor consists of several different parts:
changehat/ source for using changehat with Apache, PAM and Tomcat
common/ common makefile rules
desktop/ empty
kernel-patches/ compatibility patches for various kernel versions
libraries/ libapparmor source and language bindings
parser/ source for parser/loader and corresponding documentation
profiles/ configuration files, reference profiles and abstractions
tests/ regression and stress testsuites
utils/ high-level utilities for working with AppArmor
--------------------------------------
Important note on AppArmor kernel code
--------------------------------------
While most of the kernel AppArmor code has been accepted in the
upstream Linux kernel, a few important pieces were not included. These
missing pieces unfortunately are important bits for AppArmor userspace
and kernel interaction; therefore we have included compatibility
patches in the kernel-patches/ subdirectory, versioned by upstream
kernel (2.6.37 patches should apply cleanly to 2.6.38 source).
Without these patches applied to the kernel, the AppArmor userspace
will not function correctly.
------------------------------------------
Building and Installing AppArmor Userspace
------------------------------------------
To build and install AppArmor userspace on your system, build and install in
the following order.
libapparmor:
$ cd ./libraries/libapparmor
$ sh ./autogen.sh
$ sh ./configure --prefix=/usr --with-perl # see below
$ make
$ make check
$ make install
[optional arguments to libapparmor's configure include --with-python
and --with-ruby, to generate python and ruby bindings to libapparmor,
respectively.]
Utilities:
$ cd utils
$ make
$ make check
$ make install
parser:
$ cd parser
$ make
$ make check
$ make install
Apache mod_apparmor:
$ cd changehat/mod_apparmor
$ make # depends on libapparmor having been built first
$ make install
PAM AppArmor:
$ cd changehat/pam_apparmor
$ make # depends on libapparmor having been built first
$ make install
Profiles:
$ cd profiles
$ make
$ 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
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".]
-------------------
AppArmor Testsuites
-------------------
A number of testsuites are in the AppArmor sources. Most have documentation on
usage and how to update and add tests. Below is a quick overview of their
location and how to run them.
Regression tests
----------------
For details on structure and adding tests, see
tests/regression/apparmor/README.
To run:
$ cd tests/regression/apparmor (requires root)
$ make
$ sudo make tests
$ sudo bash open.sh -r # runs and saves the last testcase from open.sh
Parser tests
------------
For details on structure and adding tests, see parser/tst/README.
To run:
$ cd parser/tst
$ make
$ make tests
Libapparmor
-----------
For details on structure and adding tests, see libraries/libapparmor/README.
$ cd libraries/libapparmor
$ make check
Profile checks
--------------
A basic consistency check to ensure that the parser and aa-logprof parse
successfully the current set of shipped profiles. The system or other
parser and logprof can be passed in by overriding the PARSER and LOGPROF
variables.
$ cd profiles
$ make && make check
Stress Tests
------------
To run AppArmor stress tests:
$ make all
Use these:
$ ./change_hat
$ ./child
$ ./kill.sh
$ ./open
$ ./s.sh
Or run all at once:
$ ./stress.sh
Please note that the above will stress the system so much it may end up
invoking the OOM killer.
To run parser stress tests (requires /usr/bin/ruby):
$ ./stress.sh
(see stress.sh -h for options)
-----------------------------------------------
Building and Installing AppArmor Kernel Patches
-----------------------------------------------
TODO

362
README.md
View File

@@ -1,362 +0,0 @@
# AppArmor
[![Build status](https://gitlab.com/apparmor/apparmor/badges/master/build.svg)](https://gitlab.com/apparmor/apparmor/commits/master)
[![Overall test coverage](https://gitlab.com/apparmor/apparmor/badges/master/coverage.svg)](https://gitlab.com/apparmor/apparmor/pipelines)
[![Core Infrastructure Initiative Best Practices](https://bestpractices.coreinfrastructure.org/projects/1699/badge)](https://bestpractices.coreinfrastructure.org/projects/1699)
------------
Introduction
------------
AppArmor protects systems from insecure or untrusted processes by
running them in restricted confinement, while still allowing processes
to share files, exercise privilege and communicate with other processes.
AppArmor is a Mandatory Access Control (MAC) mechanism which uses the
Linux Security Module (LSM) framework. The confinement's restrictions
are mandatory and are not bound to identity, group membership, or object
ownership. The protections provided are in addition to the kernel's
regular access control mechanisms (including DAC) and can be used to
restrict the superuser.
The AppArmor kernel module and accompanying user-space tools are
available under the GPL license (the exception is the libapparmor
library, available under the LGPL license, which allows change_hat(2)
and change_profile(2) to be used by non-GPL binaries).
For more information, you can read the techdoc.pdf (available after
building the parser) and by visiting the https://apparmor.net/ web
site.
----------------
Getting in Touch
----------------
Please send all complaints, feature requests, rants about the software,
and questions to the
[AppArmor mailing list](https://lists.ubuntu.com/mailman/listinfo/apparmor).
Bug reports can be filed against the AppArmor project on
[GitLab](https://gitlab.com/apparmor/apparmor/-/issues) or reported to the mailing
list directly for those who wish not to register for an account on
GitLab. See the
[wiki page](https://gitlab.com/apparmor/apparmor/wikis/home#reporting-bugs)
for more information.
Security issues can be filed in GitLab by opening up a new [issue](https://gitlab.com/apparmor/apparmor/-/issues) and selecting the tick box ```This issue is confidential and should only be visible to team members with at least Reporter access.``` or directed to `security@apparmor.net`. Additional details can be found
in the [wiki](https://gitlab.com/apparmor/apparmor/wikis/home#reporting-security-vulnerabilities).
--------------
Privacy Policy
--------------
The AppArmor security project respects users privacy and data and does not collect data from or on its users beyond what is required for a given component to function.
The AppArmor kernel security module will log violations to the audit subsystem, and those will be logged/forwarded/recorded on the user's system(s) according to how the administrator has logging configured. Again this is not forwarded to or collected by the AppArmor project.
The AppArmor userspace tools do not collect information on the system user beyond the logs and information needed to interact with the user. This is not forwarded to, nor collected by the AppArmor project.
Users may submit information as part of an email, bug report or merge request, etc. and that will be recorded as part of the mailing list, bug/issue tracker, or code repository but only as part of a user initiated action.
The AppArmor project does not collect information from contributors beyond their interactions with the AppArmor project, code, and community. However contributors are subject to the terms and conditions and privacy policy of the individual platforms (currently GitLab) should they choose to contribute through those platforms. And those platforms may collect data on the user that the AppArmor project does not.
Currently GitLab requires a user account to submit patches or report bugs and issues. If a contributor does not wish to create an account for these platforms the mailing list is available. Membership in the list is not required. Content from non-list members will be sent to moderation, to ensure that it is on topic, so there may be a delay in choosing to interact in this way.
-------------
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
kernel-patches/ compatibility patches for various kernel versions
libraries/ libapparmor source and language bindings
parser/ source for parser/loader and corresponding documentation
profiles/ configuration files, reference profiles and abstractions
tests/ regression and stress testsuites
utils/ high-level utilities for working with AppArmor
```
--------------------------------------
Important note on AppArmor kernel code
--------------------------------------
While most of the kernel AppArmor code has been accepted in the
upstream Linux kernel, a few important pieces were not included. These
missing pieces unfortunately are important bits for AppArmor userspace
and kernel interaction; therefore we have included compatibility
patches in the kernel-patches/ subdirectory, versioned by upstream
kernel (2.6.37 patches should apply cleanly to 2.6.38 source).
Without these patches applied to the kernel, the AppArmor userspace
will not function correctly.
------------------------------------------
Building and Installing AppArmor Userspace
------------------------------------------
To build and install AppArmor userspace on your system, build and install in
the following order. Some systems may need to export various python-related
environment variables to complete the build. For example, before building
anything on these systems, use something along the lines of:
```
$ export PYTHONPATH=$(realpath libraries/libapparmor/swig/python)
$ export PYTHON=/usr/bin/python3
$ export PYTHON_VERSION=3
$ export PYTHON_VERSIONS=python3
```
### libapparmor:
```
$ cd ./libraries/libapparmor
$ sh ./autogen.sh
$ sh ./configure --prefix=/usr --with-perl --with-python # see below
$ make
$ make check
$ make install
```
[an additional optional argument to libapparmor's configure is --with-ruby, to
generate Ruby bindings to libapparmor.]
### Binary Utilities:
```
$ cd binutils
$ make
$ make check
$ make install
```
### Parser:
```
$ cd parser
$ make # depends on libapparmor having been built first
$ make check
$ make install
```
### Utilities:
```
$ cd utils
$ make
$ make check PYFLAKES=/usr/bin/pyflakes3
$ make install
```
### Apache mod_apparmor:
```
$ cd changehat/mod_apparmor
$ make # depends on libapparmor having been built first
$ make install
```
### PAM AppArmor:
```
$ cd changehat/pam_apparmor
$ make # depends on libapparmor having been built first
$ make install
```
### Profiles:
```
$ cd profiles
$ make
$ make check # depends on the parser having been built first
$ make install
```
Note that the empty local/* profile sniplets no longer get created by default.
If you want them, run `make local` before running `make check`.
[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".]
-------------------
AppArmor Testsuites
-------------------
A number of testsuites are in the AppArmor sources. Most have documentation on
usage and how to update and add tests. Below is a quick overview of their
location and how to run them.
Regression tests
----------------
For details on structure and adding tests, see
tests/regression/apparmor/README.
To run:
### Regression tests - using apparmor userspace installed on host
```
$ cd tests/regression/apparmor (requires root)
$ make USE_SYSTEM=1
$ sudo make tests USE_SYSTEM=1
$ sudo bash open.sh -r # runs and saves the last testcase from open.sh
```
### Regression tests - using apparmor userspace from the tree.
- [build libapparmor](#libapparmor)
- [build binutils](#binary-utilities)
- [build apparmor parser](#parser)
- [build Pam apparmor](#pam-apparmor)
```
$ cd tests/regression/apparmor (requires root)
$ make
$ sudo make tests
$ sudo bash open.sh -r # runs and saves the last testcase from open.sh
```
Parser tests
------------
For details on structure and adding tests, see parser/tst/README.
To run:
```
$ cd parser/tst
$ make
$ make tests
```
Libapparmor
-----------
For details on structure and adding tests, see libraries/libapparmor/README.
```
$ cd libraries/libapparmor
$ make check
```
Utils
-----
Tests for the Python utilities exist in the test/ subdirectory.
```
$ cd utils
$ make check
```
The aa-decode utility to be tested can be overridden by
setting up environment variable APPARMOR_DECODE; e.g.:
```
$ APPARMOR_DECODE=/usr/bin/aa-decode make check
```
Profile checks
--------------
A basic consistency check to ensure that the parser and aa-logprof parse
successfully the current set of shipped profiles. The system or other
parser and logprof can be passed in by overriding the PARSER and LOGPROF
variables.
```
$ cd profiles
$ make && make check
```
Stress Tests
------------
To run AppArmor stress tests:
```
$ make all
```
Use these:
```
$ ./change_hat
$ ./child
$ ./kill.sh
$ ./open
$ ./s.sh
```
Or run all at once:
```
$ ./stress.sh
```
Please note that the above will stress the system so much it may end up
invoking the OOM killer.
To run parser stress tests (requires /usr/bin/ruby):
```
$ ./stress.sh
```
(see stress.sh -h for options)
Coverity Support
----------------
Coverity scans are available to AppArmor developers at
https://scan.coverity.com/projects/apparmor.
In order to submit a Coverity build for analysis, the cov-build binary
must be discoverable from your PATH. See the "To Setup" section of
https://scan.coverity.com/download?tab=cxx to obtain a pre-built copy of
cov-build.
To generate a compressed tarball of an intermediate Coverity directory:
```
$ make coverity
```
The compressed tarball is written to
apparmor-<SNAPSHOT_VERSION>-cov-int.tar.gz, where <SNAPSHOT_VERSION>
is something like 2.10.90~3328, and must be uploaded to
https://scan.coverity.com/projects/apparmor/builds/new for analysis. You must
include the snapshot version in Coverity's project build submission form, in
the "Project Version" field, so that it is quickly obvious to all AppArmor
developers what snapshot of the AppArmor repository was used for the analysis.
-----------------------------------------------
Building and Installing AppArmor Kernel Patches
-----------------------------------------------
TODO
-----------------
Required versions
-----------------
The AppArmor userspace utilities are written with some assumptions about
installed and available versions of other tools. This is a (possibly
incomplete) list of known version dependencies:
The Python utilities require a minimum of Python 3.3.
The aa-notify tool's Python dependencies can be satisfied by installing the
following packages (Debian package names, other distros may vary):
* python3-notify2
* python3-psutil
Perl is no longer needed since none of the utilities shipped to end users depend
on it anymore.
Most shell scripts are written for POSIX-compatible sh. aa-decode expects
bash, probably version 3.2 and higher.

View File

@@ -1,178 +0,0 @@
# ----------------------------------------------------------------------
# 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=/
BINDIR=${DESTDIR}/usr/bin
SBINDIR=${DESTDIR}/usr/sbin
LOCALEDIR=/usr/share/locale
MANPAGES=aa-enabled.1 aa-exec.1 aa-features-abi.1 aa-status.8
WARNINGS = -Wall
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 = ${CFLAGS} ${CPPFLAGS} ${EXTRA_CXXFLAGS} ${CPP_WARNINGS} $(EXTRA_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 aa_load.c
HDRS =
BINTOOLS = aa-enabled aa-exec aa-features-abi
SBINTOOLS = aa-status aa-load
AALIB = -Wl,-Bstatic -lapparmor -Wl,-Bdynamic -lpthread
ifdef WITH_LIBINTL
AALIB += -lintl
endif
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: $(BINTOOLS) $(SBINTOOLS)
manpages: $(MANPAGES)
docs: manpages
indep: docs
$(Q)$(MAKE) -C po all
all: arch indep
.PHONY: coverage
coverage:
$(MAKE) clean $(BINTOOLS) $(SBINTOOLS) 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;\
exit 1; \
fi
endif
aa-features-abi: aa_features_abi.c $(LIBAPPARMOR_A)
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
aa-load: aa_load.c $(LIBAPPARMOR_A)
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
aa-enabled: aa_enabled.c $(LIBAPPARMOR_A)
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
aa-exec: aa_exec.c $(LIBAPPARMOR_A)
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
aa-status: aa_status.c cJSON.o $(LIBAPPARMOR_A)
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB) cJSON.o
cJSON.o: cJSON.c cJSON.h
$(CC) $(EXTRA_CFLAGS) -c -o $@ $<
.SILENT: check
.PHONY: check
check: check_pod_files tests
.SILENT: tests
tests: $(BINTOOLS) $(SBINTOOLS) $(TESTS)
echo "no tests atm"
.PHONY: install
install: install-indep install-arch
.PHONY: install-arch
install-arch: arch
install -m 755 -d ${BINDIR}
install -m 755 ${BINTOOLS} ${BINDIR}
install -m 755 -d ${SBINDIR}
ln -sf aa-status ${SBINDIR}/apparmor_status
install -m 755 ${SBINTOOLS} ${SBINDIR}
.PHONY: install-indep
install-indep: indep
$(MAKE) -C po install NAME=${NAME} DESTDIR=${DESTDIR}
$(MAKE) install_manpages DESTDIR=${DESTDIR}
ln -sf aa-status.8 ${DESTDIR}/${MANDIR}/man8/apparmor_status.8
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 $(BINTOOLS) $(SBINTOOLS) $(TESTS)
$(MAKE) -s -C po clean

View File

@@ -1,103 +0,0 @@
# 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<aa-enabled> [options]
=head1 DESCRIPTION
B<aa-enabled> is used to determine if AppArmor is enabled.
=head1 OPTIONS
B<aa-enabled> 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.
=item -x, --exclusive
Require AppArmor to have exclusive access to shared LSM interfaces to
be considered enabled.
=back
=head1 EXIT STATUS
Upon exiting, B<aa-enabled> will set its exit status to the following values:
=over 4
=item B<0>
if AppArmor is enabled.
=item B<1>
if AppArmor is not enabled/loaded.
=item B<2>
intentionally not used as an B<aa-enabled> exit status.
=item B<3>
if the AppArmor control files aren't available under /sys/kernel/security/.
=item B<4>
if B<aa-enabled> doesn't have enough privileges to read the apparmor control files.
=item B<10>
AppArmor is enabled but does not have access to shared LSM interfaces.
=item B<64>
if any unexpected error or condition is encountered.
=back
=head1 BUGS
If you find any bugs, please report them at
L<https://gitlab.com/apparmor/apparmor/-/issues>.
=head1 SEE ALSO
apparmor(7), apparmor.d(5), aa_is_enabled(2), and L<https://wiki.apparmor.net>.
=cut

View File

@@ -1,93 +0,0 @@
# 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-exec - confine a program with the specified AppArmor profile
=head1 SYNOPSIS
B<aa-exec> [options] [--] [I<E<lt>commandE<gt>> ...]
=head1 DESCRIPTION
B<aa-exec> is used to launch a program confined by the specified profile
and or namespace. If both a profile and namespace are specified command
will be confined by profile in the new policy namespace. If only a namespace
is specified, the profile name of the current confinement will be used. If
neither a profile or namespace is specified command will be run using
standard profile attachment (ie. as if run without the aa-exec command).
If the arguments are to be pasted to the I<E<lt>commandE<gt>> being invoked
by aa-exec then -- should be used to separate aa-exec arguments from the
command.
aa-exec -p profile1 -- ls -l
=head1 OPTIONS
B<aa-exec> accepts the following arguments:
=over 4
=item -p PROFILE, --profile=PROFILE
confine I<E<lt>commandE<gt>> with PROFILE. If the PROFILE is not specified
use the current profile name (likely unconfined).
=item -n NAMESPACE, --namespace=NAMESPACE
use profiles in NAMESPACE. This will result in confinement transitioning
to using the new profile namespace.
=item -i, --immediate
transition to PROFILE before doing executing I<E<lt>commandE<gt>>. This
subjects the running of I<E<lt>commandE<gt>> to the exec transition rules
of the current profile.
=item -v, --verbose
show commands being performed
=item -d, --debug
show commands and error codes
=item --
Signal the end of options and disables further option processing. Any
arguments after the -- are treated as arguments of the command. This is
useful when passing arguments to the I<E<lt>commandE<gt>> being invoked by
aa-exec.
=back
=head1 BUGS
If you find any bugs, please report them at
L<https://gitlab.com/apparmor/apparmor/-/issues>
=head1 SEE ALSO
aa-stack(8), aa-namespace(8), apparmor(7), apparmor.d(5), aa_change_profile(3),
aa_change_onexec(3) and L<https://wiki.apparmor.net>.
=cut

View File

@@ -1,97 +0,0 @@
# 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-features-abi - Extract, validate and manipulate AppArmor feature abis
=head1 SYNOPSIS
B<aa-features-abi> [OPTIONS] <SOURCE> [OUTPUT OPTIONS]
=head1 DESCRIPTION
B<aa-features-abi> is used to extract a features abi and output to
either stdout or a specified file. A SOURCE_OPTION must be specified.
If an output option is not specified the features abi is written to
stdout.
=head1 OPTIONS
B<aa-features-abi> accepts the following arguments:
=over 4
=item -h, --help
Display a brief usage guide.
=item -d, --debug
show messages with debugging information
=item -v, --verbose
show messages with stats
=back
=head1 SOURCE
=over 4
=item -x, --extract
Extract the features abi for the kernel
=item -f FILE, --file=FILE
Load the features abi from FILE and send it to OUTPUT OPTIONS.
=back
=head1 OUTPUT OPTIONS
=over 4
=item --stdout
Write the features abi to I<stdout>, this is the default if no output option
is specified.
=item -w FILE, --write FILE
Write the features abi to I<FILE>.
=back
=head1 BUGS
If you find any bugs, please report them at
L<https://gitlab.com/apparmor/apparmor/-/issues>.
=head1 SEE ALSO
apparmor(7), apparmor.d(5), aa_features(3), and L<https://wiki.apparmor.net>.
=cut

View File

@@ -1,100 +0,0 @@
/*
* 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 <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#define _(s) gettext(s)
#include <sys/apparmor.h>
void print_help(const char *command)
{
printf(_("%s: [options]\n"
" options:\n"
" -x | --exclusive Shared interfaces must be available\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)
{
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);
case EBUSY:
if (!quiet)
printf(_("Partially - public shared interfaces are not available.\n"));
exit(10);
}
if (!quiet)
printf(_("Error - %s\n"), strerror(saved_errno));
exit(64);
}
int main(int argc, char **argv)
{
int i, enabled;
int quiet = 0;
int require_shared = 0;
setlocale(LC_MESSAGES, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
if (argc > 3) {
printf(_("unknown or incompatible options\n"));
print_help(argv[0]);
}
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "--quiet") == 0 ||
strcmp(argv[i], "-q") == 0) {
quiet = 1;
} else if (strcmp(argv[i], "--exclusive") == 0 ||
strcmp(argv[i], "-x") == 0) {
require_shared = 1;
} else if (strcmp(argv[i], "--help") == 0 ||
strcmp(argv[i], "-h") == 0) {
print_help(argv[0]);
} else {
printf(_("unknown option '%s'\n"), argv[1]);
print_help(argv[0]);
}
}
enabled = aa_is_enabled();
if (!enabled) {
if (require_shared || errno != EBUSY)
exit_with_error(errno, quiet);
}
if (!quiet)
printf(_("Yes\n"));
exit(0);
}

View File

@@ -1,232 +0,0 @@
/*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc. or Canonical
* Ltd.
*/
#include <errno.h>
#include <getopt.h>
#include <libintl.h>
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/apparmor.h>
#include <sys/types.h>
#include <unistd.h>
#define _(s) gettext(s)
static const char *opt_profile = NULL;
static const char *opt_namespace = NULL;
static bool opt_debug = false;
static bool opt_immediate = false;
static bool opt_verbose = false;
static pid_t pid = 0;
static void usage(const char *name, bool error)
{
FILE *stream = stdout;
int status = EXIT_SUCCESS;
if (error) {
stream = stderr;
status = EXIT_FAILURE;
}
fprintf(stream,
_("USAGE: %s [OPTIONS] <prog> <args>\n"
"\n"
"Confine <prog> with the specified PROFILE.\n"
"\n"
"OPTIONS:\n"
" -p PROFILE, --profile=PROFILE PROFILE to confine <prog> with\n"
" -n NAMESPACE, --namespace=NAMESPACE NAMESPACE to confine <prog> in\n"
" -d, --debug show messages with debugging information\n"
" -i, --immediate change profile immediately instead of at exec\n"
" -v, --verbose show messages with stats\n"
" -h, --help display this help\n"
"\n"), name);
exit(status);
}
#define error(fmt, args...) _error(_("[%ld] aa-exec: ERROR: " fmt "\n"), (long)pid, ## args)
static void _error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
exit(EXIT_FAILURE);
}
#define debug(fmt, args...) _debug(_("[%ld] aa-exec: DEBUG: " fmt "\n"), (long)pid, ## args)
static void _debug(const char *fmt, ...)
{
va_list args;
if (!opt_debug)
return;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
#define verbose(fmt, args...) _verbose(_("[%ld] " fmt "\n"), (long)pid, ## args)
static void _verbose(const char *fmt, ...)
{
va_list args;
if (!opt_verbose)
return;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
static void verbose_print_argv(char **argv)
{
if (!opt_verbose)
return;
fprintf(stderr, _("[%ld] exec"), (long)pid);
for (; *argv; argv++)
fprintf(stderr, " %s", *argv);
fprintf(stderr, "\n");
}
static char **parse_args(int argc, char **argv)
{
int opt;
struct option long_opts[] = {
{"debug", no_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{"profile", required_argument, 0, 'p'},
{"namespace", required_argument, 0, 'n'},
{"immediate", no_argument, 0, 'i'},
{"verbose", no_argument, 0, 'v'},
};
while ((opt = getopt_long(argc, argv, "+dhp:n:iv", long_opts, NULL)) != -1) {
switch (opt) {
case 'd':
opt_debug = true;
break;
case 'h':
usage(argv[0], false);
break;
case 'p':
if (opt_profile)
error("Multiple -p/--profile parameters given");
opt_profile = optarg;
break;
case 'n':
if (opt_namespace)
error("Multiple -n/--namespace parameters given");
opt_namespace = optarg;
break;
case 'i':
opt_immediate = true;
break;
case 'v':
opt_verbose = true;
break;
default:
usage(argv[0], true);
break;
}
}
if (optind >= argc)
usage(argv[0], true);
return argv + optind;
}
static void build_name(char *name, size_t name_len,
const char *namespace, const char *profile)
{
size_t required_len = 1; /* reserve 1 byte for NUL-terminator */
if (namespace)
required_len += 1 + strlen(namespace) + 3; /* :<NAMESPACE>:// */
if (profile)
required_len += strlen(profile);
if (required_len > name_len)
error("name too long (%zu > %zu)", required_len, name_len);
name[0] = '\0';
if (namespace) {
strcat(name, ":");
strcat(name, namespace);
strcat(name, "://");
}
if (profile)
strcat(name, profile);
}
int main(int argc, char **argv)
{
char name[PATH_MAX];
int rc = 0;
/* IMPORTANT: pid must be initialized before doing anything else since
* it is used in a global context when printing messages
*/
pid = getpid();
argv = parse_args(argc, argv);
if (opt_namespace || opt_profile)
build_name(name, sizeof(name), opt_namespace, opt_profile);
else
goto exec;
if (opt_immediate) {
verbose("aa_change_profile(\"%s\")", name);
rc = aa_change_profile(name);
debug("%d = aa_change_profile(\"%s\")", rc, name);
} else {
verbose("aa_change_onexec(\"%s\")", name);
rc = aa_change_onexec(name);
debug("%d = aa_change_onexec(\"%s\")", rc, name);
}
if (rc) {
if (errno == ENOENT) {
error("%s '%s' does not exist",
opt_profile ? "profile" : "namespace", name);
} else if (errno == EACCES) {
error("insufficient permissions to change to the %s '%s'",
opt_profile ? "profile" : "namespace", name);
} else if (errno == EINVAL) {
error("AppArmor interface not available");
} else {
error("%m");
}
}
exec:
verbose_print_argv(argv);
execvp(argv[0], argv);
error("Failed to execute \"%s\": %m", argv[0]);
}

View File

@@ -1,207 +0,0 @@
/*
* Copyright (c) 2020
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Canonical Ltd.
*/
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <libintl.h>
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/apparmor.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define _(s) gettext(s)
#include "../libraries/libapparmor/src/private.h"
static const char *progname = NULL;
static const char *opt_file = NULL;
static const char *opt_write = NULL;
static bool opt_debug = false;
static bool opt_verbose = false;
static bool opt_extract = false;
static void usage(const char *name, bool error)
{
FILE *stream = stdout;
int status = EXIT_SUCCESS;
if (error) {
stream = stderr;
status = EXIT_FAILURE;
}
fprintf(stream,
_("USAGE: %s [OPTIONS] <SOURCE> [OUTPUT OPTIONS]\n"
"\n"
"Output AppArmor feature abi from SOURCE to OUTPUT"
"\n"
"OPTIONS:\n"
#if 0
" -d, --debug show messages with debugging information\n"
" -v, --verbose show messages with stats\n"
#endif
" -h, --help display this help\n"
"SOURCE:\n"
" -f F, --file=F load features abi from file F\n"
" -x, --extract extract features abi from the kernel\n"
"OUTPUT OPTIONS:\n"
" --stdout default, write features to stdout\n"
" -w F, --write=F write features abi to the file F instead of stdout\n"
"\n"), name);
exit(status);
}
#define error(fmt, args...) _error(_("%s: ERROR: " fmt " - %m\n"), progname, ## args)
static void _error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
exit(EXIT_FAILURE);
}
#if 0
#define debug(fmt, args...) _debug(_("%s: DEBUG: " fmt "\n"), progname, ## args)
static void _debug(const char *fmt, ...)
{
va_list args;
if (!opt_debug)
return;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
#define verbose(fmt, args...) _verbose(_(fmt "\n"), ## args)
static void _verbose(const char *fmt, ...)
{
va_list args;
if (!opt_verbose)
return;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
#endif
#define ARG_STDOUT 128
static char **parse_args(int argc, char **argv)
{
int opt;
struct option long_opts[] = {
{"debug", no_argument, 0, 'd'},
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
{"extract", no_argument, 0, 'x'},
{"file", required_argument, 0, 'f'},
{"write", required_argument, 0, 'w'},
{"stdout", no_argument, 0, ARG_STDOUT},
};
while ((opt = getopt_long(argc, argv, "+dvhxf:l:w:", long_opts, NULL)) != -1) {
switch (opt) {
case 'd':
opt_debug = true;
break;
case 'v':
opt_verbose = true;
break;
case 'h':
usage(argv[0], false);
break;
case 'x':
opt_extract = true;
break;
case 'f':
opt_file = optarg;
break;
case 'w':
opt_write = optarg;
break;
case ARG_STDOUT:
opt_write = NULL;
break;
default:
usage(argv[0], true);
break;
}
}
return argv + optind;
}
/* TODO: add features intersection and testing */
int main(int argc, char **argv)
{
struct aa_features *features;
autoclose int in = -1;
autoclose int out = -1;
int rc = 0;
progname = argv[0];
argv = parse_args(argc, argv);
if (!opt_extract && !opt_file)
usage(argv[0], true);
if (opt_extract && opt_file) {
error("options --extract and --file are mutually exclusive");
}
if (opt_extract) {
rc = aa_features_new_from_kernel(&features);
if (rc == -1)
error("failed to extract features abi from the kernel");
}
if (opt_file) {
in = open(opt_file, O_RDONLY);
if (in == -1)
error("failed to open file '%s'", opt_file);
rc = aa_features_new_from_file(&features, in);
if (rc == -1)
error("failed to load features abi from file '%s'", opt_file);
}
if (opt_write) {
out = open(opt_write, O_WRONLY | O_CREAT, 00600);
if (out == -1)
error("failed to open output file '%s'", opt_write);
} else {
out = fileno(stdout);
if (out == -1)
error("failed to get stdout");
}
rc = aa_features_write_to_fd(features, out);
if (rc == -1)
error("failed to write features abi");
return 0;
}

View File

@@ -1,409 +0,0 @@
/*
* Copyright (C) 2020 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.
*/
#define _GNU_SOURCE /* for asprintf() */
#include <stdio.h>
#include <errno.h>
#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <stddef.h>
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/apparmor.h>
#include <libintl.h>
#define _(s) gettext(s)
/* TODO: implement config locations - value can change */
#define DEFAULT_CONFIG_LOCATIONS "/etc/apparmor/parser.conf"
#define DEFAULT_POLICY_LOCATIONS "/var/cache/apparmor:/etc/apparmor.d/cache.d:/etc/apparmor.d/cache"
#define CACHE_FEATURES_FILE ".features"
bool opt_debug = false;
bool opt_verbose = false;
bool opt_dryrun = false;
bool opt_force = false;
bool opt_config = false;
#define warning(fmt, args...) _error(_("aa-load: WARN: " fmt "\n"), ## args)
#define error(fmt, args...) _error(_("aa-load: ERROR: " fmt "\n"), ## args)
static void _error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
#define verbose(fmt, args...) _debug(opt_verbose, _(fmt "\n"), ## args)
#define debug(fmt, args...) _debug(opt_debug, _("aa-load: DEBUG: " fmt "\n"), ## args)
static void _debug(bool opt_displayit, const char *fmt, ...)
{
va_list args;
if (!opt_displayit)
return;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
static int have_enough_privilege(const char *command)
{
uid_t uid, euid;
uid = getuid();
euid = geteuid();
if (uid != 0 && euid != 0) {
error("%s: Sorry. You need root privileges to run this program.\n",
command);
return EPERM;
}
if (uid != 0 && euid == 0) {
error("%s: Aborting! You've set this program setuid root.\n"
"Anybody who can run this program can update "
"your AppArmor profiles.\n", command);
exit(EXIT_FAILURE);
}
return 0;
}
static int load_config(const char *file)
{
/* TODO */
return ENOENT;
}
/**
* load a single policy cache file to the kernel
*/
static int load_policy_file(const char *file)
{
int rc = 0;
struct aa_kernel_interface *kernel_interface;
if (aa_kernel_interface_new(&kernel_interface, NULL, NULL)) {
rc = -errno;
error("Failed to open kernel interface '%s': %m", file);
return rc;
}
if (!opt_dryrun &&
aa_kernel_interface_replace_policy_from_file(kernel_interface,
AT_FDCWD, file)) {
rc = -errno;
error("Failed to load policy into kernel '%s': %m", file);
}
aa_kernel_interface_unref(kernel_interface);
return rc;
}
static void validate_features(const char *dir_path)
{
aa_features *kernel_features;
if (aa_features_new_from_kernel(&kernel_features) == -1) {
error("Failed to obtain features: %m");
return;
}
if (aa_features_check(AT_FDCWD, dir_path, kernel_features) == -1) {
if (errno == ENOENT) {
/* features file does not exist
* not an issue when loading cache policies from dir
*/
}
else if (errno == EEXIST) {
warning("Overlay features do not match kernel features");
}
}
aa_features_unref(kernel_features);
}
/**
* load a directory of policy cache files to the kernel
* This does not do a subdir search to find the kernel match but
* tries to load the dir regardless of whether its features match
*
* The hierarchy looks like
*
* dir/
* .features
* profile1
* ...
*/
static int load_policy_dir(const char *dir_path)
{
DIR *d;
struct dirent *dir;
int rc = 0;
char *file;
size_t len;
validate_features(dir_path);
d = opendir(dir_path);
if (!d) {
rc = -errno;
error("Failed to open directory '%s': %m", dir_path);
return rc;
}
while ((dir = readdir(d)) != NULL) {
/* Only check regular files for now */
if (dir->d_type == DT_REG) {
/* As per POSIX dir->d_name has at most NAME_MAX characters */
len = strnlen(dir->d_name, NAME_MAX);
/* Ignores .features */
if (strncmp(dir->d_name, CACHE_FEATURES_FILE, len) == 0) {
continue;
}
if (asprintf(&file, "%s/%s", dir_path, dir->d_name) == -1) {
error("Failure allocating memory");
closedir(d);
return -1;
}
load_policy_file(file);
free(file);
file = NULL;
}
}
closedir(d);
return 0;
}
/**
* load_hashed_policy - find policy hashed dir and load it
*
* load/replace all policy from a policy hierarchy directory
*
* Returns: 0 on success < -errno
*
* It will find the subdir that matches the kernel and load all
* precompiled policy files from it.
*
* The hierarchy looks something like
*
* location/
* kernel_hash1.0/
* .features
* profile1
* ...
* kernel_hash2.0/
* .features
* profile1
* ...
*/
static int load_policy_by_hash(const char *location)
{
aa_policy_cache *policy_cache = NULL;
int rc;
if ((rc = aa_policy_cache_new(&policy_cache, NULL, AT_FDCWD, location, 0))) {
rc = -errno;
error("Failed to open policy cache '%s': %m", location);
return rc;
}
if (opt_debug) {
/* show hash directory under location that matches the
* current kernel
*/
char *cache_loc = aa_policy_cache_dir_path_preview(NULL, AT_FDCWD, location);
if (!cache_loc) {
rc = -errno;
error("Failed to find cache location '%s': %m", location);
goto out;
}
debug("Loading cache from '%s'\n", cache_loc);
free(cache_loc);
}
if (!opt_dryrun) {
if ((rc = aa_policy_cache_replace_all(policy_cache, NULL)) < 0) {
error("Failed to load policy cache '%s': %m", location);
} else {
verbose("Success - Loaded policy cache '%s'", location);
}
}
out:
aa_policy_cache_unref(policy_cache);
return rc;
}
/**
* load_arg - calls specific load functions for files and directories
*
* load/replace all policy files/dir in arg
*
* Returns: 0 on success, 1 on failure.
*
* It will load by hash subtree first, and fallback to a cache dir
* If not a directory, it will try to load it as a cache file
*/
static int load_arg(char *arg)
{
char **location = NULL;
int i, n, rc = 0;
/* arg can specify an overlay of multiple cache locations */
if ((n = aa_split_overlay_str(arg, &location, 0, true)) == -1) {
error("Failed to parse overlay locations: %m");
return 1;
}
for (i = 0; i < n; i++) {
struct stat st;
debug("Trying to open %s", location[i]);
if (stat(location[i], &st) == -1) {
error("Failed stat of '%s': %m", location[i]);
rc = 1;
continue;
}
if (S_ISDIR(st.st_mode)) {
/* try hash dir subtree first */
if (load_policy_by_hash(location[i]) < 0) {
error("Failed load policy by hash '%s': %m", location[i]);
rc = 1;
}
/* fall back to cache dir */
if (load_policy_dir(location[i]) < 0) {
error("Failed load policy by directory '%s': %m", location[i]);
rc = 1;
}
} else if (load_policy_file(location[i]) < 0) {
rc = 1;
}
}
for (i = 0; i < n; i++)
free(location[i]);
free(location);
return rc;
}
static void print_usage(const char *command)
{
printf("Usage: %s [OPTIONS] (cache file|cache dir|cache base dir)]*\n"
"Load Precompiled AppArmor policy from a cache location or \n"
"locations.\n\n"
"Options:\n"
" -f, --force load policy even if abi does not match the kernel\n"
" -d, --debug display debug messages\n"
" -v, --verbose display progress and error messages\n"
" -n, --dry-run do everything except actual load\n"
" -h, --help this message\n",
command);
}
static const char *short_options = "c:dfvnh";
struct option long_options[] = {
{"config", 1, 0, 'c'},
{"debug", 0, 0, 'd'},
{"force", 0, 0, 'f'},
{"verbose", 0, 0, 'v'},
{"dry-run", 0, 0, 'n'},
{"help", 0, 0, 'h'},
{NULL, 0, 0, 0},
};
static int process_args(int argc, char **argv)
{
int c, o;
opterr = 1;
while ((c = getopt_long(argc, argv, short_options, long_options, &o)) != -1) {
switch(c) {
case 0:
error("error in argument processing\n");
exit(1);
break;
case 'd':
opt_debug = true;
break;
case 'f':
opt_force = true;
break;
case 'v':
opt_verbose = true;
break;
case 'n':
opt_dryrun = true;
break;
case 'h':
print_usage(argv[0]);
exit(0);
break;
case 'c':
/* TODO: reserved config location,
* act as a bad arg for now, when added update usage
*/
//opt_config = true; uncomment when implemented
/* Fall through */
default:
error("unknown argument: '%s'\n\n", optarg);
print_usage(argv[1]);
exit(1);
break;
}
}
return optind;
}
int main(int argc, char **argv)
{
int i, rc = 0;
optind = process_args(argc, argv);
if (!opt_dryrun && have_enough_privilege(argv[0]))
return 1;
/* if no location use the default one */
if (optind == argc) {
if (!opt_config && load_config(DEFAULT_CONFIG_LOCATIONS) == 0) {
verbose("Loaded policy config");
}
if ((rc = load_arg(DEFAULT_POLICY_LOCATIONS)))
verbose("Loading policy from default location '%s'", DEFAULT_POLICY_LOCATIONS);
else
debug("No policy specified, and no policy config or policy in default locations");
}
for (i = optind; i < argc; i++) {
/* Try to load all policy locations even if one fails
* but always return an error if any fail
*/
int tmp = load_arg(argv[i]);
if (!rc)
rc = tmp;
}
return rc;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,293 +0,0 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 13
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
typedef struct cJSON_Hooks
{
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* Check item type and return its value */
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
CJSON_PUBLIC(double) cJSON_GetNumberValue(cJSON *item);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* Create a string where valuestring references a string so
* it will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
/* Create an object/array that only references it's elements so
* they will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items.
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detach items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
* The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
* The input pointer json cannot point to a read-only address area, such as a string constant,
* but should point to a readable and writable adress area. */
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time.
* They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,19 +0,0 @@
# ----------------------------------------------------------------------
# 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)

View File

@@ -1,66 +0,0 @@
# Copyright (C) 2015 Canonical Ltd
# This file is distributed under the same license as the AppArmor package.
# John Johansen <john.johansen@canonical.com>, 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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 ""

View File

@@ -1,73 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Canonical Ltd
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
"POT-Creation-Date: 2020-10-14 03:52-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../aa_enabled.c:21
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -x | --exclusive Shared interfaces must be available\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:37
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:41
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:50
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:54
#, c-format
msgid "Partially - public shared interfaces are not available.\n"
msgstr ""
#: ../aa_enabled.c:58
#, c-format
msgid "Error - %s\n"
msgstr ""
#: ../aa_enabled.c:73
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:87
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:98
#, c-format
msgid "Yes\n"
msgstr ""

View File

@@ -1,55 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Canonical Ltd
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
"POT-Creation-Date: 2020-10-14 03:52-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../aa_exec.c:50
#, c-format
msgid ""
"USAGE: %s [OPTIONS] <prog> <args>\n"
"\n"
"Confine <prog> with the specified PROFILE.\n"
"\n"
"OPTIONS:\n"
" -p PROFILE, --profile=PROFILE\t\tPROFILE to confine <prog> with\n"
" -n NAMESPACE, --namespace=NAMESPACE\tNAMESPACE to confine <prog> in\n"
" -d, --debug\t\t\t\tshow messages with debugging information\n"
" -i, --immediate\t\t\tchange profile immediately instead of at exec\n"
" -v, --verbose\t\t\t\tshow messages with stats\n"
" -h, --help\t\t\t\tdisplay this help\n"
"\n"
msgstr ""
#: ../aa_exec.c:65
#, c-format
msgid "[%ld] aa-exec: ERROR: "
msgstr ""
#: ../aa_exec.c:76
#, c-format
msgid "[%ld] aa-exec: DEBUG: "
msgstr ""
#: ../aa_exec.c:89
#, c-format
msgid "[%ld] "
msgstr ""
#: ../aa_exec.c:107
#, c-format
msgid "[%ld] exec"
msgstr ""

View File

@@ -1,51 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Canonical Ltd
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
"POT-Creation-Date: 2020-10-14 03:52-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../aa_features_abi.c:53
#, c-format
msgid ""
"USAGE: %s [OPTIONS] <SOURCE> [OUTPUT OPTIONS]\n"
"\n"
"Output AppArmor feature abi from SOURCE to OUTPUT\n"
"OPTIONS:\n"
" -d, --debug show messages with debugging information\n"
" -v, --verbose show messages with stats\n"
" -h, --help display this help\n"
"SOURCE:\n"
" -f F, --file=F load features abi from file F\n"
" -x, --extract extract features abi from the kernel\n"
"OUTPUT OPTIONS:\n"
" --stdout default, write features to stdout\n"
" -w F, --write=F write features abi to the file F instead of stdout\n"
"\n"
msgstr ""
#: ../aa_features_abi.c:73
#, c-format
msgid "%s: ERROR: "
msgstr ""
#: ../aa_features_abi.c:85
#, c-format
msgid "%s: DEBUG: "
msgstr ""
#: ../aa_features_abi.c:98
msgid "\n"
msgstr ""

View File

@@ -1,71 +0,0 @@
# Afrikaans translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-03-04 17:55+0000\n"
"Last-Translator: bernard stafford <Unknown>\n"
"Language-Team: Afrikaans <af@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-03-05 05:40+0000\n"
"X-Generator: Launchpad (build e0878392dc799b267dea80578fa65500a5d74155)\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 ""
"%s: [opsies]\n"
" opsies:\n"
" -q | --quiet Moenie druk uit enige boodskappe\n"
" -h | --help Afdruk hulp\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "onbekende of onversoenbare opsies\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "onbekende opsie '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Ja\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Geen - nie beskikbaar op hierdie stelsel.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Nee - gestremde by stewel.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Miskien - beleid koppelvlak nie beskikbaar.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Miskien - onvoldoende toestemmings om beskikbaarheid te bepaal.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Fout - '%s'\n"

View File

@@ -1,73 +0,0 @@
# German translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2018-02-09 23:55+0000\n"
"Last-Translator: Tobias Bannert <tobannert@gmail.com>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
"X-Generator: Launchpad (build 18928)\n"
"Language: de\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 ""
"%s: [Optionen]\n"
" Optionen:\n"
" -q | --quiet Keine Nachrichten anzeigen\n"
" -h | --help Hilfetext anzeigen\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "unbekannte oder nicht kompatible Optionen\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "unbekannte Option »%s«\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Ja\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Nein auf diesem System nicht verfügbar.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Nein beim Start deaktiviert.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Vielleicht Richtlinienschnittstelle nicht verfügbar.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
"Vielleicht ungenügende Berechtigungen, um die Verfügbarkeit zu prüfen\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Fehler »%s«\n"

View File

@@ -1,72 +0,0 @@
# English (United Kingdom) translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2016-02-18 06:22+0000\n"
"Last-Translator: Andi Chandler <Unknown>\n"
"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
"X-Generator: Launchpad (build 18928)\n"
"Language: en_GB\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 ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "unknown or incompatible options\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "unknown option '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Yes\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "No - not available on this system.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "No - disabled at boot.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Maybe - policy interface not available.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Maybe - insufficient permissions to determine availability.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Error - '%s'\n"

View File

@@ -1,71 +0,0 @@
# Spanish translation for apparmor
# Copyright (c) 2019 Rosetta Contributors and Canonical Ltd 2019
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2019-06-09 14:01+0000\n"
"Last-Translator: Adolfo Jayme <fitoschido@gmail.com>\n"
"Language-Team: Spanish <es@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-06-10 04:32+0000\n"
"X-Generator: Launchpad (build 18978)\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 ""
"%s: [opciones]\n"
" opciones:\n"
" -q | --quiet No emitir ningún mensaje\n"
" -h | --help Mostrar la ayuda\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "opciones desconocidas o incompatibles\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "se desconoce la opción «%s»\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Sí\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "No; no disponible en este sistema.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "No; desactivado durante el arranque.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Quizá; interfaz de directiva no disponible.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Quizá; permisos insuficientes para determinar disponibilidad.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Error: «%s»\n"

View File

@@ -1,67 +0,0 @@
# Persian translation for apparmor
# Copyright (c) 2019 Rosetta Contributors and Canonical Ltd 2019
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2019-12-27 08:16+0000\n"
"Last-Translator: VahidNameni <Unknown>\n"
"Language-Team: Persian <fa@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-12-28 05:38+0000\n"
"X-Generator: Launchpad (build bceb5ef013b87ef7aafe0755545ceb689ca7ac60)\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 "تنظیم نامعلوم یا ناسازگار\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "تنظیم '%s' ناشناخته است\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "بله\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "خیر- در این سیستم موجود نیست.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "خیر - غیرفعال در زمان boot.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "شاید - رابط سیاست گذاری در دسترس نیست.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "شاید - دسترسی ناکافی جهت شناسایی در دسترس پذیری.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "خطا - '%s'\n"

View File

@@ -1,67 +0,0 @@
# Finnish translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-01-29 07:44+0000\n"
"Last-Translator: Jiri Grönroos <Unknown>\n"
"Language-Team: Finnish <fi@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-01-30 05:40+0000\n"
"X-Generator: Launchpad (build b8d1327fd820d6bf500589d6da587d5037c7d88e)\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 "tuntemattomat tai yhteensopimattomat valinnat\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "tuntematon valinta '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Kyllä\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Ei - ei käytettävissä tässä järjestelmässä.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Ei - poistettu käytöstä käynnistyksen yhteydessä.\n"
#: ../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 "Virhe - '%s'\n"

View File

@@ -1,72 +0,0 @@
# Indonesian translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2016-01-20 08:59+0000\n"
"Last-Translator: Ari Setyo Wibowo <mr.a.contact@gmail.com>\n"
"Language-Team: Indonesian <id@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
"X-Generator: Launchpad (build 18928)\n"
"Language: id\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 ""
"%s: [options]\n"
" pilihan:\n"
" -q | --quiet Jangan tampilkan pesan apapun\n"
" -h | --help Tampilkan bantuan\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "pilihan yang tidak dikenali atau tidak kompatibel\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "pilihan tidak dikenali '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Ya\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Tidak - tidak tersedia di sistem ini.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Tidak - nonaktifkan saat boot.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Mungkin - kebijakan antarmuka tidak tersedia.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Mungkin - izin tidak memadai untuk menentukan ketersediaan.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Kesalahan - '%s'\n"

View File

@@ -1,72 +0,0 @@
# Portuguese translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2016-03-03 08:34+0000\n"
"Last-Translator: Ivo Xavier <ivofernandes12@gmail.com>\n"
"Language-Team: Portuguese <pt@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
"X-Generator: Launchpad (build 18928)\n"
"Language: pt\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 ""
"%s: [opções]\n"
" opções:\n"
" -q | --silencioso Não mostrar mensagens\n"
" -h | --ajuda Mostar ajuda\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "opções desconhecidas ou incompatíveis\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "opção desconhecida '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Sim\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Não - não disponível neste sistema.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Não - desligado ao iniciar.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Talvez - política de interface não disponível.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Talvez - permissões insuficientes para determinar disponibilidade.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Erro - '%s'\n"

View File

@@ -1,72 +0,0 @@
# Romanian translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-02-20 21:47+0000\n"
"Last-Translator: Daniel Slavu <Unknown>\n"
"Language-Team: Romanian <ro@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-02-21 05:39+0000\n"
"X-Generator: Launchpad (build 19413b719a8df7423ab1390528edadce9e0e4aca)\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 ""
"%s: [opțiuni]\n"
" opțiuni:\n"
" -q | --calm Nu imprima niciun mesaj\n"
" -h | - ajutor Imprimare ajutor\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "opțiuni necunoscute sau incompatibile\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "opțiune necunoscută '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Da\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Nu - nu este disponibil pe acest sistem.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Nu - dezactivat la pornire.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Poate - interfața politică nu este disponibilă.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
"Poate - permisiuni insuficiente pentru a determina disponibilitatea.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Eroare - '%s'\n"

View File

@@ -1,72 +0,0 @@
# Russian translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2016-03-29 14:46+0000\n"
"Last-Translator: Eugene Roskin <Unknown>\n"
"Language-Team: Russian <ru@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
"X-Generator: Launchpad (build 18928)\n"
"Language: ru\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 ""
"%s: [параметры]\n"
" параметры:\n"
" -q | --quiet не выводить никакие сообщения\n"
" -h | --help вывести справку\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "неизвестные или несовместимые параметры\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "неизвестный параметр '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Да\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Нет - недоступно на этой системе.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Нет - выключено при загрузке.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Возможно - интерфейс политики недоступен.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Возможно - недостаточно разрешений для определения доступности.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Ошибка - '%s'\n"

View File

@@ -1,72 +0,0 @@
# Swedish translation for apparmor
# Copyright (c) 2018 Rosetta Contributors and Canonical Ltd 2018
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2018-09-08 03:51+0000\n"
"Last-Translator: Jonatan Nyberg <Unknown>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
"X-Generator: Launchpad (build 18928)\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 ""
"%s: [options]\n"
" flaggor:\n"
" -q | --quiet Skriv inte ut några meddelanden\n"
" -h | --help Skriv ut hjälp\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "okända eller inkompatibla flaggor\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "okänd flagga '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Ja\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Nej - inte tillgänglig på detta system.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Nej - inaktiverad vid uppstart.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Kanske - policy gränssnitt inte tillgängliga.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
"Kanske - otillräckliga behörigheter för att bestämma tillgängligheten.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Fel - '%s'\n"

View File

@@ -1,71 +0,0 @@
# Swahili translation for apparmor
# Copyright (c) 2019 Rosetta Contributors and Canonical Ltd 2019
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2019-11-14 12:33+0000\n"
"Last-Translator: Swahilinux Administration <admin@swahilinux.org>\n"
"Language-Team: Swahili <sw@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-11-15 04:30+0000\n"
"X-Generator: Launchpad (build c597c3229eb023b1e626162d5947141bf7befb13)\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 ""
"%s: [chaguzi]\n"
" chaguzi:\n"
" -q | --quiet Usichapishe jumbe yoyote\n"
" -h | --help Chapisha msaada\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "chaguo lisilojulikana au lisilofaa\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "chaguo lisilojulikana '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Ndio\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "La - haipo kwenye mfumo huu.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "La - ilizimwa kwenye washi.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Labda - kiolesura cha faragha hakipo.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Labda - hamna ruhusa ya kutosha ili kuamua kama ipo.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Dosari - '%s'\n"

View File

@@ -1,72 +0,0 @@
# Turkish translation for apparmor
# Copyright (c) 2018 Rosetta Contributors and Canonical Ltd 2018
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2018-05-19 23:10+0000\n"
"Last-Translator: Kudret EMRE <kudretemre@hotmail.com>\n"
"Language-Team: Turkish <tr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
"X-Generator: Launchpad (build 18928)\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 ""
"%s: [seçenekler]\n"
" seçenekler:\n"
" -q | --quiet Hiçbir mesajı gösterme\n"
" -h | --help Yardımı görüntüler\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "bilinmeyen veya uyumsuz seçenekler\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "bilinmeyen seçenek '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Evet\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Hayır - Bu sistemde kullanılabilir değil.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Hayır - önyüklemede devredışı bırakıldı.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Belki - policy arayüzü kullanılabilir değil.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
"Belki - kullanılabilir olup olmadığını denetlemek için yetersiz yetki.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Hata - '%s'\n"

View File

@@ -1,6 +1,5 @@
# ----------------------------------------------------------------------
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
# Copyright (c) 2016 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
@@ -18,7 +17,13 @@ NAME:=apache2-mod_apparmor
all:
COMMONDIR=../../common/
include $(COMMONDIR)/Make.rules
include common/Make.rules
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
common/Make.rules: $(COMMONDIR)/Make.rules
ln -sf $(COMMONDIR) .
endif
TARGET:=mod_apparmor.so
MANPAGES=mod_apparmor.8
@@ -36,65 +41,24 @@ APXS:=$(shell if [ -x "/usr/sbin/apxs2" ] ; then \
fi )
APXS_INSTALL_DIR=$(shell ${APXS} -q LIBEXECDIR)
DESTDIR=
ifdef USE_SYSTEM
LIBAPPARMOR = $(shell if pkg-config --exists libapparmor ; then \
pkg-config --silence-errors --libs libapparmor ; \
elif ldconfig -p | grep -q libapparmor\.so$$ ; then \
echo -lapparmor ; \
fi )
ifeq ($(strip $(LIBAPPARMOR)),)
ERROR_MESSAGE = $(error ${nl}\
************************************************************************${nl}\
Unable to find libapparmor installed on this system; either${nl}\
install libapparmor devel packages, set the LIBAPPARMOR variable${nl}\
manually, or build against in-tree libapparmor.${nl}\
************************************************************************${nl})
endif # LIBAPPARMOR not set
LDLIBS += $(LIBAPPARMOR)
else
LIBAPPARMOR_SRC := ../../libraries/libapparmor/
LIBAPPARMOR_INCLUDE = $(LIBAPPARMOR_SRC)/include
LIBAPPARMOR_PATH := $(LIBAPPARMOR_SRC)/src/.libs/
ifeq ($(realpath $(LIBAPPARMOR_PATH)/libapparmor.a),)
ERROR_MESSAGE = $(error ${nl}\
************************************************************************${nl}\
$(LIBAPPARMOR_PATH)/libapparmor.a is missing; either build against${nl}\
the in-tree libapparmor by building it first and then trying again${nl}\
(see the top-level README for help) or build against the system${nl}\
libapparmor by adding USE_SYSTEM=1 to your make command.${nl}\
************************************************************************${nl})
endif
# Need to pass -Wl twice here to get past both apxs2 and libtool, as
# libtool will add the path to the RPATH of the library if passed -L/some/path
LIBAPPARMOR_FLAGS = -I$(LIBAPPARMOR_INCLUDE) -Wl,-Wl,-L$(LIBAPPARMOR_PATH)
LDLIBS = -lapparmor
endif
# Need to pass -Wl twice here to get past both apxs2 and libtool, as
# libtool will add the path to the RPATH of the library if passed -L/some/path
LIBAPPARMOR_FLAGS=-I../../libraries/libapparmor/src -Wl,-Wl,-L../../libraries/libapparmor/src/.libs
LDLIBS=-lapparmor
APXS_CFLAGS="-Wc,$(EXTRA_WARNINGS)"
.PHONY: libapparmor_check
.SILENT: libapparmor_check
libapparmor_check: ; $(ERROR_MESSAGE)
all: libapparmor_check $(TARGET) docs
.PHONY: docs
docs: ${MANPAGES} ${HTMLMANPAGES}
all: $(TARGET) ${MANPAGES} ${HTMLMANPAGES}
%.so: %.c
${APXS} ${LIBAPPARMOR_FLAGS} ${APXS_CFLAGS} -c $< ${LDLIBS}
${APXS} ${LIBAPPARMOR_FLAGS} -c $< ${LDLIBS}
mv .libs/$@ .
.PHONY: install
install: ${TARGET} ${MANPAGES}
mkdir -p ${DESTDIR}/${APXS_INSTALL_DIR}
install -m 755 $< ${DESTDIR}/${APXS_INSTALL_DIR}
$(MAKE) install_manpages DESTDIR=${DESTDIR}
make install_manpages DESTDIR=${DESTDIR}
.PHONY: clean
clean: pod_clean
clean: _clean
rm -rf .libs
rm -f *.la *.lo *.so *.o *.slo
.PHONY: check
check: check_pod_files
rm -f *.la *.lo *.so *.o *.slo Make.rules

View File

@@ -0,0 +1,215 @@
# ----------------------------------------------------------------------
# Copyright (c) 2004, 2005 NOVELL (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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
# norootforbuild
# Check first to see if distro is already defined.
# I hate rpm macros
%if ! %{?distro:1}0
%if %{?suse_version:1}0
%define distro suse
%endif
%if %{?fedora_version:1}0
%define distro redhat
%endif
%endif
%if ! %{?distro:1}0
%define distro suse
%endif
# this is required to be underscore
%define module_name mod_apparmor
Summary: AppArmor module for apache2.
Name: apache2-mod_apparmor
Version: @@immunix_version@@
Release: @@repo_version@@
Group: Applications/System
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
License: LGPL
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
Url: http://forge.novell.com/modules/xfmod/project/?apparmor
Obsoletes: mod_change_hat mod-change-hat mod-apparmor apache2-mod-apparmor
Provides: mod_change_hat mod-change-hat mod-apparmor apache2-mod-apparmor
%if %{distro} == "suse"
%if 0%{?suse_version} < 1010
BuildRequires: libimmunix
%else
%if 0%{?suse_version} < 1030
BuildRequires: libapparmor
%else
BuildRequires: libapparmor-devel
%endif
%endif
%else
BuildRequires: libapparmor-devel
%endif
%if %{distro} == "suse"
%define apxs /usr/sbin/apxs2
%define apache_mmn %(MMN=$(%{apxs} -q LIBEXECDIR)_MMN; test -x $MMN && $MMN)
Prereq: apache2-prefork
Prereq: apparmor-parser
BuildRequires: apache2-devel
Requires: apache2 %{apache_mmn}
%else
%if %{distro} == "redhat" || %{distro} == "rhel4"
%define apxs /usr/sbin/apxs
Prereq: httpd
BuildRequires: httpd-devel
%endif
%endif
%define module_path %(%{apxs} -q LIBEXECDIR)
%define apache_sysconfdir %(%{apxs} -q SYSCONFDIR)
%description
apache2-mod_apparmor adds support to apache2 to provide AppArmor confinement
to individual cgi scripts handled by apache modules like mod_php and
mod_perl.
This package is part of a suite of tools that used to be named SubDomain.
%prep
%setup -q
%build
make APXS=%{apxs}
%install
make install DESTDIR=${RPM_BUILD_ROOT} DISTRO=%{distro} MANDIR=%{_mandir}
%if %{distro} == "suse"
mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/apache2-prefork/
ln -s %{module_path}/%{module_name}.so ${RPM_BUILD_ROOT}%{_libdir}/apache2-prefork/%{module_name}.so
%else
%if %{distro} == "redhat" || %{distro} == "rhel4"
mkdir -p ${RPM_BUILD_ROOT}/%{apache_sysconfdir}.d/
install -m 644 %{module_name}.conf ${RPM_BUILD_ROOT}/%{apache_sysconfdir}.d/
%endif
%endif
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{module_path}
%if %{distro} == "suse"
%{_libdir}/apache2-prefork/%{module_name}.so
%else
%if %{distro} == "redhat" || %{distro} == "rhel4"
%{apache_sysconfdir}.d/%{module_name}.conf
%endif
%endif
%doc COPYING.LGPL
%{_mandir}/man*/*
%doc *.[0-9].html
%doc common/apparmor.css
%post
%if %{distro} == "suse"
/usr/sbin/a2enmod apparmor
%endif
%preun
%if %{distro} == "suse"
if [ $1 = 0 ] ; then
/usr/sbin/a2dismod apparmor
fi
%endif
%triggerpostun -- mod_change_hat mod-change-hat
%if %{distro} == "suse"
/usr/sbin/a2enmod apparmor
%endif
%changelog
* Sun Jul 29 2007 - sbeattie@suse.de
- Convert builddep on libapparmor to libapparmor-devel
* Tue Apr 3 2007 - sbeattie@suse.de
- Add mod_apparmor manpage to package
* Wed Sep 06 2006 - poeml@suse.de
- rename to apache2-mod_apparmor
- use a2enmod instead of frob_sysconfig
- remove SuSEconfig calls
* Fri May 26 2006 - schwab@suse.de
- Don't strip binaries.
* Wed Apr 12 2006 - Steve Beattie <sbeattie@suse.de>
- Move to novell forge svn repo; fix build issue with new layout
* Thu Mar 30 2006 - Seth Arnold <seth.arnold@suse.de> 2.0-7.2
- Relicense to LGPL
* Mon Jan 30 2006 - Steve Beattie <sbeattie@suse.de> 2.0-7.1
- Renamed apache config options:
ImmhatName -> AAHatName
ImmDefaultHatName -> AADefaultHatName
* Mon Jan 30 2006 - poeml@suse.de
- removed libapr-util1-devel from BuildRequires (apache2-devel does
require it)
* Fri Jan 27 2006 Steve Beattie <sbeattie@suse.de> 2.0-6.1
- No more neededforbuild in STABLE
* Wed Jan 25 2006 Steve Beattie <sbeattie@suse.de> 2.0-6
- Fix linking against libapparmor.so
* Sun Jan 8 2006 Steve Beattie <sbeattie@suse.de> 2.0-5
- More SUSE autobuild fixups.
* Wed Jan 4 2006 Steve Beattie <sbeattie@suse.de> 2.0-4
- Fixup SUSE autobuild require on apache-devel-packages
- Add svn revision to the source tarball
* Sun Dec 18 2005 Steve Beattie <sbeattie@novell.com> 2.0-3
- Include symlink in %{_libdir}/apache2-prefork/
* Thu Dec 8 2005 Steve Beattie <sbeattie@novell.com> 2.0-2
- Rename to apache2-mod-apparmor for consistency w/SUSE packages
- Rename module to mod_apparmor.so
* Wed Dec 7 2005 Steve Beattie <sbeattie@novell.com> 2.0-1
- Reset version for inclusion in SUSE autobuild
* Mon Dec 5 2005 Steve Beattie <sbeattie@novell.com> 1.99-9
- Rename package to mod-apparmor
* Wed Nov 30 2005 Steve Beattie <sbeattie@novell.com> 1.99-8
- Minor packaging cleanups
* Wed Nov 30 2005 Steve Beattie <sbeattie@novell.com> 1.99-7_imnx
- Convert license to GPL
* Thu Jun 23 2005 Steve Beattie <sbeattie@novell.com> 1.99-6_imnx
- Add trigger for mod_change_hat => mod-change-hat upgrades
- Don't run SuSEconfig on SuSE 9.3 or newer
* Mon May 23 2005 Steve Beattie <sbeattie@novell.com> 1.99-5_imnx
- Fix package uninstall on RHEL4.
* Fri Mar 11 2005 Steve Beattie <steve@immunix.com> 1.99-4_imnx
- Rename to be consistent with other packages
* Fri Feb 18 2005 Steve Beattie <steve@immunix.com> 1.99-3_imnx
- Cleanup some non-64bit clean code, sigh.
- Fix install locations on 64-bit platform.
* Fri Feb 4 2005 Seth Arnold <sarnold@immunix.coM> 1.99-1_imnx
- Reversion to 1.99
* Fri Nov 12 2004 Steve Beattie <steve@immunix.com> 1.2-2_imnx
- Add configuration file for redhat build
* Tue Oct 12 2004 Steve Beattie <steve@immunix.com> 1.2-1_imnx
- Bump version after shass-1.1 branched off
* Mon Sep 20 2004 Dominic Reynolds <dominic@immunix.com> 1.0-7_imnx_(redhat|suse)
- Modified to build separate versions for suse/redhat (EL3).
- Note:RH version does not currently setup the module configuraiton
- in apache.
* Tue Aug 31 2004 Steve Beattie <steve@immunix.com> 1.0-6_imnx
- Got location and per server config directives working somewhat
correctly :-)
- copyright fixups.
* Fri Aug 20 2004 Steve Beattie <steve@immunix.com> 1.0-5_imnx
- added support for <Location> hatname </Location>
* Wed Jul 21 2004 Steve Beattie <steve@immunix.com> 1.0-4_imnx
- reduced loglevel of some debug messages
- add change_hat to list of apache modules
* Tue Jul 20 2004 Steve Beattie <steve@immunix.com> 1.0-2_imnx
- got module actually working, at least in simple cases.
* Thu Jul 15 2004 Steve Beattie <steve@immunix.com> 1.0-1_imnx
- Initial package creation.

View File

@@ -1,13 +1,12 @@
/*
* Copyright (c) 2004, 2005, 2006 NOVELL (All rights reserved)
* Copyright (c) 2014 Canonical, Ltd. (All rights reserved)
*
* The mod_apparmor module is licensed under the terms of the GNU
* Lesser General Public License, version 2.1. Please see the file
* COPYING.LGPL.
*
* mod_apparmor - (apache 2.0.x)
* Author: Steve Beattie <steve@nxnw.org>
* Author: Steve Beattie <sbeattie@suse.de>
*
* This currently only implements change_hat functionality, but could be
* extended for other stuff we decide to do.
@@ -18,244 +17,183 @@
#include "http_config.h"
#include "http_request.h"
#include "http_log.h"
#include "http_main.h"
#include "http_protocol.h"
#include "util_filter.h"
#include "apr.h"
#include "apr_strings.h"
#include "apr_lib.h"
#include <sys/apparmor.h>
#include <apparmor.h>
#include <unistd.h>
/* #define DEBUG */
#ifndef unused_
#define unused_ __attribute__ ((unused))
#ifndef __unused
#define __unused __attribute__((unused))
#endif
/* should the following be configurable? */
#define DEFAULT_HAT "HANDLING_UNTRUSTED_INPUT"
#define DEFAULT_URI_HAT "DEFAULT_URI"
/* Compatibility with apache 2.2 */
#if AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER < 3
#define APLOG_TRACE1 APLOG_DEBUG
server_rec *ap_server_conf = NULL;
#endif
#ifdef APLOG_USE_MODULE
APLOG_USE_MODULE(apparmor);
#endif
module AP_MODULE_DECLARE_DATA apparmor_module;
static unsigned long magic_token = 0;
static unsigned int magic_token = 0;
static int inside_default_hat = 0;
typedef struct {
const char *hat_name;
char *path;
} apparmor_dir_cfg;
const char * hat_name;
char * path;
} immunix_dir_cfg;
typedef struct {
const char *hat_name;
int is_initialized;
} apparmor_srv_cfg;
const char * hat_name;
int is_initialized;
} immunix_srv_cfg;
/* aa_init() gets invoked in the post_config stage of apache.
/* immunix_init() gets invoked in the post_config stage of apache.
* Unfortunately, apache reads its config once when it starts up, then
* it re-reads it when goes into its restart loop, where it starts it's
* children. This means we cannot call change_hat here, as the modules
* memory will be wiped out, and the magic_token will be lost, so apache
* wouldn't be able to change_hat back out. */
static int
aa_init(apr_pool_t *p, unused_ apr_pool_t *plog, unused_ apr_pool_t *ptemp, unused_ server_rec *s)
static int
immunix_init (apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
apr_file_t *file;
apr_size_t size = sizeof(magic_token);
apr_file_t * file;
apr_size_t size = sizeof (magic_token);
int ret;
ret = apr_file_open (&file, "/dev/urandom", APR_READ, APR_OS_DEFAULT, p);
if (!ret) {
apr_file_read(file, (void *) &magic_token, &size);
apr_file_close(file);
apr_file_read (file, (void *) &magic_token, &size);
apr_file_close (file);
} else {
ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
"Failed to open /dev/urandom");
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Failed to open /dev/urandom");
}
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
"Opened /dev/urandom successfully");
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "Opened /dev/urandom successfully");
return OK;
}
/* As each child starts up, we'll change_hat into a default hat, mostly
* to protect ourselves from bugs in parsing network input, but before
* we change_hat to the uri specific hat. */
static void
aa_child_init(unused_ apr_pool_t *p, unused_ server_rec *s)
static void
immunix_child_init (apr_pool_t *p, server_rec *s)
{
int ret;
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
"init: calling change_hat with '%s'", DEFAULT_HAT);
ret = aa_change_hat(DEFAULT_HAT, magic_token);
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "init: calling change_hat");
ret = change_hat (DEFAULT_HAT, magic_token);
if (ret < 0) {
ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
"Failed to change_hat to '%s'", DEFAULT_HAT);
change_hat (NULL, magic_token);
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Failed to change_hat to '%s'",
DEFAULT_HAT);
} else {
inside_default_hat = 1;
}
}
}
#ifdef DEBUG
static void
debug_dump_uri(request_rec *r)
debug_dump_uri (apr_uri_t * uri)
{
apr_uri_t *uri = &r->parsed_uri;
if (uri)
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Dumping uri info "
"scheme='%s' host='%s' path='%s' query='%s' fragment='%s'",
uri->scheme, uri->hostname, uri->path, uri->query,
uri->fragment);
if (uri)
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Dumping uri info "
"scheme='%s' host='%s' path='%s' query='%s' fragment='%s'",
uri->scheme, uri->hostname, uri->path, uri->query,
uri->fragment);
else
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Asked to dump NULL uri");
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Asked to dump NULL uri");
}
/*
aa_enter_hat will attempt to change_hat in the following order:
#else
static void
debug_dump_uri (apr_uri_t * __unused uri) { }
#endif
/*
immunix_enter_hat will attempt to change_hat in the following order:
(1) to a hatname in a location directive
(2) to the server name or a defined per-server default
(3) to the server name + "-" + uri
(4) to the uri
(5) to DEFAULT_URI
(6) back to the parent profile
(2) to the uri
(3) to a per-server default
(4) to DEFAULT_URI
(5) back to the parent profile
*/
static int
aa_enter_hat(request_rec *r)
static int
immunix_enter_hat (request_rec *r)
{
int aa_ret = -1;
apparmor_dir_cfg *dcfg = (apparmor_dir_cfg *)
ap_get_module_config(r->per_dir_config, &apparmor_module);
apparmor_srv_cfg *scfg = (apparmor_srv_cfg *)
ap_get_module_config(r->server->module_config, &apparmor_module);
const char *aa_hat_array[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
int i = 0;
char *aa_label, *aa_mode, *aa_hat;
const char *vhost_uri;
int sd_ret = -1;
immunix_dir_cfg * dcfg = (immunix_dir_cfg *)
ap_get_module_config (r->per_dir_config, &apparmor_module);
immunix_srv_cfg * scfg = (immunix_srv_cfg *)
ap_get_module_config (r->server->module_config, &apparmor_module);
debug_dump_uri(r);
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "aa_enter_hat (%s) n:0x%lx p:0x%lx main:0x%lx",
dcfg->path, (unsigned long) r->next, (unsigned long) r->prev,
(unsigned long) r->main);
debug_dump_uri (&r->parsed_uri);
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_enter_hat (%s) n:0x%lx p:0x%lx main:0x%lx",
dcfg->path, (unsigned long) r->next, (unsigned long) r->prev,
(unsigned long) r->main);
/* We only call change_hat for the main request, not subrequests */
if (r->main)
return OK;
if (r->main)
return OK;
if (inside_default_hat) {
aa_change_hat(NULL, magic_token);
inside_default_hat = 0;
change_hat (NULL, magic_token);
inside_default_hat = 0;
}
if (dcfg != NULL && dcfg->hat_name != NULL) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"[dcfg] adding hat '%s' to aa_change_hat vector", dcfg->hat_name);
aa_hat_array[i++] = dcfg->hat_name;
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat [dcfg] %s", dcfg->hat_name);
sd_ret = change_hat (dcfg->hat_name, magic_token);
if (sd_ret < 0) {
change_hat (NULL, magic_token);
} else {
return OK;
}
}
if (scfg) {
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Dumping scfg info: "
"scfg='0x%lx' scfg->hat_name='%s'",
(unsigned long) scfg, scfg->hat_name);
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat [uri] %s", r->uri);
sd_ret = change_hat (r->uri, magic_token);
if (sd_ret < 0) {
change_hat (NULL, magic_token);
} else {
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "scfg is null");
}
if (scfg != NULL) {
if (scfg->hat_name != NULL) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"[scfg] adding hat '%s' to aa_change_hat vector", scfg->hat_name);
aa_hat_array[i++] = scfg->hat_name;
} else {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"[scfg] adding server_name '%s' to aa_change_hat vector",
r->server->server_hostname);
aa_hat_array[i++] = r->server->server_hostname;
}
vhost_uri = apr_pstrcat(r->pool, r->server->server_hostname, "-", r->uri, NULL);
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"[vhost+uri] adding vhost+uri '%s' to aa_change_hat vector", vhost_uri);
aa_hat_array[i++] = vhost_uri;
return OK;
}
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"[uri] adding uri '%s' to aa_change_hat vector", r->uri);
aa_hat_array[i++] = r->uri;
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"[default] adding '%s' to aa_change_hat vector", DEFAULT_URI_HAT);
aa_hat_array[i++] = DEFAULT_URI_HAT;
aa_ret = aa_change_hatv(aa_hat_array, magic_token);
if (aa_ret < 0) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, errno, r, "aa_change_hatv call failed");
if (scfg != NULL && scfg->hat_name != NULL) {
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat [scfg] %s", scfg->hat_name);
sd_ret = change_hat (scfg->hat_name, magic_token);
if (sd_ret < 0) {
change_hat (NULL, magic_token);
} else {
return OK;
}
}
/* Check to see if a defined AAHatName or AADefaultHatName would
* apply, but wasn't the hat we landed up in; report a warning if
* that's the case. */
aa_ret = aa_getcon(&aa_label, &aa_mode);
if (aa_ret < 0) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, errno, r, "aa_getcon call failed");
} else {
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
"AA checks: aa_getcon result is '%s', mode '%s'", aa_label, aa_mode);
/* TODO: use libapparmor get hat_name fn here once it is implemented */
aa_hat = strstr(aa_label, "//");
if (aa_hat != NULL && strcmp(aa_mode, "enforce") == 0) {
aa_hat += 2; /* skip "//" */
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
"AA checks: apache is in hat '%s', mode '%s'", aa_hat, aa_mode);
if (dcfg != NULL && dcfg->hat_name != NULL) {
if (strcmp(aa_hat, dcfg->hat_name) != 0)
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
"AAHatName '%s' applies, but does not appear to be a hat in the apache apparmor policy",
dcfg->hat_name);
} else if (scfg != NULL && scfg->hat_name != NULL) {
if (strcmp(aa_hat, scfg->hat_name) != 0 &&
strcmp(aa_hat, r->uri) != 0)
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
"AADefaultHatName '%s' applies, but does not appear to be a hat in the apache apparmor policy",
scfg->hat_name);
}
}
free(aa_label);
}
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat DEFAULT_URI");
sd_ret = change_hat (DEFAULT_URI_HAT, magic_token);
if (sd_ret < 0) change_hat (NULL, magic_token);
return OK;
}
static int
aa_exit_hat(request_rec *r)
static int
immunix_exit_hat (request_rec *r)
{
int aa_ret;
apparmor_dir_cfg *dcfg = (apparmor_dir_cfg *)
ap_get_module_config(r->per_dir_config, &apparmor_module);
/* apparmor_srv_cfg *scfg = (apparmor_srv_cfg *)
ap_get_module_config(r->server->module_config, &apparmor_module); */
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "exiting change_hat: dir hat %s dir path %s",
dcfg->hat_name, dcfg->path);
int sd_ret;
immunix_dir_cfg * dcfg = (immunix_dir_cfg *)
ap_get_module_config (r->per_dir_config, &apparmor_module);
/* immunix_srv_cfg * scfg = (immunix_srv_cfg *)
ap_get_module_config (r->server->module_config, &apparmor_module); */
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "exiting change_hat - dir hat %s path %s", dcfg->hat_name, dcfg->path);
change_hat (NULL, magic_token);
/* can convert the following back to aa_change_hat() when the
* aa_change_hat() bug addressed in trunk commit 2329 lands in most
* system libapparmors */
aa_change_hatv(NULL, magic_token);
aa_ret = aa_change_hat(DEFAULT_HAT, magic_token);
if (aa_ret < 0) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r,
"Failed to change_hat to '%s'", DEFAULT_HAT);
sd_ret = change_hat (DEFAULT_HAT, magic_token);
if (sd_ret < 0) {
change_hat (NULL, magic_token);
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Failed to change_hat to '%s'",
DEFAULT_HAT);
} else {
inside_default_hat = 1;
}
@@ -264,15 +202,15 @@ aa_exit_hat(request_rec *r)
}
static const char *
aa_cmd_ch_path(unused_ cmd_parms *cmd, unused_ void *mconfig, const char *parm1)
aa_cmd_ch_path (cmd_parms * cmd, void * mconfig, const char * parm1)
{
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, "directory config change hat %s",
parm1 ? parm1 : "DEFAULT");
apparmor_dir_cfg *dcfg = mconfig;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "config change hat %s",
parm1 ? parm1 : "DEFAULT");
immunix_dir_cfg * dcfg = mconfig;
if (parm1 != NULL) {
dcfg->hat_name = parm1;
dcfg->hat_name = parm1;
} else {
dcfg->hat_name = "DEFAULT";
dcfg->hat_name = "DEFAULT";
}
return NULL;
}
@@ -280,27 +218,26 @@ aa_cmd_ch_path(unused_ cmd_parms *cmd, unused_ void *mconfig, const char *parm1)
static int path_warn_once;
static const char *
immunix_cmd_ch_path(cmd_parms *cmd, void *mconfig, const char *parm1)
immunix_cmd_ch_path (cmd_parms * cmd, void * mconfig, const char * parm1)
{
if (path_warn_once == 0) {
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, "ImmHatName is "
"deprecated, please use AAHatName instead");
path_warn_once = 1;
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "ImmHatName is "
"deprecated, please use AAHatName instead");
path_warn_once = 1;
}
return aa_cmd_ch_path(cmd, mconfig, parm1);
}
static const char *
aa_cmd_ch_srv(cmd_parms *cmd, unused_ void *mconfig, const char *parm1)
aa_cmd_ch_srv (cmd_parms * cmd, void * mconfig, const char * parm1)
{
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, "server config change hat %s",
parm1 ? parm1 : "DEFAULT");
apparmor_srv_cfg *scfg = (apparmor_srv_cfg *)
ap_get_module_config(cmd->server->module_config, &apparmor_module);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "config change hat %s",
parm1 ? parm1 : "DEFAULT");
immunix_srv_cfg * scfg = mconfig;
if (parm1 != NULL) {
scfg->hat_name = parm1;
scfg->hat_name = parm1;
} else {
scfg->hat_name = "DEFAULT";
scfg->hat_name = "DEFAULT";
}
return NULL;
}
@@ -308,29 +245,27 @@ aa_cmd_ch_srv(cmd_parms *cmd, unused_ void *mconfig, const char *parm1)
static int srv_warn_once;
static const char *
immunix_cmd_ch_srv(cmd_parms *cmd, void *mconfig, const char *parm1)
immunix_cmd_ch_srv (cmd_parms * cmd, void * mconfig, const char * parm1)
{
if (srv_warn_once == 0) {
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, "ImmDefaultHatName is "
"deprecated, please use AADefaultHatName instead");
srv_warn_once = 1;
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "ImmDefaultHatName is "
"deprecated, please use AADefaultHatName instead");
srv_warn_once = 1;
}
return aa_cmd_ch_srv(cmd, mconfig, parm1);
}
static void *
aa_create_dir_config(apr_pool_t *p, char *path)
immunix_create_dir_config (apr_pool_t * p, char * path)
{
apparmor_dir_cfg *newcfg = (apparmor_dir_cfg *) apr_pcalloc(p, sizeof(*newcfg));
immunix_dir_cfg * newcfg = (immunix_dir_cfg *) apr_pcalloc(p, sizeof(* newcfg));
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
"aa_create_dir_cfg (%s)", path ? path : ":no path:");
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_create_dir (%s)", path ? path : ":no path:");
if (newcfg == NULL) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
"aa_create_dir_config: couldn't alloc dir config");
return NULL;
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "immunix_create_dir: couldn't alloc dir config");
return NULL;
}
newcfg->path = apr_pstrdup(p, path ? path : ":no path:");
newcfg->path = apr_pstrdup (p, path ? path : ":no path:");
return newcfg;
}
@@ -338,85 +273,83 @@ aa_create_dir_config(apr_pool_t *p, char *path)
/* XXX: Should figure out an appropriate action to take here, if any
static void *
aa_merge_dir_config(apr_pool_t *p, void *parent, void *child)
immunix_merge_dir_config (apr_pool_t * p, void * parent, void * child)
{
apparmor_dir_cfg *newcfg = (apparmor_dir_cfg *) apr_pcalloc(p, sizeof(*newcfg));
immunix_dir_cfg * newcfg = (immunix_dir_cfg *) apr_pcalloc(p, sizeof(* newcfg));
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf, "in immunix_merge_dir ()");
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_merge_dir ()");
if (newcfg == NULL)
return NULL;
return NULL;
return newcfg;
}
*/
static void *
aa_create_srv_config(apr_pool_t *p, unused_ server_rec *srv)
immunix_create_srv_config (apr_pool_t * p, server_rec * srv)
{
apparmor_srv_cfg *newcfg = (apparmor_srv_cfg *) apr_pcalloc(p, sizeof(*newcfg));
immunix_srv_cfg * newcfg = (immunix_srv_cfg *) apr_pcalloc(p, sizeof(* newcfg));
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
"in aa_create_srv_config");
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_create_srv");
if (newcfg == NULL) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
"aa_create_srv_config: couldn't alloc srv config");
return NULL;
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "immunix_create_srv: couldn't alloc srv config");
return NULL;
}
return newcfg;
}
static const command_rec mod_apparmor_cmds[] = {
static const command_rec immunix_cmds[] = {
AP_INIT_TAKE1(
AP_INIT_TAKE1 (
"ImmHatName",
immunix_cmd_ch_path,
NULL,
ACCESS_CONF,
""
immunix_cmd_ch_path,
NULL,
ACCESS_CONF,
""
),
AP_INIT_TAKE1(
AP_INIT_TAKE1 (
"ImmDefaultHatName",
immunix_cmd_ch_srv,
NULL,
RSRC_CONF,
""
immunix_cmd_ch_srv,
NULL,
RSRC_CONF,
""
),
AP_INIT_TAKE1(
AP_INIT_TAKE1 (
"AAHatName",
aa_cmd_ch_path,
NULL,
ACCESS_CONF,
""
aa_cmd_ch_path,
NULL,
ACCESS_CONF,
""
),
AP_INIT_TAKE1(
AP_INIT_TAKE1 (
"AADefaultHatName",
aa_cmd_ch_srv,
NULL,
RSRC_CONF,
""
aa_cmd_ch_srv,
NULL,
RSRC_CONF,
""
),
{ NULL }
};
static void
register_hooks(unused_ apr_pool_t *p)
static void
register_hooks (apr_pool_t *p)
{
ap_hook_post_config(aa_init, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_child_init(aa_child_init, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_access_checker(aa_enter_hat, NULL, NULL, APR_HOOK_FIRST);
/* ap_hook_post_read_request(aa_enter_hat, NULL, NULL, APR_HOOK_FIRST); */
ap_hook_log_transaction(aa_exit_hat, NULL, NULL, APR_HOOK_LAST);
ap_hook_post_config (immunix_init, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_child_init (immunix_child_init, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_access_checker(immunix_enter_hat, NULL, NULL, APR_HOOK_FIRST);
/* ap_hook_post_read_request(immunix_enter_hat, NULL, NULL, APR_HOOK_FIRST); */
ap_hook_log_transaction(immunix_exit_hat, NULL, NULL, APR_HOOK_LAST);
}
module AP_MODULE_DECLARE_DATA apparmor_module = {
STANDARD20_MODULE_STUFF,
aa_create_dir_config, /* dir config creator */
NULL, /* dir merger --- default is to override */
/* immunix_merge_dir_config, */ /* dir merger --- default is to override */
aa_create_srv_config, /* server config */
NULL, /* merge server config */
mod_apparmor_cmds, /* command table */
register_hooks /* register hooks */
immunix_create_dir_config, /* dir config creater */
NULL, /* dir merger --- default is to override */
/* immunix_merge_dir_config, */ /* dir merger --- default is to override */
immunix_create_srv_config, /* server config */
NULL, /* merge server config */
immunix_cmds, /* command table */
register_hooks /* register hooks */
};

View File

@@ -40,15 +40,11 @@ apache2(8)/httpd(8) configuration files, and restart Apache. Make sure that
apparmor is also functioning.
Once mod_apparmor is loaded within Apache, all requests to Apache will
cause mod_apparmor to attempt to change into a hat that matches the
ServerName for the server/vhost. If no such hat is found, it will
first fall back by attempting to change into a hat composed of the
ServerName-URI (e.g. "www.example.com-/app/some.cgi"). If that hat
is not found, it will fall back to attempting to use the hat named
by the URI (e.g. "/app/some.cgi"). If that hat is not found, it will
fall back to attempting to use the hat DEFAULT_URI; if that also does
not exist, it will fall back to using the global Apache profile. Most
static web pages can simply make use of the DEFAULT_URI hat.
cause mod_apparmor to attempt to change into a hat named by the URI
(e.g. /app/some.cgi). If no such hat is found, it will fall back to
attempting to use the hat DEFAULT_URI; if that also does not exist,
it will fall back to using the global Apache profile. Most static web
pages can simply make use of the DEFAULT_URI hat.
Additionally, before any requests come in to Apache, mod_apparmor
will attempt to change hat into the HANDLING_UNTRUSTED_INPUT hat.
@@ -64,8 +60,8 @@ provides the AAHatName and AADefaultHatName Apache configuration options.
=item B<AAHatName>
AAHatName allows you to specify a hat to be used for a given Apache
E<lt>DirectoryE<gt>, E<lt>DirectoryMatchE<gt>, E<lt>LocationE<gt> or
E<lt>LocationMatchE<gt> directive (see the Apache documentation for more
E<lt>DirectoryE<gt>, E<lt>DirectoryMatch>, E<lt>LocationE<gt> or
E<lt>LocationMatchE<gt> directive (see the Apache documenation for more
details). Note that mod_apparmor behavior can become confused if
E<lt>Directory*E<gt> and E<lt>Location*E<gt> directives are intermingled
and it is recommended to use one type of directive. If the hat specified by
@@ -76,11 +72,11 @@ behavior described above.
AADefaultHatName allows you to specify a default hat to be used for
virtual hosts and other Apache server directives, so that you can have
different defaults for different virtual hosts. This can be overridden
by the AAHatName directive and is checked for only if there isn't
a matching AAHatName. The default value of AADefaultHatName is the
ServerName for the server/vhost configuration. If the AADefaultHatName
hat does not exist, then it falls back to the behavior described above.
different defaults for different virtual hosts. This can be overridden by
the AAHatName directive and is checked for only if there isn't a matching
AAHatName or hat named by the URI. If the AADefaultHatName hat does not
exist, it falls back to the DEFAULT_URI hat if it exists (as described
above).
=back
@@ -95,35 +91,20 @@ On each URI request, mod_apparmor will first aa_change_hat(2) into
Then, after performing the initial parsing of the request, mod_apparmor
will:
=over 4
=over 2
=item 1
try to aa_change_hat(2) into a matching AAHatName hat if it exists and
1. try to aa_change_hat(2) into a matching AAHatName hat if it exists and
applies, otherwise it will
=item 2
2. try to aa_change_hat(2) into the URI itself, otherwise it will
try to aa_change_hat(2) into an AADefaultHatName hat, either the
ServerName (the default) or the configuration value specified by the
AADefaultHatName directive, for the server/vhost, otherwise it will
3. try to aa_change_hat(2) into an AADefaultHatName hat if it has been defined
for the server/vhost, otherwise it will
=item 3
try to aa_change_hat(2) into the ServerName-URI, otherwise it will
=item 4
try to aa_change_hat(2) into the URI itself, otherwise it will
=item 5
try to aa_change_hat(2) into the DEFAULT_URI hat, if it exists, otherwise it
4. try to aa_change_hat(2) into the DEFAULT_URI hat, if it exists, otherwise it
will
=item 6
fall back to the global Apache policy
5. fall back to the global Apache policy
=back
@@ -131,15 +112,14 @@ fall back to the global Apache policy
mod_apparmor() currently only supports apache2, and has only been tested
with the prefork MPM configuration -- threaded configurations of Apache
may not work correctly. For Apache 2.4 users, you should enable the mpm_prefork
module.
may not work correctly.
There are likely other bugs lurking about; if you find any, please report
them at L<https://gitlab.com/apparmor/apparmor/-/issues>.
them at L<http://https://bugs.launchpad.net/apparmor/+filebug>.
=head1 SEE ALSO
apparmor(7), apparmor_parser(8), aa_change_hat(2) and
L<https://wiki.apparmor.net>.
apparmor(7), subdomain.conf(5), apparmor_parser(8), aa_change_hat(2) and
L<http://wiki.apparmor.net>.
=cut

View File

@@ -1,6 +1,5 @@
# ----------------------------------------------------------------------
# Copyright (c) 1999, 2004, 2005 NOVELL (All rights reserved)
# Copyright (c) 2016 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
@@ -17,57 +16,22 @@
NAME=pam_apparmor
all:
COMMONDIR=../../common/
MAKE_RULES=common/Make.rules
include $(COMMONDIR)/Make.rules
include ${MAKE_RULES}
ifdef USE_SYSTEM
LIBAPPARMOR = $(shell if pkg-config --exists libapparmor ; then \
pkg-config --silence-errors --libs libapparmor ; \
elif ldconfig -p | grep -q libapparmor\.so$$ ; then \
echo -lapparmor ; \
fi )
ifeq ($(strip $(LIBAPPARMOR)),)
ERROR_MESSAGE = $(error ${nl}\
************************************************************************${nl}\
Unable to find libapparmor installed on this system; either${nl}\
install libapparmor devel packages, set the LIBAPPARMOR variable${nl}\
manually, or build against in-tree libapparmor.${nl}\
************************************************************************${nl})
endif
LIBAPPARMOR_INCLUDE =
AA_LDLIBS = $(LIBAPPARMOR)
AA_LINK_FLAGS =
else
LIBAPPARMOR_SRC := ../../libraries/libapparmor/
LIBAPPARMOR_INCLUDE_PATH = $(LIBAPPARMOR_SRC)/include
LIBAPPARMOR_PATH := $(LIBAPPARMOR_SRC)/src/.libs/
ifeq ($(realpath $(LIBAPPARMOR_PATH)/libapparmor.a),)
ERROR_MESSAGE = $(error ${nl}\
************************************************************************${nl}\
$(LIBAPPARMOR_PATH)/libapparmor.a is missing; either build against${nl}\
the in-tree libapparmor by building it first and then trying again${nl}\
(see the top-level README for help) or build against the system${nl}\
libapparmor by adding USE_SYSTEM=1 to your make command.${nl}\
************************************************************************${nl})
endif
LIBAPPARMOR_INCLUDE = -I$(LIBAPPARMOR_INCLUDE_PATH)
AA_LINK_FLAGS = -L$(LIBAPPARMOR_PATH)
AA_LDLIBS = -lapparmor
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
common/Make.rules: $(COMMONDIR)/Make.rules
ln -sf $(COMMONDIR) .
endif
EXTRA_CFLAGS=$(CFLAGS) $(CPPFLAGS) -fPIC -shared -Wall $(EXTRA_WARNINGS) $(LIBAPPARMOR_INCLUDE)
LINK_FLAGS=-Xlinker -x $(AA_LINK_FLAGS) $(LDFLAGS)
LIBS=-lpam $(AA_LDLIBS)
EXTRA_CFLAGS=$(CFLAGS) -fPIC -shared -Wall -I../../libraries/libapparmor/src/
LINK_FLAGS=-Xlinker -x -L../../libraries/libapparmor/src/.libs
LIBS=-lpam -lapparmor
OBJECTS=${NAME}.o get_options.o
.PHONY: libapparmor_check
.SILENT: libapparmor_check
libapparmor_check: ; $(ERROR_MESSAGE)
all: libapparmor_check $(NAME).so docs
.PHONY: docs
# docs: we should have some
docs:
all: $(NAME).so
$(NAME).so: ${OBJECTS}
$(CC) $(EXTRA_CFLAGS) $(LINK_FLAGS) -o $@ ${OBJECTS} $(LIBS)
@@ -82,8 +46,10 @@ SECDIR ?= ${DESTDIR}/lib/security
.PHONY: install
install: $(NAME).so
install -m 755 -d $(SECDIR)
install -m 755 $(NAME).so $(SECDIR)/
install -m 555 $(NAME).so $(SECDIR)/
.PHONY: clean
clean:
clean: ${MAKE_RULES}
rm -f core core.* *.so *.o *.s *.a *~
rm -f ${NAME}-*.tar.gz Make.rules

View File

@@ -67,10 +67,10 @@ to syslog.
References
----------
Project webpage:
https://apparmor.net/
http://developer.novell.com/wiki/index.php/Novell_AppArmor
To provide feedback or ask questions please contact the
apparmor@lists.ubuntu.com mail list. This is the development list
apparmor-dev@forge.novell.com mail list. This is the development list
for the AppArmor team.
See also: change_hat(3), and the Linux-PAM online documentation at

View File

@@ -27,7 +27,7 @@
#include <grp.h>
#include <syslog.h>
#include <errno.h>
#include <sys/apparmor.h>
#include <apparmor.h>
#include <security/pam_ext.h>
#include <security/pam_modutil.h>
@@ -45,10 +45,6 @@
int debug_flag = 0;
#ifndef unused_
#define unused_ __attribute__ ((unused))
#endif
static struct config default_config = {
.hat_type[0] = eGroupname,
.hat_type[1] = eDefault,
@@ -58,14 +54,14 @@ static struct config default_config = {
/* --- session management functions (only) --- */
PAM_EXTERN int
pam_sm_close_session (unused_ pam_handle_t *pamh, unused_ int flags,
unused_ int argc, unused_ const char **argv)
pam_sm_close_session (pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
return PAM_IGNORE;
}
PAM_EXTERN
int pam_sm_open_session(pam_handle_t *pamh, unused_ int flags,
int pam_sm_open_session(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
int fd, retval, pam_retval = PAM_SUCCESS;
@@ -115,7 +111,6 @@ int pam_sm_open_session(pam_handle_t *pamh, unused_ int flags,
sizeof(magic_token));
if (retval < 0) {
pam_syslog(pamh, LOG_ERR, "Can't read from /dev/urandom\n");
close(fd);
return PAM_PERM_DENIED;
}
} while ((magic_token == 0) || (retval != sizeof(magic_token)));

View File

@@ -0,0 +1,83 @@
#
# spec file for package pam_apparmor (Version 2)
#
# Copyright (c) 2005 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
# package are under the same license as the package itself.
#
# Please submit bugfixes or comments via http://www.suse.de/feedback/
#
# norootforbuild
Name: pam_apparmor
License: GPL
Group: Productivity/Security
Autoreqprov: on
Version: @@immunix_version@@
Release: @@repo_version@@
Summary: Pam module to add AppArmor change_hat functionality
URL: http://forge.novell.com/modules/xfmod/project/?apparmor
Source: pam_apparmor-%{version}-@@repo_version@@.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: pam-devel
Requires: pam
Prereq: pam
%if %{?suse_version:1}0
%if 0%{?suse_version} < 1030
BuildRequires: libapparmor
%else
BuildRequires: libapparmor-devel
%endif
%else
BuildRequires: libapparmor-devel
%endif
%description
The pam_apparmor module provides the means for any pam applications that
call pam_open_session() to automatically perform an AppArmor change_hat
operation in order to switch to a user-specific security policy.
Authors:
--------
Jesse Michael jmichael@suse.de
%prep
%setup -q
%build
make CFLAGS="${RPM_OPT_FLAGS}"
%install
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
make install DESTDIR=${RPM_BUILD_ROOT} SECDIR=${RPM_BUILD_ROOT}/%{_lib}/security
%clean
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
%files
%defattr(444,root,root,755)
%doc README COPYING
%attr(555,root,root) /%{_lib}/security/pam_apparmor.so
%changelog -n pam_apparmor
* Tue Oct 31 2006 Jesse Michael <jmichael@suse.de>
- Add debug option
* Tue Oct 31 2006 Steve Beattie <sbeattie@suse.de>
- Add configuration options to order attempted hat changes
* Wed Oct 25 2006 Steve Beattie <sbeattie@suse.de>
- remove auto-editing of pam's common-session
- honor RPM's CFLAGS when building
- add license (same as Linux PAM package).
* Thu Sep 14 2006 Jesse Michael <jmichael@suse.de>
- header comment was incorrect
- use pam_get_user() instead of pam_get_item()
- fix read from urandom if 0
* Fri Jan 13 2006 Steve Beattie <sbeattie@suse.de>
- Add svn repo number to tarball
* Fri Jan 13 2006 Jesse Michael <jmichael@suse.de>
- Make magic tokens harder to guess by pulling them from /dev/urandom
* Wed Dec 21 2005 - jmichael@suse.de
- initial

View File

@@ -17,7 +17,13 @@ NAME = tomcat_apparmor
all:
COMMONDIR=../../../common/
include $(COMMONDIR)/Make.rules
include common/Make.rules
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
common/Make.rules: $(COMMONDIR)/Make.rules
ln -sf $(COMMONDIR) .
endif
LIB = lib
CATALINA_HOME = /usr/share/tomcat5
@@ -28,6 +34,7 @@ all:
clean:
ant clean
rm -f tomcat_apparmor.spec ${NAME}-*.tar.gz Make.rules
install:
install: $(SPECFILE)
ant -Dversion=$(VERSION) -Drelease=$(MAN_RELEASE) -Dcatalina_home=${CATALINA_HOME} -Dinstall_lib=${LIB} install_jar install_jni

View File

@@ -66,8 +66,8 @@ under src/jni_src.
cp dist/libJNIChangeHat.so /usr/lib
[Note: you must ensure that the target directory is passed to tomcat via the
java.library.path property. This can be accomplished by setting the JAVA_OPTS
environment variable, export JAVA_OPTS=-Djava.library.path, or set via the
java.library.path propert. This can be accomplished by setting the JAVA_OPTS
enviroment variable, export JAVA_OPTS=-Djava.library.path, or set via the
env variable LD_LIBRARY_PATH to include this directory so that tomcat can
find this library at startup]
@@ -108,13 +108,13 @@ under src/jni_src.
Once the installation steps above have been started you are ready to begin
creating a profile for your application. The profile creation tool genprof will
guide you through generating a profile and its support for change_hat will
prompt you create discrete hats as requested by the changeHatValve during
prompt you create discrete hats as requested byt the changeHatValve during
tomcat execution.
1. Create a basic profile for the tomcat server.
- Run the command "genprof PATH_TO_CATALINA.SH"
- In a separate window start tomcat and then stop tomcat
- In a seperate window start tomcat and then stop tomcat
- In the genprof window press "S" to scan for events
- Answer the questions about the initial profile for tomcat
@@ -124,7 +124,7 @@ tomcat execution.
- Stop the tomcat server
- Deploy your WAR file or equivalent files under the container.
- execute "genprof PATH_TO_CATALINA.SH"
- In a separate window start tomcat and then exercise your web application
- In a seperate window start tomcat and then exercise your web application
- In the genprof window press "S" to scan for events
During the prompting you will be asked questions similar to:
@@ -180,7 +180,7 @@ all subsequent resource requests will be mediated in this hew hat (or security
context).
If you choose to use the default hat: genprof will mediate all resource
requests in the default hat for the duration of processing this request.
When the request processing is complete the valve will change_hat back to the
When the request processng is complete the valve will change_hat back to the
parent context.
@@ -188,9 +188,10 @@ parent context.
8. Feedback/Resources
-----------------
Project webpage:
https://apparmor.net/
To provide feedback or ask questions please contact the
apparmor-dev@forge.novell.com mail list. This is the development list for the
AppArmor team.
To provide feedback or ask questions please contact the
apparmor@lists.ubuntu.com mail list. This is the development list
for the AppArmor team.

View File

@@ -13,7 +13,7 @@
#include "jni.h"
#include <errno.h>
#include <sys/apparmor.h>
#include "sys/apparmor.h"
#include "com_novell_apparmor_JNIChangeHat.h"
/* c intermediate lib call for Java -> JNI -> c library execution of the change_hat call */

View File

@@ -0,0 +1,85 @@
# ----------------------------------------------------------------------
# Copyright (c) 2006 NOVELL (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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
# norootforbuild
# Check first to see if distro is already defined.
%if ! %{?distro:1}0
%define distro suse
%endif
%if %{distro} == "suse"
%define CATALINA_HOME /usr/share/tomcat5
%endif
%define APPARMOR_DOC_DIR /usr/share/doc/packages/apparmor-docs/
%define JNI_SO libJNIChangeHat.so
%define JAR_FILE changeHatValve.jar
Summary: Tomcat 5 plugin for AppArmor change_hat
Name: tomcat_apparmor
Version: @@immunix_version@@
Release: @@repo_version@@
Group: System/Libraries
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
License: LGPL
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
Url: http://developer.novell.com/wiki/index.php/Novell_AppArmor
Prereq: tomcat5, servletapi5, libapparmor
BuildRequires: tomcat5, servletapi5 ant, java, libapparmor, java2-devel-packages, apparmor-docs
Provides: tomcat_apparmor
%description
tomcat_apparmor - is a plugin for Apache Tomcat version 5.x that provides
support for AppArmor change_hat for creating AppArmor containers that are
bound to discrete elements of processing within the Tomcat servlet
container. The AppArmor containers, or "hats", can be created for invidual
URL processing or per servlet.
%prep
%setup -q
%build
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
ant -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dtarget=1.4 jar jni_so
%install
ant -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dversion=%{version} -Drelease=%{release} -Dcatalina_home=%{CATALINA_HOME} -Dinstall_root=${RPM_BUILD_ROOT} -Dinstall_lib=%{_lib} install_jar install_jni
mkdir -p ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
install ${RPM_BUILD_DIR}/%{name}-%{version}/README.tomcat_apparmor ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{CATALINA_HOME}/server/lib/%{JAR_FILE}
/%{_lib}/lib*
/%{_libdir}/lib*
%{APPARMOR_DOC_DIR}/README.tomcat_apparmor
%post
ldconfig
%postun
ldconfig
%changelog
* Mon Oct 9 2006 - dreynolds@suse.de
- Initial package creation.

View File

@@ -17,7 +17,13 @@ NAME = tomcat_apparmor
all:
COMMONDIR=../../../common/
include $(COMMONDIR)/Make.rules
include common/Make.rules
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
common/Make.rules: $(COMMONDIR)/Make.rules
ln -sf $(COMMONDIR) .
endif
LIB = lib
CATALINA_HOME = /usr/share/tomcat55
@@ -28,6 +34,7 @@ all:
clean:
ant clean
rm -f tomcat_apparmor.spec ${NAME}-*.tar.gz Make.rules
install:
install: $(SPECFILE)
ant -Dversion=$(VERSION) -Drelease=$(MAN_RELEASE) -Dcatalina_home=${CATALINA_HOME} -Dinstall_lib=${LIB} install_jar install_jni

View File

@@ -66,8 +66,8 @@ under src/jni_src.
cp dist/libJNIChangeHat.so /usr/lib
[Note: you must ensure that the target directory is passed to tomcat via the
java.library.path property. This can be accomplished by setting the JAVA_OPTS
environment variable, export JAVA_OPTS=-Djava.library.path, or set via the
java.library.path propert. This can be accomplished by setting the JAVA_OPTS
enviroment variable, export JAVA_OPTS=-Djava.library.path, or set via the
env variable LD_LIBRARY_PATH to include this directory so that tomcat can
find this library at startup]
@@ -108,13 +108,13 @@ under src/jni_src.
Once the installation steps above have been started you are ready to begin
creating a profile for your application. The profile creation tool genprof will
guide you through generating a profile and its support for change_hat will
prompt you create discrete hats as requested by the changeHatValve during
prompt you create discrete hats as requested byt the changeHatValve during
tomcat execution.
1. Create a basic profile for the tomcat server.
- Run the command "genprof PATH_TO_CATALINA.SH"
- In a separate window start tomcat and then stop tomcat
- In a seperate window start tomcat and then stop tomcat
- In the genprof window press "S" to scan for events
- Answer the questions about the initial profile for tomcat
@@ -124,7 +124,7 @@ tomcat execution.
- Stop the tomcat server
- Deploy your WAR file or equivalent files under the container.
- execute "genprof PATH_TO_CATALINA.SH"
- In a separate window start tomcat and then exercise your web application
- In a seperate window start tomcat and then exercise your web application
- In the genprof window press "S" to scan for events
During the prompting you will be asked questions similar to:
@@ -180,7 +180,7 @@ all subsequent resource requests will be mediated in this hew hat (or security
context).
If you choose to use the default hat: genprof will mediate all resource
requests in the default hat for the duration of processing this request.
When the request processing is complete the valve will change_hat back to the
When the request processng is complete the valve will change_hat back to the
parent context.
@@ -188,9 +188,10 @@ parent context.
8. Feedback/Resources
-----------------
Project webpage:
https://apparmor.net/
To provide feedback or ask questions please contact the
apparmor-dev@forge.novell.com mail list. This is the development list for the
AppArmor team.
To provide feedback or ask questions please contact the
apparmor@lists.ubuntu.com mail list. This is the development list
for the AppArmor team.

View File

@@ -13,7 +13,7 @@
#include "jni.h"
#include <errno.h>
#include <sys/apparmor.h>
#include <apparmor.h>
#include "com_novell_apparmor_JNIChangeHat.h"
/* c intermediate lib call for Java -> JNI -> c library execution of the change_hat call */

View File

@@ -0,0 +1,86 @@
# ----------------------------------------------------------------------
# Copyright (c) 2006 NOVELL (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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
# norootforbuild
# Check first to see if distro is already defined.
%if ! %{?distro:1}0
%define distro suse
%endif
%if %{distro} == "suse"
%define CATALINA_HOME /usr/share/tomcat55
%endif
%define APPARMOR_DOC_DIR /usr/share/doc/packages/apparmor-docs/
%define JNI_SO libJNIChangeHat.so
%define JAR_FILE changeHatValve.jar
Summary: Tomcat 5 plugin for AppArmor change_hat
Name: tomcat_apparmor
Version: @@immunix_version@@
Release: @@repo_version@@
Group: System/Libraries
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
License: LGPL
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
Url: http://developer.novell.com/wiki/index.php/Novell_AppArmor
Prereq: tomcat55, servletapi5
BuildRequires: tomcat55, servletapi5, ant, java, libapparmor-devel, java2-devel-packages, apparmor-docs
%description
tomcat_apparmor - is a plugin for Apache Tomcat version 5.x that provides
support for AppArmor change_hat for creating AppArmor containers that are
bound to discrete elements of processing within the Tomcat servlet
container. The AppArmor containers, or "hats", can be created for invidual
URL processing or per servlet.
%prep
%setup -q
%build
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
ant -Dinstall_lib=%{_lib} -Dcatalina_home=%{CATALINA_HOME} -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dtarget=1.4 jar jni_so
%install
ant -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dversion=%{version} -Drelease=%{release} -Dcatalina_home=%{CATALINA_HOME} -Dinstall_root=${RPM_BUILD_ROOT} -Dinstall_lib=%{_lib} install_jar install_jni
mkdir -p ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
install ${RPM_BUILD_DIR}/%{name}-%{version}/README.tomcat_apparmor ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{CATALINA_HOME}/server/lib/%{JAR_FILE}
/%{_lib}/lib*
/%{_libdir}/lib*
doc %attr(0644,root,root) %{APPARMOR_DOC_DIR}/README.tomcat_apparmor
%post
ldconfig
%postun
ldconfig
%changelog
* Mon Jul 20 2007 - sbeattie@suse.de
- Convert builddep on libapparmor to libapparmor-devel
* Mon Oct 9 2006 - dreynolds@suse.de
- Initial package creation.

View File

@@ -1,7 +1,7 @@
# ------------------------------------------------------------------
#
# Copyright (c) 1999-2008 NOVELL (All rights reserved)
# Copyright 2009-2015 Canonical Ltd.
# Copyright 2009-2010 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="Canonical Ltd" --msgid-bugs-address=apparmor@lists.ubuntu.com -d ${NAME}
XGETTEXT_ARGS=--copyright-holder="NOVELL, Inc." --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

View File

@@ -1,7 +1,7 @@
# ------------------------------------------------------------------
#
# Copyright (C) 2002-2005 Novell/SUSE
# Copyright (C) 2010-2015 Canonical, Ltd.
# Copyright (C) 2010 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
@@ -15,76 +15,139 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ------------------------------------------------------------------
# Make.rules - common make targets and variables for building AppArmor
# Make.rules - common make targets and variables for building the SHASS
# product.
#
# NOTES:
# Before including this file in your Makefile, you should
# - define COMMONDIR (the location of the common/ directory)
# - define the default rule (usually 'all:'). (Note: you can redefine
# it later in your Makefile)
.PHONY: common_Make.rules_is_a_bad_target
common_Make.rules_is_a_bad_target:
@echo "*** default target in common/Make.rules hit - either you did something strange, or something is broken... ***"
exit 1
# - must define the package NAME before including this file.
# - After checking in to cvs, you'll need to delele the hardlinked
# Make.rules files that already exist in the individual application
# directories
DISTRIBUTION=AppArmor
VERSION=$(shell cat $(COMMONDIR)/Version)
VERSION=$(shell cat common/Version)
# Convenience functions
pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))
map = $(foreach a,$(2),$(call $(1),$(a)))
# OVERRIDABLE variables
# Set these variables before including Make.rules to change its behavior
# SPECFILE - for packages that have a non-standard specfile name
# EXTERNAL_PACKAGE - for packages that have upstream versions that
# we're locally modifying (e.g. imnxcerttool/gnutls).
#
# use 'make BUILDIR=/some/where/else/' to override the /usr/src/redhat
# location -- it *should* pick out the right thing to do based on the
# .rpmmacros file, but you can still use BUILDDIR to override that.
TESTBUILDDIR=$(shell [ -f ${HOME}/.rpmmacros ] && awk '/^%_topdir/ {print $$2}' ${HOME}/.rpmmacros)
ifndef BUILDDIR
BUILDDIR=$(shell if [ -d "${TESTBUILDDIR}" ] ; then \
echo ${TESTBUILDDIR} | sed "s^/$$^^" ; \
elif [ -d "/usr/src/redhat" ] ; then \
echo "/usr/src/redhat" ; \
elif [ -d "/usr/src/packages" ] ; then \
echo "/usr/src/packages" ; \
else \
echo "/tmp/${NAME}" ; \
fi ;)
endif
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
RPMARG=--define "_topdir $(BUILDDIR:/=)" \
--define "vendor NOVELL, Inc." \
--define "distribution ${DISTRIBUTION}" \
--define "debug_package %{nil}" \
--define "immunix_version ${VERSION}" \
$(shell [ -d ${BUILDDIR}/BUILDROOT ] && echo --define \"buildroot $(BUILDDIR:/=)/BUILDROOT\") \
$(shell [ -n "${DISTRO}" ] && echo --define \"distro ${DISTRO}\")
AWK:=$(shell which awk)
ifndef AWK
$(error awk utility required for build but not available)
REPO_VERSION_CMD=([ -x /usr/bin/bzr ] && /usr/bin/bzr version-info . 2> /dev/null || awk '{ print "revno: "$2 }' common/.stamp_rev) | awk '/^revno:/ { print $2 }'
ifdef EXTERNAL_PACKAGE
RPMARG+=--define "_sourcedir $(shell pwd)"
endif
define nl
ifndef SPECFILE
SPECFILE = $(NAME).spec
endif
RELEASE_DIR = $(NAME)-$(VERSION)
TAR = /bin/tar czvp -h --exclude .svn --exclude .bzr --exclude .bzrignore --exclude ${RELEASE_DIR}/${RELEASE_DIR} $(shell test -f ${NAME}.exclude && echo "-X ${NAME}.exclude")
LDCONFIG = /sbin/ldconfig
RPMSUBDIRS=SOURCES SPECS BUILD BUILDROOT SRPMS RPMS/i386 RPMS/i586 \
RPMS/i686 RPMS/athlon RPMS/noarch RPMS/x86_64
BUILDRPMSUBDIRS=$(foreach subdir, $(RPMSUBDIRS), $(BUILDDIR:/=)/$(subdir))
endef
ifdef EXTERNAL_PACKAGE
.PHONY: rpm
rpm: clean $(BUILDRPMSUBDIRS)
rpmbuild -ba ${RPMARG} ${SPECFILE}
REPO_VERSION_CMD=[ -x /usr/bin/git ] && /usr/bin/git describe --tags --long --abbrev=16 --match 'v*' 2> /dev/null || awk '{ print $2 }' common/.stamp_rev
else
.PHONY: rpm
rpm: clean $(BUILDRPMSUBDIRS)
__REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
__TARBALL=$(NAME)-$(VERSION)-$${__REPO_VERSION}.tar.gz ; \
make $${__TARBALL} ; \
cp $${__TARBALL} $(BUILDDIR)/SOURCES/
cp ${SPECFILE} $(BUILDDIR)/SPECS/
rpmbuild -ba ${RPMARG} ${SPECFILE}
ifndef PYTHON_VERSIONS
PYTHON_VERSIONS = $(call map, pathsearch, python3)
.PHONY: ${SPECFILE}
${SPECFILE}: ${SPECFILE}.in
__REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
sed -e "s/@@immunix_version@@/${VERSION}/g" \
-e "s/@@repo_version@@/$${__REPO_VERSION}/g" $< > $@
%.tar.gz: clean ${SPECFILE}
-rm -rf $(RELEASE_DIR)
mkdir $(RELEASE_DIR)
$(TAR) --exclude $@ . | tar xz -C $(RELEASE_DIR)
$(TAR) --exclude $@ -f $@ $(RELEASE_DIR)
rm -rf $(RELEASE_DIR)
ifndef OVERRIDE_TARBALL
.PHONY: tarball
tarball: clean $(TARBALL)
endif
ifndef PYTHON
PYTHON = $(firstword ${PYTHON_VERSIONS})
endif
#Helper function to be used with $(call pyalldo, run_test_with_all.py)
pyalldo=set -e; $(foreach py, $(PYTHON_VERSIONS), $(py) $(1);)
# Common set of compiler warnings
_EXTRA_WARNINGS = -Wall -Wsign-compare -Wmissing-field-initializers -Wformat -Wformat-security -Wunused-parameter -Wimplicit-fallthrough
EXTRA_WARNINGS := $(shell for warning in ${_EXTRA_WARNINGS} ; do \
if ${CC} $${warning} -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then \
echo "$${warning}"; \
else \
echo "***" >&2 ; \
echo "WARNING: unable to use $${warning} with ${CC}, dropping" >&2 ; \
echo "***" >&2 ; \
fi ; \
done)
.PHONY: version
.SILENT: version
version:
echo $(VERSION)
rpm -q --define "_sourcedir ." ${RPMARG} --specfile ${SPECFILE}
.PHONY: repo_version
.SILENT: repo_version
repo_version:
echo $(shell $(value REPO_VERSION_CMD))
$(value REPO_VERSION_CMD)
.PHONY: pod_clean
ifndef VERBOSE
.SILENT: pod_clean
endif
pod_clean:
.PHONY: build_dir
build_dir: $(BUILDRPMSUBDIRS)
$(BUILDRPMSUBDIRS):
mkdir -p $(BUILDRPMSUBDIRS)
.PHONY: _clean
.SILENT: _clean
_clean:
-rm -f ${NAME}-${VERSION}-*.tar.gz
-rm -f ${MANPAGES} *.[0-9].gz ${HTMLMANPAGES} pod2htm*.tmp
# =====================
@@ -109,8 +172,29 @@ install_manpages: $(MANPAGES)
MAN_RELEASE="AppArmor ${VERSION}"
%.1 %.2 %.3 %.4 %.5 %.6 %.7 %.8: %.pod
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --stderr --section=$(subst .,,$(suffix $@)) > $@
%.1: %.pod
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --section=1 > $@
%.2: %.pod
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --section=2 > $@
%.3: %.pod
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --section=3 > $@
%.4: %.pod
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --section=4 > $@
%.5: %.pod
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --section=5 > $@
%.6: %.pod
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --section=6 > $@
%.7: %.pod
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --section=7 > $@
%.8: %.pod
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --section=8 > $@
%.1.html: %.pod
$(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@
@@ -144,7 +228,3 @@ ENSCRIPT_ARGS=-C -2jGr -f Courier6 -E
%.pm.ps: %.pm
enscript ${ENSCRIPT_ARGS} -o $@ $<
.PHONY: check_pod_files
check_pod_files:
LANG=C podchecker -warning -warning *.pod

View File

@@ -1 +1 @@
4.0.3
2.7.1

View File

@@ -1,19 +0,0 @@
#!/bin/bash -e
# =====================
# generate list of network protocols based on
# sys/socket.h for use in multiple locations in
# the source tree
# =====================
# It doesn't make sense for AppArmor to mediate PF_UNIX, filter it out. Search
# for "PF_" constants since that is what is required in bits/socket.h, but
# rewrite as "AF_".
echo "#include <sys/socket.h>" | \
cpp -dM | \
LC_ALL=C sed -n \
-e '/PF_UNIX/d' \
-e 's/PF_LOCAL/PF_UNIX/' \
-e 's/^#define[ \t]\+PF_\([A-Z0-9_]\+\)[ \t]\+\([0-9]\+\).*$/AF_\1 \2,/p' | \
sort -n -k2

View File

@@ -1,14 +0,0 @@
#!/bin/bash -e
# =====================
# generate list of capabilities based on
# /usr/include/linux/capabilities.h for use in multiple locations in
# the source tree
# =====================
echo "#include <linux/capability.h>" | \
cpp -dM | \
LC_ALL=C sed -n \
-e '/CAP_EMPTY_SET/d' \
-e 's/^\#define[ \t]\+CAP_\([A-Z0-9_]\+\)[ \t]\+\([0-9xa-f]\+\)\(.*\)$/CAP_\1/p' | \
LC_ALL=C sort

View File

@@ -0,0 +1 @@
Matt Barringer <mbarringer@suse.de>

View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@@ -0,0 +1,167 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes a while. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Type `make install' to install the programs and any data files and
documentation.
4. You can remove the program binaries and object files from the
source code directory by typing `make clean'.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

View File

@@ -0,0 +1,5 @@
# not a GNU package. You can remove this line, if
# have all needed files, that a GNU package needs
AUTOMAKE_OPTIONS = foreign 1.4
SUBDIRS = src

View File

@@ -0,0 +1,8 @@
In order to actually use aadbus, you need to tell auditd to use it as a dispatcher. It's simple:
* As root, edit /etc/auditd.conf
* Add the following line (using the correct path, of course):
dispatcher=/usr/local/bin/apparmor-dbus
* Restart auditd

View File

@@ -0,0 +1,43 @@
#
# spec file for package apparmor-dbus
#
# norootforbuild
Name: apparmor-dbus
BuildRequires: audit-devel dbus-1-devel pkgconfig libapparmor-devel
Requires: libapparmor
Version: 2.3
Release: 0
License: GPL
Group: System/Management
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Source0: %{name}-%{version}.tar.bz2
Summary: -
%description
-
%prep
%setup -n %{name}-%{version}
%build
autoreconf --force --install
export CFLAGS="$RPM_OPT_FLAGS"
%{?suse_update_config:%{suse_update_config -f}}
./configure --prefix=%{_prefix}
make
%install
rm -rf %{buildroot}
%makeinstall
%clean
rm -rf %{buildroot}
%files
%defattr(-, root, root)
%{_prefix}/bin/apparmor-dbus
%changelog
* Thu Sep 13 2007 - sbeattie@suse.de
- Bump to revision 1.2

View File

@@ -0,0 +1,31 @@
#!/bin/sh
DIE=0
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $package."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have automake installed to compile $package."
echo "Download the appropriate package for your system,"
echo "or get the source from one of the GNU ftp sites"
echo "listed in http://www.gnu.org/order/ftp.html"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
echo "Running aclocal"
aclocal
echo "Running autoconf"
autoconf --force
echo "Running automake -ac"
automake -ac

View File

@@ -0,0 +1,16 @@
AC_INIT(configure.in)
AM_INIT_AUTOMAKE(apparmor-dbus, 2.3)
AC_LANG_C
AC_PROG_CC
AC_CHECK_HEADERS(libaudit.h,,AC_MSG_ERROR([libaudit header file not found!]))
AC_CHECK_LIB(audit, audit_open)
AC_CHECK_HEADERS(aalogparse/aalogparse.h)
AC_CHECK_LIB(apparmor, parse_record)
PKG_CHECK_MODULES(DBUS, dbus-1 >= 0.60)
CFLAGS="${CFLAGS} ${DBUS_CFLAGS}"
AC_CHECK_LIB(dbus-1, exit,,AC_MSG_ERROR([dbus-1 not found!]))
AC_OUTPUT(Makefile src/Makefile)

View File

@@ -0,0 +1,2 @@
bin_PROGRAMS = apparmor-dbus
apparmor_dbus_SOURCES = aadbus.c

View File

@@ -0,0 +1,322 @@
#define DBUS_API_SUBJECT_TO_CHANGE
#include <stdio.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <locale.h>
#include <libaudit.h>
#include <dbus/dbus.h>
#include <aalogparse/aalogparse.h>
#define NULLSPACE(x) (x == NULL) ? &empty_string : &x
#define NULLSTRLEN(x) (x == NULL) ? 1 : (strlen(x) + 1)
// Local data
static volatile int signaled = 0;
static int pipe_fd;
// Local functions
static int event_loop(void);
static int is_reject(char *data);
// SIGTERM handler
static void term_handler( int sig )
{
signaled = 1;
}
/*
* main is started by auditd. See dispatcher in auditd.conf
*/
int main(int argc, char *argv[])
{
struct sigaction sa;
setlocale (LC_ALL, "");
#ifndef DEBUG
/* Make sure we are root */
if (getuid() != 0) {
printf("You must be root to run this program.\n");
return 4;
}
#endif
// register sighandlers
sa.sa_flags = 0 ;
sa.sa_handler = term_handler;
sigemptyset( &sa.sa_mask ) ;
sigaction( SIGTERM, &sa, NULL );
sa.sa_handler = term_handler;
sigemptyset( &sa.sa_mask ) ;
sigaction( SIGCHLD, &sa, NULL );
sa.sa_handler = SIG_IGN;
sigaction( SIGHUP, &sa, NULL );
(void)chdir("/");
// change over to pipe_fd
pipe_fd = dup(0);
close(0);
open("/dev/null", O_RDONLY);
fcntl(pipe_fd, F_SETFD, FD_CLOEXEC);
// Start the program
return event_loop();
}
/* This function is needed for "old" messages which lumped
* everything together under one audit ID.
*/
static int is_reject (char *data)
{
int ret = -1;
/* Look for the first space */
char *start = strchr(data, ' ');
if ((start != NULL) && (strlen(start) > 9))
{
if (strncmp(start + 1, "REJECTING", 9) == 0)
{
ret = 0;
}
}
return ret;
}
static int event_loop(void)
{
void* data;
char *empty_string = " "; /* This is a quick way to indicate a 'null' value in our DBUS message */
struct iovec vec[2];
struct audit_dispatcher_header hdr;
DBusError error; /* Error, if any */
DBusMessage *message; /* Message to send */
static DBusConnection *con = NULL; /* Connection to DBUS server */
DBusMessageIter iter, /* The main message iterator */
profileIter,
nameIter,
name2Iter,
parentIter,
activeIter,
dataIter;
char *line = NULL, *parsable_line = NULL;
int real_data_size;
aa_log_record *record;
int is_rejection = 0;
if (con && !dbus_connection_get_is_connected(con))
{
dbus_connection_unref(con);
con = NULL;
}
if (!con)
{
dbus_error_init(&error);
con = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (!con)
{
dbus_error_free(&error);
return 1;
}
}
//message = dbus_message_new_signal("/com/Novell/AppArmor","com.novell.apparmor", "Reject");
/* allocate data structures */
data = malloc(MAX_AUDIT_MESSAGE_LENGTH);
if (data == NULL)
{
printf("Cannot allocate buffer\n");
return 1;
}
memset(data, 0, MAX_AUDIT_MESSAGE_LENGTH);
memset(&hdr, 0, sizeof(hdr));
do
{
int rc;
parsable_line = NULL;
is_rejection = 0;
struct timeval tv;
fd_set fd;
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(pipe_fd, &fd);
rc = select(pipe_fd+1, &fd, NULL, NULL, &tv);
if (rc == 0)
continue;
else if (rc == -1)
break;
/* Get header first. it is fixed size */
vec[0].iov_base = (void*)&hdr;
vec[0].iov_len = sizeof(hdr);
memset(data, 0, MAX_AUDIT_MESSAGE_LENGTH);
// Next payload
vec[1].iov_base = data;
vec[1].iov_len = MAX_AUDIT_MESSAGE_LENGTH;
rc = readv(pipe_fd, vec, 2);
if (rc == 0 || rc == -1) {
printf("rc == %d(%s)\n", rc, strerror(errno));
break;
}
/* Handle the AppArmor events.
* 1500 is used for "old" style messages.
* 1503 is used for APPARMOR_DENIED messages.
*/
if ((hdr.type == 1500) || (hdr.type == 1503))
{
line = (char *) data;
record = NULL;
if (hdr.type == 1503)
is_rejection = 1;
if ((hdr.type == 1500) && (is_reject(line) == 0))
is_rejection = 1;
/* We only care about REJECTING messages */
if (is_rejection == 1)
{
/* parse_record expects things like they appear in audit.log -
* which means we need to prepend TYPE=APPARMOR (if hdr.type is 1500)
* or type=APPARMOR_DENIED (if hdr.type is 1503). This is not ideal.
*/
real_data_size = strlen(line);
if (hdr.type == 1500)
{
parsable_line = (char *) malloc(real_data_size + 20);
snprintf(parsable_line, real_data_size + 19, "type=APPARMOR msg=%s", line);
}
else
{
parsable_line = (char *) malloc(real_data_size + 27);
snprintf(parsable_line, real_data_size + 26, "type=APPARMOR_DENIED msg=%s", line);
}
record = parse_record(parsable_line);
message = dbus_message_new_signal("/com/Novell/AppArmor","com.novell.apparmor", "REJECT");
dbus_message_iter_init_append(message, &iter);
/*
* The message has a number of fields appended to it,
* all of which map to the aa_log_record struct that we get back from
* parse_record(). If an entry in the struct is NULL or otherwise invalid,
* the field is still appended as a single blank space (in the case of strings), or a
* 0 in case of integers (which are all PIDs and unlikely to ever be 0).
*
* TODO: Pass a bitmask int along for the denied & requested masks
*
* 1 - The full string - BYTE ARRAY
* 2 - The PID (record->pid) - DBUS_TYPE_INT64
* 3 - The task (record->task) - DBUS_TYPE_INT64
* 4 - The audit ID (record->audit_id) - DBUS_TYPE_STRING
* 5 - The operation (record->operation: "Exec" "ptrace" etc) - DBUS_TYPE_STRING
* 6 - The denied mask (record->denied_mask: "rwx" etc) - DBUS_TYPE_STRING
* 7 - The requested mask (record->requested_mask) - DBUS_TYPE_STRING
* 8 - The name of the profile (record->profile) - BYTE ARRAY
* 9 - The first name field (record->name) - BYTE ARRAY
* 10- The second name field (record->name2) - BYTE ARRAY
* 11- The attribute (record->attribute) - DBUS_TYPE_STRING
* 12- The parent task (record->parent) - BYTE ARRAY
* 13- The magic token (record->magic_token) - DBUS_TYPE_INT64
* 14- The info field (record->info) - BYTE ARRAY
* 15- The active hat (record->active_hat) - BYTE ARRAY
*/
if (record != NULL)
{
/* Please note: NULLSPACE is defined at the top of this file, and will expand to
a ternary conditional:
(record->audit_id == NULL) ? &empty_string : &record->audit_id
for example.
The way we handle strings is ugly - some of the characters we allow (0x80, for example) are invalid Unicode,
which will cause our DBus connection to be dropped if we send them as a DBUS_TYPE_STRING.
Instead, we send a bunch of containers, each with a byte array. Perhaps a struct would be better?
*/
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &dataIter);
dbus_message_iter_append_fixed_array(&dataIter, DBUS_TYPE_BYTE, &data, strlen(data) + 1);
dbus_message_iter_close_container(&iter, &dataIter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT64, &record->pid);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT64, &record->task);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->audit_id));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->operation));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->denied_mask));
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->requested_mask));
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &profileIter);
dbus_message_iter_append_fixed_array(&profileIter,
DBUS_TYPE_BYTE,
NULLSPACE(record->profile),
NULLSTRLEN(record->profile));
dbus_message_iter_close_container(&iter, &profileIter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &nameIter);
dbus_message_iter_append_fixed_array(&nameIter,
DBUS_TYPE_BYTE,
NULLSPACE(record->name),
NULLSTRLEN(record->name));
dbus_message_iter_close_container(&iter, &nameIter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &name2Iter);
dbus_message_iter_append_fixed_array(&name2Iter,
DBUS_TYPE_BYTE,
NULLSPACE(record->name2),
NULLSTRLEN(record->name2));
dbus_message_iter_close_container(&iter, &name2Iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->attribute));
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &parentIter);
dbus_message_iter_append_fixed_array(&parentIter,
DBUS_TYPE_BYTE,
NULLSPACE(record->parent),
NULLSTRLEN(record->parent));
dbus_message_iter_close_container(&iter, &parentIter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT64, &record->magic_token);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, NULLSPACE(record->info));
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &activeIter);
dbus_message_iter_append_fixed_array(&activeIter,
DBUS_TYPE_BYTE,
NULLSPACE(record->active_hat),
NULLSTRLEN(record->active_hat));
dbus_message_iter_close_container(&iter, &activeIter);
}
dbus_connection_send(con, message, NULL);
dbus_connection_flush(con);
dbus_message_unref(message);
free_record(record);
if (parsable_line != NULL)
free(parsable_line);
}
}
} while(!signaled);
if (con)
dbus_connection_unref(con);
free(data);
return 0;
}

View File

@@ -0,0 +1 @@
Matt Barringer <mbarringer@suse.de>

View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@@ -0,0 +1,167 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes a while. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Type `make install' to install the programs and any data files and
documentation.
4. You can remove the program binaries and object files from the
source code directory by typing `make clean'.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

View File

@@ -0,0 +1,2 @@
SUBDIRS = src doc

View File

@@ -0,0 +1,5 @@
default: all
all:
srcdir=`pwd` sh macros/autogen.sh

View File

@@ -0,0 +1,6 @@
The profile editor requires wxWidgets 2.6 or higher. Your distro probably has a
binary package you could install, or you can install from a source distribution
from http://www.wxwidgets.org
This program is released under the GPL, except for all source files under
the src/wxStyledTextCtrl directory. Check there for license details for those files.

View File

@@ -0,0 +1,55 @@
AC_INIT(src/profileeditor.cpp)
AM_INIT_AUTOMAKE(profileeditor, 0.9)
AC_PROG_CXX
AC_PROG_INSTALL
AC_LIBTOOL_DLOPEN
AC_PROG_LIBTOOL
CPPFLAGS="$CPPFLAGS -Wall -g -fexceptions"
CXXFLAGS="$CPPFLAGS -Wall -g -fexceptions"
WXCONFIG=wx-config
AC_ARG_WITH(wx-config,
[[ --with-wx-config=FILE Use the given path to wx-config when determining
wxWidgets configuration; defaults to "wx-config"]],
[
if test "$withval" != "yes" -a "$withval" != ""; then
WXCONFIG=$withval
fi
])
wxversion=0
AC_DEFUN([WXTEST],
[
AC_REQUIRE([AC_PROG_AWK])
AC_MSG_CHECKING([wxWidgets version])
if wxversion=`$WXCONFIG --version`; then
AC_MSG_RESULT([$wxversion])
else
AC_MSG_RESULT([not found])
AC_MSG_ERROR([wxWidgets is required. Try --with-wx-config.])
fi])
# Call WXTEST func
WXTEST
# Verify minimus requires
vers=`echo $wxversion | $AWK 'BEGIN { FS = "."; } { printf "% d", ($1 * 1000 + $2) * 1000 + $3;}'`
if test -n "$vers" && test "$vers" -ge 2006000; then
WX_CPPFLAGS="`$WXCONFIG --cppflags`"
WX_CXXFLAGS="`$WXCONFIG --cxxflags | sed -e 's/-fno-exceptions//'`"
WX_LIBS="`$WXCONFIG --libs`"
else
AC_MSG_ERROR([wxWidgets 2.6.0 or newer is required])
fi
CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS"
CXXFLAGS="$CXXFLAGS $WX_CPPFLAGS"
AC_SUBST(WX_LIBS)
AC_OUTPUT(Makefile src/Makefile src/wxStyledTextCtrl/Makefile doc/Makefile)

View File

@@ -0,0 +1,4 @@
docdir = $(datadir)/doc/@PACKAGE@
doc_DATA = \
en/AppArmorProfileEditor.htb

View File

@@ -0,0 +1,342 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = doc
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(docdir)"
docDATA_INSTALL = $(INSTALL_DATA)
DATA = $(doc_DATA)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WX_LIBS = @WX_LIBS@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
docdir = $(datadir)/doc/@PACKAGE@
doc_DATA = \
en/AppArmorProfileEditor.htb
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu doc/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
install-docDATA: $(doc_DATA)
@$(NORMAL_INSTALL)
test -z "$(docdir)" || $(mkdir_p) "$(DESTDIR)$(docdir)"
@list='$(doc_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
$(docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
done
uninstall-docDATA:
@$(NORMAL_UNINSTALL)
@list='$(doc_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
rm -f "$(DESTDIR)$(docdir)/$$f"; \
done
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(DATA)
installdirs:
for dir in "$(DESTDIR)$(docdir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-docDATA
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-docDATA uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-docDATA install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
uninstall uninstall-am uninstall-docDATA uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,2 @@
KDE_DOCS = profileeditor
KDE_LANG = en

View File

@@ -0,0 +1,6 @@
#!/bin/sh
aclocal
libtoolize --automake --force --copy
automake -a -c
autoconf

View File

@@ -0,0 +1,44 @@
# norootforbuild
Name: apparmor-profile-editor
BuildRequires: wxGTK-devel gcc-c++
Version: 0.9
Release: 1
Vendor: Novell
Copyright: GPL
Summary: AppArmor profile editor
Group: Application/Editors
Packager: mbarringer@suse.de
BuildRoot: %{_tmppath}/%{name}-root
Source: apparmor-profile-editor-0.9.tar.gz
%description
AppArmor profile editor
%prep
%setup -q -n %{name}-%{version}
%build
autoreconf --force --install
export CFLAGS="$RPM_OPT_FLAGS -DSCI_LEXER -DLINK_LEXERS -fPIC -DPIC -DWX_PRECOMP -DNO_GCC_PRAGMA -D__WX"
export CXXFLAGS="$RPM_OPT_FLAGS -DSCI_LEXER -DLINK_LEXERS -fPIC -DPIC -DWX_PRECOMP -DNO_GCC_PRAGMA -D__WX"
%{?suse_update_config:%{suse_update_config -f}}
./configure --prefix=%{_prefix} --disable-debug --enable-debug=no
make
%install
strip $RPM_BUILD_ROOT%{_prefix}/bin/* || :
rm -rf %{buildroot}
%makeinstall
%clean
rm -rf %{buildroot}
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr(-, root, root)
%{_prefix}/bin/profileeditor
%{_prefix}/share/doc/profileeditor/AppArmorProfileEditor.htb
%dir %{_prefix}/share/doc/profileeditor
%doc AUTHORS COPYING ChangeLog NEWS README TODO
%changelog

View File

@@ -0,0 +1,114 @@
/* AppArmor Profile Editor (C) 2006 Novell, Inc.
*
* 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.
*
*/
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/wfstream.h>
#include "AboutDialog.h"
#include "opensuse_logo.xpm"
IMPLEMENT_DYNAMIC_CLASS(AboutDialog, wxDialog)
BEGIN_EVENT_TABLE(AboutDialog, wxDialog)
END_EVENT_TABLE()
AboutDialog::AboutDialog()
{
}
AboutDialog::AboutDialog(wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style)
{
Create(parent, id, caption, pos, size, style);
}
bool AboutDialog::Create(wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style)
{
mpLogoBitmap = NULL;
mpVersionStaticText = NULL;
mpCopyrightStaticText = NULL;
mpOkButtonSizer = NULL;
mpOkButton = NULL;
SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
wxDialog::Create(parent, id, caption, pos, size, style);
CreateControls();
GetSizer()->Fit(this);
GetSizer()->SetSizeHints(this);
Centre();
return true;
}
void AboutDialog::CreateControls()
{
SetBackgroundColour(wxColour(255, 255, 255));
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
SetSizer(mainSizer);
wxBitmap mpLogoBitmapBitmap(opensuse_logo_xpm);
mpLogoBitmap = new wxStaticBitmap(this,
wxID_ANY,
mpLogoBitmapBitmap,
wxDefaultPosition,
wxSize(223, 137),
0);
mainSizer->Add(mpLogoBitmap, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
mpVersionStaticText = new wxStaticText(this,
wxID_ANY,
VERSION_STRING,
wxDefaultPosition,
wxDefaultSize,
0);
mainSizer->Add(mpVersionStaticText, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxADJUST_MINSIZE, 5);
mpCopyrightStaticText = new wxStaticText(this,
wxID_ANY,
_("(C) 2006 Novell, Inc\n"),
wxDefaultPosition,
wxDefaultSize,
0);
mainSizer->Add(mpCopyrightStaticText, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxADJUST_MINSIZE, 5);
mpLicenseTextCtrl = new wxTextCtrl(this,
wxID_ANY,
_T(""),
wxDefaultPosition,
wxSize(400, -1),
wxTE_MULTILINE|wxTE_READONLY);
mpLicenseTextCtrl->SetValue(GPL_STRING);
mainSizer->Add(mpLicenseTextCtrl, 0, wxGROW|wxALL, 5);
mpOkButtonSizer = new wxStdDialogButtonSizer;
mainSizer->Add(mpOkButtonSizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
mpOkButton = new wxButton(this,
wxID_OK,
_("&OK"),
wxDefaultPosition,
wxDefaultSize,
0);
mpOkButtonSizer->AddButton(mpOkButton);
mpOkButtonSizer->Realize();
}

View File

@@ -0,0 +1,56 @@
#ifndef _ABOUTDIALOG_H_
#define _ABOUTDIALOG_H_
#define VERSION_STRING _("AppArmor Profile Editor version 0.9")
#define GPL_STRING _(" \
Portions of this software (C) 1998-2003 by Neil Hodgson <neilh@scintilla.org>\n\n \
This rest of 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. \
\n\n \
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. \
\n\n \
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 St, Fifth Floor, Boston, MA 02110-1301 USA \
")
/**
* The "About" dialog
*/
class AboutDialog: public wxDialog
{
DECLARE_DYNAMIC_CLASS(AboutDialog)
DECLARE_EVENT_TABLE()
public:
AboutDialog();
AboutDialog(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxString& caption = _T("About"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(400, 300),
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX);
bool Create(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxString& caption = _T("About"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(400, 300),
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX);
void CreateControls();
private:
wxStaticBitmap* mpLogoBitmap;
wxStaticText* mpVersionStaticText;
wxStaticText* mpCopyrightStaticText;
wxStdDialogButtonSizer* mpOkButtonSizer;
wxTextCtrl* mpLicenseTextCtrl;
wxButton* mpOkButton;
};
#endif
// _ABOUTDIALOG_H_

View File

@@ -0,0 +1,185 @@
/* AppArmor Profile Editor (C) 2006 Novell, Inc.
*
* 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.
*
*/
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/config.h>
#include "Configuration.h"
// Initialize all of the static variables
wxString Configuration::mProfileDirectory = wxEmptyString;
wxString Configuration::mProfileEditorExecutable = wxEmptyString;
wxString Configuration::mParserCommand = wxEmptyString;
wxString Configuration::mTemplateText = wxEmptyString;
wxColour Configuration::mCommentColour = wxColour(DEFAULT_COMMENT_COLOUR);
wxColour Configuration::mIncludeColour = wxColour(DEFAULT_INCLUDE_COLOUR);
wxColour Configuration::mCapColour = wxColour(DEFAULT_CAP_COLOUR);
wxColour Configuration::mPathColour = wxColour(DEFAULT_PATH_COLOUR);
wxColour Configuration::mPermColour = wxColour(DEFAULT_PERM_COLOUR);
wxFont Configuration::mCapabilityFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
wxFont Configuration::mCommentFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL);
wxFont Configuration::mIncludeFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
wxFont Configuration::mPathFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
wxFont Configuration::mPermsFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL);
int Configuration::mWindowX;
int Configuration::mWindowY;
int Configuration::mWindowHeight;
int Configuration::mWindowWidth;
/**
* Reads in the initial variables
*/
void Configuration::Initialize()
{
// Read in all of the values
mProfileEditorExecutable = wxTheApp->argv[0];
mWindowX = wxConfig::Get()->Read(_("WindowX"), 50);
mWindowY = wxConfig::Get()->Read(_("WindowY"), 50);
mWindowWidth = wxConfig::Get()->Read(_("WindowWidth"), 800);
mWindowHeight = wxConfig::Get()->Read(_("WindowHeight"), 600);
mProfileDirectory = wxConfig::Get()->Read(_("ProfileDirectory"), Configuration::BestGuessProfileDirectory());
mParserCommand = wxConfig::Get()->Read(_("Parser"), BestGuessParserCommand());
mTemplateText = wxConfig::Get()->Read(_("ProfileTemplate"), wxEmptyString);
mCommentColour = _ReadColour(_("CommentColour"), mCommentColour);
mIncludeColour = _ReadColour(_("IncludeColour"), mIncludeColour);
mCapColour = _ReadColour(_("CapabilityColour"), mCapColour);
mPathColour = _ReadColour(_("PathColour"), mPathColour);
mPermColour = _ReadColour(_("PermissionColour"), mPermColour);
_ReadFont(_("CommentFont"), mCommentFont);
_ReadFont(_("IncludeFont"), mIncludeFont);
_ReadFont(_("CapabilityFont"), mCapabilityFont);
_ReadFont(_("PathFont"), mPathFont);
_ReadFont(_("PermsFont"), mPermsFont);
}
/**
* Profiles are most likely stored in either /etc/subdomain.d or
* /etc/apparmor.d. Stat each to see which.
* @param void
* @return profile directory
*/
wxString Configuration::BestGuessProfileDirectory(void)
{
if (wxDirExists(_("/etc/apparmor.d")))
return (_("/etc/apparmor.d"));
else if (wxDirExists(_("/etc/subdomain.d")))
return (_("/etc/subdomain.d"));
else
return (_("/"));
}
/**
* The parser is probably apparmor_parser or
* subdomain_parser. If it's neither, the user
* will need to set it manually, so return /bin/false
* @return the path to the parser
*/
wxString Configuration::BestGuessParserCommand()
{
if (wxFileExists(_("/sbin/apparmor_parser")))
return _("/sbin/apparmor_parser");
else if (wxFileExists(_("/sbin/subdomain_parser")))
return _("/sbin/subdomain_parser");
else
return _("/bin/false");
}
/**
* Writes all of the values to disk
* @return only true for now
*/
bool Configuration::CommitChanges()
{
wxConfig::Get()->Write(_("ProfileDirectory"), mProfileDirectory);
wxConfig::Get()->Write(_("Parser"), mParserCommand);
wxConfig::Get()->Write(_("ProfileTemplate"), mTemplateText);
_WriteColour(_("CommentColour"), mCommentColour);
_WriteColour(_("IncludeColour"), mIncludeColour);
_WriteColour(_("CapabilityColour"), mCapColour);
_WriteColour(_("PathColour"), mPathColour);
_WriteColour(_("PermissionColour"), mPermColour);
wxConfig::Get()->Write(_("CommentFont"), mCommentFont.GetNativeFontInfoDesc());
wxConfig::Get()->Write(_("IncludeFont"), mIncludeFont.GetNativeFontInfoDesc());
wxConfig::Get()->Write(_("CapabilityFont"), mCapabilityFont.GetNativeFontInfoDesc());
wxConfig::Get()->Write(_("PathFont"), mPathFont.GetNativeFontInfoDesc());
wxConfig::Get()->Write(_("PermsFont"), mPermsFont.GetNativeFontInfoDesc());
wxConfig::Get()->Flush();
return true;
}
/**
* Writes the given window settings to the configuration file.
* This is kept separately from CommitChanges() because:
* a) There's no reason to re-write all configuration changes on exit and
* b) There's no reason to update the window position and size on every OnSize() event
*/
void Configuration::WriteWindowSettings(const wxPoint &pos, const wxSize& size)
{
wxConfig::Get()->Write(_("WindowX"), pos.x);
wxConfig::Get()->Write(_("WindowY"), pos.y);
wxConfig::Get()->Write(_("WindowWidth"), size.GetWidth());
wxConfig::Get()->Write(_("WindowHeight"), size.GetHeight());
wxConfig::Get()->Flush();
}
/**
* Reads a colour setting from the config file and translates it into
* a wxColour. If it can't convert the stored value, or the stored value
* does not exist, it will return whatever is passed as defaultColour.
* @param key the configuration key
* @param defaultColour a colour to return
* @return a colour
*/
wxColour Configuration::_ReadColour(const wxString& key, const wxColour& defaultColour)
{
wxColour ret;
wxString tmpStr = wxConfig::Get()->Read(key, wxEmptyString);
if (tmpStr.Length() == 6)
{
ret.Set(wxHexToDec(tmpStr.Mid(0,2)), // Red
wxHexToDec(tmpStr.Mid(2,2)), // Green
wxHexToDec(tmpStr.Mid(4,2)) // Blue
);
}
if (ret.Ok())
return ret;
else
return defaultColour;
}
/**
* Reads a font from the configuration file, and sets it as the 'font'
* @param key configuration key
* @param font the font to set
*/
void Configuration::_ReadFont(const wxString& key, wxFont& font)
{
wxString tmpStr;
if (wxConfig::Get()->Read(key, &tmpStr))
font.SetNativeFontInfo(tmpStr);
}
/**
* Takes a wxColour and converts it to a hex string for writing to disk.
* @param key configuration key
* @param colour the colour to convert
*/
void Configuration::_WriteColour(const wxString& key, const wxColour& colour)
{
wxConfig::Get()->Write(key, wxString::Format(_T("%02x%02x%02x"),
colour.Red(),
colour.Green(),
colour.Blue()));
}

View File

@@ -0,0 +1,84 @@
#ifndef CONFIGURATION_H
#define CONFIGURATION_H
#define DEFAULT_COMMENT_COLOUR 31, 31, 210
#define DEFAULT_INCLUDE_COLOUR 56, 136, 31
#define DEFAULT_CAP_COLOUR 229, 33, 204
#define DEFAULT_PATH_COLOUR 1, 1, 1
#define DEFAULT_PERM_COLOUR 160, 32, 240
class wxConfig;
/**
* The configuration details class
*/
class Configuration
{
public:
static void Initialize();
static wxString BestGuessProfileDirectory();
static wxString BestGuessParserCommand();
static bool CommitChanges();
static wxString GetProfileDirectory() { return mProfileDirectory; }
static wxString GetEditorExecutable() { return mProfileEditorExecutable; }
static wxString GetTemplateText() { return mTemplateText; }
static wxString GetParserCommand() { return mParserCommand; }
static wxColour GetCommentColour() { return mCommentColour; }
static wxColour GetIncludeColour() { return mIncludeColour; }
static wxColour GetCapColour() { return mCapColour; }
static wxColour GetPathColour() { return mPathColour; }
static wxColour GetPermColour() { return mPermColour; }
static wxFont GetCapabilityFont() { return mCapabilityFont; }
static wxFont GetCommentFont() { return mCommentFont; }
static wxFont GetIncludeFont() { return mIncludeFont; }
static wxFont GetPathFont() { return mPathFont; }
static wxFont GetPermFont() { return mPermsFont; }
static wxSize GetWindowSize() { return wxSize(mWindowWidth, mWindowHeight); }
static wxPoint GetWindowPos() { return wxPoint(mWindowX, mWindowY); }
static void WriteWindowSettings(const wxPoint &pos, const wxSize& size);
static void SetProfileDirectory(const wxString& profileDirectory)
{ mProfileDirectory = profileDirectory; }
static void SetEditorExecutable(const wxString& executable) { mProfileEditorExecutable = executable; }
static void SetParserCommand(const wxString& parserCommand) { mParserCommand = parserCommand; }
static void SetTemplateText(const wxString& templateText) { mTemplateText = templateText; }
static void SetCommentColour(const wxColour& commentColour) { mCommentColour = commentColour; }
static void SetIncludeColour(const wxColour& includeColour) { mIncludeColour = includeColour; }
static void SetCapColour(const wxColour& capColour) { mCapColour = capColour; }
static void SetPathColour(const wxColour& pathColour) { mPathColour = pathColour; }
static void SetPermColour(const wxColour& permColour) { mPermColour = permColour; }
static void SetCapabilityFont(const wxFont& capabilityFont) { mCapabilityFont = capabilityFont; }
static void SetCommentFont(const wxFont& commentFont) { mCommentFont = commentFont; }
static void SetIncludeFont(const wxFont& includeFont) { mIncludeFont = includeFont; }
static void SetPathFont(const wxFont& pathFont) { mPathFont = pathFont; }
static void SetPermFont(const wxFont& permsFont) { mPermsFont = permsFont; }
private:
static void _WriteColour(const wxString& key, const wxColour& colour);
static wxColour _ReadColour(const wxString& key, const wxColour& defaultColour);
static void _ReadFont(const wxString& key, wxFont& font);
static wxString mProfileDirectory;
static wxString mProfileEditorExecutable;
static wxString mParserCommand;
static wxString mTemplateText;
static wxColour mCommentColour;
static wxColour mIncludeColour;
static wxColour mCapColour;
static wxColour mPathColour;
static wxColour mPermColour;
static wxFont mCapabilityFont;
static wxFont mCommentFont;
static wxFont mIncludeFont;
static wxFont mPathFont;
static wxFont mPermsFont;
static int mWindowX; // These are just the settings from the
static int mWindowY; // config file, they are *NOT* updated
static int mWindowWidth; // in any size events
static int mWindowHeight;
};
#endif

View File

@@ -0,0 +1,24 @@
# these are the headers for your project
noinst_HEADERS = ProfileDirectoryTraverser.h ProfileTextCtrl.h Preferences.h \
AboutDialog.h opensuse_logo.xpm SearchAllProfiles.h Configuration.h
#########################################################################
# APPLICATION SECTION
#########################################################################
# this is the program that gets installed. it's name is used for all
# of the other Makefile.am variables
bin_PROGRAMS = profileeditor
# the application source, library search path, and link libraries
profileeditor_SOURCES = ProfileTextCtrl.cpp Preferences.cpp AboutDialog.cpp \
SearchAllProfiles.cpp Configuration.cpp profileeditor.cpp
profileeditor_LDFLAGS = $(WX_LIBS)
SUBDIRS = wxStyledTextCtrl
profileeditor_LDADD =\
$(top_builddir)/src/wxStyledTextCtrl/libAppArmorStyledTextCtrl.a
AM_CXXFLAGS = \
-DHELP_FILE_LOCATION=\"$(datadir)/doc/@PACKAGE@/AppArmorProfileEditor.htb\"

View File

@@ -0,0 +1,322 @@
/* AppArmor Profile Editor (C) 2006 Novell, Inc.
*
* 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.
*
*/
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/propdlg.h>
#include <wx/config.h>
#include <wx/colordlg.h>
#include <wx/fontdlg.h>
#include "Configuration.h"
#include "ProfileTextCtrl.h"
#include "Preferences.h"
IMPLEMENT_DYNAMIC_CLASS(PreferencesDialog, wxDialog)
BEGIN_EVENT_TABLE(PreferencesDialog, wxDialog)
EVT_BUTTON(ID_COMMENT_COLOUR_BUTTON, PreferencesDialog::OnColourButton)
EVT_BUTTON(ID_INCLUDES_COLOUR_BUTTON, PreferencesDialog::OnColourButton)
EVT_BUTTON(ID_PERMS_COLOUR_BUTTON, PreferencesDialog::OnColourButton)
EVT_BUTTON(ID_CAPABILITIES_COLOUR_BUTTON, PreferencesDialog::OnColourButton)
EVT_BUTTON(ID_PATHS_COLOUR_BUTTON, PreferencesDialog::OnColourButton)
EVT_BUTTON(ID_COMMENT_FONT_BUTTON, PreferencesDialog::OnFontButton)
EVT_BUTTON(ID_INCLUDES_FONT_BUTTON, PreferencesDialog::OnFontButton)
EVT_BUTTON(ID_CAPABILITIES_FONT_BUTTON, PreferencesDialog::OnFontButton)
EVT_BUTTON(ID_PATHS_FONT_BUTTON, PreferencesDialog::OnFontButton)
EVT_BUTTON(ID_PERMS_FONT_BUTTON, PreferencesDialog::OnFontButton)
END_EVENT_TABLE()
PreferencesDialog::PreferencesDialog( )
{
}
PreferencesDialog::PreferencesDialog(wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style)
{
Create(parent, id, caption, pos, size, style);
}
bool PreferencesDialog::Create(wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style)
{
mpPrefsNotebook = NULL;
mpProfileDir = NULL;
mpParserCommand = NULL;
mpTemplateTextCtrl = NULL;
mpCommentsButton = NULL;
mpIncludesButton = NULL;
mpPermsButton = NULL;
mpCapabilitiesButton = NULL;
mpPathsButton = NULL;
mpCommentsFontButton = NULL;
mpIncludesFontButton = NULL;
mpCapabilitiesFontButton = NULL;
mpPathsFontButton = NULL;
SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS);
wxDialog::Create( parent, id, caption, pos, size, style );
CreateControls();
GetSizer()->Fit(this);
GetSizer()->SetSizeHints(this);
Centre();
return true;
}
void PreferencesDialog::CreateControls()
{
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
SetSizer(mainSizer);
mpPrefsNotebook = new wxNotebook(this, ID_PREFERENCES_NOTEBOOK, wxDefaultPosition, wxDefaultSize, wxNB_TOP );
// The paths pane
wxPanel* pathsPanel = new wxPanel( mpPrefsNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
wxGridSizer* prefsGridSizer = new wxGridSizer(2, 2, 0, 0);
pathsPanel->SetSizer(prefsGridSizer);
wxStaticText* profileDirectoryText = new wxStaticText( pathsPanel, wxID_ANY, _("Profile Directory:"), wxDefaultPosition, wxDefaultSize, 0 );
prefsGridSizer->Add(profileDirectoryText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpProfileDir = new wxTextCtrl( pathsPanel, wxID_ANY, Configuration::GetProfileDirectory(), wxDefaultPosition, wxSize(200, -1), 0 );
prefsGridSizer->Add(mpProfileDir, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxStaticText* parserCommandText = new wxStaticText( pathsPanel, wxID_ANY, _("Path to apparmor_parser:"), wxDefaultPosition, wxDefaultSize, 0 );
prefsGridSizer->Add(parserCommandText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpParserCommand = new wxTextCtrl( pathsPanel, wxID_ANY, Configuration::GetParserCommand(), wxDefaultPosition, wxSize(200, -1), 0 );
prefsGridSizer->Add(mpParserCommand, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
mpPrefsNotebook->AddPage(pathsPanel, _("Paths"));
// The colours pane //
wxPanel* coloursPanel = new wxPanel( mpPrefsNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
wxBoxSizer* colorFontBoxSizer = new wxBoxSizer(wxHORIZONTAL);
coloursPanel->SetSizer(colorFontBoxSizer);
wxStaticBox* colourBoxSizer = new wxStaticBox(coloursPanel, wxID_ANY, _("Colours"));
wxStaticBoxSizer* colourStaticBoxSizer = new wxStaticBoxSizer(colourBoxSizer, wxVERTICAL);
colorFontBoxSizer->Add(colourStaticBoxSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxGridSizer* colourSubSizer = new wxGridSizer(4, 2, 0, 0);
colourStaticBoxSizer->Add(colourSubSizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
wxStaticText* commentsText = new wxStaticText( coloursPanel, wxID_STATIC, _("Comments"), wxDefaultPosition, wxDefaultSize, 0 );
colourSubSizer->Add(commentsText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpCommentsButton = new wxButton( coloursPanel, ID_COMMENT_COLOUR_BUTTON, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
mpCommentsButton->SetBackgroundColour(Configuration::GetCommentColour());
colourSubSizer->Add(mpCommentsButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxStaticText* includesText = new wxStaticText( coloursPanel, wxID_STATIC, _("Includes"), wxDefaultPosition, wxDefaultSize, 0 );
colourSubSizer->Add(includesText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpIncludesButton = new wxButton( coloursPanel, ID_INCLUDES_COLOUR_BUTTON, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
colourSubSizer->Add(mpIncludesButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
mpIncludesButton->SetBackgroundColour(Configuration::GetIncludeColour());
wxStaticText* capabilitiesText = new wxStaticText( coloursPanel, wxID_STATIC, _("Capabilities"), wxDefaultPosition, wxDefaultSize, 0 );
colourSubSizer->Add(capabilitiesText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpCapabilitiesButton = new wxButton( coloursPanel, ID_CAPABILITIES_COLOUR_BUTTON, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
colourSubSizer->Add(mpCapabilitiesButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
mpCapabilitiesButton->SetBackgroundColour(Configuration::GetCapColour());
wxStaticText* pathsText = new wxStaticText( coloursPanel, wxID_STATIC, _("Paths"), wxDefaultPosition, wxDefaultSize, 0 );
colourSubSizer->Add(pathsText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpPathsButton = new wxButton( coloursPanel, ID_PATHS_COLOUR_BUTTON, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
mpPathsButton->SetBackgroundColour(Configuration::GetPathColour());
colourSubSizer->Add(mpPathsButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxStaticText* permsText = new wxStaticText( coloursPanel, wxID_STATIC, _("Permissions"), wxDefaultPosition, wxDefaultSize, 0 );
colourSubSizer->Add(permsText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpPermsButton = new wxButton( coloursPanel, ID_PERMS_COLOUR_BUTTON, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
mpPermsButton->SetBackgroundColour(Configuration::GetPermColour());
colourSubSizer->Add(mpPermsButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
// Fonts pane //
wxStaticBox* fontSubSizer = new wxStaticBox(coloursPanel, wxID_ANY, _("Fonts"));
wxStaticBoxSizer* fontBoxSizer = new wxStaticBoxSizer(fontSubSizer, wxVERTICAL);
colorFontBoxSizer->Add(fontBoxSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxGridSizer* fontsGridSizer = new wxGridSizer(4, 2, 0, 0);
fontBoxSizer->Add(fontsGridSizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
wxStaticText* commentFontText = new wxStaticText( coloursPanel, wxID_STATIC, _("Comments"), wxDefaultPosition, wxDefaultSize, 0 );
fontsGridSizer->Add(commentFontText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpCommentsFontButton = new wxButton( coloursPanel, ID_COMMENT_FONT_BUTTON, _("ABCdef"), wxDefaultPosition, wxDefaultSize, 0 );
mpCommentsFontButton->SetFont(Configuration::GetCommentFont());
fontsGridSizer->Add(mpCommentsFontButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxStaticText* includesFontText = new wxStaticText( coloursPanel, wxID_STATIC, _("Includes"), wxDefaultPosition, wxDefaultSize, 0 );
fontsGridSizer->Add(includesFontText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpIncludesFontButton = new wxButton( coloursPanel, ID_INCLUDES_FONT_BUTTON, _("ABCdef"), wxDefaultPosition, wxDefaultSize, 0 );
mpIncludesFontButton->SetFont(Configuration::GetIncludeFont());
fontsGridSizer->Add(mpIncludesFontButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxStaticText* capabilitiesFontText = new wxStaticText( coloursPanel, wxID_STATIC, _("Capabilities"), wxDefaultPosition, wxDefaultSize, 0 );
fontsGridSizer->Add(capabilitiesFontText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpCapabilitiesFontButton = new wxButton( coloursPanel, ID_CAPABILITIES_FONT_BUTTON, _("ABCdef"), wxDefaultPosition, wxDefaultSize, 0 );
mpCapabilitiesFontButton->SetFont(Configuration::GetCapabilityFont());
fontsGridSizer->Add(mpCapabilitiesFontButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxStaticText* pathsFontText = new wxStaticText( coloursPanel, wxID_STATIC, _("Paths"), wxDefaultPosition, wxDefaultSize, 0 );
fontsGridSizer->Add(pathsFontText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpPathsFontButton = new wxButton( coloursPanel, ID_PATHS_FONT_BUTTON, _("ABCdef"), wxDefaultPosition, wxDefaultSize, 0 );
mpPathsFontButton->SetFont(Configuration::GetPathFont());
fontsGridSizer->Add(mpPathsFontButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxStaticText* permsFontText = new wxStaticText( coloursPanel, wxID_STATIC, _("Permissions"), wxDefaultPosition, wxDefaultSize, 0 );
fontsGridSizer->Add(permsFontText, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpPermsFontButton = new wxButton( coloursPanel, ID_PERMS_FONT_BUTTON, _("ABCdef"), wxDefaultPosition, wxDefaultSize, 0 );
mpPermsFontButton->SetFont(Configuration::GetPermFont());
fontsGridSizer->Add(mpPermsFontButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
mpPrefsNotebook->AddPage(coloursPanel, _("Colours & Fonts"));
// Templates pane //
mpTemplateTextCtrl = new ProfileTextCtrl (mpPrefsNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize);
mpTemplateTextCtrl->SetText(Configuration::GetTemplateText());
mpPrefsNotebook->AddPage(mpTemplateTextCtrl, _("New Profile Template"));
mainSizer->Add(mpPrefsNotebook, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
wxBoxSizer* buttonBoxSizer = new wxBoxSizer(wxHORIZONTAL);
mainSizer->Add(buttonBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
wxStdDialogButtonSizer* buttonSizer = new wxStdDialogButtonSizer;
buttonBoxSizer->Add(buttonSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxButton* okButton = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
buttonSizer->AddButton(okButton);
wxButton* cancelButton = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
buttonSizer->AddButton(cancelButton);
buttonSizer->Realize();
}
void PreferencesDialog::OnColourButton(wxCommandEvent &event)
{
wxColourData currentData;
switch (event.GetId())
{
case ID_COMMENT_COLOUR_BUTTON:
currentData.SetColour(mpCommentsButton->GetBackgroundColour());
break;
case ID_INCLUDES_COLOUR_BUTTON:
currentData.SetColour(mpIncludesButton->GetBackgroundColour());
break;
case ID_CAPABILITIES_COLOUR_BUTTON:
currentData.SetColour(mpCapabilitiesButton->GetBackgroundColour());
break;
case ID_PATHS_COLOUR_BUTTON:
currentData.SetColour(mpPathsButton->GetBackgroundColour());
break;
case ID_PERMS_COLOUR_BUTTON:
currentData.SetColour(mpPermsButton->GetBackgroundColour());
break;
default:
currentData.SetColour(*wxWHITE);
break;
}
wxColourDialog *colourPicker = new wxColourDialog(this, &currentData);
if (colourPicker->ShowModal() == wxID_OK)
{
currentData = colourPicker->GetColourData();
wxColour currentColour = currentData.GetColour();
switch (event.GetId())
{
case ID_COMMENT_COLOUR_BUTTON:
mpCommentsButton->SetBackgroundColour(currentColour);
break;
case ID_INCLUDES_COLOUR_BUTTON:
mpIncludesButton->SetBackgroundColour(currentColour);
break;
case ID_CAPABILITIES_COLOUR_BUTTON:
mpCapabilitiesButton->SetBackgroundColour(currentColour);
break;
case ID_PATHS_COLOUR_BUTTON:
mpPathsButton->SetBackgroundColour(currentColour);
break;
case ID_PERMS_COLOUR_BUTTON:
mpPermsButton->SetBackgroundColour(currentColour);
break;
default:
break;
}
}
colourPicker->Destroy();
}
void PreferencesDialog::OnFontButton(wxCommandEvent &event)
{
wxFontData fontData;
switch (event.GetId())
{
case ID_COMMENT_FONT_BUTTON:
fontData.SetInitialFont(mpCommentsFontButton->GetFont());
break;
case ID_INCLUDES_FONT_BUTTON:
fontData.SetInitialFont(mpIncludesFontButton->GetFont());
break;
case ID_CAPABILITIES_FONT_BUTTON:
fontData.SetInitialFont(mpCapabilitiesFontButton->GetFont());
break;
case ID_PATHS_FONT_BUTTON:
fontData.SetInitialFont(mpPathsFontButton->GetFont());
break;
case ID_PERMS_FONT_BUTTON:
fontData.SetInitialFont(mpPermsFontButton->GetFont());
break;
default:
break;
}
wxFontDialog *fontDialog = new wxFontDialog(this, fontData);
if (fontDialog->ShowModal() == wxID_OK)
{
fontData = fontDialog->GetFontData();
wxFont newFont = fontData.GetChosenFont();
// Write it back to disk
switch (event.GetId())
{
case ID_COMMENT_FONT_BUTTON:
mpCommentsFontButton->SetFont(newFont);
break;
case ID_INCLUDES_FONT_BUTTON:
mpIncludesFontButton->SetFont(newFont);
break;
case ID_CAPABILITIES_FONT_BUTTON:
mpCapabilitiesFontButton->SetFont(newFont);
break;
case ID_PATHS_FONT_BUTTON:
mpPathsFontButton->SetFont(newFont);
break;
case ID_PERMS_FONT_BUTTON:
mpPermsFontButton->SetFont(newFont);
break;
default:
break;
}
}
fontDialog->Destroy();
}

View File

@@ -0,0 +1,102 @@
#ifndef PREFERENCES_H
#define PREFERENCES_H
#include <wx/notebook.h>
#define CONFIG_NAME "AppArmorProfileEditor"
#define DEFAULT_COMMENT_COLOUR_R 31
#define DEFAULT_COMMENT_COLOUR_G 31
#define DEFAULT_COMMENT_COLOUR_B 210
#define DEFAULT_INCLUDE_COLOUR_R 56
#define DEFAULT_INCLUDE_COLOUR_G 136
#define DEFAULT_INCLUDE_COLOUR_B 31
#define DEFAULT_CAP_COLOUR_R 229
#define DEFAULT_CAP_COLOUR_G 33
#define DEFAULT_CAP_COLOUR_B 204
#define DEFAULT_PATH_COLOUR_R 1
#define DEFAULT_PATH_COLOUR_G 1
#define DEFAULT_PATH_COLOUR_B 1
#define DEFAULT_PERM_COLOUR_R 160
#define DEFAULT_PERM_COLOUR_G 32
#define DEFAULT_PERM_COLOUR_B 240
enum
{
ID_COMMENT_COLOUR_BUTTON,
ID_PERMS_COLOUR_BUTTON,
ID_INCLUDES_COLOUR_BUTTON,
ID_CAPABILITIES_COLOUR_BUTTON,
ID_PATHS_COLOUR_BUTTON,
ID_COMMENT_FONT_BUTTON,
ID_PERMS_FONT_BUTTON,
ID_INCLUDES_FONT_BUTTON,
ID_CAPABILITIES_FONT_BUTTON,
ID_PATHS_FONT_BUTTON,
ID_PREFERENCES_NOTEBOOK,
};
/**
* The preferences dialog
*/
class PreferencesDialog: public wxDialog
{
DECLARE_DYNAMIC_CLASS( PreferencesDialog )
DECLARE_EVENT_TABLE()
public:
PreferencesDialog();
PreferencesDialog(wxWindow* parent,
wxWindowID id,
const wxString& caption = _("Preferences"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(400, 300),
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX);
bool Create(wxWindow* parent,
wxWindowID,
const wxString& caption = _("Preferences"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(400, 300),
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX );
void CreateControls();
wxString BestGuessProfileDirectory ();
wxString BestGuessParserCommand ();
// Event handlers
void OnColourButton(wxCommandEvent &event);
void OnFontButton (wxCommandEvent &event);
// Various accessor functions so we can save the data
wxColour GetCommentButtonColour(void) { return mpCommentsButton->GetBackgroundColour(); }
wxColour GetIncludeButtonColour(void) { return mpIncludesButton->GetBackgroundColour(); }
wxColour GetCapabilityButtonColour(void) { return mpCapabilitiesButton->GetBackgroundColour(); }
wxColour GetPathButtonColour(void) { return mpPathsButton->GetBackgroundColour(); }
wxColour GetPermButtonColour(void) { return mpPermsButton->GetBackgroundColour(); }
wxFont GetCommentButtonFont(void) { return mpCommentsFontButton->GetFont(); }
wxFont GetIncludeButtonFont(void) { return mpIncludesFontButton->GetFont(); }
wxFont GetPathButtonFont(void) { return mpPathsFontButton->GetFont(); }
wxFont GetCapabilityButtonFont(void) { return mpCapabilitiesFontButton->GetFont(); }
wxFont GetPermButtonFont(void) { return mpPermsFontButton->GetFont(); }
wxString GetProfileDir(void) { return mpProfileDir->GetValue(); }
wxString GetParser(void) { return mpParserCommand->GetValue(); }
wxString GetTemplateText(void) { return mpTemplateTextCtrl->GetText(); }
private:
wxNotebook* mpPrefsNotebook;
wxTextCtrl* mpProfileDir;
wxTextCtrl* mpParserCommand;
ProfileTextCtrl* mpTemplateTextCtrl;
wxButton* mpCommentsButton;
wxButton* mpIncludesButton;
wxButton* mpPermsButton;
wxButton* mpCapabilitiesButton;
wxButton* mpPathsButton;
wxButton* mpCommentsFontButton;
wxButton* mpIncludesFontButton;
wxButton* mpCapabilitiesFontButton;
wxButton* mpPathsFontButton;
wxButton* mpPermsFontButton;
};
#endif

View File

@@ -0,0 +1,43 @@
#ifndef PROFILE_DIRECTORY_TRAVERSER
#define PROFILE_DIRECTORY_TRAVERSER
/**
* The wxDirTraverser that searches through the profile directory
*/
class ProfileDirectoryTraverser : public wxDirTraverser
{
public:
ProfileDirectoryTraverser(wxTreeCtrl* profileTree,
const wxTreeItemId& startNode,
const wxString& profileDirectory)
: mpProfileTree(profileTree),
mCurNode(startNode),
mOriginalNode(startNode),
mProfileDirectory(profileDirectory) {}
virtual wxDirTraverseResult OnFile(const wxString& filename)
{
ProfileTreeData* data = new ProfileTreeData(filename);
// OnDir isn't called when the traverser starts
// going through the files in the top level directory,
// so we do this to keep the profiles in the right place
if (wxFileName(filename).GetPath() == mProfileDirectory)
mCurNode = mOriginalNode;
mpProfileTree->AppendItem(mCurNode, wxFileName(filename).GetFullName(), -1, -1, data);
return wxDIR_CONTINUE;
}
virtual wxDirTraverseResult OnDir(const wxString& dirname)
{
mCurNode = mpProfileTree->AppendItem(mOriginalNode, wxFileName(dirname).GetName());
return wxDIR_CONTINUE;
}
private:
wxTreeCtrl* mpProfileTree;
wxTreeItemId mCurNode, mOriginalNode;
wxString mProfileDirectory;
};
#endif

View File

@@ -0,0 +1,115 @@
/* AppArmor Profile Editor (C) 2006 Novell, Inc.
*
* 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.
*
*/
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/textctrl.h>
#include <wx/textfile.h>
#include <wx/config.h>
#include "ProfileTextCtrl.h"
#include "Preferences.h"
#include "Configuration.h"
BEGIN_EVENT_TABLE(ProfileTextCtrl, wxStyledTextCtrl)
EVT_STC_CHANGE(ID_STYLED_PROFILE_WINDOW, ProfileTextCtrl::OnModified)
END_EVENT_TABLE()
ProfileTextCtrl::ProfileTextCtrl(wxWindow *parent, wxWindowID id,
const wxPoint &pos,
const wxSize &size,
long style)
: wxStyledTextCtrl (parent, id, pos, size, style|wxTE_WORDWRAP|wxTE_MULTILINE|wxTE_PROCESS_ENTER)
{
mpParentWindow = parent;
SetLexer(wxSTC_LEX_APPARMOR);
StyleClearAll();
RefreshColoursAndFonts();
mNeedSaving = false;
mIsNew = false;
}
/**
* Loads a file from disk
* @param filename The file to load
* @return true on success, false on failure
*/
bool ProfileTextCtrl::LoadFile(const wxString& filename)
{
wxTextFile file;
wxString currentLine;
if (!file.Open(filename))
return false;
mIgnoreChanges = true; // Have OnModified ignore the events from loading the file
Clear();
mFilename = filename;
wxStyledTextCtrl::LoadFile(filename);
mIgnoreChanges = false;
mNeedSaving = false;
mIsNew = false;
return true;
}
/**
* Event handler triggered by any change in the window
* @param event
*/
void ProfileTextCtrl::OnModified(wxStyledTextEvent &event)
{
if (!mIgnoreChanges)
{
mNeedSaving = true;
wxPostEvent(mpParentWindow, event);
}
}
/**
* Reloads the syntax colouring and fonts
* @param
*/
void ProfileTextCtrl::RefreshColoursAndFonts(void)
{
wxColour yellowColour(252,253,127);
wxFont defaultFont (10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
wxFont commentFont = Configuration::GetCommentFont();
wxFont includeFont = Configuration::GetIncludeFont();
wxFont capabilityFont = Configuration::GetCapabilityFont();
wxFont permFont = Configuration::GetPermFont();
wxFont pathFont = Configuration::GetPathFont();
StyleSetFont (wxSTC_STYLE_DEFAULT, defaultFont);
StyleSetForeground (wxSTC_STYLE_DEFAULT, *wxBLACK);
StyleSetBackground (wxSTC_STYLE_DEFAULT, *wxWHITE);
StyleSetFont (wxSTC_APPARMOR_COMMENT, commentFont);
StyleSetForeground (wxSTC_APPARMOR_COMMENT, Configuration::GetCommentColour());
StyleSetBackground (wxSTC_APPARMOR_COMMENT, *wxWHITE);
StyleSetFont (wxSTC_APPARMOR_INCLUDE, includeFont);
StyleSetForeground (wxSTC_APPARMOR_INCLUDE, Configuration::GetIncludeColour());
StyleSetBackground (wxSTC_APPARMOR_INCLUDE, *wxWHITE);
StyleSetFont (wxSTC_APPARMOR_CAPABILITY, capabilityFont);
StyleSetForeground (wxSTC_APPARMOR_CAPABILITY, Configuration::GetCapColour());
StyleSetBackground (wxSTC_APPARMOR_CAPABILITY, *wxWHITE);
StyleSetFont (wxSTC_APPARMOR_PATH, pathFont);
StyleSetForeground (wxSTC_APPARMOR_PATH, Configuration::GetPathColour());
StyleSetBackground (wxSTC_APPARMOR_PATH, *wxWHITE);
StyleSetFont (wxSTC_APPARMOR_PERMS, permFont);
StyleSetForeground (wxSTC_APPARMOR_PERMS, Configuration::GetPermColour());
StyleSetBackground (wxSTC_APPARMOR_PERMS, *wxWHITE);
StyleSetForeground (wxSTC_STYLE_BRACELIGHT, *wxBLACK);
StyleSetBackground (wxSTC_STYLE_BRACELIGHT, yellowColour);
StyleSetForeground (wxSTC_STYLE_BRACEBAD, *wxBLACK);
StyleSetBackground (wxSTC_STYLE_BRACEBAD, *wxRED);
SetCaretWidth(2);
}

View File

@@ -0,0 +1,44 @@
#ifndef PROFILE_TEXT_CTRL_H
#define PROFILE_TEXT_CTRL_H
#include "wxStyledTextCtrl/stc.h"
#define ID_STYLED_PROFILE_WINDOW 13082
/**
* The syntax highlighting text control
*/
class ProfileTextCtrl : public wxStyledTextCtrl
{
public:
ProfileTextCtrl (wxWindow *parent,
wxWindowID id = wxID_ANY,
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = wxSUNKEN_BORDER | wxVSCROLL);
bool LoadFile(const wxString &filename);
void ProcessLine(const wxString &currentLine);
void RefreshColoursAndFonts();
void OnModified(wxStyledTextEvent &event);
void OnReturnKey(wxCommandEvent& event);
bool GetNeedSaving() { return mNeedSaving; }
void SetNeedSaving(bool status) { mNeedSaving = status; }
wxString GetFileName() { return mFilename; }
void SetFileName(wxString fileName) { mFilename = fileName; }
void SetIsNew(bool status) { mIsNew = status; }
bool GetIsNew() { return mIsNew; }
void SetIgnoreChanges(bool value) { mIgnoreChanges = value; }
private:
wxWindow *mpParentWindow;
wxString mFilename;
bool mNeedSaving;
bool mIsNew;
bool mIgnoreChanges;
DECLARE_EVENT_TABLE()
};
#endif

View File

@@ -0,0 +1,179 @@
/* AppArmor Profile Editor (C) 2006 Novell, Inc.
*
* 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.
*
*/
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/dir.h>
#include <wx/ffile.h>
#include <wx/busyinfo.h>
#include <wx/process.h>
#include "SearchAllProfiles.h"
IMPLEMENT_DYNAMIC_CLASS(SearchAllProfilesDialog, wxDialog)
BEGIN_EVENT_TABLE(SearchAllProfilesDialog, wxDialog)
EVT_BUTTON(ID_SEARCH_ALL_PROFILES_BUTTON, SearchAllProfilesDialog::OnSearch)
EVT_LISTBOX_DCLICK(ID_SEARCH_ALL_PROFILES_LIST_BOX, SearchAllProfilesDialog::OnListBoxDClick)
END_EVENT_TABLE()
SearchAllProfilesDialog::SearchAllProfilesDialog( )
{
}
SearchAllProfilesDialog::SearchAllProfilesDialog(wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style)
{
Create(parent, id, caption, pos, size, style);
}
bool SearchAllProfilesDialog::Create(wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style )
{
mpSearchPhraseSizer = NULL;
mpSearchStaticText = NULL;
mpSearchPhraseTextCtrl = NULL;
mpSearchButton = NULL;
mpSearchResultsListBox = NULL;
mpOKButtonSizer = NULL;
mProfileDirectory = wxEmptyString;
mEditorExecutable = wxEmptyString;
mSearchedPhrase = wxEmptyString;
SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
wxDialog::Create(parent, id, caption, pos, size, style);
CreateControls();
GetSizer()->Fit(this);
GetSizer()->SetSizeHints(this);
Centre();
return true;
}
void SearchAllProfilesDialog::CreateControls()
{
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
SetSizer(mainSizer);
mpSearchPhraseSizer = new wxFlexGridSizer(1, 3, 0, 0);
mainSizer->Add(mpSearchPhraseSizer, 0, wxGROW|wxALL, 5);
mpSearchStaticText = new wxStaticText(this,
wxID_ANY,
_T("Search phrase:"),
wxDefaultPosition,
wxDefaultSize,
0);
mpSearchPhraseSizer->Add(mpSearchStaticText, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
mpSearchPhraseTextCtrl = new wxTextCtrl(this,
wxID_ANY,
_T(""),
wxDefaultPosition,
wxSize(300, -1),
0);
mpSearchPhraseSizer->Add(mpSearchPhraseTextCtrl, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
mpSearchButton = new wxButton(this,
ID_SEARCH_ALL_PROFILES_BUTTON,
_("Search"),
wxDefaultPosition,
wxDefaultSize,
0);
mpSearchPhraseSizer->Add(mpSearchButton, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
mpSearchResultsListBox = new wxListBox(this,
ID_SEARCH_ALL_PROFILES_LIST_BOX,
wxDefaultPosition,
wxSize(-1, 200),
0,
NULL,
wxLB_SINGLE);
mainSizer->Add(mpSearchResultsListBox, 0, wxGROW|wxALL, 5);
mpOKButtonSizer = new wxStdDialogButtonSizer;
mainSizer->Add(mpOKButtonSizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
wxButton* okButton = new wxButton(this,
wxID_CANCEL,
_("&Cancel"),
wxDefaultPosition,
wxDefaultSize, 0);
mpOKButtonSizer->AddButton(okButton);
mpOKButtonSizer->Realize();
}
/**
* Event handler triggered by the Search button
* @param WXUNUSED( event )
*/
void SearchAllProfilesDialog::OnSearch(wxCommandEvent& WXUNUSED(event))
{
mpSearchButton->Disable();
mpSearchResultsListBox->Clear();
mSearchedPhrase = mpSearchPhraseTextCtrl->GetValue();
DoSearch(mSearchedPhrase);
mpSearchButton->Enable();
}
/**
* Calls the directory traverser
* @param searchString
*/
void SearchAllProfilesDialog::DoSearch(const wxString& searchString)
{
if (mProfileDirectory != wxEmptyString)
{
wxBusyInfo wait(_("Searching..."));
wxTheApp->Yield(); // Needed to repaint the busy window
SearchAllProfilesTraverser traverser(searchString, mpSearchResultsListBox);
wxDir dir (mProfileDirectory);
dir.Traverse(traverser,wxEmptyString);
}
}
/**
* A user has double clicked on a search result
* @param event
*/
void SearchAllProfilesDialog::OnListBoxDClick (wxCommandEvent& event)
{
wxString execString = mEditorExecutable;
execString.Append(_T(" "));
execString.Append(event.GetString());
execString.Append(_T(" \""));
execString.Append(mSearchedPhrase);
execString.Append(_T("\""));
wxProcess *proc = wxProcess::Open(execString);
if (proc == NULL)
{
wxMessageDialog *dlg = new wxMessageDialog(this, _("Could not exec!"), _("Error"),
wxOK|wxICON_ERROR);
dlg->ShowModal();
dlg->Destroy();
}
else
{
proc->Detach();
}
}

View File

@@ -0,0 +1,95 @@
#ifndef _SEARCHALLPROFILESDIALOG_H_
#define _SEARCHALLPROFILESDIALOG_H_
class wxFlexGridSizer;
class wxStdDialogButtonSizer;
/**
* A "Search All Profiles" dialog
*/
class SearchAllProfilesDialog: public wxDialog
{
DECLARE_DYNAMIC_CLASS(SearchAllProfilesDialog)
DECLARE_EVENT_TABLE()
public:
SearchAllProfilesDialog();
SearchAllProfilesDialog(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxString& caption = _("Search All Profiles"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(400, 300),
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX);
/// Creation
bool Create(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxString& caption = _("Search All Profiles"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(400, 300),
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX );
void CreateControls();
void OnSearch(wxCommandEvent& event);
void OnListBoxDClick (wxCommandEvent& event);
void DoSearch(const wxString& searchString);
void SetProfileDirectory (const wxString& dir) { mProfileDirectory = dir; }
void SetEditorExecutable (const wxString& exec) { mEditorExecutable = exec; }
void SetSearchText (const wxString& searchString) { mpSearchPhraseTextCtrl->SetValue(searchString); }
private:
wxFlexGridSizer* mpSearchPhraseSizer;
wxStaticText* mpSearchStaticText;
wxTextCtrl* mpSearchPhraseTextCtrl;
wxButton* mpSearchButton;
wxListBox* mpSearchResultsListBox;
wxStdDialogButtonSizer* mpOKButtonSizer;
wxString mProfileDirectory;
wxString mEditorExecutable;
wxString mSearchedPhrase;
};
/**
* The "Search All" traverser
*/
class SearchAllProfilesTraverser : public wxDirTraverser
{
public:
SearchAllProfilesTraverser (const wxString& search, wxListBox *rBox)
: searchString(search),
resultsBox(rBox) {}
virtual wxDirTraverseResult OnFile(const wxString& filename)
{
if (!tmpFile.Open(filename))
return wxDIR_CONTINUE;
if (!tmpFile.ReadAll(&tmpString))
return wxDIR_CONTINUE;
if (tmpString.Find(searchString) != -1)
resultsBox->Append(filename);
tmpFile.Close();
return wxDIR_CONTINUE;
}
virtual wxDirTraverseResult OnDir(const wxString& dirname)
{
return wxDIR_CONTINUE;
}
private:
wxString searchString;
wxListBox *resultsBox;
wxString tmpString;
wxFFile tmpFile;
};
enum
{
ID_SEARCH_ALL_PROFILES_BUTTON = 15599,
ID_SEARCH_ALL_PROFILES_LIST_BOX
};
#endif

Some files were not shown because too many files have changed in this diff Show More