From f8b9d40abd7fd4d131f3c68c73017819f5305fff Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Wed, 21 Apr 2021 17:02:58 +0530 Subject: [PATCH 01/12] Removes Xenial from Vagrantfile --- Vagrantfile | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index 43dd9ac64e..3dbb28c56c 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -23,7 +23,7 @@ Vagrant.configure("2") do |config| config.ssh.port = 22 end staging.vm.hostname = "mon-staging" - staging.vm.box = "bento/ubuntu-16.04" + staging.vm.box = "bento/ubuntu-20.04" staging.vm.network "private_network", ip: "10.0.1.3" staging.vm.synced_folder './', '/vagrant', disabled: true staging.vm.provider "libvirt" do |lv, override| @@ -41,7 +41,7 @@ Vagrant.configure("2") do |config| config.ssh.port = 22 end staging.vm.hostname = "app-staging" - staging.vm.box = "bento/ubuntu-16.04" + staging.vm.box = "bento/ubuntu-20.04" staging.vm.network "private_network", ip: "10.0.1.2" staging.vm.synced_folder './', '/vagrant', disabled: true staging.vm.provider "virtualbox" do |v| @@ -71,11 +71,7 @@ Vagrant.configure("2") do |config| config.ssh.port = 22 end prod.vm.hostname = "mon-prod" - if ENV['USE_FOCAL'] - prod.vm.box = "bento/ubuntu-20.04" - else - prod.vm.box = "bento/ubuntu-16.04" - end + prod.vm.box = "bento/ubuntu-20.04" prod.vm.network "private_network", ip: "10.0.1.5", virtualbox__intnet: internal_network_name prod.vm.synced_folder './', '/vagrant', disabled: true prod.vm.provider "libvirt" do |lv, override| @@ -90,11 +86,7 @@ Vagrant.configure("2") do |config| config.ssh.port = 22 end prod.vm.hostname = "app-prod" - if ENV['USE_FOCAL'] - prod.vm.box = "bento/ubuntu-20.04" - else - prod.vm.box = "bento/ubuntu-16.04" - end + prod.vm.box = "bento/ubuntu-20.04" prod.vm.network "private_network", ip: "10.0.1.4", virtualbox__intnet: internal_network_name prod.vm.synced_folder './', '/vagrant', disabled: true prod.vm.provider "virtualbox" do |v| From 8955bd1f6ee77c25359870030acf0d6df3c7c35e Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Wed, 21 Apr 2021 17:04:24 +0530 Subject: [PATCH 02/12] Make staging now runs Focal by default --- Makefile | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Makefile b/Makefile index ac79fcc4fc..fa8bb3ee00 100644 --- a/Makefile +++ b/Makefile @@ -189,13 +189,7 @@ dev-focal: ## Run the development server in a Docker container. .PHONY: staging -staging: ## Create a local staging environment in virtual machines (Xenial) - @echo "███ Creating staging environment on Ubuntu Xenial..." - @$(SDROOT)/devops/scripts/create-staging-env xenial - @echo - -.PHONY: staging-focal -staging-focal: ## Create a local staging environment in virtual machines (Focal) +staging: ## Create a local staging environment in virtual machines (Focal) @echo "███ Creating staging environment on Ubuntu Focal..." @$(SDROOT)/devops/scripts/create-staging-env focal @echo From 20634515024fe3dca460dbcc63fc7ba290a50f91 Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Wed, 21 Apr 2021 17:13:17 +0530 Subject: [PATCH 03/12] Updates make dev to Focal --- Makefile | 6 ------ securedrop/bin/dev-shell | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Makefile b/Makefile index fa8bb3ee00..9303967631 100644 --- a/Makefile +++ b/Makefile @@ -181,12 +181,6 @@ dev: ## Run the development server in a Docker container. @OFFSET_PORTS='false' DOCKER_BUILD_VERBOSE='true' $(DEVSHELL) $(SDBIN)/run @echo -.PHONY: dev-focal -dev-focal: ## Run the development server in a Docker container. - @echo "███ Starting development server..." - @OFFSET_PORTS='false' DOCKER_BUILD_VERBOSE='true' BASE_OS='focal' $(DEVSHELL) $(SDBIN)/run - @echo - .PHONY: staging staging: ## Create a local staging environment in virtual machines (Focal) diff --git a/securedrop/bin/dev-shell b/securedrop/bin/dev-shell index fba5e96dbf..4dc44e2da0 100755 --- a/securedrop/bin/dev-shell +++ b/securedrop/bin/dev-shell @@ -9,7 +9,7 @@ set -eu export PATH="/opt/venvs/securedrop-app-code/bin:$PATH" TOPLEVEL=$(git rev-parse --show-toplevel) -BASE_OS="${BASE_OS:-xenial}" +BASE_OS="${BASE_OS:-focal}" ## Get an integer offset for exposed ports, to support multiple containers get_port_offset() { From 798cf9c241d900f7f0115dce5dbf015b8e739431 Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Wed, 21 Apr 2021 18:35:56 +0530 Subject: [PATCH 04/12] Make build-debs now has Focal as default --- Makefile | 20 ++++---------------- devops/scripts/build-debs.sh | 2 +- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 9303967631..e912742755 100644 --- a/Makefile +++ b/Makefile @@ -308,27 +308,15 @@ endif ########### .PHONY: build-debs -build-debs: ## Build and test SecureDrop Debian packages (for Xenial) - @echo "Building SecureDrop Debian packages for Xenial..." +build-debs: ## Build and test SecureDrop Debian packages (for Focal) + @echo "Building SecureDrop Debian packages for Focal..." @$(SDROOT)/devops/scripts/build-debs.sh @echo .PHONY: build-debs-notest -build-debs-notest: ## Build SecureDrop Debian packages (for Xenial) without running tests. - @echo "Building SecureDrop Debian packages for Xenial; skipping tests..." - @$(SDROOT)/devops/scripts/build-debs.sh notest - @echo - -.PHONY: build-debs-focal -build-debs-focal: ## Build and test SecureDrop Debian packages (for Focal) - @echo "Building SecureDrop Debian packages for Focal..." - @$(SDROOT)/devops/scripts/build-debs.sh test focal - @echo - -.PHONY: build-debs-notest-focal -build-debs-notest-focal: ## Build SecureDrop Debian packages (for Focal) without running tests. +build-debs-notest: ## Build SecureDrop Debian packages (for Focal) without running tests. @echo "Building SecureDrop Debian packages for Focal; skipping tests..." - @$(SDROOT)/devops/scripts/build-debs.sh notest focal + @$(SDROOT)/devops/scripts/build-debs.sh notest @echo diff --git a/devops/scripts/build-debs.sh b/devops/scripts/build-debs.sh index 4041754a67..81eb17c07d 100755 --- a/devops/scripts/build-debs.sh +++ b/devops/scripts/build-debs.sh @@ -11,7 +11,7 @@ set -o pipefail virtualenv_bootstrap RUN_TESTS="${1:-test}" -TARGET_PLATFORM="${2:-xenial}" +TARGET_PLATFORM="${2:-focal}" SCENARIO_NAME="builder-${TARGET_PLATFORM}" case "$RUN_TESTS" in From 0bb420b620a85ebac906d99e2e4dd95b20b3b84f Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Wed, 21 Apr 2021 18:58:13 +0530 Subject: [PATCH 05/12] Removes xenial scenarios from molecule Ports the deb pkg tests into the focal directory, so the logic is preserved. --- .../tests/conftest.py | 0 .../tests/test_build_dependencies.py | 0 .../tests/test_legacy_paths.py | 0 .../tests/test_securedrop_deb_package.py | 0 .../tests/test_security_updates.py | 0 .../tests/vars.yml | 0 molecule/builder-xenial/Dockerfile | 39 --------- molecule/builder-xenial/Makefile | 20 ----- molecule/builder-xenial/aptpreferences.conf | 7 -- molecule/builder-xenial/create.yml | 28 ------ molecule/builder-xenial/destroy.yml | 15 ---- molecule/builder-xenial/image_hash | 2 - molecule/builder-xenial/molecule.yml | 78 ----------------- molecule/builder-xenial/playbook.yml | 80 ----------------- molecule/builder-xenial/push.sh | 12 --- molecule/fetch-tor-packages/molecule.yml | 4 - .../tests/test_tor_packages.py | 8 +- .../ansible-override-vars.yml | 7 -- molecule/libvirt-staging-xenial/create.yml | 56 ------------ molecule/libvirt-staging-xenial/destroy.yml | 35 -------- molecule/libvirt-staging-xenial/molecule.yml | 76 ----------------- molecule/libvirt-staging-xenial/prepare.yml | 9 -- molecule/qubes-staging-xenial/create.yml | 85 ------------------- molecule/qubes-staging-xenial/destroy.yml | 45 ---------- molecule/qubes-staging-xenial/molecule.yml | 60 ------------- molecule/qubes-staging-xenial/qubes-vars.yml | 14 --- molecule/qubes-staging-xenial/ssh_config.j2 | 8 -- .../ansible-override-vars.yml | 7 -- .../virtualbox-staging-xenial/molecule.yml | 69 --------------- update_version.sh | 2 +- 30 files changed, 4 insertions(+), 762 deletions(-) rename molecule/{builder-xenial => builder-focal}/tests/conftest.py (100%) rename molecule/{builder-xenial => builder-focal}/tests/test_build_dependencies.py (100%) rename molecule/{builder-xenial => builder-focal}/tests/test_legacy_paths.py (100%) rename molecule/{builder-xenial => builder-focal}/tests/test_securedrop_deb_package.py (100%) rename molecule/{builder-xenial => builder-focal}/tests/test_security_updates.py (100%) rename molecule/{builder-xenial => builder-focal}/tests/vars.yml (100%) delete mode 100644 molecule/builder-xenial/Dockerfile delete mode 100644 molecule/builder-xenial/Makefile delete mode 100644 molecule/builder-xenial/aptpreferences.conf delete mode 100644 molecule/builder-xenial/create.yml delete mode 100644 molecule/builder-xenial/destroy.yml delete mode 100644 molecule/builder-xenial/image_hash delete mode 100644 molecule/builder-xenial/molecule.yml delete mode 100644 molecule/builder-xenial/playbook.yml delete mode 100755 molecule/builder-xenial/push.sh delete mode 100644 molecule/libvirt-staging-xenial/ansible-override-vars.yml delete mode 100644 molecule/libvirt-staging-xenial/create.yml delete mode 100644 molecule/libvirt-staging-xenial/destroy.yml delete mode 100644 molecule/libvirt-staging-xenial/molecule.yml delete mode 100644 molecule/libvirt-staging-xenial/prepare.yml delete mode 100644 molecule/qubes-staging-xenial/create.yml delete mode 100644 molecule/qubes-staging-xenial/destroy.yml delete mode 100644 molecule/qubes-staging-xenial/molecule.yml delete mode 100644 molecule/qubes-staging-xenial/qubes-vars.yml delete mode 100644 molecule/qubes-staging-xenial/ssh_config.j2 delete mode 100644 molecule/virtualbox-staging-xenial/ansible-override-vars.yml delete mode 100644 molecule/virtualbox-staging-xenial/molecule.yml diff --git a/molecule/builder-xenial/tests/conftest.py b/molecule/builder-focal/tests/conftest.py similarity index 100% rename from molecule/builder-xenial/tests/conftest.py rename to molecule/builder-focal/tests/conftest.py diff --git a/molecule/builder-xenial/tests/test_build_dependencies.py b/molecule/builder-focal/tests/test_build_dependencies.py similarity index 100% rename from molecule/builder-xenial/tests/test_build_dependencies.py rename to molecule/builder-focal/tests/test_build_dependencies.py diff --git a/molecule/builder-xenial/tests/test_legacy_paths.py b/molecule/builder-focal/tests/test_legacy_paths.py similarity index 100% rename from molecule/builder-xenial/tests/test_legacy_paths.py rename to molecule/builder-focal/tests/test_legacy_paths.py diff --git a/molecule/builder-xenial/tests/test_securedrop_deb_package.py b/molecule/builder-focal/tests/test_securedrop_deb_package.py similarity index 100% rename from molecule/builder-xenial/tests/test_securedrop_deb_package.py rename to molecule/builder-focal/tests/test_securedrop_deb_package.py diff --git a/molecule/builder-xenial/tests/test_security_updates.py b/molecule/builder-focal/tests/test_security_updates.py similarity index 100% rename from molecule/builder-xenial/tests/test_security_updates.py rename to molecule/builder-focal/tests/test_security_updates.py diff --git a/molecule/builder-xenial/tests/vars.yml b/molecule/builder-focal/tests/vars.yml similarity index 100% rename from molecule/builder-xenial/tests/vars.yml rename to molecule/builder-focal/tests/vars.yml diff --git a/molecule/builder-xenial/Dockerfile b/molecule/builder-xenial/Dockerfile deleted file mode 100644 index ea29026cf7..0000000000 --- a/molecule/builder-xenial/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -# ubuntu:xenial-20200902 -FROM ubuntu@sha256:3dd44f7ca10f07f86add9d0dc611998a1641f501833692a2651c96defe8db940 - -# additional meta-data makes it easier to clean up, find -LABEL org="Freedom of the Press" -LABEL image_name="xenial-sd-builder-app" - -RUN apt-get -y update && apt-get upgrade -y && apt-get install -y \ - apache2-dev \ - coreutils \ - debhelper \ - devscripts \ - dh-python \ - dh-systemd \ - dh-virtualenv \ - gdb \ - git \ - gnupg2 \ - haveged \ - inotify-tools \ - libffi-dev \ - libssl-dev \ - make \ - ntp \ - paxctl \ - python3-all \ - python3-pip \ - python3-setuptools \ - python3-venv \ - rsync \ - ruby \ - sqlite \ - sudo \ - tzdata \ - unzip \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -RUN paxctl -cm /usr/bin/python3.5 && mkdir -p /tmp/build diff --git a/molecule/builder-xenial/Makefile b/molecule/builder-xenial/Makefile deleted file mode 100644 index 39faf51f2d..0000000000 --- a/molecule/builder-xenial/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -DATE_STR := $(shell date +"%Y_%m_%d") -BUILDER_IMAGE ?= "quay.io/freedomofpress/sd-docker-builder-xenial:$(DATE_STR)" - -.PHONY: build-container -build-container: ## Build Docker image for Debian package creation - @echo "███Building Docker image $(BUILDER_IMAGE) for Debian package creation..." - @docker build --no-cache -t $(BUILDER_IMAGE) . - -.PHONY: push-container -push-container: ## Push the Docker image for Debian package creation to quay.io - @echo "███Pushing Docker image for Debian package creation to quay.io..." - @./push.sh - -.PHONY: help -help: ## Print this message and exit. - @printf "Molecule scenario for building a Docker container for Debian package creation.\n" - @printf "Subcommands:\n\n" - @awk 'BEGIN {FS = ":.*?## "} /^[0-9a-zA-Z_-]+:.*?## / {printf "\033[36m%s\033[0m : %s\n", $$1, $$2}' $(MAKEFILE_LIST) \ - | sort \ - | column -s ':' -t diff --git a/molecule/builder-xenial/aptpreferences.conf b/molecule/builder-xenial/aptpreferences.conf deleted file mode 100644 index a041f3b002..0000000000 --- a/molecule/builder-xenial/aptpreferences.conf +++ /dev/null @@ -1,7 +0,0 @@ -Package: * -Pin: release a=xenial -Pin-Priority: 700 - -Package: * -Pin: release a=unstable -Pin-Priority: 1 diff --git a/molecule/builder-xenial/create.yml b/molecule/builder-xenial/create.yml deleted file mode 100644 index c01fd76007..0000000000 --- a/molecule/builder-xenial/create.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: Create - hosts: localhost - connection: local - gather_facts: False - vars: - molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}" - molecule_ephemeral_directory: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}" - molecule_scenario_directory: "{{ lookup('env', 'MOLECULE_SCENARIO_DIRECTORY') }}" - molecule_yml: "{{ lookup('file', molecule_file) | from_yaml }}" - image_hash: "{{ lookup('pipe', 'egrep -v ^# image_hash') }}" - default_image: "quay.io/freedomofpress/sd-docker-builder-xenial@sha256:{{image_hash}}" - image: "{{ lookup('env', 'BUILDER_IMAGE') | default(default_image, true) }}" - tasks: - - debug: - msg: "Building with Docker image {{ image }}" - - - name: Create builders - docker_container: - name: "{{ item.name }}" - hostname: "{{ item.name }}" - image: "{{ image }}" - state: started - command: "tail -f /dev/null" - privileged: "{{ item.privileged | default(omit) }}" - volumes: "{{ item.volumes | default(omit) }}" - capabilities: "{{ item.capabilities | default(omit) }}" - with_items: "{{ molecule_yml.platforms }}" diff --git a/molecule/builder-xenial/destroy.yml b/molecule/builder-xenial/destroy.yml deleted file mode 100644 index f804be7578..0000000000 --- a/molecule/builder-xenial/destroy.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Destroy - hosts: localhost - connection: local - gather_facts: False - vars: - molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}" - molecule_yml: "{{ lookup('file', molecule_file) | from_yaml }}" - tasks: - - name: Destroy molecule instance(s) - docker_container: - name: "{{ item.name }}" - state: absent - force_kill: "{{ item.force_kill | default(True) }}" - with_items: "{{ molecule_yml.platforms }}" diff --git a/molecule/builder-xenial/image_hash b/molecule/builder-xenial/image_hash deleted file mode 100644 index 21821f70f4..0000000000 --- a/molecule/builder-xenial/image_hash +++ /dev/null @@ -1,2 +0,0 @@ -# sha256 digest quay.io/freedomofpress/sd-docker-builder-xenial:2021_04_14 -3fefc5cb2382fbcdb650606a62c88e58003d858c6722a72b51a8982dec37a052 diff --git a/molecule/builder-xenial/molecule.yml b/molecule/builder-xenial/molecule.yml deleted file mode 100644 index 2258b8c1ea..0000000000 --- a/molecule/builder-xenial/molecule.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- -driver: - name: docker -lint: | - yamllint -platforms: - - name: xenial-sd-app - groups: - - builders - - name: xenial-sd-generic-ossec-agent - groups: - - builders - - name: xenial-sd-generic-ossec-server - groups: - - builders - - name: xenial-sd-generic-ossec-agent2 - groups: - - builders - - name: xenial-sd-generic-ossec-server2 - groups: - - builders - - name: xenial-sd-grsec - groups: - - builders - - name: xenial-sd-config - groups: - - builders - - name: xenial-sd-keyring - groups: - - builders - - name: xenial-sd-sec-update - groups: - - builders - - name: xenial-sd-dpkg-verification - groups: - - testers -provisioner: - name: ansible - inventory: - links: - group_vars: ../../install_files/ansible-base/group_vars - config_options: - defaults: - interpreter_python: auto - env: - ANSIBLE_ROLES_PATH: ../../install_files/ansible-base/roles - ANSIBLE_ACTION_PLUGINS: ../../install_files/ansible-base/action_plugins - ANSIBLE_CALLBACK_WHITELIST: skippy - ANSIBLE_STDOUT_CALLBACK: skippy - ANSIBLE_GATHER_TIMEOUT: "120" - lint: | - ansible-lint - playbooks: - converge: playbook.yml -scenario: - name: builder-xenial - converge_sequence: - - destroy - - create - - converge - - destroy - test_sequence: - - destroy - - create - - converge - - verify - - destroy -verifier: - name: testinfra - options: - # provided by pytest-xdist - n: auto - env: - SECUREDROP_TARGET_DISTRIBUTION: xenial - SECUREDROP_PYTHON_VERSION: "3.5" - directory: tests/ - lint: | - flake8 diff --git a/molecule/builder-xenial/playbook.yml b/molecule/builder-xenial/playbook.yml deleted file mode 100644 index 93db7596c4..0000000000 --- a/molecule/builder-xenial/playbook.yml +++ /dev/null @@ -1,80 +0,0 @@ ---- -- name: Build SecureDrop application Debian package from local repository. - hosts: builders - # Build as fast as possible with each host going individually - strategy: free - become: yes - tasks: - - name: Update apt-cache for our security checker - apt: - update_cache: yes - when: ansible_host.endswith("-sd-sec-update") - roles: - - role: build-securedrop-app-code-deb-pkg - tags: app-deb - when: ansible_host.endswith("-sd-app") - - - role: build-ossec-deb-pkg - tags: ossec-server - purpose: server - when: ansible_host.endswith("-sd-generic-ossec-server") - - - role: build-ossec-deb-pkg - tags: ossec-agent - purpose: agent - when: ansible_host.endswith("-sd-generic-ossec-agent") - - - role: build-generic-pkg - tags: securedrop-ossec-server - package_name: securedrop-ossec-server - when: ansible_host.endswith("-sd-generic-ossec-server2") or ansible_host == "localhost" - - - role: build-generic-pkg - tags: securedrop-ossec-agent - package_name: securedrop-ossec-agent - when: ansible_host.endswith("-sd-generic-ossec-agent2") or ansible_host == "localhost" - - - role: build-generic-pkg - tags: securedrop-keyring - package_name: securedrop-keyring - when: ansible_host.endswith("-sd-keyring") or ansible_host == "localhost" - - - role: build-generic-pkg - tags: securedrop-grsec - package_name: securedrop-grsec - when: ansible_host.endswith("-sd-grsec") or ansible_host == "localhost" - - - role: build-generic-pkg - tags: securedrop-config - package_name: securedrop-config - when: ansible_host.endswith("-sd-config") or ansible_host == "localhost" - tags: rebuild - -# Typically we'd perform volume mounting here but to work around docker -# remote calls (in CircleCI) we have to copy the files instead -- name: Give dpkg verify container access to debs - hosts: testers - gather_facts: false - vars: - sd_build_root: "{{ playbook_dir + '/../../build' }}" - securedrop_target_distribution: xenial - sd_build_dest: "{{ sd_build_root + '/' + securedrop_target_distribution }}" - - tasks: - - name: Discover local debian build files - find: - paths: "{{ sd_build_dest }}" - patterns: '*.deb' - delegate_to: localhost - register: debian_files - - - name: Create build dir - file: - state: directory - path: /tmp/build - - - name: Drop debian files into container - copy: - src: "{{ item.path }}" - dest: /tmp/build/ - with_items: "{{ debian_files.files }}" diff --git a/molecule/builder-xenial/push.sh b/molecule/builder-xenial/push.sh deleted file mode 100755 index efd08cd8df..0000000000 --- a/molecule/builder-xenial/push.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -DATE_STR=$(date +"%Y_%m_%d") -QUAY_REPO=quay.io/freedomofpress/sd-docker-builder-xenial - -set -e -set -x - -docker push "${QUAY_REPO}:${DATE_STR}" - -echo "# sha256 digest ${QUAY_REPO}:${DATE_STR}" > image_hash -docker inspect --format='{{index .RepoDigests 0}}' "${QUAY_REPO}:${DATE_STR}" \ - | sed 's/.*://g' >> image_hash diff --git a/molecule/fetch-tor-packages/molecule.yml b/molecule/fetch-tor-packages/molecule.yml index 0f75468efd..dc82692030 100644 --- a/molecule/fetch-tor-packages/molecule.yml +++ b/molecule/fetch-tor-packages/molecule.yml @@ -6,10 +6,6 @@ driver: lint: | yamllint platforms: - - name: tor-package-fetcher-xenial - image: "quay.io/freedomofpress/sd-docker-builder-xenial" - distro: xenial - - name: tor-package-fetcher-focal image: "quay.io/freedomofpress/sd-docker-builder-focal" distro: focal diff --git a/molecule/fetch-tor-packages/tests/test_tor_packages.py b/molecule/fetch-tor-packages/tests/test_tor_packages.py index 688b7e0431..27eaa7ed10 100644 --- a/molecule/fetch-tor-packages/tests/test_tor_packages.py +++ b/molecule/fetch-tor-packages/tests/test_tor_packages.py @@ -3,7 +3,6 @@ testinfra_hosts = [ - "docker://tor-package-fetcher-xenial", "docker://tor-package-fetcher-focal", ] TOR_DOWNLOAD_DIR = "/tmp/tor-debs" @@ -46,10 +45,9 @@ def test_tor_package_versions(host, pkg): def test_tor_package_platform(host): """ Sanity check to ensure we're running on a version of Ubuntu - that is supported by the upstream Tor Project, i.e. Xenial or Focal. - The Trusty channel was disabled by Tor Project on 2019-01-08. + that is supported by the upstream Tor Project, i.e. Focal. """ assert host.system_info.type == "linux" assert host.system_info.distribution == "ubuntu" - assert host.system_info.codename in ("xenial", "focal") - assert host.system_info.release in ("16.04", "20.04") + assert host.system_info.codename == "focal" + assert host.system_info.release == "20.04" diff --git a/molecule/libvirt-staging-xenial/ansible-override-vars.yml b/molecule/libvirt-staging-xenial/ansible-override-vars.yml deleted file mode 100644 index 05c029a0ca..0000000000 --- a/molecule/libvirt-staging-xenial/ansible-override-vars.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Permit direct access via SSH -ssh_net_in_override: 0.0.0.0/0 - -# In libvirt, we want to connect over eth0, not eth1 which is used for -# inter-VM communication for OSSEC. -ssh_ip: "{{ ansible_default_ipv4.address }}" diff --git a/molecule/libvirt-staging-xenial/create.yml b/molecule/libvirt-staging-xenial/create.yml deleted file mode 100644 index 7e6b416f85..0000000000 --- a/molecule/libvirt-staging-xenial/create.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- -- name: Create - hosts: localhost - connection: local - vars: - molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}" - molecule_instance_config: "{{ lookup('env', 'MOLECULE_INSTANCE_CONFIG') }}" - molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}" - tasks: - - - name: Create molecule instance(s) - vagrant: - instance_name: "{{ item.name }}" - instance_interfaces: "{{ item.interfaces | default(omit) }}" - instance_raw_config_args: "{{ item.instance_raw_config_args | default(omit) }}" - - platform_box: "{{ item.box }}" - platform_box_version: "{{ item.box_version | default(omit) }}" - platform_box_url: "{{ item.box_url | default(omit) }}" - - provider_name: "{{ molecule_yml.driver.provider.name }}" - provider_memory: "{{ item.memory | default(omit) }}" - provider_cpus: "{{ item.cpus | default(omit) }}" - provider_raw_config_args: "{{ item.raw_config_args | default(omit) }}" - force_stop: yes - - state: up - register: server - with_items: "{{ molecule_yml.platforms }}" - - # Mandatory configuration for Molecule to function. - - - name: Populate instance config dict - set_fact: - instance_conf_dict: { - 'instance': "{{ item.Host }}", - 'address': "{{ item.HostName }}", - 'user': "{{ item.User }}", - 'port': "{{ item.Port }}", - 'identity_file': "{{ item.IdentityFile }}", } - with_items: "{{ server.results }}" - register: instance_config_dict - when: server.changed | bool - - - name: Convert instance config dict to a list - set_fact: - instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}" - when: server.changed | bool - - - name: Dump instance config - copy: - # NOTE(retr0h): Workaround for Ansible 2.2. - # https://github.com/ansible/ansible/issues/20885 - content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" - dest: "{{ molecule_instance_config }}" - when: server.changed | bool diff --git a/molecule/libvirt-staging-xenial/destroy.yml b/molecule/libvirt-staging-xenial/destroy.yml deleted file mode 100644 index 3645c7c90f..0000000000 --- a/molecule/libvirt-staging-xenial/destroy.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- - -- name: Destroy - hosts: localhost - connection: local - vars: - molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}" - molecule_instance_config: "{{ lookup('env',' MOLECULE_INSTANCE_CONFIG') }}" - molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}" - molecule_ephemeral_directory: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}" - tasks: - - name: Destroy molecule instance(s) - vagrant: - instance_name: "{{ item.name }}" - platform_box: "{{ item.box }}" - provider_name: "{{ molecule_yml.driver.provider.name }}" - force_stop: "{{ item.force_stop | default(True) }}" - - state: destroy - register: server - with_items: "{{ molecule_yml.platforms }}" - - # Mandatory configuration for Molecule to function. - - - name: Populate instance config - set_fact: - instance_conf: {} - - - name: Dump instance config - copy: - # NOTE(retr0h): Workaround for Ansible 2.2. - # https://github.com/ansible/ansible/issues/20885 - content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" - dest: "{{ molecule_instance_config }}" - when: server.changed | bool diff --git a/molecule/libvirt-staging-xenial/molecule.yml b/molecule/libvirt-staging-xenial/molecule.yml deleted file mode 100644 index 58ba6c56a0..0000000000 --- a/molecule/libvirt-staging-xenial/molecule.yml +++ /dev/null @@ -1,76 +0,0 @@ ---- -driver: - name: vagrant - provider: - name: libvirt -lint: | - yamllint - -platforms: - - name: app-staging - box: bento/ubuntu-16.04 - raw_config_args: - - "cpu_mode = 'host-passthrough'" - - "video_type = 'virtio'" - instance_raw_config_args: - - "vm.synced_folder './', '/vagrant', disabled: true" - - "vm.network 'private_network', ip: '10.0.1.2'" - - "ssh.insert_key = false" - memory: 1024 - private_ip: 10.0.1.2 - groups: - - securedrop_application_server - - securedrop - - staging - - - name: mon-staging - box: bento/ubuntu-16.04 - raw_config_args: - - "cpu_mode = 'host-passthrough'" - - "video_type = 'virtio'" - instance_raw_config_args: - - "vm.synced_folder './', '/vagrant', disabled: true" - - "vm.network 'private_network', ip: '10.0.1.3'" - - "ssh.insert_key = false" - memory: 1024 - private_ip: 10.0.1.3 - groups: - - securedrop_monitor_server - - securedrop - - staging - -provisioner: - name: ansible - lint: | - ansible-lint - config_options: - defaults: - interpreter_python: auto - options: - e: "@ansible-override-vars.yml" - playbooks: - converge: ../../install_files/ansible-base/securedrop-staging.yml - create: create.yml - destroy: destroy.yml - prepare: prepare.yml - env: - ANSIBLE_CONFIG: ../../install_files/ansible-base/ansible.cfg - -scenario: - name: libvirt-staging-xenial - test_sequence: - - destroy - - create - - converge - - verify -verifier: - name: testinfra - lint: | - flake8 - directory: ../testinfra - options: - n: auto - v: 2 - junit-xml: ../../junit/testinfra-results.xml - env: - SECUREDROP_TARGET_DISTRIBUTION: xenial diff --git a/molecule/libvirt-staging-xenial/prepare.yml b/molecule/libvirt-staging-xenial/prepare.yml deleted file mode 100644 index 112da19982..0000000000 --- a/molecule/libvirt-staging-xenial/prepare.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: Prepare - hosts: all - gather_facts: False - tasks: - - name: Install python for Ansible - raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal) - become: True - changed_when: False diff --git a/molecule/qubes-staging-xenial/create.yml b/molecule/qubes-staging-xenial/create.yml deleted file mode 100644 index 77234875ac..0000000000 --- a/molecule/qubes-staging-xenial/create.yml +++ /dev/null @@ -1,85 +0,0 @@ ---- -- name: Create - hosts: localhost - connection: local - vars: - molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}" - molecule_instance_config: "{{ lookup('env', 'MOLECULE_INSTANCE_CONFIG') }}" - molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}" - tasks: - - name: Check that Qubes admin tools are installed - shell: > - which qvm-clone - || { echo 'qvm-clone not found, install qubes-core-admin-client'; - exit 1; } - changed_when: false - - - name: Clone base image for staging VMs - # The "ignore-errors" flag sidesteps an issue with qvm-sync-appmenus. We don't need - # app menus for the SD VMs, so an error there need not block provisioning. - command: qvm-clone {{ item.vm_base }} {{ item.vm_name }} --ignore-errors - register: clone_result - failed_when: >- - clone_result.rc != 0 and "qvm-clone: error: VM "+item.vm_name+" already exists" not in clone_result.stderr_lines - changed_when: >- - clone_result.rc == 0 and clone_result.stdout == "" - with_items: "{{ molecule_yml.platforms }}" - - - name: Start Qubes VMs - command: qvm-start {{ item.vm_name }} - register: start_result - failed_when: >- - start_result.rc != 0 and "domain "+item.vm_name+" is already running" not in start_result.stderr_lines - changed_when: >- - start_result.rc == 0 and start_result.stdout == "" - with_items: "{{ molecule_yml.platforms }}" - - - name: Wait for VMs to boot - pause: - seconds: 15 - when: start_result.changed - - - name: Get IP address for instances - command: qvm-ls --raw-data --field ip {{ item.vm_name }} - register: server_info - changed_when: false - # Not necessary, using pipe lookup to avoid convoluted Jinja logic. - when: false - with_items: "{{ molecule_yml.platforms }}" - - # Mandatory configuration for Molecule to function. - - - name: Populate instance config dict - set_fact: - instance_conf_dict: - instance: "{{ item.name }}" - address: "{{ lookup('pipe', 'qvm-ls --raw-data --field ip '+item.vm_name) }}" - identity_file: "~/.ssh/id_rsa" - port: "22" - # Hardcoded username, must match the username manually configured during - # base VM creation (see developer documentation). - user: "sdadmin" - with_items: "{{ molecule_yml.platforms }}" - register: instance_config_dict - when: start_result.changed | bool - - - name: Convert instance config dict to a list - set_fact: - instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}" - when: start_result.changed | bool - - - name: render ssh_config for instances - template: - src: ssh_config.j2 - dest: "/tmp/molecule-qubes-ssh-config" - when: start_result.changed | bool - - - debug: var=instance_conf - - - name: Dump instance config - copy: - # NOTE(retr0h): Workaround for Ansible 2.2. - # https://github.com/ansible/ansible/issues/20885 - content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" - dest: "{{ molecule_instance_config }}" - when: start_result.changed | bool diff --git a/molecule/qubes-staging-xenial/destroy.yml b/molecule/qubes-staging-xenial/destroy.yml deleted file mode 100644 index 1c33e3facd..0000000000 --- a/molecule/qubes-staging-xenial/destroy.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- - -- name: Destroy - hosts: localhost - connection: local - vars: - molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}" - molecule_instance_config: "{{ lookup('env',' MOLECULE_INSTANCE_CONFIG') }}" - molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}" - molecule_ephemeral_directory: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}" - tasks: - - name: Check that Qubes admin tools are installed - shell: > - which qvm-clone - || { echo 'qvm-clone not found, install qubes-core-admin-client'; - exit 1; } - changed_when: false - - - name: Halt molecule instance(s) - command: qvm-shutdown --wait "{{ item.vm_name }}" - register: server - failed_when: >- - server.rc != 0 and "qvm-shutdown: error: no such domain: '"+item.vm_name+"'" not in server.stderr_lines - with_items: "{{ molecule_yml.platforms }}" - - - name: Destroy molecule instance(s) - command: qvm-remove --force "{{ item.vm_name }}" - register: server - failed_when: >- - server.rc != 0 and "qvm-remove: error: no such domain: '"+item.vm_name+"'" not in server.stderr_lines - with_items: "{{ molecule_yml.platforms }}" - - # Mandatory configuration for Molecule to function. - - - name: Populate instance config - set_fact: - instance_conf: {} - - - name: Dump instance config - copy: - # NOTE(retr0h): Workaround for Ansible 2.2. - # https://github.com/ansible/ansible/issues/20885 - content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" - dest: "{{ molecule_instance_config }}" - when: server.changed | bool diff --git a/molecule/qubes-staging-xenial/molecule.yml b/molecule/qubes-staging-xenial/molecule.yml deleted file mode 100644 index 0537696411..0000000000 --- a/molecule/qubes-staging-xenial/molecule.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- -driver: - name: delegated - options: - managed: True - login_cmd_template: 'ssh {instance} -F /tmp/molecule-qubes-ssh-config' - ansible_connection_options: - connection: ssh - ansible_ssh_common_args: -F /tmp/molecule-qubes-ssh-config - ansible_become_pass: securedrop - -platforms: - - name: app-staging - vm_base: sd-staging-app-base-xenial - vm_name: sd-staging-app-xenial - groups: - - securedrop_application_server - - staging - - - name: mon-staging - vm_base: sd-staging-mon-base-xenial - vm_name: sd-staging-mon-xenial - groups: - - securedrop_monitor_server - - staging - -provisioner: - name: ansible - lint: | - ansible-lint - config_options: - defaults: - callback_whitelist: "profile_tasks, timer" - interpreter_python: auto - options: - e: "@qubes-vars.yml" - playbooks: - converge: ../../install_files/ansible-base/securedrop-staging.yml - env: - ANSIBLE_CONFIG: ../../install_files/ansible-base/ansible.cfg -scenario: - name: qubes-staging-xenial - # Skip unnecessary "prepare" step in create sequence - create_sequence: - - create - test_sequence: - - destroy - - create - - converge -verifier: - name: testinfra - lint: | - flake8 - directory: ../testinfra - options: - n: auto - v: 2 - env: - SECUREDROP_TARGET_DISTRIBUTION: xenial - SECUREDROP_TESTINFRA_TARGET_HOST: qubes-staging diff --git a/molecule/qubes-staging-xenial/qubes-vars.yml b/molecule/qubes-staging-xenial/qubes-vars.yml deleted file mode 100644 index 88d04e3154..0000000000 --- a/molecule/qubes-staging-xenial/qubes-vars.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -# Support dynamic lookups for Qubes host IPs. The staging vars -# in the Ansible config still assume hardcoded Vagrant-only IPs. -app_ip: "{{ hostvars['app-staging']['ansible_default_ipv4'].address }}" -monitor_ip: "{{ hostvars['mon-staging']['ansible_default_ipv4'].address }}" - -# Use hardcoded username from the manual VM provisioning step. -ssh_users: sdadmin - -securedrop_target_distribution: xenial - -# Inform the Ansible logic we're targeting Qubes staging VMs, -# helps to customize the reboot logic. -securedrop_staging_qubes_env: True diff --git a/molecule/qubes-staging-xenial/ssh_config.j2 b/molecule/qubes-staging-xenial/ssh_config.j2 deleted file mode 100644 index 4a51d69162..0000000000 --- a/molecule/qubes-staging-xenial/ssh_config.j2 +++ /dev/null @@ -1,8 +0,0 @@ -{% for host in instance_conf %} -Host {{ host.instance }} - HostName {{ host.address }} - Port {{ host.port }} - IdentityFile {{ host.identity_file }} - PreferredAuthentications publickey - User {{ host.user }} -{%endfor%} diff --git a/molecule/virtualbox-staging-xenial/ansible-override-vars.yml b/molecule/virtualbox-staging-xenial/ansible-override-vars.yml deleted file mode 100644 index 05c029a0ca..0000000000 --- a/molecule/virtualbox-staging-xenial/ansible-override-vars.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Permit direct access via SSH -ssh_net_in_override: 0.0.0.0/0 - -# In libvirt, we want to connect over eth0, not eth1 which is used for -# inter-VM communication for OSSEC. -ssh_ip: "{{ ansible_default_ipv4.address }}" diff --git a/molecule/virtualbox-staging-xenial/molecule.yml b/molecule/virtualbox-staging-xenial/molecule.yml deleted file mode 100644 index 3268a75968..0000000000 --- a/molecule/virtualbox-staging-xenial/molecule.yml +++ /dev/null @@ -1,69 +0,0 @@ ---- -driver: - name: vagrant - provider: - name: libvirt -lint: | - yamllint - -platforms: - - name: app-staging - box: bento/ubuntu-16.04 - instance_raw_config_args: - - "vm.synced_folder './', '/vagrant', disabled: true" - - "vm.network 'private_network', ip: '10.0.1.2'" - - "ssh.insert_key = false" - memory: 1024 - private_ip: 10.0.1.2 - groups: - - securedrop_application_server - - securedrop - - staging - - - name: mon-staging - box: bento/ubuntu-16.04 - instance_raw_config_args: - - "vm.synced_folder './', '/vagrant', disabled: true" - - "vm.network 'private_network', ip: '10.0.1.3'" - - "ssh.insert_key = false" - memory: 1024 - private_ip: 10.0.1.3 - groups: - - securedrop_monitor_server - - securedrop - - staging - -provisioner: - name: ansible - lint: | - ansible-lint - config_options: - defaults: - interpreter_python: auto - options: - e: "@ansible-override-vars.yml" - playbooks: - converge: ../../install_files/ansible-base/securedrop-staging.yml - create: ../libvirt-staging-xenial/create.yml - destroy: ../libvirt-staging-xenial/destroy.yml - prepare: ../libvirt-staging-xenial/prepare.yml - env: - ANSIBLE_CONFIG: ../../install_files/ansible-base/ansible.cfg - -scenario: - name: virtualbox-staging-xenial - test_sequence: - - destroy - - create - - converge - - verify -verifier: - name: testinfra - lint: | - flake8 - directory: ../testinfra - options: - n: auto - v: 2 - env: - SECUREDROP_TARGET_DISTRIBUTION: xenial diff --git a/update_version.sh b/update_version.sh index 908cd93736..6109ecfc13 100755 --- a/update_version.sh +++ b/update_version.sh @@ -50,7 +50,7 @@ sed -i "s@$(echo "${OLD_VERSION}" | sed 's/\./\\./g')@$NEW_VERSION@g" securedrop sed -E -i "s/^(securedrop_version: \").*/\1$NEW_VERSION\"/" install_files/ansible-base/group_vars/all/securedrop # Update the version in molecule testinfra vars -sed -i "s@$(echo "${OLD_VERSION}" | sed 's/\./\\./g')@$NEW_VERSION@g" molecule/builder-xenial/tests/vars.yml +sed -i "s@$(echo "${OLD_VERSION}" | sed 's/\./\\./g')@$NEW_VERSION@g" molecule/builder-focal/tests/vars.yml # If version doesn't have an rc designator, it's considered stable. # The upgrade testing logic relies on this variable. From 5a486834923a9569eea33d3f112864206a6089c6 Mon Sep 17 00:00:00 2001 From: John Hensley Date: Wed, 21 Apr 2021 14:28:30 -0400 Subject: [PATCH 06/12] Update the Focal Dockerfile --- securedrop/dockerfiles/focal/python3/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/securedrop/dockerfiles/focal/python3/Dockerfile b/securedrop/dockerfiles/focal/python3/Dockerfile index aaad8e19e4..b040fc5f96 100644 --- a/securedrop/dockerfiles/focal/python3/Dockerfile +++ b/securedrop/dockerfiles/focal/python3/Dockerfile @@ -1,5 +1,5 @@ -# ubuntu 20.04 image from 2020-09-26 -FROM ubuntu@sha256:2e70e9c81838224b5311970dbf7ed16802fbfe19e7a70b3cbfa3d7522aa285b4 +# ubuntu 20.04 image from 2021-04-03 +FROM ubuntu@sha256:3c9c713e0979e9bd6061ed52ac1e9e1f246c9495aa063619d9d695fb8039aa1f ARG USER_NAME ENV USER_NAME ${USER_NAME:-root} ARG USER_ID From b3c8a43b9b5f207d4e25c7e6b8a22ac612ab4531 Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Thu, 22 Apr 2021 19:33:29 +0530 Subject: [PATCH 07/12] Removes all EOL related code and tests --- securedrop/journalist_app/__init__.py | 8 --- securedrop/server_os.py | 26 +-------- securedrop/source_app/__init__.py | 12 ---- securedrop/tests/test_journalist.py | 59 -------------------- securedrop/tests/test_source.py | 80 --------------------------- 5 files changed, 1 insertion(+), 184 deletions(-) diff --git a/securedrop/journalist_app/__init__.py b/securedrop/journalist_app/__init__.py index 920e56a356..88994fe43c 100644 --- a/securedrop/journalist_app/__init__.py +++ b/securedrop/journalist_app/__init__.py @@ -23,7 +23,6 @@ JournalistInterfaceSessionInterface, cleanup_expired_revoked_tokens) from models import InstanceConfig, Journalist -from server_os import is_os_near_eol, is_os_past_eol from store import Storage import typing @@ -72,8 +71,6 @@ def create_app(config: 'SDConfig') -> Flask: app.config['SQLALCHEMY_DATABASE_URI'] = config.DATABASE_URI db.init_app(app) - app.config.update(OS_PAST_EOL=is_os_past_eol(), OS_NEAR_EOL=is_os_near_eol()) - # TODO: Attaching a Storage dynamically like this disables all type checking (and # breaks code analysis tools) for code that uses current_app.storage; it should be refactored app.storage = Storage(config.STORE_DIR, @@ -179,11 +176,6 @@ def setup_g() -> 'Optional[Response]': except FileNotFoundError: app.logger.error("Site logo not found.") - if app.config["OS_PAST_EOL"]: - g.show_os_past_eol_warning = True - elif app.config["OS_NEAR_EOL"]: - g.show_os_near_eol_warning = True - if request.path.split('/')[1] == 'api': pass # We use the @token_required decorator for the API endpoints else: # We are not using the API diff --git a/securedrop/server_os.py b/securedrop/server_os.py index 0bac8fa743..a9107ba6c2 100644 --- a/securedrop/server_os.py +++ b/securedrop/server_os.py @@ -1,38 +1,14 @@ import functools import subprocess -from datetime import date FOCAL_VERSION = "20.04" -@functools.lru_cache() -def get_xenial_eol_date() -> date: - return date(2021, 4, 30) - - @functools.lru_cache() def get_os_release() -> str: return subprocess.run( - ["lsb_release", "--release", "--short"], + ["/usr/bin/lsb_release", "--release", "--short"], check=True, stdout=subprocess.PIPE, universal_newlines=True ).stdout.strip() - - -def is_os_past_eol() -> bool: - """ - Assumption: Any OS that is not Focal is an earlier version of the OS. - """ - if get_os_release() != FOCAL_VERSION and date.today() > get_xenial_eol_date(): - return True - return False - - -def is_os_near_eol() -> bool: - """ - Assumption: Any OS that is not Focal is an earlier version of the OS. - """ - if get_os_release() != FOCAL_VERSION and date.today() <= get_xenial_eol_date(): - return True - return False diff --git a/securedrop/source_app/__init__.py b/securedrop/source_app/__init__.py index 37297e2392..f2781e5d5a 100644 --- a/securedrop/source_app/__init__.py +++ b/securedrop/source_app/__init__.py @@ -26,7 +26,6 @@ from source_app.decorators import ignore_static from source_app.utils import logged_in, was_in_generate_flow from store import Storage -from server_os import is_os_past_eol def get_logo_url(app: Flask) -> str: @@ -60,17 +59,6 @@ def setup_i18n() -> None: """Store i18n-related values in Flask's special g object""" i18n.set_locale(config) - app.config.update(OS_PAST_EOL=is_os_past_eol()) - - @app.before_request - @ignore_static - def disable_ui() -> Optional[str]: - if app.config["OS_PAST_EOL"]: - session.clear() - g.show_offline_message = True - return render_template("base.html") - return None - # The default CSRF token expiration is 1 hour. Since large uploads can # take longer than an hour over Tor, we increase the valid window to 24h. app.config['WTF_CSRF_TIME_LIMIT'] = 60 * 60 * 24 diff --git a/securedrop/tests/test_journalist.py b/securedrop/tests/test_journalist.py index b5ff436653..70b49d79c9 100644 --- a/securedrop/tests/test_journalist.py +++ b/securedrop/tests/test_journalist.py @@ -62,65 +62,6 @@ def _login_user(app, username, password, otp_secret): assert hasattr(g, 'user') # ensure logged in -def test_user_sees_os_warning_if_server_past_eol(config, journalist_app, test_journo): - journalist_app.config.update(OS_PAST_EOL=True, OS_NEAR_EOL=False) - with journalist_app.test_client() as app: - _login_user( - app, test_journo["username"], test_journo["password"], test_journo["otp_secret"] - ) - - resp = app.get(url_for("main.index")) - - text = resp.data.decode("utf-8") - assert 'id="os-past-eol"' in text, text - assert 'id="os-near-eol"' not in text, text - - -def test_user_sees_os_warning_if_server_past_eol_sanity_check(config, journalist_app, test_journo): - """ - Sanity check (both conditions cannot be True but test guard against developer error) - """ - journalist_app.config.update(OS_PAST_EOL=True, OS_NEAR_EOL=True) - with journalist_app.test_client() as app: - _login_user( - app, test_journo["username"], test_journo["password"], test_journo["otp_secret"] - ) - - resp = app.get(url_for("main.index")) - - text = resp.data.decode("utf-8") - assert 'id="os-past-eol"' in text, text - assert 'id="os-near-eol"' not in text, text - - -def test_user_sees_os_warning_if_server_close_to_eol(config, journalist_app, test_journo): - journalist_app.config.update(OS_PAST_EOL=False, OS_NEAR_EOL=True) - with journalist_app.test_client() as app: - _login_user( - app, test_journo["username"], test_journo["password"], test_journo["otp_secret"] - ) - - resp = app.get(url_for("main.index")) - - text = resp.data.decode("utf-8") - assert 'id="os-past-eol"' not in text, text - assert 'id="os-near-eol"' in text, text - - -def test_user_does_not_see_os_warning_if_server_is_current(config, journalist_app, test_journo): - journalist_app.config.update(OS_PAST_EOL=False, OS_NEAR_EOL=False) - with journalist_app.test_client() as app: - _login_user( - app, test_journo["username"], test_journo["password"], test_journo["otp_secret"] - ) - - resp = app.get(url_for("main.index")) - - text = resp.data.decode("utf-8") - assert 'id="os-past-eol"' not in text, text - assert 'id="os-near-eol"' not in text, text - - def test_user_with_whitespace_in_username_can_login(journalist_app): # Create a user with whitespace at the end of the username with journalist_app.app_context(): diff --git a/securedrop/tests/test_source.py b/securedrop/tests/test_source.py index 2cab8abd13..04cdd36421 100644 --- a/securedrop/tests/test_source.py +++ b/securedrop/tests/test_source.py @@ -38,86 +38,6 @@ overly_long_codename = 'a' * (PassphraseGenerator.MAX_PASSPHRASE_LENGTH + 1) -def test_source_interface_is_disabled_when_xenial_is_eol(config, source_app): - disabled_endpoints = [ - "main.index", - "main.generate", - "main.login", - "info.download_public_key", - "info.tor2web_warning", - "info.recommend_tor_browser", - "info.why_download_public_key", - ] - static_assets = [ - "css/source.css", - "i/custom_logo.png", - "i/font-awesome/fa-globe-black.png", - "i/favicon.png", - ] - with patch("server_os.get_os_release", return_value="16.04"): - with patch("server_os.get_xenial_eol_date", return_value=date(2020, 1, 1)): - app = source_app_module.create_app(config) - with app.test_client() as test_client: - for endpoint in disabled_endpoints: - resp = test_client.get(url_for(endpoint)) - assert resp.status_code == 200 - text = resp.data.decode("utf-8") - assert "We're sorry, our SecureDrop is currently offline." in text - # Ensure static assets are properly served - for asset in static_assets: - resp = test_client.get(url_for("static", filename=asset)) - assert resp.status_code == 200 - text = resp.data.decode("utf-8") - assert "We're sorry, our SecureDrop is currently offline." not in text - - -def test_source_interface_is_not_disabled_before_xenial_eol(config, source_app): - disabled_endpoints = [ - "main.index", - "main.generate", - "main.login", - "info.download_public_key", - "info.tor2web_warning", - "info.recommend_tor_browser", - "info.why_download_public_key", - ] - with patch("server_os.get_os_release", return_value="16.04"): - with patch("server_os.get_xenial_eol_date", return_value=date(2200, 1, 1)): - app = source_app_module.create_app(config) - with app.test_client() as test_client: - print( - "OS_RELEASE: {} EOL DATE: {}".format( - server_os.get_os_release(), server_os.get_xenial_eol_date() - ) - ) - for endpoint in disabled_endpoints: - resp = test_client.get(url_for(endpoint), follow_redirects=True) - assert resp.status_code == 200 - text = resp.data.decode("utf-8") - assert "We're sorry, our SecureDrop is currently offline." not in text - - -def test_source_interface_is_not_disabled_for_focal(config, source_app): - disabled_endpoints = [ - "main.index", - "main.generate", - "main.login", - "info.download_public_key", - "info.tor2web_warning", - "info.recommend_tor_browser", - "info.why_download_public_key", - ] - with patch("server_os.get_os_release", return_value="20.04"): - with patch("server_os.get_xenial_eol_date", return_value=date(2020, 1, 1)): - app = source_app_module.create_app(config) - with app.test_client() as test_client: - for endpoint in disabled_endpoints: - resp = test_client.get(url_for(endpoint)) - assert resp.status_code == 200 - text = resp.data.decode("utf-8") - assert "We're sorry, our SecureDrop is currently offline." not in text - - def test_logo_default_available(source_app): # if the custom image is available, this test will fail custom_image_location = os.path.join(config.SECUREDROP_ROOT, "static/i/custom_logo.png") From b8ef5d69ab5016569ce89889b5041376ce30738b Mon Sep 17 00:00:00 2001 From: Conor Schaefer Date: Wed, 28 Apr 2021 14:58:46 -0700 Subject: [PATCH 08/12] Removes Xenial-specific Ansible logic --- .../ansible-base/group_vars/all/securedrop | 10 +-- .../ansible-base/roles/common/files/0-update | 1 - .../roles/common/files/5-security | 3 - .../ansible-base/roles/common/files/9-remove | 1 - .../roles/common/files/cron-apt-config | 5 -- .../roles/common/tasks/cron_apt.yml | 70 ------------------- .../ansible-base/roles/common/tasks/main.yml | 10 --- .../tasks/post_ubuntu_install_checks.yml | 27 ------- .../roles/common/tasks/sysctl.yml | 13 ---- .../common/templates/cron-apt-cron-job.j2 | 11 --- .../roles/common/templates/security.list | 5 -- .../roles/common/vars/Ubuntu_xenial.yml | 19 ----- .../roles/grsecurity/defaults/main.yml | 5 -- .../tasks/from_fpf_repo_install_grsec.yml | 53 -------------- .../roles/grsecurity/tasks/main.yml | 7 -- .../roles/grsecurity/tasks/paxctl.yml | 28 -------- .../roles/install-fpf-repo/defaults/main.yml | 2 +- .../roles/install-fpf-repo/tasks/main.yml | 2 - .../tasks/validate_apt_version.yml | 16 ----- .../restrict-direct-access/defaults/main.yml | 4 +- .../restrict-direct-access/tasks/iptables.yml | 19 ----- 21 files changed, 7 insertions(+), 304 deletions(-) delete mode 100644 install_files/ansible-base/roles/common/files/0-update delete mode 100644 install_files/ansible-base/roles/common/files/5-security delete mode 100644 install_files/ansible-base/roles/common/files/9-remove delete mode 100644 install_files/ansible-base/roles/common/files/cron-apt-config delete mode 100644 install_files/ansible-base/roles/common/tasks/cron_apt.yml delete mode 100644 install_files/ansible-base/roles/common/templates/cron-apt-cron-job.j2 delete mode 100644 install_files/ansible-base/roles/common/templates/security.list delete mode 100644 install_files/ansible-base/roles/common/vars/Ubuntu_xenial.yml delete mode 100644 install_files/ansible-base/roles/grsecurity/tasks/paxctl.yml delete mode 100644 install_files/ansible-base/roles/install-fpf-repo/tasks/validate_apt_version.yml diff --git a/install_files/ansible-base/group_vars/all/securedrop b/install_files/ansible-base/group_vars/all/securedrop index 4353bc14f8..f958ffc1cd 100644 --- a/install_files/ansible-base/group_vars/all/securedrop +++ b/install_files/ansible-base/group_vars/all/securedrop @@ -26,7 +26,7 @@ apparmor_profiles: - usr.sbin.apache2 # Installing the securedrop-app-code.deb package -securedrop_target_distribution: xenial +securedrop_target_distribution: focal securedrop_app_code_deb: "securedrop-app-code_{{ securedrop_version }}+{{ securedrop_target_distribution }}_amd64" # do not enter .deb extension # Enable Tor over SSH by default @@ -37,14 +37,10 @@ enable_ssh_over_tor: true # the many roles of the current prod playbook securedrop_cond_reboot_file: /tmp/sd-reboot-now -# If you bump this, also remember to bump in molecule/builder-xenial/tests/vars.yml -securedrop_pkg_grsec_xenial: - ver: "4.14.188" - depends: "linux-image-4.14.188-grsec-securedrop,linux-image-4.14.175-grsec-securedrop,intel-microcode" - +# If you bump this, also remember to bump in molecule/builder-focal/tests/vars.yml securedrop_pkg_grsec_focal: ver: "5.4.97" depends: "linux-image-5.4.97-grsec-securedrop,intel-microcode" # Mostly useful for local package installation -grsec_version: "{{ securedrop_pkg_grsec_xenial.ver if securedrop_target_distribution == 'xenial' else securedrop_pkg_grsec_focal.ver }}" +grsec_version: "{{ securedrop_pkg_grsec_focal.ver }}" diff --git a/install_files/ansible-base/roles/common/files/0-update b/install_files/ansible-base/roles/common/files/0-update deleted file mode 100644 index b60b116b2d..0000000000 --- a/install_files/ansible-base/roles/common/files/0-update +++ /dev/null @@ -1 +0,0 @@ -update -o quiet=2 -o Dir::Etc::SourceList=/etc/apt/security.list -o Dir::Etc::SourceParts="" diff --git a/install_files/ansible-base/roles/common/files/5-security b/install_files/ansible-base/roles/common/files/5-security deleted file mode 100644 index 8542bc82be..0000000000 --- a/install_files/ansible-base/roles/common/files/5-security +++ /dev/null @@ -1,3 +0,0 @@ -autoclean -y -dist-upgrade -y -o APT::Get::Show-Upgraded=true -o Dir::Etc::SourceList=/etc/apt/security.list -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold -autoremove -y diff --git a/install_files/ansible-base/roles/common/files/9-remove b/install_files/ansible-base/roles/common/files/9-remove deleted file mode 100644 index eb3890ce0e..0000000000 --- a/install_files/ansible-base/roles/common/files/9-remove +++ /dev/null @@ -1 +0,0 @@ -remove -y linux-image-generic-lts-xenial linux-image-.*generic -o quiet=2 diff --git a/install_files/ansible-base/roles/common/files/cron-apt-config b/install_files/ansible-base/roles/common/files/cron-apt-config deleted file mode 100644 index 631c420e87..0000000000 --- a/install_files/ansible-base/roles/common/files/cron-apt-config +++ /dev/null @@ -1,5 +0,0 @@ -# Configuration for cron-apt. For further information about the possible -# configuration settings see /usr/share/doc/cron-apt/README.gz. - -SYSLOGON="always" -EXITON=error diff --git a/install_files/ansible-base/roles/common/tasks/cron_apt.yml b/install_files/ansible-base/roles/common/tasks/cron_apt.yml deleted file mode 100644 index fe405db54a..0000000000 --- a/install_files/ansible-base/roles/common/tasks/cron_apt.yml +++ /dev/null @@ -1,70 +0,0 @@ ---- -- name: Install cron-apt for unattended security upgrades. - apt: - name: cron-apt - state: latest - tags: - - apt - - cron-apt - -- name: Copy cron-apt config file. - copy: - src: cron-apt-config - dest: /etc/cron-apt/config - tags: - - apt - - cron-apt - -- name: Add security.list apt configuration. - template: - src: security.list - dest: /etc/apt/security.list - tags: - - apt - -- name: Configure cron-apt to update the security.list repos. - copy: - src: 0-update - dest: /etc/cron-apt/action.d/0-update - tags: - - apt - - cron-apt - - # This action is also added by the securedrop-config package as of 0.1.1 to provide - # this logic for existing installs. -- name: Configure cron-apt to remove vanilla kernels if they are installed. - copy: - src: 9-remove - dest: /etc/cron-apt/action.d/9-remove - tags: - - apt - - cron-apt - -- name: Configure cron-apt to upgrade the packages in the security.list repos. - copy: - src: 5-security - dest: /etc/cron-apt/action.d/5-security - tags: - - apt - - cron-apt - - # The default config file would download all security update every night - # regardless if they were a security update. we only need it download and - # install the security updates. -- name: Remove default cron-apt config file for downloading all updates. - file: - dest: /etc/cron-apt/action.d/3-download - state: absent - tags: - - apt - - cron-apt - -- name: Create cron job for running cron-apt updates nightly. - template: - src: cron-apt-cron-job.j2 - dest: /etc/cron.d/cron-apt - mode: "0644" - owner: root - tags: - - apt - - cron-apt diff --git a/install_files/ansible-base/roles/common/tasks/main.yml b/install_files/ansible-base/roles/common/tasks/main.yml index 6db46f612e..8800b9f3f0 100644 --- a/install_files/ansible-base/roles/common/tasks/main.yml +++ b/install_files/ansible-base/roles/common/tasks/main.yml @@ -2,8 +2,6 @@ - include_vars: "{{ ansible_distribution }}_{{ ansible_distribution_release }}.yml" - include: apt_sources.yml - when: - - ansible_distribution_release == "focal" - include: apt_upgrade.yml @@ -17,15 +15,7 @@ - include: harden_dns.yml -- include: cron_apt.yml - when: - - ansible_distribution_release == "xenial" - tags: - - reboot - - include: unattended_upgrades.yml - when: - - ansible_distribution_release == "focal" tags: - ua - reboot diff --git a/install_files/ansible-base/roles/common/tasks/post_ubuntu_install_checks.yml b/install_files/ansible-base/roles/common/tasks/post_ubuntu_install_checks.yml index bad4bed79b..1dba316ad3 100644 --- a/install_files/ansible-base/roles/common/tasks/post_ubuntu_install_checks.yml +++ b/install_files/ansible-base/roles/common/tasks/post_ubuntu_install_checks.yml @@ -31,34 +31,11 @@ tags: - dns -# We expect that once ntpd is running, the socket will be in use, so we -# ignore errors in the below task. However, if the command fails for some other -# reason, we want to fail the task, so we inspect the error output. -- name: Ensure the system clock is set accurately. - command: "ntpdate ntp.ubuntu.com" - register: ntpdate_result - changed_when: "'offset' in ntpdate_result.stdout" - ignore_errors: yes - become: yes - when: ansible_distribution_release == "xenial" - tags: - - ntp - -- name: See if ntpd is already running. - fail: - msg: "{{ ntpdate_result.stderr }}" - when: - - ansible_distribution_release == "xenial" - - "ntpdate_result.rc != 0 and 'NTP socket is in use' not in ntpdate_result.stderr" - tags: - - ntp - - name: Disable VirtualBox services to avoid conflict with systemd-timesyncd. systemd: name: "{{ item }}" enabled: no state: stopped - when: ansible_distribution_release == "focal" failed_when: false with_items: - vboxadd @@ -73,14 +50,12 @@ enabled: yes masked: no state: started - when: ansible_distribution_release == "focal" become: yes tags: - ntp - name: Ensure NTP is enabled. command: "timedatectl set-ntp 1" - when: ansible_distribution_release == "focal" become: yes tags: - ntp @@ -88,7 +63,6 @@ - name: Verify time service configuration. command: "timedatectl show" register: timedatectl_show_result - when: ansible_distribution_release == "focal" become: yes changed_when: - "'\nNTP=yes' in timedatectl_show_result.stdout" @@ -99,7 +73,6 @@ - name: Ensure the system clock is set accurately. command: "timedatectl show-timesync" register: timedatectl_show_timesync_result - when: ansible_distribution_release == "focal" become: yes changed_when: - "'\nNTPMessage=' in timedatectl_show_timesync_result.stdout" diff --git a/install_files/ansible-base/roles/common/tasks/sysctl.yml b/install_files/ansible-base/roles/common/tasks/sysctl.yml index 5c542cb4ea..e05adc5415 100644 --- a/install_files/ansible-base/roles/common/tasks/sysctl.yml +++ b/install_files/ansible-base/roles/common/tasks/sysctl.yml @@ -12,16 +12,3 @@ tags: - sysctl - hardening - -- name: Set sysctl flags for net.ipv6 config. - sysctl: - name: "{{ item.name }}" - value: "{{ item.value }}" - sysctl_set: yes - state: present - reload: yes - with_items: "{{ sysctl_flags_ipv6 }}" - when: ansible_distribution_release == "xenial" - tags: - - sysctl - - hardening diff --git a/install_files/ansible-base/roles/common/templates/cron-apt-cron-job.j2 b/install_files/ansible-base/roles/common/templates/cron-apt-cron-job.j2 deleted file mode 100644 index af4623c2cf..0000000000 --- a/install_files/ansible-base/roles/common/templates/cron-apt-cron-job.j2 +++ /dev/null @@ -1,11 +0,0 @@ -# -# Regular cron jobs for the cron-apt package -# - -# Every night at {{ daily_reboot_time }}:00 AM run cron-apt, then reboot. -# Note that cron-apt sleeps for 0-60 minutes when run -# noninteractively (e.g. in this cron job), so the actual -# start time may be as much as an hour later. Only reboot -# if cron-apt exited successfully, so broken or partially -# installed packages don't cause problems with booting. -0 {{ daily_reboot_time }} * * * root /usr/bin/test -x /usr/sbin/cron-apt && /usr/sbin/cron-apt && /sbin/reboot diff --git a/install_files/ansible-base/roles/common/templates/security.list b/install_files/ansible-base/roles/common/templates/security.list deleted file mode 100644 index 9baf91838a..0000000000 --- a/install_files/ansible-base/roles/common/templates/security.list +++ /dev/null @@ -1,5 +0,0 @@ -deb http://security.ubuntu.com/ubuntu {{ ansible_distribution_release }}-security main -deb-src http://security.ubuntu.com/ubuntu {{ ansible_distribution_release }}-security main -deb http://security.ubuntu.com/ubuntu {{ ansible_distribution_release }}-security universe -deb-src http://security.ubuntu.com/ubuntu {{ ansible_distribution_release }}-security universe -deb [arch=amd64] {{ apt_repo_url }} {{ ansible_distribution_release }} main diff --git a/install_files/ansible-base/roles/common/vars/Ubuntu_xenial.yml b/install_files/ansible-base/roles/common/vars/Ubuntu_xenial.yml deleted file mode 100644 index bc373e4c5b..0000000000 --- a/install_files/ansible-base/roles/common/vars/Ubuntu_xenial.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -securedrop_kernel_packages_to_remove: - - linux-signed-generic - - linux-signed-generic-lts-utopic - - linux-signed-image-generic - - linux-signed-image-generic-lts-utopic - - linux-image-generic-lts-xenial - - 'linux-image-.*generic' - - 'linux-headers-.*' - -resolvconf_target_filepath: /etc/resolvconf/resolv.conf.d/base - -securedrop_common_packages: - - apt-transport-https - - cron-apt - - ntp - - ntpdate - - resolvconf - - tmux diff --git a/install_files/ansible-base/roles/grsecurity/defaults/main.yml b/install_files/ansible-base/roles/grsecurity/defaults/main.yml index d6ae096311..4d245bdcff 100644 --- a/install_files/ansible-base/roles/grsecurity/defaults/main.yml +++ b/install_files/ansible-base/roles/grsecurity/defaults/main.yml @@ -11,8 +11,3 @@ grsec_sysctl_flags: # exist otherwise. - name: "vm.heap_stack_gap" value: "1048576" - -# Lookup table for how to create PaX flags, depending on OS. -paxctl_header_type: - xenial: C - focal: c diff --git a/install_files/ansible-base/roles/grsecurity/tasks/from_fpf_repo_install_grsec.yml b/install_files/ansible-base/roles/grsecurity/tasks/from_fpf_repo_install_grsec.yml index 9844443b0a..adc6e8775f 100644 --- a/install_files/ansible-base/roles/grsecurity/tasks/from_fpf_repo_install_grsec.yml +++ b/install_files/ansible-base/roles/grsecurity/tasks/from_fpf_repo_install_grsec.yml @@ -37,56 +37,3 @@ - grsec - kernel - hardening - -- name: Get grsec kernel string from grub config. - shell: grep menuentry /boot/grub/grub.cfg | grep grsec | grep -v recovery | head -1 | cut -d "'" -f2 - # Read-only task for - changed_when: false - register: grsec_str - when: ansible_distribution_release == "xenial" - tags: - - grsec - - kernel - - hardening - -- name: Check initial default grub entry for next boot. - stat: - path: /boot/grub/grubenv - register: grubenv_check_initial_result - when: ansible_distribution_release == "xenial" - tags: - - grsec - - grub - - hardening - - kernel - -- name: Set grsec kernel as default for next boot. - command: grub-reboot "Advanced options for Ubuntu>{{ grsec_str.stdout }}" - # The grub-reboot command writes to /boot/grub/grubenv, - # so "changed" status can only be determined by comparing - # checksums on that file. We'll do so in the subsequent task. - changed_when: false - when: ansible_distribution_release == "xenial" - tags: - - grsec - - grub - - hardening - - kernel - - # Kludge to detect changes accurately from the `grub-reboot` command - # in the previous task. We're just comparing checksums on the - # /boot/grub/grubenv file before and after the command, since that's - # where `grub-reboot` writes its changes. Hopefully a future version - # of Ansible will provide an `args: changes:` parameter to command calls. -- name: Check customized default grub entry for next boot. - stat: - path: /boot/grub/grubenv - register: grubenv_check_configured_result - changed_when: grubenv_check_initial_result.stat.checksum != - grubenv_check_configured_result.stat.checksum - when: ansible_distribution_release == "xenial" - tags: - - grsec - - grub - - hardening - - kernel diff --git a/install_files/ansible-base/roles/grsecurity/tasks/main.yml b/install_files/ansible-base/roles/grsecurity/tasks/main.yml index 298cf1eb08..1a397ff806 100644 --- a/install_files/ansible-base/roles/grsecurity/tasks/main.yml +++ b/install_files/ansible-base/roles/grsecurity/tasks/main.yml @@ -3,13 +3,6 @@ # since that fact will be used in multiple includes. - include: check_installation.yml -- include: paxctl.yml - when: ansible_distribution_release == "xenial" - tags: - - paxctl - - kernel - - hardening - # Install the grsec kernel prior to running unattended-upgrades to avoid # reboots - include: from_fpf_repo_install_grsec.yml diff --git a/install_files/ansible-base/roles/grsecurity/tasks/paxctl.yml b/install_files/ansible-base/roles/grsecurity/tasks/paxctl.yml deleted file mode 100644 index e4b0c8b991..0000000000 --- a/install_files/ansible-base/roles/grsecurity/tasks/paxctl.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: Install paxctl. - apt: - pkg: paxctl - state: present - tags: - - apt - -- name: Check paxctl headers on grub binaries. - command: paxctl -vQ {{ item }} - # Read-only task, so don't report changed - changed_when: false - # The first time this task is run, the grub binaries won't have - # their headers converted yet, which will cause paxctl to exit 1. - # We'll catch that error and respond accordingly in the next task. - failed_when: false - register: paxctl_grub_header_check - with_items: - - /usr/sbin/grub-probe - - /usr/sbin/grub-mkdevicemap - - /usr/bin/grub-script-check - -- name: Adjust paxctl headers on grub binaries. - command: paxctl -z{{ paxctl_header_type[ansible_distribution_release] }}E {{ item.item }} - with_items: "{{ paxctl_grub_header_check.results }}" - when: > - item.stdout != '- PaX flags: --------E--- ['+item.item+']' - or item.rc != 0 diff --git a/install_files/ansible-base/roles/install-fpf-repo/defaults/main.yml b/install_files/ansible-base/roles/install-fpf-repo/defaults/main.yml index d186993dfe..4248cb9db8 100644 --- a/install_files/ansible-base/roles/install-fpf-repo/defaults/main.yml +++ b/install_files/ansible-base/roles/install-fpf-repo/defaults/main.yml @@ -22,5 +22,5 @@ install_local_packages: False apt_repo_pubkey_files: - fpf-signing-key.pub -# Enabling support for xenial by default. +# As of v2.0.0, only Focal is supported. apt_repo_target_distro: "{{ ansible_distribution_release }}" diff --git a/install_files/ansible-base/roles/install-fpf-repo/tasks/main.yml b/install_files/ansible-base/roles/install-fpf-repo/tasks/main.yml index debe63d81a..cc59d495fc 100644 --- a/install_files/ansible-base/roles/install-fpf-repo/tasks/main.yml +++ b/install_files/ansible-base/roles/install-fpf-repo/tasks/main.yml @@ -1,6 +1,4 @@ --- -- include: validate_apt_version.yml - - name: Install SecureDrop apt repo GPG signing key. apt_key: state: present diff --git a/install_files/ansible-base/roles/install-fpf-repo/tasks/validate_apt_version.yml b/install_files/ansible-base/roles/install-fpf-repo/tasks/validate_apt_version.yml deleted file mode 100644 index 9e75b724fc..0000000000 --- a/install_files/ansible-base/roles/install-fpf-repo/tasks/validate_apt_version.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -# Test for CVE-2019-3462 (see https://justi.cz/security/2019/01/22/apt-rce.html) -# If apt < 1.4.9, it is vulnerable to CVE-2019-3462 and we must ensure no -# redirects are followed when updating apt via apt. -- name: Get apt version - shell: dpkg-query --showformat='${Version}' --show apt - register: _apt_query_command_output_result - changed_when: false - tags: - - apt - -- name: Verify that the version of apt installed is not vulnerable to 2019-3462 (Xenial) - assert: - that: _apt_query_command_output_result.stdout is version('1.2.29ubuntu0.1', '>=') - tags: - - apt diff --git a/install_files/ansible-base/roles/restrict-direct-access/defaults/main.yml b/install_files/ansible-base/roles/restrict-direct-access/defaults/main.yml index d1fa879a83..c8ed96d012 100644 --- a/install_files/ansible-base/roles/restrict-direct-access/defaults/main.yml +++ b/install_files/ansible-base/roles/restrict-direct-access/defaults/main.yml @@ -41,4 +41,6 @@ tor_v3_service_map: app-ssh.auth_private: "app_ssh_private_key" mon-ssh.auth_private: "mon_ssh_private_key" -time_service_user: '{{ "root" if ansible_distribution_release == "xenial" else "systemd-timesync" }}' +# As of Ubuntu Focal 20.04, the time_server user is 'systemd-timesync', +# whereas earlier versions of Ubuntu used 'root'. +time_service_user: "systemd-timesync" diff --git a/install_files/ansible-base/roles/restrict-direct-access/tasks/iptables.yml b/install_files/ansible-base/roles/restrict-direct-access/tasks/iptables.yml index 05538598b8..18445e396b 100644 --- a/install_files/ansible-base/roles/restrict-direct-access/tasks/iptables.yml +++ b/install_files/ansible-base/roles/restrict-direct-access/tasks/iptables.yml @@ -21,25 +21,6 @@ delegate_to: localhost delegate_facts: True -- name: Copy load_iptables if-up script. - copy: - src: load_iptables - dest: /etc/network/if-up.d/load_iptables - owner: root - mode: "0744" - when: - - ansible_distribution_release == 'xenial' - -- name: Create iptables directory. - file: - state: directory - mode: "0700" - owner: root - group: root - dest: /etc/network/iptables - when: - - ansible_distribution_release == 'xenial' - - name: Determine local platform specific routing info set_fact: admin_route_map: "{{ admin_net_int[hostvars['localhost']['ansible_system']] }}" From bf8cefbbd58be5b568618b35f77bf4ac0c41d1e9 Mon Sep 17 00:00:00 2001 From: Conor Schaefer Date: Wed, 28 Apr 2021 15:33:49 -0700 Subject: [PATCH 09/12] Removes Xenial-specific packaging logic We had a few dual-distro packages. The Xenial versions are now removed. The postinst for the single "securedrop-app-code" pkg had some Xenial logic, so that's been removed. --- .../securedrop-app-code/debian/postinst | 18 ---- .../securedrop-config/DEBIAN/control.j2 | 10 -- .../securedrop-config/DEBIAN/postinst | 97 ------------------- .../etc/cron-apt/action.d/9-remove | 1 - .../etc/profile.d/securedrop_additions.sh | 22 ----- .../securedrop-grsec/DEBIAN/control.j2 | 12 --- .../securedrop-grsec/DEBIAN/postinst | 48 --------- .../etc/default/grub.d/50-mds-smt.cfg | 3 - .../etc/kernel/postinst.d/paxctl-grub | 17 ---- .../etc/sysctl.d/30-securedrop.conf | 1 - 10 files changed, 229 deletions(-) delete mode 100644 install_files/securedrop-config/DEBIAN/control.j2 delete mode 100755 install_files/securedrop-config/DEBIAN/postinst delete mode 100644 install_files/securedrop-config/etc/cron-apt/action.d/9-remove delete mode 100644 install_files/securedrop-config/etc/profile.d/securedrop_additions.sh delete mode 100644 install_files/securedrop-grsec/DEBIAN/control.j2 delete mode 100755 install_files/securedrop-grsec/DEBIAN/postinst delete mode 100644 install_files/securedrop-grsec/etc/default/grub.d/50-mds-smt.cfg delete mode 100755 install_files/securedrop-grsec/etc/kernel/postinst.d/paxctl-grub delete mode 100644 install_files/securedrop-grsec/etc/sysctl.d/30-securedrop.conf diff --git a/install_files/securedrop-app-code/debian/postinst b/install_files/securedrop-app-code/debian/postinst index 51f192822a..dd68e9eed4 100644 --- a/install_files/securedrop-app-code/debian/postinst +++ b/install_files/securedrop-app-code/debian/postinst @@ -104,27 +104,9 @@ remove_bytecode() { find "${SDVE}" -name '*.py[co]' -delete } -# 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,shredder,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-config/DEBIAN/control.j2 b/install_files/securedrop-config/DEBIAN/control.j2 deleted file mode 100644 index 5cf6e9b8e1..0000000000 --- a/install_files/securedrop-config/DEBIAN/control.j2 +++ /dev/null @@ -1,10 +0,0 @@ -Source: securedrop -Section: web -Priority: optional -Maintainer: SecureDrop Team -Homepage: https://securedrop.org -Package: securedrop-config -Version: 0.1.4+{{ securedrop_version }}+{{ securedrop_target_distribution }} -Architecture: all -Description: Establishes baseline system state for running SecureDrop. - Configures apt repositories. diff --git a/install_files/securedrop-config/DEBIAN/postinst b/install_files/securedrop-config/DEBIAN/postinst deleted file mode 100755 index ce47e15afe..0000000000 --- a/install_files/securedrop-config/DEBIAN/postinst +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/sh -# postinst script for securedrop-config - -set -e -set -x - -revert_update_release_available_script() { - for file in /usr/lib/ubuntu-release-upgrader/check-new-release /var/lib/ubuntu-release-upgrader/release-upgrade-available; do - if [ -f $file ]; then - sed -i "s|Visit https://securedrop\\.org/xenial-upgrade for more information|Run 'do-release-upgrade' to upgrade to it.|" "$file" - fi - done -} - -# Issue #4104 -# Set Prompt=never on Xenial -# Trusty logic update_release_available_script removed as part of issue #4341 -update_release_prompt() { - set -e - upgrade_config='/etc/update-manager/release-upgrades' - sed -i 's/Prompt=.*/Prompt=never/' "$upgrade_config" - revert_update_release_available_script -} - -remove_2fa_tty_req() { - # The goal here is to remove legacy 2FA req on TTY logins - # Lets prevent this from bombing out the install though if it fails - auth_file=/etc/pam.d/common-auth - sed -i "/^auth\ required\ pam_google.*/d" ${auth_file} || true - # Since we are removing the pam_google module, we must ensure password - # authentication for sshd is disabled to ensure only key authentication is used. - grep -qF "PasswordAuthentication no" /etc/ssh/sshd_config || echo "PasswordAuthentication no" >> /etc/ssh/sshd_config - sed -i "/^UsePAM\ /s/\ .*/\ no/" /etc/ssh/sshd_config - sed -i "/^ChallengeResponseAuthentication\ /s/\ .*/\ no/" /etc/ssh/sshd_config - service ssh restart -} - -allow_apt_user_in_iptables() { - rules_v4="/etc/network/iptables/rules_v4" - # During initial install, file won't exist on disk, so skip. - if [ -f "$rules_v4" ]; then - # Find already configured apt allow line, targeting root uid, and - # subsitute entire line, dropping the uid targeting entirely, - # so both Trusty and Xenial continue to work well when invoking apt. - perl -npi -e \ - 's/^.*--uid-owner root.*apt updates.*$/-A OUTPUT -p tcp --match multiport --dports 80,8080,443 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT -m comment --comment "apt updates"/' \ - "$rules_v4" - - # Remove root restriction for general DNS calls. Using matching - # groups to preserve custom DNS settings via site-specific info. - perl -npi -e \ - 's/^(.*--dport 53) -m owner --uid-owner root(.*)$/$1$2/' \ - "$rules_v4" - fi -} - -manage_tor_repo_config() { - # Ensure official Tor repo entry is removed, so that only FPF mirror is used. - rm -f /etc/apt/sources.list.d/deb_torproject_org_torproject_org.list - - # Ensure FPF mirror config is removed, so that only primary FPF repo is used - rm -f /etc/apt/sources.list.d/tor_apt_freedom_press.list - - # Remove references to separate Tor-specific repositories - apt_security_list="/etc/apt/security.list" - if [ -f "$apt_security_list" ]; then - sed -i '/deb\.torproject\.org\/torproject\.org/d' "$apt_security_list" - sed -i '/tor-apt\.freedom\.press/d' "$apt_security_list" - fi -} - -case "$1" in - configure) - - manage_tor_repo_config - remove_2fa_tty_req - update_release_prompt - - # Remove cron-apt action should occur after security upgrades to avoid breaking - # automatic upgrades (see issue #4003) - if [ -f "/etc/cron-apt/action.d/1-remove" ]; then - rm /etc/cron-apt/action.d/1-remove - fi - - allow_apt_user_in_iptables - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -exit 0 diff --git a/install_files/securedrop-config/etc/cron-apt/action.d/9-remove b/install_files/securedrop-config/etc/cron-apt/action.d/9-remove deleted file mode 100644 index eb3890ce0e..0000000000 --- a/install_files/securedrop-config/etc/cron-apt/action.d/9-remove +++ /dev/null @@ -1 +0,0 @@ -remove -y linux-image-generic-lts-xenial linux-image-.*generic -o quiet=2 diff --git a/install_files/securedrop-config/etc/profile.d/securedrop_additions.sh b/install_files/securedrop-config/etc/profile.d/securedrop_additions.sh deleted file mode 100644 index 4bab3c8ea3..0000000000 --- a/install_files/securedrop-config/etc/profile.d/securedrop_additions.sh +++ /dev/null @@ -1,22 +0,0 @@ -[[ $- != *i* ]] && return - -which tmux >/dev/null 2>&1 || return - -tmux_attach_via_proc() { - # If the tmux package is upgraded during the lifetime of a - # session, attaching with the new binary can fail due to different - # protocol versions. This function attaches using the reference to - # the old executable found in the /proc tree of an existing - # session. - pid=$(pgrep --newest tmux) - if test -n "$pid" - then - /proc/$pid/exe attach - fi - return 1 -} - -if test -z "$TMUX" -then - (tmux attach || tmux_attach_via_proc || tmux new-session) -fi diff --git a/install_files/securedrop-grsec/DEBIAN/control.j2 b/install_files/securedrop-grsec/DEBIAN/control.j2 deleted file mode 100644 index 3b8b839b5b..0000000000 --- a/install_files/securedrop-grsec/DEBIAN/control.j2 +++ /dev/null @@ -1,12 +0,0 @@ -Package: securedrop-grsec -Source: securedrop-grsec -Version: {{ securedrop_pkg_grsec_xenial.ver }}+{{ securedrop_target_distribution }} -Architecture: amd64 -Maintainer: SecureDrop Team -Depends: {{ securedrop_pkg_grsec_xenial.depends }} -Section: admin -Priority: optional -Homepage: https://securedrop.org -Description: Metapackage providing a grsecurity-patched Linux kernel for use - with SecureDrop. Depends on the most recently built patched kernel maintained - by FPF. Package also includes sysctl and PaX flags calls for GRUB. diff --git a/install_files/securedrop-grsec/DEBIAN/postinst b/install_files/securedrop-grsec/DEBIAN/postinst deleted file mode 100755 index 6591a2b4d5..0000000000 --- a/install_files/securedrop-grsec/DEBIAN/postinst +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh -# postinst script for securedrop-grsec -# -# see: dh_installdeb(1) -set -e -set -x -# summary of how this script can be called: -# * `configure' -# * `abort-upgrade' -# * `abort-remove' `in-favour' -# -# * `abort-remove' -# * `abort-deconfigure' `in-favour' -# `removing' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - -case "$1" in - configure) - - # Replace the default GRUB boot option with 0, which defaults to the - # highest kernel version. Any kernel provided by apt.freedom.press must - # suprecede the ones provided by Ubuntu. - sed -i '/^GRUB_DEFAULT=/s/=.*/=0/' /etc/default/grub - # When using CONFIG_PAX_KERNEXEC, the grsecurity team recommends the kernel - # is booted with "noefi" on the kernel command line if "CONFIG_EFI" is - # enabled, as EFI runtime services are necessarily mapped as RWX. - sed -i '/^GRUB_CMDLINE_LINUX_DEFAULT=/s/=.*/=\"noefi\"/' /etc/default/grub - - update-grub - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 diff --git a/install_files/securedrop-grsec/etc/default/grub.d/50-mds-smt.cfg b/install_files/securedrop-grsec/etc/default/grub.d/50-mds-smt.cfg deleted file mode 100644 index e35a4469fd..0000000000 --- a/install_files/securedrop-grsec/etc/default/grub.d/50-mds-smt.cfg +++ /dev/null @@ -1,3 +0,0 @@ -# disables smt and provide full mds mitigations -# see https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html -GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX mds=full,nosmt" diff --git a/install_files/securedrop-grsec/etc/kernel/postinst.d/paxctl-grub b/install_files/securedrop-grsec/etc/kernel/postinst.d/paxctl-grub deleted file mode 100755 index 580909aacb..0000000000 --- a/install_files/securedrop-grsec/etc/kernel/postinst.d/paxctl-grub +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -set -e - -# Set PaX flags on GRUB binaries. Required when running under a grsec kernel, -# i.e. during kernel upgrades. If the GRUB binaries do not have the proper flags, -# the kernel image will fail to install. -# -# This script must run prior to the `zz-update-grub` kernel postinst hook, -# which will happen automatically due to sorting of the postinst scripts. -# -# Enabling EMUTRAMP on grub binaries, which requires `CONFIG_PAX_EMUTRAMP=y` -# to be set in the kernel config. Using `-z` to clear out any other flags, -# so the binaries will get only the intended settings, and all others -# not maintained by this script will be removed. -paxctl -zCE /usr/sbin/grub-probe -paxctl -zCE /usr/sbin/grub-mkdevicemap -paxctl -zCE /usr/bin/grub-script-check diff --git a/install_files/securedrop-grsec/etc/sysctl.d/30-securedrop.conf b/install_files/securedrop-grsec/etc/sysctl.d/30-securedrop.conf deleted file mode 100644 index 05d116ca3f..0000000000 --- a/install_files/securedrop-grsec/etc/sysctl.d/30-securedrop.conf +++ /dev/null @@ -1 +0,0 @@ -vm.heap_stack_gap=1048576 From 80b6d109acfaa86d95ebf4e061a95ec04cd6a40b Mon Sep 17 00:00:00 2001 From: Conor Schaefer Date: Wed, 28 Apr 2021 15:43:18 -0700 Subject: [PATCH 10/12] Removes Xenial-specific logic from config tests --- molecule/builder-focal/molecule.yml | 2 - .../tests/test_build_dependencies.py | 2 +- .../tests/test_securedrop_deb_package.py | 42 +--- molecule/builder-focal/tests/vars.yml | 1 - .../test_apache_journalist_interface.py | 77 +----- .../apache/test_apache_source_interface.py | 77 +----- molecule/testinfra/app/test_apparmor.py | 2 - molecule/testinfra/app/test_ossec_agent.py | 9 +- molecule/testinfra/app/test_paxctld.py | 39 --- molecule/testinfra/app/test_tor_config.py | 3 +- .../common/test_automatic_updates.py | 233 ++++-------------- .../common/test_basic_configuration.py | 44 ++-- molecule/testinfra/common/test_grsecurity.py | 54 +--- molecule/testinfra/common/test_ip6tables.py | 22 -- molecule/testinfra/common/test_platform.py | 14 +- .../testinfra/common/test_release_upgrades.py | 20 +- .../testinfra/common/test_system_hardening.py | 26 +- molecule/testinfra/common/test_user_config.py | 29 --- molecule/testinfra/conftest.py | 20 +- molecule/testinfra/mon/test_ossec_server.py | 9 +- molecule/testinfra/mon/test_postfix.py | 8 +- molecule/testinfra/vars/app-prod.yml | 11 - molecule/testinfra/vars/app-staging.yml | 11 - molecule/testinfra/vars/prod.yml | 12 - molecule/testinfra/vars/prodVM.yml | 12 - molecule/testinfra/vars/qubes-staging.yml | 12 - molecule/testinfra/vars/staging.yml | 12 - 27 files changed, 118 insertions(+), 685 deletions(-) delete mode 100644 molecule/testinfra/app/test_paxctld.py diff --git a/molecule/builder-focal/molecule.yml b/molecule/builder-focal/molecule.yml index 8f90fadb0b..b1b3cb0fe4 100644 --- a/molecule/builder-focal/molecule.yml +++ b/molecule/builder-focal/molecule.yml @@ -75,7 +75,5 @@ verifier: env: SECUREDROP_TARGET_DISTRIBUTION: focal SECUREDROP_PYTHON_VERSION: "3.8" - # Reuse the same test suite for all packages - directory: ../builder-xenial/tests/ lint: | flake8 diff --git a/molecule/builder-focal/tests/test_build_dependencies.py b/molecule/builder-focal/tests/test_build_dependencies.py index cdf8f820bd..0b37db1f3d 100644 --- a/molecule/builder-focal/tests/test_build_dependencies.py +++ b/molecule/builder-focal/tests/test_build_dependencies.py @@ -48,7 +48,7 @@ def test_dh_virtualenv(host): """ Confirm the expected version of dh-virtualenv is found. """ - expected_version = "0.11" if host.system_info.codename == "xenial" else "1.2.1" + expected_version = "1.2.1" version_string = "dh_virtualenv {}".format(expected_version) c = host.run("dh_virtualenv --version") assert c.stdout.startswith(version_string) diff --git a/molecule/builder-focal/tests/test_securedrop_deb_package.py b/molecule/builder-focal/tests/test_securedrop_deb_package.py index 24ab33c2c9..24c7c4e336 100644 --- a/molecule/builder-focal/tests/test_securedrop_deb_package.py +++ b/molecule/builder-focal/tests/test_securedrop_deb_package.py @@ -62,16 +62,10 @@ def make_deb_paths() -> Dict[str, Path]: reuse vars in other var values, as is the case with Ansible). """ - if SECUREDROP_TARGET_DISTRIBUTION == "xenial": - grsec_version = "{}+{}".format( - securedrop_test_vars["grsec_version_xenial"], - SECUREDROP_TARGET_DISTRIBUTION - ) - else: - grsec_version = "{}+{}".format( - securedrop_test_vars["grsec_version_focal"], - SECUREDROP_TARGET_DISTRIBUTION - ) + grsec_version = "{}+{}".format( + securedrop_test_vars["grsec_version_focal"], + SECUREDROP_TARGET_DISTRIBUTION + ) substitutions = dict( securedrop_version=securedrop_test_vars["securedrop_version"], @@ -417,14 +411,8 @@ def test_grsec_metapackage(host: Host): c = host.run("dpkg-deb --contents {}".format(deb_paths["securedrop_grsec"])) contents = c.stdout - if SECUREDROP_TARGET_DISTRIBUTION == "xenial": - # Post-install kernel hook for managing PaX flags must exist. - assert re.search(r"^.*\./etc/kernel/postinst.d/paxctl-grub$", contents, re.M) - # Config file for paxctld should not be present - assert not re.search(r"^.*\./opt/securedrop/paxctld.conf$", contents, re.M) - else: - assert not re.search(r"^.*\./etc/kernel/postinst.d/paxctl-grub$", contents, re.M) - assert re.search(r"^.*\./opt/securedrop/paxctld.conf$", contents, re.M) + assert not re.search(r"^.*\./etc/kernel/postinst.d/paxctl-grub$", contents, re.M) + assert re.search(r"^.*\./opt/securedrop/paxctld.conf$", contents, re.M) # Custom sysctl options should be present assert re.search(r"^.*\./etc/sysctl.d/30-securedrop.conf$", contents, re.M) @@ -550,18 +538,12 @@ def test_config_package_contains_expected_files(host: Host) -> None: Inspect the package contents to ensure all config files are included in the package. """ - if SECUREDROP_TARGET_DISTRIBUTION == "xenial": - wanted_files = [ - "/etc/cron-apt/action.d/9-remove", - "/etc/profile.d/securedrop_additions.sh", - ] - else: - wanted_files = [ - "/etc/profile.d/securedrop_additions.sh", - "/opt/securedrop/20auto-upgrades", - "/opt/securedrop/50unattended-upgrades", - "/opt/securedrop/reboot-flag", - ] + wanted_files = [ + "/etc/profile.d/securedrop_additions.sh", + "/opt/securedrop/20auto-upgrades", + "/opt/securedrop/50unattended-upgrades", + "/opt/securedrop/reboot-flag", + ] c = host.run("dpkg-deb --contents {}".format(deb_paths["securedrop_config"])) for wanted_file in wanted_files: assert re.search( diff --git a/molecule/builder-focal/tests/vars.yml b/molecule/builder-focal/tests/vars.yml index 950f54b955..a196f2b081 100644 --- a/molecule/builder-focal/tests/vars.yml +++ b/molecule/builder-focal/tests/vars.yml @@ -3,7 +3,6 @@ securedrop_version: "1.9.0~rc1" ossec_version: "3.6.0" keyring_version: "0.1.4" config_version: "0.1.4" -grsec_version_xenial: "4.14.188" grsec_version_focal: "5.4.97" # These values will be interpolated with values populated above diff --git a/molecule/testinfra/app/apache/test_apache_journalist_interface.py b/molecule/testinfra/app/apache/test_apache_journalist_interface.py index 585c66930c..fd0b65affc 100644 --- a/molecule/testinfra/app/apache/test_apache_journalist_interface.py +++ b/molecule/testinfra/app/apache/test_apache_journalist_interface.py @@ -17,14 +17,10 @@ def test_apache_headers_journalist_interface(host, header, value): assert f.user == "root" assert f.group == "root" assert f.mode == 0o644 - if host.system_info.codename == "focal": - header_unset = "Header onsuccess unset {}".format(header) - assert f.contains(header_unset) - header_set = "Header always set {} \"{}\"".format(header, value) - assert f.contains(header_set) - else: - header_regex = "^Header set {}.*{}.*$".format(re.escape(header), re.escape(value)) - assert re.search(header_regex, f.content_string, re.M) + header_unset = "Header onsuccess unset {}".format(header) + assert f.contains(header_unset) + header_set = "Header always set {} \"{}\"".format(header, value) + assert f.contains(header_set) # declare journalist-specific Apache configs @@ -68,19 +64,13 @@ def test_apache_config_journalist_interface(host, apache_opt): def test_apache_config_journalist_interface_headers_per_distro(host): """ During migration to Focal, we updated the syntax for forcing HTTP headers. - Honor the old Xenial syntax until EOL. """ f = host.file("/etc/apache2/sites-available/journalist.conf") - if host.system_info.codename == "xenial": - assert f.contains("Header always append X-Frame-Options: DENY") - assert f.contains('Header set Referrer-Policy "no-referrer"') - assert f.contains('Header edit Set-Cookie ^(.*)$ $1;HttpOnly') - else: - assert f.contains("Header onsuccess unset X-Frame-Options") - assert f.contains('Header always set X-Frame-Options "DENY"') - assert f.contains('Header onsuccess unset Referrer-Policy') - assert f.contains('Header always set Referrer-Policy "no-referrer"') - assert f.contains('Header edit Set-Cookie ^(.*)$ $1;HttpOnly') + assert f.contains("Header onsuccess unset X-Frame-Options") + assert f.contains('Header always set X-Frame-Options "DENY"') + assert f.contains('Header onsuccess unset Referrer-Policy') + assert f.contains('Header always set Referrer-Policy "no-referrer"') + assert f.contains('Header edit Set-Cookie ^(.*)$ $1;HttpOnly') def test_apache_logging_journalist_interface(host): @@ -137,57 +127,10 @@ def test_apache_logging_journalist_interface(host): """.strip('\n').format(securedrop_test_vars.securedrop_code), ]) -def test_apache_config_journalist_interface_access_control_focal(host, apache_opt): +def test_apache_config_journalist_interface_access_control(host, apache_opt): """ Verifies the access control directives for the Journalist Interface. - Using a separate test because Xenial / Focal syntax differs. """ - if host.system_info.codename != "focal": - return True - f = host.file("/etc/apache2/sites-available/journalist.conf") - regex = "^{}$".format(re.escape(apache_opt)) - assert re.search(regex, f.content_string, re.M) - - -@pytest.mark.parametrize("apache_opt", [ - """ - - Options None - AllowOverride None - Order deny,allow - Deny from all - -""".strip('\n'), - """ - - Order allow,deny - Allow from all - # Cache static resources for 1 hour - Header set Cache-Control "max-age=3600" - -""".strip('\n').format(securedrop_test_vars.securedrop_code), - """ - - Options None - AllowOverride None - - Order allow,deny - allow from 127.0.0.1 - - - Order deny,allow - Deny from all - - -""".strip('\n').format(securedrop_test_vars.securedrop_code), -]) -def test_apache_config_journalist_interface_access_control_xenial(host, apache_opt): - """ - Verifies the access control directives for the Source Interface. - Using a separate test because Xenial / Focal syntax differs. - """ - if host.system_info.codename != "xenial": - return True f = host.file("/etc/apache2/sites-available/journalist.conf") regex = "^{}$".format(re.escape(apache_opt)) assert re.search(regex, f.content_string, re.M) diff --git a/molecule/testinfra/app/apache/test_apache_source_interface.py b/molecule/testinfra/app/apache/test_apache_source_interface.py index ab298daa50..67871b0788 100644 --- a/molecule/testinfra/app/apache/test_apache_source_interface.py +++ b/molecule/testinfra/app/apache/test_apache_source_interface.py @@ -17,14 +17,10 @@ def test_apache_headers_source_interface(host, header, value): assert f.user == "root" assert f.group == "root" assert f.mode == 0o644 - if host.system_info.codename == "focal": - header_unset = "Header onsuccess unset {}".format(header) - assert f.contains(header_unset) - header_set = "Header always set {} \"{}\"".format(header, value) - assert f.contains(header_set) - else: - header_regex = "^Header set {}.*{}.*$".format(re.escape(header), re.escape(value)) - assert re.search(header_regex, f.content_string, re.M) + header_unset = "Header onsuccess unset {}".format(header) + assert f.contains(header_unset) + header_set = "Header always set {} \"{}\"".format(header, value) + assert f.contains(header_set) @pytest.mark.parametrize("apache_opt", [ @@ -62,19 +58,13 @@ def test_apache_config_source_interface(host, apache_opt): def test_apache_config_source_interface_headers_per_distro(host): """ During migration to Focal, we updated the syntax for forcing HTTP headers. - Honor the old Xenial syntax until EOL. """ f = host.file("/etc/apache2/sites-available/source.conf") - if host.system_info.codename == "xenial": - assert f.contains("Header always append X-Frame-Options: DENY") - assert f.contains('Header set Referrer-Policy "same-origin"') - assert f.contains('Header edit Set-Cookie ^(.*)$ $1;HttpOnly') - else: - assert f.contains("Header onsuccess unset X-Frame-Options") - assert f.contains('Header always set X-Frame-Options "DENY"') - assert f.contains('Header onsuccess unset Referrer-Policy') - assert f.contains('Header always set Referrer-Policy "same-origin"') - assert f.contains('Header edit Set-Cookie ^(.*)$ $1;HttpOnly') + assert f.contains("Header onsuccess unset X-Frame-Options") + assert f.contains('Header always set X-Frame-Options "DENY"') + assert f.contains('Header onsuccess unset Referrer-Policy') + assert f.contains('Header always set Referrer-Policy "same-origin"') + assert f.contains('Header edit Set-Cookie ^(.*)$ $1;HttpOnly') @pytest.mark.parametrize("apache_opt", [ @@ -105,57 +95,10 @@ def test_apache_config_source_interface_headers_per_distro(host): """.strip('\n').format(securedrop_test_vars.securedrop_code), ]) -def test_apache_config_source_interface_access_control_focal(host, apache_opt): +def test_apache_config_source_interface_access_control(host, apache_opt): """ Verifies the access control directives for the Source Interface. - Using a separate test because Xenial / Focal syntax differs. """ - if host.system_info.codename != "focal": - return True - f = host.file("/etc/apache2/sites-available/source.conf") - regex = "^{}$".format(re.escape(apache_opt)) - assert re.search(regex, f.content_string, re.M) - - -@pytest.mark.parametrize("apache_opt", [ - """ - - Options None - AllowOverride None - Order deny,allow - Deny from all - -""".strip('\n'), - """ - - Order allow,deny - Allow from all - # Cache static resources for 1 hour - Header set Cache-Control "max-age=3600" - -""".strip('\n').format(securedrop_test_vars.securedrop_code), - """ - - Options None - AllowOverride None - - Order allow,deny - allow from 127.0.0.1 - - - Order deny,allow - Deny from all - - -""".strip('\n').format(securedrop_test_vars.securedrop_code), -]) -def test_apache_config_source_interface_access_control_xenial(host, apache_opt): - """ - Verifies the access control directives for the Source Interface. - Using a separate test because Xenial / Focal syntax differs. - """ - if host.system_info.codename != "xenial": - return True f = host.file("/etc/apache2/sites-available/source.conf") regex = "^{}$".format(re.escape(apache_opt)) assert re.search(regex, f.content_string, re.M) diff --git a/molecule/testinfra/app/test_apparmor.py b/molecule/testinfra/app/test_apparmor.py index 1a349c01b0..b3710d1f7c 100644 --- a/molecule/testinfra/app/test_apparmor.py +++ b/molecule/testinfra/app/test_apparmor.py @@ -102,8 +102,6 @@ def test_apparmor_total_profiles(host): complaining profiles """ with host.sudo(): total_expected = len(sdvars.apparmor_enforce) + len(sdvars.apparmor_complain) - # Xenial about ~20 profiles, so let's expect - # *at least* the sum. assert int(host.check_output("aa-status --profiled")) >= total_expected diff --git a/molecule/testinfra/app/test_ossec_agent.py b/molecule/testinfra/app/test_ossec_agent.py index 493df90a18..e9e68981bd 100644 --- a/molecule/testinfra/app/test_ossec_agent.py +++ b/molecule/testinfra/app/test_ossec_agent.py @@ -23,16 +23,11 @@ def test_hosts_files(host): def test_ossec_service_start_style(host): """ - Ensure that the OSSEC services are managed by systemd under Focal, - but by sysv under Xenial. + Ensure that the OSSEC services are managed by systemd. """ - if host.system_info.codename == "focal": - value = "/etc/systemd/system/ossec.service" - else: - value = "/etc/init.d/ossec" with host.sudo(): c = host.check_output("systemctl status ossec") - assert value in c + assert "/etc/systemd/system/ossec.service" in c def test_hosts_duplicate(host): diff --git a/molecule/testinfra/app/test_paxctld.py b/molecule/testinfra/app/test_paxctld.py deleted file mode 100644 index 6bc210771f..0000000000 --- a/molecule/testinfra/app/test_paxctld.py +++ /dev/null @@ -1,39 +0,0 @@ -import re -import testutils - -securedrop_test_vars = testutils.securedrop_test_vars -testinfra_hosts = [securedrop_test_vars.app_hostname] - - -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 = r"^/usr/sbin/apache2\s+m$" - assert re.search(regex, f.content_string, 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 diff --git a/molecule/testinfra/app/test_tor_config.py b/molecule/testinfra/app/test_tor_config.py index a3f769d476..190e949f0a 100644 --- a/molecule/testinfra/app/test_tor_config.py +++ b/molecule/testinfra/app/test_tor_config.py @@ -22,8 +22,7 @@ def test_tor_packages(host, package): def test_tor_service_running(host): """ Ensure Tor is running and enabled. Tor is required for SSH access, - so it must be enabled to start on boot. Checks systemd-style services, - used by Xenial. + so it must be enabled to start on boot. """ s = host.service("tor") assert s.is_running diff --git a/molecule/testinfra/common/test_automatic_updates.py b/molecule/testinfra/common/test_automatic_updates.py index bc1530848f..b72136f72b 100644 --- a/molecule/testinfra/common/test_automatic_updates.py +++ b/molecule/testinfra/common/test_automatic_updates.py @@ -11,61 +11,24 @@ def test_automatic_updates_dependencies(host): """ Ensure critical packages are installed. If any of these are missing, the system will fail to receive automatic updates. - - In Xenial, the apt config uses cron-apt, rather than unattended-upgrades. - Previously the apt.freedom.press repo was not reporting any "Origin" field, - making use of unattended-upgrades problematic. In Focal, the apt config uses unattended-upgrades. """ - apt_dependencies = { - 'xenial': ['cron-apt', 'ntp'], - 'focal': ['unattended-upgrades'] - } - - for package in apt_dependencies[host.system_info.codename]: - assert host.package(package).is_installed + assert host.package("unattended-upgrades").is_installed + assert not host.package("cron-apt").is_installed + assert not host.package("ntp").is_installed def test_cron_apt_config(host): """ - Ensure custom cron-apt config file is present in Xenial, and absent in Focal - """ - f = host.file('/etc/cron-apt/config') - if host.system_info.codename == "xenial": - assert f.is_file - assert f.user == "root" - assert f.mode == 0o644 - assert f.contains('^SYSLOGON="always"$') - assert f.contains('^EXITON=error$') - else: - assert not f.exists - - -@pytest.mark.parametrize('repo', [ - 'deb http://security.ubuntu.com/ubuntu {securedrop_target_distribution}-security main', - 'deb-src http://security.ubuntu.com/ubuntu {securedrop_target_distribution}-security main', - 'deb http://security.ubuntu.com/ubuntu {securedrop_target_distribution}-security universe', - 'deb-src http://security.ubuntu.com/ubuntu {securedrop_target_distribution}-security universe', - 'deb [arch=amd64] {fpf_apt_repo_url} {securedrop_target_distribution} main', -]) -def test_cron_apt_repo_list(host, repo): - """ - Ensure the correct apt repositories are specified - in the security list for apt. + Ensure custom cron-apt config is absent, as of Focal """ - repo_config = repo.format( - fpf_apt_repo_url=test_vars.fpf_apt_repo_url, - securedrop_target_distribution=host.system_info.codename - ) - f = host.file('/etc/apt/security.list') - if host.system_info.codename == "xenial": - assert f.is_file - assert f.user == "root" - assert f.mode == 0o644 - repo_regex = '^{}$'.format(re.escape(repo_config)) - assert f.contains(repo_regex) - else: - assert not f.exists + assert not host.file("/etc/cron-apt/config").exists + assert not host.file('/etc/cron-apt/action.d/0-update').exists + assert not host.file('/etc/cron-apt/action.d/5-security').exists + assert not host.file('/etc/cron-apt/action.d/9-remove').exists + assert not host.file('/etc/cron.d/cron-apt').exists + assert not host.file("/etc/apt/security.list").exists + assert not host.file("/etc/cron-apt/action.d/3-download").exists @pytest.mark.parametrize('repo', [ @@ -83,108 +46,11 @@ def test_sources_list(host, repo): securedrop_target_platform=host.system_info.codename ) f = host.file('/etc/apt/sources.list') - if host.system_info.codename == "focal": - assert f.is_file - assert f.user == "root" - assert f.mode == 0o644 - repo_regex = '^{}$'.format(re.escape(repo_config)) - assert f.contains(repo_regex) - - -def test_cron_apt_repo_config_update(host): - """ - Ensure cron-apt updates repos from the security.list config for Xenial. - """ - - f = host.file('/etc/cron-apt/action.d/0-update') - if host.system_info.codename == "xenial": - assert f.is_file - assert f.user == "root" - assert f.mode == 0o644 - repo_config = str('update -o quiet=2' - ' -o Dir::Etc::SourceList=/etc/apt/security.list' - ' -o Dir::Etc::SourceParts=""') - assert f.contains('^{}$'.format(repo_config)) - else: - assert not f.exists - - -def test_cron_apt_delete_vanilla_kernels(host): - """ - Ensure cron-apt removes generic linux image packages when installed. This - file is provisioned via ansible and via the securedrop-config package. We - should remove it once Xenial is fully deprecated. In the meantime, it will - not impact Focal systems running unattended-upgrades - """ - - f = host.file('/etc/cron-apt/action.d/9-remove') - if host.system_info.codename == "xenial": - assert f.is_file - assert f.user == "root" - assert f.mode == 0o644 - command = str('remove -y' - ' linux-image-generic-lts-xenial linux-image-.*generic' - ' -o quiet=2') - assert f.contains('^{}$'.format(command)) - else: - assert not f.exists - - -def test_cron_apt_repo_config_upgrade(host): - """ - Ensure cron-apt upgrades packages from the security.list config. - """ - f = host.file('/etc/cron-apt/action.d/5-security') - if host.system_info.codename == "xenial": - assert f.is_file - assert f.user == "root" - assert f.mode == 0o644 - assert f.contains('^autoclean -y$') - repo_config = str('dist-upgrade -y -o APT::Get::Show-Upgraded=true' - ' -o Dir::Etc::SourceList=/etc/apt/security.list' - ' -o Dpkg::Options::=--force-confdef' - ' -o Dpkg::Options::=--force-confold') - assert f.contains(re.escape(repo_config)) - else: - assert not f.exists - - -def test_cron_apt_config_deprecated(host): - """ - Ensure default cron-apt file to download all updates does not exist. - """ - f = host.file('/etc/cron-apt/action.d/3-download') - assert not f.exists - - -@pytest.mark.parametrize('cron_job', [ - {'job': '0 4 * * * root /usr/bin/test -x /usr/sbin/cron-apt && /usr/sbin/cron-apt && /sbin/reboot', # noqa - 'state': 'present'}, - {'job': '0 4 * * * root /usr/bin/test -x /usr/sbin/cron-apt && /usr/sbin/cron-apt', # noqa - 'state': 'absent'}, - {'job': '0 5 * * * root /sbin/reboot', - 'state': 'absent'}, -]) -def test_cron_apt_cron_jobs(host, cron_job): - """ - Check for correct cron job for upgrading all packages and rebooting. - We'll also check for absence of previous versions of the cron job, - to make sure those have been cleaned up via the playbooks. - """ - f = host.file('/etc/cron.d/cron-apt') - - if host.system_info.codename == "xenial": - assert f.is_file - assert f.user == "root" - assert f.mode == 0o644 - - regex_job = '^{}$'.format(re.escape(cron_job['job'])) - if cron_job['state'] == 'present': - assert f.contains(regex_job) - else: - assert not f.contains(regex_job) - else: - assert not f.exists + assert f.is_file + assert f.user == "root" + assert f.mode == 0o644 + repo_regex = '^{}$'.format(re.escape(repo_config)) + assert f.contains(repo_regex) apt_config_options = { @@ -215,8 +81,6 @@ def test_unattended_upgrades_config(host, k, v): """ Ensures the apt and unattended-upgrades config is correct only under Ubuntu Focal """ - if host.system_info.codename == "xenial": - return True # Dump apt config to inspect end state, apt will build config # from all conf files on disk, e.g. 80securedrop. c = host.run("apt-config dump --format '%v%n' {}".format(k)) @@ -240,10 +104,7 @@ def test_unattended_securedrop_specific(host): assert f.user == "root" assert f.mode == 0o644 assert f.contains('APT::Install-Recommends "false";') - if host.system_info.codename == "focal": - assert f.contains("Automatic-Reboot-Time") - else: - assert not f.contains("Automatic-Reboot-Time") + assert f.contains("Automatic-Reboot-Time") def test_unattended_upgrades_functional(host): @@ -251,19 +112,18 @@ def test_unattended_upgrades_functional(host): Ensure unatteded-upgrades completes successfully and ensures all packages are up-to-date. """ - if host.system_info.codename != "xenial": - c = host.run('sudo unattended-upgrades --dry-run --debug') - assert c.rc == 0 - expected_origins = ( - "Allowed origins are: origin=Ubuntu,archive=focal, origin=Ubuntu,archive=focal-security" - ", origin=Ubuntu,archive=focal-updates, origin=SecureDrop,codename=focal" - ) - expected_result = ( - "No packages found that can be upgraded unattended and no pending auto-removals" - ) + c = host.run('sudo unattended-upgrades --dry-run --debug') + assert c.rc == 0 + expected_origins = ( + "Allowed origins are: origin=Ubuntu,archive=focal, origin=Ubuntu,archive=focal-security" + ", origin=Ubuntu,archive=focal-updates, origin=SecureDrop,codename=focal" + ) + expected_result = ( + "No packages found that can be upgraded unattended and no pending auto-removals" + ) - assert expected_origins in c.stdout - assert expected_result in c.stdout + assert expected_origins in c.stdout + assert expected_result in c.stdout @pytest.mark.parametrize('service', [ @@ -277,11 +137,10 @@ def test_apt_daily_services_and_timers_enabled(host, service): Ensure the services and timers used for unattended upgrades are enabled in Ubuntu 20.04 Focal. """ - if host.system_info.codename != "xenial": - with host.sudo(): - # The services are started only when the upgrades are being performed. - s = host.service(service) - assert s.is_enabled + with host.sudo(): + # The services are started only when the upgrades are being performed. + s = host.service(service) + assert s.is_enabled def test_apt_daily_timer_schedule(host): @@ -289,10 +148,9 @@ def test_apt_daily_timer_schedule(host): Timer for running apt-daily, i.e. 'apt-get update', should be 2h before the daily_reboot_time. """ - if host.system_info.codename != "xenial": - c = host.run("systemctl show apt-daily.timer") - assert "TimersCalendar={ OnCalendar=*-*-* 02:00:00 ;" in c.stdout - assert "RandomizedDelayUSec=20m" in c.stdout + c = host.run("systemctl show apt-daily.timer") + assert "TimersCalendar={ OnCalendar=*-*-* 02:00:00 ;" in c.stdout + assert "RandomizedDelayUSec=20m" in c.stdout def test_apt_daily_upgrade_timer_schedule(host): @@ -300,10 +158,9 @@ def test_apt_daily_upgrade_timer_schedule(host): Timer for running apt-daily-upgrade, i.e. 'apt-get upgrade', should be 1h before the daily_reboot_time, and 1h after the apt-daily time. """ - if host.system_info.codename != "xenial": - c = host.run("systemctl show apt-daily-upgrade.timer") - assert "TimersCalendar={ OnCalendar=*-*-* 03:00:00 ;" in c.stdout - assert "RandomizedDelayUSec=20m" in c.stdout + c = host.run("systemctl show apt-daily-upgrade.timer") + assert "TimersCalendar={ OnCalendar=*-*-* 03:00:00 ;" in c.stdout + assert "RandomizedDelayUSec=20m" in c.stdout def test_reboot_required_cron(host): @@ -314,16 +171,12 @@ def test_reboot_required_cron(host): is rebooted every day at the scheduled time. """ f = host.file('/etc/cron.d/reboot-flag') + assert f.is_file + assert f.user == "root" + assert f.mode == 0o644 - if host.system_info.codename == "xenial": - assert not f.exists - else: - assert f.is_file - assert f.user == "root" - assert f.mode == 0o644 - - line = '^{}$'.format(re.escape("0 */12 * * * root touch /var/run/reboot-required")) - assert f.contains(line) + line = '^{}$'.format(re.escape("0 */12 * * * root touch /var/run/reboot-required")) + assert f.contains(line) def test_all_packages_updated(host): diff --git a/molecule/testinfra/common/test_basic_configuration.py b/molecule/testinfra/common/test_basic_configuration.py index 5f95eb63ee..8b1eeb941e 100644 --- a/molecule/testinfra/common/test_basic_configuration.py +++ b/molecule/testinfra/common/test_basic_configuration.py @@ -8,32 +8,18 @@ def test_system_time(host: Host) -> None: - if host.system_info.codename == "xenial": - assert host.package("ntp").is_installed - assert host.package("ntpdate").is_installed - - # TODO: The staging setup timing is too erratic for the - # following check. If we do want to reinstate it before - # dropping Xenial support, it should be done in a loop to give - # ntpd time to sync after the machines are created. - - # c = host.run("ntpq -c rv") - # assert "leap_none" in c.stdout - # assert "sync_ntp" in c.stdout - # assert "refid" in c.stdout - else: - assert not host.package("ntp").is_installed - assert not host.package("ntpdate").is_installed - - s = host.service("systemd-timesyncd") - assert s.is_running - assert s.is_enabled - assert not s.is_masked - - # File will be touched on every successful synchronization, - # see 'man systemd-timesyncd'` - assert host.file("/run/systemd/timesync/synchronized").exists - - c = host.run("timedatectl show") - assert "NTP=yes" in c.stdout - assert "NTPSynchronized=yes" in c.stdout + assert not host.package("ntp").is_installed + assert not host.package("ntpdate").is_installed + + s = host.service("systemd-timesyncd") + assert s.is_running + assert s.is_enabled + assert not s.is_masked + + # File will be touched on every successful synchronization, + # see 'man systemd-timesyncd'` + assert host.file("/run/systemd/timesync/synchronized").exists + + c = host.run("timedatectl show") + assert "NTP=yes" in c.stdout + assert "NTPSynchronized=yes" in c.stdout diff --git a/molecule/testinfra/common/test_grsecurity.py b/molecule/testinfra/common/test_grsecurity.py index 39596e0535..c41fb0ca35 100644 --- a/molecule/testinfra/common/test_grsecurity.py +++ b/molecule/testinfra/common/test_grsecurity.py @@ -31,10 +31,7 @@ def test_grsecurity_apt_packages(host, package): Includes the FPF-maintained metapackage, as well as paxctl, for managing PaX flags on binaries. """ - if host.system_info.codename == "xenial": - KERNEL_VERSION = sdvars.grsec_version_xenial - else: - KERNEL_VERSION = sdvars.grsec_version_focal + KERNEL_VERSION = sdvars.grsec_version_focal if package.startswith("linux-image"): package = package.format(KERNEL_VERSION) assert host.package(package).is_installed @@ -80,10 +77,7 @@ def test_grsecurity_kernel_is_running(host): """ Make sure the currently running kernel is specific grsec kernel. """ - if host.system_info.codename == "xenial": - KERNEL_VERSION = sdvars.grsec_version_xenial - else: - KERNEL_VERSION = sdvars.grsec_version_focal + KERNEL_VERSION = sdvars.grsec_version_focal c = host.run('uname -r') assert c.stdout.strip().endswith('-grsec-securedrop') assert c.stdout.strip() == '{}-grsec-securedrop'.format(KERNEL_VERSION) @@ -171,36 +165,7 @@ def test_paxctl(host): As of Focal, paxctl is not used, and shouldn't be installed. """ p = host.package("paxctl") - if host.system_info.codename == "xenial": - assert p.is_installed - else: - assert not p.is_installed - - -def test_paxctld_xenial(host): - """ - Xenial-specific paxctld config checks. - Ensures paxctld is running and enabled, and relevant - exemptions are present in the config file. - """ - if host.system_info.codename != "xenial": - return True - - hostname = host.check_output('hostname -s') - assert (("app" in hostname) or ("mon" in hostname)) - - # Under Xenial, apache2 pax flags managed by securedrop-app-code. - if "app" not in hostname: - return True - - assert host.package("paxctld").is_installed - f = host.file("/etc/paxctld.conf") - assert f.is_file - assert f.contains("^/usr/sbin/apache2\tm") - - s = host.service("paxctld") - assert s.is_enabled - assert s.is_running + assert not p.is_installed def test_paxctld_focal(host): @@ -209,9 +174,6 @@ def test_paxctld_focal(host): Ensures paxctld is running and enabled, and relevant exemptions are present in the config file. """ - if host.system_info.codename != "focal": - return True - assert host.package("paxctld").is_installed f = host.file("/etc/paxctld.conf") assert f.is_file @@ -249,10 +211,7 @@ def test_wireless_disabled_in_kernel_config(host, kernel_opts): remove wireless support from the kernel. Let's make sure wireless is disabled in the running kernel config! """ - if host.system_info.codename == "xenial": - KERNEL_VERSION = sdvars.grsec_version_xenial - else: - KERNEL_VERSION = sdvars.grsec_version_focal + KERNEL_VERSION = sdvars.grsec_version_focal with host.sudo(): kernel_config_path = "/boot/config-{}-grsec-securedrop".format(KERNEL_VERSION) kernel_config = host.file(kernel_config_path).content_string @@ -271,10 +230,7 @@ def test_kernel_options_enabled_config(host, kernel_opts): Tests kernel config for options that should be enabled """ - if host.system_info.codename == "xenial": - KERNEL_VERSION = sdvars.grsec_version_xenial - else: - KERNEL_VERSION = sdvars.grsec_version_focal + KERNEL_VERSION = sdvars.grsec_version_focal with host.sudo(): kernel_config_path = "/boot/config-{}-grsec-securedrop".format(KERNEL_VERSION) kernel_config = host.file(kernel_config_path).content_string diff --git a/molecule/testinfra/common/test_ip6tables.py b/molecule/testinfra/common/test_ip6tables.py index ecc6e29c3f..64c56e77d3 100644 --- a/molecule/testinfra/common/test_ip6tables.py +++ b/molecule/testinfra/common/test_ip6tables.py @@ -4,34 +4,12 @@ testinfra_hosts = [test_vars.app_hostname, test_vars.monitor_hostname] -def test_ip6tables_drop_everything_xenial(host): - """ - Ensure that all IPv6 packets are dropped by default. - The IPv4 rules are more complicated, and tested separately. - This test is Xenial-specific, given that on Focal we disable - IPv6 functionality completely. - """ - if host.system_info.codename != "xenial": - return True - desired_ip6tables_output = """ --P INPUT DROP --P FORWARD DROP --P OUTPUT DROP -""".lstrip().rstrip() - - with host.sudo(): - c = host.check_output("ip6tables -S") - assert c == desired_ip6tables_output - - def test_ip6tables_drop_everything_focal(host): """ Ensures that IPv6 firewall settings are inaccessible, due to fully disabling IPv6 functionality at boot-time, via boot options. """ - if host.system_info.codename != "focal": - return True with host.sudo(): c = host.run("ip6tables -S") assert c.rc != 0 diff --git a/molecule/testinfra/common/test_platform.py b/molecule/testinfra/common/test_platform.py index 97a53f12c5..1cde420958 100644 --- a/molecule/testinfra/common/test_platform.py +++ b/molecule/testinfra/common/test_platform.py @@ -3,18 +3,10 @@ test_vars = testutils.securedrop_test_vars testinfra_hosts = [test_vars.app_hostname, test_vars.monitor_hostname] -# We expect Ubuntu Xenial -SUPPORTED_CODENAMES = ('xenial', 'focal') -SUPPORTED_RELEASES = ('16.04', '20.04') - def test_ansible_version(host): """ Check that a supported version of Ansible is being used. - - The project has long used the Ansible 1.x series, ans now - requires the 2.x series starting with the 0.4 release. Ensure - installation is not being performed with an outdated ansible version. """ localhost = host.get_host("local://") c = localhost.check_output("ansible --version") @@ -23,9 +15,9 @@ def test_ansible_version(host): def test_platform(host): """ - SecureDrop requires Ubuntu Ubuntu 16.04 or 20.04 LTS + SecureDrop requires Ubuntu 20.04 LTS """ assert host.system_info.type == "linux" assert host.system_info.distribution == "ubuntu" - assert host.system_info.codename in SUPPORTED_CODENAMES - assert host.system_info.release in SUPPORTED_RELEASES + assert host.system_info.codename == "focal" + assert host.system_info.release == "20.04" diff --git a/molecule/testinfra/common/test_release_upgrades.py b/molecule/testinfra/common/test_release_upgrades.py index 15b45be7e3..2d5d1409e1 100644 --- a/molecule/testinfra/common/test_release_upgrades.py +++ b/molecule/testinfra/common/test_release_upgrades.py @@ -12,32 +12,18 @@ def test_release_manager_installed(host): remove it to make the boxes leaner. """ assert host.package("ubuntu-release-upgrader-core").is_installed + assert host.exists("do-release-upgrade") def test_release_manager_upgrade_channel(host): """ Ensures that the `do-release-upgrade` command will not - suggest upgrades from Xenial to Bionic (which is untested - and unsupported.) + suggest upgrades to a future LTS, until we test it and provide support. """ - expected_channels = { - "xenial": "never", - "focal": "never", - } - config_path = "/etc/update-manager/release-upgrades" assert host.file(config_path).is_file raw_output = host.check_output("grep '^Prompt' {}".format(config_path)) _, channel = raw_output.split("=") - expected_channel = expected_channels[host.system_info.codename] - assert channel == expected_channel - - -def test_do_release_upgrade_is_installed(host): - """ - Ensure the `do-release-upgrade` command is present on target systems, - so that instance Admins can upgrade from Trusty to Xenial. - """ - assert host.exists("do-release-upgrade") + assert channel == "never" diff --git a/molecule/testinfra/common/test_system_hardening.py b/molecule/testinfra/common/test_system_hardening.py index d7825a3bd7..e18569b90b 100644 --- a/molecule/testinfra/common/test_system_hardening.py +++ b/molecule/testinfra/common/test_system_hardening.py @@ -22,20 +22,13 @@ ('net.ipv4.ip_forward', 0), ('net.ipv4.tcp_max_syn_backlog', 4096), ('net.ipv4.tcp_syncookies', 1), - ('net.ipv6.conf.all.disable_ipv6', 1), - ('net.ipv6.conf.default.disable_ipv6', 1), - ('net.ipv6.conf.lo.disable_ipv6', 1), ]) def test_sysctl_options(host, sysctl_opt): """ Ensure sysctl flags are set correctly. Most of these checks - are disabling IPv6 and hardening IPv4, which is appropriate - due to the heavy use of Tor. + are hardening IPv4, which is appropriate due to the heavy use of Tor. """ with host.sudo(): - # For Focal, we disable IPv6 entirely, so the IPv6 sysctl options won't exist - if sysctl_opt[0].startswith("net.ipv6") and host.system_info.codename == "focal": - return True assert host.sysctl(sysctl_opt[0]) == sysctl_opt[1] @@ -43,11 +36,7 @@ def test_dns_setting(host): """ Ensure DNS service is hard-coded in resolv.conf config. """ - if host.system_info.codename == "focal": - fpath = "/etc/resolv.conf" - else: - fpath = "/etc/resolvconf/resolv.conf.d/base" - f = host.file(fpath) + f = host.file("/etc/resolv.conf") assert f.is_file assert f.user == "root" assert f.group == "root" @@ -88,8 +77,8 @@ def test_swap_disabled(host): # A leading slash will indicate full path to a swapfile. assert not re.search("^/", c, re.M) - # On Xenial, swapon 2.27.1 shows blank output, with no headers, so - # check for empty output as confirmation of no swap. + # Since swapon 2.27.1, the summary shows blank output, with no headers, + # when no swap is configured, check for empty output as confirmation disabled. rgx = re.compile("^$") assert re.search(rgx, c) @@ -160,7 +149,7 @@ def test_no_ecrypt_messages_in_logs(host, logfile): ]) def test_unused_packages_are_removed(host, package): """ Check if unused package is present """ - assert host.package(package).is_installed is False + assert not host.package(package).is_installed def test_iptables_packages(host): @@ -168,10 +157,7 @@ def test_iptables_packages(host): Focal hosts should use iptables-persistent for enforcing firewall config across reboots. """ - if host.system_info.codename == "focal": - assert host.package("iptables-persistent").is_installed - else: - assert not host.package("iptables-persistent").is_installed + assert host.package("iptables-persistent").is_installed def test_snapd_absent(host): diff --git a/molecule/testinfra/common/test_user_config.py b/molecule/testinfra/common/test_user_config.py index 3bae3840d8..6a69411066 100644 --- a/molecule/testinfra/common/test_user_config.py +++ b/molecule/testinfra/common/test_user_config.py @@ -73,35 +73,6 @@ def test_sudoers_tmux_env(host): fi""" ) - expected_content_xenial = textwrap.dedent( - """\ - [[ $- != *i* ]] && return - - which tmux >/dev/null 2>&1 || return - - tmux_attach_via_proc() { - # If the tmux package is upgraded during the lifetime of a - # session, attaching with the new binary can fail due to different - # protocol versions. This function attaches using the reference to - # the old executable found in the /proc tree of an existing - # session. - pid=$(pgrep --newest tmux) - if test -n "$pid" - then - /proc/$pid/exe attach - fi - return 1 - } - - if test -z "$TMUX" - then - (tmux attach || tmux_attach_via_proc || tmux new-session) - fi""" - ) - - if host.system_info.codename == "xenial": - expected_content = expected_content_xenial - assert host_file.content_string.strip() == expected_content diff --git a/molecule/testinfra/conftest.py b/molecule/testinfra/conftest.py index 8f2ca6555d..3cf32da95d 100644 --- a/molecule/testinfra/conftest.py +++ b/molecule/testinfra/conftest.py @@ -31,23 +31,9 @@ def securedrop_import_testinfra_vars(hostname, with_header=False): with io.open(filepath, 'r') as f: hostvars = yaml.safe_load(f) - # Testing against both Focal and Xenial must be supported for now in both - # staging scenarios, and in prod via `USE_FOCAL=1 ./securedrop-admin verify` - testing_focal = False - scenario_env = "MOLECULE_SCENARIO_NAME" - if scenario_env in os.environ and os.environ.get(scenario_env).endswith("focal"): - testing_focal = True - if "USE_FOCAL" in os.environ: - testing_focal = True - - if testing_focal: - hostvars['securedrop_venv_site_packages'] = hostvars["securedrop_venv_site_packages"].format("3.8") # noqa: E501 - hostvars['python_version'] = "3.8" - hostvars['apparmor_enforce_actual'] = hostvars['apparmor_enforce']['focal'] - else: - hostvars['securedrop_venv_site_packages'] = hostvars["securedrop_venv_site_packages"].format("3.5") # noqa: E501 - hostvars['python_version'] = "3.5" - hostvars['apparmor_enforce_actual'] = hostvars['apparmor_enforce']['xenial'] + hostvars['securedrop_venv_site_packages'] = hostvars["securedrop_venv_site_packages"].format("3.8") # noqa: E501 + hostvars['python_version'] = "3.8" + hostvars['apparmor_enforce_actual'] = hostvars['apparmor_enforce']['focal'] if with_header: hostvars = dict(securedrop_test_vars=hostvars) diff --git a/molecule/testinfra/mon/test_ossec_server.py b/molecule/testinfra/mon/test_ossec_server.py index 141afa415b..024a4cb369 100644 --- a/molecule/testinfra/mon/test_ossec_server.py +++ b/molecule/testinfra/mon/test_ossec_server.py @@ -24,16 +24,11 @@ def test_ossec_connectivity(host): def test_ossec_service_start_style(host): """ - Ensure that the OSSEC services are managed by systemd under Focal, - but by sysv under Xenial. + Ensure that the OSSEC services are managed by systemd. """ - if host.system_info.codename == "focal": - value = "/etc/systemd/system/ossec.service" - else: - value = "/etc/init.d/ossec" with host.sudo(): c = host.check_output("systemctl status ossec") - assert value in c + assert "/etc/systemd/system/ossec.service" in c # Permissions don't match between Ansible and OSSEC deb packages postinst. diff --git a/molecule/testinfra/mon/test_postfix.py b/molecule/testinfra/mon/test_postfix.py index 890766d66b..4b1b0d78ee 100644 --- a/molecule/testinfra/mon/test_postfix.py +++ b/molecule/testinfra/mon/test_postfix.py @@ -37,12 +37,8 @@ def test_postfix_generic_maps(host): """ assert not host.file("/etc/postfix/generic").exists assert not host.file("/etc/postfix/main.cf").contains("^smtp_generic_maps") - if host.system_info.codename == "focal": - assert host.file("/etc/postfix/main.cf").contains( - "^smtpd_recipient_restrictions = reject_unauth_destination") - if host.system_info.codename == "xenial": - assert not host.file("/etc/postfix/main.cf").contains( - "^smtpd_recipient_restrictions = reject_unauth_destination") + assert host.file("/etc/postfix/main.cf").contains( + "^smtpd_recipient_restrictions = reject_unauth_destination") def test_postfix_service(host): diff --git a/molecule/testinfra/vars/app-prod.yml b/molecule/testinfra/vars/app-prod.yml index 9543eb97fb..030c531467 100644 --- a/molecule/testinfra/vars/app-prod.yml +++ b/molecule/testinfra/vars/app-prod.yml @@ -30,17 +30,6 @@ apparmor_enforce: - "/usr/sbin/apache2//DEFAULT_URI" - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - "/usr/sbin/tor" - xenial: - - "sbin/dhclient" - - "/usr/lib/NetworkManager/nm-dhcp-client.action" - - "/usr/lib/connman/scripts/dhclient-script" - - "/usr/sbin/ntpd" - - "/usr/sbin/tcpdump" - - "system_tor" - - "/usr/sbin/apache2" - - "/usr/sbin/apache2//DEFAULT_URI" - - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - - "/usr/sbin/tor" apparmor_complain: [] diff --git a/molecule/testinfra/vars/app-staging.yml b/molecule/testinfra/vars/app-staging.yml index 39fafc5d7f..41a3ee293b 100644 --- a/molecule/testinfra/vars/app-staging.yml +++ b/molecule/testinfra/vars/app-staging.yml @@ -43,17 +43,6 @@ apparmor_enforce: - "/usr/sbin/apache2//DEFAULT_URI" - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - "/usr/sbin/tor" - xenial: - - "sbin/dhclient" - - "/usr/lib/NetworkManager/nm-dhcp-client.action" - - "/usr/lib/connman/scripts/dhclient-script" - - "/usr/sbin/ntpd" - - "/usr/sbin/tcpdump" - - "system_tor" - - "/usr/sbin/apache2" - - "/usr/sbin/apache2//DEFAULT_URI" - - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - - "/usr/sbin/tor" app_directories: - /var/www/securedrop diff --git a/molecule/testinfra/vars/prod.yml b/molecule/testinfra/vars/prod.yml index 9ccd6fe5fe..77afa044f7 100644 --- a/molecule/testinfra/vars/prod.yml +++ b/molecule/testinfra/vars/prod.yml @@ -43,17 +43,6 @@ apparmor_enforce: - "/usr/sbin/apache2//DEFAULT_URI" - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - "/usr/sbin/tor" - xenial: - - "sbin/dhclient" - - "/usr/lib/NetworkManager/nm-dhcp-client.action" - - "/usr/lib/connman/scripts/dhclient-script" - - "/usr/sbin/ntpd" - - "/usr/sbin/tcpdump" - - "system_tor" - - "/usr/sbin/apache2" - - "/usr/sbin/apache2//DEFAULT_URI" - - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - - "/usr/sbin/tor" app_directories: - /var/www/securedrop @@ -203,5 +192,4 @@ log_events_with_ossec_alerts: rule_id: "400700" fpf_apt_repo_url: "https://apt.freedom.press" -grsec_version_xenial: "4.14.188" grsec_version_focal: "5.4.97" diff --git a/molecule/testinfra/vars/prodVM.yml b/molecule/testinfra/vars/prodVM.yml index 660cee5936..1b9f8744aa 100644 --- a/molecule/testinfra/vars/prodVM.yml +++ b/molecule/testinfra/vars/prodVM.yml @@ -42,17 +42,6 @@ apparmor_enforce: - "/usr/sbin/apache2//DEFAULT_URI" - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - "/usr/sbin/tor" - xenial: - - "sbin/dhclient" - - "/usr/lib/NetworkManager/nm-dhcp-client.action" - - "/usr/lib/connman/scripts/dhclient-script" - - "/usr/sbin/ntpd" - - "/usr/sbin/tcpdump" - - "system_tor" - - "/usr/sbin/apache2" - - "/usr/sbin/apache2//DEFAULT_URI" - - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - - "/usr/sbin/tor" app_directories: - /var/www/securedrop @@ -202,5 +191,4 @@ log_events_with_ossec_alerts: rule_id: "400700" fpf_apt_repo_url: "https://apt.freedom.press" -grsec_version_xenial: "4.14.188" grsec_version_focal: "5.4.97" diff --git a/molecule/testinfra/vars/qubes-staging.yml b/molecule/testinfra/vars/qubes-staging.yml index 4f681ea542..83a1969a15 100644 --- a/molecule/testinfra/vars/qubes-staging.yml +++ b/molecule/testinfra/vars/qubes-staging.yml @@ -44,17 +44,6 @@ apparmor_enforce: - "/usr/sbin/apache2//DEFAULT_URI" - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - "/usr/sbin/tor" - xenial: - - "sbin/dhclient" - - "/usr/lib/NetworkManager/nm-dhcp-client.action" - - "/usr/lib/connman/scripts/dhclient-script" - - "/usr/sbin/ntpd" - - "/usr/sbin/tcpdump" - - "system_tor" - - "/usr/sbin/apache2" - - "/usr/sbin/apache2//DEFAULT_URI" - - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - - "/usr/sbin/tor" app_directories: - /var/www/securedrop @@ -205,5 +194,4 @@ log_events_with_ossec_alerts: fpf_apt_repo_url: "https://apt-test.freedom.press" -grsec_version_xenial: "4.14.188" grsec_version_focal: "5.4.97" diff --git a/molecule/testinfra/vars/staging.yml b/molecule/testinfra/vars/staging.yml index 6582a1042c..c800fa266f 100644 --- a/molecule/testinfra/vars/staging.yml +++ b/molecule/testinfra/vars/staging.yml @@ -44,17 +44,6 @@ apparmor_enforce: - "/usr/sbin/apache2//DEFAULT_URI" - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - "/usr/sbin/tor" - xenial: - - "sbin/dhclient" - - "/usr/lib/NetworkManager/nm-dhcp-client.action" - - "/usr/lib/connman/scripts/dhclient-script" - - "/usr/sbin/ntpd" - - "/usr/sbin/tcpdump" - - "system_tor" - - "/usr/sbin/apache2" - - "/usr/sbin/apache2//DEFAULT_URI" - - "/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" - - "/usr/sbin/tor" app_directories: - /var/www/securedrop @@ -218,5 +207,4 @@ log_events_with_ossec_alerts: rule_id: "400700" fpf_apt_repo_url: "https://apt-test.freedom.press" -grsec_version_xenial: "4.14.188" grsec_version_focal: "5.4.97" From 0105b3bbcbce898d5927be65ac9a88b40d6ce255 Mon Sep 17 00:00:00 2001 From: Conor Schaefer Date: Wed, 28 Apr 2021 15:26:41 -0700 Subject: [PATCH 11/12] Updates CI config to remove Xenial references A few scripts have been updated, mostly it's the default for BASE_OS and similar vars that now defaults to Focal. The big change is snipping out all the special cases for Focal within the CircleCI config, and using it by default everywhere. --- .circleci/config.yml | 178 +++----------------------- Makefile | 16 +-- devops/gce-nested/ci-go.sh | 2 +- devops/gce-nested/gce-runner.sh | 13 +- devops/scripts/select-staging-env | 5 +- devops/scripts/test-built-packages.sh | 2 +- update_version.sh | 2 - 7 files changed, 26 insertions(+), 192 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5f350d7d66..4d61769f15 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ common-steps: - &restorecache restore_cache: - key: v1-sd-layers-{{ checksum "securedrop/dockerfiles/xenial/python3/Dockerfile" }} + key: v1-sd-layers-{{ checksum "securedrop/dockerfiles/focal/python3/Dockerfile" }} paths: - /caches/layers.tar.gz @@ -35,63 +35,21 @@ common-steps: command: | set +o pipefail docker images - fromtag=$(docker images |grep securedrop-test-xenial-py3 |head -n1 |awk '{print $2}') - cd securedrop && DOCKER_BUILD_VERBOSE=true DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-xenial-py3:${fromtag:-latest}" ./bin/dev-shell true + fromtag=$(docker images |grep securedrop-test-focal-py3 |head -n1 |awk '{print $2}') + cd securedrop && DOCKER_BUILD_VERBOSE=true DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-focal-py3:${fromtag:-latest}" ./bin/dev-shell true - &saveimagelayers run: name: Save Docker image layer cache command: | docker images - docker save -o /caches/layers.tar securedrop-test-xenial-py3:latest + docker save -o /caches/layers.tar securedrop-test-focal-py3:latest - &savecache - save_cache: - key: v1-sd-layers-{{ checksum "securedrop/dockerfiles/xenial/python3/Dockerfile" }} - paths: - - /caches/layers.tar - - - &focalcreatecachedir - run: - name: Ensure cache dir exists and permissions are good - command: | - sudo mkdir -p /focalcaches && sudo chown circleci: -R /focalcaches - - - &focalrestorecache - restore_cache: - key: v1-sd-layers-{{ checksum "securedrop/dockerfiles/focal/python3/Dockerfile" }} - paths: - - /focalcaches/layers.tar.gz - - - &focalloadimagelayers - run: - name: Load image layer cache on Focal - command: | - set +o pipefail - docker load -i /focalcaches/layers.tar || true - - - &focaldockerimagebuild - run: - name: Build Docker images for Focal - command: | - set +o pipefail - docker images - fromtag=$(docker images |grep securedrop-test-focal-py3 |head -n1 |awk '{print $2}') - cd securedrop && DOCKER_BUILD_VERBOSE=true DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-focal-py3:${fromtag:-latest}" BASE_OS=focal ./bin/dev-shell true - - - &focalsaveimagelayers - run: - name: Save Docker image layer cache on Focal - command: | - docker images - docker save -o /focalcaches/layers.tar securedrop-test-focal-py3:latest - - - &focalsavecache save_cache: key: v1-sd-layers-{{ checksum "securedrop/dockerfiles/focal/python3/Dockerfile" }} paths: - - /focalcaches/layers.tar - + - /caches/layers.tar version: 2 jobs: @@ -123,47 +81,13 @@ jobs: name: Run shellcheck command: make shellcheck - focal-app-tests: - machine: - image: ubuntu-2004:202010-01 - enabled: true - environment: - DOCKER_API_VERSION: 1.23 - BASE_OS: focal - parallelism: 3 - steps: - - checkout - - *rebaseontarget - - *focalcreatecachedir - - *focalrestorecache - - *focalloadimagelayers - - *focaldockerimagebuild - - *focalsaveimagelayers - - *focalsavecache - - - run: - name: Run tests on Focal - command: | - BRANCH_MATCH=$(devops/scripts/match-ci-branch.sh "^(i18n|update-builder)") - if [[ $BRANCH_MATCH =~ ^found ]]; then echo "Skipping: ${BRANCH_MATCH}"; exit 0; fi - export TESTFILES=$(cd securedrop; circleci tests glob 'tests/test*py' 'tests/**/test*py' |circleci tests split --split-by=timings |xargs echo) - fromtag=$(docker images |grep securedrop-test-focal-py3 |head -n1 |awk '{print $2}') - DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-focal-py3:${fromtag:-latest}" make test-focal - no_output_timeout: 15m - - - store_test_results: - path: ~/project/test-results-focal - - - store_artifacts: - path: ~/project/test-results-focal - app-tests: machine: image: ubuntu-2004:202010-01 enabled: true environment: DOCKER_API_VERSION: 1.23 - BASE_OS: xenial + BASE_OS: focal parallelism: 3 steps: - checkout @@ -181,8 +105,8 @@ jobs: BRANCH_MATCH=$(devops/scripts/match-ci-branch.sh "^(i18n|update-builder)") if [[ $BRANCH_MATCH =~ ^found ]]; then echo "Skipping: ${BRANCH_MATCH}"; exit 0; fi export TESTFILES=$(cd securedrop; circleci tests glob 'tests/test*py' 'tests/**/test*py' |circleci tests split --split-by=timings |xargs echo) - fromtag=$(docker images |grep securedrop-test-xenial-py3 |head -n1 |awk '{print $2}') - DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-xenial-py3:${fromtag:-latest}" make test + fromtag=$(docker images |grep securedrop-test-focal-py3 |head -n1 |awk '{print $2}') + DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-focal-py3:${fromtag:-latest}" make test no_output_timeout: 15m - store_test_results: @@ -197,7 +121,7 @@ jobs: enabled: true environment: DOCKER_API_VERSION: 1.23 - BASE_OS: xenial + BASE_OS: focal parallelism: 20 steps: - checkout @@ -216,8 +140,8 @@ jobs: if ! [[ $BRANCH_MATCH =~ ^found ]]; then echo "Skipping: ${BRANCH_MATCH}"; exit 0; fi sudo apt update && sudo apt install python3-sh python3-babel export LOCALES="$(/usr/bin/python3 securedrop/i18n_tool.py list-locales --lines | circleci tests split | tr '\n' ' ')" - fromtag=$(docker images | grep securedrop-test-xenial-py3 | head -n1 | awk '{print $2}') - DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-xenial-py3:${fromtag:-latest}" make translation-test + fromtag=$(docker images | grep securedrop-test-focal-py3 | head -n1 | awk '{print $2}') + DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-focal-py3:${fromtag:-latest}" make translation-test - store_test_results: path: ~/project/test-results @@ -284,7 +208,7 @@ jobs: enabled: true environment: DOCKER_API_VERSION: 1.23 - BASE_OS: xenial + BASE_OS: focal steps: - checkout - *rebaseontarget @@ -298,14 +222,14 @@ jobs: - run: name: Check Python dependencies for CVEs command: | - fromtag=$(docker images |grep securedrop-test-xenial-py3 |head -n1 |awk '{print $2}') - DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-xenial-py3:${fromtag:-latest}" securedrop/bin/dev-shell bash -c "pip3 install -U -q --upgrade safety && make -C .. safety" + fromtag=$(docker images |grep securedrop-test-focal-py3 |head -n1 |awk '{print $2}') + DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-focal-py3:${fromtag:-latest}" securedrop/bin/dev-shell bash -c "pip3 install -U -q --upgrade safety && make -C .. safety" - run: name: Run static security testing on source code command: | - fromtag=$(docker images |grep securedrop-test-xenial-py3 |head -n1 |awk '{print $2}') - DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-xenial-py3:${fromtag:-latest}" securedrop/bin/dev-shell bash -c "pip3 install -U -q --upgrade pip && pip3 install -U -q --upgrade bandit && make -C .. bandit" + fromtag=$(docker images |grep securedrop-test-focal-py3 |head -n1 |awk '{print $2}') + DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-focal-py3:${fromtag:-latest}" securedrop/bin/dev-shell bash -c "pip3 install -U -q --upgrade pip && pip3 install -U -q --upgrade bandit && make -C .. bandit" staging-test-with-rebase: @@ -340,38 +264,6 @@ jobs: - store_artifacts: path: ~/sd/junit - staging-test-with-rebase-focal: - machine: - image: ubuntu-2004:202010-01 - enabled: true - - working_directory: ~/sd - steps: - - checkout - - *rebaseontarget - - *installenchant - - - run: - name: Run Staging tests on GCE - command: | - BRANCH_MATCH=$(devops/scripts/match-ci-branch.sh "^(i18n)") - if [[ $BRANCH_MATCH =~ ^found ]]; then echo "Skipping: ${BRANCH_MATCH}"; exit 0; fi - BASE_OS=focal make ci-go - no_output_timeout: 35m - - - run: - name: Ensure environment torn down - # Always report true, since env should will destroyed already - # if all tests passed. - command: make ci-teardown || true - when: always - - - store_test_results: - path: ~/sd/junit - - - store_artifacts: - path: ~/sd/junit - deb-tests: docker: - image: cimg/python:3.7 @@ -389,21 +281,6 @@ jobs: if ! [[ $BRANCH_MATCH =~ ^found ]]; then echo "Skipping: ${BRANCH_MATCH}"; exit 0; fi make ci-deb-tests - deb-tests-focal: - docker: - - image: cimg/python:3.7 - environment: - LC_ALL: C.UTF-8 - LANG: C.UTF-8 - steps: - - run: sudo apt-get update && sudo apt-get install -y make virtualenv enchant jq python3-dev build-essential rsync - - checkout - - setup_remote_docker - - run: - name: Test Debian package build on Focal - command: | - make ci-deb-tests-focal - workflows: version: 2 securedrop_ci: @@ -417,14 +294,6 @@ workflows: - /update-builder-.*/ requires: - lint - - focal-app-tests: - filters: - branches: - ignore: - - /i18n-.*/ - - /update-builder-.*/ - requires: - - lint - admin-tests: filters: branches: @@ -451,13 +320,6 @@ workflows: - /i18n-.*/ requires: - lint - - staging-test-with-rebase-focal: - filters: - branches: - ignore: - - /i18n-.*/ - requires: - - lint - translation-tests: requires: - lint @@ -468,13 +330,6 @@ workflows: - /update-builder-.*/ requires: - lint - - deb-tests-focal: - filters: - branches: - ignore: - - /i18n-.*/ - requires: - - lint nightly: triggers: @@ -497,6 +352,5 @@ workflows: - develop jobs: - deb-tests - - deb-tests-focal - translation-tests - fetch-tor-debs diff --git a/Makefile b/Makefile index e912742755..56a642ad12 100644 --- a/Makefile +++ b/Makefile @@ -219,10 +219,7 @@ test: ## Run the test suite in a Docker container. @echo .PHONY: test-focal -test-focal: ## Run the test suite in a Docker container. - @echo "███ Running SecureDrop application tests..." - @BASE_OS='focal' $(DEVSHELL) $(SDBIN)/run-test -v $${TESTFILES:-tests} - @echo +test-focal: test .PHONY: docker-vnc docker-vnc: ## Open a VNC connection to a running Docker instance. @@ -230,7 +227,6 @@ docker-vnc: ## Open a VNC connection to a running Docker instance. @$(SDROOT)/devops/scripts/vnc-docker-connect.sh @echo -# Xenial upgrade targets .PHONY: upgrade-start upgrade-start: ## Boot an upgrade test environment using libvirt. @echo "███ Starting upgrade test environment..." @@ -344,14 +340,6 @@ ci-deb-tests: ## Test SecureDrop Debian packages in CI environment. @$(SDROOT)/devops/scripts/test-built-packages.sh @echo -.PHONY: ci-deb-tests-focal -ci-deb-tests-focal: ## Test SecureDrop Debian packages in CI environment. - @echo "███ Running Debian package tests in CI..." - @$(SDROOT)/devops/scripts/test-built-packages.sh focal - @echo - - - .PHONY: build-gcloud-docker build-gcloud-docker: ## Build Docker container for Google Cloud SDK. @echo "Building Docker container for Google Cloud SDK..." @@ -368,7 +356,7 @@ vagrant-package: ## Package a Vagrant box of the last stable SecureDrop release @echo .PHONY: fetch-tor-packages -fetch-tor-packages: ## Retrieves the most recent Tor packages for Xenial, for apt repo. +fetch-tor-packages: ## Retrieves the most recent Tor packages, for apt repo. @echo "Fetching most recent Tor packages..." @$(SDROOT)/devops/scripts/fetch-tor-packages.sh @echo diff --git a/devops/gce-nested/ci-go.sh b/devops/gce-nested/ci-go.sh index 850324eccd..ff80aa107e 100755 --- a/devops/gce-nested/ci-go.sh +++ b/devops/gce-nested/ci-go.sh @@ -12,7 +12,7 @@ set -e set -u set -o pipefail -export BASE_OS="${BASE_OS:-xenial}" +export BASE_OS="${BASE_OS:-focal}" ./devops/gce-nested/gce-start.sh ./devops/gce-nested/gce-runner.sh diff --git a/devops/gce-nested/gce-runner.sh b/devops/gce-nested/gce-runner.sh index 374f0493f1..955e937296 100755 --- a/devops/gce-nested/gce-runner.sh +++ b/devops/gce-nested/gce-runner.sh @@ -4,7 +4,7 @@ # for storage as artifacts on the build, so devs can review via web. set -e set -u -BASE_OS="${BASE_OS:-xenial}" +BASE_OS="${BASE_OS:-focal}" TOPLEVEL="$(git rev-parse --show-toplevel)" @@ -56,11 +56,6 @@ copy_securedrop_repo # The test results should be collected regardless of pass/fail, # so register a trap to ensure the fetch always runs. trap fetch_junit_test_results EXIT -if [ "${BASE_OS:-'xenial'}" = "xenial" ] -then - ssh_gce "make build-debs-notest" - ssh_gce "make staging" -else - ssh_gce "make build-debs-notest-focal" - ssh_gce "make staging-focal" -fi + +ssh_gce "make build-debs-notest" +ssh_gce "make staging" diff --git a/devops/scripts/select-staging-env b/devops/scripts/select-staging-env index df67de7c6a..b11ecb514f 100755 --- a/devops/scripts/select-staging-env +++ b/devops/scripts/select-staging-env @@ -13,14 +13,13 @@ set -o pipefail # Support overrides for LTS version -securedrop_platform_suffix="-${1:-xenial}" +securedrop_platform_suffix="-${1:-focal}" # Respect explicit choice of Vagrant provider if set. if [[ -n "${VAGRANT_DEFAULT_PROVIDER:-}" ]] ; then securedrop_vm_provider="${VAGRANT_DEFAULT_PROVIDER}" # Check whether it appears we're running in Qubes, in which case the standard Vagrant -# logic will not work at all, due to lack of nested virt support. The Qubes staging -# environment uses Xenial template VMs only, so we also suppress the platform suffix. +# logic will not work at all, due to lack of nested virt support. elif printenv | grep -q ^QUBES_ ; then securedrop_vm_provider="qubes" elif [[ "${OSTYPE:-}" == "linux-gnu" ]]; then diff --git a/devops/scripts/test-built-packages.sh b/devops/scripts/test-built-packages.sh index 79af577b1e..70eaba326e 100755 --- a/devops/scripts/test-built-packages.sh +++ b/devops/scripts/test-built-packages.sh @@ -5,7 +5,7 @@ set -e set -o pipefail -TARGET_PLATFORM="${1:-xenial}" +TARGET_PLATFORM="${1:-focal}" . ./devops/scripts/boot-strap-venv.sh virtualenv_bootstrap diff --git a/update_version.sh b/update_version.sh index 6109ecfc13..4a2ef44388 100755 --- a/update_version.sh +++ b/update_version.sh @@ -65,8 +65,6 @@ sed -i "s/\(## ${OLD_VERSION}\)/## ${NEW_VERSION}\n\n\n\n\1/g" changelog.md export DEBEMAIL="${DEBEMAIL:-securedrop@freedom.press}" export DEBFULLNAME="${DEBFULLNAME:-SecureDrop Team}" -# Update the Xenial changelog in the Debian package -dch -b -v "${NEW_VERSION}+xenial" -D xenial -c install_files/ansible-base/roles/build-securedrop-app-code-deb-pkg/files/changelog-xenial # Update the Focal changelog in the Debian package dch -b -v "${NEW_VERSION}+focal" -D focal -c install_files/ansible-base/roles/build-securedrop-app-code-deb-pkg/files/changelog-focal # Commit the change From 7fa6f651955d16fe3c4795f5f84299f815288477 Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Fri, 30 Apr 2021 18:30:51 +0530 Subject: [PATCH 12/12] Removes EOL related strings from journalist interface Also updated the translations after updating the journalist interface. --- securedrop/journalist_templates/base.html | 10 ----- .../translations/ar/LC_MESSAGES/messages.po | 38 +++++++++---------- .../translations/ca/LC_MESSAGES/messages.po | 30 +++++++-------- .../translations/cs/LC_MESSAGES/messages.po | 32 ++++++++-------- .../de_DE/LC_MESSAGES/messages.po | 30 +++++++-------- .../translations/el/LC_MESSAGES/messages.po | 30 +++++++-------- .../es_ES/LC_MESSAGES/messages.po | 30 +++++++-------- .../fr_FR/LC_MESSAGES/messages.po | 30 +++++++-------- .../translations/hi/LC_MESSAGES/messages.po | 30 +++++++-------- .../translations/is/LC_MESSAGES/messages.po | 30 +++++++-------- .../it_IT/LC_MESSAGES/messages.po | 30 +++++++-------- securedrop/translations/messages.pot | 13 +------ .../nb_NO/LC_MESSAGES/messages.po | 30 +++++++-------- .../translations/nl/LC_MESSAGES/messages.po | 30 +++++++-------- .../pt_BR/LC_MESSAGES/messages.po | 30 +++++++-------- .../translations/ro/LC_MESSAGES/messages.po | 32 ++++++++-------- .../translations/ru/LC_MESSAGES/messages.po | 32 ++++++++-------- .../translations/sk/LC_MESSAGES/messages.po | 32 ++++++++-------- .../translations/sv/LC_MESSAGES/messages.po | 30 +++++++-------- .../translations/tr/LC_MESSAGES/messages.po | 30 +++++++-------- .../zh_Hans/LC_MESSAGES/messages.po | 28 +++++++------- .../zh_Hant/LC_MESSAGES/messages.po | 28 +++++++------- 22 files changed, 307 insertions(+), 328 deletions(-) diff --git a/securedrop/journalist_templates/base.html b/securedrop/journalist_templates/base.html index d95f1b425b..d889f50bce 100644 --- a/securedrop/journalist_templates/base.html +++ b/securedrop/journalist_templates/base.html @@ -19,16 +19,6 @@ {% if g.user %} - {% if g.show_os_past_eol_warning %} -
- {{ gettext ('Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More') }} -
- {% elif g.show_os_near_eol_warning %} -
- {{ gettext ('Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More') }} -
- {% endif %} -
{{ gettext('Logged on as') }} {{ g.user.username }} | {% if g.user and g.user.is_admin %} diff --git a/securedrop/translations/ar/LC_MESSAGES/messages.po b/securedrop/translations/ar/LC_MESSAGES/messages.po index 616939504f..5f66751ff0 100644 --- a/securedrop/translations/ar/LC_MESSAGES/messages.po +++ b/securedrop/translations/ar/LC_MESSAGES/messages.po @@ -24,10 +24,7 @@ msgstr "" msgid "Name too long" msgstr "إن نص الرسالة طويلٌ جداً." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "يجب ألا يحوي أي حرف." msgstr[1] "يجب أن يحوي حرفًا واحدًا على الأقل." @@ -140,15 +137,6 @@ msgstr[3] "تتألّف كلمة السرّ من نوع HOTP من 40 حرفًا msgstr[4] "تتألّف كلمة السرّ من نوع HOTP من 40 حرفًا على الأقل - أنت أدخلت {num} حرفًا." msgstr[5] "تتألّف كلمة السرّ من نوع HOTP من 40 حرفًا على الأقل - أنت أدخلت {num} حرفًا." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "يجب ألا يحوي أي حرف." -msgstr[1] "يجب أن يحوي حرفًا واحدًا على الأقل." -msgstr[2] "يجب أن يحوي حرفين على الأقل." -msgstr[3] "يجب أن يحوي {num} حروف على الأقل." -msgstr[4] "يجب أن يحوي {num} حرفًا على الأقل." -msgstr[5] "يجب أن يحوي {num} حرفًا على الأقل." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "هذا الحقل لا يقبل أي حرف." @@ -448,12 +436,6 @@ msgstr "هل عجزت عن مسح وقراءة شريط الرموز أي الب msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "بعد إتمام ضبط مفتاح الاستيثاق \"YubiKey\" أدخل الرمز المكون من 6 أرقام:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "تنبيه أمني حرج  نظام التشغيل المستخدم فى خواديم SecureDrop الخاصة بك قد بلغ نهاية مدة الخدمة. لا بد من ترقيته يدويا لإعادة تفعيل واجهة المصدر والمحافظة على الأمان. من فضلك تواصل مع مسئولكلمعرفة المزيد" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "تنبيه أمنى حرج  نظام التشغيل المستخدم فى خواديم SecureDrop الخاصة بك قد سوف يبلغ نهاية مدة الخدمة في 30 أبريل/نيسان 2021. لا بد من ترقيته يدويا للحفاظ على الأمان. من فضلك تواصل مع مسئولكلمعرفة المزيد" - msgid "Logged on as" msgstr "والج باسم" @@ -1037,6 +1019,24 @@ msgstr "هام: إذا كنت ترغب في البقاء مجه msgid "Back to submission page" msgstr "الرجوع إلى صفحة الإيداع" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "يجب ألا يحوي أي حرف." +#~ msgstr[1] "يجب أن يحوي حرفًا واحدًا على الأقل." +#~ msgstr[2] "يجب أن يحوي حرفين على الأقل." +#~ msgstr[3] "يجب أن يحوي {num} حروف على الأقل." +#~ msgstr[4] "يجب أن يحوي {num} حرفًا على الأقل." +#~ msgstr[5] "يجب أن يحوي {num} حرفًا على الأقل." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "تنبيه أمني حرج  نظام التشغيل المستخدم فى خواديم SecureDrop الخاصة بك قد بلغ نهاية مدة الخدمة. لا بد من ترقيته يدويا لإعادة تفعيل واجهة المصدر والمحافظة على الأمان. من فضلك تواصل مع مسئولكلمعرفة المزيد" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "تنبيه أمنى حرج  نظام التشغيل المستخدم فى خواديم SecureDrop الخاصة بك قد سوف يبلغ نهاية مدة الخدمة في 30 أبريل/نيسان 2021. لا بد من ترقيته يدويا للحفاظ على الأمان. من فضلك تواصل مع مسئولكلمعرفة المزيد" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "تنبيه: يبدو أنك تستخدم خدمة Tor2Web. يجب الانتباه إلى أنّ هذه الوسيلة لا تحقق المجهولية للمستخدم. ما الخطر في ذلك؟" diff --git a/securedrop/translations/ca/LC_MESSAGES/messages.po b/securedrop/translations/ca/LC_MESSAGES/messages.po index 80338fdfca..ba8bfe8f89 100644 --- a/securedrop/translations/ca/LC_MESSAGES/messages.po +++ b/securedrop/translations/ca/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "El missatge de text és massa llarg." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Cal que tingui com a mínim {num} caràcter." msgstr[1] "Cal que tingui com a mínim {num} caràcters." @@ -131,11 +128,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "Els secrets HOTP tenen una mida de 40 caràcters, però n’heu introduït {num}." msgstr[1] "Els secrets HOTP tenen una mida de 40 caràcters, però n’heu introduït {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Cal que tingui com a mínim {num} caràcter." -msgstr[1] "Cal que tingui com a mínim {num} caràcters." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "No pot tenir més d'{num} caràcter." @@ -407,12 +399,6 @@ msgstr "No podeu escanejar el codi de barres? Podeu vincular manualment el FreeO msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Quan hàgiu configurat la YubiKey, introduïu aquest codi de sis dígits:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Seguretat crítica  El sistema operatiu usat pels servidors del vostre SecureDrop ha assolit el final de cicle. Cal una actualització manual per restablir la interfície de fonts i mantenir-se segur. Contacteu amb l'administrador. Més informació" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Seguretat crítica  El sistema operatiu usat pels servidors del vostre SecureDrop assolirà el final de cicle el 30 d'abril de 2021. Cal una actualització manual de forma urgent per a mantenir-se segur. Contacteu amb l'administrador. Més informació" - msgid "Logged on as" msgstr "Sessió iniciada com a" @@ -992,6 +978,20 @@ msgstr "Important: si voleu romandre anònimament, noCritical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Seguretat crítica  El sistema operatiu usat pels servidors del vostre SecureDrop ha assolit el final de cicle. Cal una actualització manual per restablir la interfície de fonts i mantenir-se segur. Contacteu amb l'administrador. Més informació" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Seguretat crítica  El sistema operatiu usat pels servidors del vostre SecureDrop assolirà el final de cicle el 30 d'abril de 2021. Cal una actualització manual de forma urgent per a mantenir-se segur. Contacteu amb l'administrador. Més informació" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "ATENCIÓ:  Sembla que feu servir el Tor2Web. Això  no  proporciona anonimat. Per què és perillós?" diff --git a/securedrop/translations/cs/LC_MESSAGES/messages.po b/securedrop/translations/cs/LC_MESSAGES/messages.po index b0f4f6f81d..4120b63c2f 100644 --- a/securedrop/translations/cs/LC_MESSAGES/messages.po +++ b/securedrop/translations/cs/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "Zpráva je příliš dlouhá." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Uživatelské jméno musí mít alespoň {num} znak." msgstr[1] "Uživatelské jméno musí mít alespoň {num} znaky." @@ -133,12 +130,6 @@ msgstr[0] "HOTP hesla mají 40 znaků - zadal/a jste {num} znak." msgstr[1] "HOTP hesla mají 40 znaků - zadal/a jste {num} znaky." msgstr[2] "HOTP hesla mají 40 znaků - zadal/a jste {num} znaků." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Uživatelské jméno musí mít alespoň {num} znak." -msgstr[1] "Uživatelské jméno musí mít alespoň {num} znaky." -msgstr[2] "Uživatelské jméno musí mít alespoň {num} znaků." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Uživatelské jméno nemůže obsahovat více než {num} znak." @@ -417,12 +408,6 @@ msgstr "Nemůžete načíst čárový kód? Můžete manuálně spárovat FreeOT msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Jakmile nastavíte svůj YubiKey, zadejte šesticiferný kód níže:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Nezbytné zabezpečení: Operační systém vašich SecureDrop serverů dosáhl konce životnosti. Pro bezpečné zprovoznění rozhraní pro zdroje je nutný manuální upgrade. Kontaktujte svého administrátora.Dozvědět se více" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Nezbytné zabezpečení: Operačnímu systému vašich SecureDrop serverů končí životnost 30. dubna 2021. Pro bezpečnou komunikaci je urgentně vyžadován manuální upgrade. Kontaktujte svého administrátora.Dozvědět se více" - msgid "Logged on as" msgstr "Přihlášen/a jako" @@ -1003,6 +988,21 @@ msgstr "Důležité: Chcete-li zůstat v anonymitě, ne msgid "Back to submission page" msgstr "Zpátky na stránku podání" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Uživatelské jméno musí mít alespoň {num} znak." +#~ msgstr[1] "Uživatelské jméno musí mít alespoň {num} znaky." +#~ msgstr[2] "Uživatelské jméno musí mít alespoň {num} znaků." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Nezbytné zabezpečení: Operační systém vašich SecureDrop serverů dosáhl konce životnosti. Pro bezpečné zprovoznění rozhraní pro zdroje je nutný manuální upgrade. Kontaktujte svého administrátora.Dozvědět se více" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Nezbytné zabezpečení: Operačnímu systému vašich SecureDrop serverů končí životnost 30. dubna 2021. Pro bezpečnou komunikaci je urgentně vyžadován manuální upgrade. Kontaktujte svého administrátora.Dozvědět se více" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "VAROVÁNÍ:  Vypadá to, že používáte Tor2Web. To  neposkytuje anonymitu. Proč je to nebezpečné?" diff --git a/securedrop/translations/de_DE/LC_MESSAGES/messages.po b/securedrop/translations/de_DE/LC_MESSAGES/messages.po index f189b1ea30..4d06bca791 100644 --- a/securedrop/translations/de_DE/LC_MESSAGES/messages.po +++ b/securedrop/translations/de_DE/LC_MESSAGES/messages.po @@ -19,10 +19,7 @@ msgstr "" msgid "Name too long" msgstr "Nachricht zu lang." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Muss mindestens {num} Zeichen lang sein." msgstr[1] "Muss mindestens {num} Zeichen lang sein." @@ -127,11 +124,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "HOTP-Geheimnisse sind 40 Zeichen lang - Sie haben {num} eingegeben." msgstr[1] "HOTP-Geheimnisse sind 40 Zeichen lang - Sie haben {num} eingegeben." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Muss mindestens {num} Zeichen lang sein." -msgstr[1] "Muss mindestens {num} Zeichen lang sein." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Darf nicht länger als {num} Zeichen sein." @@ -403,12 +395,6 @@ msgstr "Können Sie den Barcode nicht scannen? Um FreeOTP manuell mit diesem Kon msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Geben sie den folgenden 6-stelligen Code unten ein, sobald Sie Ihren YubiKey konfiguriert haben:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Kritische Sicherheitswarnung:  Das von Ihren SecureDrop Servern benutzte Betriebssystem hat sein Lebensende erreicht. Ein manuelles Upgrade ist nötig um die Eingabemaske für Quellen wieder zu aktivieren und um Sicherheit weiterhin zu gewährleisten. Mehr Erfahren" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Kritische Sicherheitswarnung:   Das von Ihren SecureDrop Servern benutzte Betriebssystem wird am 30. April 2021 sein Lebensende erreichen. Ein manuelles Upgrade wird dringend benötigt um Sicherheit weiterhin zu gewährleisten. Bitte kontaktieren Sie Ihren Administrator - Mehr Erfahren" - msgid "Logged on as" msgstr "Angemeldet als" @@ -988,6 +974,20 @@ msgstr "Wichtig: Verwenden Sie nicht GPG, um d msgid "Back to submission page" msgstr "Zurück zur Einreichungsseite" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Muss mindestens {num} Zeichen lang sein." +#~ msgstr[1] "Muss mindestens {num} Zeichen lang sein." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritische Sicherheitswarnung:  Das von Ihren SecureDrop Servern benutzte Betriebssystem hat sein Lebensende erreicht. Ein manuelles Upgrade ist nötig um die Eingabemaske für Quellen wieder zu aktivieren und um Sicherheit weiterhin zu gewährleisten. Mehr Erfahren" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritische Sicherheitswarnung:   Das von Ihren SecureDrop Servern benutzte Betriebssystem wird am 30. April 2021 sein Lebensende erreichen. Ein manuelles Upgrade wird dringend benötigt um Sicherheit weiterhin zu gewährleisten. Bitte kontaktieren Sie Ihren Administrator - Mehr Erfahren" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "ACHTUNG:  Es scheint, dass Sie Tor2Web benutzen. Das garantiert  keine Anonymität.  Warum ist das gefährlich?" diff --git a/securedrop/translations/el/LC_MESSAGES/messages.po b/securedrop/translations/el/LC_MESSAGES/messages.po index 5035e34700..03d69cb618 100644 --- a/securedrop/translations/el/LC_MESSAGES/messages.po +++ b/securedrop/translations/el/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "Το κείμενο του μηνύματος είναι πολύ μεγάλο." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Πρέπει να έχει τουλάχιστον {num} χαρακτήρα." msgstr[1] "Πρέπει να έχει τουλάχιστον {num} χαρακτήρες." @@ -131,11 +128,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "Τα μυστικά HOTP έχουν μήκος 40 χαρακτήρες. Έχετε εισάγει {num}." msgstr[1] "Τα μυστικά HOTP έχουν μήκος 40 χαρακτήρες. Έχετε εισάγει {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Πρέπει να έχει τουλάχιστον {num} χαρακτήρα." -msgstr[1] "Πρέπει να έχει τουλάχιστον {num} χαρακτήρες." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Δεν μπορεί να περιέχει παραπάνω από {num} χαρακτήρα." @@ -407,12 +399,6 @@ msgstr "Δεν μπορείτε να σαρώσετε το barcode; Μπορεί msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Όταν ολοκληρώσετε την παραμετροποίηση του YubiKey σας, πληκτρολογήστε τον εξαψήφιο κωδικό παρακάτω:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Κρίσιμο ζήτημα ασφάλειας:  Το λειτουργικό σύστημα που χρησιμοποιούν οι διακομιστές του SecureDrop σας έχει φτάσει στο τέλος του κύκλου ζωής του. Χρειάζεται χειροκίνητη αναβάθμιση για να επανενεργοποιήσετε τη Διεπαφή πηγών και να παραμείνετε ασφαλείς. Παρακαλώ επικοινωνήστε με τη διαχείριση. Μάθετε περισσότερα" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Κρίσιμο ζήτημα ασφάλειας:  Το λειτουργικό σύστημα που χρησιμοποιούν οι διακομιστές του SecureDrop σας θα φτάσει στο τέλος του κύκλου ζωής του στις 30 Απριλίου 2021. Χρειάζεται επειγόντως μια χειροκίνητη αναβάθμιση για να παραμείνετε ασφαλείς. Παρακαλούμε επικοινωνήστε με τη διαχείριση. Μάθετε περισσότερα" - msgid "Logged on as" msgstr "Συνδεδεμένος/η ως" @@ -992,6 +978,20 @@ msgstr "Σημαντικό: Αν επιθυμείτε να δι msgid "Back to submission page" msgstr "Πίσω στη σελίδα υποβολών" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Πρέπει να έχει τουλάχιστον {num} χαρακτήρα." +#~ msgstr[1] "Πρέπει να έχει τουλάχιστον {num} χαρακτήρες." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Κρίσιμο ζήτημα ασφάλειας:  Το λειτουργικό σύστημα που χρησιμοποιούν οι διακομιστές του SecureDrop σας έχει φτάσει στο τέλος του κύκλου ζωής του. Χρειάζεται χειροκίνητη αναβάθμιση για να επανενεργοποιήσετε τη Διεπαφή πηγών και να παραμείνετε ασφαλείς. Παρακαλώ επικοινωνήστε με τη διαχείριση. Μάθετε περισσότερα" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Κρίσιμο ζήτημα ασφάλειας:  Το λειτουργικό σύστημα που χρησιμοποιούν οι διακομιστές του SecureDrop σας θα φτάσει στο τέλος του κύκλου ζωής του στις 30 Απριλίου 2021. Χρειάζεται επειγόντως μια χειροκίνητη αναβάθμιση για να παραμείνετε ασφαλείς. Παρακαλούμε επικοινωνήστε με τη διαχείριση. Μάθετε περισσότερα" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "ΠΡΟΣΟΧΗ:  Φαίνεται πως χρησιμοποιείτε την υπηρεσία Tor2Web. Αυτή  δεν  παρέχει ανωνυμία. Γιατί είναι επικίνδυνο αυτό;" diff --git a/securedrop/translations/es_ES/LC_MESSAGES/messages.po b/securedrop/translations/es_ES/LC_MESSAGES/messages.po index aefb3c179b..f3426d4b9f 100644 --- a/securedrop/translations/es_ES/LC_MESSAGES/messages.po +++ b/securedrop/translations/es_ES/LC_MESSAGES/messages.po @@ -24,10 +24,7 @@ msgstr "" msgid "Name too long" msgstr "Texto del mensaje demasiado largo." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Debe tener por lo menos {num} carácter de longitud." msgstr[1] "Debe tener por lo menos {num} caracteres de longitud." @@ -132,11 +129,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "Los secretos de HOTP deben ser de 40 caracteres de longitud, has introducido {num}." msgstr[1] "Los secretos de HOTP deben ser de 40 caracteres de longitud, has introducido {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Debe tener por lo menos {num} carácter de longitud." -msgstr[1] "Debe tener por lo menos {num} caracteres de longitud." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "No puede tener más que {num} carácter." @@ -408,12 +400,6 @@ msgstr "¿No puedes escanear el código de barras? Puedes emparejar manualmente msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Una vez que hayas configurado tu YubiKey, ingresa abajo el código de verificación de 6 dígitos:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Situación crítica de Seguridad:  El sistema operativo usado en tus servidores SecureDrop ha alcanzado el final de su ciclo de vida. Se necesita una actualización manual para rehabilitar la Interfaz de Fuente y permanecer seguro. Por favor contacta a tu administrador. Aprender Más" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Situación crítica de Seguridad:  El sistema operativo usado en tus servidores SecureDrop alcanzará el final de su ciclo de vida el 30 de abril de 2021. Se necesita urgentemente una actualización manual para permanecer seguro. Por favor contacta a tu administrador. Aprender Más" - msgid "Logged on as" msgstr "Sesión iniciada como" @@ -993,6 +979,20 @@ msgstr "Importante: Si deseas permanecer anónimo, noCritical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Situación crítica de Seguridad:  El sistema operativo usado en tus servidores SecureDrop ha alcanzado el final de su ciclo de vida. Se necesita una actualización manual para rehabilitar la Interfaz de Fuente y permanecer seguro. Por favor contacta a tu administrador. Aprender Más" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Situación crítica de Seguridad:  El sistema operativo usado en tus servidores SecureDrop alcanzará el final de su ciclo de vida el 30 de abril de 2021. Se necesita urgentemente una actualización manual para permanecer seguro. Por favor contacta a tu administrador. Aprender Más" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "ADVERTENCIA:  Pareces estar usando Tor2Web. Esto   no   proporciona anonimato. ¿Por qué es peligroso? " diff --git a/securedrop/translations/fr_FR/LC_MESSAGES/messages.po b/securedrop/translations/fr_FR/LC_MESSAGES/messages.po index 26098e7de1..30a7b58f22 100644 --- a/securedrop/translations/fr_FR/LC_MESSAGES/messages.po +++ b/securedrop/translations/fr_FR/LC_MESSAGES/messages.po @@ -24,10 +24,7 @@ msgstr "" msgid "Name too long" msgstr "Le texte du message est trop long." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Doit comporter au moins {num} caractère." msgstr[1] "Doit comporter au moins {num} caractères." @@ -132,11 +129,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "Les secrets HOTP comportent 40 caractères. Vous en avez saisi {num}." msgstr[1] "Les secrets HOTP comportent 40 caractères. Vous en avez saisi {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Doit comporter au moins {num} caractère." -msgstr[1] "Doit comporter au moins {num} caractères." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Ne peut pas dépasser {num} caractère." @@ -408,12 +400,6 @@ msgstr "Des difficultés pour balayer le code à barres ? Vous pouvez associer msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Après avoir configuré votre YubiKey, saisissez le code à 6 chiffres ci-dessous :" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Sécurité critique :  Le système d’exploitation utilisé par vos serveurs SecureDrop est arrivé en fin de vie. Une mise à niveau manuelle est exigée pour réactiver l’interface des sources et assurer la sécurité. Veuillez contacter votre administrateur. En apprendre davantage" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Sécurité critique :  Le système d’exploitation utilisé par vos serveurs SecureDrop arrivera en fin de vie le 30 avril 2021. Une mise à niveau manuelle est urgemment exigée pour assurer la sécurité. Veuillez contacter votre administrateur. En apprendre davantage" - msgid "Logged on as" msgstr "Connecté en tant que" @@ -993,6 +979,20 @@ msgstr "Important : Si vous souhaitez rester anonyme, msgid "Back to submission page" msgstr "Revenir à la page d'envoi" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Doit comporter au moins {num} caractère." +#~ msgstr[1] "Doit comporter au moins {num} caractères." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Sécurité critique :  Le système d’exploitation utilisé par vos serveurs SecureDrop est arrivé en fin de vie. Une mise à niveau manuelle est exigée pour réactiver l’interface des sources et assurer la sécurité. Veuillez contacter votre administrateur. En apprendre davantage" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Sécurité critique :  Le système d’exploitation utilisé par vos serveurs SecureDrop arrivera en fin de vie le 30 avril 2021. Une mise à niveau manuelle est urgemment exigée pour assurer la sécurité. Veuillez contacter votre administrateur. En apprendre davantage" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "AVERTISSEMENT :  il semble que vous utilisez Tor2Web. Cela ne garantit pas votre anonymat. Pourquoi est-ce dangereux ?" diff --git a/securedrop/translations/hi/LC_MESSAGES/messages.po b/securedrop/translations/hi/LC_MESSAGES/messages.po index 551d2fc53f..18a4f648ec 100644 --- a/securedrop/translations/hi/LC_MESSAGES/messages.po +++ b/securedrop/translations/hi/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "संदेश पाठ बहुत लंबा है |" -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "कम से कम {num} वर्ण लंबा होना चाहिए।" msgstr[1] "कम से कम {num} अक्षर लंबा होनी चाहिए।" @@ -131,11 +128,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "फ़ील्ड 40 वर्ण लंबा होनी चाहिए, लेकिन {num} मिले।" msgstr[1] "फ़ील्ड 40 वर्ण लंबा होनी चाहिए, लेकिन {num} मिले।" -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "कम से कम {num} वर्ण लंबा होना चाहिए।" -msgstr[1] "कम से कम {num} अक्षर लंबा होनी चाहिए।" - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "{num} वर्ण से अधिक लंबा नहीं होना चाहिए।" @@ -407,12 +399,6 @@ msgstr "बारकोड को स्कैन नहीं कर सकत msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "एक बार जब आप अपने YubiKey को कॉन्फ़िगर कर लेते हैं, तो नीचे 6 अंकों का कोड डालें:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "गंभीर सिक्यूरिटी समस्या:आपके SecureDrop सर्वर द्वारा उपयोग किए जाने वाला ऑपरेटिंग सिस्टम बहुत पुरानी हो चुकी है। सुरक्षित रहने के लिए मैन्युअल अपडेट की तत्काल आवश्यकता है - और जानें" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "गंभीर सिक्यूरिटी समस्या:आपके SecureDrop सर्वर द्वारा उपयोग किए जाने वाला ऑपरेटिंग सिस्टम बहुत पुरानी हो चुकी है। सुरक्षित रहने के लिए मैन्युअल अपडेट की तत्काल आवश्यकता है - और जानें" - msgid "Logged on as" msgstr "जैसे लॉग ऑन" @@ -992,6 +978,20 @@ msgstr "महत्वपूर्ण: यदि आप गु msgid "Back to submission page" msgstr "सबमिशन पृष्ठ पर वापस जाएं" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "कम से कम {num} वर्ण लंबा होना चाहिए।" +#~ msgstr[1] "कम से कम {num} अक्षर लंबा होनी चाहिए।" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "गंभीर सिक्यूरिटी समस्या:आपके SecureDrop सर्वर द्वारा उपयोग किए जाने वाला ऑपरेटिंग सिस्टम बहुत पुरानी हो चुकी है। सुरक्षित रहने के लिए मैन्युअल अपडेट की तत्काल आवश्यकता है - और जानें" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "गंभीर सिक्यूरिटी समस्या:आपके SecureDrop सर्वर द्वारा उपयोग किए जाने वाला ऑपरेटिंग सिस्टम बहुत पुरानी हो चुकी है। सुरक्षित रहने के लिए मैन्युअल अपडेट की तत्काल आवश्यकता है - और जानें" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "चेतावनी:  आप Tor2Web का उपयोग करते हुए दिखाई देते हैं| ये गुमनामी सुनिश्चित  नहीं   करता| यह घातक क्यों है?" diff --git a/securedrop/translations/is/LC_MESSAGES/messages.po b/securedrop/translations/is/LC_MESSAGES/messages.po index 47037a4266..255c4899b0 100644 --- a/securedrop/translations/is/LC_MESSAGES/messages.po +++ b/securedrop/translations/is/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "Texti skilaboðanna er of langur." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Verður að vera a.m.k. {num} stafur að lengd." msgstr[1] "Verður að vera a.m.k. {num} stafa langt." @@ -131,11 +128,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "HOTP leynilyklar eru 40 stafa langir - þú hefur sett inn {num}." msgstr[1] "HOTP leynilyklar eru 40 stafa langir - þú hefur sett inn {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Verður að vera a.m.k. {num} stafur að lengd." -msgstr[1] "Verður að vera a.m.k. {num} stafa langt." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Má ekki vera meira en {num} stafur." @@ -407,12 +399,6 @@ msgstr "Nærðu ekki að skanna strikamerkið? Þú getur parað FreeOTP handvir msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Þegar þú hefur sett upp YubiKey (dulritunarlykill), settu inn 6-stafa kóðann hér fyrir neðan:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Áríðandi öryggismál:  Stýrikerfið sem notað er á SecureDrop-netþjónunum þínum er komið á enda líftíma síns. Til að gæta öryggis er nauðsynlegt að framkvæma handvirka uppfærslu sem fyrst. Hafðu samband við kerfisstjórann þinn. Kanna nánar" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Áríðandi öryggismál:  Stýrikerfið sem notað er á SecureDrop-þjónunum þínum mun enda líftíma sinn þann 30. apríl, 2021. Til að gæta öryggis er nauðsynlegt að framkvæma handvirka uppfærslu sem fyrst. Hafðu samband við kerfisstjórann þinn. Kanna nánar" - msgid "Logged on as" msgstr "Innskráður sem" @@ -992,6 +978,20 @@ msgstr "Mikilvægt: Ef þú óskar áframhaldandi nafnleyndar, msgid "Back to submission page" msgstr "Til baka á innsendingasíðuna" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Verður að vera a.m.k. {num} stafur að lengd." +#~ msgstr[1] "Verður að vera a.m.k. {num} stafa langt." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Áríðandi öryggismál:  Stýrikerfið sem notað er á SecureDrop-netþjónunum þínum er komið á enda líftíma síns. Til að gæta öryggis er nauðsynlegt að framkvæma handvirka uppfærslu sem fyrst. Hafðu samband við kerfisstjórann þinn. Kanna nánar" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Áríðandi öryggismál:  Stýrikerfið sem notað er á SecureDrop-þjónunum þínum mun enda líftíma sinn þann 30. apríl, 2021. Til að gæta öryggis er nauðsynlegt að framkvæma handvirka uppfærslu sem fyrst. Hafðu samband við kerfisstjórann þinn. Kanna nánar" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "AÐVÖRUN:  Það lítur út eins og þú sért að nota Tor2Web. Það  gefur þér ekki  nafnleysi. Hversvegna er það hættulegt?" diff --git a/securedrop/translations/it_IT/LC_MESSAGES/messages.po b/securedrop/translations/it_IT/LC_MESSAGES/messages.po index 9d41c15140..def7e80c6b 100644 --- a/securedrop/translations/it_IT/LC_MESSAGES/messages.po +++ b/securedrop/translations/it_IT/LC_MESSAGES/messages.po @@ -27,10 +27,7 @@ msgstr "" msgid "Name too long" msgstr "Testo del messaggio troppo lungo." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Deve essere lungo almeno {num} carattere." msgstr[1] "Deve essere lungo almeno {num} caratteri." @@ -135,11 +132,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "Le password HOTP sono di 40 caratteri - ne è stato inserito {num}." msgstr[1] "Le password HOTP sono di 40 caratteri - ne sono stati inseriti {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Deve essere lungo almeno {num} carattere." -msgstr[1] "Deve essere lungo almeno {num} caratteri." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Non può contenere più di {num} carattere." @@ -411,12 +403,6 @@ msgstr "Impossibile eseguire la scansione del codice a barre? È possibile accop msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Una volta configurata la tua Yubikey, inserisci il codice di 6 cifre qui sotto:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Sicurezza critica:  il sistema operativo usato dai propri server SecureDrop ha raggiunto la fine del suo ciclo di vita. È richiesto un aggiornamento manuale per abilitare nuovamente l'interfaccia per le fonti e rimanere al sicuro. Contattare il proprio amministartore. Maggiorni informazioni" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Sicurezza critica:  il sistema operativo usato dai propri server SecureDrop raggiungerà la fine del suo ciclo di vita il 30 aprile 2021. È urgentemente richiesto un aggiornamento manuale per rimanere al sicuro. Contattare il proprio amministartore. Maggiorni informazioni" - msgid "Logged on as" msgstr "Accesso eseguito come" @@ -996,6 +982,20 @@ msgstr "Importante: per rimanere anonimi non usareCritical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Sicurezza critica:  il sistema operativo usato dai propri server SecureDrop ha raggiunto la fine del suo ciclo di vita. È richiesto un aggiornamento manuale per abilitare nuovamente l'interfaccia per le fonti e rimanere al sicuro. Contattare il proprio amministartore. Maggiorni informazioni" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Sicurezza critica:  il sistema operativo usato dai propri server SecureDrop raggiungerà la fine del suo ciclo di vita il 30 aprile 2021. È urgentemente richiesto un aggiornamento manuale per rimanere al sicuro. Contattare il proprio amministartore. Maggiorni informazioni" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "ATTENZIONE: sembra che tu stia usando Tor2Web. Questo non fornisce anonimato. Perché è pericoloso?" diff --git a/securedrop/translations/messages.pot b/securedrop/translations/messages.pot index 89412790ca..a1f373f7b5 100644 --- a/securedrop/translations/messages.pot +++ b/securedrop/translations/messages.pot @@ -19,7 +19,7 @@ msgstr "" msgid "Name too long" msgstr "" -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "" msgstr[1] "" @@ -118,11 +118,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "" msgstr[1] "" -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "" -msgstr[1] "" - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "" @@ -392,12 +387,6 @@ msgstr "" msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "" - msgid "Logged on as" msgstr "" diff --git a/securedrop/translations/nb_NO/LC_MESSAGES/messages.po b/securedrop/translations/nb_NO/LC_MESSAGES/messages.po index f8dd80a4aa..870a9d1887 100644 --- a/securedrop/translations/nb_NO/LC_MESSAGES/messages.po +++ b/securedrop/translations/nb_NO/LC_MESSAGES/messages.po @@ -24,10 +24,7 @@ msgstr "" msgid "Name too long" msgstr "Meldingsteksten er for lang." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Må være minst {num} tegn langt." msgstr[1] "Må være minst {num} tegn langt." @@ -132,11 +129,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "HOTP-koden skal være 40 tegn lang – du har skrevet inn {num}." msgstr[1] "HOTP-koden skal være 40 tegn lang – du har skrevet inn {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Må være minst {num} tegn langt." -msgstr[1] "Må være minst {num} tegn langt." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Kan ikke inneholde mer enn {num} tegn." @@ -408,12 +400,6 @@ msgstr "Kan du ikke skanne strekkoden? Du kan koble FreeOTP til denne kontoen ma msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Når du har satt opp din YubiKey, skriv inn den 6 tegn lange koden nedenfor:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Sikkerhetskritisk:  Operativsystemet på tjenerne som drifter denne installasjonen av SecureDrop har nådd slutten av sin levetid. En manuell oppgradering kreves for å reaktivere kilde-nettsiden og opprettholde sikkerheten. Kontakt din administrator. Les mer" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Sikkerhetskritisk:  Operativsystemet på tjenerne som drifter denne installasjonen av SecureDrop vil nå slutten av sin levetid den 30. april 2021. En manuell oppgradering må gjøres innen kort tid for å opprettholde sikkerheten. Kontakt din administrator. Les mer" - msgid "Logged on as" msgstr "Innlogget som" @@ -993,6 +979,20 @@ msgstr "Viktig: Om du ønsker å være helt anonym, ikk msgid "Back to submission page" msgstr "Tilbake til innsendelsesside" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Må være minst {num} tegn langt." +#~ msgstr[1] "Må være minst {num} tegn langt." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Sikkerhetskritisk:  Operativsystemet på tjenerne som drifter denne installasjonen av SecureDrop har nådd slutten av sin levetid. En manuell oppgradering kreves for å reaktivere kilde-nettsiden og opprettholde sikkerheten. Kontakt din administrator. Les mer" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Sikkerhetskritisk:  Operativsystemet på tjenerne som drifter denne installasjonen av SecureDrop vil nå slutten av sin levetid den 30. april 2021. En manuell oppgradering må gjøres innen kort tid for å opprettholde sikkerheten. Kontakt din administrator. Les mer" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "ADVARSEL:  Det ser ut som du bruker Tor2Web. Dette  gir ikke  anonym kommunikasjon. Hvorfor kan dette være problematisk?" diff --git a/securedrop/translations/nl/LC_MESSAGES/messages.po b/securedrop/translations/nl/LC_MESSAGES/messages.po index 40c64f21f1..ff39cd64e5 100644 --- a/securedrop/translations/nl/LC_MESSAGES/messages.po +++ b/securedrop/translations/nl/LC_MESSAGES/messages.po @@ -24,10 +24,7 @@ msgstr "" msgid "Name too long" msgstr "Bericht is te lang." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Moet ten minste {num} teken lang zijn." msgstr[1] "Moet ten minste {num} tekens lang zijn." @@ -132,11 +129,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "HOTP-geheimen zijn 40 tekens lang - u heeft er {num} ingevoerd." msgstr[1] "HOTP-geheimen zijn 40 tekens lang - u heeft er {num} ingevoerd." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Moet ten minste {num} teken lang zijn." -msgstr[1] "Moet ten minste {num} tekens lang zijn." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Kan niet langer dan {num} teken zijn." @@ -408,12 +400,6 @@ msgstr "Lukt het niet de barcode te scannen? U kunt handmatig FreeOTP aan dit ac msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Zodra u uw YubiKey geconfigureerd heeft, voert u de zescijferige code hieronder in:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Kritiek veiligheidsprobleem:  Het besturingssysteem op uw SecureDrop servers is aan het einde van zijn levensduur. Een handmatige upgrade is vereist om de broninterface opnieuw in te schakelen en veilig te blijven. Neem contact op met uw beheerder.Meer informatie." - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Kritiek veiligheidsprobleem:  Het besturingssysteem op uw SecureDrop servers zal aan het zijn levensduur zijn op 30 april 2021. Een handmatige upgrade is dringend vereist om veilig te blijven. Gelieve uw beheerder te contacteren. Meer informatie." - msgid "Logged on as" msgstr "Aangemeld als" @@ -993,6 +979,20 @@ msgstr "Belangrijk: Als u anoniem wilt blijven, gebruik dan Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritiek veiligheidsprobleem:  Het besturingssysteem op uw SecureDrop servers is aan het einde van zijn levensduur. Een handmatige upgrade is vereist om de broninterface opnieuw in te schakelen en veilig te blijven. Neem contact op met uw beheerder.Meer informatie." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritiek veiligheidsprobleem:  Het besturingssysteem op uw SecureDrop servers zal aan het zijn levensduur zijn op 30 april 2021. Een handmatige upgrade is dringend vereist om veilig te blijven. Gelieve uw beheerder te contacteren. Meer informatie." + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "WAARSCHUWING:  Het lijkt erop dat u Tor2Web gebruikt. Tor2Web zorgt  niet  voor anonimiteit. Waarom is dit gevaarlijk?" diff --git a/securedrop/translations/pt_BR/LC_MESSAGES/messages.po b/securedrop/translations/pt_BR/LC_MESSAGES/messages.po index f845bd643e..5d0eaf8026 100644 --- a/securedrop/translations/pt_BR/LC_MESSAGES/messages.po +++ b/securedrop/translations/pt_BR/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "Mensagem de texto muito longa." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Deve conter pelo menos {num} caracteres." msgstr[1] "Deve conter pelo menos {num} caracteres." @@ -131,11 +128,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "Senhas HOTP contêm 40 caracteres. Você inseriu {num}." msgstr[1] "Senhas HOTP contêm 40 caracteres. Você inseriu {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Deve conter pelo menos {num} caracteres." -msgstr[1] "Deve conter pelo menos {num} caracteres." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Não pode conter mais do que {num} caracteres." @@ -407,12 +399,6 @@ msgstr "Não consegue escanear o código de barras? Você pode emparelhar manual msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Após configurar a sua YubiKey, insira o código de seis dígitos abaixo:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Ponto crítico de segurança:   O sistema operacional usado pelos servidores de SecureDrop não funciona mais. Uma atualização manual é necessária para habilitar a Interface da Fonte novamente e garantir a segurança. Por favor, entre em contato com a pessoa administradora. Saiba mais" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Ponto crítico de segurança:   O sistema operacional usado pelos servidores de SecureDrop não funciona mais. Uma atualização manual é urgentemente necessária para garantir a segurança. Por favor, entre em contato com a pessoa administradora. Saiba mais" - msgid "Logged on as" msgstr "Conectado(a) como" @@ -991,6 +977,20 @@ msgstr "Importante: Para manter o seu anonimato, nãoCritical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Ponto crítico de segurança:   O sistema operacional usado pelos servidores de SecureDrop não funciona mais. Uma atualização manual é necessária para habilitar a Interface da Fonte novamente e garantir a segurança. Por favor, entre em contato com a pessoa administradora. Saiba mais" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Ponto crítico de segurança:   O sistema operacional usado pelos servidores de SecureDrop não funciona mais. Uma atualização manual é urgentemente necessária para garantir a segurança. Por favor, entre em contato com a pessoa administradora. Saiba mais" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "ATENÇÃO:  Parece que você está usando o Tor2Web, o que  não  garante o seu anonimato. Por que isso é perigoso?" diff --git a/securedrop/translations/ro/LC_MESSAGES/messages.po b/securedrop/translations/ro/LC_MESSAGES/messages.po index 56a182fb6c..4389a3c4d8 100644 --- a/securedrop/translations/ro/LC_MESSAGES/messages.po +++ b/securedrop/translations/ro/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "Textul mesajului este prea lung." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Trebuie să aibă cel puțin {num} caracter." msgstr[1] "Trebuie să aibă cel puțin {num} caractere." @@ -133,12 +130,6 @@ msgstr[0] "Secretele HOTP au 40 de caractere lungime - ai introdus {num}." msgstr[1] "Secretele HOTP au 40 de caractere lungime - ai introdus {num}." msgstr[2] "Secretele HOTP au 40 de caractere lungime - ai introdus {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Trebuie să aibă cel puțin {num} caracter." -msgstr[1] "Trebuie să aibă cel puțin {num} caractere." -msgstr[2] "Trebuie să aibă cel puțin {num} de caractere." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Nu poate avea mai mult de {num} caracter." @@ -417,12 +408,6 @@ msgstr "Nu poți scana codul de bare? Poți asocia manual FreeOTP cu acest cont msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "După ce ai configurat cheia fizică YubiKey, introdu codul de 6 cifre de mai jos:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Alertă critică de securitate:  Sistemul de operare folosit de serverele SecureDrop a ajuns la sfârșitul duratei de viață. Este necesară trecerea manuală la o versiune superioară pentru reactivarea interfeței pentru surse și pentru a rămâne în siguranță. Contactează administratorul. Află mai multe" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Alertă critică de securitate: Sistemul de operare folosit de serverele SecureDrop va ajunge la sfârșitul duratei de viață la data de 30 aprilie 2021. Este necesară de urgență trecerea manuală la o versiune superioară pentru a rămâne în siguranță. Contactează administratorul. Află mai multe" - msgid "Logged on as" msgstr "Autentificat ca" @@ -1003,6 +988,21 @@ msgstr "Important: Dacă vrei să rămâi anonim(ă), n msgid "Back to submission page" msgstr "Înapoi la pagina de trimitere" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Trebuie să aibă cel puțin {num} caracter." +#~ msgstr[1] "Trebuie să aibă cel puțin {num} caractere." +#~ msgstr[2] "Trebuie să aibă cel puțin {num} de caractere." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Alertă critică de securitate:  Sistemul de operare folosit de serverele SecureDrop a ajuns la sfârșitul duratei de viață. Este necesară trecerea manuală la o versiune superioară pentru reactivarea interfeței pentru surse și pentru a rămâne în siguranță. Contactează administratorul. Află mai multe" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Alertă critică de securitate: Sistemul de operare folosit de serverele SecureDrop va ajunge la sfârșitul duratei de viață la data de 30 aprilie 2021. Este necesară de urgență trecerea manuală la o versiune superioară pentru a rămâne în siguranță. Contactează administratorul. Află mai multe" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "AVERTISMENT:  Se pare că folosești Tor2Web. Acest serviciu  nu oferă  anonimitate. De ce este periculos?" diff --git a/securedrop/translations/ru/LC_MESSAGES/messages.po b/securedrop/translations/ru/LC_MESSAGES/messages.po index ee0c8ed115..a838dbac8f 100644 --- a/securedrop/translations/ru/LC_MESSAGES/messages.po +++ b/securedrop/translations/ru/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "Текст сообщения слишком длинный." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Должно быть не менее {num} символ." msgstr[1] "Должно быть не менее {num} символа." @@ -133,12 +130,6 @@ msgstr[0] "Секреты HOTP должны содержать 40 символо msgstr[1] "Секреты HOTP должны содержать 40 символов. Вы ввели {num}." msgstr[2] "Секреты HOTP должны содержать 40 символов. Вы ввели {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Должно быть не менее {num} символ." -msgstr[1] "Должно быть не менее {num} символа." -msgstr[2] "Должно быть не менее {num} символов." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Длина не может превышать {num} символ." @@ -417,12 +408,6 @@ msgstr "Не получается считать штрихкод? Вы може msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "После того, как вы настроили ваш YubiKey, введите 6-значный код ниже:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Критическое предупреждение:   Операционная система которая использовалась серверами SecureDrop отслужила своё. Для безопасного сохранения данных требуется срочное ручное обновление - Подробнее" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Критическое предупреждение:   Операционная система которая использовалась серверами SecureDrop отслужила своё и её срок истекает 30го апреля, 2021. Для безопасного сохранения данных требуется срочное ручное обновление, пожалуйста свяжитесь с администратором.- Подробнее" - msgid "Logged on as" msgstr "Вы вошли как" @@ -1003,6 +988,21 @@ msgstr "Внимание: Если вы хотите сохра msgid "Back to submission page" msgstr "Вернуться на страницу отправки" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Должно быть не менее {num} символ." +#~ msgstr[1] "Должно быть не менее {num} символа." +#~ msgstr[2] "Должно быть не менее {num} символов." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Критическое предупреждение:   Операционная система которая использовалась серверами SecureDrop отслужила своё. Для безопасного сохранения данных требуется срочное ручное обновление - Подробнее" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Критическое предупреждение:   Операционная система которая использовалась серверами SecureDrop отслужила своё и её срок истекает 30го апреля, 2021. Для безопасного сохранения данных требуется срочное ручное обновление, пожалуйста свяжитесь с администратором.- Подробнее" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "ВНИМАНИЕ:  Кажется, вы используете Tor2Web. Это  не обеспечивает  анонимность. Почему это опасно?" diff --git a/securedrop/translations/sk/LC_MESSAGES/messages.po b/securedrop/translations/sk/LC_MESSAGES/messages.po index 6f45d8de0c..d4d080548b 100644 --- a/securedrop/translations/sk/LC_MESSAGES/messages.po +++ b/securedrop/translations/sk/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "Správa je príliš dlhá." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Musí byť aspoň {num} znak dlhé." msgstr[1] "Musí byť aspoň {num} znaky dlhé." @@ -133,12 +130,6 @@ msgstr[0] "HOTP heslá sú 40 znakov dlhé - zadali ste {num} znak." msgstr[1] "HOTP heslá sú 40 znakov dlhé - zadali ste {num} znaky." msgstr[2] "HOTP heslá sú 40 znakov dlhé - zadali ste {num} znakov." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Musí byť aspoň {num} znak dlhé." -msgstr[1] "Musí byť aspoň {num} znaky dlhé." -msgstr[2] "Musí byť aspoň {num} znakov dlhé." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Nesmie byť dlhšie ako {num} znak." @@ -417,12 +408,6 @@ msgstr "Nemôžete nasnímať čiarový kód? Môžete manuálne spárovať Free msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "Akonáhle nastavíte svoj YubiKey, zadajte šesťmiestny kód nižšie:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Kritické bezpečnostné riziko:  Operačný systém vašich SecureDrop serverov dosiahol koniec životnosti (EoL). Pre opätovné spustenie rozhrania pre zdroje je vyžadovaná manuálna aktualizácia. Kontaktujte prosím svojho administrátora. Viac informácií" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Kritické bezpečnostné riziko:   30. apríla končí operačnému systému vašich SecureDrop serverov životnosť (EoL). Kontaktujte prosím svojho administrátora. Pre ďalšie zabezpečenie je vyžadovaná aktualizácia.Viac informácií" - msgid "Logged on as" msgstr "Ste prihlásení ako" @@ -1003,6 +988,21 @@ msgstr "Dôležité: Ak chcete zostať v anonymite, nep msgid "Back to submission page" msgstr "Späť na stránku podania" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Musí byť aspoň {num} znak dlhé." +#~ msgstr[1] "Musí byť aspoň {num} znaky dlhé." +#~ msgstr[2] "Musí byť aspoň {num} znakov dlhé." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritické bezpečnostné riziko:  Operačný systém vašich SecureDrop serverov dosiahol koniec životnosti (EoL). Pre opätovné spustenie rozhrania pre zdroje je vyžadovaná manuálna aktualizácia. Kontaktujte prosím svojho administrátora. Viac informácií" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritické bezpečnostné riziko:   30. apríla končí operačnému systému vašich SecureDrop serverov životnosť (EoL). Kontaktujte prosím svojho administrátora. Pre ďalšie zabezpečenie je vyžadovaná aktualizácia.Viac informácií" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "VAROVANIE:  Zdá sa, že používate Tor2Web. Toto  neposkytuje  anonymitu. Prečo je to nebezpečné?" diff --git a/securedrop/translations/sv/LC_MESSAGES/messages.po b/securedrop/translations/sv/LC_MESSAGES/messages.po index 76389619ec..4dfa3ca517 100644 --- a/securedrop/translations/sv/LC_MESSAGES/messages.po +++ b/securedrop/translations/sv/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "Meddelandet är för långt." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "Måste vara minst {num} tecken långt." msgstr[1] "Måste vara minst {num} tecken långt." @@ -131,11 +128,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "HOTP-hemligheter är 40 tecken långa - du har fyllt i {num}." msgstr[1] "HOTP-hemligheter är 40 tecken långa - du har fyllt i {num}." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "Måste vara minst {num} tecken långt." -msgstr[1] "Måste vara minst {num} tecken långt." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "Kan inte vara längre än {num} tecken." @@ -407,12 +399,6 @@ msgstr "Kan du inte skanna koden? Du kan manuellt koppla FreeOTP till detta kont msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "När du har konfigurerat din Yubikey, ange den sexsiffriga koden nedan:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Kritisk sårbarhet:  Operativsystemet som används av dina SecureDrop-servrar har passerat sin livslängd. En manuell uppdatering krävs snarast för att återaktivera källgränssnittet och för att fortsätta vara säker. Vänligen kontakta din administratör. Läs mer" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Kritisk sårbarhet: Operativsystemet som används av dina SecureDrop-servrar kommer passera sin livslängd 30 April 2021. En manuell uppdatering krävs snarast för att skydda systemet. Vänligen kontakta din administratör. Läs mer" - msgid "Logged on as" msgstr "Inloggad som" @@ -992,6 +978,20 @@ msgstr " Viktigt: Ifall du önskar att förbli anonym, msgid "Back to submission page" msgstr "Tillbaka till inlämningssidan" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "Måste vara minst {num} tecken långt." +#~ msgstr[1] "Måste vara minst {num} tecken långt." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritisk sårbarhet:  Operativsystemet som används av dina SecureDrop-servrar har passerat sin livslängd. En manuell uppdatering krävs snarast för att återaktivera källgränssnittet och för att fortsätta vara säker. Vänligen kontakta din administratör. Läs mer" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritisk sårbarhet: Operativsystemet som används av dina SecureDrop-servrar kommer passera sin livslängd 30 April 2021. En manuell uppdatering krävs snarast för att skydda systemet. Vänligen kontakta din administratör. Läs mer" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "VARNING: Du verkar använda Tor2Web. Det gör dig   inte  anonym. Varför är det farligt?" diff --git a/securedrop/translations/tr/LC_MESSAGES/messages.po b/securedrop/translations/tr/LC_MESSAGES/messages.po index 3967728d12..35332b04ab 100644 --- a/securedrop/translations/tr/LC_MESSAGES/messages.po +++ b/securedrop/translations/tr/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "İleti metni çok uzun." -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "{num} karakterden az olamaz." msgstr[1] "{num} karakterden az olamaz." @@ -131,11 +128,6 @@ msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "HOTP parolaları 40 karakter uzunluğundadır - sadece {num} karakter yazdınız." msgstr[1] "HOTP parolaları 40 karakter uzunluğundadır - sadece {num} karakter yazdınız." -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "{num} karakterden az olamaz." -msgstr[1] "{num} karakterden az olamaz." - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "{num} karakterden fazla olamaz." @@ -407,12 +399,6 @@ msgstr "Barkodu okutamıyor musunuz? Şu iki aşamalı kimlik doğrulama parolas msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "YubiKey yapılandırmasını tamamladığınızda, aşağıdaki 6 haneli kodu yazın:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "Kritik Güvenlik:  SecureDrop sunucularınız tarafından kullanılan işletim sisteminizin ömrü sona erdi. Kaynak arayüzünü yeniden etkinleştirmek ve güvende kalmak için elle bir güncelleme yapmanız gerekiyor. Lütfen BT yöneticiniz ile görüşün. Ayrıntılı Bilgi Alın" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "Kritik Güvenlik:  SecureDrop sunucularınızda kullanılan işletim sisteminin kullanım ömrü 30 Nisan 2021'de sona eriyor. Güvende kalmak için el ile bir güncelleme yapmanız gerekiyor. Lütfen BT yöneticiniz ile görüşün. Ayrıntılı Bilgi Alın" - msgid "Logged on as" msgstr "Oturum açan" @@ -992,6 +978,20 @@ msgstr "Önemli: Anonim kalmak istiyorsanız, dosyanın GPG tar msgid "Back to submission page" msgstr "Gönderi sayfasına geri dön" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "{num} karakterden az olamaz." +#~ msgstr[1] "{num} karakterden az olamaz." + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritik Güvenlik:  SecureDrop sunucularınız tarafından kullanılan işletim sisteminizin ömrü sona erdi. Kaynak arayüzünü yeniden etkinleştirmek ve güvende kalmak için elle bir güncelleme yapmanız gerekiyor. Lütfen BT yöneticiniz ile görüşün. Ayrıntılı Bilgi Alın" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "Kritik Güvenlik:  SecureDrop sunucularınızda kullanılan işletim sisteminin kullanım ömrü 30 Nisan 2021'de sona eriyor. Güvende kalmak için el ile bir güncelleme yapmanız gerekiyor. Lütfen BT yöneticiniz ile görüşün. Ayrıntılı Bilgi Alın" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "UYARI:  Tor2Web kullanıyor gibi gözüküyorsunuz. Bu size anonimlik  sağlamaz . Bu neden tehlikeli?" diff --git a/securedrop/translations/zh_Hans/LC_MESSAGES/messages.po b/securedrop/translations/zh_Hans/LC_MESSAGES/messages.po index 1814a2bdfa..b92b10cc3d 100644 --- a/securedrop/translations/zh_Hans/LC_MESSAGES/messages.po +++ b/securedrop/translations/zh_Hans/LC_MESSAGES/messages.po @@ -23,10 +23,7 @@ msgstr "" msgid "Name too long" msgstr "消息文本太长。" -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "该字段需要至少 {num} 个字符。" @@ -129,10 +126,6 @@ msgid "HOTP secrets are 40 characters long - you have entered {num}." msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "HOTP 密码长度为40个字符 - 您已输入 {num} 个字符。" -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "该字段需要至少 {num} 个字符。" - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "字段长度需小于 {num} 个字符。" @@ -397,12 +390,6 @@ msgstr "无法扫描二维码?您可手动输入下列两步验证密钥以将 msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "当你配置好 YubiKey 后,输入下面的 6 位口令:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "安全隐患:您使用的操作系统已经达到了使用年限,请您手动更新来重新启用线人界面。请联系你的管理员。进一步了解" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "安全隐患:您使用的操作系统将在2021年4月30日达到使用年限。请您手动更新来保证安全。请联系你的管理员。进一步了解" - msgid "Logged on as" msgstr "以身份登录" @@ -981,6 +968,19 @@ msgstr "重要提示:若您想保持匿名身份, msgid "Back to submission page" msgstr "返回提交页面" +#, fuzzy +#~| msgid "Must be at least {num} character long." +#~| msgid_plural "Must be at least {num} characters long." +#~ msgid "Must be at least one character long." +#~ msgid_plural "Must be at least {num} characters long." +#~ msgstr[0] "该字段需要至少 {num} 个字符。" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "安全隐患:您使用的操作系统已经达到了使用年限,请您手动更新来重新启用线人界面。请联系你的管理员。进一步了解" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "安全隐患:您使用的操作系统将在2021年4月30日达到使用年限。请您手动更新来保证安全。请联系你的管理员。进一步了解" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr "警告:  您似乎正使用 Tor2Web。此服务 无法 隐藏您的行踪。为何存在风险?" diff --git a/securedrop/translations/zh_Hant/LC_MESSAGES/messages.po b/securedrop/translations/zh_Hant/LC_MESSAGES/messages.po index 77c621e2b6..f64cdf2cbc 100644 --- a/securedrop/translations/zh_Hant/LC_MESSAGES/messages.po +++ b/securedrop/translations/zh_Hant/LC_MESSAGES/messages.po @@ -24,10 +24,7 @@ msgstr "" msgid "Name too long" msgstr "訊息文字過長。" -#, fuzzy -#| msgid "Must be at least {num} character long." -#| msgid_plural "Must be at least {num} characters long." -msgid "Must be at least one character long." +msgid "Must be at least {num} character long." msgid_plural "Must be at least {num} characters long." msgstr[0] "须至少有 {num} 個字符長度。" @@ -130,10 +127,6 @@ msgid "HOTP secrets are 40 characters long - you have entered {num}." msgid_plural "HOTP secrets are 40 characters long - you have entered {num}." msgstr[0] "HOTP secrets 需為 40 個字符長,已輸入 {num} 個字符。" -msgid "Must be at least {num} character long." -msgid_plural "Must be at least {num} characters long." -msgstr[0] "须至少有 {num} 個字符長度。" - msgid "Cannot be longer than {num} character." msgid_plural "Cannot be longer than {num} characters." msgstr[0] "不可多於 {num} 字元。" @@ -398,12 +391,6 @@ msgstr "無法掃描條碼?您可以輸入以下雙重驗證密鑰以便手動 msgid "Once you have configured your YubiKey, enter the 6-digit code below:" msgstr "設定 Yubikey 後,請在下面輸入 6 位數字代碼:" -msgid "Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" -msgstr "重要安全課題:   SecureDrop 伺服器作業系統已逾使用年限,亟需手動更新才能啟用線人界面與維持安全。請聯絡網管人員 - 了解進一步資訊" - -msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" -msgstr "重要安全課題:   SecureDrop 伺服器作業系統將在月30日超過使用年限,亟需手動更新以維持安全。 請聯絡網管人員 了解詳情" - msgid "Logged on as" msgstr "登入為" @@ -982,6 +969,19 @@ msgstr "重要:如果您希望保持匿名,請勿Critical Security:  The operating system used by your SecureDrop servers has reached its end-of-life. A manual upgrade is required to re-enable the Source Interface and remain safe. Please contact your administrator. Learn More" +#~ msgstr "重要安全課題:   SecureDrop 伺服器作業系統已逾使用年限,亟需手動更新才能啟用線人界面與維持安全。請聯絡網管人員 - 了解進一步資訊" + +#~ msgid "Critical Security:  The operating system used by your SecureDrop servers will reach its end-of-life on April 30, 2021. A manual upgrade is urgently required to remain safe. Please contact your administrator. Learn More" +#~ msgstr "重要安全課題:   SecureDrop 伺服器作業系統將在月30日超過使用年限,亟需手動更新以維持安全。 請聯絡網管人員 了解詳情" + #~ msgid "WARNING:  You appear to be using Tor2Web. This  does not  provide anonymity. Why is this dangerous?" #~ msgstr " 警告:  看來你正在使用 Tor2Web。 它  不能  提供匿名功能 這樣為什麼有危險?"