Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.8 KiB
123 lines
3.8 KiB
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 |
|
|
|
// 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) |
|
}
|
|
|