Skip to content

Commit 8bf87a3

Browse files
committed
Merge branch 'feature/add-remote-port-forwarding' into develop
2 parents 7ccb4bb + 6985fb7 commit 8bf87a3

File tree

2 files changed

+66
-3
lines changed

2 files changed

+66
-3
lines changed

src/clj_ssh/ssh.clj

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,29 @@ keys. All other option key pairs will be passed as SSH config options."
399399
(.toByteArray err-stream)
400400
(.toString err-stream out))]))))
401401

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+
402425
(defn forward-local-port
403426
"Start local port forwarding"
404427
([session local-port remote-port remote-host]
@@ -413,7 +436,7 @@ keys. All other option key pairs will be passed as SSH config options."
413436

414437
(defmacro with-local-port-forward
415438
"Creates a context in which a local SSH tunnel is established for the session.
416-
(Use before the connection is opened.)"
439+
(Use after the connection is opened.)"
417440
[[session local-port remote-port & [remote-host & _]] & body]
418441
`(try
419442
(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)