diff --git a/install_files/ansible-base/roles/app-test/tasks/disable_mprotect_ff_plugin_container.yml b/install_files/ansible-base/roles/app-test/tasks/disable_mprotect_ff_plugin_container.yml index ec631e5d3f..9a5f6ed96b 100644 --- a/install_files/ansible-base/roles/app-test/tasks/disable_mprotect_ff_plugin_container.yml +++ b/install_files/ansible-base/roles/app-test/tasks/disable_mprotect_ff_plugin_container.yml @@ -8,7 +8,9 @@ # We'll catch that error and respond accordingly in the next task. failed_when: false register: paxctl_firefox_header_check - when: ansible_kernel.endswith('-grsec') + when: + - ansible_kernel.endswith('-grsec') + - ansible_distribution_release == "trusty" with_items: - /usr/lib/firefox/firefox - /usr/lib/firefox/plugin-container @@ -20,4 +22,5 @@ when: # Chained conditional; only inspect command results if running under grsecurity. - ansible_kernel.endswith('-grsec') + - ansible_distribution_release == "trusty" - "item.stdout != '- PaX flags: -----m-x---- [{{ item.item }}]' or item.rc != 0" diff --git a/install_files/securedrop-app-code/debian/postinst b/install_files/securedrop-app-code/debian/postinst index 9e84c39dc6..bab2330891 100644 --- a/install_files/securedrop-app-code/debian/postinst +++ b/install_files/securedrop-app-code/debian/postinst @@ -76,8 +76,27 @@ function permit_wsgi_authorization() { fi } +# Manage PaX flags for web app, only required under Xenial. +# paxctld will already be present on Xenial due to apt dependencies, +# then we substitute the config inline +set_paxctld_config() { + paxctld_config="/etc/paxctld.conf" + if [ -f "$paxctld_config" ]; then + if ! grep -q '^/usr/sbin/apache2' "$paxctld_config"; then + printf '%s\t%s\n' "/usr/sbin/apache2" "m" >> "$paxctld_config" + systemctl restart paxctld + fi + systemctl enable paxctld + systemctl start paxctld + fi +} + case "$1" in configure) + + # Ensure PaX flags are set appropriately + set_paxctld_config + # Ensure SecureDrop's necessary directories are created for dir in /var/lib/securedrop/{,tmp,store,keys,/keys/private-keys-v1.d,/keys/openpgp-revocs.d,backups} /var/www/securedrop; do mkdir -p "$dir" diff --git a/install_files/securedrop-app-code/debian/rules b/install_files/securedrop-app-code/debian/rules index 1c9b3b45b9..3ef32adac5 100755 --- a/install_files/securedrop-app-code/debian/rules +++ b/install_files/securedrop-app-code/debian/rules @@ -5,7 +5,7 @@ DEB_DH_INSTALL_ARGS=-X .git # Set distro-specific packages here, for interpolation in Depends field. # All other deps can be reused, regardless of distro. TRUSTY_DEPS=apache2-mpm-worker -XENIAL_DEPS=apache2 +XENIAL_DEPS=apache2,paxctld SECUREDROP_BUILD_PLATFORM=$(shell lsb_release -sc) diff --git a/molecule/testinfra/staging/app/test_paxctld.py b/molecule/testinfra/staging/app/test_paxctld.py new file mode 100644 index 0000000000..c8dbd0631e --- /dev/null +++ b/molecule/testinfra/staging/app/test_paxctld.py @@ -0,0 +1,40 @@ +import pytest +import re + + +testinfra_hosts = ["app-staging"] +securedrop_test_vars = pytest.securedrop_test_vars + + +def test_paxctld_installed(host): + """ + Ensure the paxctld package is installed. + """ + # Only relevant to Xenial installs + if host.system_info.codename == "xenial": + pkg = host.package("paxctld") + assert pkg.is_installed + + +def test_paxctld_config(host): + """ + Ensure the relevant binaries have appropriate flags set in paxctld config. + """ + f = host.file("/etc/paxctld.conf") + + # Only relevant to Xenial installs + if host.system_info.codename == "xenial": + assert f.is_file + regex = "^/usr/sbin/apache2\s+m$" + assert re.search(regex, f.content, re.M) + + +def test_paxctld_service(host): + """ + Ensure the paxctld service is enabled and running. + """ + # Only relevant to Xenial installs + if host.system_info.codename == "xenial": + s = host.service("paxctld") + assert s.is_running + assert s.is_enabled