1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#!/bin/bash
# called by dracut
check() {
local fs
# if cryptsetup is not installed, then we cannot support encrypted devices.
require_any_binary "$systemdutildir"/systemd-cryptsetup || return 1
[[ $hostonly ]] || [[ $mount_needs ]] && {
for fs in "${host_fs_types[@]}"; do
[[ $fs == "crypto_LUKS" ]] && return 0
done
return 255
}
return 0
}
# called by dracut
depends() {
local deps
deps="dm rootfs-block crypt systemd-ask-password"
if [[ $hostonly && -f "$dracutsysrootdir"/etc/crypttab ]]; then
if grep -q -e "fido2-device=" -e "fido2-cid=" "$dracutsysrootdir"/etc/crypttab; then
deps+=" fido2"
fi
if grep -q "pkcs11-uri" "$dracutsysrootdir"/etc/crypttab; then
deps+=" pkcs11"
fi
if grep -q "tpm2-device=" "$dracutsysrootdir"/etc/crypttab; then
deps+=" tpm2-tss"
fi
elif [[ ! $hostonly ]]; then
for module in fido2 pkcs11 tpm2-tss; do
module_check $module > /dev/null 2>&1
if [[ $? == 255 ]]; then
deps+=" $module"
fi
done
fi
echo "$deps"
return 0
}
# called by dracut
install() {
# the cryptsetup targets are already pulled in by 00systemd, but not
# the enablement symlinks
inst_multiple -o \
"$tmpfilesdir"/cryptsetup.conf \
"$systemdutildir"/system-generators/systemd-cryptsetup-generator \
"$systemdutildir"/systemd-cryptsetup \
"$systemdsystemunitdir"/cryptsetup.target \
"$systemdsystemunitdir"/sysinit.target.wants/cryptsetup.target \
"$systemdsystemunitdir"/remote-cryptsetup.target \
"$systemdsystemunitdir"/initrd-root-device.target.wants/remote-cryptsetup.target
if [[ $hostonly ]] && [[ -f $initdir/etc/crypttab ]]; then
# for each entry in /etc/crypttab check if the key file is backed by a socket unit and if so,
# include it along with its corresponding service unit.
while read -r _mapper _dev _luksfile _luksoptions || [[ -n $_mapper ]]; do
# ignore paths followed by a device specification
if [[ $_luksfile == *":"* ]]; then
return
fi
# if no explicit path is provided, try to include units for auto-discoverable keys
if [[ -z $_luksfile ]] || [[ $_luksfile == "-" ]] || [[ $_luksfile == "none" ]]; then
_luksfile="/run/cryptsetup-keys.d/$_mapper.key"
fi
find "$systemdsystemunitdir" "$systemdsystemconfdir" -type f -name "*.socket" | while read -r socket_unit; do
# systemd-cryptsetup utility only supports SOCK_STREAM (ListenStream) sockets, so we ignore
# other types like SOCK_DGRAM (ListenDatagram), SOCK_SEQPACKET (ListenSequentialPacket), etc.
if ! grep -E -q "^ListenStream\s*=\s*$_luksfile$" "$socket_unit"; then
continue
fi
service_name=$(grep -E "^Service\s*=\s*" "$socket_unit" | cut -d= -f2)
if [ -z "$service_name" ]; then
# if no explicit Service= is defined, construct the service name based on the socket unit's name
if grep -P -q "^Accept\s*=\s*(?i)(1|yes|y|true|t|on)$" "$socket_unit"; then
# if Accept is truthy, assemble a service template
service_name=$(basename "$socket_unit" .socket)"@.service"
else
# otherwise, just replace .socket with .service
service_name=$(basename "$socket_unit" .socket)".service"
fi
fi
# this assumes the service file is in the same directory as the socket file,
# which is a common configuration but not guaranteed.
if ! inst_multiple -H "${socket_unit%/*}/$service_name" "$socket_unit"; then
continue
fi
# sanity check - all units which use default dependencies will depend on sysinit.target,
# which itself depends on cryptsetup.target. This could lead to either:
# a) systemd-cryptsetup falling back to a passphrase prompt due to a missing socket file
# b) a deadlock caused by a circular dependency (service unit -> sysinit.target -> cryptsetup.target -> service unit)
if ! grep -P -q "^DefaultDependencies\s*=\s*(?i)(0|no|n|false|f|off)" "$socket_unit"; then
dwarning "crypt: $socket_unit: default dependencies are not disabled," \
"the socket file may not exist by the time systemd-cryptsetup gets executed"
fi
if ! grep -P -q "^DefaultDependencies\s*=\s*(?i)(0|no|n|false|f|off)" "${socket_unit%/*}/$service_name"; then
dwarning "crypt: ${socket_unit%/*}/$service_name: default dependencies are not disabled," \
"the service unit may encounter a deadlock due to a circular dependency"
fi
socket_unit_basename=$(basename "$socket_unit")
inst_multiple -H -o \
"$systemdsystemunitdir"/sockets.target.wants/"$socket_unit_basename" \
"$systemdsystemconfdir"/sockets.target.wants/"$socket_unit_basename"
break
done
done < "$initdir"/etc/crypttab
fi
}
|