From f6ff00ebef0e6e6f324e1199f69bb2b9d8dcf2ed Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 8 May 2019 20:28:04 +0800 Subject: [PATCH 1/4] [Update] Support partial success state --- server.go | 36 ++++++++++++++++++++++++++---------- ssh.go | 10 ++++++++++ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/server.go b/server.go index 3b6cd20..8b0e1c4 100644 --- a/server.go +++ b/server.go @@ -90,37 +90,53 @@ func (srv *Server) config(ctx Context) *gossh.ServerConfig { for _, signer := range srv.HostSigners { config.AddHostKey(signer) } - if srv.PasswordHandler == nil && srv.PublicKeyHandler == nil { - config.NoClientAuth = true - } + //if srv.PasswordHandler == nil && srv.PublicKeyHandler == nil { + // config.NoClientAuth = true + //} if srv.Version != "" { config.ServerVersion = "SSH-2.0-" + srv.Version } if srv.PasswordHandler != nil { config.PasswordCallback = func(conn gossh.ConnMetadata, password []byte) (*gossh.Permissions, error) { applyConnMetadata(ctx, conn) - if ok := srv.PasswordHandler(ctx, string(password)); !ok { + res := srv.PasswordHandler(ctx, string(password)) + switch res { + case AuthSuccessful: + return ctx.Permissions().Permissions, nil + case AuthPartiallySuccessful: + return ctx.Permissions().Permissions, gossh.ErrPartialSuccess + default: return ctx.Permissions().Permissions, fmt.Errorf("permission denied") } - return ctx.Permissions().Permissions, nil } } if srv.PublicKeyHandler != nil { config.PublicKeyCallback = func(conn gossh.ConnMetadata, key gossh.PublicKey) (*gossh.Permissions, error) { applyConnMetadata(ctx, conn) - if ok := srv.PublicKeyHandler(ctx, key); !ok { + res := srv.PublicKeyHandler(ctx, key) + switch res { + case AuthSuccessful: + ctx.SetValue(ContextKeyPublicKey, key) + return ctx.Permissions().Permissions, nil + case AuthPartiallySuccessful: + ctx.SetValue(ContextKeyPublicKey, key) + return ctx.Permissions().Permissions, gossh.ErrPartialSuccess + default: return ctx.Permissions().Permissions, fmt.Errorf("permission denied") } - ctx.SetValue(ContextKeyPublicKey, key) - 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 { + res := srv.KeyboardInteractiveHandler(ctx, challenger) + switch res { + case AuthSuccessful: + return ctx.Permissions().Permissions, nil + case AuthPartiallySuccessful: + return ctx.Permissions().Permissions, gossh.ErrPartialSuccess + default: return ctx.Permissions().Permissions, fmt.Errorf("permission denied") } - return ctx.Permissions().Permissions, nil } } return config diff --git a/ssh.go b/ssh.go index aefb681..ab07987 100644 --- a/ssh.go +++ b/ssh.go @@ -26,6 +26,16 @@ const ( SIGUSR2 Signal = "USR2" ) +// AuthResult, use some code except bool, to mark +// auth state +type AuthResult int + +const ( + AuthFailed AuthResult = iota + AuthSuccessful + AuthPartiallySuccessful +) + // DefaultHandler is the default Handler used by Serve. var DefaultHandler Handler From 624e955a0ae6c0e82fe0095ad5276051483ae67d Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 9 May 2019 10:46:51 +0800 Subject: [PATCH 2/4] [Update] Modify handle return result type --- ssh.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ssh.go b/ssh.go index ab07987..8a1120c 100644 --- a/ssh.go +++ b/ssh.go @@ -49,13 +49,13 @@ type Handler func(Session) type SubsystemHandler func(Session) // PublicKeyHandler is a callback for performing public key authentication. -type PublicKeyHandler func(ctx Context, key PublicKey) bool +type PublicKeyHandler func(ctx Context, key PublicKey) AuthResult // PasswordHandler is a callback for performing password authentication. -type PasswordHandler func(ctx Context, password string) bool +type PasswordHandler func(ctx Context, password string) AuthResult // KeyboardInteractiveHandler is a callback for performing keyboard-interactive authentication. -type KeyboardInteractiveHandler func(ctx Context, challenger gossh.KeyboardInteractiveChallenge) bool +type KeyboardInteractiveHandler func(ctx Context, challenger gossh.KeyboardInteractiveChallenge) AuthResult // PtyCallback is a hook for allowing PTY sessions. type PtyCallback func(ctx Context, pty Pty) bool From 1c00c8e8b607f53b40cdcb98816d682b0d007d12 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 9 May 2019 14:50:47 +0800 Subject: [PATCH 3/4] [Update] Add next auth methods handler --- server.go | 7 +++++++ ssh.go | 3 +++ 2 files changed, 10 insertions(+) diff --git a/server.go b/server.go index 8b0e1c4..18419b8 100644 --- a/server.go +++ b/server.go @@ -27,6 +27,7 @@ type Server struct { KeyboardInteractiveHandler KeyboardInteractiveHandler // keyboard-interactive authentication handler PasswordHandler PasswordHandler // password authentication handler PublicKeyHandler PublicKeyHandler // public key authentication handler + NextAuthMethodsHandler NextAuthMethodsHandler // next auth methods handler for 2 step auth PtyCallback PtyCallback // callback for allowing PTY sessions, allows all if nil ConnCallback ConnCallback // optional callback for wrapping net.Conn before handling LocalPortForwardingCallback LocalPortForwardingCallback // callback for allowing local port forwarding, denies all if nil @@ -139,6 +140,12 @@ func (srv *Server) config(ctx Context) *gossh.ServerConfig { } } } + if srv.NextAuthMethodsHandler != nil { + config.NextAuthMethodsCallback = func(conn gossh.ConnMetadata) []string { + applyConnMetadata(ctx, conn) + return srv.NextAuthMethodsHandler(ctx) + } + } return config } diff --git a/ssh.go b/ssh.go index 8a1120c..f727b52 100644 --- a/ssh.go +++ b/ssh.go @@ -57,6 +57,9 @@ type PasswordHandler func(ctx Context, password string) AuthResult // KeyboardInteractiveHandler is a callback for performing keyboard-interactive authentication. type KeyboardInteractiveHandler func(ctx Context, challenger gossh.KeyboardInteractiveChallenge) AuthResult +// NextAuthMethodsHandler is a callback for performing 2 step auth +type NextAuthMethodsHandler func(ctx Context) []string + // PtyCallback is a hook for allowing PTY sessions. type PtyCallback func(ctx Context, pty Pty) bool From 162377ae907836e10afe1e04c43d3546dd3dcf17 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 22 Oct 2019 17:50:41 +0800 Subject: [PATCH 4/4] fix panic bug when not found any subsystem --- session.go | 1 + 1 file changed, 1 insertion(+) diff --git a/session.go b/session.go index c105aae..86a69ce 100644 --- a/session.go +++ b/session.go @@ -301,6 +301,7 @@ func (sess *session) handleRequests(reqs <-chan *gossh.Request) { handler, ok := sess.subsystemHandlers[subname] if !ok { req.Reply(false, nil) + continue } sess.handled = true req.Reply(true, nil)