client_auth_test.go 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ssh
  5. import (
  6. "bytes"
  7. "crypto/rand"
  8. "errors"
  9. "fmt"
  10. "io"
  11. "log"
  12. "net"
  13. "os"
  14. "runtime"
  15. "strings"
  16. "testing"
  17. )
  18. type keyboardInteractive map[string]string
  19. func (cr keyboardInteractive) Challenge(user string, instruction string, questions []string, echos []bool) ([]string, error) {
  20. var answers []string
  21. for _, q := range questions {
  22. answers = append(answers, cr[q])
  23. }
  24. return answers, nil
  25. }
  26. // reused internally by tests
  27. var clientPassword = "tiger"
  28. // tryAuth runs a handshake with a given config against an SSH server
  29. // with config serverConfig. Returns both client and server side errors.
  30. func tryAuth(t *testing.T, config *ClientConfig) error {
  31. err, _ := tryAuthBothSides(t, config, nil)
  32. return err
  33. }
  34. // tryAuthWithGSSAPIWithMICConfig runs a handshake with a given config against an SSH server
  35. // with a given GSSAPIWithMICConfig and config serverConfig. Returns both client and server side errors.
  36. func tryAuthWithGSSAPIWithMICConfig(t *testing.T, clientConfig *ClientConfig, gssAPIWithMICConfig *GSSAPIWithMICConfig) error {
  37. err, _ := tryAuthBothSides(t, clientConfig, gssAPIWithMICConfig)
  38. return err
  39. }
  40. // tryAuthBothSides runs the handshake and returns the resulting errors from both sides of the connection.
  41. func tryAuthBothSides(t *testing.T, config *ClientConfig, gssAPIWithMICConfig *GSSAPIWithMICConfig) (clientError error, serverAuthErrors []error) {
  42. c1, c2, err := netPipe()
  43. if err != nil {
  44. t.Fatalf("netPipe: %v", err)
  45. }
  46. defer c1.Close()
  47. defer c2.Close()
  48. certChecker := CertChecker{
  49. IsUserAuthority: func(k PublicKey) bool {
  50. return bytes.Equal(k.Marshal(), testPublicKeys["ecdsa"].Marshal())
  51. },
  52. UserKeyFallback: func(conn ConnMetadata, key PublicKey) (*Permissions, error) {
  53. if conn.User() == "testuser" && bytes.Equal(key.Marshal(), testPublicKeys["rsa"].Marshal()) {
  54. return nil, nil
  55. }
  56. return nil, fmt.Errorf("pubkey for %q not acceptable", conn.User())
  57. },
  58. IsRevoked: func(c *Certificate) bool {
  59. return c.Serial == 666
  60. },
  61. }
  62. serverConfig := &ServerConfig{
  63. PasswordCallback: func(conn ConnMetadata, pass []byte) (*Permissions, error) {
  64. if conn.User() == "testuser" && string(pass) == clientPassword {
  65. return nil, nil
  66. }
  67. return nil, errors.New("password auth failed")
  68. },
  69. PublicKeyCallback: certChecker.Authenticate,
  70. KeyboardInteractiveCallback: func(conn ConnMetadata, challenge KeyboardInteractiveChallenge) (*Permissions, error) {
  71. ans, err := challenge("user",
  72. "instruction",
  73. []string{"question1", "question2"},
  74. []bool{true, true})
  75. if err != nil {
  76. return nil, err
  77. }
  78. ok := conn.User() == "testuser" && ans[0] == "answer1" && ans[1] == "answer2"
  79. if ok {
  80. challenge("user", "motd", nil, nil)
  81. return nil, nil
  82. }
  83. return nil, errors.New("keyboard-interactive failed")
  84. },
  85. GSSAPIWithMICConfig: gssAPIWithMICConfig,
  86. }
  87. serverConfig.AddHostKey(testSigners["rsa"])
  88. serverConfig.AuthLogCallback = func(conn ConnMetadata, method string, err error) {
  89. serverAuthErrors = append(serverAuthErrors, err)
  90. }
  91. go newServer(c1, serverConfig)
  92. _, _, _, err = NewClientConn(c2, "", config)
  93. return err, serverAuthErrors
  94. }
  95. type loggingAlgorithmSigner struct {
  96. used []string
  97. AlgorithmSigner
  98. }
  99. func (l *loggingAlgorithmSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
  100. l.used = append(l.used, "[Sign]")
  101. return l.AlgorithmSigner.Sign(rand, data)
  102. }
  103. func (l *loggingAlgorithmSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
  104. l.used = append(l.used, algorithm)
  105. return l.AlgorithmSigner.SignWithAlgorithm(rand, data, algorithm)
  106. }
  107. func TestClientAuthPublicKey(t *testing.T) {
  108. signer := &loggingAlgorithmSigner{AlgorithmSigner: testSigners["rsa"].(AlgorithmSigner)}
  109. config := &ClientConfig{
  110. User: "testuser",
  111. Auth: []AuthMethod{
  112. PublicKeys(signer),
  113. },
  114. HostKeyCallback: InsecureIgnoreHostKey(),
  115. }
  116. if err := tryAuth(t, config); err != nil {
  117. t.Fatalf("unable to dial remote side: %s", err)
  118. }
  119. if len(signer.used) != 1 || signer.used[0] != KeyAlgoRSASHA256 {
  120. t.Errorf("unexpected Sign/SignWithAlgorithm calls: %q", signer.used)
  121. }
  122. }
  123. // TestClientAuthNoSHA2 tests a ssh-rsa Signer that doesn't implement AlgorithmSigner.
  124. func TestClientAuthNoSHA2(t *testing.T) {
  125. config := &ClientConfig{
  126. User: "testuser",
  127. Auth: []AuthMethod{
  128. PublicKeys(&legacyRSASigner{testSigners["rsa"]}),
  129. },
  130. HostKeyCallback: InsecureIgnoreHostKey(),
  131. }
  132. if err := tryAuth(t, config); err != nil {
  133. t.Fatalf("unable to dial remote side: %s", err)
  134. }
  135. }
  136. // TestClientAuthThirdKey checks that the third configured can succeed. If we
  137. // were to do three attempts for each key (rsa-sha2-256, rsa-sha2-512, ssh-rsa),
  138. // we'd hit the six maximum attempts before reaching it.
  139. func TestClientAuthThirdKey(t *testing.T) {
  140. config := &ClientConfig{
  141. User: "testuser",
  142. Auth: []AuthMethod{
  143. PublicKeys(testSigners["rsa-openssh-format"],
  144. testSigners["rsa-openssh-format"], testSigners["rsa"]),
  145. },
  146. HostKeyCallback: InsecureIgnoreHostKey(),
  147. }
  148. if err := tryAuth(t, config); err != nil {
  149. t.Fatalf("unable to dial remote side: %s", err)
  150. }
  151. }
  152. func TestAuthMethodPassword(t *testing.T) {
  153. config := &ClientConfig{
  154. User: "testuser",
  155. Auth: []AuthMethod{
  156. Password(clientPassword),
  157. },
  158. HostKeyCallback: InsecureIgnoreHostKey(),
  159. }
  160. if err := tryAuth(t, config); err != nil {
  161. t.Fatalf("unable to dial remote side: %s", err)
  162. }
  163. }
  164. func TestAuthMethodFallback(t *testing.T) {
  165. var passwordCalled bool
  166. config := &ClientConfig{
  167. User: "testuser",
  168. Auth: []AuthMethod{
  169. PublicKeys(testSigners["rsa"]),
  170. PasswordCallback(
  171. func() (string, error) {
  172. passwordCalled = true
  173. return "WRONG", nil
  174. }),
  175. },
  176. HostKeyCallback: InsecureIgnoreHostKey(),
  177. }
  178. if err := tryAuth(t, config); err != nil {
  179. t.Fatalf("unable to dial remote side: %s", err)
  180. }
  181. if passwordCalled {
  182. t.Errorf("password auth tried before public-key auth.")
  183. }
  184. }
  185. func TestAuthMethodWrongPassword(t *testing.T) {
  186. config := &ClientConfig{
  187. User: "testuser",
  188. Auth: []AuthMethod{
  189. Password("wrong"),
  190. PublicKeys(testSigners["rsa"]),
  191. },
  192. HostKeyCallback: InsecureIgnoreHostKey(),
  193. }
  194. if err := tryAuth(t, config); err != nil {
  195. t.Fatalf("unable to dial remote side: %s", err)
  196. }
  197. }
  198. func TestAuthMethodKeyboardInteractive(t *testing.T) {
  199. answers := keyboardInteractive(map[string]string{
  200. "question1": "answer1",
  201. "question2": "answer2",
  202. })
  203. config := &ClientConfig{
  204. User: "testuser",
  205. Auth: []AuthMethod{
  206. KeyboardInteractive(answers.Challenge),
  207. },
  208. HostKeyCallback: InsecureIgnoreHostKey(),
  209. }
  210. if err := tryAuth(t, config); err != nil {
  211. t.Fatalf("unable to dial remote side: %s", err)
  212. }
  213. }
  214. func TestAuthMethodWrongKeyboardInteractive(t *testing.T) {
  215. answers := keyboardInteractive(map[string]string{
  216. "question1": "answer1",
  217. "question2": "WRONG",
  218. })
  219. config := &ClientConfig{
  220. User: "testuser",
  221. Auth: []AuthMethod{
  222. KeyboardInteractive(answers.Challenge),
  223. },
  224. }
  225. if err := tryAuth(t, config); err == nil {
  226. t.Fatalf("wrong answers should not have authenticated with KeyboardInteractive")
  227. }
  228. }
  229. // the mock server will only authenticate ssh-rsa keys
  230. func TestAuthMethodInvalidPublicKey(t *testing.T) {
  231. config := &ClientConfig{
  232. User: "testuser",
  233. Auth: []AuthMethod{
  234. PublicKeys(testSigners["dsa"]),
  235. },
  236. }
  237. if err := tryAuth(t, config); err == nil {
  238. t.Fatalf("dsa private key should not have authenticated with rsa public key")
  239. }
  240. }
  241. // the client should authenticate with the second key
  242. func TestAuthMethodRSAandDSA(t *testing.T) {
  243. config := &ClientConfig{
  244. User: "testuser",
  245. Auth: []AuthMethod{
  246. PublicKeys(testSigners["dsa"], testSigners["rsa"]),
  247. },
  248. HostKeyCallback: InsecureIgnoreHostKey(),
  249. }
  250. if err := tryAuth(t, config); err != nil {
  251. t.Fatalf("client could not authenticate with rsa key: %v", err)
  252. }
  253. }
  254. type invalidAlgSigner struct {
  255. Signer
  256. }
  257. func (s *invalidAlgSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
  258. sig, err := s.Signer.Sign(rand, data)
  259. if sig != nil {
  260. sig.Format = "invalid"
  261. }
  262. return sig, err
  263. }
  264. func TestMethodInvalidAlgorithm(t *testing.T) {
  265. config := &ClientConfig{
  266. User: "testuser",
  267. Auth: []AuthMethod{
  268. PublicKeys(&invalidAlgSigner{testSigners["rsa"]}),
  269. },
  270. HostKeyCallback: InsecureIgnoreHostKey(),
  271. }
  272. err, serverErrors := tryAuthBothSides(t, config, nil)
  273. if err == nil {
  274. t.Fatalf("login succeeded")
  275. }
  276. found := false
  277. want := "algorithm \"invalid\""
  278. var errStrings []string
  279. for _, err := range serverErrors {
  280. found = found || (err != nil && strings.Contains(err.Error(), want))
  281. errStrings = append(errStrings, err.Error())
  282. }
  283. if !found {
  284. t.Errorf("server got error %q, want substring %q", errStrings, want)
  285. }
  286. }
  287. func TestClientHMAC(t *testing.T) {
  288. for _, mac := range supportedMACs {
  289. config := &ClientConfig{
  290. User: "testuser",
  291. Auth: []AuthMethod{
  292. PublicKeys(testSigners["rsa"]),
  293. },
  294. Config: Config{
  295. MACs: []string{mac},
  296. },
  297. HostKeyCallback: InsecureIgnoreHostKey(),
  298. }
  299. if err := tryAuth(t, config); err != nil {
  300. t.Fatalf("client could not authenticate with mac algo %s: %v", mac, err)
  301. }
  302. }
  303. }
  304. // issue 4285.
  305. func TestClientUnsupportedCipher(t *testing.T) {
  306. config := &ClientConfig{
  307. User: "testuser",
  308. Auth: []AuthMethod{
  309. PublicKeys(),
  310. },
  311. Config: Config{
  312. Ciphers: []string{"aes128-cbc"}, // not currently supported
  313. },
  314. }
  315. if err := tryAuth(t, config); err == nil {
  316. t.Errorf("expected no ciphers in common")
  317. }
  318. }
  319. func TestClientUnsupportedKex(t *testing.T) {
  320. if os.Getenv("GO_BUILDER_NAME") != "" {
  321. t.Skip("skipping known-flaky test on the Go build dashboard; see golang.org/issue/15198")
  322. }
  323. config := &ClientConfig{
  324. User: "testuser",
  325. Auth: []AuthMethod{
  326. PublicKeys(),
  327. },
  328. Config: Config{
  329. KeyExchanges: []string{"non-existent-kex"},
  330. },
  331. HostKeyCallback: InsecureIgnoreHostKey(),
  332. }
  333. if err := tryAuth(t, config); err == nil || !strings.Contains(err.Error(), "common algorithm") {
  334. t.Errorf("got %v, expected 'common algorithm'", err)
  335. }
  336. }
  337. func TestClientLoginCert(t *testing.T) {
  338. cert := &Certificate{
  339. Key: testPublicKeys["rsa"],
  340. ValidBefore: CertTimeInfinity,
  341. CertType: UserCert,
  342. }
  343. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  344. certSigner, err := NewCertSigner(cert, testSigners["rsa"])
  345. if err != nil {
  346. t.Fatalf("NewCertSigner: %v", err)
  347. }
  348. clientConfig := &ClientConfig{
  349. User: "user",
  350. HostKeyCallback: InsecureIgnoreHostKey(),
  351. }
  352. clientConfig.Auth = append(clientConfig.Auth, PublicKeys(certSigner))
  353. // should succeed
  354. if err := tryAuth(t, clientConfig); err != nil {
  355. t.Errorf("cert login failed: %v", err)
  356. }
  357. // corrupted signature
  358. cert.Signature.Blob[0]++
  359. if err := tryAuth(t, clientConfig); err == nil {
  360. t.Errorf("cert login passed with corrupted sig")
  361. }
  362. // revoked
  363. cert.Serial = 666
  364. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  365. if err := tryAuth(t, clientConfig); err == nil {
  366. t.Errorf("revoked cert login succeeded")
  367. }
  368. cert.Serial = 1
  369. // sign with wrong key
  370. cert.SignCert(rand.Reader, testSigners["dsa"])
  371. if err := tryAuth(t, clientConfig); err == nil {
  372. t.Errorf("cert login passed with non-authoritative key")
  373. }
  374. // host cert
  375. cert.CertType = HostCert
  376. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  377. if err := tryAuth(t, clientConfig); err == nil {
  378. t.Errorf("cert login passed with wrong type")
  379. }
  380. cert.CertType = UserCert
  381. // principal specified
  382. cert.ValidPrincipals = []string{"user"}
  383. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  384. if err := tryAuth(t, clientConfig); err != nil {
  385. t.Errorf("cert login failed: %v", err)
  386. }
  387. // wrong principal specified
  388. cert.ValidPrincipals = []string{"fred"}
  389. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  390. if err := tryAuth(t, clientConfig); err == nil {
  391. t.Errorf("cert login passed with wrong principal")
  392. }
  393. cert.ValidPrincipals = nil
  394. // added critical option
  395. cert.CriticalOptions = map[string]string{"root-access": "yes"}
  396. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  397. if err := tryAuth(t, clientConfig); err == nil {
  398. t.Errorf("cert login passed with unrecognized critical option")
  399. }
  400. // allowed source address
  401. cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42/24,::42/120"}
  402. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  403. if err := tryAuth(t, clientConfig); err != nil {
  404. t.Errorf("cert login with source-address failed: %v", err)
  405. }
  406. // disallowed source address
  407. cert.CriticalOptions = map[string]string{"source-address": "127.0.0.42,::42"}
  408. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  409. if err := tryAuth(t, clientConfig); err == nil {
  410. t.Errorf("cert login with source-address succeeded")
  411. }
  412. }
  413. func testPermissionsPassing(withPermissions bool, t *testing.T) {
  414. serverConfig := &ServerConfig{
  415. PublicKeyCallback: func(conn ConnMetadata, key PublicKey) (*Permissions, error) {
  416. if conn.User() == "nopermissions" {
  417. return nil, nil
  418. }
  419. return &Permissions{}, nil
  420. },
  421. }
  422. serverConfig.AddHostKey(testSigners["rsa"])
  423. clientConfig := &ClientConfig{
  424. Auth: []AuthMethod{
  425. PublicKeys(testSigners["rsa"]),
  426. },
  427. HostKeyCallback: InsecureIgnoreHostKey(),
  428. }
  429. if withPermissions {
  430. clientConfig.User = "permissions"
  431. } else {
  432. clientConfig.User = "nopermissions"
  433. }
  434. c1, c2, err := netPipe()
  435. if err != nil {
  436. t.Fatalf("netPipe: %v", err)
  437. }
  438. defer c1.Close()
  439. defer c2.Close()
  440. go NewClientConn(c2, "", clientConfig)
  441. serverConn, err := newServer(c1, serverConfig)
  442. if err != nil {
  443. t.Fatal(err)
  444. }
  445. if p := serverConn.Permissions; (p != nil) != withPermissions {
  446. t.Fatalf("withPermissions is %t, but Permissions object is %#v", withPermissions, p)
  447. }
  448. }
  449. func TestPermissionsPassing(t *testing.T) {
  450. testPermissionsPassing(true, t)
  451. }
  452. func TestNoPermissionsPassing(t *testing.T) {
  453. testPermissionsPassing(false, t)
  454. }
  455. func TestRetryableAuth(t *testing.T) {
  456. n := 0
  457. passwords := []string{"WRONG1", "WRONG2"}
  458. config := &ClientConfig{
  459. User: "testuser",
  460. Auth: []AuthMethod{
  461. RetryableAuthMethod(PasswordCallback(func() (string, error) {
  462. p := passwords[n]
  463. n++
  464. return p, nil
  465. }), 2),
  466. PublicKeys(testSigners["rsa"]),
  467. },
  468. HostKeyCallback: InsecureIgnoreHostKey(),
  469. }
  470. if err := tryAuth(t, config); err != nil {
  471. t.Fatalf("unable to dial remote side: %s", err)
  472. }
  473. if n != 2 {
  474. t.Fatalf("Did not try all passwords")
  475. }
  476. }
  477. func ExampleRetryableAuthMethod() {
  478. user := "testuser"
  479. NumberOfPrompts := 3
  480. // Normally this would be a callback that prompts the user to answer the
  481. // provided questions
  482. Cb := func(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
  483. return []string{"answer1", "answer2"}, nil
  484. }
  485. config := &ClientConfig{
  486. HostKeyCallback: InsecureIgnoreHostKey(),
  487. User: user,
  488. Auth: []AuthMethod{
  489. RetryableAuthMethod(KeyboardInteractiveChallenge(Cb), NumberOfPrompts),
  490. },
  491. }
  492. host := "mysshserver"
  493. netConn, err := net.Dial("tcp", host)
  494. if err != nil {
  495. log.Fatal(err)
  496. }
  497. sshConn, _, _, err := NewClientConn(netConn, host, config)
  498. if err != nil {
  499. log.Fatal(err)
  500. }
  501. _ = sshConn
  502. }
  503. // Test if username is received on server side when NoClientAuth is used
  504. func TestClientAuthNone(t *testing.T) {
  505. user := "testuser"
  506. serverConfig := &ServerConfig{
  507. NoClientAuth: true,
  508. }
  509. serverConfig.AddHostKey(testSigners["rsa"])
  510. clientConfig := &ClientConfig{
  511. User: user,
  512. HostKeyCallback: InsecureIgnoreHostKey(),
  513. }
  514. c1, c2, err := netPipe()
  515. if err != nil {
  516. t.Fatalf("netPipe: %v", err)
  517. }
  518. defer c1.Close()
  519. defer c2.Close()
  520. go NewClientConn(c2, "", clientConfig)
  521. serverConn, err := newServer(c1, serverConfig)
  522. if err != nil {
  523. t.Fatalf("newServer: %v", err)
  524. }
  525. if serverConn.User() != user {
  526. t.Fatalf("server: got %q, want %q", serverConn.User(), user)
  527. }
  528. }
  529. // Test if authentication attempts are limited on server when MaxAuthTries is set
  530. func TestClientAuthMaxAuthTries(t *testing.T) {
  531. user := "testuser"
  532. serverConfig := &ServerConfig{
  533. MaxAuthTries: 2,
  534. PasswordCallback: func(conn ConnMetadata, pass []byte) (*Permissions, error) {
  535. if conn.User() == "testuser" && string(pass) == "right" {
  536. return nil, nil
  537. }
  538. return nil, errors.New("password auth failed")
  539. },
  540. }
  541. serverConfig.AddHostKey(testSigners["rsa"])
  542. expectedErr := fmt.Errorf("ssh: handshake failed: %v", &disconnectMsg{
  543. Reason: 2,
  544. Message: "too many authentication failures",
  545. })
  546. for tries := 2; tries < 4; tries++ {
  547. n := tries
  548. clientConfig := &ClientConfig{
  549. User: user,
  550. Auth: []AuthMethod{
  551. RetryableAuthMethod(PasswordCallback(func() (string, error) {
  552. n--
  553. if n == 0 {
  554. return "right", nil
  555. }
  556. return "wrong", nil
  557. }), tries),
  558. },
  559. HostKeyCallback: InsecureIgnoreHostKey(),
  560. }
  561. c1, c2, err := netPipe()
  562. if err != nil {
  563. t.Fatalf("netPipe: %v", err)
  564. }
  565. defer c1.Close()
  566. defer c2.Close()
  567. errCh := make(chan error, 1)
  568. go func() {
  569. _, err := newServer(c1, serverConfig)
  570. errCh <- err
  571. }()
  572. _, _, _, cliErr := NewClientConn(c2, "", clientConfig)
  573. srvErr := <-errCh
  574. if tries > serverConfig.MaxAuthTries {
  575. if cliErr == nil {
  576. t.Fatalf("client: got no error, want %s", expectedErr)
  577. } else if cliErr.Error() != expectedErr.Error() {
  578. t.Fatalf("client: got %s, want %s", err, expectedErr)
  579. }
  580. var authErr *ServerAuthError
  581. if !errors.As(srvErr, &authErr) {
  582. t.Errorf("expected ServerAuthError, got: %v", srvErr)
  583. }
  584. } else {
  585. if cliErr != nil {
  586. t.Fatalf("client: got %s, want no error", cliErr)
  587. }
  588. }
  589. }
  590. }
  591. // Test if authentication attempts are correctly limited on server
  592. // when more public keys are provided then MaxAuthTries
  593. func TestClientAuthMaxAuthTriesPublicKey(t *testing.T) {
  594. signers := []Signer{}
  595. for i := 0; i < 6; i++ {
  596. signers = append(signers, testSigners["dsa"])
  597. }
  598. validConfig := &ClientConfig{
  599. User: "testuser",
  600. Auth: []AuthMethod{
  601. PublicKeys(append([]Signer{testSigners["rsa"]}, signers...)...),
  602. },
  603. HostKeyCallback: InsecureIgnoreHostKey(),
  604. }
  605. if err := tryAuth(t, validConfig); err != nil {
  606. t.Fatalf("unable to dial remote side: %s", err)
  607. }
  608. expectedErr := fmt.Errorf("ssh: handshake failed: %v", &disconnectMsg{
  609. Reason: 2,
  610. Message: "too many authentication failures",
  611. })
  612. invalidConfig := &ClientConfig{
  613. User: "testuser",
  614. Auth: []AuthMethod{
  615. PublicKeys(append(signers, testSigners["rsa"])...),
  616. },
  617. HostKeyCallback: InsecureIgnoreHostKey(),
  618. }
  619. if err := tryAuth(t, invalidConfig); err == nil {
  620. t.Fatalf("client: got no error, want %s", expectedErr)
  621. } else if err.Error() != expectedErr.Error() {
  622. // On Windows we can see a WSAECONNABORTED error
  623. // if the client writes another authentication request
  624. // before the client goroutine reads the disconnection
  625. // message. See issue 50805.
  626. if runtime.GOOS == "windows" && strings.Contains(err.Error(), "wsarecv: An established connection was aborted") {
  627. // OK.
  628. } else {
  629. t.Fatalf("client: got %s, want %s", err, expectedErr)
  630. }
  631. }
  632. }
  633. // Test whether authentication errors are being properly logged if all
  634. // authentication methods have been exhausted
  635. func TestClientAuthErrorList(t *testing.T) {
  636. publicKeyErr := errors.New("This is an error from PublicKeyCallback")
  637. clientConfig := &ClientConfig{
  638. Auth: []AuthMethod{
  639. PublicKeys(testSigners["rsa"]),
  640. },
  641. HostKeyCallback: InsecureIgnoreHostKey(),
  642. }
  643. serverConfig := &ServerConfig{
  644. PublicKeyCallback: func(_ ConnMetadata, _ PublicKey) (*Permissions, error) {
  645. return nil, publicKeyErr
  646. },
  647. }
  648. serverConfig.AddHostKey(testSigners["rsa"])
  649. c1, c2, err := netPipe()
  650. if err != nil {
  651. t.Fatalf("netPipe: %v", err)
  652. }
  653. defer c1.Close()
  654. defer c2.Close()
  655. go NewClientConn(c2, "", clientConfig)
  656. _, err = newServer(c1, serverConfig)
  657. if err == nil {
  658. t.Fatal("newServer: got nil, expected errors")
  659. }
  660. authErrs, ok := err.(*ServerAuthError)
  661. if !ok {
  662. t.Fatalf("errors: got %T, want *ssh.ServerAuthError", err)
  663. }
  664. for i, e := range authErrs.Errors {
  665. switch i {
  666. case 0:
  667. if e != ErrNoAuth {
  668. t.Fatalf("errors: got error %v, want ErrNoAuth", e)
  669. }
  670. case 1:
  671. if e != publicKeyErr {
  672. t.Fatalf("errors: got %v, want %v", e, publicKeyErr)
  673. }
  674. default:
  675. t.Fatalf("errors: got %v, expected 2 errors", authErrs.Errors)
  676. }
  677. }
  678. }
  679. func TestAuthMethodGSSAPIWithMIC(t *testing.T) {
  680. type testcase struct {
  681. config *ClientConfig
  682. gssConfig *GSSAPIWithMICConfig
  683. clientWantErr string
  684. serverWantErr string
  685. }
  686. testcases := []*testcase{
  687. {
  688. config: &ClientConfig{
  689. User: "testuser",
  690. Auth: []AuthMethod{
  691. GSSAPIWithMICAuthMethod(
  692. &FakeClient{
  693. exchanges: []*exchange{
  694. {
  695. outToken: "client-valid-token-1",
  696. },
  697. {
  698. expectedToken: "server-valid-token-1",
  699. },
  700. },
  701. mic: []byte("valid-mic"),
  702. maxRound: 2,
  703. }, "testtarget",
  704. ),
  705. },
  706. HostKeyCallback: InsecureIgnoreHostKey(),
  707. },
  708. gssConfig: &GSSAPIWithMICConfig{
  709. AllowLogin: func(conn ConnMetadata, srcName string) (*Permissions, error) {
  710. if srcName != conn.User()+"@DOMAIN" {
  711. return nil, fmt.Errorf("srcName is %s, conn user is %s", srcName, conn.User())
  712. }
  713. return nil, nil
  714. },
  715. Server: &FakeServer{
  716. exchanges: []*exchange{
  717. {
  718. outToken: "server-valid-token-1",
  719. expectedToken: "client-valid-token-1",
  720. },
  721. },
  722. maxRound: 1,
  723. expectedMIC: []byte("valid-mic"),
  724. srcName: "testuser@DOMAIN",
  725. },
  726. },
  727. },
  728. {
  729. config: &ClientConfig{
  730. User: "testuser",
  731. Auth: []AuthMethod{
  732. GSSAPIWithMICAuthMethod(
  733. &FakeClient{
  734. exchanges: []*exchange{
  735. {
  736. outToken: "client-valid-token-1",
  737. },
  738. {
  739. expectedToken: "server-valid-token-1",
  740. },
  741. },
  742. mic: []byte("valid-mic"),
  743. maxRound: 2,
  744. }, "testtarget",
  745. ),
  746. },
  747. HostKeyCallback: InsecureIgnoreHostKey(),
  748. },
  749. gssConfig: &GSSAPIWithMICConfig{
  750. AllowLogin: func(conn ConnMetadata, srcName string) (*Permissions, error) {
  751. return nil, fmt.Errorf("user is not allowed to login")
  752. },
  753. Server: &FakeServer{
  754. exchanges: []*exchange{
  755. {
  756. outToken: "server-valid-token-1",
  757. expectedToken: "client-valid-token-1",
  758. },
  759. },
  760. maxRound: 1,
  761. expectedMIC: []byte("valid-mic"),
  762. srcName: "testuser@DOMAIN",
  763. },
  764. },
  765. serverWantErr: "user is not allowed to login",
  766. clientWantErr: "ssh: handshake failed: ssh: unable to authenticate",
  767. },
  768. {
  769. config: &ClientConfig{
  770. User: "testuser",
  771. Auth: []AuthMethod{
  772. GSSAPIWithMICAuthMethod(
  773. &FakeClient{
  774. exchanges: []*exchange{
  775. {
  776. outToken: "client-valid-token-1",
  777. },
  778. {
  779. expectedToken: "server-valid-token-1",
  780. },
  781. },
  782. mic: []byte("valid-mic"),
  783. maxRound: 2,
  784. }, "testtarget",
  785. ),
  786. },
  787. HostKeyCallback: InsecureIgnoreHostKey(),
  788. },
  789. gssConfig: &GSSAPIWithMICConfig{
  790. AllowLogin: func(conn ConnMetadata, srcName string) (*Permissions, error) {
  791. if srcName != conn.User() {
  792. return nil, fmt.Errorf("srcName is %s, conn user is %s", srcName, conn.User())
  793. }
  794. return nil, nil
  795. },
  796. Server: &FakeServer{
  797. exchanges: []*exchange{
  798. {
  799. outToken: "server-invalid-token-1",
  800. expectedToken: "client-valid-token-1",
  801. },
  802. },
  803. maxRound: 1,
  804. expectedMIC: []byte("valid-mic"),
  805. srcName: "testuser@DOMAIN",
  806. },
  807. },
  808. clientWantErr: "ssh: handshake failed: got \"server-invalid-token-1\", want token \"server-valid-token-1\"",
  809. },
  810. {
  811. config: &ClientConfig{
  812. User: "testuser",
  813. Auth: []AuthMethod{
  814. GSSAPIWithMICAuthMethod(
  815. &FakeClient{
  816. exchanges: []*exchange{
  817. {
  818. outToken: "client-valid-token-1",
  819. },
  820. {
  821. expectedToken: "server-valid-token-1",
  822. },
  823. },
  824. mic: []byte("invalid-mic"),
  825. maxRound: 2,
  826. }, "testtarget",
  827. ),
  828. },
  829. HostKeyCallback: InsecureIgnoreHostKey(),
  830. },
  831. gssConfig: &GSSAPIWithMICConfig{
  832. AllowLogin: func(conn ConnMetadata, srcName string) (*Permissions, error) {
  833. if srcName != conn.User() {
  834. return nil, fmt.Errorf("srcName is %s, conn user is %s", srcName, conn.User())
  835. }
  836. return nil, nil
  837. },
  838. Server: &FakeServer{
  839. exchanges: []*exchange{
  840. {
  841. outToken: "server-valid-token-1",
  842. expectedToken: "client-valid-token-1",
  843. },
  844. },
  845. maxRound: 1,
  846. expectedMIC: []byte("valid-mic"),
  847. srcName: "testuser@DOMAIN",
  848. },
  849. },
  850. serverWantErr: "got MICToken \"invalid-mic\", want \"valid-mic\"",
  851. clientWantErr: "ssh: handshake failed: ssh: unable to authenticate",
  852. },
  853. }
  854. for i, c := range testcases {
  855. clientErr, serverErrs := tryAuthBothSides(t, c.config, c.gssConfig)
  856. if (c.clientWantErr == "") != (clientErr == nil) {
  857. t.Fatalf("client got %v, want %s, case %d", clientErr, c.clientWantErr, i)
  858. }
  859. if (c.serverWantErr == "") != (len(serverErrs) == 2 && serverErrs[1] == nil || len(serverErrs) == 1) {
  860. t.Fatalf("server got err %v, want %s", serverErrs, c.serverWantErr)
  861. }
  862. if c.clientWantErr != "" {
  863. if clientErr != nil && !strings.Contains(clientErr.Error(), c.clientWantErr) {
  864. t.Fatalf("client got %v, want %s, case %d", clientErr, c.clientWantErr, i)
  865. }
  866. }
  867. found := false
  868. var errStrings []string
  869. if c.serverWantErr != "" {
  870. for _, err := range serverErrs {
  871. found = found || (err != nil && strings.Contains(err.Error(), c.serverWantErr))
  872. errStrings = append(errStrings, err.Error())
  873. }
  874. if !found {
  875. t.Errorf("server got error %q, want substring %q, case %d", errStrings, c.serverWantErr, i)
  876. }
  877. }
  878. }
  879. }
  880. func TestCompatibleAlgoAndSignatures(t *testing.T) {
  881. type testcase struct {
  882. algo string
  883. sigFormat string
  884. compatible bool
  885. }
  886. testcases := []*testcase{
  887. {
  888. KeyAlgoRSA,
  889. KeyAlgoRSA,
  890. true,
  891. },
  892. {
  893. KeyAlgoRSA,
  894. KeyAlgoRSASHA256,
  895. true,
  896. },
  897. {
  898. KeyAlgoRSA,
  899. KeyAlgoRSASHA512,
  900. true,
  901. },
  902. {
  903. KeyAlgoRSASHA256,
  904. KeyAlgoRSA,
  905. true,
  906. },
  907. {
  908. KeyAlgoRSASHA512,
  909. KeyAlgoRSA,
  910. true,
  911. },
  912. {
  913. KeyAlgoRSASHA512,
  914. KeyAlgoRSASHA256,
  915. true,
  916. },
  917. {
  918. KeyAlgoRSASHA256,
  919. KeyAlgoRSASHA512,
  920. true,
  921. },
  922. {
  923. KeyAlgoRSASHA512,
  924. KeyAlgoRSASHA512,
  925. true,
  926. },
  927. {
  928. CertAlgoRSAv01,
  929. KeyAlgoRSA,
  930. true,
  931. },
  932. {
  933. CertAlgoRSAv01,
  934. KeyAlgoRSASHA256,
  935. true,
  936. },
  937. {
  938. CertAlgoRSAv01,
  939. KeyAlgoRSASHA512,
  940. true,
  941. },
  942. {
  943. CertAlgoRSASHA256v01,
  944. KeyAlgoRSASHA512,
  945. true,
  946. },
  947. {
  948. CertAlgoRSASHA512v01,
  949. KeyAlgoRSASHA512,
  950. true,
  951. },
  952. {
  953. CertAlgoRSASHA512v01,
  954. KeyAlgoRSASHA256,
  955. true,
  956. },
  957. {
  958. CertAlgoRSASHA256v01,
  959. CertAlgoRSAv01,
  960. true,
  961. },
  962. {
  963. CertAlgoRSAv01,
  964. CertAlgoRSASHA512v01,
  965. true,
  966. },
  967. {
  968. KeyAlgoECDSA256,
  969. KeyAlgoRSA,
  970. false,
  971. },
  972. {
  973. KeyAlgoECDSA256,
  974. KeyAlgoECDSA521,
  975. false,
  976. },
  977. {
  978. KeyAlgoECDSA256,
  979. KeyAlgoECDSA256,
  980. true,
  981. },
  982. {
  983. KeyAlgoECDSA256,
  984. KeyAlgoED25519,
  985. false,
  986. },
  987. {
  988. KeyAlgoED25519,
  989. KeyAlgoED25519,
  990. true,
  991. },
  992. }
  993. for _, c := range testcases {
  994. if isAlgoCompatible(c.algo, c.sigFormat) != c.compatible {
  995. t.Errorf("algorithm %q, signature format %q, expected compatible to be %t", c.algo, c.sigFormat, c.compatible)
  996. }
  997. }
  998. }
  999. func TestPickSignatureAlgorithm(t *testing.T) {
  1000. type testcase struct {
  1001. name string
  1002. extensions map[string][]byte
  1003. }
  1004. cases := []testcase{
  1005. {
  1006. name: "server with empty server-sig-algs",
  1007. extensions: map[string][]byte{
  1008. "server-sig-algs": []byte(``),
  1009. },
  1010. },
  1011. {
  1012. name: "server with no server-sig-algs",
  1013. extensions: nil,
  1014. },
  1015. }
  1016. for _, c := range cases {
  1017. t.Run(c.name, func(t *testing.T) {
  1018. signer, ok := testSigners["rsa"].(MultiAlgorithmSigner)
  1019. if !ok {
  1020. t.Fatalf("rsa test signer does not implement the MultiAlgorithmSigner interface")
  1021. }
  1022. // The signer supports the public key algorithm which is then returned.
  1023. _, algo, err := pickSignatureAlgorithm(signer, c.extensions)
  1024. if err != nil {
  1025. t.Fatalf("got %v, want no error", err)
  1026. }
  1027. if algo != signer.PublicKey().Type() {
  1028. t.Fatalf("got algo %q, want %q", algo, signer.PublicKey().Type())
  1029. }
  1030. // Test a signer that uses a certificate algorithm as the public key
  1031. // type.
  1032. cert := &Certificate{
  1033. CertType: UserCert,
  1034. Key: signer.PublicKey(),
  1035. }
  1036. cert.SignCert(rand.Reader, signer)
  1037. certSigner, err := NewCertSigner(cert, signer)
  1038. if err != nil {
  1039. t.Fatalf("error generating cert signer: %v", err)
  1040. }
  1041. // The signer supports the public key algorithm and the
  1042. // public key format is a certificate type so the cerificate
  1043. // algorithm matching the key format must be returned
  1044. _, algo, err = pickSignatureAlgorithm(certSigner, c.extensions)
  1045. if err != nil {
  1046. t.Fatalf("got %v, want no error", err)
  1047. }
  1048. if algo != certSigner.PublicKey().Type() {
  1049. t.Fatalf("got algo %q, want %q", algo, certSigner.PublicKey().Type())
  1050. }
  1051. signer, err = NewSignerWithAlgorithms(signer.(AlgorithmSigner), []string{KeyAlgoRSASHA512, KeyAlgoRSASHA256})
  1052. if err != nil {
  1053. t.Fatalf("unable to create signer with algorithms: %v", err)
  1054. }
  1055. // The signer does not support the public key algorithm so an error
  1056. // is returned.
  1057. _, _, err = pickSignatureAlgorithm(signer, c.extensions)
  1058. if err == nil {
  1059. t.Fatal("got no error, no common public key signature algorithm error expected")
  1060. }
  1061. })
  1062. }
  1063. }
  1064. // configurablePublicKeyCallback is a public key callback that allows to
  1065. // configure the signature algorithm and format. This way we can emulate the
  1066. // behavior of buggy clients.
  1067. type configurablePublicKeyCallback struct {
  1068. signer AlgorithmSigner
  1069. signatureAlgo string
  1070. signatureFormat string
  1071. }
  1072. func (cb configurablePublicKeyCallback) method() string {
  1073. return "publickey"
  1074. }
  1075. func (cb configurablePublicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) {
  1076. pub := cb.signer.PublicKey()
  1077. ok, err := validateKey(pub, cb.signatureAlgo, user, c)
  1078. if err != nil {
  1079. return authFailure, nil, err
  1080. }
  1081. if !ok {
  1082. return authFailure, nil, fmt.Errorf("invalid public key")
  1083. }
  1084. pubKey := pub.Marshal()
  1085. data := buildDataSignedForAuth(session, userAuthRequestMsg{
  1086. User: user,
  1087. Service: serviceSSH,
  1088. Method: cb.method(),
  1089. }, cb.signatureAlgo, pubKey)
  1090. sign, err := cb.signer.SignWithAlgorithm(rand, data, underlyingAlgo(cb.signatureFormat))
  1091. if err != nil {
  1092. return authFailure, nil, err
  1093. }
  1094. s := Marshal(sign)
  1095. sig := make([]byte, stringLength(len(s)))
  1096. marshalString(sig, s)
  1097. msg := publickeyAuthMsg{
  1098. User: user,
  1099. Service: serviceSSH,
  1100. Method: cb.method(),
  1101. HasSig: true,
  1102. Algoname: cb.signatureAlgo,
  1103. PubKey: pubKey,
  1104. Sig: sig,
  1105. }
  1106. p := Marshal(&msg)
  1107. if err := c.writePacket(p); err != nil {
  1108. return authFailure, nil, err
  1109. }
  1110. var success authResult
  1111. success, methods, err := handleAuthResponse(c)
  1112. if err != nil {
  1113. return authFailure, nil, err
  1114. }
  1115. if success == authSuccess || !contains(methods, cb.method()) {
  1116. return success, methods, err
  1117. }
  1118. return authFailure, methods, nil
  1119. }
  1120. func TestPublicKeyAndAlgoCompatibility(t *testing.T) {
  1121. cert := &Certificate{
  1122. Key: testPublicKeys["rsa"],
  1123. ValidBefore: CertTimeInfinity,
  1124. CertType: UserCert,
  1125. }
  1126. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  1127. certSigner, err := NewCertSigner(cert, testSigners["rsa"])
  1128. if err != nil {
  1129. t.Fatalf("NewCertSigner: %v", err)
  1130. }
  1131. clientConfig := &ClientConfig{
  1132. User: "user",
  1133. HostKeyCallback: InsecureIgnoreHostKey(),
  1134. Auth: []AuthMethod{
  1135. configurablePublicKeyCallback{
  1136. signer: certSigner.(AlgorithmSigner),
  1137. signatureAlgo: KeyAlgoRSASHA256,
  1138. signatureFormat: KeyAlgoRSASHA256,
  1139. },
  1140. },
  1141. }
  1142. if err := tryAuth(t, clientConfig); err == nil {
  1143. t.Error("cert login passed with incompatible public key type and algorithm")
  1144. }
  1145. }
  1146. func TestClientAuthGPGAgentCompat(t *testing.T) {
  1147. clientConfig := &ClientConfig{
  1148. User: "testuser",
  1149. HostKeyCallback: InsecureIgnoreHostKey(),
  1150. Auth: []AuthMethod{
  1151. // algorithm rsa-sha2-512 and signature format ssh-rsa.
  1152. configurablePublicKeyCallback{
  1153. signer: testSigners["rsa"].(AlgorithmSigner),
  1154. signatureAlgo: KeyAlgoRSASHA512,
  1155. signatureFormat: KeyAlgoRSA,
  1156. },
  1157. },
  1158. }
  1159. if err := tryAuth(t, clientConfig); err != nil {
  1160. t.Fatalf("unable to dial remote side: %s", err)
  1161. }
  1162. }
  1163. func TestCertAuthOpenSSHCompat(t *testing.T) {
  1164. cert := &Certificate{
  1165. Key: testPublicKeys["rsa"],
  1166. ValidBefore: CertTimeInfinity,
  1167. CertType: UserCert,
  1168. }
  1169. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  1170. certSigner, err := NewCertSigner(cert, testSigners["rsa"])
  1171. if err != nil {
  1172. t.Fatalf("NewCertSigner: %v", err)
  1173. }
  1174. clientConfig := &ClientConfig{
  1175. User: "user",
  1176. HostKeyCallback: InsecureIgnoreHostKey(),
  1177. Auth: []AuthMethod{
  1178. // algorithm ssh-rsa-cert-v01@openssh.com and signature format
  1179. // rsa-sha2-256.
  1180. configurablePublicKeyCallback{
  1181. signer: certSigner.(AlgorithmSigner),
  1182. signatureAlgo: CertAlgoRSAv01,
  1183. signatureFormat: KeyAlgoRSASHA256,
  1184. },
  1185. },
  1186. }
  1187. if err := tryAuth(t, clientConfig); err != nil {
  1188. t.Fatalf("unable to dial remote side: %s", err)
  1189. }
  1190. }
  1191. func TestKeyboardInteractiveAuthEarlyFail(t *testing.T) {
  1192. const maxAuthTries = 2
  1193. c1, c2, err := netPipe()
  1194. if err != nil {
  1195. t.Fatalf("netPipe: %v", err)
  1196. }
  1197. defer c1.Close()
  1198. defer c2.Close()
  1199. // Start testserver
  1200. serverConfig := &ServerConfig{
  1201. MaxAuthTries: maxAuthTries,
  1202. KeyboardInteractiveCallback: func(c ConnMetadata,
  1203. client KeyboardInteractiveChallenge) (*Permissions, error) {
  1204. // Fail keyboard-interactive authentication early before
  1205. // any prompt is sent to client.
  1206. return nil, errors.New("keyboard-interactive auth failed")
  1207. },
  1208. PasswordCallback: func(c ConnMetadata,
  1209. pass []byte) (*Permissions, error) {
  1210. if string(pass) == clientPassword {
  1211. return nil, nil
  1212. }
  1213. return nil, errors.New("password auth failed")
  1214. },
  1215. }
  1216. serverConfig.AddHostKey(testSigners["rsa"])
  1217. serverDone := make(chan struct{})
  1218. go func() {
  1219. defer func() { serverDone <- struct{}{} }()
  1220. conn, chans, reqs, err := NewServerConn(c2, serverConfig)
  1221. if err != nil {
  1222. return
  1223. }
  1224. _ = conn.Close()
  1225. discarderDone := make(chan struct{})
  1226. go func() {
  1227. defer func() { discarderDone <- struct{}{} }()
  1228. DiscardRequests(reqs)
  1229. }()
  1230. for newChannel := range chans {
  1231. newChannel.Reject(Prohibited,
  1232. "testserver not accepting requests")
  1233. }
  1234. <-discarderDone
  1235. }()
  1236. // Connect to testserver, expect KeyboardInteractive() to be not called,
  1237. // PasswordCallback() to be called and connection to succeed.
  1238. passwordCallbackCalled := false
  1239. clientConfig := &ClientConfig{
  1240. User: "testuser",
  1241. Auth: []AuthMethod{
  1242. RetryableAuthMethod(KeyboardInteractive(func(name,
  1243. instruction string, questions []string,
  1244. echos []bool) ([]string, error) {
  1245. t.Errorf("unexpected call to KeyboardInteractive()")
  1246. return []string{clientPassword}, nil
  1247. }), maxAuthTries),
  1248. RetryableAuthMethod(PasswordCallback(func() (secret string,
  1249. err error) {
  1250. t.Logf("PasswordCallback()")
  1251. passwordCallbackCalled = true
  1252. return clientPassword, nil
  1253. }), maxAuthTries),
  1254. },
  1255. HostKeyCallback: InsecureIgnoreHostKey(),
  1256. }
  1257. conn, _, _, err := NewClientConn(c1, "", clientConfig)
  1258. if err != nil {
  1259. t.Errorf("unexpected NewClientConn() error: %v", err)
  1260. }
  1261. if conn != nil {
  1262. conn.Close()
  1263. }
  1264. // Wait for server to finish.
  1265. <-serverDone
  1266. if !passwordCallbackCalled {
  1267. t.Errorf("expected PasswordCallback() to be called")
  1268. }
  1269. }