Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

Upgrade gitlibs. This also address the issue with private keys #58

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
9 changes: 4 additions & 5 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
(defproject reifyhealth/lein-git-down "0.4.1"
(defproject reifyhealth/lein-git-down "0.4.2"
:description "A Leiningen plugin for resolving Clojure(Script) dependencies from a Git repository"
:url "http://github.com/reifyhealth/lein-git-down"
:license {:name "MIT"}
:dependencies [[org.clojure/tools.gitlibs "1.0.100"
:exclusions [org.apache.httpcomponents/httpclient
org.slf4j/slf4j-api]]
[leiningen "2.9.4" :scope "provided"]]
:dependencies [[org.clojure/tools.gitlibs "2.5.190"]
[org.eclipse.jgit/org.eclipse.jgit "4.10.0.201712302008-r"]
[leiningen "2.9.4" :scope "provided" :exclusions [commons-codec org.apache.httpcomponents/httpclient org.slf4j/slf4j-api org.apache.httpcomponents/httpcore]]]
:deploy-repositories [["clojars" {:url "https://clojars.org/repo"
:username :env/clojars_username
:password :env/clojars_password
Expand Down
110 changes: 5 additions & 105 deletions src/lein_git_down/impl/git.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,129 +6,29 @@
[clojure.tools.gitlibs.impl :as git-impl]
[leiningen.core.main :as lein]
[robert.hooke :as hooke])
(:import (com.jcraft.jsch JSch Session UserInfo ConfigRepository ConfigRepository$Config KeyPair)
(com.jcraft.jsch.agentproxy ConnectorFactory RemoteIdentityRepository)
(org.eclipse.jgit.api TransportConfigCallback Git)
(org.eclipse.jgit.transport SshTransport JschConfigSessionFactory OpenSshConfig)
(:import (org.eclipse.jgit.api TransportConfigCallback Git)
(java.io File)))

;; This namespace provides patched `procure` & `resolve` functions that fix
;; issues in JGit's implementation of JSCH. The first is a problem that causes
;; failure if using an encrypted (password protected) SSH key to connect to a
;; private repository. There is a [patch](https://dev.clojure.org/jira/browse/TDEPS-49)
;; submitted to gitlibs for this. The second is how JSCH handles keys in an
;; unsupported format. Without the patch it will fail at the first key it
;; encounters that it does not recognize, which is undesirable as the user
;; may have another key configured that will work. The patched impl below
;; will print a warn message and move on to the next key.

(def ^:dynamic *monkeypatch-tools-gitlibs* true)

(defn valid-key?
[jsch v]
(try
(KeyPair/load ^JSch jsch v)
true
(catch Throwable e
(let [m (if (.startsWith (.getMessage e) "invalid privatekey")
"The private key file is in an unsupported format."
(.getMessage e))]
(lein/warn "Exception processing private key," v ":"
m "Skipping..."))
false)))

(defn get-unsupported-algorithms
[^Session session k]
(into #{}
(filter #(nil? (JSch/getConfig %)))
(some-> (.getConfig session k) (string/split #","))))

(defn check-algorithms
"Jsch fails with an NPE when an unsupported algorithm is configured in the
ssh config file. This provides the user with more helpful information as to
the cause of the error."
[^Session session]
(let [kex (get-unsupported-algorithms session "kex")
cph (get-unsupported-algorithms session "cipher.c2s")
mac (get-unsupported-algorithms session "mac.c2s")
msg (str "Detected unsupported algorithm(s) configured for the '%s' "
"property in ssh config: %s")]
(when (not-empty kex) (lein/warn (format msg "KexAlgorithms" kex)))
(when (not-empty cph) (lein/warn (format msg "Ciphers" cph)))
(when (not-empty mac) (lein/warn (format msg "MACs" mac)))))

(def ssh-callback
(delay
(let [factory (doto (ConnectorFactory/getDefault)
(.setPreferredUSocketFactories "jna,nc"))
connector (.createConnector factory)]
(JSch/setConfig "PreferredAuthentications" "publickey")
(reify TransportConfigCallback
(configure [_ transport]
(.setSshSessionFactory
^SshTransport transport
(proxy [JschConfigSessionFactory] []
(configure [_host session]
(check-algorithms session)
(.setUserInfo
^Session session
(proxy [UserInfo] []
(getPassword [])
(promptYesNo [_] true)
(getPassphrase [])
(promptPassphrase [_] true)
(promptPassword [_] true)
(showMessage [_]))))
(getJSch [_hc fs]
(let [jsch (proxy-super createDefaultJSch fs)]
(doto jsch
(.setIdentityRepository
(RemoteIdentityRepository. connector))
(.setConfigRepository
(let [osc (OpenSshConfig/get fs)]
(proxy [ConfigRepository] []
(getConfig [host-name]
(let [oscc (.getConfig osc host-name)]
(proxy [ConfigRepository$Config] []
(getHostname [] (.getHostname oscc))
(getUser [] (.getUser oscc))
(getPort [] (.getPort oscc))
(getValue [key] (.getValue oscc key))
(getValues [key]
(let [vs (.getValues oscc key)]
(if (= key "IdentityFile")
(into-array String
(filter (partial valid-key? jsch) vs))
vs)))))))))))))))))))

(defn dev-null-hook
[_ & _])

(defn procure
"Monkey patches gitlibs/procure to resolve some JSCH issues unless explicitly
told not to. Writes a meta-data file with information about the source."
"Monkey patches gitlibs/procure to writes a meta-data file with information about the source."
[uri mvn-coords rev]
(hooke/with-scope
(hooke/add-hook #'git-impl/printerrln #'dev-null-hook)
(let [path (if *monkeypatch-tools-gitlibs*
(with-redefs [git-impl/ssh-callback ssh-callback]
(git/procure uri mvn-coords rev))
(git/procure uri mvn-coords rev))
(let [path (git/procure uri mvn-coords rev)
meta (io/file path ".lein-git-down")]
(when-not (.exists meta)
(spit meta {:uri uri :mvn-coords mvn-coords :rev rev}))
path)))

(defn resolve
"Monkey patches gitlibs/resolve to resolve some JSCH issues unless explicitly
told not to."
"Monkey patches gitlibs/resolve to silence errors."
[uri version]
(hooke/with-scope
(hooke/add-hook #'git-impl/printerrln #'dev-null-hook)
(if *monkeypatch-tools-gitlibs*
(with-redefs [git-impl/ssh-callback ssh-callback]
(git/resolve uri version))
(git/resolve uri version))))
(git/resolve uri version)))

(defn init
"Initializes a fresh git repository at `project-dir` and sets HEAD to the
Expand Down
10 changes: 3 additions & 7 deletions src/lein_git_down/plugin.clj
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,9 @@

(defn inject-properties
[{:keys [git-down repositories] :as project}]
(when-not (contains? @git-wagon-properties :monkeypatch-tools-gitlibs)
(let [patch? (boolean (get project :monkeypatch-tools-gitlibs true))]
(alter-var-root #'git/*monkeypatch-tools-gitlibs*
(constantly patch?))
(swap! git-wagon-properties
assoc
:monkeypatch-tools-gitlibs patch?)))
(when (or (contains? @git-wagon-properties :monkeypatch-tools-gitlibs)
(true? (get project :monkeypatch-tools-gitlibs)))
(lein/warn "':monkeypatch-tools-gitlibs' option is no longer necessary"))
(swap! git-wagon-properties
#(merge-with merge %
{:protocols (get-repo-protocols repositories)
Expand Down