crypto/ssh: return unexpected msg error when server fails keyboard-in… · golang/crypto@f2a8ba2 (original) (raw)

`@@ -15,6 +15,7 @@ import (

`

15

15

`"os"

`

16

16

`"runtime"

`

17

17

`"strings"

`

``

18

`+

"sync"

`

18

19

`"testing"

`

19

20

`)

`

20

21

``

`@@ -1293,3 +1294,84 @@ func TestCertAuthOpenSSHCompat(t *testing.T) {

`

1293

1294

`t.Fatalf("unable to dial remote side: %s", err)

`

1294

1295

` }

`

1295

1296

`}

`

``

1297

+

``

1298

`+

func TestKeyboardInteractiveAuthEarlyFail(t *testing.T) {

`

``

1299

`+

const maxAuthTries = 2

`

``

1300

+

``

1301

`+

c1, c2, err := netPipe()

`

``

1302

`+

if err != nil {

`

``

1303

`+

t.Fatalf("netPipe: %v", err)

`

``

1304

`+

}

`

``

1305

`+

defer c1.Close()

`

``

1306

`+

defer c2.Close()

`

``

1307

+

``

1308

`+

// Start testserver

`

``

1309

`+

go func() {

`

``

1310

`+

config := &ServerConfig{

`

``

1311

`+

MaxAuthTries: maxAuthTries,

`

``

1312

`+

KeyboardInteractiveCallback: func(c ConnMetadata,

`

``

1313

`+

client KeyboardInteractiveChallenge) (*Permissions, error) {

`

``

1314

`+

// Fail keyboard-interactive authentication early before

`

``

1315

`+

// any prompt is sent to client.

`

``

1316

`+

return nil, errors.New("keyboard-interactive auth failed")

`

``

1317

`+

},

`

``

1318

`+

PasswordCallback: func(c ConnMetadata,

`

``

1319

`+

pass []byte) (*Permissions, error) {

`

``

1320

`+

if string(pass) == clientPassword {

`

``

1321

`+

return nil, nil

`

``

1322

`+

}

`

``

1323

`+

return nil, errors.New("password auth failed")

`

``

1324

`+

},

`

``

1325

`+

}

`

``

1326

`+

config.AddHostKey(testSigners["rsa"])

`

``

1327

+

``

1328

`+

conn, chans, reqs, err := NewServerConn(c2, config)

`

``

1329

`+

if err != nil {

`

``

1330

`+

return

`

``

1331

`+

}

`

``

1332

`+

_ = conn.Close()

`

``

1333

+

``

1334

`+

var wg sync.WaitGroup

`

``

1335

`+

wg.Add(1)

`

``

1336

`+

go func() {

`

``

1337

`+

defer wg.Done()

`

``

1338

`+

DiscardRequests(reqs)

`

``

1339

`+

}()

`

``

1340

`+

for newChannel := range chans {

`

``

1341

`+

newChannel.Reject(Prohibited,

`

``

1342

`+

"testserver not accepting requests")

`

``

1343

`+

}

`

``

1344

`+

wg.Wait()

`

``

1345

`+

}()

`

``

1346

+

``

1347

`+

// Connect to testserver expect KeyboardInteractive() to be not called and

`

``

1348

`+

// PasswordCallback() to be called.

`

``

1349

`+

passwordCallbackCalled := false

`

``

1350

`+

cfg := &ClientConfig{

`

``

1351

`+

User: "testuser",

`

``

1352

`+

Auth: []AuthMethod{

`

``

1353

`+

RetryableAuthMethod(KeyboardInteractive(func(name,

`

``

1354

`+

instruction string, questions []string,

`

``

1355

`+

echos []bool) ([]string, error) {

`

``

1356

`+

t.Errorf("unexpected call to KeyboardInteractive()")

`

``

1357

`+

return []string{clientPassword}, nil

`

``

1358

`+

}), maxAuthTries),

`

``

1359

`+

RetryableAuthMethod(PasswordCallback(func() (secret string,

`

``

1360

`+

err error) {

`

``

1361

`+

t.Logf("PasswordCallback()")

`

``

1362

`+

passwordCallbackCalled = true

`

``

1363

`+

return clientPassword, nil

`

``

1364

`+

}), maxAuthTries),

`

``

1365

`+

},

`

``

1366

`+

HostKeyCallback: InsecureIgnoreHostKey(),

`

``

1367

`+

}

`

``

1368

+

``

1369

`+

conn, _, _, _ := NewClientConn(c1, "", cfg)

`

``

1370

`+

if conn != nil {

`

``

1371

`+

conn.Close()

`

``

1372

`+

}

`

``

1373

+

``

1374

`+

if !passwordCallbackCalled {

`

``

1375

`+

t.Errorf("expected PasswordCallback() to be called")

`

``

1376

`+

}

`

``

1377

`+

}

`