Package: guix-patches;
Reported by: Richard Sent <richard <at> freakingpenguin.com>
Date: Tue, 18 Jun 2024 22:08:02 UTC
Severity: normal
Tags: patch
Message #29 received at 71639 <at> debbugs.gnu.org (full text, mbox):
From: Richard Sent <richard <at> freakingpenguin.com> To: guix-patches <at> gnu.org, 71639 <at> debbugs.gnu.org Cc: Richard Sent <richard <at> freakingpenguin.com> Subject: [PATCH v2 2/5] services: backup: Add password-command support to restic-service Date: Wed, 19 Jun 2024 23:44:13 -0400
* gnu/services/backup.scm (restic-backup-job): Add password-command. (verify-restic-backup-job-configuration): Create. (restic-backup-job-program): Set either RESTIC_PASSWORD or RESTIC_PASSWORD_COMMAND depending on what is configured. * doc/guix.texi (Miscellaneous Services): Document it. Change-Id: Ice9cf85d1ee4485a2737f515c63c969918219df0 --- doc/guix.texi | 7 +++++++ gnu/services/backup.scm | 41 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 63c9cbd1a7..f22d679023 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -41344,6 +41344,13 @@ Miscellaneous Services that will be used to set the @env{RESTIC_PASSWORD} environment variable for the current job. +@item @code{password-command} (type: file-like) +String path or file-like object representing the executable file that +prints password to stdout. If a file-like object is used, it is placed +in the store globally executable and in plain text. The executable +should be designed such that it does not compromise the password if an +unauthorized user runs it. + @item @code{schedule} (type: gexp-or-string) A string or a gexp that will be passed as time specification in the mcron job specification (@pxref{Syntax, mcron job specifications,, diff --git a/gnu/services/backup.scm b/gnu/services/backup.scm index 1279ece88f..fd904bc9a9 100644 --- a/gnu/services/backup.scm +++ b/gnu/services/backup.scm @@ -66,6 +66,9 @@ (define (lowerable? value) (define list-of-lowerables? (list-of lowerable?)) +(define-maybe/no-serialization string) +(define-maybe/no-serialization file-like) + (define-configuration/no-serialization restic-backup-job (restic (package restic) @@ -80,10 +83,16 @@ (define-configuration/no-serialization restic-backup-job (string) "The restic repository target of this job.") (password-file - (string) + (maybe-string) "Name of the password file, readable by the configured @code{user}, that will be used to set the @code{RESTIC_PASSWORD} environment variable for the current job.") + (password-command + (maybe-file-like) + "An executable file who's path is stored in @code{RESTIC_PASSWORD_COMMAND}. +When run, the file writes the password to standard output. Due to the nature +of the store this command will be globally executable and should have external +protections to ensure unauthorized users cannot retrieve the password.") (schedule (gexp-or-string) "A string or a gexp that will be passed as time specification in the mcron @@ -104,6 +113,14 @@ (define-configuration/no-serialization restic-backup-job "A list of values that are lowered to strings. These will be passed as command-line arguments to the current job @command{restic backup} invokation.")) +(define (verify-restic-backup-job-configuration config) + (unless (or (maybe-value-set? (restic-backup-job-password-file config)) + (maybe-value-set? (restic-backup-job-password-command config))) + (error "either password-file or password-command must be configured.")) + (when (and (maybe-value-set? (restic-backup-job-password-file config)) + (maybe-value-set? (restic-backup-job-password-command config))) + (error "password-file and password-command can not be configured simultaneously."))) + (define list-of-restic-backup-jobs? (list-of restic-backup-job?)) @@ -113,12 +130,21 @@ (define-configuration/no-serialization restic-backup-configuration "The list of backup jobs for the current system.")) (define (restic-backup-job-program config) + (define (maybe-value-or-false maybe) + (if (maybe-value-set? maybe) + maybe + #f)) + + (verify-restic-backup-job-configuration config) + (let ((restic (file-append (restic-backup-job-restic config) "/bin/restic")) (repository (restic-backup-job-repository config)) (password-file - (restic-backup-job-password-file config)) + (maybe-value-or-false (restic-backup-job-password-file config))) + (password-command + (maybe-value-or-false (restic-backup-job-password-command config))) (files (restic-backup-job-files config)) (extra-flags @@ -134,9 +160,14 @@ (define (restic-backup-job-program config) #~(begin (use-modules (ice-9 popen) (ice-9 rdelim)) - (setenv "RESTIC_PASSWORD" - (with-input-from-file #$password-file read-line)) - + (or (and=> #$password-file (lambda (x) + (setenv "RESTIC_PASSWORD" + (with-input-from-file x read-line)))) + (and=> #$password-command (lambda (x) + (setenv "RESTIC_PASSWORD_COMMAND" x))) + ;; Have a backup error message in case + ;; verify-restic-backup-job-configuration is messed with + (error "Neither password-file or password-command set")) (when #$init? ;; Use cat config to check if the repository exists. See ;; https://github.com/restic/restic/issues/1690 and -- 2.45.1
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.