Skip to content

Commit f33f121

Browse files
nabijaczlewelitonyhutter
authored andcommitted
libzfs: add keylocation=https://, backed by fetch(3) or libcurl
Add support for http and https to the keylocation properly to allow encryption keys to be fetched from the specified URL. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Ryan Moeller <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Issue openzfs#9543 Closes openzfs#9947 Closes openzfs#11956
1 parent 80f4460 commit f33f121

29 files changed

+581
-53
lines changed

config/Substfiles.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ subst_sed_cmd = \
1515
-e 's|@PYTHON[@]|$(PYTHON)|g' \
1616
-e 's|@PYTHON_SHEBANG[@]|$(PYTHON_SHEBANG)|g' \
1717
-e 's|@DEFAULT_INIT_NFS_SERVER[@]|$(DEFAULT_INIT_NFS_SERVER)|g' \
18-
-e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g'
18+
-e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g' \
19+
-e 's|@LIBFETCH_DYNAMIC[@]|$(LIBFETCH_DYNAMIC)|g' \
20+
-e 's|@LIBFETCH_SONAME[@]|$(LIBFETCH_SONAME)|g'
1921

2022
SUBSTFILES =
2123
CLEANFILES = $(SUBSTFILES)

config/user-libfetch.m4

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
dnl #
2+
dnl # Check for a libfetch - either fetch(3) or libcurl.
3+
dnl #
4+
dnl # There are two configuration dimensions:
5+
dnl # * fetch(3) vs libcurl
6+
dnl # * static vs dynamic
7+
dnl #
8+
dnl # fetch(3) is only dynamic.
9+
dnl # We use sover 6, which first appeared in FreeBSD 8.0-RELEASE.
10+
dnl #
11+
dnl # libcurl development packages include curl-config(1) – we want:
12+
dnl # * HTTPS support
13+
dnl # * version at least 7.16 (October 2006), for sover 4
14+
dnl # * to decide if it's static or not
15+
dnl #
16+
AC_DEFUN([ZFS_AC_CONFIG_USER_LIBFETCH], [
17+
AC_MSG_CHECKING([for libfetch])
18+
LIBFETCH_LIBS=
19+
LIBFETCH_IS_FETCH=0
20+
LIBFETCH_IS_LIBCURL=0
21+
LIBFETCH_DYNAMIC=0
22+
LIBFETCH_SONAME=
23+
have_libfetch=
24+
25+
saved_libs="$LIBS"
26+
LIBS="$LIBS -lfetch"
27+
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
28+
#include <sys/param.h>
29+
#include <stdio.h>
30+
#include <fetch.h>
31+
]], [fetchGetURL("", "");])], [
32+
have_libfetch=1
33+
LIBFETCH_IS_FETCH=1
34+
LIBFETCH_DYNAMIC=1
35+
LIBFETCH_SONAME='"libfetch.so.6"'
36+
LIBFETCH_LIBS="-ldl"
37+
AC_MSG_RESULT([fetch(3)])
38+
], [])
39+
LIBS="$saved_libs"
40+
41+
if test -z "$have_libfetch"; then
42+
if curl-config --protocols 2>/dev/null | grep -q HTTPS &&
43+
test "$(printf "%u" "0x$(curl-config --vernum)")" -ge "$(printf "%u" "0x071000")"; then
44+
have_libfetch=1
45+
LIBFETCH_IS_LIBCURL=1
46+
if test "$(curl-config --built-shared)" = "yes"; then
47+
LIBFETCH_DYNAMIC=1
48+
LIBFETCH_SONAME='"libcurl.so.4"'
49+
LIBFETCH_LIBS="-ldl"
50+
AC_MSG_RESULT([libcurl])
51+
else
52+
LIBFETCH_LIBS="$(curl-config --libs)"
53+
AC_MSG_RESULT([libcurl (static)])
54+
fi
55+
56+
CCFLAGS="$CCFLAGS $(curl-config --cflags)"
57+
fi
58+
fi
59+
60+
if test -z "$have_libfetch"; then
61+
AC_MSG_RESULT([none])
62+
fi
63+
64+
AC_SUBST([LIBFETCH_LIBS])
65+
AC_SUBST([LIBFETCH_DYNAMIC])
66+
AC_SUBST([LIBFETCH_SONAME])
67+
AC_DEFINE_UNQUOTED([LIBFETCH_IS_FETCH], [$LIBFETCH_IS_FETCH], [libfetch is fetch(3)])
68+
AC_DEFINE_UNQUOTED([LIBFETCH_IS_LIBCURL], [$LIBFETCH_IS_LIBCURL], [libfetch is libcurl])
69+
AC_DEFINE_UNQUOTED([LIBFETCH_DYNAMIC], [$LIBFETCH_DYNAMIC], [whether the chosen libfetch is to be loaded at run-time])
70+
AC_DEFINE_UNQUOTED([LIBFETCH_SONAME], [$LIBFETCH_SONAME], [soname of chosen libfetch])
71+
])

config/user.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
2222
ZFS_AC_CONFIG_USER_LIBCRYPTO
2323
ZFS_AC_CONFIG_USER_LIBAIO
2424
ZFS_AC_CONFIG_USER_LIBATOMIC
25+
ZFS_AC_CONFIG_USER_LIBFETCH
2526
ZFS_AC_CONFIG_USER_CLOCK_GETTIME
2627
ZFS_AC_CONFIG_USER_PAM
2728
ZFS_AC_CONFIG_USER_RUNSTATEDIR

contrib/dracut/90zfs/module-setup.sh.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ install() {
6060
# Fallback: Guess the path and include all matches
6161
dracut_install /usr/lib*/gcc/**/libgcc_s.so*
6262
fi
63+
if [ @LIBFETCH_DYNAMIC@ != 0 ]; then
64+
for d in $libdirs; do
65+
[ -e "$d"/@LIBFETCH_SONAME@ ] && dracut_install "$d"/@LIBFETCH_SONAME@
66+
done
67+
fi
6368
dracut_install @mounthelperdir@/mount.zfs
6469
dracut_install @udevdir@/vdev_id
6570
dracut_install awk

contrib/dracut/90zfs/zfs-env-bootfs.service.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Before=zfs-import.target
88

99
[Service]
1010
Type=oneshot
11-
ExecStart=/bin/sh -c "systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | grep -m1 -v '^-$')"
11+
ExecStart=/bin/sh -c "exec systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | grep -m1 -v '^-$')"
1212

1313
[Install]
1414
WantedBy=zfs-import.target

contrib/dracut/90zfs/zfs-load-key.sh.in

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,14 @@ if [ "$(zpool list -H -o feature@encryption "${BOOTFS%%/*}")" = 'active' ]; then
4343

4444
KEYLOCATION="$(zfs get -H -o value keylocation "${ENCRYPTIONROOT}")"
4545
if ! [ "${KEYLOCATION}" = "prompt" ]; then
46+
if ! [ "${KEYLOCATION#http}" = "${KEYLOCATION}" ]; then
47+
systemctl start network-online.target
48+
fi
4649
zfs load-key "${ENCRYPTIONROOT}"
4750
else
4851
# decrypt them
49-
TRY_COUNT=5
50-
while [ $TRY_COUNT -gt 0 ]; do
52+
for _ in 1 2 3 4 5; do
5153
systemd-ask-password "Encrypted ZFS password for ${BOOTFS}" --no-tty | zfs load-key "${ENCRYPTIONROOT}" && break
52-
TRY_COUNT=$((TRY_COUNT - 1))
5354
done
5455
fi
5556
fi

contrib/dracut/90zfs/zfs-rollback-bootfs.service.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ ConditionKernelCommandLine=bootfs.rollback
1010
# ${BOOTFS} should have been set by zfs-env-bootfs.service
1111
Type=oneshot
1212
ExecStartPre=/bin/sh -c 'test -n "${BOOTFS}"'
13-
ExecStart=/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.rollback)"; @sbindir@/zfs rollback -Rf "${BOOTFS}@${SNAPNAME:-%v}"'
13+
ExecStart=/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.rollback)"; exec @sbindir@/zfs rollback -Rf "${BOOTFS}@${SNAPNAME:-%v}"'
1414
RemainAfterExit=yes

contrib/dracut/90zfs/zfs-snapshot-bootfs.service.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ ConditionKernelCommandLine=bootfs.snapshot
1010
# ${BOOTFS} should have been set by zfs-env-bootfs.service
1111
Type=oneshot
1212
ExecStartPre=/bin/sh -c 'test -n "${BOOTFS}"'
13-
ExecStart=-/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.snapshot)"; @sbindir@/zfs snapshot "${BOOTFS}@${SNAPNAME:-%v}"'
13+
ExecStart=-/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.snapshot)"; exec @sbindir@/zfs snapshot "${BOOTFS}@${SNAPNAME:-%v}"'
1414
RemainAfterExit=yes

contrib/initramfs/hooks/zfs.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ find /lib/ -type f -name "libgcc_s.so.[1-9]" | while read -r libgcc; do
3030
copy_exec "$libgcc"
3131
done
3232

33+
# shellcheck disable=SC2050
34+
if [ @LIBFETCH_DYNAMIC@ != 0 ]; then
35+
find /lib/ -name @LIBFETCH_SONAME@ | while read -r libfetch; do
36+
copy_exec "$libfetch"
37+
done
38+
fi
39+
3340
copy_file config "/etc/hostid"
3441
copy_file cache "@sysconfdir@/zfs/zpool.cache"
3542
copy_file config "@initconfdir@/zfs"

contrib/initramfs/scripts/zfs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -403,28 +403,25 @@ decrypt_fs()
403403
KEYSTATUS="$(get_fs_value "${ENCRYPTIONROOT}" keystatus)"
404404
# Continue only if the key needs to be loaded
405405
[ "$KEYSTATUS" = "unavailable" ] || return 0
406-
TRY_COUNT=3
407406

408-
# If key is stored in a file, do not prompt
407+
# Do not prompt if key is stored noninteractively,
409408
if ! [ "${KEYLOCATION}" = "prompt" ]; then
410409
$ZFS load-key "${ENCRYPTIONROOT}"
411410

412411
# Prompt with plymouth, if active
413-
elif [ -e /bin/plymouth ] && /bin/plymouth --ping 2>/dev/null; then
412+
elif /bin/plymouth --ping 2>/dev/null; then
414413
echo "plymouth" > /run/zfs_console_askpwd_cmd
415-
while [ $TRY_COUNT -gt 0 ]; do
414+
for _ in 1 2 3; do
416415
plymouth ask-for-password --prompt "Encrypted ZFS password for ${ENCRYPTIONROOT}" | \
417416
$ZFS load-key "${ENCRYPTIONROOT}" && break
418-
TRY_COUNT=$((TRY_COUNT - 1))
419417
done
420418

421419
# Prompt with systemd, if active
422420
elif [ -e /run/systemd/system ]; then
423421
echo "systemd-ask-password" > /run/zfs_console_askpwd_cmd
424-
while [ $TRY_COUNT -gt 0 ]; do
422+
for _ in 1 2 3; do
425423
systemd-ask-password "Encrypted ZFS password for ${ENCRYPTIONROOT}" --no-tty | \
426424
$ZFS load-key "${ENCRYPTIONROOT}" && break
427-
TRY_COUNT=$((TRY_COUNT - 1))
428425
done
429426

430427
# Prompt with ZFS tty, otherwise

include/libzfs_impl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ struct libzfs_handle {
7272
boolean_t libzfs_prop_debug;
7373
regex_t libzfs_urire;
7474
uint64_t libzfs_max_nvlist;
75+
void *libfetch;
76+
char *libfetch_load_error;
7577
};
7678

7779
struct zfs_handle {

lib/libzfs/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ libzfs_la_LIBADD = \
7575
$(abs_top_builddir)/lib/libnvpair/libnvpair.la \
7676
$(abs_top_builddir)/lib/libuutil/libuutil.la
7777

78-
libzfs_la_LIBADD += -lm $(LIBCRYPTO_LIBS) $(ZLIB_LIBS) $(LTLIBINTL)
78+
libzfs_la_LIBADD += -lm $(LIBCRYPTO_LIBS) $(ZLIB_LIBS) $(LIBFETCH_LIBS) $(LTLIBINTL)
7979

8080
libzfs_la_LDFLAGS = -pthread
8181

lib/libzfs/libzfs.abi

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -551,10 +551,6 @@
551551
<parameter type-id='e1c52942'/>
552552
<return type-id='95e97e5e'/>
553553
</function-decl>
554-
<function-decl name='unlink' visibility='default' binding='global' size-in-bits='64'>
555-
<parameter type-id='80f4b756'/>
556-
<return type-id='95e97e5e'/>
557-
</function-decl>
558554
</abi-instr>
559555
<abi-instr address-size='64' path='os/linux/smb.c' language='LANG_C99'>
560556
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='2040' id='11641789'>
@@ -1373,7 +1369,7 @@
13731369
<typedef-decl name='zpool_handle_t' type-id='67002a8a' id='b1efc708'/>
13741370
<typedef-decl name='libzfs_handle_t' type-id='c8a9d9d8' id='95942d0c'/>
13751371
<typedef-decl name='zfs_iter_f' type-id='5571cde4' id='d8e49ab9'/>
1376-
<class-decl name='libzfs_handle' size-in-bits='20224' is-struct='yes' visibility='default' id='c8a9d9d8'>
1372+
<class-decl name='libzfs_handle' size-in-bits='20352' is-struct='yes' visibility='default' id='c8a9d9d8'>
13771373
<data-member access='public' layout-offset-in-bits='0'>
13781374
<var-decl name='libzfs_error' type-id='95e97e5e' visibility='default'/>
13791375
</data-member>
@@ -1434,6 +1430,12 @@
14341430
<data-member access='public' layout-offset-in-bits='20160'>
14351431
<var-decl name='libzfs_max_nvlist' type-id='9c313c2d' visibility='default'/>
14361432
</data-member>
1433+
<data-member access='public' layout-offset-in-bits='20224'>
1434+
<var-decl name='libfetch' type-id='eaa32e2f' visibility='default'/>
1435+
</data-member>
1436+
<data-member access='public' layout-offset-in-bits='20288'>
1437+
<var-decl name='libfetch_load_error' type-id='26a90f95' visibility='default'/>
1438+
</data-member>
14371439
</class-decl>
14381440
<class-decl name='zfs_handle' size-in-bits='4928' is-struct='yes' visibility='default' id='f6ee4445'>
14391441
<data-member access='public' layout-offset-in-bits='0'>
@@ -3190,6 +3192,19 @@
31903192
<function-decl name='__ctype_b_loc' visibility='default' binding='global' size-in-bits='64'>
31913193
<return type-id='c59e1ef0'/>
31923194
</function-decl>
3195+
<function-decl name='dlopen' visibility='default' binding='global' size-in-bits='64'>
3196+
<parameter type-id='80f4b756'/>
3197+
<parameter type-id='95e97e5e'/>
3198+
<return type-id='eaa32e2f'/>
3199+
</function-decl>
3200+
<function-decl name='dlsym' visibility='default' binding='global' size-in-bits='64'>
3201+
<parameter type-id='1b7446cd'/>
3202+
<parameter type-id='9d26089a'/>
3203+
<return type-id='eaa32e2f'/>
3204+
</function-decl>
3205+
<function-decl name='dlerror' visibility='default' binding='global' size-in-bits='64'>
3206+
<return type-id='26a90f95'/>
3207+
</function-decl>
31933208
<function-decl name='PKCS5_PBKDF2_HMAC_SHA1' visibility='default' binding='global' size-in-bits='64'>
31943209
<parameter type-id='80f4b756'/>
31953210
<parameter type-id='95e97e5e'/>
@@ -3231,6 +3246,11 @@
32313246
<parameter type-id='822cd80b'/>
32323247
<return type-id='95e97e5e'/>
32333248
</function-decl>
3249+
<function-decl name='fdopen' visibility='default' binding='global' size-in-bits='64'>
3250+
<parameter type-id='95e97e5e'/>
3251+
<parameter type-id='80f4b756'/>
3252+
<return type-id='822cd80b'/>
3253+
</function-decl>
32343254
<function-decl name='printf' visibility='default' binding='global' size-in-bits='64'>
32353255
<parameter type-id='80f4b756'/>
32363256
<parameter is-variadic='yes'/>
@@ -3243,6 +3263,12 @@
32433263
<parameter is-variadic='yes'/>
32443264
<return type-id='95e97e5e'/>
32453265
</function-decl>
3266+
<function-decl name='asprintf' visibility='default' binding='global' size-in-bits='64'>
3267+
<parameter type-id='8c85230f'/>
3268+
<parameter type-id='9d26089a'/>
3269+
<parameter is-variadic='yes'/>
3270+
<return type-id='95e97e5e'/>
3271+
</function-decl>
32463272
<function-decl name='fputc' visibility='default' binding='global' size-in-bits='64'>
32473273
<parameter type-id='95e97e5e'/>
32483274
<parameter type-id='822cd80b'/>
@@ -3262,6 +3288,10 @@
32623288
<parameter type-id='e75a27e9'/>
32633289
<return type-id='b59d7dce'/>
32643290
</function-decl>
3291+
<function-decl name='rewind' visibility='default' binding='global' size-in-bits='64'>
3292+
<parameter type-id='822cd80b'/>
3293+
<return type-id='48b5725f'/>
3294+
</function-decl>
32653295
<function-decl name='ferror' visibility='default' binding='global' size-in-bits='64'>
32663296
<parameter type-id='822cd80b'/>
32673297
<return type-id='95e97e5e'/>
@@ -3285,6 +3315,10 @@
32853315
<parameter type-id='b59d7dce'/>
32863316
<return type-id='eaa32e2f'/>
32873317
</function-decl>
3318+
<function-decl name='strdup' visibility='default' binding='global' size-in-bits='64'>
3319+
<parameter type-id='80f4b756'/>
3320+
<return type-id='26a90f95'/>
3321+
</function-decl>
32883322
<function-decl name='strerror' visibility='default' binding='global' size-in-bits='64'>
32893323
<parameter type-id='95e97e5e'/>
32903324
<return type-id='26a90f95'/>
@@ -3317,6 +3351,10 @@
33173351
<parameter type-id='95e97e5e'/>
33183352
<return type-id='95e97e5e'/>
33193353
</function-decl>
3354+
<function-decl name='unlink' visibility='default' binding='global' size-in-bits='64'>
3355+
<parameter type-id='80f4b756'/>
3356+
<return type-id='95e97e5e'/>
3357+
</function-decl>
33203358
<function-type size-in-bits='64' id='ee076206'>
33213359
<return type-id='48b5725f'/>
33223360
</function-type>
@@ -4425,12 +4463,6 @@
44254463
<parameter is-variadic='yes'/>
44264464
<return type-id='95e97e5e'/>
44274465
</function-decl>
4428-
<function-decl name='asprintf' visibility='default' binding='global' size-in-bits='64'>
4429-
<parameter type-id='8c85230f'/>
4430-
<parameter type-id='9d26089a'/>
4431-
<parameter is-variadic='yes'/>
4432-
<return type-id='95e97e5e'/>
4433-
</function-decl>
44344466
<function-decl name='strtol' visibility='default' binding='global' size-in-bits='64'>
44354467
<parameter type-id='9d26089a'/>
44364468
<parameter type-id='8c85230f'/>
@@ -4452,10 +4484,6 @@
44524484
<parameter type-id='b59d7dce'/>
44534485
<return type-id='26a90f95'/>
44544486
</function-decl>
4455-
<function-decl name='strdup' visibility='default' binding='global' size-in-bits='64'>
4456-
<parameter type-id='80f4b756'/>
4457-
<return type-id='26a90f95'/>
4458-
</function-decl>
44594487
<function-decl name='strrchr' visibility='default' binding='global' size-in-bits='64'>
44604488
<parameter type-id='80f4b756'/>
44614489
<parameter type-id='95e97e5e'/>
@@ -4620,11 +4648,6 @@
46204648
<parameter type-id='4051f5e7'/>
46214649
<return type-id='95e97e5e'/>
46224650
</function-decl>
4623-
<function-decl name='fdopen' visibility='default' binding='global' size-in-bits='64'>
4624-
<parameter type-id='95e97e5e'/>
4625-
<parameter type-id='80f4b756'/>
4626-
<return type-id='822cd80b'/>
4627-
</function-decl>
46284651
<function-decl name='pipe2' visibility='default' binding='global' size-in-bits='64'>
46294652
<parameter type-id='7292109c'/>
46304653
<parameter type-id='95e97e5e'/>
@@ -6705,6 +6728,12 @@
67056728
<parameter type-id='95e97e5e'/>
67066729
<return type-id='48b5725f'/>
67076730
</function-decl>
6731+
<function-decl name='avl_insert' visibility='default' binding='global' size-in-bits='64'>
6732+
<parameter type-id='a3681dea'/>
6733+
<parameter type-id='eaa32e2f'/>
6734+
<parameter type-id='fba6cb51'/>
6735+
<return type-id='48b5725f'/>
6736+
</function-decl>
67086737
<function-decl name='nvlist_lookup_boolean' visibility='default' binding='global' size-in-bits='64'>
67096738
<parameter type-id='5ce45b60'/>
67106739
<parameter type-id='80f4b756'/>
@@ -7235,6 +7264,10 @@
72357264
<function-decl name='__ctype_toupper_loc' visibility='default' binding='global' size-in-bits='64'>
72367265
<return type-id='24f95ba5'/>
72377266
</function-decl>
7267+
<function-decl name='dlclose' visibility='default' binding='global' size-in-bits='64'>
7268+
<parameter type-id='eaa32e2f'/>
7269+
<return type-id='95e97e5e'/>
7270+
</function-decl>
72387271
<function-decl name='regcomp' visibility='default' binding='global' size-in-bits='64'>
72397272
<parameter type-id='5c53ba29'/>
72407273
<parameter type-id='9d26089a'/>

0 commit comments

Comments
 (0)