|
18 | 18 |
|
19 | 19 | set -euo pipefail |
20 | 20 |
|
21 | | -REPO_HTTPS="https://github.com/alexgreensh/token-optimizer.git" |
22 | | -REPO_SSH="git@github.com:alexgreensh/token-optimizer.git" |
| 21 | +GITHUB_REPO="alexgreensh/token-optimizer" |
| 22 | +REPO_HTTPS="https://github.com/${GITHUB_REPO}.git" |
| 23 | +REPO_SSH="git@github.com:${GITHUB_REPO}.git" |
23 | 24 | INSTALL_DIR="${HOME}/.claude/token-optimizer" |
24 | 25 | SKILL_DIR="${HOME}/.claude/skills" |
25 | 26 |
|
@@ -63,6 +64,11 @@ if ! command -v git &>/dev/null; then |
63 | 64 | fi |
64 | 65 | info "git OK" |
65 | 66 |
|
| 67 | +# curl (needed for out-of-band checksum verification) |
| 68 | +if ! command -v curl &>/dev/null; then |
| 69 | + fail "curl not found. Install curl first." |
| 70 | +fi |
| 71 | + |
66 | 72 | # Claude Code directory |
67 | 73 | if [ ! -d "${HOME}/.claude" ]; then |
68 | 74 | fail "~/.claude/ not found. Install Claude Code first: https://claude.ai/download" |
@@ -152,29 +158,56 @@ else |
152 | 158 | fi |
153 | 159 |
|
154 | 160 | # ── Integrity Verification ──────────────────────────────────── |
155 | | -# Checksums verify file integrity post-clone/pull. |
156 | | -# For full supply-chain security, pin to a specific commit SHA in your |
157 | | -# deployment pipeline instead of relying on HEAD. |
158 | | -# This check is advisory: it warns but does not block, because the |
159 | | -# CHECKSUMS.sha256 file itself is updated with each code change. |
160 | | - |
161 | | -CHECKSUM_FILE="${INSTALL_DIR}/CHECKSUMS.sha256" |
162 | | -if [ -f "$CHECKSUM_FILE" ]; then |
163 | | - info "Verifying file integrity..." |
164 | | - ( |
165 | | - cd "$INSTALL_DIR" || exit 1 |
166 | | - if sha256sum -c "$CHECKSUM_FILE" --quiet 2>/dev/null || \ |
167 | | - shasum -a 256 -c "$CHECKSUM_FILE" --quiet 2>/dev/null; then |
168 | | - printf "${GREEN}>${NC} Integrity check passed\n" |
169 | | - else |
170 | | - printf "${YELLOW}!${NC} WARNING: Integrity check failed or checksums are outdated.\n" |
171 | | - printf "${YELLOW}!${NC} This is expected immediately after a code update (checksums\n" |
172 | | - printf "${YELLOW}!${NC} are regenerated with each release). If you did not just\n" |
173 | | - printf "${YELLOW}!${NC} update, verify your clone manually: cd ${INSTALL_DIR} && git log --oneline -5\n" |
174 | | - fi |
175 | | - ) |
| 161 | +# Checksums are fetched from the GitHub release (out-of-band), NOT from |
| 162 | +# the repo tree. This prevents a single compromised commit from swapping |
| 163 | +# both code and checksums simultaneously. |
| 164 | +# Set TOKEN_OPTIMIZER_SKIP_VERIFY=1 to bypass (air-gapped installs). |
| 165 | + |
| 166 | +CHECKSUM_FILE="/tmp/token-optimizer-checksums-$$.sha256" |
| 167 | +trap 'rm -f "$CHECKSUM_FILE"' EXIT |
| 168 | + |
| 169 | +fetch_release_checksums() { |
| 170 | + local asset_url |
| 171 | + asset_url=$(curl -fsSL \ |
| 172 | + "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" \ |
| 173 | + 2>/dev/null \ |
| 174 | + | python3 -c ' |
| 175 | +import json, sys |
| 176 | +try: |
| 177 | + data = json.load(sys.stdin) |
| 178 | + for a in data.get("assets", []): |
| 179 | + if a["name"] == "CHECKSUMS.sha256": |
| 180 | + print(a["browser_download_url"]) |
| 181 | + break |
| 182 | +except Exception: |
| 183 | + pass |
| 184 | +' 2>/dev/null) |
| 185 | + |
| 186 | + if [ -z "$asset_url" ]; then |
| 187 | + return 1 |
| 188 | + fi |
| 189 | + |
| 190 | + curl -fsSL -o "$CHECKSUM_FILE" "$asset_url" 2>/dev/null && [ -s "$CHECKSUM_FILE" ] |
| 191 | +} |
| 192 | + |
| 193 | +if [ "${TOKEN_OPTIMIZER_SKIP_VERIFY:-}" = "1" ]; then |
| 194 | + warn "Skipping integrity verification (TOKEN_OPTIMIZER_SKIP_VERIFY=1)" |
176 | 195 | else |
177 | | - warn "CHECKSUMS.sha256 not found, skipping integrity check." |
| 196 | + info "Fetching checksums from GitHub release..." |
| 197 | + if fetch_release_checksums; then |
| 198 | + info "Verifying file integrity (out-of-band checksums)..." |
| 199 | + ( |
| 200 | + cd "$INSTALL_DIR" || exit 1 |
| 201 | + if sha256sum -c "$CHECKSUM_FILE" --quiet 2>/dev/null || \ |
| 202 | + shasum -a 256 -c "$CHECKSUM_FILE" --quiet 2>/dev/null; then |
| 203 | + printf "${GREEN}>${NC} Integrity check passed\n" |
| 204 | + else |
| 205 | + fail "Integrity check FAILED. Files do not match release checksums. Your install may be compromised. Re-clone from: https://github.com/${GITHUB_REPO}" |
| 206 | + fi |
| 207 | + ) |
| 208 | + else |
| 209 | + fail "Could not fetch checksums from GitHub release. Cannot verify file integrity. Check network connectivity or install manually from: https://github.com/${GITHUB_REPO}/releases" |
| 210 | + fi |
178 | 211 | fi |
179 | 212 |
|
180 | 213 | # Log the current commit SHA so users can audit which version is installed. |
|
0 commit comments