| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- 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) error
- type NoClientAuthHandler func(ctx Context) error
- type BannerHandler func(ctx Context) string
- // 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.
- //
- // See https://datatracker.ietf.org/doc/html/rfc4254#section-6.2
- //
- // Zero dimension parameters MUST be ignored. The character/row dimensions
- // override the pixel dimensions (when nonzero). Pixel dimensions refer
- // to the drawable area of the window.
- type Window struct {
- // Width is the number of columns.
- // It overrides WidthPixels.
- Width int
- // Height is the number of rows.
- // It overrides HeightPixels.
- Height int
- // WidthPixels is the drawable width of the window, in pixels.
- WidthPixels int
- // HeightPixels is the drawable height of the window, in pixels.
- HeightPixels int
- }
- // Pty represents a PTY request and configuration.
- type Pty struct {
- // Term is the TERM environment variable value.
- Term string
- // Window is the Window sent as part of the pty-req.
- Window Window
- // Modes represent a mapping of Terminal Mode opcode to value as it was
- // requested by the client as part of the pty-req. These are outlined as
- // part of https://datatracker.ietf.org/doc/html/rfc4254#section-8.
- //
- // The opcodes are defined as constants in golang.org/x/crypto/ssh (VINTR,VQUIT,etc.).
- // Boolean opcodes have values 0 or 1.
- Modes gossh.TerminalModes
- }
- // 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)
- }
|