Skip to content

Commit d6f0a8c

Browse files
bradfitzrolandshoemaker
authored andcommitted
ssh: add ServerConfig.NoClientAuthCallback
It was possible to accept auth type "none" before, but not dynamically at runtime as a function of the ConnMetadata like the other auth types' callback hooks. Fixes golang/go#51994 Change-Id: I83ea80901d4977d8f78523e3d1e16e0a7df5b172 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/395314 Reviewed-by: Roland Shoemaker <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Julie Qiu <[email protected]>
1 parent 4161e89 commit d6f0a8c

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

ssh/server.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,16 @@ type ServerConfig struct {
6868

6969
// NoClientAuth is true if clients are allowed to connect without
7070
// authenticating.
71+
// To determine NoClientAuth at runtime, set NoClientAuth to true
72+
// and the optional NoClientAuthCallback to a non-nil value.
7173
NoClientAuth bool
7274

75+
// NoClientAuthCallback, if non-nil, is called when a user
76+
// attempts to authenticate with auth method "none".
77+
// NoClientAuth must also be set to true for this be used, or
78+
// this func is unused.
79+
NoClientAuthCallback func(ConnMetadata) (*Permissions, error)
80+
7381
// MaxAuthTries specifies the maximum number of authentication attempts
7482
// permitted per connection. If set to a negative number, the number of
7583
// attempts are unlimited. If set to zero, the number of attempts are limited
@@ -455,7 +463,11 @@ userAuthLoop:
455463
switch userAuthReq.Method {
456464
case "none":
457465
if config.NoClientAuth {
458-
authErr = nil
466+
if config.NoClientAuthCallback != nil {
467+
perms, authErr = config.NoClientAuthCallback(s)
468+
} else {
469+
authErr = nil
470+
}
459471
}
460472

461473
// allow initial attempt of 'none' without penalty

ssh/session_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,3 +779,54 @@ func TestHostKeyAlgorithms(t *testing.T) {
779779
t.Fatal("succeeded connecting with unknown hostkey algorithm")
780780
}
781781
}
782+
783+
func TestServerClientAuthCallback(t *testing.T) {
784+
c1, c2, err := netPipe()
785+
if err != nil {
786+
t.Fatalf("netPipe: %v", err)
787+
}
788+
defer c1.Close()
789+
defer c2.Close()
790+
791+
userCh := make(chan string, 1)
792+
793+
serverConf := &ServerConfig{
794+
NoClientAuth: true,
795+
NoClientAuthCallback: func(conn ConnMetadata) (*Permissions, error) {
796+
userCh <- conn.User()
797+
return nil, nil
798+
},
799+
}
800+
const someUsername = "some-username"
801+
802+
serverConf.AddHostKey(testSigners["ecdsa"])
803+
clientConf := &ClientConfig{
804+
HostKeyCallback: InsecureIgnoreHostKey(),
805+
User: someUsername,
806+
}
807+
808+
go func() {
809+
_, chans, reqs, err := NewServerConn(c1, serverConf)
810+
if err != nil {
811+
t.Errorf("server handshake: %v", err)
812+
userCh <- "error"
813+
return
814+
}
815+
go DiscardRequests(reqs)
816+
for ch := range chans {
817+
ch.Reject(Prohibited, "")
818+
}
819+
}()
820+
821+
conn, _, _, err := NewClientConn(c2, "", clientConf)
822+
if err != nil {
823+
t.Fatalf("client handshake: %v", err)
824+
return
825+
}
826+
conn.Close()
827+
828+
got := <-userCh
829+
if got != someUsername {
830+
t.Errorf("username = %q; want %q", got, someUsername)
831+
}
832+
}

0 commit comments

Comments
 (0)