mirror of
https://codeberg.org/forgejo/forgejo
synced 2024-12-01 06:16:09 +01:00
f825f20d49
* Upgrade Gliderlabs SSH to 0.3.3 and add FailedConnectionCallback Following the merging of https://github.com/gliderlabs/ssh/pull/143 we can now report connections to the ssh server that have failed before public key exchange has completed using the standard fail2ban message. This PR updates Gliderlabs SSH and adds a callback that will provide this logging. Signed-off-by: Andrew Thornton <art27@cantab.net> * move the callback to its own function to make the logging appear little nicer Signed-off-by: Andrew Thornton <art27@cantab.net>
128 lines
4 KiB
Go
Vendored
128 lines
4 KiB
Go
Vendored
package ssh
|
|
|
|
import (
|
|
"crypto/subtle"
|
|
"net"
|
|
|
|
gossh "golang.org/x/crypto/ssh"
|
|
)
|
|
|
|
type Signal string
|
|
|
|
// POSIX signals as listed in RFC 4254 Section 6.10.
|
|
const (
|
|
SIGABRT Signal = "ABRT"
|
|
SIGALRM Signal = "ALRM"
|
|
SIGFPE Signal = "FPE"
|
|
SIGHUP Signal = "HUP"
|
|
SIGILL Signal = "ILL"
|
|
SIGINT Signal = "INT"
|
|
SIGKILL Signal = "KILL"
|
|
SIGPIPE Signal = "PIPE"
|
|
SIGQUIT Signal = "QUIT"
|
|
SIGSEGV Signal = "SEGV"
|
|
SIGTERM Signal = "TERM"
|
|
SIGUSR1 Signal = "USR1"
|
|
SIGUSR2 Signal = "USR2"
|
|
)
|
|
|
|
// DefaultHandler is the default Handler used by Serve.
|
|
var DefaultHandler Handler
|
|
|
|
// Option is a functional option handler for Server.
|
|
type Option func(*Server) error
|
|
|
|
// Handler is a callback for handling established SSH sessions.
|
|
type Handler func(Session)
|
|
|
|
// PublicKeyHandler is a callback for performing public key authentication.
|
|
type PublicKeyHandler func(ctx Context, key PublicKey) bool
|
|
|
|
// PasswordHandler is a callback for performing password authentication.
|
|
type PasswordHandler func(ctx Context, password string) bool
|
|
|
|
// KeyboardInteractiveHandler is a callback for performing keyboard-interactive authentication.
|
|
type KeyboardInteractiveHandler func(ctx Context, challenger gossh.KeyboardInteractiveChallenge) bool
|
|
|
|
// PtyCallback is a hook for allowing PTY sessions.
|
|
type PtyCallback func(ctx Context, pty Pty) bool
|
|
|
|
// SessionRequestCallback is a callback for allowing or denying SSH sessions.
|
|
type SessionRequestCallback func(sess Session, requestType string) bool
|
|
|
|
// ConnCallback is a hook for new connections before handling.
|
|
// It allows wrapping for timeouts and limiting by returning
|
|
// the net.Conn that will be used as the underlying connection.
|
|
type ConnCallback func(ctx Context, conn net.Conn) net.Conn
|
|
|
|
// LocalPortForwardingCallback is a hook for allowing port forwarding
|
|
type LocalPortForwardingCallback func(ctx Context, destinationHost string, destinationPort uint32) bool
|
|
|
|
// ReversePortForwardingCallback is a hook for allowing reverse port forwarding
|
|
type ReversePortForwardingCallback func(ctx Context, bindHost string, bindPort uint32) bool
|
|
|
|
// ServerConfigCallback is a hook for creating custom default server configs
|
|
type ServerConfigCallback func(ctx Context) *gossh.ServerConfig
|
|
|
|
// ConnectionFailedCallback is a hook for reporting failed connections
|
|
// Please note: the net.Conn is likely to be closed at this point
|
|
type ConnectionFailedCallback func(conn net.Conn, err error)
|
|
|
|
// Window represents the size of a PTY window.
|
|
type Window struct {
|
|
Width int
|
|
Height int
|
|
}
|
|
|
|
// Pty represents a PTY request and configuration.
|
|
type Pty struct {
|
|
Term string
|
|
Window Window
|
|
// HELP WANTED: terminal modes!
|
|
}
|
|
|
|
// Serve accepts incoming SSH connections on the listener l, creating a new
|
|
// connection goroutine for each. The connection goroutines read requests and
|
|
// then calls handler to handle sessions. Handler is typically nil, in which
|
|
// case the DefaultHandler is used.
|
|
func Serve(l net.Listener, handler Handler, options ...Option) error {
|
|
srv := &Server{Handler: handler}
|
|
for _, option := range options {
|
|
if err := srv.SetOption(option); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return srv.Serve(l)
|
|
}
|
|
|
|
// ListenAndServe listens on the TCP network address addr and then calls Serve
|
|
// with handler to handle sessions on incoming connections. Handler is typically
|
|
// nil, in which case the DefaultHandler is used.
|
|
func ListenAndServe(addr string, handler Handler, options ...Option) error {
|
|
srv := &Server{Addr: addr, Handler: handler}
|
|
for _, option := range options {
|
|
if err := srv.SetOption(option); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return srv.ListenAndServe()
|
|
}
|
|
|
|
// Handle registers the handler as the DefaultHandler.
|
|
func Handle(handler Handler) {
|
|
DefaultHandler = handler
|
|
}
|
|
|
|
// KeysEqual is constant time compare of the keys to avoid timing attacks.
|
|
func KeysEqual(ak, bk PublicKey) bool {
|
|
|
|
//avoid panic if one of the keys is nil, return false instead
|
|
if ak == nil || bk == nil {
|
|
return false
|
|
}
|
|
|
|
a := ak.Marshal()
|
|
b := bk.Marshal()
|
|
return (len(a) == len(b) && subtle.ConstantTimeCompare(a, b) == 1)
|
|
}
|