From c44a249fc8b0638e3876e1e662bf85ea52c7d07a Mon Sep 17 00:00:00 2001 From: Tom Lebreux Date: Wed, 8 Nov 2023 23:00:38 -0500 Subject: [PATCH] Add cryptprompt kernel param to run a custom prompt --- Makefile | 6 ++-- initramfs-init.in | 14 +++----- nlplug-findfs/nlplug-findfs.c | 65 ++++++++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index 0a0edbb..72d1e5f 100644 --- a/Makefile +++ b/Makefile @@ -107,11 +107,9 @@ LIBKMOD_CFLAGS := $(shell $(PKGCONF) --cflags libkmod) LIBKMOD_LIBS := $(shell $(PKGCONF) --libs libkmod) CRYPTSETUP_CFLAGS := $(shell $(PKGCONF) --cflags libcryptsetup) CRYPTSETUP_LIBS := $(shell $(PKGCONF) --libs libcryptsetup) -LIBKEYUTILS_CFLAGS := $(shell $(PKGCONF) --cflags libkeyutils) -LIBKEYUTILS_LIBS := $(shell $(PKGCONF) --libs libkeyutils) -CFLAGS += $(BLKID_CFLAGS) $(LIBKMOD_CFLAGS) $(CRYPTSETUP_CFLAGS) $(LIBKEYUTILS_CFLAGS) -LIBS = $(BLKID_LIBS) $(LIBKMOD_LIBS) $(CRYPTSETUP_LIBS) $(LIBKEYUTILS_LIBS) +CFLAGS += $(BLKID_CFLAGS) $(LIBKMOD_CFLAGS) $(CRYPTSETUP_CFLAGS) +LIBS = $(BLKID_LIBS) $(LIBKMOD_LIBS) $(CRYPTSETUP_LIBS) %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< diff --git a/initramfs-init.in b/initramfs-init.in index 89eb9dd..452921d 100755 --- a/initramfs-init.in +++ b/initramfs-init.in @@ -371,7 +371,7 @@ $MOCK mount -t tmpfs -o nodev,nosuid,noexec shm /dev/shm # acpi_osi="!Windows 2006" xen-pciback.hide=(01:00.0) set -- $(cat "$ROOT"/proc/cmdline) -myopts="alpine_dev autodetect autoraid chart cryptroot cryptdm cryptheader cryptoffset +myopts="alpine_dev autodetect autoraid chart cryptroot cryptdm cryptheader cryptoffset cryptprompt cryptdiscards cryptkey debug_init dma init init_args keep_apk_new modules ovl_dev pkgs quiet root_size root usbdelay ip alpine_repo apkovl alpine_start splash blacklist overlaytmpfs overlaytmpfsflags rootfstype rootflags nbd resume s390x_net @@ -522,6 +522,9 @@ if [ -n "$KOPT_cryptroot" ]; then elif [ -n "$KOPT_cryptkey" ]; then cryptopts="$cryptopts -k ${KOPT_cryptkey}" fi + if [ -n "$KOPT_cryptprompt" ]; then + cryptopts="$cryptopts -P ${KOPT_cryptprompt}" + fi fi if [ -n "$KOPT_nbd" ]; then @@ -535,16 +538,9 @@ ln -s /proc/mounts "$ROOT"/etc/mtab # check if root=... was set if [ -n "$KOPT_root" ]; then - keyctl newring hackweek @u - keyctl chown %:hackweek 1000 - keyctl setperm %:hackweek 0x3f3f3f3f - keyid=$(keyctl add user hackweek "the-secret" %:hackweek) - keyctl chown "$keyid" 1000 - keyctl setperm "$keyid" 0x3f3f3f3f - # run nlplug-findfs before SINGLEMODE so we load keyboard drivers ebegin "Mounting root" - $MOCK nlplug-findfs -i "$keyid" $cryptopts -p /sbin/mdev ${KOPT_debug_init:+-d} \ + $MOCK nlplug-findfs $cryptopts -p /sbin/mdev ${KOPT_debug_init:+-d} \ ${KOPT_uevent_buf_size:+-U $KOPT_uevent_buf_size} \ $KOPT_root diff --git a/nlplug-findfs/nlplug-findfs.c b/nlplug-findfs/nlplug-findfs.c index 64b7fa5..153ed20 100644 --- a/nlplug-findfs/nlplug-findfs.c +++ b/nlplug-findfs/nlplug-findfs.c @@ -40,7 +40,6 @@ #include #include #include -#include #define MAX_EVENT_TIMEOUT 5000 #define DEFAULT_EVENT_TIMEOUT 250 @@ -60,8 +59,6 @@ static char *default_envp[2]; char *argv0; static int use_mdadm, use_lvm, use_zpool; -static long keyid; - #if defined(DEBUG) #include static void dbg(const char *fmt, ...) @@ -313,6 +310,7 @@ struct cryptdev { char *device; char *name; char *key; + char *prompt; char devnode[256]; }; @@ -608,6 +606,48 @@ static void *cryptsetup_thread(void *data) goto free_out; } + if (!stat(c->crypt.data.prompt, &st)) { + int fd[2]; + pid_t pid; + char pass[1024]; + + if (pipe(fd) == -1) { + warn("pipe"); + goto free_out; + } + + pid = fork(); + if (pid < 0) { + warn("fork"); + goto free_out; + } + + if (pid == 0) { + close(fd[0]); + dup2(fd[1], 3); + close(fd[1]); + execlp(c->crypt.data.prompt, c->crypt.data.prompt, NULL); + warn("executing prompt %s", c->crypt.data.prompt); + } + + close(fd[1]); + read(fd[0], pass, sizeof(pass)); + + wait(NULL); + close(fd[0]); + + pthread_mutex_lock(&c->crypt.mutex); + r = crypt_activate_by_passphrase(cd, c->crypt.data.name, + CRYPT_ANY_SLOT, + pass, strlen(pass), + c->crypt.flags); + pthread_mutex_unlock(&c->crypt.mutex); + memset(pass, 0, sizeof(pass)); /* wipe pass after use */ + + if (r >= 0) + goto free_out; + } + while (passwd_tries > 0) { char pass[1024]; @@ -624,18 +664,11 @@ static void *cryptsetup_thread(void *data) pass, strlen(pass), c->crypt.flags); pthread_mutex_unlock(&c->crypt.mutex); + memset(pass, 0, sizeof(pass)); /* wipe pass after use */ - if (r >= 0) { - printf("The keyid for hackweek is %ld\n", keyid); - if (keyctl_update(keyid, pass, strlen(pass)) < 0) { - printf("error updating keyring\n"); - } - - memset(pass, 0, sizeof(pass)); /* wipe pass after use */ + if (r >= 0) goto free_out; - } - memset(pass, 0, sizeof(pass)); /* wipe pass after use */ printf("No key available with this passphrase.\n"); } printf("Mounting %s failed, amount of tries exhausted.\n", c->crypt.data.devnode); @@ -1286,6 +1319,7 @@ int main(int argc, char *argv[]) { "crypt-header", required_argument, NULL, 'H'}, { "crypt-key", required_argument, NULL, 'k'}, { "crypt-name", required_argument, NULL, 'm'}, + { "crypt-prompt", required_argument, NULL, 'P'}, { "allow-not-found", required_argument, NULL, 'n'}, { "crypt-offset", required_argument, NULL, 'o'}, { "crypt-discards", no_argument, NULL, 'D'}, @@ -1296,7 +1330,7 @@ int main(int argc, char *argv[]) { "uevent-buffer-size", required_argument, NULL, 'U'}, }; - int c = getopt_long(argc, argv, "a:b:c:hH:k:m:no:Ddf:p:t:U:i:", options, NULL); + int c = getopt_long(argc, argv, "a:b:c:hH:k:m:no:Ddf:p:t:U:P:", options, NULL); if (c == -1) break; @@ -1322,15 +1356,14 @@ int main(int argc, char *argv[]) case 'h': usage(0); break; - case 'i': - keyid = atoi(optarg); - break; case 'k': conf.crypt.data.key = optarg; break; case 'm': conf.crypt.data.name = optarg; break; + case 'P': + conf.crypt.data.prompt = optarg; case 'n': not_found_is_ok = 1; break; -- 2.45.2