diff --git a/README.md b/README.md index ab4a0ba..6c6e0b2 100644 --- a/README.md +++ b/README.md @@ -73,9 +73,9 @@ No SHA256 hashes file available. Skipping SHA256 hash validation Installation of driftctl v0.2.3 successful. To make this your default version, run 'dctlenv use 0.2.3' ``` -For signed version of driftctl (starting v0.4.0) you can now install and verify digital signature with dctlenv. +For signed version of driftctl (starting v0.10.0) you can now install and verify digital signature with dctlenv. -You will need first to import the public key of CloudSkiff and then use the environment variable `DCTLENV_PGP`. +You just need to import the public key of CloudSkiff and have the gpg binary already installed. ```console # Import key @@ -85,15 +85,15 @@ gpg: Total number processed: 1 gpg: imported: 1 # Install and verify signature -$ DCTLENV_PGP=1 dctlenv install 0.4.0 -Installing driftctl v0.4.0 -Downloading release tarball from https://github.com/snyk/driftctl/releases/download/v0.4.0/driftctl_darwin_amd64 +$ dctlenv install 0.10.0 +Installing driftctl v0.10.0 +Downloading release tarball from https://github.com/snyk/driftctl/releases/download/v0.10.0/driftctl_darwin_amd64 ######################################################################################################################## 100.0% -Downloading SHA256 hashes file from https://github.com/snyk/driftctl/releases/download/v0.4.0/driftctl_SHA256SUMS +Downloading SHA256 hashes file from https://github.com/snyk/driftctl/releases/download/v0.10.0/driftctl_SHA256SUMS SHA256 hash matched! -Downloading SHA256 hashes signature file from https://github.com/snyk/driftctl/releases/download/v0.4.0/driftctl_SHA256SUMS.gpg +Downloading SHA256 hashes signature file from https://github.com/snyk/driftctl/releases/download/v0.10.0/driftctl_SHA256SUMS.gpg PGP signature matched! -Installation of driftctl v0.4.0 successful. To make this your default version, run 'dctlenv use 0.4.0' +Installation of driftctl v0.10.0 successful. To make this your default version, run 'dctlenv use 0.10.0' ``` ### `dctlenv use []` @@ -267,7 +267,6 @@ You can configure how `dctlenv` operates with the following settings: | `DCTLENV_ROOT` | | Defines the directory under which dctlenv resides
Current value shown by `dctlenv root` | | `DCTLENV_ARCH` | `amd64` | Architecture other than the default amd64 can be specified | | `DCTLENV_DEBUG` | `0` | Outputs debug information | -| `DCTLENV_PGP` | `0` | Verify digital signatures | | `DCTLENV_CURL` | `0` | Curl download progress bar, 0 will run a -# curl and 1 will run a -s curl | ## Contributors ✨ diff --git a/lib/utils.sh b/lib/utils.sh index 307527d..22b0154 100755 --- a/lib/utils.sh +++ b/lib/utils.sh @@ -15,3 +15,9 @@ curlw() { curl $TLS_OPT "$@" } export -f curlw + +# Check if one version is lower or equal to another version +version_le() { + [ "$1" = "`echo -e "$1\n$2" | sort -V | head -n 1`" ] +} +export -f version_le diff --git a/libexec/dctlenv-install b/libexec/dctlenv-install index 9758de2..97141c4 100755 --- a/libexec/dctlenv-install +++ b/libexec/dctlenv-install @@ -53,6 +53,14 @@ case "${DCTLENV_CURL:-0}" in ;; esac +# By default we enable the PGP verification unless the +# version is below or equal to 0.9.1 +pgp=1 +if version_le $version "0.9.1"; then + pgp=0 +fi + +driftctl_key="0xACC776A79C824EBD" driftctl_url="https://github.com/snyk/driftctl/releases/download" echo "Installing driftctl v$version" @@ -72,33 +80,42 @@ if [[ -f "$dst_path/driftctl_SHA256SUMS" ]]; then else echo 'No sha256sum tool available. Skipping SHA256 hash validation' fi - if [ "${DCTLENV_PGP:-0}" -eq 0 ]; then + if [ $pgp -eq 0 ]; then $(rm "$dst_path/driftctl_SHA256SUMS") fi else echo 'No SHA256 hashes file available. Skipping SHA256 hash validation' fi -if [ "${DCTLENV_PGP:-0}" -gt 0 ]; then - echo "Downloading SHA256 hashes signature file from $driftctl_url/v$version/driftctl_SHA256SUMS.gpg" - $(curlw -s -f -L -o "$dst_path/driftctl_SHA256SUMS.gpg" "$driftctl_url/v$version/driftctl_SHA256SUMS.gpg") || log_debug 'SHA256 hashes signature download failed' +bin_is_verified=0 +if [ $pgp -eq 1 ]; then + gpg_bin="$(command -v gpg 2>/dev/null)" + if [[ -n "$gpg_bin" ]]; then + # Check if we have the key to verify the signature + ("$gpg_bin" --list-keys $driftctl_key) &>/dev/null \ + && has_key=1 \ + || has_key=0 + if [ $has_key -eq 1 ]; then + echo "Downloading SHA256 hashes signature file from $driftctl_url/v$version/driftctl_SHA256SUMS.gpg" + $(curlw -s -f -L -o "$dst_path/driftctl_SHA256SUMS.gpg" "$driftctl_url/v$version/driftctl_SHA256SUMS.gpg") || log_debug 'SHA256 hashes signature download failed' - if [[ -f "$dst_path/driftctl_SHA256SUMS.gpg" ]]; then - gpg_bin="$(command -v gpg 2>/dev/null)" - if [[ -n "$gpg_bin" ]]; then - ("$gpg_bin" --verify "$dst_path/driftctl_SHA256SUMS.gpg" "$dst_path/driftctl_SHA256SUMS") &>/dev/null \ - && echo "PGP signature matched!" \ - || log_error 'PGP signature rejected!' - else - echo 'No gpg tool available. Skipping signature validation' + if [[ -f "$dst_path/driftctl_SHA256SUMS.gpg" ]]; then + ("$gpg_bin" --verify "$dst_path/driftctl_SHA256SUMS.gpg" "$dst_path/driftctl_SHA256SUMS") &>/dev/null \ + && echo "PGP signature matched!" && bin_is_verified=1 \ + || log_error 'PGP signature rejected!' + $(rm "$dst_path/driftctl_SHA256SUMS.gpg") + else + echo 'No SHA256 hashes signature file available. Skipping signature validation' + fi fi - $(rm "$dst_path/driftctl_SHA256SUMS.gpg") - else - echo 'No SHA256 hashes signature file available. Skipping signature validation' fi $(rm "$dst_path/driftctl_SHA256SUMS") fi +if [ $bin_is_verified -eq 0 ]; then + echo 'Unable to verify the authenticity of the binary' +fi + $(mv "$dst_path/driftctl_$os" "$dst_path/driftctl") $(chmod +x "$dst_path/driftctl") || log_error "Fail to make the binary executable" diff --git a/test/dctlenv-install.bats b/test/dctlenv-install.bats index 9205b0d..6ae63e5 100644 --- a/test/dctlenv-install.bats +++ b/test/dctlenv-install.bats @@ -6,7 +6,6 @@ setup() { export DCTLENV_TMPDIR="$BATS_TMPDIR/dctlenv" export DCTLENV_TMPDIR="$(mktemp -d "$DCTLENV_TMPDIR.XXX" 2>/dev/null || echo "$DCTLENV_TMPDIR")" export DCTLENV_ROOT="$DCTLENV_TMPDIR" - export DCTLENV_PGP=0 dctlenv-list-remote() { echo "0.1.0 @@ -16,9 +15,15 @@ setup() { 0.2.2 0.2.3 0.3.0 -0.3.1" +0.3.1 +0.10.0" } export -f dctlenv-list-remote; + + version_le() { + [ "$1" = "`echo -e "$1\n$2" | sort -V | head -n 1`" ] + } + export -f version_le } @test "dctlenv install []: prints an error message if we try to install more than one version" { @@ -83,6 +88,7 @@ Installing driftctl v0.3.1 Downloading release tarball from https://github.com/snyk/driftctl/releases/download/v0.3.1/driftctl_linux_amd64 Downloading SHA256 hashes file from https://github.com/snyk/driftctl/releases/download/v0.3.1/driftctl_SHA256SUMS No SHA256 hashes file available. Skipping SHA256 hash validation +Unable to verify the authenticity of the binary Fail to make the binary executable OUT refute [ -e "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS" ] @@ -105,6 +111,7 @@ Installing driftctl v0.3.1 Downloading release tarball from https://github.com/snyk/driftctl/releases/download/v0.3.1/driftctl_linux_amd64 Downloading SHA256 hashes file from https://github.com/snyk/driftctl/releases/download/v0.3.1/driftctl_SHA256SUMS No SHA256 hashes file available. Skipping SHA256 hash validation +Unable to verify the authenticity of the binary Installation of driftctl v0.3.1 successful. To make this your default version, run 'dctlenv use 0.3.1' OUT refute [ -e "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS" ] @@ -148,6 +155,7 @@ Installing driftctl v0.3.1 Downloading release tarball from https://github.com/snyk/driftctl/releases/download/v0.3.1/driftctl_linux_amd64 Downloading SHA256 hashes file from https://github.com/snyk/driftctl/releases/download/v0.3.1/driftctl_SHA256SUMS SHA256 hash matched! +Unable to verify the authenticity of the binary Installation of driftctl v0.3.1 successful. To make this your default version, run 'dctlenv use 0.3.1' OUT refute [ -e "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS" ] @@ -170,6 +178,7 @@ Installing driftctl v0.3.1 Downloading release tarball from https://github.com/snyk/driftctl/releases/download/v0.3.1/driftctl_linux_amd64 Downloading SHA256 hashes file from https://github.com/snyk/driftctl/releases/download/v0.3.1/driftctl_SHA256SUMS SHA256 hash matched! +Unable to verify the authenticity of the binary Installation of driftctl v0.3.1 successful. To make this your default version, run 'dctlenv use 0.3.1' OUT refute [ -e "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS" ] @@ -178,101 +187,112 @@ OUT @test "dctlenv install []: prints a success message if it can install the latest version" { uname() { echo "Linux"; }; export -f uname; curlw() { - mkdir -p "$DCTLENV_TMPDIR/versions/0.3.1" - touch "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_linux_amd64" - (cd "$DCTLENV_TMPDIR/versions/0.3.1"; sha256sum * > "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS") + mkdir -p "$DCTLENV_TMPDIR/versions/0.10.0" + touch "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_linux_amd64" + (cd "$DCTLENV_TMPDIR/versions/0.10.0"; sha256sum * > "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_SHA256SUMS") exit 0 }; export -f curlw; + gpg() { exit 0; }; export -f gpg; run dctlenv install latest assert_success assert_output <]: prints a missing hashes signature file" { uname() { echo "Linux"; }; export -f uname; curlw() { - mkdir -p "$DCTLENV_TMPDIR/versions/0.3.1" - touch "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_linux_amd64" - (cd "$DCTLENV_TMPDIR/versions/0.3.1"; sha256sum * > "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS") + mkdir -p "$DCTLENV_TMPDIR/versions/0.10.0" + touch "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_linux_amd64" + (cd "$DCTLENV_TMPDIR/versions/0.10.0"; sha256sum * > "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_SHA256SUMS") exit 0 }; export -f curlw; + gpg() { exit 0; }; export -f gpg; - DCTLENV_PGP=1 run dctlenv install 0.3.1 + run dctlenv install 0.10.0 assert_success assert_output <]: prints an error message if the PGP signature check fails" { uname() { echo "Linux"; }; export -f uname; curlw() { - mkdir -p "$DCTLENV_TMPDIR/versions/0.3.1" - touch "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_linux_amd64" - (cd "$DCTLENV_TMPDIR/versions/0.3.1"; sha256sum * > "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS") - touch "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS.gpg" + mkdir -p "$DCTLENV_TMPDIR/versions/0.10.0" + touch "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_linux_amd64" + (cd "$DCTLENV_TMPDIR/versions/0.10.0"; sha256sum * > "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_SHA256SUMS") + touch "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_SHA256SUMS.gpg" exit 0 }; export -f curlw; - gpg() { exit 1; }; export -f gpg; + gpg() { + if [ $1 == "--verify" ]; then + exit 1 + fi + exit 0 + }; export -f gpg; - DCTLENV_PGP=1 run dctlenv install 0.3.1 + run dctlenv install 0.10.0 assert_failure assert_output <]: prints a success message if the PGP signature check matches" { uname() { echo "Linux"; }; export -f uname; curlw() { - mkdir -p "$DCTLENV_TMPDIR/versions/0.3.1" - touch "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_linux_amd64" - (cd "$DCTLENV_TMPDIR/versions/0.3.1"; sha256sum * > "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS") - touch "$DCTLENV_TMPDIR/versions/0.3.1/driftctl_SHA256SUMS.gpg" + mkdir -p "$DCTLENV_TMPDIR/versions/0.10.0" + touch "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_linux_amd64" + (cd "$DCTLENV_TMPDIR/versions/0.10.0"; sha256sum * > "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_SHA256SUMS") + touch "$DCTLENV_TMPDIR/versions/0.10.0/driftctl_SHA256SUMS.gpg" exit 0 }; export -f curlw; gpg() { exit 0; }; export -f gpg; - DCTLENV_PGP=1 run dctlenv install 0.3.1 + run dctlenv install 0.10.0 assert_success assert_output <