Permalink
Browse files

Update to jsch 0.1.49 and enable adding keys to ssh-agent

  • Loading branch information...
1 parent 0d90718 commit 6dffd6b18c12f6f86865f5015d8b04eb6973f1c2 @hugoduncan committed Oct 13, 2012
Showing with 75 additions and 47 deletions.
  1. +1 −1 project.clj
  2. +44 −23 src/clj_ssh/ssh.clj
  3. +2 −3 test/clj_ssh/cli_test.clj
  4. +28 −20 test/clj_ssh/ssh_test.clj
View
@@ -11,4 +11,4 @@
:exclusions [com.jcraft/jsch-agent-proxy]]
[slingshot "0.10.2"
:exclusions [org.clojure/clojure]]
- [com.jcraft/jsch "0.1.48"]])
+ [com.jcraft/jsch "0.1.49"]])
View
@@ -39,7 +39,7 @@
PipedInputStream PipedOutputStream]
[com.jcraft.jsch
JSch Session Channel ChannelShell ChannelExec ChannelSftp
- Identity IdentityFile Logger KeyPair]))
+ Identity IdentityFile Logger KeyPair LocalIdentityRepository]))
;;; forward jsch's logging to java logging
(def ^{:dynamic true}
@@ -130,33 +130,54 @@
[^JSch agent {:keys [^String name
^String public-key
^String private-key
- public-key-path
- private-key-path
+ ^String public-key-path
+ ^String private-key-path
^Identity identity
^bytes passphrase]
:as options}]
{:pre [(map? options)]}
- (let [name (or name private-key-path public-key)]
+ (let [name (or name private-key-path public-key)
+ id-repository (fn []
+ (reflect/call-method
+ com.jcraft.jsch.JSch 'getIdentityRepository []
+ agent))
+ local-repo? (fn [id-repo]
+ ;; LocalIdentityRepository is not public, so we can't use
+ ;; instance?
+ (= "com.jcraft.jsch.LocalIdentityRepository"
+ (.getName (type id-repo))))]
(cond
- identity
- (.addIdentity agent identity passphrase)
-
- (and public-key private-key)
- (.addIdentity agent name private-key public-key passphrase)
-
- (and public-key-path private-key-path)
- (.addIdentity
- agent
- (file-path private-key-path) (file-path public-key-path) passphrase)
-
- private-key-path
- (.addIdentity agent (file-path private-key-path) passphrase)
-
- :else
- (throw+
- {:reason :do-not-know-how-to-add-identity
- :args options}
- "Don't know how to add identity"))))
+ identity
+ (.addIdentity agent identity passphrase)
+
+ (and public-key private-key)
+ (let [id-repo (id-repository)]
+ (if (local-repo? id-repo)
+ (.addIdentity agent name private-key public-key passphrase)
+ (let [keypair (KeyPair/load agent private-key-path public-key-path)]
+ (.add id-repo (.forSSHAgent keypair)))))
+
+ (and public-key-path private-key-path)
+ (let [id-repo (id-repository)]
+ (if (local-repo? id-repo)
+ (.addIdentity
+ agent
+ (file-path private-key-path) (file-path public-key-path) passphrase)
+ (let [keypair (KeyPair/load agent private-key-path public-key-path)]
+ (.add id-repo (.forSSHAgent keypair)))))
+
+ private-key-path
+ (let [id-repo (id-repository)]
+ (if (local-repo? id-repo)
+ (.addIdentity agent (file-path private-key-path) passphrase)
+ (let [keypair (KeyPair/load agent private-key-path)]
+ (.add id-repo (.forSSHAgent keypair)))))
+
+ :else
+ (throw+
+ {:reason :do-not-know-how-to-add-identity
+ :args options}
+ "Don't know how to add identity"))))
(defn add-identity-with-keychain
"Add a private key, only if not already known, using the keychain to obtain
@@ -46,11 +46,10 @@
(let [key (private-key-path)]
(with-ssh-agent (ssh-agent {:use-system-ssh-agent false})
(is (not (has-identity? key)))
+ (is (zero? (count (.getIdentityNames *ssh-agent*))))
(add-identity :private-key-path key)
(is (= 1 (count (.getIdentityNames *ssh-agent*))))
- (is (has-identity? key))
- (add-identity :private-key-path key)
- (is (= 1 (count (.getIdentityNames *ssh-agent*)))))))
+ (is (has-identity? key)))))
(deftest session-test
(with-ssh-agent (ssh-agent {:use-system-ssh-agent false})
View
@@ -57,28 +57,36 @@
(is (= 1 (count (.getIdentityNames agent))))
(is (= "name" (first (.getIdentityNames agent))))))
(testing "ssh-agent"
- ;; adding identities to the system ssh-agent isn't implemented in jsch
- ;; (with-ssh-agent (ssh-agent {})
- ;; (let [n (count (.getIdentityNames *ssh-agent*))]
- ;; (add-identity
- ;; {:agent *ssh-agent*
- ;; :name "name"
- ;; :private-key (.getBytes (slurp (private-key-path)))
- ;; :public-key (.getBytes (slurp (public-key-path)))})
- ;; (is (= (inc n) (count (.getIdentityNames *ssh-agent*)))))
- ;; (is (some #(= "name" %) (.getIdentityNames *ssh-agent*))))
- ))
+ (let [agent (ssh-agent {})]
+ (let [n (count (.getIdentityNames agent))
+ test-key-comment "key for test clj-ssh"
+ has-key (some #(= test-key-comment %) (.getIdentityNames agent))]
+ (add-identity
+ agent
+ {:name "name"
+ :private-key-path (private-key-path)
+ :public-key-path (public-key-path)})
+ (is (or has-key (= (inc n) (count (.getIdentityNames agent)))))
+ (is (some #(= test-key-comment %) (.getIdentityNames agent)))))))
(deftest has-identity?-test
- (let [key (private-key-path)]
- (let [agent (ssh-agent {:use-system-ssh-agent false})]
- (is (not (has-identity? agent key)))
- (add-identity agent {:private-key-path key})
- (is (= 1 (count (.getIdentityNames agent))))
- (is (has-identity? agent key))
- (add-identity agent {:private-key-path key})
- (is (= 1 (count (.getIdentityNames agent)))))))
-
+ (let [key (private-key-path)
+ pub-key (public-key-path)]
+ (testing "private-key-path only"
+ (let [agent (ssh-agent {:use-system-ssh-agent false})]
+ (is (not (has-identity? agent key)))
+ (is (zero? (count (.getIdentityNames agent))))
+ (add-identity agent {:private-key-path key})
+ (is (= 1 (count (.getIdentityNames agent))))
+ (is (has-identity? agent key))))
+ (testing "private-key-path and public-key-path"
+ (let [agent (ssh-agent {:use-system-ssh-agent false})]
+ (is (not (has-identity? agent key)))
+ (is (zero? (count (.getIdentityNames agent))))
+ (add-identity agent {:private-key-path key
+ :public-key-path pub-key})
+ (is (= 1 (count (.getIdentityNames agent))))
+ (is (has-identity? agent key))))))
(deftest session-impl-test
(let [agent (ssh-agent {:use-system-ssh-agent false})]

0 comments on commit 6dffd6b

Please sign in to comment.