Skip to content

Commit

Permalink
Verify sha256 of downloaded zip (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude authored Aug 15, 2023
1 parent 2cbdff0 commit b3b021d
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 58 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ DEPS_CLJ_TOOLS_VERSION=1.11.1.1165 bb clojure

[deps.clj](https://github.com/borkdude/deps.clj): a faithful port of the clojure CLI bash script to Clojure

## 1.11.1.1386
## 1.11.1.1403

- [#104](https://github.com/borkdude/deps.clj/issues/104): print repl-aliases in -Sdescribe
- Make installation of tools jar more robust using transaction file
- [#106](https://github.com/borkdude/deps.clj/issues/106): System deps.edn should be extracted on tools install
- Download tools jar from new Github releases link
- Verify downloaded zip file with .sha256 file

## 1.11.1.1347

Expand Down
68 changes: 50 additions & 18 deletions deps.bat
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
;; see https://github.com/clojure/brew-install/blob/1.11.1/CHANGELOG.md
(def ^:private version
(delay (or (System/getenv "DEPS_CLJ_TOOLS_VERSION")
"1.11.1.1386")))
"1.11.1.1403")))

(def ^:private cache-version "4")

Expand Down Expand Up @@ -386,15 +386,19 @@ For more info, see:
commit (-> (str/split version #"\.")
last
(Long/parseLong))
github-release? (>= commit 1386)]
github-release? (>= commit 1386)
verify-sha256 (>= commit 1403)
url (if github-release?
(format "https://github.com/clojure/brew-install/releases/download/%s/clojure-tools.zip" version)
(format "https://download.clojure.org/install/clojure-tools-%s.zip" version))]
{:ct-base-dir "ClojureTools"
:ct-error-exit-code 99
:ct-aux-files-names ["exec.jar" "example-deps.edn" "tools.edn"]
:ct-jar-name (format "clojure-tools-%s.jar" version)
:ct-url-str (if github-release?
(format "https://github.com/clojure/brew-install/releases/download/%s/clojure-tools.zip" version)
(format "https://download.clojure.org/install/clojure-tools-%s.zip" version))
:ct-zip-name "clojure-tools.zip"})))
:ct-url-str url
:ct-zip-name "clojure-tools.zip"
:sha256-url-str (when verify-sha256
(str url ".sha256"))})))

(def zip-invalid-msg
(str/join \n
Expand Down Expand Up @@ -500,7 +504,7 @@ public class ClojureToolsDownloader {
"Downloads `:url` zip file to `:dest` by invoking `java` with
`:proxy` options on a `.java` program file, and returns true on
success. Requires Java 11+ (JEP 330)."
[{:keys [url dest proxy-opts clj-jvm-opts]}]
[{:keys [url dest proxy-opts clj-jvm-opts sha256-url]}]
(let [dest-dir (.getCanonicalPath (io/file dest ".."))
dlr-path (clojure-tools-java-downloader-spit dest-dir)
java-cmd [(get-java-cmd) "-XX:-OmitStackTraceInFastThrow"]
Expand All @@ -513,6 +517,11 @@ public class ClojureToolsDownloader {
clj-jvm-opts
(proxy-jvm-opts proxy-opts)
[dlr-path url (str dest)]))})
(when sha256-url
(*aux-process-fn* {:cmd (vec (concat java-cmd
clj-jvm-opts
(proxy-jvm-opts proxy-opts)
[dlr-path sha256-url (str dest ".sha256")]))}))
(io/delete-file dlr-path true)
@success?*)))

Expand Down Expand Up @@ -544,27 +553,50 @@ public class ClojureToolsDownloader {
It calls `*exit-fn*` if it cannot download the archive, with
instructions how to manually download it."
[{:keys [out-dir debug proxy-opts clj-jvm-opts config-dir]}]
(let [{:keys [ct-error-exit-code ct-url-str ct-zip-name]} @clojure-tools-info*
(let [{:keys [ct-error-exit-code ct-url-str ct-zip-name sha256-url-str]} @clojure-tools-info*
dir (io/file out-dir)
zip-file (io/file out-dir ct-zip-name)
sha256-file (io/file (str zip-file ".sha256"))
transaction-start (io/file out-dir "TRANSACTION_START")]
(io/make-parents transaction-start)
(spit transaction-start "")
(when-not (.exists zip-file)
(warn "Downloading" ct-url-str "to" (str zip-file))
(or (when *clojure-tools-download-fn*
(when debug (warn "Attempting download using custom download function..."))
(*clojure-tools-download-fn* {:url ct-url-str :dest (str zip-file) :proxy-opts proxy-opts :clj-jvm-opts clj-jvm-opts}))
(when (seq clj-jvm-opts)
(when debug (warn "Attempting download using java subprocess... (requires Java11+)"))
(clojure-tools-download-java! {:url ct-url-str :dest (str zip-file) :proxy-opts proxy-opts :clj-jvm-opts clj-jvm-opts}))
(do (when debug (warn "Attempting direct download..."))
(clojure-tools-download-direct! {:url ct-url-str :dest zip-file}))
(let [res (or (when *clojure-tools-download-fn*
(when debug (warn "Attempting download using custom download function..."))
(*clojure-tools-download-fn* {:url ct-url-str :dest (str zip-file) :proxy-opts proxy-opts :clj-jvm-opts clj-jvm-opts :sha256-url sha256-url-str}))
(when (seq clj-jvm-opts)
(prn :via-java)
(when debug (warn "Attempting download using java subprocess... (requires Java11+)"))
(clojure-tools-download-java! {:url ct-url-str :dest (str zip-file) :proxy-opts proxy-opts :clj-jvm-opts clj-jvm-opts :sha256-url sha256-url-str}))
(do (when debug (warn "Attempting direct download..."))
(prn :via-tools-download-direct)
(let [res (clojure-tools-download-direct! {:url ct-url-str :dest zip-file})]
(when sha256-url-str
(clojure-tools-download-direct! {:url sha256-url-str :dest (str zip-file ".sha256")}))
res))
(*exit-fn* {:exit ct-error-exit-code
:message (str "Error: Cannot download Clojure tools."
" Please download manually from " ct-url-str
" to " (str (io/file dir ct-zip-name)))})
::passthrough)]
(when (and sha256-url-str (not *clojure-tools-download-fn*) (not (.exists sha256-file)) (not= ::passthrough res))
(*exit-fn* {:exit ct-error-exit-code
:message (str "Error: Cannot download Clojure tools."
:message (str "Expected sha256 file to be downloaded to: " sha256-file)}))))
(when (.exists sha256-file)
(let [sha (str/trim (slurp sha256-file))
bytes (Files/readAllBytes (.toPath zip-file))
hash (-> (java.security.MessageDigest/getInstance "SHA-256")
(.digest bytes))
hash (-> (new BigInteger 1 hash)
(.toString 16))]
(if-not (= sha hash)
(*exit-fn* {:exit ct-error-exit-code
:message (str "Error: sha256 of zip and expected sha256 do not match: "
hash " vs. " sha "\n"
" Please download manually from " ct-url-str
" to " (str (io/file dir ct-zip-name)))})
{:url ct-url-str :out-dir (str dir)}))
(.delete sha256-file))))
(warn "Unzipping" (str zip-file) "...")
(unzip zip-file (.getPath dir))
(.delete zip-file)
Expand Down
68 changes: 50 additions & 18 deletions deps.clj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
;; see https://github.com/clojure/brew-install/blob/1.11.1/CHANGELOG.md
(def ^:private version
(delay (or (System/getenv "DEPS_CLJ_TOOLS_VERSION")
"1.11.1.1386")))
"1.11.1.1403")))

(def ^:private cache-version "4")

Expand Down Expand Up @@ -381,15 +381,19 @@ For more info, see:
commit (-> (str/split version #"\.")
last
(Long/parseLong))
github-release? (>= commit 1386)]
github-release? (>= commit 1386)
verify-sha256 (>= commit 1403)
url (if github-release?
(format "https://github.com/clojure/brew-install/releases/download/%s/clojure-tools.zip" version)
(format "https://download.clojure.org/install/clojure-tools-%s.zip" version))]
{:ct-base-dir "ClojureTools"
:ct-error-exit-code 99
:ct-aux-files-names ["exec.jar" "example-deps.edn" "tools.edn"]
:ct-jar-name (format "clojure-tools-%s.jar" version)
:ct-url-str (if github-release?
(format "https://github.com/clojure/brew-install/releases/download/%s/clojure-tools.zip" version)
(format "https://download.clojure.org/install/clojure-tools-%s.zip" version))
:ct-zip-name "clojure-tools.zip"})))
:ct-url-str url
:ct-zip-name "clojure-tools.zip"
:sha256-url-str (when verify-sha256
(str url ".sha256"))})))

(def zip-invalid-msg
(str/join \n
Expand Down Expand Up @@ -495,7 +499,7 @@ public class ClojureToolsDownloader {
"Downloads `:url` zip file to `:dest` by invoking `java` with
`:proxy` options on a `.java` program file, and returns true on
success. Requires Java 11+ (JEP 330)."
[{:keys [url dest proxy-opts clj-jvm-opts]}]
[{:keys [url dest proxy-opts clj-jvm-opts sha256-url]}]
(let [dest-dir (.getCanonicalPath (io/file dest ".."))
dlr-path (clojure-tools-java-downloader-spit dest-dir)
java-cmd [(get-java-cmd) "-XX:-OmitStackTraceInFastThrow"]
Expand All @@ -508,6 +512,11 @@ public class ClojureToolsDownloader {
clj-jvm-opts
(proxy-jvm-opts proxy-opts)
[dlr-path url (str dest)]))})
(when sha256-url
(*aux-process-fn* {:cmd (vec (concat java-cmd
clj-jvm-opts
(proxy-jvm-opts proxy-opts)
[dlr-path sha256-url (str dest ".sha256")]))}))
(io/delete-file dlr-path true)
@success?*)))

Expand Down Expand Up @@ -539,27 +548,50 @@ public class ClojureToolsDownloader {
It calls `*exit-fn*` if it cannot download the archive, with
instructions how to manually download it."
[{:keys [out-dir debug proxy-opts clj-jvm-opts config-dir]}]
(let [{:keys [ct-error-exit-code ct-url-str ct-zip-name]} @clojure-tools-info*
(let [{:keys [ct-error-exit-code ct-url-str ct-zip-name sha256-url-str]} @clojure-tools-info*
dir (io/file out-dir)
zip-file (io/file out-dir ct-zip-name)
sha256-file (io/file (str zip-file ".sha256"))
transaction-start (io/file out-dir "TRANSACTION_START")]
(io/make-parents transaction-start)
(spit transaction-start "")
(when-not (.exists zip-file)
(warn "Downloading" ct-url-str "to" (str zip-file))
(or (when *clojure-tools-download-fn*
(when debug (warn "Attempting download using custom download function..."))
(*clojure-tools-download-fn* {:url ct-url-str :dest (str zip-file) :proxy-opts proxy-opts :clj-jvm-opts clj-jvm-opts}))
(when (seq clj-jvm-opts)
(when debug (warn "Attempting download using java subprocess... (requires Java11+)"))
(clojure-tools-download-java! {:url ct-url-str :dest (str zip-file) :proxy-opts proxy-opts :clj-jvm-opts clj-jvm-opts}))
(do (when debug (warn "Attempting direct download..."))
(clojure-tools-download-direct! {:url ct-url-str :dest zip-file}))
(let [res (or (when *clojure-tools-download-fn*
(when debug (warn "Attempting download using custom download function..."))
(*clojure-tools-download-fn* {:url ct-url-str :dest (str zip-file) :proxy-opts proxy-opts :clj-jvm-opts clj-jvm-opts :sha256-url sha256-url-str}))
(when (seq clj-jvm-opts)
(prn :via-java)
(when debug (warn "Attempting download using java subprocess... (requires Java11+)"))
(clojure-tools-download-java! {:url ct-url-str :dest (str zip-file) :proxy-opts proxy-opts :clj-jvm-opts clj-jvm-opts :sha256-url sha256-url-str}))
(do (when debug (warn "Attempting direct download..."))
(prn :via-tools-download-direct)
(let [res (clojure-tools-download-direct! {:url ct-url-str :dest zip-file})]
(when sha256-url-str
(clojure-tools-download-direct! {:url sha256-url-str :dest (str zip-file ".sha256")}))
res))
(*exit-fn* {:exit ct-error-exit-code
:message (str "Error: Cannot download Clojure tools."
" Please download manually from " ct-url-str
" to " (str (io/file dir ct-zip-name)))})
::passthrough)]
(when (and sha256-url-str (not *clojure-tools-download-fn*) (not (.exists sha256-file)) (not= ::passthrough res))
(*exit-fn* {:exit ct-error-exit-code
:message (str "Error: Cannot download Clojure tools."
:message (str "Expected sha256 file to be downloaded to: " sha256-file)}))))
(when (.exists sha256-file)
(let [sha (str/trim (slurp sha256-file))
bytes (Files/readAllBytes (.toPath zip-file))
hash (-> (java.security.MessageDigest/getInstance "SHA-256")
(.digest bytes))
hash (-> (new BigInteger 1 hash)
(.toString 16))]
(if-not (= sha hash)
(*exit-fn* {:exit ct-error-exit-code
:message (str "Error: sha256 of zip and expected sha256 do not match: "
hash " vs. " sha "\n"
" Please download manually from " ct-url-str
" to " (str (io/file dir ct-zip-name)))})
{:url ct-url-str :out-dir (str dir)}))
(.delete sha256-file))))
(warn "Unzipping" (str zip-file) "...")
(unzip zip-file (.getPath dir))
(.delete zip-file)
Expand Down
2 changes: 1 addition & 1 deletion resources/DEPS_CLJ_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.11.1.1386
1.11.1.1403
Loading

0 comments on commit b3b021d

Please sign in to comment.