mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-14 06:57:31 +00:00
ssh/tailssh: add password-forcing workaround for buggy SSH clients
If the username includes a suffix of +password, then we accept password auth and just let them in like it were no auth. This exists purely for SSH clients that get confused by seeing success to their initial auth type "none". Co-authored-by: Maisem Ali <maisem@tailscale.com> Change-Id: I616d4c64d042449fb164f615012f3bae246e91ec Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
c070d39287
commit
e24de8a617
@@ -335,10 +335,12 @@ func TestSSHAuthFlow(t *testing.T) {
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
state *localState
|
||||
wantBanners []string
|
||||
authErr bool
|
||||
name string
|
||||
sshUser string // defaults to alice
|
||||
state *localState
|
||||
wantBanners []string
|
||||
usesPassword bool
|
||||
authErr bool
|
||||
}{
|
||||
{
|
||||
name: "no-policy",
|
||||
@@ -410,6 +412,16 @@ func TestSSHAuthFlow(t *testing.T) {
|
||||
wantBanners: []string{"First", "Go Away!"},
|
||||
authErr: true,
|
||||
},
|
||||
{
|
||||
name: "force-password-auth",
|
||||
sshUser: "alice+password",
|
||||
state: &localState{
|
||||
sshEnabled: true,
|
||||
matchingRule: acceptRule,
|
||||
},
|
||||
usesPassword: true,
|
||||
wantBanners: []string{"Welcome to Tailscale SSH!"},
|
||||
},
|
||||
}
|
||||
s := &server{
|
||||
logf: logger.Discard,
|
||||
@@ -420,9 +432,24 @@ func TestSSHAuthFlow(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
sc, dc := nettest.NewTCPConn(src, dst, 1024)
|
||||
s.lb = tc.state
|
||||
sshUser := "alice"
|
||||
if tc.sshUser != "" {
|
||||
sshUser = tc.sshUser
|
||||
}
|
||||
var passwordUsed atomic.Bool
|
||||
cfg := &gossh.ClientConfig{
|
||||
User: "alice",
|
||||
User: sshUser,
|
||||
HostKeyCallback: gossh.InsecureIgnoreHostKey(),
|
||||
Auth: []gossh.AuthMethod{
|
||||
gossh.PasswordCallback(func() (secret string, err error) {
|
||||
if !tc.usesPassword {
|
||||
t.Error("unexpected use of PasswordCallback")
|
||||
return "", errors.New("unexpected use of PasswordCallback")
|
||||
}
|
||||
passwordUsed.Store(true)
|
||||
return "any-pass", nil
|
||||
}),
|
||||
},
|
||||
BannerCallback: func(message string) error {
|
||||
if len(tc.wantBanners) == 0 {
|
||||
t.Errorf("unexpected banner: %q", message)
|
||||
|
Reference in New Issue
Block a user