Skip to content

Commit 78ac393

Browse files
committed
Merge branch 'release/0.3.3'
2 parents c56f963 + ba9cd5e commit 78ac393

File tree

6 files changed

+160
-47
lines changed

6 files changed

+160
-47
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ A: Probably a disk full, or permission error.
8282
Via [clojars](http://clojars.org) and
8383
[Leiningen](http://github.com/technomancy/leiningen).
8484

85-
:dependencies [clj-ssh "0.3.2"]
85+
:dependencies [clj-ssh "0.3.3"]
8686

8787
or your favourite maven repository aware tool.
8888

ReleaseNotes.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
# Release Notes
22

3-
Current release is 0.3.2
3+
Current release is 0.3.3
4+
5+
## 0.3.3
6+
7+
- Add a :agent-forwarding option
8+
A boolean value is passed with :agent-forwarding to clj-ssh.ssh/ssh.
9+
10+
- Add support for system ssh-agent
11+
Support the system ssh-agent (or pageant on windows when using putty) via
12+
jsch-agent-proxy. Introduces a new agent function, clj-ssh.ssh/ssh-agent.
413

514
## 0.3.2
615

pom.xml

Lines changed: 74 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>clj-ssh</groupId>
55
<artifactId>clj-ssh</artifactId>
6-
<version>0.3.3-SNAPSHOT</version>
6+
<version>0.3.4-SNAPSHOT</version>
77
<name>clj-ssh</name>
88
<description>
99
clj-ssh is a clojure wrapper for he jsch library, and can be used as an
@@ -26,39 +26,63 @@
2626
</resource>
2727
</resources>
2828
<plugins>
29-
<plugin>
30-
<groupId>com.theoryinpractise</groupId>
31-
<artifactId>clojure-maven-plugin</artifactId>
32-
<version>1.3.7</version>
33-
<configuration>
34-
<sourceDirectories>
35-
<sourceDirectory>src</sourceDirectory>
36-
</sourceDirectories>
37-
<testSourceDirectories>
38-
<testSourceDirectory>test</testSourceDirectory>
39-
</testSourceDirectories>
40-
<clojureOptions>-Xmx512m -Djava.awt.headless=true -XX:MaxPermSize=256m</clojureOptions>
41-
<warnOnReflection>false</warnOnReflection>
42-
<compileDeclaredNamespaceOnly>true</compileDeclaredNamespaceOnly>
43-
<temporaryOutputDirectory>true</temporaryOutputDirectory>
44-
</configuration>
45-
<executions>
46-
<execution>
47-
<id>compile-clojure</id>
48-
<phase>compile</phase>
49-
<goals>
50-
<goal>compile</goal>
51-
</goals>
52-
</execution>
53-
<execution>
54-
<id>test-clojure</id>
55-
<phase>test</phase>
56-
<goals>
57-
<goal>test</goal>
58-
</goals>
59-
</execution>
60-
</executions>
61-
</plugin>
29+
<plugin>
30+
<groupId>org.cloudhoist.plugin</groupId>
31+
<artifactId>zi</artifactId>
32+
<version>${zi.version}</version>
33+
<dependencies>
34+
<dependency>
35+
<groupId>org.clojure</groupId>
36+
<artifactId>clojure</artifactId>
37+
<version>${clojure.version}</version>
38+
</dependency>
39+
<dependency>
40+
<groupId>ritz</groupId>
41+
<artifactId>ritz</artifactId>
42+
<version>${ritz.version}</version>
43+
</dependency>
44+
<dependency>
45+
<groupId>codox</groupId>
46+
<artifactId>codox</artifactId>
47+
<version>${codox.version}</version>
48+
</dependency>
49+
</dependencies>
50+
<executions>
51+
<!-- setup zi to process sources and test sources, and run tests -->
52+
<execution>
53+
<id>default-resources</id>
54+
<phase>process-resources</phase>
55+
<goals>
56+
<goal>resources</goal>
57+
</goals>
58+
</execution>
59+
<execution>
60+
<id>default-test-resources</id>
61+
<phase>process-test-resources</phase>
62+
<goals>
63+
<goal>testResources</goal>
64+
</goals>
65+
</execution>
66+
<execution>
67+
<id>default-test</id>
68+
<phase>test</phase>
69+
<goals>
70+
<goal>test</goal>
71+
</goals>
72+
</execution>
73+
<execution>
74+
<id>default-site</id>
75+
<phase>site</phase>
76+
<goals>
77+
<goal>marginalia</goal>
78+
<goal>codox</goal>
79+
</goals>
80+
<configuration>
81+
<copyright>Copyright (c) 2010, 2011, 2012 Hugo Duncan</copyright>
82+
</configuration>
83+
</execution>
84+
</executions>
85+
</plugin>
6286
<plugin>
6387
<artifactId>maven-jar-plugin</artifactId>
6488
<version>2.3.1</version>
@@ -97,7 +121,17 @@
97121
<dependency>
98122
<groupId>com.jcraft</groupId>
99123
<artifactId>jsch</artifactId>
100-
<version>0.1.44-1</version>
124+
<version>${jsch.version}</version>
125+
</dependency>
126+
<dependency>
127+
<groupId>jsch-agent-proxy</groupId>
128+
<artifactId>jsch-agent-proxy</artifactId>
129+
<version>0.0.4</version>
130+
</dependency>
131+
<dependency>
132+
<groupId>jsch-agent-proxy</groupId>
133+
<artifactId>jsch-agent-proxy-jna</artifactId>
134+
<version>0.0.4</version>
101135
</dependency>
102136
<dependency>
103137
<groupId>log4j</groupId>
@@ -106,13 +140,6 @@
106140
<optional>true</optional>
107141
<scope>test</scope>
108142
</dependency>
109-
<dependency>
110-
<groupId>swank-clojure</groupId>
111-
<artifactId>swank-clojure</artifactId>
112-
<version>1.3.1</version>
113-
<optional>true</optional>
114-
<scope>test</scope>
115-
</dependency>
116143
</dependencies>
117144

118145
<profiles>
@@ -149,5 +176,10 @@
149176
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
150177
<clojure.version>1.2.0</clojure.version>
151178
<slingshot.version>0.2.0</slingshot.version>
179+
<jsch.version>0.1.48</jsch.version>
180+
<zi.version>0.4.5</zi.version>
181+
<codox.version>0.6.1</codox.version>
182+
<marginalia.version>0.7.0</marginalia.version>
183+
<ritz.version>0.2.1</ritz.version>
152184
</properties>
153185
</project>

src/clj_ssh/agent.clj

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
(ns clj-ssh.agent
2+
"Agent integration (using jsch-agent-proxy)"
3+
(:require
4+
[clojure.tools.logging :as logging])
5+
(:import
6+
com.jcraft.jsch.JSch
7+
[com.jcraft.jsch.agentproxy
8+
AgentProxyException Connector RemoteIdentityRepository]
9+
[com.jcraft.jsch.agentproxy.connector
10+
PageantConnector SSHAgentConnector]
11+
com.jcraft.jsch.agentproxy.usocket.JNAUSocketFactory))
12+
13+
(defn sock-agent-connector
14+
[]
15+
(when (SSHAgentConnector/isConnectorAvailable)
16+
(try
17+
(let [usf (JNAUSocketFactory.)]
18+
(SSHAgentConnector. usf))
19+
(catch AgentProxyException e
20+
(logging/warnf
21+
e "Failed to load JNA connector, although SSH_AUTH_SOCK is set")))))
22+
23+
(defn pageant-connector
24+
[]
25+
(when (PageantConnector/isConnectorAvailable)
26+
(try
27+
(PageantConnector.)
28+
(catch AgentProxyException e
29+
(logging/warn
30+
e "Failed to load Pageant connector, although running on windows")))))
31+
32+
(defn connect
33+
"Connect the specified jsch object to the system ssh-agent."
34+
[^JSch jsch]
35+
(when-let [connector (or (sock-agent-connector) (pageant-connector))]
36+
(doto jsch
37+
;(.setConfig "PreferredAuthentications" "publickey")
38+
(.setIdentityRepository (RemoteIdentityRepository. connector)))))

src/clj_ssh/ssh.clj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Leiningen (http://github.com/technomancy/leiningen).
3838
3939
Licensed under EPL (http://www.eclipse.org/legal/epl-v10.html)"
4040
(:require
41+
[clj-ssh.agent :as agent]
4142
[clj-ssh.keychain :as keychain]
4243
[clj-ssh.reflect :as reflect]
4344
[clojure.java.io :as io]
@@ -177,6 +178,11 @@ Licensed under EPL (http://www.eclipse.org/legal/epl-v10.html)"
177178
(logging/error "Passphrase required, but none findable."))
178179
(add-identity agent identity))))))
179180

181+
(defn ssh-agent
182+
"Create an agent that uses the system ssh-agent (or paegant on windows)."
183+
[]
184+
(doto (JSch.) (agent/connect)))
185+
180186
(defn create-ssh-agent
181187
"Create an ssh-agent. By default try and add the current user's id_rsa key."
182188
([] (create-ssh-agent true))
@@ -353,6 +359,10 @@ keys. All other option key pairs will be passed as SSH config options."
353359
(reflect/call-method
354360
com.jcraft.jsch.ChannelSession 'setPty [Boolean/TYPE]
355361
shell (boolean (opts :pty))))
362+
(when (contains? opts :agent-forwarding)
363+
(reflect/call-method
364+
com.jcraft.jsch.ChannelSession 'setAgentForwarding [Boolean/TYPE]
365+
shell (boolean (opts :agent-forwarding))))
356366
(if out-inputstream
357367
(do
358368
(connect shell)
@@ -384,6 +394,10 @@ keys. All other option key pairs will be passed as SSH config options."
384394
(reflect/call-method
385395
com.jcraft.jsch.ChannelSession 'setPty [Boolean/TYPE]
386396
exec (boolean (opts :pty))))
397+
(when (contains? opts :agent-forwarding)
398+
(reflect/call-method
399+
com.jcraft.jsch.ChannelSession 'setAgentForwarding [Boolean/TYPE]
400+
exec (boolean (opts :agent-forwarding))))
387401
(if out-inputstream
388402
(do
389403
(connect exec)

test/clj_ssh/ssh_test.clj

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,18 @@ list, Alan Dipert and MeikelBrandmeyer."
137137
(.getBytes (slurp (public-key-path)))
138138
nil)
139139
(is (= 1 (count (.getIdentityNames *ssh-agent*))))
140-
(is (= "name" (first (.getIdentityNames *ssh-agent*)))))))
140+
(is (= "name" (first (.getIdentityNames *ssh-agent*))))))
141+
(testing "ssh-agent"
142+
(with-ssh-agent (ssh-agent)
143+
(let [n (count (.getIdentityNames *ssh-agent*))]
144+
(add-identity
145+
*ssh-agent*
146+
"name"
147+
(.getBytes (slurp (private-key-path)))
148+
(.getBytes (slurp (public-key-path)))
149+
nil)
150+
(is (= (inc n) (count (.getIdentityNames *ssh-agent*)))))
151+
(is (some #(= "name" %) (.getIdentityNames *ssh-agent*))))))
141152

142153
(deftest has-identity?-test
143154
(let [key (private-key-path)]
@@ -254,7 +265,14 @@ list, Alan Dipert and MeikelBrandmeyer."
254265
(let [result (ssh-shell session "exit $(tty -s)" "UTF-8" {:pty true})]
255266
(is (= 0 (first result))))
256267
(let [result (ssh-shell session "exit $(tty -s)" "UTF-8" {:pty nil})]
257-
(is (= 1 (first result))))))))
268+
(is (= 1 (first result))))
269+
(let [result (ssh-shell session "ssh-add -l" "UTF-8" {})]
270+
(is (pos? (first result))))
271+
(let [result (ssh-shell session "ssh-add -l" "UTF-8" {:agent-forwarding false})]
272+
(is (pos? (first result))))
273+
(let [result (ssh-shell session "ssh-add -l" "UTF-8" {:agent-forwarding true})]
274+
(is (re-find #"RSA" (second result)))
275+
(is (= 0 (first result))))))))
258276

259277
(deftest ssh-exec-test
260278
(with-ssh-agent [false]
@@ -311,7 +329,9 @@ list, Alan Dipert and MeikelBrandmeyer."
311329
(let [result (ssh "localhost" :in "tty -s" :pty true :username (username))]
312330
(is (= 0 (first result))))
313331
(let [result (ssh "localhost" :in "tty -s" :pty false :username (username))]
314-
(is (= 1 (first result)))))
332+
(is (= 1 (first result))))
333+
(let [result (ssh "localhost" :in "ssh-add -l" :agent-forwarding true :username (username))]
334+
(is (zero? (first result)))))
315335
(with-default-session-options {:strict-host-key-checking :no}
316336
(with-default-identity (private-key-path)
317337
(let [result (ssh "localhost" :in "echo hello" :username (username))]

0 commit comments

Comments
 (0)