@@ -40,6 +40,7 @@ Licensed under EPL (http://www.eclipse.org/legal/epl-v10.html)"
40
40
(:use
41
41
[clojure.contrib.def :only [defvar ]])
42
42
(:require
43
+ clj-ssh.keychain
43
44
[clojure.contrib.logging :as logging])
44
45
(:import [com.jcraft.jsch
45
46
JSch Session Channel ChannelShell ChannelExec ChannelSftp
@@ -123,12 +124,19 @@ Licensed under EPL (http://www.eclipse.org/legal/epl-v10.html)"
123
124
(if (.canRead id-file)
124
125
id-file)))
125
126
127
+ (defn has-identity?
128
+ " Check if the given identity is present."
129
+ ([name] (has-identity? *ssh-agent* name))
130
+ ([agent name] (some #(= name %) (.getIdentityNames agent))))
131
+
126
132
(defn make-identity
127
133
" Create a JSch identity. This can be used to check whether the key is
128
134
encrypted."
129
135
([private-key-path public-key-path]
130
136
(make-identity *ssh-agent* private-key-path public-key-path))
131
137
([#^JSch agent #^String private-key-path #^String public-key-path]
138
+ (logging/trace
139
+ (format " Make identity %s %s" private-key-path public-key-path))
132
140
(call-method
133
141
com.jcraft.jsch.IdentityFile 'newInstance [String String JSch]
134
142
nil private-key-path public-key-path agent)))
@@ -139,7 +147,7 @@ Licensed under EPL (http://www.eclipse.org/legal/epl-v10.html)"
139
147
(add-identity *ssh-agent* (default-identity ) nil ))
140
148
([private-key]
141
149
(add-identity *ssh-agent* private-key nil ))
142
- ([#^JSch agent private-key]
150
+ ([agent private-key]
143
151
(if (ssh-agent? agent)
144
152
(add-identity agent private-key nil )
145
153
(add-identity *ssh-agent* agent private-key)))
@@ -151,10 +159,22 @@ Licensed under EPL (http://www.eclipse.org/legal/epl-v10.html)"
151
159
(file-path private-key))
152
160
(and passphrase (.getBytes passphrase)))))
153
161
154
- (defn has-identity?
155
- " Check if the given identity is present."
156
- ([name] (has-identity? *ssh-agent* name))
157
- ([agent name] (some #(= name %) (.getIdentityNames *ssh-agent*))))
162
+ (defn add-identity-with-keychain
163
+ " Add a private key, only if not already known, using the keychain to obtain
164
+ a passphrase if required"
165
+ ([] (add-identity-with-keychain *ssh-agent* (default-identity )))
166
+ ([private-key-path] (add-identity-with-keychain *ssh-agent* private-key-path))
167
+ ([agent private-key-path]
168
+ (when-not (has-identity? agent private-key-path)
169
+ (let [identity (make-identity
170
+ agent
171
+ (file-path private-key-path)
172
+ (str private-key-path " .pub" ))]
173
+ (if (.isEncrypted identity)
174
+ (if-let [passphrase (clj-ssh.keychain/passphrase private-key-path)]
175
+ (add-identity agent identity passphrase)
176
+ (logging/error " Passphrase required, but none findable." ))
177
+ (add-identity agent identity))))))
158
178
159
179
(defn create-ssh-agent
160
180
" Create an ssh-agent. By default try and add the current user's id_rsa key."
@@ -166,13 +186,13 @@ Licensed under EPL (http://www.eclipse.org/legal/epl-v10.html)"
166
186
(let [agent (JSch. )]
167
187
(when add-default-identity?
168
188
(if-let [default-id (default-identity )]
169
- (add-identity agent default-id )))
189
+ (add-identity-with-keychain agent default-id )))
170
190
agent)))
171
191
([private-key passphrase?]
172
192
(let [agent (JSch. )]
173
193
(if passphrase?
174
194
(add-identity agent private-key passphrase?)
175
- (add-identity agent private-key))
195
+ (add-identity-with-keychain agent private-key))
176
196
agent)))
177
197
178
198
(defmacro with-ssh-agent
0 commit comments