Browse Source

Merge upstream version 20

Christoph Biedl 1 year ago
parent
commit
eab03f02f9
33 changed files with 349 additions and 57 deletions
  1. 11 5
      .github/workflows/build.yml
  2. 3 1
      .github/workflows/differential-shellcheck.yml
  3. 1 1
      .github/workflows/install-dependencies
  4. 43 0
      .github/workflows/spellcheck.yml
  5. 1 1
      INSTALL.md
  6. 49 10
      README.md
  7. 1 1
      meson.build
  8. 8 0
      src/initramfs-tools/hooks/clevis.in
  9. 4 2
      src/initramfs-tools/scripts/local-bottom/clevis.in
  10. 17 0
      src/initramfs-tools/scripts/local-top/clevis.in
  11. 13 25
      src/luks/clevis-luks-common-functions.in
  12. 7 2
      src/luks/clevis-luks-unlock
  13. 3 0
      src/luks/clevis-luks-unlock.1.adoc
  14. 0 0
      src/luks/dracut/clevis-pin-null/meson.build
  15. 0 0
      src/luks/dracut/clevis-pin-null/module-setup.sh.in
  16. 0 0
      src/luks/dracut/clevis-pin-sss/meson.build
  17. 0 0
      src/luks/dracut/clevis-pin-sss/module-setup.sh.in
  18. 0 0
      src/luks/dracut/clevis-pin-tang/meson.build
  19. 0 0
      src/luks/dracut/clevis-pin-tang/module-setup.sh.in
  20. 0 0
      src/luks/dracut/clevis-pin-tpm2/meson.build
  21. 0 0
      src/luks/dracut/clevis-pin-tpm2/module-setup.sh.in
  22. 22 0
      src/luks/dracut/clevis/clevis-hook.sh.in
  23. 72 0
      src/luks/dracut/clevis/clevis-luks-unlocker
  24. 2 0
      src/luks/systemd/dracut/clevis/meson.build
  25. 13 4
      src/luks/systemd/dracut/clevis/module-setup.sh.in
  26. 0 0
      src/luks/dracut/meson.build
  27. 4 2
      src/luks/meson.build
  28. 0 2
      src/luks/systemd/dracut/clevis/clevis-hook.sh.in
  29. 0 1
      src/luks/systemd/meson.build
  30. 3 0
      src/luks/tests/meson.build
  31. 68 0
      src/luks/tests/unlock-arbitrary-parameter
  32. 3 0
      src/luks/udisks2/clevis-luks-udisks2.c
  33. 1 0
      src/pins/sss/clevis-decrypt-sss.c

+ 11 - 5
.github/workflows/build.yml

@@ -1,11 +1,17 @@
 ---
 name: build
 
-on: [push, pull_request]
+on:
+  push:
+    ignore-paths:
+      - '**.md'
+  pull_request:
+    ignore-paths:
+      - '**.md'
 
 jobs:
   build:
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-latest
     continue-on-error: ${{ ! matrix.stable }}
     strategy:
       matrix:
@@ -16,15 +22,15 @@ jobs:
           - debian:testing
           - debian:latest
           - ubuntu:rolling
-          - ubuntu:bionic
+          - ubuntu:latest
         stable: [true]
         include:
-          - os: fedora:rawhide
+          - os: quay.io/fedora/fedora:rawhide
             stable: false
           - os: ubuntu:devel
             stable: false
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v4
 
       - name: Show OS information
         run: cat /etc/os-release 2>/dev/null || echo /etc/os-release not available

+ 3 - 1
.github/workflows/differential-shellcheck.yml

@@ -5,6 +5,8 @@ name: Differential ShellCheck
 on:
   pull_request:
     branches: [master]
+    ignore-paths:
+      - '**.md'
 
 permissions:
   contents: read
@@ -19,7 +21,7 @@ jobs:
 
     steps:
       - name: Repository checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           fetch-depth: 0
 

+ 1 - 1
.github/workflows/install-dependencies

@@ -29,7 +29,7 @@ debian:*|ubuntu:*)
     done
     ;;
 
-fedora:*)
+*fedora:*)
     printf 'max_parallel_downloads=10\nfastestmirror=1\n' >> /etc/dnf/dnf.conf
     dnf -y clean all
     dnf -y --setopt=deltarpm=0 update

+ 43 - 0
.github/workflows/spellcheck.yml

@@ -0,0 +1,43 @@
+name: Spellcheck
+on: 
+  push:
+    # branches: [main]
+  pull_request:  
+jobs: 
+  spell-check:
+    name: Language tool & Misspell check
+    runs-on: ubuntu-latest
+    steps:
+      - name: check out code
+        uses: actions/checkout@v4
+      - name: running language tool 
+        uses: reviewdog/action-languagetool@v1
+        with:
+          github_token: ${{ secrets.github_token }}
+          # Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review].
+          reporter: github-check
+          # Change reporter level if you need.
+          level: warning
+          language: en-US
+          disabled_categories: 'TYPOS,TYPOGRAPHY,CASING'
+          disabled_rules: 'WHITESPACE_RULE,EN_QUOTES,DASH_RULE,WORD_CONTAINS_UNDERSCORE,UPPERCASE_SENTENCE_START,ARROWS,COMMA_PARENTHESIS_WHITESPACE,UNLIKELY_OPENING_PUNCTUATION,SENTENCE_WHITESPACE,CURRENCY,EN_UNPAIRED_BRACKETS,PHRASE_REPETITION,PUNCTUATION_PARAGRAPH_END,METRIC_UNITS_EN_US,ENGLISH_WORD_REPEAT_BEGINNING_RULE,DOUBLE_PUNCTUATION,'
+          enabled_only: 'false'
+          enabled_rules: ''
+          enabled_categories: ''
+          patterns: "**.md"
+            
+    
+    
+      - name: running misspell
+        # To perform misspell check even after the language tool test fails 
+        if: success() || failure()  
+        uses: reviewdog/action-misspell@v1
+        with:
+          github_token: ${{ secrets.github_token }}
+          locale: "US"
+          reporter: github-check
+          level: info
+          pattern: "**.md"
+          exclude: |
+            ./.git/*
+            ./.cache/*

+ 1 - 1
INSTALL.md

@@ -57,7 +57,7 @@ $ sudo ninja -C build install
 
 This will install Clevis to a location determined at configure time.
 
-See the output of `meson --help` for the available options. Typically
+See the output of `meson --help` for the available options. Typically,
 much won't be needed besides providing an alternative --prefix option at
 configure time, and maybe DESTDIR at install time if you're packaging for
 a distro.

+ 49 - 10
README.md

@@ -12,7 +12,9 @@ volumes.
 What does this look like? Well, the first step is encrypting some data. We do
 this with a simple command:
 
-    $ clevis encrypt PIN CONFIG < PLAINTEXT > CIPHERTEXT.jwe
+```bash
+$ clevis encrypt PIN CONFIG < PLAINTEXT > CIPHERTEXT.jwe
+```
 
 This command takes plaintext on standard input and produces an encrypted JWE
 object on standard output. Besides the plaintext, we need to specify two
@@ -64,8 +66,7 @@ advertisement is trusted.
 
 Clevis provides support to encrypt a key in a Trusted Platform Module 2.0 (TPM2)
 chip. The cryptographically-strong, random key used for encryption is encrypted
-using the TPM2 chip, and then at decryption time is decrypted using the TPM2 to
-allow clevis to decrypt the secret stored in the JWE.
+using the TPM2 chip, and is decrypted using TPM2 at the time of decryption to allow clevis to decrypt the secret stored in the JWE.
 
 For example:
 
@@ -88,11 +89,11 @@ recursively). Additionally, you define the threshold `t`. If at least `t`
 pieces can be decrypted, then the encryption key can be recovered and
 decryption can succeed.
 
-Here is an example where we use the SSS pin with both the Tang and HTTP pins:
+Here is an example where we use the SSS pin with both the Tang and TPM2 pins:
 
 ```bash
 $ echo hi | clevis encrypt sss \
-'{"t": 2, "pins": {"http": {"url": "http://server.local/key"}, "tang": {"url": "http://tang.local"}}}' \
+'{"t": 2, "pins": {"tpm2": {"pcr_ids": "0"}, "tang": {"url": "http://tang.local"}}}' \
 > hi.jwe
 ```
 
@@ -100,16 +101,16 @@ In the above example, we define two child pins and have a threshold of 2.
 This means that during decryption **both** child pins must succeed in order for
 SSS itself to succeed.
 
-Here is another example where we use just the HTTP pin:
+Here is another example where we use just the Tang pin:
 
 ```bash
 $ echo hi | clevis encrypt sss \
-'{"t": 1, "pins": {"http": [{"url": "http://server1.local/key"}, {"url": "http://server1.local/key"}]}}' \
+'{"t": 1, "pins": {"tang": [{"url": "http://server1.local/key"}, {"url": "http://server2.local/key"}]}}' \
 > hi.jwe
 ```
 
-In this example, we define two child instances of the HTTP pin - each with its
-own configuration. Since we have a threshold of 1, if **either** of the HTTP
+In this example, we define two child instances of the Tang pin - each with its
+own configuration. Since we have a threshold of 1, if **either** of the Tang
 pin instances succeed during decryption, SSS will succeed.
 
 ### Binding LUKS Volumes
@@ -162,7 +163,7 @@ initramfs you will need to run:
 sudo update-initramfs -u -k 'all'
 ```
 
-Upon reboot it will behave exactly as if using Dracut.
+Upon reboot, it will behave exactly as if using Dracut.
 
 #### Unlocker: UDisks2
 
@@ -215,3 +216,41 @@ UDisks2 unlocker, respectively.
 ```bash
 $ sudo dnf install clevis clevis-dracut clevis-udisks2
 ```
+
+## Manual compilation
+
+As remarked in the previous section, **it is suggested not to install Clevis directly**.
+However, in case no Clevis packages exist for your Linux distribution, the steps to 
+manually compile and install Clevis are next ones:
+
+* Download latest version of the binaries (not that the latest version could change):
+```bash
+$ wget https://github.com/latchset/clevis/releases/download/v19/clevis-19.tar.xz
+```
+
+* Untar the binaries file:
+```bash
+$ tar Jxvf clevis-19.tar.xz 
+```
+
+* Create build directory and change path to it:
+```bash
+$ cd clevis-19
+$ mkdir build
+$ cd build
+```
+
+* Execute `meson` to setup compilation:
+```bash
+$ meson setup ..
+```
+
+* Compile with `ninja` command:
+```bash
+$ ninja
+```
+
+* Install with `ninja install` command (you will need root permissions for it):
+```bash
+$ sudo ninja install
+```

+ 1 - 1
meson.build

@@ -1,5 +1,5 @@
 project('clevis', 'c', license: 'GPL3+',
-  version: '19',
+  version: '20',
   default_options: 'c_std=c99'
 )
 

+ 8 - 0
src/initramfs-tools/hooks/clevis.in

@@ -95,3 +95,11 @@ bash_bin=$(find_binary "bash")
 copy_exec "${curl_bin}" || die 2 "Unable to copy ${curl_bin} to initrd image"
 copy_exec "${awk_bin}" || die 2 "Unable to copy ${awk_bin} to initrd image"
 copy_exec "${bash_bin}" || die 2 "Unable to copy ${bash_bin} to initrd image"
+
+# Copy latest versions of shared objects needed for DNS resolution
+for so in $(ldconfig -p | sed -nr 's/^\s*libnss_files\.so\.[0-9]+\s.*=>\s*//p'); do
+  copy_exec "${so}"
+done
+for so in $(ldconfig -p | sed -nr 's/^\s*libnss_dns\.so\.[0-9]+\s.*=>\s*//p'); do
+  copy_exec "${so}"
+done

+ 4 - 2
src/initramfs-tools/scripts/local-bottom/clevis.in

@@ -34,8 +34,10 @@ esac
 [ -s /run/clevis.pid ] || exit 0
 
 pid=$(cat /run/clevis.pid)
-ps -l | awk -v pid="$pid" '$4==pid { system("kill " $3) }'
-kill "$pid"
+child_pids=$(ps -o pid,ppid | awk -v pid="$pid" '$2==pid { print $1 }')
+for kill_pid in $pid $child_pids; do
+	kill "$kill_pid"
+done
 
 # Not really worried about downing extra interfaces: they will come up
 # during the actual boot. Might make this configurable later if needed.

+ 17 - 0
src/initramfs-tools/scripts/local-top/clevis.in

@@ -263,6 +263,23 @@ do_configure_networking() {
             echo "clevis: Warning: multiple network interfaces available but no ip= parameter provided."
         fi
         configure_networking
+
+        # Add DNS servers from configure_networking to /etc/resolv.conf
+        if [ ! -e /etc/resolv.conf ]; then
+            touch /etc/resolv.conf
+            for intf in /run/net-*.conf; do
+                . "${intf}"
+                if [ ! -z "${IPV4DNS0}" ] && [ "${IPV4DNS0}" != "0.0.0.0" ]; then
+                    echo nameserver "${IPV4DNS0}" >> /etc/resolv.conf
+                fi
+                if [ ! -z "${IPV4DNS1}" ] && [ "${IPV4DNS1}" != "0.0.0.0" ]; then
+                    echo nameserver "${IPV4DNS1}" >> /etc/resolv.conf
+                fi
+                if [ ! -z "${IPV6DNS0}" ]; then
+                    echo nameserver "${IPV6DNS0}" >> /etc/resolv.conf
+                fi
+            done
+        fi
     fi
 }
 

+ 13 - 25
src/luks/clevis-luks-common-functions.in

@@ -20,6 +20,11 @@
 
 CLEVIS_UUID="cb6e8904-81ff-40da-a84a-07ab9ab5715e"
 
+# Length, in bytes, used for password generated for LUKS key
+# This value corresponds to an entropy of 256 bits if the password
+# was generated by pwmake or similar tool
+JOSE_PASSWORD_LENGTH=40
+
 enable_debugging() {
     # Automatically enable debugging if in initramfs phase and rd.debug
     if [ -e /usr/lib/dracut-lib.sh ]; then
@@ -788,7 +793,7 @@ clevis_luks_add_key() {
     fi
     local pbkdf_args="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
 
-    printf '%s' "${input}" | cryptsetup luksAddKey --batch-mode \
+    printf '%s' "${input}" | cryptsetup luksAddKey --force-password --batch-mode \
                                          --key-slot "${SLT}" \
                                          "${DEV}" \
                                          ${pbkdf_args} \
@@ -818,11 +823,11 @@ clevis_luks_update_key() {
     local input extra_args=
     input="$(printf '%s\n%s' "${KEY}" "${NEWKEY}")"
     if [ -n "${KEYFILE}" ]; then
-        extra_args="$(printf -- '--key-file %s' "${KEYFILE}")"
+        extra_args="$(printf -- '--key-file %s --force-password' "${KEYFILE}")"
         input="$(printf '%s' "${NEWKEY}")"
     fi
     if [ -n "${EXISTING_TOKEN_ID}" ]; then
-        extra_args="$(printf -- '--token-id %s' "${EXISTING_TOKEN_ID}")"
+        extra_args="$(printf -- '--token-id %s --force-password' "${EXISTING_TOKEN_ID}")"
         input="$(printf '%s' "${NEWKEY}")"
     fi
 
@@ -884,26 +889,10 @@ clevis_luks_save_key_to_slot() {
 
 # clevis_luks_generate_key() generates a new key for use with clevis.
 clevis_luks_generate_key() {
-    local DEV="${1}"
-    [ -z "${DEV}" ] && return 1
-
-    local dump filter bits
-    local MAX_ENTROPY_BITS=256  # Maximum allowed by pwmake.
-    dump=$(cryptsetup luksDump "${DEV}")
-    if cryptsetup isLuks --type luks1 "${DEV}"; then
-        filter="$(echo "${dump}" | sed -rn 's|MK bits:[ \t]*([0-9]+)|\1|p')"
-    elif cryptsetup isLuks --type luks2 "${DEV}"; then
-        filter="$(echo -n "${dump}" | \
-                  sed -rn 's|^\s+Key:\s+([0-9]+) bits\s*$|\1|p')"
-    else
-        return 1
-    fi
-
-    bits="$(echo -n "${filter}" | sort -n | tail -n 1)"
-    if [ "${bits}" -gt "${MAX_ENTROPY_BITS}" ]; then
-        bits="${MAX_ENTROPY_BITS}"
-    fi
-    pwmake "${bits}"
+    local input
+    input=$(printf '{"kty":"oct","bytes":%s}' "${JOSE_PASSWORD_LENGTH}")
+    jose jwk gen --input="${input}" --output=- | \
+        jose fmt --json=- --object --get k --unquote=-
 }
 
 # clevis_luks_token_id_by_slot() returns the token ID linked to a
@@ -993,8 +982,7 @@ clevis_luks_do_bind() {
     fi
 
     local newkey jwe
-    if ! newkey="$(clevis_luks_generate_key "${DEV}")" \
-                   || [ -z "${newkey}" ]; then
+    if ! newkey="$(clevis_luks_generate_key)" || [ -z "${newkey}" ]; then
         echo "Unable to generate a new key" >&2
         return 1
     fi

+ 7 - 2
src/luks/clevis-luks-unlock

@@ -35,6 +35,10 @@ function usage() {
     echo "  -t SLT Test the passphrase for the given slot without unlocking"
     echo "         the device"
     echo
+    echo "  -o OPTS Pass options to underlying 'cryptsetup open'; be sure"
+    echo "          to quote the OPTS you pass, if they contain a space,"
+    echo "          etc."
+    echo
     exit 2
 }
 
@@ -43,11 +47,12 @@ if [ $# -eq 1 ] && [ "$1" == "--summary" ]; then
     exit 0
 fi
 
-while getopts ":d:n:t:" o; do
+while getopts ":d:n:t:o:" o; do
     case "$o" in
     d) DEV="$OPTARG";;
     n) NAME="$OPTARG";;
     t) SLT="$OPTARG";;
+    o) OPENARGS="$OPTARG";;
     *) usage;;
     esac
 done
@@ -75,5 +80,5 @@ else
         exit 1
     fi
 
-    echo -n "${pt}" | cryptsetup open -d- "${DEV}" "${NAME}"
+    echo -n "${pt}" | cryptsetup ${OPENARGS} open -d- "${DEV}" "${NAME}"
 fi

+ 3 - 0
src/luks/clevis-luks-unlock.1.adoc

@@ -29,6 +29,9 @@ provisioned Clevis policy. For example:
 * *-t* _SLT_ :
   Test the passphrase for the given slot without unlocking the device
 
+* *-o* _PARAMS_ :
+  Pass arbitrary parameters to cryptsetup; quote parameters as necessary
+
 == SEE ALSO
 
 link:clevis-luks-bind.1.adoc[*clevis-luks-bind*(1)]

src/luks/systemd/dracut/clevis-pin-null/meson.build → src/luks/dracut/clevis-pin-null/meson.build


src/luks/systemd/dracut/clevis-pin-null/module-setup.sh.in → src/luks/dracut/clevis-pin-null/module-setup.sh.in


src/luks/systemd/dracut/clevis-pin-sss/meson.build → src/luks/dracut/clevis-pin-sss/meson.build


src/luks/systemd/dracut/clevis-pin-sss/module-setup.sh.in → src/luks/dracut/clevis-pin-sss/module-setup.sh.in


src/luks/systemd/dracut/clevis-pin-tang/meson.build → src/luks/dracut/clevis-pin-tang/meson.build


src/luks/systemd/dracut/clevis-pin-tang/module-setup.sh.in → src/luks/dracut/clevis-pin-tang/module-setup.sh.in


src/luks/systemd/dracut/clevis-pin-tpm2/meson.build → src/luks/dracut/clevis-pin-tpm2/meson.build


src/luks/systemd/dracut/clevis-pin-tpm2/module-setup.sh.in → src/luks/dracut/clevis-pin-tpm2/module-setup.sh.in


+ 22 - 0
src/luks/dracut/clevis/clevis-hook.sh.in

@@ -0,0 +1,22 @@
+#!/bin/sh
+set -eu
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2020-2024 Red Hat, Inc.
+# Author: Sergio Correia <scorreia@redhat.com>
+#
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+@libexecdir@/clevis-luks-unlocker -l

+ 72 - 0
src/luks/dracut/clevis/clevis-luks-unlocker

@@ -0,0 +1,72 @@
+#!/bin/sh
+set -eu
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2020-2024 Red Hat, Inc.
+# Author: Sergio Correia <scorreia@redhat.com>
+#
+# Non-systemd clevis unlocker
+# Modifications sponsored by PMGA Tech LLP
+#
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+. clevis-luks-common-functions
+
+# Make sure to exit cleanly if SIGTERM is received.
+trap 'echo "Exiting due to SIGTERM" && exit 0' TERM
+
+loop=
+while getopts ":l" o; do
+    case "${o}" in
+    l) loop=true;;
+    *) ;;
+    esac
+done
+
+to_unlock() {
+    _devices=''
+    for _d in $(blkid -t TYPE=crypto_LUKS -o device); do
+        if ! bindings="$(clevis luks list -d "${_d}" 2>/dev/null)" \
+                         || [ -z "${bindings}" ]; then
+            continue
+        fi
+        _uuid="$(cryptsetup luksUUID "${_d}")"
+        if clevis_is_luks_device_by_uuid_open "${_uuid}"; then
+            continue
+        fi
+        _devices="$(printf '%s\n%s' "${_devices}" "${_d}")"
+    done
+    echo "${_devices}" | sed -e 's/^\n$//'
+}
+
+while true; do
+    for d in $(to_unlock); do
+        uuid="$(cryptsetup luksUUID "${d}")"
+        if ! clevis luks unlock -d "${d}"; then
+            echo "Unable to unlock ${d} (UUID=${uuid})" >&2
+            continue
+        fi
+        echo "Unlocked ${d} (UUID=${uuid}) successfully" >&2
+    done
+
+    [ "${loop}" != true ] && break
+    # Checking for pending devices to be unlocked.
+    if remaining=$(to_unlock) && [ -z "${remaining}" ]; then
+        break;
+    fi
+
+    sleep 0.5
+done

+ 2 - 0
src/luks/systemd/dracut/clevis/meson.build

@@ -16,6 +16,8 @@ if dracut.found()
     install_dir: dracutdir,
     configuration: data,
   )
+
+  install_data('clevis-luks-unlocker', install_dir: libexecdir)
 else
   warning('Will not install dracut module due to missing dependencies!')
 endif

+ 13 - 4
src/luks/systemd/dracut/clevis/module-setup.sh.in

@@ -19,7 +19,11 @@
 #
 
 depends() {
-    echo crypt systemd
+    local __depends=crypt
+    if dracut_module_included "systemd"; then
+        __depends=$(printf '%s systemd' "${__depends}")
+    fi
+    echo "${__depends}"
     return 255
 }
 
@@ -27,17 +31,22 @@ install() {
     if dracut_module_included "systemd"; then
         inst_multiple \
             $systemdsystemunitdir/clevis-luks-askpass.service \
-            $systemdsystemunitdir/clevis-luks-askpass.path
+            $systemdsystemunitdir/clevis-luks-askpass.path \
+            @SYSTEMD_REPLY_PASS@ \
+            @libexecdir@/clevis-luks-askpass
+
         systemctl -q --root "$initdir" add-wants cryptsetup.target clevis-luks-askpass.path
     else
         inst_hook initqueue/online 60 "$moddir/clevis-hook.sh"
         inst_hook initqueue/settled 60 "$moddir/clevis-hook.sh"
+        inst_multiple \
+            @libexecdir@/clevis-luks-unlocker \
+            clevis-luks-unlock \
+            blkid
     fi
 
     inst_multiple \
         /etc/services \
-        @SYSTEMD_REPLY_PASS@ \
-        @libexecdir@/clevis-luks-askpass \
         clevis-luks-common-functions \
         grep sed cut \
         clevis-decrypt \

src/luks/systemd/dracut/meson.build → src/luks/dracut/meson.build


+ 4 - 2
src/luks/meson.build

@@ -1,7 +1,6 @@
 
 luksmeta_data = configuration_data()
 luksmeta = dependency('luksmeta', version: '>=8', required: false)
-pwmake = find_program('pwmake', required: false)
 
 libcryptsetup = dependency('libcryptsetup', version: '>=2.0.4', required: false)
 if libcryptsetup.found()
@@ -33,8 +32,11 @@ clevis_luks_unbind = configure_file(input: 'clevis-luks-unbind.in',
                output: 'clevis-luks-unbind',
                configuration: luksmeta_data)
 
-if libcryptsetup.found() and luksmeta.found() and pwmake.found()
+if libcryptsetup.found() and luksmeta.found()
   subdir('systemd')
+  # systemd should come before dracut in order to set up
+  # variables like SYSTEMD_REPLY_PASS.
+  subdir('dracut')
   subdir('udisks2')
 
   bins += clevis_luks_unbind

+ 0 - 2
src/luks/systemd/dracut/clevis/clevis-hook.sh.in

@@ -1,2 +0,0 @@
-#!/bin/bash
-@libexecdir@/clevis-luks-askpass

+ 0 - 1
src/luks/systemd/meson.build

@@ -10,7 +10,6 @@ sd_reply_pass = find_program(
 
 if systemd.found() and sd_reply_pass.found()
   data.set('SYSTEMD_REPLY_PASS', sd_reply_pass.path())
-  subdir('dracut')
 
   unitdir = systemd.get_pkgconfig_variable('systemdsystemunitdir')
 

+ 3 - 0
src/luks/tests/meson.build

@@ -100,3 +100,6 @@ if luksmeta_data.get('OLD_CRYPTSETUP') == '0'
   test('backup-restore-luks2', find_program('backup-restore-luks2'), env: env, timeout: 120)
   test('pass-tang-luks2', find_program('pass-tang-luks2'), env: env, timeout: 60)
 endif
+
+test('unlock-arbitrary-parameter', find_program('unlock-arbitrary-parameter'), env: env)
+

+ 68 - 0
src/luks/tests/unlock-arbitrary-parameter

@@ -0,0 +1,68 @@
+#!/bin/bash -ex
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+TEST=$(basename "${0}")
+. tests-common-functions
+
+. clevis-luks-common-functions
+
+on_exit() {
+    [ ! -d "${TMP}" ] && return 0
+    tang_stop "${TMP}"
+    rm -rf "${TMP}"
+}
+
+trap 'on_exit' EXIT
+trap 'on_exit' ERR
+
+TMP="$(mktemp -d)"
+
+port=$(tang_new_random_port)
+tang_run "${TMP}" "${port}"
+
+url="http://localhost:${port}"
+adv="${TMP}/adv"
+tang_get_adv "${port}" "${adv}"
+
+cfg=$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")
+
+DEV="${TMP}/luks1-device"
+new_device "luks1" "${DEV}"
+
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
+    error "${TEST}: Bind should have succeeded."
+fi
+
+TESTPARAM="arbitrarytestparameter"
+
+#set up a "cryptsetup" function, to hijack the command
+cryptsetup () { 
+    #need to handle "cryptsetup isLuks" from clevis-luks-unlock, among others   
+    if [[ $1 == "isLuks" ]]; then
+        exit 0;
+    elif [[ $1 == "luksUUID" ]]; then
+        echo "TESTINGLUKSUUID"
+        exit 0;
+    else
+        echo "$*" | grep -q -- "${TESTPARAM}"
+        exit $?
+    fi
+}
+export -f cryptsetup
+
+if ! clevis-luks-unlock -o "$TESTPARAM" -d ${DEV} -n clevis_unlock_test; then
+    error "${TEST}: clevis luks unlock did not match arbitrary test parameter \"$TESTPARAM\"."
+fi

+ 3 - 0
src/luks/udisks2/clevis-luks-udisks2.c

@@ -591,6 +591,9 @@ main(int argc, char *const argv[])
         req.used = recv(pair[0], req.data, sizeof(req.data), 0);
         if (req.used < 1 || req.data[req.used - 1])
             break;
+        /* Technically, req.data is already NULL-terminated, but let's
+         * be explicit. */
+        req.data[req.used - 1] = '\0';
 
         if (crypt_init(&cd, req.data) < 0)
             goto next;

+ 1 - 0
src/pins/sss/clevis-decrypt-sss.c

@@ -275,6 +275,7 @@ main(int argc, char *argv[])
         const uint8_t *xy[t];
         size_t i = 0;
 
+        memset(xy, 0, t * sizeof(uint8_t));
         for (struct pin *pin = chldrn.next; pin != &chldrn; pin = pin->next) {
             if (pin->pt && i < (size_t) t)
                 xy[i++] = pin->pt;