diff --git a/server.go b/server.go index 31e3353..a41902e 100644 --- a/server.go +++ b/server.go @@ -24,6 +24,7 @@ type Server struct { HostSigners []Signer // private keys for the host key, must have at least one Version string // server version to be sent before the initial handshake + KeyboardInteractiveHandler KeyboardInteractiveHandler // keyboard-interactive authentication handler PasswordHandler PasswordHandler // password authentication handler PublicKeyHandler PublicKeyHandler // public key authentication handler PtyCallback PtyCallback // callback for allowing PTY sessions, allows all if nil @@ -105,6 +106,14 @@ func (srv *Server) config(ctx Context) *gossh.ServerConfig { return ctx.Permissions().Permissions, nil } } + if srv.KeyboardInteractiveHandler != nil { + config.KeyboardInteractiveCallback = func(conn gossh.ConnMetadata, challenger gossh.KeyboardInteractiveChallenge) (*gossh.Permissions, error) { + if ok := srv.KeyboardInteractiveHandler(ctx, challenger); !ok { + return ctx.Permissions().Permissions, fmt.Errorf("permission denied") + } + return ctx.Permissions().Permissions, nil + } + } return config } diff --git a/ssh.go b/ssh.go index 88cf934..1d339c4 100644 --- a/ssh.go +++ b/ssh.go @@ -2,6 +2,7 @@ package ssh import ( "crypto/subtle" + gossh "golang.org/x/crypto/ssh" "net" ) @@ -39,6 +40,9 @@ 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