Skip to content

Commit c56f963

Browse files
committed
Merge branch 'release/0.3.2'
2 parents 5415a8f + 54b6a7d commit c56f963

File tree

6 files changed

+134
-76
lines changed

6 files changed

+134
-76
lines changed

README.md

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,13 @@ time.
5454

5555
SSH tunneling is also supported:
5656

57+
```clj
5758
(with-ssh-agent []
5859
(let [session (session "localhost" :strict-host-key-checking :no)]
59-
(with-local-tunnel session 8080 80
60-
(with-connection session
61-
(while (connected? session)
62-
(Thread/sleep 100))))))
63-
64-
or more conveniently:
65-
66-
(with-ssh-agent []
67-
(let [session (session "localhost" :strict-host-key-checking :no)]
68-
(ssh-tunnel session 8080 80)))
60+
(with-connection session
61+
(with-local-port-forward [session 8080 80]
62+
(comment do something with port 8080 here)))))
63+
```
6964

7065
## Documentation
7166

@@ -87,17 +82,12 @@ A: Probably a disk full, or permission error.
8782
Via [clojars](http://clojars.org) and
8883
[Leiningen](http://github.com/technomancy/leiningen).
8984

90-
:dependencies [clj-ssh "0.3.1"]
85+
:dependencies [clj-ssh "0.3.2"]
9186

9287
or your favourite maven repository aware tool.
9388

9489
## License
9590

96-
Licensed under [EPL](http://www.eclipse.org/legal/epl-v10.html)
97-
98-
## TODO
91+
Copyright © 2012 Hugo Duncan
9992

100-
port forwarding
101-
environment setup
102-
sftp
103-
scp
93+
Licensed under [EPL](http://www.eclipse.org/legal/epl-v10.html)

ReleaseNotes.md

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

3-
Current release is 0.3.1
3+
Current release is 0.3.2
4+
5+
## 0.3.2
6+
7+
- Add remote port forwarding support
8+
9+
- Fix documentation for with-local-port-forward
10+
11+
- Allow specification of session options as strings
12+
This should allow options like:
13+
(default-session-options {"GSSAPIAuthentication" "no"})
414

515
## 0.3.1
616

pom.xml

Lines changed: 43 additions & 50 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.1</version>
6+
<version>0.3.3-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
@@ -22,42 +22,42 @@
2222
<testSourceDirectory>test</testSourceDirectory>
2323
<resources>
2424
<resource>
25-
<directory>src</directory>
25+
<directory>src</directory>
2626
</resource>
2727
</resources>
2828
<plugins>
2929
<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>
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>
4242
<compileDeclaredNamespaceOnly>true</compileDeclaredNamespaceOnly>
4343
<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>
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>
6161
</plugin>
6262
<plugin>
6363
<artifactId>maven-jar-plugin</artifactId>
@@ -69,22 +69,15 @@
6969
</configuration>
7070
</plugin>
7171
<plugin>
72-
<artifactId>maven-release-plugin</artifactId>
73-
<version>2.0</version>
72+
<artifactId>maven-release-plugin</artifactId>
73+
<version>2.0</version>
7474
<configuration>
7575
<pushChanges>false</pushChanges>
7676
</configuration>
7777
</plugin>
7878
</plugins>
7979
</build>
8080

81-
<repositories>
82-
<repository>
83-
<id>clojars</id>
84-
<url>http://clojars.org/repo/</url>
85-
</repository>
86-
</repositories>
87-
8881
<dependencies>
8982
<dependency>
9083
<groupId>org.clojure</groupId>
@@ -126,16 +119,16 @@
126119
<profile>
127120
<id>testuser</id>
128121
<build>
129-
<plugins>
130-
<plugin>
131-
<groupId>com.theoryinpractise</groupId>
132-
<artifactId>clojure-maven-plugin</artifactId>
133-
<version>1.3.7</version>
134-
<configuration>
135-
<clojureOptions>-Xmx512m -Djava.awt.headless=true -XX:MaxPermSize=256m -Dssh.username=testuser</clojureOptions>
136-
</configuration>
137-
</plugin>
138-
</plugins>
122+
<plugins>
123+
<plugin>
124+
<groupId>com.theoryinpractise</groupId>
125+
<artifactId>clojure-maven-plugin</artifactId>
126+
<version>1.3.7</version>
127+
<configuration>
128+
<clojureOptions>-Xmx512m -Djava.awt.headless=true -XX:MaxPermSize=256m -Dssh.username=testuser</clojureOptions>
129+
</configuration>
130+
</plugin>
131+
</plugins>
139132
</build>
140133
</profile>
141134
<profile>

project.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(defproject clj-ssh "0.3.1"
1+
(defproject clj-ssh "0.3.2-SNAPSHOT"
22
:description "Library for using SSH from clojure."
33
:dependencies [[org.clojure/clojure "1.2.0"]
44
[org.clojure/tools.logging "0.1.2"]

src/clj_ssh/ssh.clj

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,13 @@ be added. An existing agent instance can alternatively be passed."
237237
(or port 22))]
238238
(when password
239239
(.setPassword session password))
240-
(doseq [option options]
240+
(doseq [[k v :as option] options]
241241
(.setConfig
242242
session
243-
(camelize (as-string (first option)))
244-
(as-string (second option))))
243+
(if (string? k)
244+
k
245+
(camelize (as-string k)))
246+
(as-string v)))
245247
session))
246248

247249
(defn session
@@ -397,6 +399,29 @@ keys. All other option key pairs will be passed as SSH config options."
397399
(.toByteArray err-stream)
398400
(.toString err-stream out))]))))
399401

402+
(defn forward-remote-port
403+
"Start remote port forwarding"
404+
([session remote-port local-port local-host]
405+
(.setPortForwardingR session remote-port local-host local-port))
406+
([session remote-port local-port]
407+
(forward-remote-port session remote-port local-port "localhost")))
408+
409+
(defn unforward-remote-port
410+
"Remove remote port forwarding"
411+
[session remote-port]
412+
(.delPortForwardingR session remote-port))
413+
414+
(defmacro with-remote-port-forward
415+
"Creates a context in which a remote SSH tunnel is established for the
416+
session. (Use after the connection is opened.)"
417+
[[session remote-port local-port & [local-host & _]] & body]
418+
`(try
419+
(forward-remote-port
420+
~session ~remote-port ~local-port ~(or local-host "localhost"))
421+
~@body
422+
(finally
423+
(unforward-remote-port ~session ~remote-port))))
424+
400425
(defn forward-local-port
401426
"Start local port forwarding"
402427
([session local-port remote-port remote-host]
@@ -411,7 +436,7 @@ keys. All other option key pairs will be passed as SSH config options."
411436

412437
(defmacro with-local-port-forward
413438
"Creates a context in which a local SSH tunnel is established for the session.
414-
(Use before the connection is opened.)"
439+
(Use after the connection is opened.)"
415440
[[session local-port remote-port & [remote-host & _]] & body]
416441
`(try
417442
(forward-local-port

test/clj_ssh/ssh_test.clj

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,23 @@ list, Alan Dipert and MeikelBrandmeyer."
523523
(let [[priv pub] (generate-keypair :rsa 1024 "hello")]
524524
(add-identity *ssh-agent* "name" priv pub (.getBytes "hello")))))
525525

526+
(defn port-reachable?
527+
([ip port timeout]
528+
(let [socket (doto (java.net.Socket.)
529+
(.setReuseAddress false)
530+
(.setSoLinger false 1)
531+
(.setSoTimeout timeout))]
532+
(try
533+
(.connect socket (java.net.InetSocketAddress. ip port))
534+
true
535+
(catch java.io.IOException _)
536+
(finally
537+
(try (.close socket) (catch java.io.IOException _))))))
538+
([ip port]
539+
(port-reachable? ip port 2000))
540+
([port]
541+
(port-reachable? "localhost" port)))
542+
526543
(deftest forward-local-port-test
527544
(testing "minimal test"
528545
(with-ssh-agent [false]
@@ -531,13 +548,36 @@ list, Alan Dipert and MeikelBrandmeyer."
531548
:strict-host-key-checking :no)]
532549
(is (instance? com.jcraft.jsch.Session session))
533550
(is (not (connected? session)))
551+
(is (not (port-reachable? 2222)))
534552
(connect session)
535553
(is (connected? session))
536554
(forward-local-port session 2222 22)
555+
(is (port-reachable? 2222))
537556
(unforward-local-port session 2222)
538557
(forward-local-port session 2222 22 "localhost")
539558
(unforward-local-port session 2222)
540559
(with-local-port-forward [session 2222 22]
541-
(is true))
560+
(is (port-reachable? 2222)))
542561
(with-local-port-forward [session 2222 22 "localhost"]
543-
(is true))))))
562+
(is (port-reachable? 2222)))))))
563+
564+
(deftest forward-remote-port-test
565+
(testing "minimal test"
566+
(with-ssh-agent [false]
567+
(add-identity (private-key-path))
568+
(let [session (session "localhost" :username (username)
569+
:strict-host-key-checking :no)]
570+
(is (instance? com.jcraft.jsch.Session session))
571+
(is (not (connected? session)))
572+
(is (not (port-reachable? 2222)))
573+
(connect session)
574+
(is (connected? session))
575+
(forward-remote-port session 2222 22)
576+
(is (port-reachable? 2222))
577+
(unforward-remote-port session 2222)
578+
(forward-remote-port session 2222 22 "localhost")
579+
(unforward-remote-port session 2222)
580+
(with-remote-port-forward [session 2222 22]
581+
(is (port-reachable? 2222)))
582+
(with-remote-port-forward [session 2222 22 "localhost"]
583+
(is (port-reachable? 2222)))))))

0 commit comments

Comments
 (0)