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

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

`

1293

1293

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

`

1294

1294

` }

`

1295

1295

`}

`

``

1296

+

``

1297

`+

func TestKeyboardInteractiveAuthEarlyFail(t *testing.T) {

`

``

1298

`+

const maxAuthTries = 2

`

``

1299

+

``

1300

`+

c1, c2, err := netPipe()

`

``

1301

`+

if err != nil {

`

``

1302

`+

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

`

``

1303

`+

}

`

``

1304

`+

defer c1.Close()

`

``

1305

`+

defer c2.Close()

`

``

1306

+

``

1307

`+

// Start testserver

`

``

1308

`+

serverConfig := &ServerConfig{

`

``

1309

`+

MaxAuthTries: maxAuthTries,

`

``

1310

`+

KeyboardInteractiveCallback: func(c ConnMetadata,

`

``

1311

`+

client KeyboardInteractiveChallenge) (*Permissions, error) {

`

``

1312

`+

// Fail keyboard-interactive authentication early before

`

``

1313

`+

// any prompt is sent to client.

`

``

1314

`+

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

`

``

1315

`+

},

`

``

1316

`+

PasswordCallback: func(c ConnMetadata,

`

``

1317

`+

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

`

``

1318

`+

if string(pass) == clientPassword {

`

``

1319

`+

return nil, nil

`

``

1320

`+

}

`

``

1321

`+

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

`

``

1322

`+

},

`

``

1323

`+

}

`

``

1324

`+

serverConfig.AddHostKey(testSigners["rsa"])

`

``

1325

+

``

1326

`+

serverDone := make(chan struct{})

`

``

1327

`+

go func() {

`

``

1328

`+

defer func() { serverDone <- struct{}{} }()

`

``

1329

`+

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

`

``

1330

`+

if err != nil {

`

``

1331

`+

return

`

``

1332

`+

}

`

``

1333

`+

_ = conn.Close()

`

``

1334

+

``

1335

`+

discarderDone := make(chan struct{})

`

``

1336

`+

go func() {

`

``

1337

`+

defer func() { discarderDone <- struct{}{} }()

`

``

1338

`+

DiscardRequests(reqs)

`

``

1339

`+

}()

`

``

1340

`+

for newChannel := range chans {

`

``

1341

`+

newChannel.Reject(Prohibited,

`

``

1342

`+

"testserver not accepting requests")

`

``

1343

`+

}

`

``

1344

+

``

1345

`+

<-discarderDone

`

``

1346

`+

}()

`

``

1347

+

``

1348

`+

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

`

``

1349

`+

// PasswordCallback() to be called and connection to succeed.

`

``

1350

`+

passwordCallbackCalled := false

`

``

1351

`+

clientConfig := &ClientConfig{

`

``

1352

`+

User: "testuser",

`

``

1353

`+

Auth: []AuthMethod{

`

``

1354

`+

RetryableAuthMethod(KeyboardInteractive(func(name,

`

``

1355

`+

instruction string, questions []string,

`

``

1356

`+

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

`

``

1357

`+

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

`

``

1358

`+

return []string{clientPassword}, nil

`

``

1359

`+

}), maxAuthTries),

`

``

1360

`+

RetryableAuthMethod(PasswordCallback(func() (secret string,

`

``

1361

`+

err error) {

`

``

1362

`+

t.Logf("PasswordCallback()")

`

``

1363

`+

passwordCallbackCalled = true

`

``

1364

`+

return clientPassword, nil

`

``

1365

`+

}), maxAuthTries),

`

``

1366

`+

},

`

``

1367

`+

HostKeyCallback: InsecureIgnoreHostKey(),

`

``

1368

`+

}

`

``

1369

+

``

1370

`+

conn, _, _, err := NewClientConn(c1, "", clientConfig)

`

``

1371

`+

if err != nil {

`

``

1372

`+

t.Errorf("unexpected NewClientConn() error: %v", err)

`

``

1373

`+

}

`

``

1374

`+

if conn != nil {

`

``

1375

`+

conn.Close()

`

``

1376

`+

}

`

``

1377

+

``

1378

`+

// Wait for server to finish.

`

``

1379

`+

<-serverDone

`

``

1380

+

``

1381

`+

if !passwordCallbackCalled {

`

``

1382

`+

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

`

``

1383

`+

}

`

``

1384

`+

}

`