Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ gri remove <name> <version> # remove an installed version
|---|---|
| `--user` / `-u` | Install in `~/.local/opt` and `~/.local/bin` (no sudo required) |
| `--dry-run` / `-n` | Print what would happen without doing anything |
| `--allow-missing-checksum` / `-k` | Proceed even if the release provides no checksum file |

Flags can appear anywhere in the command line and can be combined.

Expand All @@ -89,6 +90,9 @@ sudo gri install yannh/kubeconform
gri --user install gruntwork-io/terragrunt
gri --user install yannh/kubeconform

# release with no checksum file (explicit opt-out)
gri --allow-missing-checksum install stackrox/kube-linter

# preview before installing
gri --dry-run install junegunn/fzf
gri --user --dry-run install gruntwork-io/terragrunt
Expand Down
17 changes: 12 additions & 5 deletions gri
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ BIN_DIR="${GRI_BIN_DIR:-/usr/local/bin}"
GITHUB_API="https://api.github.com"
DRY_RUN=0
USER_MODE=0
ALLOW_MISSING_CHECKSUM=0
tmp_dir=""

# build curl auth header from GITHUB_TOKEN if set
Expand Down Expand Up @@ -417,7 +418,11 @@ cmd_install() {
curl -sfL -o "${tmp_dir}/checksums" "$ck_url"
verify_checksum "${tmp_dir}/${asset_name}" "$ck_algo" "${tmp_dir}/checksums" "$asset_name"
else
echo "warning: no checksum file found in release assets, skipping verification"
if (( ALLOW_MISSING_CHECKSUM )); then
echo "warning: --allow-missing-checksum set, proceeding without verification" >&2
else
die "no checksum file found in release assets\n → use --allow-missing-checksum to install without verification"
fi
fi

case "${asset_name,,}" in
Expand Down Expand Up @@ -534,8 +539,9 @@ usage:
gri [flags] remove <name> <version> remove an installed version

flags (combinable, any position):
--user / -u install in ~/.local/opt and ~/.local/bin (no sudo required)
--dry-run / -n print what would happen without doing it
--user / -u install in ~/.local/opt and ~/.local/bin (no sudo required)
--dry-run / -n print what would happen without doing it
--allow-missing-checksum / -k proceed even if the release provides no checksum file

environment:
GRI_OPT_DIR override install base (/opt with default, ~/.local/opt with --user)
Expand All @@ -560,8 +566,9 @@ EOF
args=()
for arg in "$@"; do
case "$arg" in
--dry-run|-n) DRY_RUN=1 ;;
--user|-u) USER_MODE=1 ;;
--dry-run|-n) DRY_RUN=1 ;;
--user|-u) USER_MODE=1 ;;
--allow-missing-checksum|-k) ALLOW_MISSING_CHECKSUM=1 ;;
*) args+=("$arg") ;;
esac
done
Expand Down
39 changes: 36 additions & 3 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,40 @@ check_output "-n is alias for --dry-run" "\[dry-run\]" \
check_output "--dry-run flag accepted anywhere" "\[dry-run\]" \
"$GRI" install --dry-run junegunn/fzf

# ── 5. prefix comparison — staging-evil attack ────────────────────────────────
# ── 5. allow-missing-checksum ────────────────────────────────────────────────

section "allow-missing-checksum"

_ck_assets_none='[{"name":"tool-linux-amd64.tar.gz","browser_download_url":"http://x/tool.tar.gz"}]'
_ck_assets_present='[{"name":"tool-linux-amd64.tar.gz","browser_download_url":"http://x/tool.tar.gz"},{"name":"checksums.txt","browser_download_url":"http://x/checksums.txt"}]'

check_fails "find_checksum_asset: no checksum asset returns 1" \
find_checksum_asset "$_ck_assets_none" "tool-linux-amd64.tar.gz"

check "find_checksum_asset: checksums.txt present returns 0" \
find_checksum_asset "$_ck_assets_present" "tool-linux-amd64.tar.gz"

check_output "missing checksum without flag: error mentions --allow-missing-checksum" \
"allow-missing-checksum" \
bash -c "source '$GRI'
assets=\$'[{\"name\":\"t.tar.gz\",\"browser_download_url\":\"http://x\"}]'
if ! find_checksum_asset \"\$assets\" 't.tar.gz'; then
(( ALLOW_MISSING_CHECKSUM )) \
&& echo 'warning: --allow-missing-checksum set, proceeding without verification' >&2 \
|| die 'no checksum file found in release assets\n → use --allow-missing-checksum to install without verification'
fi"

check_output "missing checksum with --allow-missing-checksum: warning printed" \
"proceeding without verification" \
bash -c "source '$GRI'; ALLOW_MISSING_CHECKSUM=1
assets=\$'[{\"name\":\"t.tar.gz\",\"browser_download_url\":\"http://x\"}]'
if ! find_checksum_asset \"\$assets\" 't.tar.gz'; then
(( ALLOW_MISSING_CHECKSUM )) \
&& echo 'warning: --allow-missing-checksum set, proceeding without verification' >&2 \
|| die 'no checksum file found'
fi"

# ── 6. prefix comparison — staging-evil attack ───────────────────────────────

section "prefix comparison"

Expand All @@ -105,7 +138,7 @@ check_fails "/stagingX is rejected" _prefix_check "/staging" "/stag
check_fails "absolute escape is rejected" _prefix_check "/staging" "/etc/passwd"
check_fails "sibling dir is rejected" _prefix_check "/staging" "/tmp/other"

# ── 6. archive security ───────────────────────────────────────────────────────
# ── 7. archive security ───────────────────────────────────────────────────────

section "archive security"

Expand Down Expand Up @@ -200,7 +233,7 @@ tar -czf "$TMPDIR_SEC/clean.tar.gz" -C "$TMPDIR_SEC/clean-src" mytool
_expect_allow "tar: clean archive is allowed" \
"$TMPDIR_SEC/clean.tar.gz" tgz

# ── 7. smoke install (real network) ──────────────────────────────────────────
# ── 8. smoke install (real network) ──────────────────────────────────────────

section "smoke install (network)"

Expand Down
Loading