aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2022 muradm <mail@muradm.net>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu tests security)
  #:use-module (guix gexp)
  #:use-module (gnu packages admin)
  #:use-module (gnu services)
  #:use-module (gnu services base)
  #:use-module (gnu services security)
  #:use-module (gnu services ssh)
  #:use-module (gnu system)
  #:use-module (gnu system vm)
  #:use-module (gnu tests)
  #:export (%test-fail2ban-basic
            %test-fail2ban-extension
            %test-fail2ban-simple))


;;;
;;; fail2ban tests
;;;

(define-syntax-rule (fail2ban-test test-name test-os tests-more ...)
  (lambda ()
    (define os
      (marionette-operating-system
       test-os
       #:imported-modules '((gnu services herd))))

    (define vm
      (virtual-machine
       (operating-system os)
       (port-forwardings '())))

    (define test
      (with-imported-modules '((gnu build marionette)
                               (guix build utils))
        #~(begin
            (use-modules (srfi srfi-64)
                         (gnu build marionette))

            (define marionette (make-marionette (list #$vm)))

            (test-runner-current (system-test-runner #$output))
            (test-begin test-name)

            (test-assert "fail2ban running"
              (marionette-eval
               '(begin
                  (use-modules (gnu services herd))
                  (start-service 'fail2ban))
               marionette))

            (test-assert "fail2ban socket ready"
              (wait-for-unix-socket
               "/var/run/fail2ban/fail2ban.sock" marionette))

            (test-assert "fail2ban running after restart"
              (marionette-eval
               '(begin
                  (use-modules (gnu services herd))
                  (restart-service 'fail2ban))
               marionette))

            (test-assert "fail2ban socket ready after restart"
              (wait-for-unix-socket
               "/var/run/fail2ban/fail2ban.sock" marionette))

            (test-assert "fail2ban pid ready"
              (marionette-eval
               '(file-exists? "/var/run/fail2ban/fail2ban.pid")
               marionette))

            (test-assert "fail2ban log file"
              (marionette-eval
               '(file-exists? "/var/log/fail2ban.log")
               marionette))

            tests-more ...

            (test-end))))

    (gexp->derivation test-name test)))

(define run-fail2ban-basic-test
  (fail2ban-test
   "fail2ban-basic-test"

   (simple-operating-system
    (service fail2ban-service-type))))

(define %test-fail2ban-basic
  (system-test
   (name "fail2ban-basic")
   (description "Test basic fail2ban running capability.")
   (value (run-fail2ban-basic-test))))

(define %fail2ban-server-cmd
  (program-file
   "fail2ban-server-cmd"
   #~(begin
       (let ((cmd #$(file-append fail2ban "/bin/fail2ban-server")))
         (apply execl cmd cmd `("-p" "/var/run/fail2ban/fail2ban.pid"
                                "-s" "/var/run/fail2ban/fail2ban.sock"
                                ,@(cdr (program-arguments))))))))

(define run-fail2ban-simple-test
  (fail2ban-test
   "fail2ban-basic-test"

   (simple-operating-system
    (service fail2ban-service-type (fail2ban-configuration
                                    (jails (list (fail2ban-jail-configuration
                                                  (name "sshd")))))))

   (test-equal "fail2ban sshd jail running status output"
     '("Status for the jail: sshd"
       "|- Filter"
       "|  |- Currently failed:\t0"
       "|  |- Total failed:\t0"
       "|  `- File list:\t/var/log/secure"
       "`- Actions"
       "   |- Currently banned:\t0"
       "   |- Total banned:\t0"
       "   `- Banned IP list:\t"
       "")
     (marionette-eval
      '(begin
         (use-modules (ice-9 rdelim) (ice-9 popen) (rnrs io ports))
         (let ((call-command
                (lambda (cmd)
                  (let* ((err-cons (pipe))
                         (port (with-error-to-port (cdr err-cons)
                                 (lambda () (open-input-pipe cmd))))
                         (_ (setvbuf (car err-cons) 'block
                                     (* 1024 1024 16)))
                         (result (read-delimited "" port)))
                    (close-port (cdr err-cons))
                    (values result (read-delimited "" (car err-cons)))))))
           (string-split
            (call-command
             (string-join (list #$%fail2ban-server-cmd "status" "sshd") " "))
            #\newline)))
      marionette))

   (test-equal "fail2ban sshd jail running exit code"
     0
     (marionette-eval
      '(status:exit-val (system* #$%fail2ban-server-cmd "status" "sshd"))
      marionette))))

(define %test-fail2ban-simple
  (system-test
   (name "fail2ban-simple")
   (description "Test simple fail2ban running capability.")
   (value (run-fail2ban-simple-test))))

(define run-fail2ban-extension-test
  (fail2ban-test
   "fail2ban-extension-test"

   (simple-operating-system
    (service (fail2ban-jail-service openssh-service-type (fail2ban-jail-configuration
                                                          (name "sshd") (enabled? #t)))
             (openssh-configuration))
    (service static-networking-service-type
             (list %qemu-static-networking)))

   (test-equal "fail2ban sshd jail running status output"
     '("Status for the jail: sshd"
       "|- Filter"
       "|  |- Currently failed:\t0"
       "|  |- Total failed:\t0"
       "|  `- File list:\t/var/log/secure"
       "`- Actions"
       "   |- Currently banned:\t0"
       "   |- Total banned:\t0"
       "   `- Banned IP list:\t"
       "")
     (marionette-eval
      '(begin
         (use-modules (ice-9 rdelim) (ice-9 popen) (rnrs io ports))
         (let ((call-command
                (lambda (cmd)
                  (let* ((err-cons (pipe))
                         (port (with-error-to-port (cdr err-cons)
                                 (lambda () (open-input-pipe cmd))))
                         (_ (setvbuf (car err-cons) 'block
                                     (* 1024 1024 16)))
                         (result (read-delimited "" port)))
                    (close-port (cdr err-cons))
                    (values result (read-delimited "" (car err-cons)))))))
           (string-split
            (call-command
             (string-join (list #$%fail2ban-server-cmd "status" "sshd") " "))
            #\newline)))
      marionette))

   (test-equal "fail2ban sshd jail running exit code"
     0
     (marionette-eval
      '(status:exit-val (system* #$%fail2ban-server-cmd "status" "sshd"))
      marionette))))

(define %test-fail2ban-extension
  (system-test
   (name "fail2ban-extension")
   (description "Test extension fail2ban running capability.")
   (value (run-fail2ban-extension-test))))
t accordingly. * tests/packages.scm ("package-source-derivation, origin, sha512"): New test. * guix/tests.scm: Hide (gcrypt hash) 'sha256' for proper syntax matching. * tests/challenge.scm: Add #:prefix for (gcrypt hash) and adjust users. * tests/derivations.scm: Likewise. * tests/store.scm: Likewise. * tests/graph.scm ("bag DAG, including origins"): Provide 'sha256' field with the right length. * gnu/packages/aspell.scm (aspell-dictionary) (aspell-dict-ca, aspell-dict-it): Use 'hash' and 'content-hash' for proper syntax matching. * gnu/packages/bash.scm (bash-patch): Rename 'sha256' to 'sha256-bv'. * gnu/packages/bootstrap.scm (bootstrap-executable): Rename 'sha256' to 'bv'. * gnu/packages/readline.scm (readline-patch): Likewise. * gnu/packages/virtualization.scm (qemu-patch): Rename 'sha256' to 'sha256-bv'. * guix/import/utils.scm: Hide (gcrypt hash) 'sha256'. Ludovic Courtès 2020-05-22tests: Test 'add-to-store' with several hash algorithms....* tests/store.scm ("add-to-store"): New test. Ludovic Courtès 2020-05-14store: 'mapm/accumulate-builds' preserves '%current-target-system'....Fixes <https://bugs.gnu.org/41182>. * guix/store.scm (mapm/accumulate-builds): Pass #:system and #:target to 'run-with-store'. * tests/store.scm ("mapm/accumulate-builds, %current-target-system"): New test. * tests/guix-pack.sh: Add 'guix pack -d --target' test. Ludovic Courtès 2020-04-04store: 'with-store' doesn't close the store upon abort....Fixes <https://bugs.gnu.org/40428>. Reported by Marius Bakke <mbakke@fastmail.com> and 白い熊. Regression introduced with the first uses of 'with-build-handler' in commit 62195b9a8fd6846117c5d7698842748300d13e31 and subsequent. * guix/store.scm (call-with-store): Use 'catch #t' instead of 'dynamic-wind'. This ensures STORE remains open when a non-local exit other than an exception occurs, such as an abort to the build handler prompt. * tests/store.scm ("with-build-handler + with-store"): New test. Ludovic Courtès 2020-03-29store: Add 'map/accumulate-builds'....* guix/store.scm (<unresolved>): New record type. (build-accumulator, map/accumulate-builds, mapm/accumulate-builds): New procedures. * tests/store.scm ("map/accumulate-builds", "mapm/accumulate-builds"): New tests. Ludovic Courtès 2020-03-22store: Add 'with-build-handler'....* guix/store.scm (current-build-prompt): New variable. (call-with-build-handler, invoke-build-handler): New procedures. (with-build-handler): New macro. * tests/store.scm ("with-build-handler"): New test. Ludovic Courtès 2019-10-16daemon: Make 'profiles/per-user' non-world-writable....Fixes <https://bugs.gnu.org/37744>. Reported at <https://www.openwall.com/lists/oss-security/2019/10/09/4>. Based on Nix commit 5a303093dcae1e5ce9212616ef18f2ca51020b0d by Eelco Dolstra <edolstra@gmail.com>. * nix/libstore/local-store.cc (LocalStore::LocalStore): Set 'perUserDir' to #o755 instead of #o1777. (LocalStore::createUser): New function. * nix/libstore/local-store.hh (LocalStore): Add it. * nix/libstore/store-api.hh (StoreAPI): Add it. * nix/nix-daemon/nix-daemon.cc (performOp): In 'wopSetOptions', add condition to handle "user-name" property and honor it. (processConnection): Add 'userId' parameter. Call 'store->createUser' when userId is not -1. * guix/profiles.scm (ensure-profile-directory): Note that this is now handled by the daemon. * guix/store.scm (current-user-name): New procedure. (set-build-options): Add #:user-name parameter and pass it to the daemon. * tests/guix-daemon.sh: Test the creation of 'profiles/per-user' when listening on a TCP socket. * tests/store.scm ("profiles/per-user exists and is not writable") ("profiles/per-user/$USER exists"): New tests. Ludovic Courtès 2019-06-10store: 'build-things' accepts derivation/output pairs....This allows callers to request the substitution of a single derivation output. * guix/store.scm (build-things): Accept derivation/output pairs among THINGS. * guix/derivations.scm (build-derivations): Likewise. * tests/store.scm ("substitute + build-things with specific output"): New test. * tests/derivations.scm ("build-derivations with specific output"): New test. * doc/guix.texi (The Store): Adjust accordingly. Ludovic Courtès 2019-02-06daemon: Emit a 'build-succeeded' event in check mode....Until now, something like "guix build sed -v1 --check" would not get a 'build-succeeded' event, which in turn meant that the spinner would not be erased upon build completion. * nix/libstore/build.cc (DerivationGoal::registerOutputs): When 'buildMode' is bmCheck and 'settings.printBuildTrace' emit a "@ build-succeeded" trace upon success. * tests/store.scm ("build-succeeded trace in check mode"): New test. Ludovic Courtès 2019-01-21store: Rename '&nix-error' to '&store-error'....* guix/store.scm (&nix-error): Rename to... (&store-error): ... this, and adjust users. (&nix-connection-error): Rename to... (&store-connection-error): ... this, and adjust users. (&nix-protocol-error): Rename to... (&store-protocol-error): ... this, adjust users. (&nix-error, &nix-connection-error, &nix-protocol-error): Define these condition types and their getters as deprecrated aliases. * build-aux/run-system-tests.scm, guix/derivations.scm, guix/grafts.scm, guix/scripts/challenge.scm, guix/scripts/graph.scm, guix/scripts/lint.scm, guix/scripts/offload.scm, guix/serialization.scm, guix/ssh.scm, guix/tests.scm, guix/ui.scm, tests/derivations.scm, tests/gexp.scm, tests/guix-daemon.sh, tests/packages.scm, tests/store.scm, doc/guix.texi: Adjust to use the new names. Ludovic Courtès 2019-01-09maint: Remove 'cond-expand' forms for Guile 2.0....Note: Leave 'cond-expand' forms used in the build-side modules that can run on %BOOTSTRAP-GUILE, which is currently Guile 2.0. * guix/build/compile.scm: Move 'use-modules' clause from 'cond-expand' to 'define-module' form. (%default-optimizations): Remove 'cond-expand'. * guix/build/download.scm (tls-wrap): Remove 'cond-expand'. * guix/build/syscalls.scm: Remove 'cond-expand' form around '%set-automatic-finalization-enabled?!' and 'without-automatic-finalization'. * guix/inferior.scm (port->inferior): Remove 'cond-expand'. * guix/scripts/pack.scm (wrapped-package)[build]: Remove 'cond-expand'. * guix/status.scm (build-event-output-port): Remove 'cond-expand'. * guix/store.scm (open-inet-socket): Remove 'cond-expand'. * guix/ui.scm (install-locale): Remove 'cond-expand'. * tests/status.scm ("current-build-output-port, UTF-8 + garbage"): Remove 'cond-expand'. * tests/store.scm ("current-build-output-port, UTF-8 + garbage"): Remove 'cond-expand'. Ludovic Courtès