-
Notifications
You must be signed in to change notification settings - Fork 51
/
ykfde-enroll
228 lines (203 loc) · 8.49 KB
/
ykfde-enroll
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#!/bin/bash -p
set -euo pipefail
# sanitize environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
YKFDE_LUKS_DEV=""
YKFDE_LUKS_KEYSLOT=""
YKFDE_CHANGE_KEYSLOT=""
YKFDE_OLD_YUBIKEY=""
DBG=""
YKFDE_SLOT_CHECK=""
YKFDE_SLOT_KILL=""
YKFDE_CHALLENGE_SLOT="2"
YKFDE_CHALLENGE_PASSWORD_NEEDED=""
YKFDE_CHALLENGE=""
YKFDE_RESPONSE=""
YKFDE_PASSPHRASE=""
YKFDE_OLD_CHALLENGE=""
YKFDE_OLD_RESPONSE=""
YKFDE_OLD_PASSPHRASE=""
if [ -r /etc/ykfde.conf ]; then
# shellcheck source=ykfde.conf
. /etc/ykfde.conf
else
echo "WARNING: Can't access /etc/ykfde.conf. Falling back to defaults."
fi
while getopts ":d:s:ckovh" opt; do
case "$opt" in
d)
YKFDE_LUKS_DEV="$OPTARG"
printf '%s\n' "INFO: Setting device to '$OPTARG'."
;;
s)
if [ "$OPTARG" -gt -8 ] && [ "$OPTARG" -lt 8 ]; then
YKFDE_LUKS_KEYSLOT="$OPTARG"
printf '%s\n' "INFO: Setting LUKS keyslot to '$OPTARG'."
else
printf '%s\n' "ERROR: Chosen LUKS keyslot '$OPTARG' is invalid. Please choose valid LUKS keyslot number between '0-7'."
exit 1
fi
;;
c)
YKFDE_CHANGE_KEYSLOT=1
echo "INFO: Changing existing LUKS keyslot"
;;
k)
YKFDE_SLOT_KILL=1
echo "WARNING: Killing existing LUKS keyslot. If it's the last configured keyslot, the device will be inaccessible!"
;;
o)
YKFDE_OLD_YUBIKEY=1
echo "INFO: Using old YubiKey for passphrase"
;;
v)
DBG=1
echo "INFO: Debugging enabled"
;;
h)
echo
echo " -d <device> : select an existing device"
echo " -s <slot> : select the LUKS keyslot"
echo " -c : change an existing keyslot"
echo " -k : killing an existing keyslot"
echo " -o : use old YubiKey for passphrase"
echo " -v : show input/output in cleartext"
echo
exit 0
;;
\?)
printf '%s\n' "ERROR: Invalid option: '-$OPTARG'" >&2
echo
echo " -d <device> : select an existing device"
echo " -s <slot> : select the LUKS keyslot"
echo " -c : change an existing keyslot"
echo " -k : killing an existing keyslot"
echo " -o : use old YubiKey for passphrase"
echo " -v : show input/output in cleartext"
echo
exit 1
;;
esac
done
YKFDE_SLOT_CHECK="$(ykinfo -q -"$YKFDE_CHALLENGE_SLOT")"
[ "$DBG" ] && printf '%s\n' " > YubiKey slot status 'ykinfo -q -$YKFDE_CHALLENGE_SLOT': $YKFDE_SLOT_CHECK"
if [ "$YKFDE_SLOT_CHECK" != 1 ]; then
printf '%s\n' "ERROR: Chosen YubiKey slot '$YKFDE_CHALLENGE_SLOT' isn't configured. Please choose slot configured for 'HMAC-SHA1 Challenge-Response' mode in '/etc/ykfde.conf'"
exit 1
fi
if [ -z "$YKFDE_LUKS_DEV" ]; then
echo "ERROR: Device not selected. Please select an existing device using '-d' option, see 'ykfde-enroll -h' for help."
exit 1
fi
if [ ! -e "$YKFDE_LUKS_DEV" ]; then
printf '%s\n' "ERROR: Selected device '$YKFDE_LUKS_DEV' doesn't exist. Please select an existing device."
exit 1
fi
if [ ! -r "$YKFDE_LUKS_DEV" ] || [ ! -w "$YKFDE_LUKS_DEV" ]; then
printf '%s\n' "ERROR: Selected device '$YKFDE_LUKS_DEV' isn't accessible for current user '$(whoami)'. Please execute this script as 'root'."
exit 1
fi
if ! cryptsetup isLuks "$YKFDE_LUKS_DEV"; then
printf '%s\n' "ERROR: Selected device '$YKFDE_LUKS_DEV' isn't a LUKS encrypted volume. Please select a valid device."
exit 1
fi
if [ -z "$YKFDE_LUKS_KEYSLOT" ]; then
echo "ERROR: LUKS keyslot not selected. Please select LUKS keyslot using '-s' option, see 'ykfde-enroll -h' for help."
exit 1
fi
printf '%s\n' "WARNING: This script will utilize LUKS keyslot '$YKFDE_LUKS_KEYSLOT' on device '$YKFDE_LUKS_DEV'. If this is not what you intended, please abort."
[ -z "$YKFDE_CHALLENGE" ] && YKFDE_CHALLENGE_PASSWORD_NEEDED=1
[ "$YKFDE_CHALLENGE_PASSWORD_NEEDED" ] && YKFDE_CHALLENGE=""
while [ -z "$YKFDE_CHALLENGE" ]; do
echo " > Please provide the challenge."
printf " Enter challenge: "
if [ "$DBG" ]; then read -r YKFDE_CHALLENGE; else read -r -s YKFDE_CHALLENGE; fi
printf "\\n > Please repeat the challenge.\\n"
printf " Enter challenge: "
if [ "$DBG" ]; then read -r YKFDE_CHALLENGE2; else read -r -s YKFDE_CHALLENGE2; fi
if [ "$YKFDE_CHALLENGE" != "$YKFDE_CHALLENGE2" ]; then
echo "WARNING: Challenges do not match. Try again."
YKFDE_CHALLENGE=""
fi
[ "$YKFDE_CHALLENGE" ] && YKFDE_CHALLENGE="$(printf %s "$YKFDE_CHALLENGE" | sha256sum | awk '{print $1}')"
# if /NOT/ DBG, we need to output \n here.
[ "$DBG" ] || echo
done
if [ -z "$YKFDE_CHALLENGE" ]; then
echo "ERROR: ykfde challenge is empty. Operation aborted."
exit 1
fi
while [ -z "$YKFDE_RESPONSE" ]; do
[ "$DBG" ] && printf '%s\n' " Running: 'ykchalresp -$YKFDE_CHALLENGE_SLOT $YKFDE_CHALLENGE'..."
echo " Remember to touch the device if necessary."
YKFDE_RESPONSE="$(printf %s "$YKFDE_CHALLENGE" | ykchalresp -"$YKFDE_CHALLENGE_SLOT" -i- | tr -d '\n')" || true
[ "$DBG" ] && printf '%s\n' " Received response: '$YKFDE_RESPONSE'"
done
if [ "$YKFDE_RESPONSE" ]; then
if [ "$YKFDE_CHALLENGE_PASSWORD_NEEDED" ]; then
YKFDE_PASSPHRASE="$YKFDE_CHALLENGE$YKFDE_RESPONSE"
else
YKFDE_PASSPHRASE="$YKFDE_RESPONSE"
fi
fi
if [ "$YKFDE_SLOT_KILL" ]; then
[ "$DBG" ] && printf '%s\n' " > Killing with 'cryptsetup luksKillSlot $YKFDE_LUKS_DEV $YKFDE_LUKS_KEYSLOT'..." || echo " > Killing slot with 'cryptsetup'..."
printf %s "$YKFDE_PASSPHRASE" | cryptsetup luksKillSlot "$YKFDE_LUKS_DEV" "$YKFDE_LUKS_KEYSLOT" 2>&1
printf '%s\n' " LUKS key slot $YKFDE_LUKS_KEYSLOT successfully killed"
exit 0
fi
if [ "$YKFDE_OLD_YUBIKEY" ]; then
echo "Please insert old YubiKey for existing keyslot."
while [ -z "$YKFDE_OLD_CHALLENGE" ]; do
echo " > Please provide the old challenge."
printf " Enter challenge: "
if [ "$DBG" ]; then read -r YKFDE_OLD_CHALLENGE; else read -r -s YKFDE_OLD_CHALLENGE; fi
printf "\\n > Please repeat the old challenge.\\n"
printf " Enter challenge: "
if [ "$DBG" ]; then read -r YKFDE_OLD_CHALLENGE2; else read -r -s YKFDE_OLD_CHALLENGE2; fi
if [ "$YKFDE_OLD_CHALLENGE" != "$YKFDE_OLD_CHALLENGE2" ]; then
echo "WARNING: Challenges do not match. Try again."
YKFDE_OLD_CHALLENGE=""
fi
[ "$YKFDE_OLD_CHALLENGE" ] && YKFDE_OLD_CHALLENGE="$(printf %s "$YKFDE_OLD_CHALLENGE" | sha256sum | awk '{print $1}')"
# if /NOT/ DBG, we need to output \n here.
[ "$DBG" ] || echo
done
if [ -z "$YKFDE_OLD_CHALLENGE" ]; then
echo "ERROR: ykfde old challenge is empty. Operation aborted."
exit 1
fi
while [ -z "$YKFDE_OLD_RESPONSE" ]; do
[ "$DBG" ] && printf '%s\n' " Running: 'ykchalresp -$YKFDE_CHALLENGE_SLOT $YKFDE_OLD_CHALLENGE'..."
echo " Remember to touch the old device if necessary."
YKFDE_OLD_RESPONSE="$(printf %s "$YKFDE_OLD_CHALLENGE" | ykchalresp -"$YKFDE_CHALLENGE_SLOT" -i- | tr -d '\n')" || true
[ "$DBG" ] && printf '%s\n' " Received response: '$YKFDE_OLD_RESPONSE'"
done
if [ "$YKFDE_OLD_RESPONSE" ]; then
if [ "$YKFDE_CHALLENGE_PASSWORD_NEEDED" ]; then
YKFDE_OLD_PASSPHRASE="$YKFDE_OLD_CHALLENGE$YKFDE_OLD_RESPONSE"
else
YKFDE_OLD_PASSPHRASE="$YKFDE_OLD_RESPONSE"
fi
fi
else
echo "Please provide the old LUKS passphrase for the existing keyslot."
printf " Enter passphrase: "
if [ "$DBG" ]; then read -r YKFDE_OLD_PASSPHRASE; else read -r -s YKFDE_OLD_PASSPHRASE; fi
fi
if [ "$YKFDE_PASSPHRASE" ]; then
[ "$DBG" ] && printf '%s\n' " > Passing '$YKFDE_PASSPHRASE' to 'cryptsetup'"
if [ "$YKFDE_CHANGE_KEYSLOT" ]; then
[ "$DBG" ] && printf '%s\n' " > Changing LUKS passphrase with 'cryptsetup --key-slot=$YKFDE_LUKS_KEYSLOT luksChangeKey $YKFDE_LUKS_DEV'..." || echo " > Changing LUKS passphrase with 'cryptsetup'..."
printf '%s\n' "$YKFDE_OLD_PASSPHRASE" "$YKFDE_PASSPHRASE" "$YKFDE_PASSPHRASE" | cryptsetup --key-slot="$YKFDE_LUKS_KEYSLOT" luksChangeKey "$YKFDE_LUKS_DEV" 2>&1
printf '%s\n' " LUKS passphrase for key slot $YKFDE_LUKS_KEYSLOT successfully changed"
else
[ "$DBG" ] && printf '%s\n' " > Adding new LUKS passphrase with 'cryptsetup --key-slot=$YKFDE_LUKS_KEYSLOT luksAddKey $YKFDE_LUKS_DEV'..." || echo " > Adding new LUKS passphrase with 'cryptsetup'..."
printf '%s\n' "$YKFDE_OLD_PASSPHRASE" "$YKFDE_PASSPHRASE" "$YKFDE_PASSPHRASE" | cryptsetup --key-slot="$YKFDE_LUKS_KEYSLOT" luksAddKey "$YKFDE_LUKS_DEV" 2>&1
printf '%s\n' " New LUKS passphrase successfully added"
fi
else
echo "ERROR: ykfde passphrase is empty. Operation aborted."
exit 1
fi
exit 0