2017-04-28 22:54:12 +00:00
|
|
|
package ssh
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
"log"
|
2017-04-28 22:54:12 +00:00
|
|
|
"net"
|
Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
2018-09-24 00:41:38 +00:00
|
|
|
"strconv"
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
"sync"
|
2017-04-28 22:54:12 +00:00
|
|
|
|
|
|
|
gossh "golang.org/x/crypto/ssh"
|
|
|
|
)
|
|
|
|
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
const (
|
|
|
|
forwardedTCPChannelType = "forwarded-tcpip"
|
|
|
|
)
|
|
|
|
|
2017-04-28 22:54:12 +00:00
|
|
|
// direct-tcpip data struct as specified in RFC4254, Section 7.2
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
type localForwardChannelData struct {
|
|
|
|
DestAddr string
|
|
|
|
DestPort uint32
|
2017-04-28 22:54:12 +00:00
|
|
|
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
OriginAddr string
|
|
|
|
OriginPort uint32
|
2017-04-28 22:54:12 +00:00
|
|
|
}
|
|
|
|
|
2019-06-12 17:52:26 +00:00
|
|
|
// DirectTCPIPHandler can be enabled by adding it to the server's
|
|
|
|
// ChannelHandlers under direct-tcpip.
|
|
|
|
func DirectTCPIPHandler(srv *Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx Context) {
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
d := localForwardChannelData{}
|
2017-04-28 22:54:12 +00:00
|
|
|
if err := gossh.Unmarshal(newChan.ExtraData(), &d); err != nil {
|
|
|
|
newChan.Reject(gossh.ConnectionFailed, "error parsing forward data: "+err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
if srv.LocalPortForwardingCallback == nil || !srv.LocalPortForwardingCallback(ctx, d.DestAddr, d.DestPort) {
|
2017-04-28 22:54:12 +00:00
|
|
|
newChan.Reject(gossh.Prohibited, "port forwarding is disabled")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
dest := net.JoinHostPort(d.DestAddr, strconv.FormatInt(int64(d.DestPort), 10))
|
|
|
|
|
2017-04-28 22:54:12 +00:00
|
|
|
var dialer net.Dialer
|
|
|
|
dconn, err := dialer.DialContext(ctx, "tcp", dest)
|
|
|
|
if err != nil {
|
|
|
|
newChan.Reject(gossh.ConnectionFailed, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ch, reqs, err := newChan.Accept()
|
|
|
|
if err != nil {
|
|
|
|
dconn.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
go gossh.DiscardRequests(reqs)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
defer ch.Close()
|
|
|
|
defer dconn.Close()
|
|
|
|
io.Copy(ch, dconn)
|
|
|
|
}()
|
|
|
|
go func() {
|
|
|
|
defer ch.Close()
|
|
|
|
defer dconn.Close()
|
|
|
|
io.Copy(dconn, ch)
|
|
|
|
}()
|
|
|
|
}
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
|
|
|
|
type remoteForwardRequest struct {
|
|
|
|
BindAddr string
|
|
|
|
BindPort uint32
|
|
|
|
}
|
|
|
|
|
|
|
|
type remoteForwardSuccess struct {
|
|
|
|
BindPort uint32
|
|
|
|
}
|
|
|
|
|
|
|
|
type remoteForwardCancelRequest struct {
|
|
|
|
BindAddr string
|
|
|
|
BindPort uint32
|
|
|
|
}
|
|
|
|
|
|
|
|
type remoteForwardChannelData struct {
|
|
|
|
DestAddr string
|
|
|
|
DestPort uint32
|
|
|
|
OriginAddr string
|
|
|
|
OriginPort uint32
|
|
|
|
}
|
|
|
|
|
2019-06-12 17:52:26 +00:00
|
|
|
// ForwardedTCPHandler can be enabled by creating a ForwardedTCPHandler and
|
2019-06-19 08:24:53 +00:00
|
|
|
// adding the HandleSSHRequest callback to the server's RequestHandlers under
|
|
|
|
// tcpip-forward and cancel-tcpip-forward.
|
2019-06-12 17:52:26 +00:00
|
|
|
type ForwardedTCPHandler struct {
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
forwards map[string]net.Listener
|
|
|
|
sync.Mutex
|
|
|
|
}
|
|
|
|
|
2019-06-19 08:43:09 +00:00
|
|
|
func (h *ForwardedTCPHandler) HandleSSHRequest(ctx Context, srv *Server, req *gossh.Request) (bool, []byte) {
|
Remote forwarding (#88)
* context: fixed documentation to be more specific about ContextKeyConn being the key for a gossh.ServerConn
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* server: fixes handler setup, changed to interface based handlers, added global request handler map
* tcpip: working remote forwarding
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* context: docs typo
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* session: always reply to unblock clients trying something
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* tcpip: stop listening when ssh clients disconnect
Signed-off-by: Jeff Lindsay <progrium@gmail.com>
* Remote forwarding (#87)
* Update generateSigner key size to 2048 (#62)
Fixes #58
* Add syntax highlighting to readme (#67)
* small api updates (#69)
These updates make it easier to implement and pass custom Session and
Context implementations
No compatibilty breaking, all tests pass
* Move channelHandlers to avoid data race (#59)
* Update tests to work with go 1.10+ (#73)
Fixes #72
* Update shutdown to use a WaitGroup rather than sleeping (#74)
* Fix race condition in TestServerClose (#75)
In test server close, 3 things need to happen in order:
- Client session start
- Server.Close
- Client session exit (With io.EOF)
This fix ensures the client won't do anything until after the call to
close which ensure's we'll get io.EOF rather than a different error.
* Update circleci config to test multiple go versions
* Update CircleCI config to test 1.9 and the latest
The x/crypto/ssh library dropped support go < 1.9 as that's the first
version to have the math/bits library.
https://github.com/golang/crypto/commit/83c378c48d6ee2ca9c20551b599aa74cb7765785
* Wait for connections to finish when shutting down
PR #74 introduced a WaitGroup for listeners, but it doesn't wait for
open connections before closing the server. This patch waits until all
conns are closed before returning from Shutdown.
* Support port forwarding of literal IPv6 addresses (#85)
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Support port forwarding of literal IPv6 addresses
To disambiguate between colons as host:port separators and as IPv6 address separators, literal IPv6 addresses use square brackets around the address (https://en.wikipedia.org/wiki/IPv6_address#Literal_IPv6_addresses_in_network_resource_identifiers). So host ::1, port 22 is written as [::1]:22, and therefore a simple concatenation of host, colon, and port doesn't work. Fortunately net.JoinHostPort already implements this functionality, so with a bit of type gymnastics we can generate dest in an IPv6-safe way.
* Reverse port forwarding callback added
* garbage removed
2018-11-13 16:04:02 +00:00
|
|
|
h.Lock()
|
|
|
|
if h.forwards == nil {
|
|
|
|
h.forwards = make(map[string]net.Listener)
|
|
|
|
}
|
|
|
|
h.Unlock()
|
|
|
|
conn := ctx.Value(ContextKeyConn).(*gossh.ServerConn)
|
|
|
|
switch req.Type {
|
|
|
|
case "tcpip-forward":
|
|
|
|
var reqPayload remoteForwardRequest
|
|
|
|
if err := gossh.Unmarshal(req.Payload, &reqPayload); err != nil {
|
|
|
|
// TODO: log parse failure
|
|
|
|
return false, []byte{}
|
|
|
|
}
|
|
|
|
if srv.ReversePortForwardingCallback == nil || !srv.ReversePortForwardingCallback(ctx, reqPayload.BindAddr, reqPayload.BindPort) {
|
|
|
|
return false, []byte("port forwarding is disabled")
|
|
|
|
}
|
|
|
|
addr := net.JoinHostPort(reqPayload.BindAddr, strconv.Itoa(int(reqPayload.BindPort)))
|
|
|
|
ln, err := net.Listen("tcp", addr)
|
|
|
|
if err != nil {
|
|
|
|
// TODO: log listen failure
|
|
|
|
return false, []byte{}
|
|
|
|
}
|
|
|
|
_, destPortStr, _ := net.SplitHostPort(ln.Addr().String())
|
|
|
|
destPort, _ := strconv.Atoi(destPortStr)
|
|
|
|
h.Lock()
|
|
|
|
h.forwards[addr] = ln
|
|
|
|
h.Unlock()
|
|
|
|
go func() {
|
|
|
|
<-ctx.Done()
|
|
|
|
h.Lock()
|
|
|
|
ln, ok := h.forwards[addr]
|
|
|
|
h.Unlock()
|
|
|
|
if ok {
|
|
|
|
ln.Close()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
c, err := ln.Accept()
|
|
|
|
if err != nil {
|
|
|
|
// TODO: log accept failure
|
|
|
|
break
|
|
|
|
}
|
|
|
|
originAddr, orignPortStr, _ := net.SplitHostPort(c.RemoteAddr().String())
|
|
|
|
originPort, _ := strconv.Atoi(orignPortStr)
|
|
|
|
payload := gossh.Marshal(&remoteForwardChannelData{
|
|
|
|
DestAddr: reqPayload.BindAddr,
|
|
|
|
DestPort: uint32(destPort),
|
|
|
|
OriginAddr: originAddr,
|
|
|
|
OriginPort: uint32(originPort),
|
|
|
|
})
|
|
|
|
go func() {
|
|
|
|
ch, reqs, err := conn.OpenChannel(forwardedTCPChannelType, payload)
|
|
|
|
if err != nil {
|
|
|
|
// TODO: log failure to open channel
|
|
|
|
log.Println(err)
|
|
|
|
c.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
go gossh.DiscardRequests(reqs)
|
|
|
|
go func() {
|
|
|
|
defer ch.Close()
|
|
|
|
defer c.Close()
|
|
|
|
io.Copy(ch, c)
|
|
|
|
}()
|
|
|
|
go func() {
|
|
|
|
defer ch.Close()
|
|
|
|
defer c.Close()
|
|
|
|
io.Copy(c, ch)
|
|
|
|
}()
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
h.Lock()
|
|
|
|
delete(h.forwards, addr)
|
|
|
|
h.Unlock()
|
|
|
|
}()
|
|
|
|
return true, gossh.Marshal(&remoteForwardSuccess{uint32(destPort)})
|
|
|
|
|
|
|
|
case "cancel-tcpip-forward":
|
|
|
|
var reqPayload remoteForwardCancelRequest
|
|
|
|
if err := gossh.Unmarshal(req.Payload, &reqPayload); err != nil {
|
|
|
|
// TODO: log parse failure
|
|
|
|
return false, []byte{}
|
|
|
|
}
|
|
|
|
addr := net.JoinHostPort(reqPayload.BindAddr, strconv.Itoa(int(reqPayload.BindPort)))
|
|
|
|
h.Lock()
|
|
|
|
ln, ok := h.forwards[addr]
|
|
|
|
h.Unlock()
|
|
|
|
if ok {
|
|
|
|
ln.Close()
|
|
|
|
}
|
|
|
|
return true, nil
|
|
|
|
default:
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
}
|