Skip to content

Commit 6dffd6b

Browse files
committed
Update to jsch 0.1.49 and enable adding keys to ssh-agent
1 parent 0d90718 commit 6dffd6b

File tree

4 files changed

+75
-47
lines changed

4 files changed

+75
-47
lines changed

project.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
:exclusions [com.jcraft/jsch-agent-proxy]]
1212
[slingshot "0.10.2"
1313
:exclusions [org.clojure/clojure]]
14-
[com.jcraft/jsch "0.1.48"]])
14+
[com.jcraft/jsch "0.1.49"]])

src/clj_ssh/ssh.clj

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
PipedInputStream PipedOutputStream]
4040
[com.jcraft.jsch
4141
JSch Session Channel ChannelShell ChannelExec ChannelSftp
42-
Identity IdentityFile Logger KeyPair]))
42+
Identity IdentityFile Logger KeyPair LocalIdentityRepository]))
4343

4444
;;; forward jsch's logging to java logging
4545
(def ^{:dynamic true}
@@ -130,33 +130,54 @@
130130
[^JSch agent {:keys [^String name
131131
^String public-key
132132
^String private-key
133-
public-key-path
134-
private-key-path
133+
^String public-key-path
134+
^String private-key-path
135135
^Identity identity
136136
^bytes passphrase]
137137
:as options}]
138138
{:pre [(map? options)]}
139-
(let [name (or name private-key-path public-key)]
139+
(let [name (or name private-key-path public-key)
140+
id-repository (fn []
141+
(reflect/call-method
142+
com.jcraft.jsch.JSch 'getIdentityRepository []
143+
agent))
144+
local-repo? (fn [id-repo]
145+
;; LocalIdentityRepository is not public, so we can't use
146+
;; instance?
147+
(= "com.jcraft.jsch.LocalIdentityRepository"
148+
(.getName (type id-repo))))]
140149
(cond
141-
identity
142-
(.addIdentity agent identity passphrase)
143-
144-
(and public-key private-key)
145-
(.addIdentity agent name private-key public-key passphrase)
146-
147-
(and public-key-path private-key-path)
148-
(.addIdentity
149-
agent
150-
(file-path private-key-path) (file-path public-key-path) passphrase)
151-
152-
private-key-path
153-
(.addIdentity agent (file-path private-key-path) passphrase)
154-
155-
:else
156-
(throw+
157-
{:reason :do-not-know-how-to-add-identity
158-
:args options}
159-
"Don't know how to add identity"))))
150+
identity
151+
(.addIdentity agent identity passphrase)
152+
153+
(and public-key private-key)
154+
(let [id-repo (id-repository)]
155+
(if (local-repo? id-repo)
156+
(.addIdentity agent name private-key public-key passphrase)
157+
(let [keypair (KeyPair/load agent private-key-path public-key-path)]
158+
(.add id-repo (.forSSHAgent keypair)))))
159+
160+
(and public-key-path private-key-path)
161+
(let [id-repo (id-repository)]
162+
(if (local-repo? id-repo)
163+
(.addIdentity
164+
agent
165+
(file-path private-key-path) (file-path public-key-path) passphrase)
166+
(let [keypair (KeyPair/load agent private-key-path public-key-path)]
167+
(.add id-repo (.forSSHAgent keypair)))))
168+
169+
private-key-path
170+
(let [id-repo (id-repository)]
171+
(if (local-repo? id-repo)
172+
(.addIdentity agent (file-path private-key-path) passphrase)
173+
(let [keypair (KeyPair/load agent private-key-path)]
174+
(.add id-repo (.forSSHAgent keypair)))))
175+
176+
:else
177+
(throw+
178+
{:reason :do-not-know-how-to-add-identity
179+
:args options}
180+
"Don't know how to add identity"))))
160181

161182
(defn add-identity-with-keychain
162183
"Add a private key, only if not already known, using the keychain to obtain

test/clj_ssh/cli_test.clj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@
4646
(let [key (private-key-path)]
4747
(with-ssh-agent (ssh-agent {:use-system-ssh-agent false})
4848
(is (not (has-identity? key)))
49+
(is (zero? (count (.getIdentityNames *ssh-agent*))))
4950
(add-identity :private-key-path key)
5051
(is (= 1 (count (.getIdentityNames *ssh-agent*))))
51-
(is (has-identity? key))
52-
(add-identity :private-key-path key)
53-
(is (= 1 (count (.getIdentityNames *ssh-agent*)))))))
52+
(is (has-identity? key)))))
5453

5554
(deftest session-test
5655
(with-ssh-agent (ssh-agent {:use-system-ssh-agent false})

test/clj_ssh/ssh_test.clj

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,36 @@
5757
(is (= 1 (count (.getIdentityNames agent))))
5858
(is (= "name" (first (.getIdentityNames agent))))))
5959
(testing "ssh-agent"
60-
;; adding identities to the system ssh-agent isn't implemented in jsch
61-
;; (with-ssh-agent (ssh-agent {})
62-
;; (let [n (count (.getIdentityNames *ssh-agent*))]
63-
;; (add-identity
64-
;; {:agent *ssh-agent*
65-
;; :name "name"
66-
;; :private-key (.getBytes (slurp (private-key-path)))
67-
;; :public-key (.getBytes (slurp (public-key-path)))})
68-
;; (is (= (inc n) (count (.getIdentityNames *ssh-agent*)))))
69-
;; (is (some #(= "name" %) (.getIdentityNames *ssh-agent*))))
70-
))
60+
(let [agent (ssh-agent {})]
61+
(let [n (count (.getIdentityNames agent))
62+
test-key-comment "key for test clj-ssh"
63+
has-key (some #(= test-key-comment %) (.getIdentityNames agent))]
64+
(add-identity
65+
agent
66+
{:name "name"
67+
:private-key-path (private-key-path)
68+
:public-key-path (public-key-path)})
69+
(is (or has-key (= (inc n) (count (.getIdentityNames agent)))))
70+
(is (some #(= test-key-comment %) (.getIdentityNames agent)))))))
7171

7272
(deftest has-identity?-test
73-
(let [key (private-key-path)]
74-
(let [agent (ssh-agent {:use-system-ssh-agent false})]
75-
(is (not (has-identity? agent key)))
76-
(add-identity agent {:private-key-path key})
77-
(is (= 1 (count (.getIdentityNames agent))))
78-
(is (has-identity? agent key))
79-
(add-identity agent {:private-key-path key})
80-
(is (= 1 (count (.getIdentityNames agent)))))))
81-
73+
(let [key (private-key-path)
74+
pub-key (public-key-path)]
75+
(testing "private-key-path only"
76+
(let [agent (ssh-agent {:use-system-ssh-agent false})]
77+
(is (not (has-identity? agent key)))
78+
(is (zero? (count (.getIdentityNames agent))))
79+
(add-identity agent {:private-key-path key})
80+
(is (= 1 (count (.getIdentityNames agent))))
81+
(is (has-identity? agent key))))
82+
(testing "private-key-path and public-key-path"
83+
(let [agent (ssh-agent {:use-system-ssh-agent false})]
84+
(is (not (has-identity? agent key)))
85+
(is (zero? (count (.getIdentityNames agent))))
86+
(add-identity agent {:private-key-path key
87+
:public-key-path pub-key})
88+
(is (= 1 (count (.getIdentityNames agent))))
89+
(is (has-identity? agent key))))))
8290

8391
(deftest session-impl-test
8492
(let [agent (ssh-agent {:use-system-ssh-agent false})]

0 commit comments

Comments
 (0)