summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorTomas Volf <wolf@wolfsden.cz>2024-01-11 18:35:39 +0100
committerLudovic Courtès <ludo@gnu.org>2024-01-14 23:00:03 +0100
commitd082312ef7adfea69c79d30ef947817b39832161 (patch)
treed588cc3cda334c2c08cf08fe311255a5aa56841b /gnu
parentdb43edaa0a7eaa0064224b31fbce07469ebeb93e (diff)
mapped-devices: Allow unlocking by a key file.
Requiring the user to input their password in order to unlock a device is not always reasonable, so having an option to unlock the device using a key file is a nice quality of life change. * gnu/system/mapped-devices.scm (open-luks-device): Add #:key-file argument. (luks-device-mapping-with-options): New procedure. * doc/guix.texi (Mapped Devices): Describe the new procedure. Change-Id: I1de4e045f8c2c11f9a94f1656e839c785b0c11c4 Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'gnu')
-rw-r--r--gnu/system/mapped-devices.scm67
1 files changed, 42 insertions, 25 deletions
diff --git a/gnu/system/mapped-devices.scm b/gnu/system/mapped-devices.scm
index e6b8970c121..c19a8184533 100644
--- a/gnu/system/mapped-devices.scm
+++ b/gnu/system/mapped-devices.scm
@@ -2,6 +2,7 @@
2;;; Copyright © 2014-2022 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2014-2022 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2016 Andreas Enge <andreas@enge.fr> 3;;; Copyright © 2016 Andreas Enge <andreas@enge.fr>
4;;; Copyright © 2017, 2018 Mark H Weaver <mhw@netris.org> 4;;; Copyright © 2017, 2018 Mark H Weaver <mhw@netris.org>
5;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz>
5;;; 6;;;
6;;; This file is part of GNU Guix. 7;;; This file is part of GNU Guix.
7;;; 8;;;
@@ -64,6 +65,7 @@
64 check-device-initrd-modules ;XXX: needs a better place 65 check-device-initrd-modules ;XXX: needs a better place
65 66
66 luks-device-mapping 67 luks-device-mapping
68 luks-device-mapping-with-options
67 raid-device-mapping 69 raid-device-mapping
68 lvm-device-mapping)) 70 lvm-device-mapping))
69 71
@@ -188,7 +190,7 @@ option of @command{guix system}.\n")
188;;; Common device mappings. 190;;; Common device mappings.
189;;; 191;;;
190 192
191(define (open-luks-device source targets) 193(define* (open-luks-device source targets #:key key-file)
192 "Return a gexp that maps SOURCE to TARGET as a LUKS device, using 194 "Return a gexp that maps SOURCE to TARGET as a LUKS device, using
193'cryptsetup'." 195'cryptsetup'."
194 (with-imported-modules (source-module-closure 196 (with-imported-modules (source-module-closure
@@ -198,7 +200,8 @@ option of @command{guix system}.\n")
198 ((target) 200 ((target)
199 #~(let ((source #$(if (uuid? source) 201 #~(let ((source #$(if (uuid? source)
200 (uuid-bytevector source) 202 (uuid-bytevector source)
201 source))) 203 source))
204 (keyfile #$key-file))
202 ;; XXX: 'use-modules' should be at the top level. 205 ;; XXX: 'use-modules' should be at the top level.
203 (use-modules (rnrs bytevectors) ;bytevector? 206 (use-modules (rnrs bytevectors) ;bytevector?
204 ((gnu build file-systems) 207 ((gnu build file-systems)
@@ -215,29 +218,35 @@ option of @command{guix system}.\n")
215 ;; 'cryptsetup open' requires standard input to be a tty to allow 218 ;; 'cryptsetup open' requires standard input to be a tty to allow
216 ;; for interaction but shepherd sets standard input to /dev/null; 219 ;; for interaction but shepherd sets standard input to /dev/null;
217 ;; thus, explicitly request a tty. 220 ;; thus, explicitly request a tty.
218 (zero? (system*/tty 221 (let ((partition
219 #$(file-append cryptsetup-static "/sbin/cryptsetup") 222 ;; Note: We cannot use the "UUID=source" syntax here
220 "open" "--type" "luks" 223 ;; because 'cryptsetup' implements it by searching the
221 224 ;; udev-populated /dev/disk/by-id directory but udev may
222 ;; Note: We cannot use the "UUID=source" syntax here 225 ;; be unavailable at the time we run this.
223 ;; because 'cryptsetup' implements it by searching the 226 (if (bytevector? source)
224 ;; udev-populated /dev/disk/by-id directory but udev may 227 (or (let loop ((tries-left 10))
225 ;; be unavailable at the time we run this. 228 (and (positive? tries-left)
226 (if (bytevector? source) 229 (or (find-partition-by-luks-uuid source)
227 (or (let loop ((tries-left 10)) 230 ;; If the underlying partition is
228 (and (positive? tries-left) 231 ;; not found, try again after
229 (or (find-partition-by-luks-uuid source) 232 ;; waiting a second, up to ten
230 ;; If the underlying partition is 233 ;; times. FIXME: This should be
231 ;; not found, try again after 234 ;; dealt with in a more robust way.
232 ;; waiting a second, up to ten 235 (begin (sleep 1)
233 ;; times. FIXME: This should be 236 (loop (- tries-left 1))))))
234 ;; dealt with in a more robust way. 237 (error "LUKS partition not found" source))
235 (begin (sleep 1) 238 source)))
236 (loop (- tries-left 1)))))) 239 ;; We want to fallback to the password unlock if the keyfile fails.
237 (error "LUKS partition not found" source)) 240 (or (and keyfile
238 source) 241 (zero? (system*/tty
239 242 #$(file-append cryptsetup-static "/sbin/cryptsetup")
240 #$target))))))) 243 "open" "--type" "luks"
244 "--key-file" keyfile
245 partition #$target)))
246 (zero? (system*/tty
247 #$(file-append cryptsetup-static "/sbin/cryptsetup")
248 "open" "--type" "luks"
249 partition #$target)))))))))
241 250
242(define (close-luks-device source targets) 251(define (close-luks-device source targets)
243 "Return a gexp that closes TARGET, a LUKS device." 252 "Return a gexp that closes TARGET, a LUKS device."
@@ -276,6 +285,14 @@ option of @command{guix system}.\n")
276 (close close-luks-device) 285 (close close-luks-device)
277 (check check-luks-device))) 286 (check check-luks-device)))
278 287
288(define* (luks-device-mapping-with-options #:key key-file)
289 "Return a luks-device-mapping object with open modified to pass the arguments
290into the open-luks-device procedure."
291 (mapped-device-kind
292 (inherit luks-device-mapping)
293 (open (λ (source targets) (open-luks-device source targets
294 #:key-file key-file)))))
295
279(define (open-raid-device sources targets) 296(define (open-raid-device sources targets)
280 "Return a gexp that assembles SOURCES (a list of devices) to the RAID device 297 "Return a gexp that assembles SOURCES (a list of devices) to the RAID device
281TARGET (e.g., \"/dev/md0\"), using 'mdadm'." 298TARGET (e.g., \"/dev/md0\"), using 'mdadm'."