client_auth_test.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  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. // tryAuth 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. go newServer(c1, serverConfig)
  568. _, _, _, err = NewClientConn(c2, "", clientConfig)
  569. if tries > 2 {
  570. if err == nil {
  571. t.Fatalf("client: got no error, want %s", expectedErr)
  572. } else if err.Error() != expectedErr.Error() {
  573. t.Fatalf("client: got %s, want %s", err, expectedErr)
  574. }
  575. } else {
  576. if err != nil {
  577. t.Fatalf("client: got %s, want no error", err)
  578. }
  579. }
  580. }
  581. }
  582. // Test if authentication attempts are correctly limited on server
  583. // when more public keys are provided then MaxAuthTries
  584. func TestClientAuthMaxAuthTriesPublicKey(t *testing.T) {
  585. signers := []Signer{}
  586. for i := 0; i < 6; i++ {
  587. signers = append(signers, testSigners["dsa"])
  588. }
  589. validConfig := &ClientConfig{
  590. User: "testuser",
  591. Auth: []AuthMethod{
  592. PublicKeys(append([]Signer{testSigners["rsa"]}, signers...)...),
  593. },
  594. HostKeyCallback: InsecureIgnoreHostKey(),
  595. }
  596. if err := tryAuth(t, validConfig); err != nil {
  597. t.Fatalf("unable to dial remote side: %s", err)
  598. }
  599. expectedErr := fmt.Errorf("ssh: handshake failed: %v", &disconnectMsg{
  600. Reason: 2,
  601. Message: "too many authentication failures",
  602. })
  603. invalidConfig := &ClientConfig{
  604. User: "testuser",
  605. Auth: []AuthMethod{
  606. PublicKeys(append(signers, testSigners["rsa"])...),
  607. },
  608. HostKeyCallback: InsecureIgnoreHostKey(),
  609. }
  610. if err := tryAuth(t, invalidConfig); err == nil {
  611. t.Fatalf("client: got no error, want %s", expectedErr)
  612. } else if err.Error() != expectedErr.Error() {
  613. // On Windows we can see a WSAECONNABORTED error
  614. // if the client writes another authentication request
  615. // before the client goroutine reads the disconnection
  616. // message. See issue 50805.
  617. if runtime.GOOS == "windows" && strings.Contains(err.Error(), "wsarecv: An established connection was aborted") {
  618. // OK.
  619. } else {
  620. t.Fatalf("client: got %s, want %s", err, expectedErr)
  621. }
  622. }
  623. }
  624. // Test whether authentication errors are being properly logged if all
  625. // authentication methods have been exhausted
  626. func TestClientAuthErrorList(t *testing.T) {
  627. publicKeyErr := errors.New("This is an error from PublicKeyCallback")
  628. clientConfig := &ClientConfig{
  629. Auth: []AuthMethod{
  630. PublicKeys(testSigners["rsa"]),
  631. },
  632. HostKeyCallback: InsecureIgnoreHostKey(),
  633. }
  634. serverConfig := &ServerConfig{
  635. PublicKeyCallback: func(_ ConnMetadata, _ PublicKey) (*Permissions, error) {
  636. return nil, publicKeyErr
  637. },
  638. }
  639. serverConfig.AddHostKey(testSigners["rsa"])
  640. c1, c2, err := netPipe()
  641. if err != nil {
  642. t.Fatalf("netPipe: %v", err)
  643. }
  644. defer c1.Close()
  645. defer c2.Close()
  646. go NewClientConn(c2, "", clientConfig)
  647. _, err = newServer(c1, serverConfig)
  648. if err == nil {
  649. t.Fatal("newServer: got nil, expected errors")
  650. }
  651. authErrs, ok := err.(*ServerAuthError)
  652. if !ok {
  653. t.Fatalf("errors: got %T, want *ssh.ServerAuthError", err)
  654. }
  655. for i, e := range authErrs.Errors {
  656. switch i {
  657. case 0:
  658. if e != ErrNoAuth {
  659. t.Fatalf("errors: got error %v, want ErrNoAuth", e)
  660. }
  661. case 1:
  662. if e != publicKeyErr {
  663. t.Fatalf("errors: got %v, want %v", e, publicKeyErr)
  664. }
  665. default:
  666. t.Fatalf("errors: got %v, expected 2 errors", authErrs.Errors)
  667. }
  668. }
  669. }
  670. func TestAuthMethodGSSAPIWithMIC(t *testing.T) {
  671. type testcase struct {
  672. config *ClientConfig
  673. gssConfig *GSSAPIWithMICConfig
  674. clientWantErr string
  675. serverWantErr string
  676. }
  677. testcases := []*testcase{
  678. {
  679. config: &ClientConfig{
  680. User: "testuser",
  681. Auth: []AuthMethod{
  682. GSSAPIWithMICAuthMethod(
  683. &FakeClient{
  684. exchanges: []*exchange{
  685. {
  686. outToken: "client-valid-token-1",
  687. },
  688. {
  689. expectedToken: "server-valid-token-1",
  690. },
  691. },
  692. mic: []byte("valid-mic"),
  693. maxRound: 2,
  694. }, "testtarget",
  695. ),
  696. },
  697. HostKeyCallback: InsecureIgnoreHostKey(),
  698. },
  699. gssConfig: &GSSAPIWithMICConfig{
  700. AllowLogin: func(conn ConnMetadata, srcName string) (*Permissions, error) {
  701. if srcName != conn.User()+"@DOMAIN" {
  702. return nil, fmt.Errorf("srcName is %s, conn user is %s", srcName, conn.User())
  703. }
  704. return nil, nil
  705. },
  706. Server: &FakeServer{
  707. exchanges: []*exchange{
  708. {
  709. outToken: "server-valid-token-1",
  710. expectedToken: "client-valid-token-1",
  711. },
  712. },
  713. maxRound: 1,
  714. expectedMIC: []byte("valid-mic"),
  715. srcName: "testuser@DOMAIN",
  716. },
  717. },
  718. },
  719. {
  720. config: &ClientConfig{
  721. User: "testuser",
  722. Auth: []AuthMethod{
  723. GSSAPIWithMICAuthMethod(
  724. &FakeClient{
  725. exchanges: []*exchange{
  726. {
  727. outToken: "client-valid-token-1",
  728. },
  729. {
  730. expectedToken: "server-valid-token-1",
  731. },
  732. },
  733. mic: []byte("valid-mic"),
  734. maxRound: 2,
  735. }, "testtarget",
  736. ),
  737. },
  738. HostKeyCallback: InsecureIgnoreHostKey(),
  739. },
  740. gssConfig: &GSSAPIWithMICConfig{
  741. AllowLogin: func(conn ConnMetadata, srcName string) (*Permissions, error) {
  742. return nil, fmt.Errorf("user is not allowed to login")
  743. },
  744. Server: &FakeServer{
  745. exchanges: []*exchange{
  746. {
  747. outToken: "server-valid-token-1",
  748. expectedToken: "client-valid-token-1",
  749. },
  750. },
  751. maxRound: 1,
  752. expectedMIC: []byte("valid-mic"),
  753. srcName: "testuser@DOMAIN",
  754. },
  755. },
  756. serverWantErr: "user is not allowed to login",
  757. clientWantErr: "ssh: handshake failed: ssh: unable to authenticate",
  758. },
  759. {
  760. config: &ClientConfig{
  761. User: "testuser",
  762. Auth: []AuthMethod{
  763. GSSAPIWithMICAuthMethod(
  764. &FakeClient{
  765. exchanges: []*exchange{
  766. {
  767. outToken: "client-valid-token-1",
  768. },
  769. {
  770. expectedToken: "server-valid-token-1",
  771. },
  772. },
  773. mic: []byte("valid-mic"),
  774. maxRound: 2,
  775. }, "testtarget",
  776. ),
  777. },
  778. HostKeyCallback: InsecureIgnoreHostKey(),
  779. },
  780. gssConfig: &GSSAPIWithMICConfig{
  781. AllowLogin: func(conn ConnMetadata, srcName string) (*Permissions, error) {
  782. if srcName != conn.User() {
  783. return nil, fmt.Errorf("srcName is %s, conn user is %s", srcName, conn.User())
  784. }
  785. return nil, nil
  786. },
  787. Server: &FakeServer{
  788. exchanges: []*exchange{
  789. {
  790. outToken: "server-invalid-token-1",
  791. expectedToken: "client-valid-token-1",
  792. },
  793. },
  794. maxRound: 1,
  795. expectedMIC: []byte("valid-mic"),
  796. srcName: "testuser@DOMAIN",
  797. },
  798. },
  799. clientWantErr: "ssh: handshake failed: got \"server-invalid-token-1\", want token \"server-valid-token-1\"",
  800. },
  801. {
  802. config: &ClientConfig{
  803. User: "testuser",
  804. Auth: []AuthMethod{
  805. GSSAPIWithMICAuthMethod(
  806. &FakeClient{
  807. exchanges: []*exchange{
  808. {
  809. outToken: "client-valid-token-1",
  810. },
  811. {
  812. expectedToken: "server-valid-token-1",
  813. },
  814. },
  815. mic: []byte("invalid-mic"),
  816. maxRound: 2,
  817. }, "testtarget",
  818. ),
  819. },
  820. HostKeyCallback: InsecureIgnoreHostKey(),
  821. },
  822. gssConfig: &GSSAPIWithMICConfig{
  823. AllowLogin: func(conn ConnMetadata, srcName string) (*Permissions, error) {
  824. if srcName != conn.User() {
  825. return nil, fmt.Errorf("srcName is %s, conn user is %s", srcName, conn.User())
  826. }
  827. return nil, nil
  828. },
  829. Server: &FakeServer{
  830. exchanges: []*exchange{
  831. {
  832. outToken: "server-valid-token-1",
  833. expectedToken: "client-valid-token-1",
  834. },
  835. },
  836. maxRound: 1,
  837. expectedMIC: []byte("valid-mic"),
  838. srcName: "testuser@DOMAIN",
  839. },
  840. },
  841. serverWantErr: "got MICToken \"invalid-mic\", want \"valid-mic\"",
  842. clientWantErr: "ssh: handshake failed: ssh: unable to authenticate",
  843. },
  844. }
  845. for i, c := range testcases {
  846. clientErr, serverErrs := tryAuthBothSides(t, c.config, c.gssConfig)
  847. if (c.clientWantErr == "") != (clientErr == nil) {
  848. t.Fatalf("client got %v, want %s, case %d", clientErr, c.clientWantErr, i)
  849. }
  850. if (c.serverWantErr == "") != (len(serverErrs) == 2 && serverErrs[1] == nil || len(serverErrs) == 1) {
  851. t.Fatalf("server got err %v, want %s", serverErrs, c.serverWantErr)
  852. }
  853. if c.clientWantErr != "" {
  854. if clientErr != nil && !strings.Contains(clientErr.Error(), c.clientWantErr) {
  855. t.Fatalf("client got %v, want %s, case %d", clientErr, c.clientWantErr, i)
  856. }
  857. }
  858. found := false
  859. var errStrings []string
  860. if c.serverWantErr != "" {
  861. for _, err := range serverErrs {
  862. found = found || (err != nil && strings.Contains(err.Error(), c.serverWantErr))
  863. errStrings = append(errStrings, err.Error())
  864. }
  865. if !found {
  866. t.Errorf("server got error %q, want substring %q, case %d", errStrings, c.serverWantErr, i)
  867. }
  868. }
  869. }
  870. }
  871. func TestCompatibleAlgoAndSignatures(t *testing.T) {
  872. type testcase struct {
  873. algo string
  874. sigFormat string
  875. compatible bool
  876. }
  877. testcases := []*testcase{
  878. {
  879. KeyAlgoRSA,
  880. KeyAlgoRSA,
  881. true,
  882. },
  883. {
  884. KeyAlgoRSA,
  885. KeyAlgoRSASHA256,
  886. true,
  887. },
  888. {
  889. KeyAlgoRSA,
  890. KeyAlgoRSASHA512,
  891. true,
  892. },
  893. {
  894. KeyAlgoRSASHA256,
  895. KeyAlgoRSA,
  896. true,
  897. },
  898. {
  899. KeyAlgoRSASHA512,
  900. KeyAlgoRSA,
  901. true,
  902. },
  903. {
  904. KeyAlgoRSASHA512,
  905. KeyAlgoRSASHA256,
  906. true,
  907. },
  908. {
  909. KeyAlgoRSASHA256,
  910. KeyAlgoRSASHA512,
  911. true,
  912. },
  913. {
  914. KeyAlgoRSASHA512,
  915. KeyAlgoRSASHA512,
  916. true,
  917. },
  918. {
  919. CertAlgoRSAv01,
  920. KeyAlgoRSA,
  921. true,
  922. },
  923. {
  924. CertAlgoRSAv01,
  925. KeyAlgoRSASHA256,
  926. true,
  927. },
  928. {
  929. CertAlgoRSAv01,
  930. KeyAlgoRSASHA512,
  931. true,
  932. },
  933. {
  934. CertAlgoRSASHA256v01,
  935. KeyAlgoRSASHA512,
  936. true,
  937. },
  938. {
  939. CertAlgoRSASHA512v01,
  940. KeyAlgoRSASHA512,
  941. true,
  942. },
  943. {
  944. CertAlgoRSASHA512v01,
  945. KeyAlgoRSASHA256,
  946. true,
  947. },
  948. {
  949. CertAlgoRSASHA256v01,
  950. CertAlgoRSAv01,
  951. true,
  952. },
  953. {
  954. CertAlgoRSAv01,
  955. CertAlgoRSASHA512v01,
  956. true,
  957. },
  958. {
  959. KeyAlgoECDSA256,
  960. KeyAlgoRSA,
  961. false,
  962. },
  963. {
  964. KeyAlgoECDSA256,
  965. KeyAlgoECDSA521,
  966. false,
  967. },
  968. {
  969. KeyAlgoECDSA256,
  970. KeyAlgoECDSA256,
  971. true,
  972. },
  973. {
  974. KeyAlgoECDSA256,
  975. KeyAlgoED25519,
  976. false,
  977. },
  978. {
  979. KeyAlgoED25519,
  980. KeyAlgoED25519,
  981. true,
  982. },
  983. }
  984. for _, c := range testcases {
  985. if isAlgoCompatible(c.algo, c.sigFormat) != c.compatible {
  986. t.Errorf("algorithm %q, signature format %q, expected compatible to be %t", c.algo, c.sigFormat, c.compatible)
  987. }
  988. }
  989. }
  990. func TestPickSignatureAlgorithm(t *testing.T) {
  991. type testcase struct {
  992. name string
  993. extensions map[string][]byte
  994. }
  995. cases := []testcase{
  996. {
  997. name: "server with empty server-sig-algs",
  998. extensions: map[string][]byte{
  999. "server-sig-algs": []byte(``),
  1000. },
  1001. },
  1002. {
  1003. name: "server with no server-sig-algs",
  1004. extensions: nil,
  1005. },
  1006. }
  1007. for _, c := range cases {
  1008. t.Run(c.name, func(t *testing.T) {
  1009. signer, ok := testSigners["rsa"].(MultiAlgorithmSigner)
  1010. if !ok {
  1011. t.Fatalf("rsa test signer does not implement the MultiAlgorithmSigner interface")
  1012. }
  1013. // The signer supports the public key algorithm which is then returned.
  1014. _, algo, err := pickSignatureAlgorithm(signer, c.extensions)
  1015. if err != nil {
  1016. t.Fatalf("got %v, want no error", err)
  1017. }
  1018. if algo != signer.PublicKey().Type() {
  1019. t.Fatalf("got algo %q, want %q", algo, signer.PublicKey().Type())
  1020. }
  1021. // Test a signer that uses a certificate algorithm as the public key
  1022. // type.
  1023. cert := &Certificate{
  1024. CertType: UserCert,
  1025. Key: signer.PublicKey(),
  1026. }
  1027. cert.SignCert(rand.Reader, signer)
  1028. certSigner, err := NewCertSigner(cert, signer)
  1029. if err != nil {
  1030. t.Fatalf("error generating cert signer: %v", err)
  1031. }
  1032. // The signer supports the public key algorithm and the
  1033. // public key format is a certificate type so the cerificate
  1034. // algorithm matching the key format must be returned
  1035. _, algo, err = pickSignatureAlgorithm(certSigner, c.extensions)
  1036. if err != nil {
  1037. t.Fatalf("got %v, want no error", err)
  1038. }
  1039. if algo != certSigner.PublicKey().Type() {
  1040. t.Fatalf("got algo %q, want %q", algo, certSigner.PublicKey().Type())
  1041. }
  1042. signer, err = NewSignerWithAlgorithms(signer.(AlgorithmSigner), []string{KeyAlgoRSASHA512, KeyAlgoRSASHA256})
  1043. if err != nil {
  1044. t.Fatalf("unable to create signer with algorithms: %v", err)
  1045. }
  1046. // The signer does not support the public key algorithm so an error
  1047. // is returned.
  1048. _, _, err = pickSignatureAlgorithm(signer, c.extensions)
  1049. if err == nil {
  1050. t.Fatal("got no error, no common public key signature algorithm error expected")
  1051. }
  1052. })
  1053. }
  1054. }
  1055. // configurablePublicKeyCallback is a public key callback that allows to
  1056. // configure the signature algorithm and format. This way we can emulate the
  1057. // behavior of buggy clients.
  1058. type configurablePublicKeyCallback struct {
  1059. signer AlgorithmSigner
  1060. signatureAlgo string
  1061. signatureFormat string
  1062. }
  1063. func (cb configurablePublicKeyCallback) method() string {
  1064. return "publickey"
  1065. }
  1066. func (cb configurablePublicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) {
  1067. pub := cb.signer.PublicKey()
  1068. ok, err := validateKey(pub, cb.signatureAlgo, user, c)
  1069. if err != nil {
  1070. return authFailure, nil, err
  1071. }
  1072. if !ok {
  1073. return authFailure, nil, fmt.Errorf("invalid public key")
  1074. }
  1075. pubKey := pub.Marshal()
  1076. data := buildDataSignedForAuth(session, userAuthRequestMsg{
  1077. User: user,
  1078. Service: serviceSSH,
  1079. Method: cb.method(),
  1080. }, cb.signatureAlgo, pubKey)
  1081. sign, err := cb.signer.SignWithAlgorithm(rand, data, underlyingAlgo(cb.signatureFormat))
  1082. if err != nil {
  1083. return authFailure, nil, err
  1084. }
  1085. s := Marshal(sign)
  1086. sig := make([]byte, stringLength(len(s)))
  1087. marshalString(sig, s)
  1088. msg := publickeyAuthMsg{
  1089. User: user,
  1090. Service: serviceSSH,
  1091. Method: cb.method(),
  1092. HasSig: true,
  1093. Algoname: cb.signatureAlgo,
  1094. PubKey: pubKey,
  1095. Sig: sig,
  1096. }
  1097. p := Marshal(&msg)
  1098. if err := c.writePacket(p); err != nil {
  1099. return authFailure, nil, err
  1100. }
  1101. var success authResult
  1102. success, methods, err := handleAuthResponse(c)
  1103. if err != nil {
  1104. return authFailure, nil, err
  1105. }
  1106. if success == authSuccess || !contains(methods, cb.method()) {
  1107. return success, methods, err
  1108. }
  1109. return authFailure, methods, nil
  1110. }
  1111. func TestPublicKeyAndAlgoCompatibility(t *testing.T) {
  1112. cert := &Certificate{
  1113. Key: testPublicKeys["rsa"],
  1114. ValidBefore: CertTimeInfinity,
  1115. CertType: UserCert,
  1116. }
  1117. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  1118. certSigner, err := NewCertSigner(cert, testSigners["rsa"])
  1119. if err != nil {
  1120. t.Fatalf("NewCertSigner: %v", err)
  1121. }
  1122. clientConfig := &ClientConfig{
  1123. User: "user",
  1124. HostKeyCallback: InsecureIgnoreHostKey(),
  1125. Auth: []AuthMethod{
  1126. configurablePublicKeyCallback{
  1127. signer: certSigner.(AlgorithmSigner),
  1128. signatureAlgo: KeyAlgoRSASHA256,
  1129. signatureFormat: KeyAlgoRSASHA256,
  1130. },
  1131. },
  1132. }
  1133. if err := tryAuth(t, clientConfig); err == nil {
  1134. t.Error("cert login passed with incompatible public key type and algorithm")
  1135. }
  1136. }
  1137. func TestClientAuthGPGAgentCompat(t *testing.T) {
  1138. clientConfig := &ClientConfig{
  1139. User: "testuser",
  1140. HostKeyCallback: InsecureIgnoreHostKey(),
  1141. Auth: []AuthMethod{
  1142. // algorithm rsa-sha2-512 and signature format ssh-rsa.
  1143. configurablePublicKeyCallback{
  1144. signer: testSigners["rsa"].(AlgorithmSigner),
  1145. signatureAlgo: KeyAlgoRSASHA512,
  1146. signatureFormat: KeyAlgoRSA,
  1147. },
  1148. },
  1149. }
  1150. if err := tryAuth(t, clientConfig); err != nil {
  1151. t.Fatalf("unable to dial remote side: %s", err)
  1152. }
  1153. }
  1154. func TestCertAuthOpenSSHCompat(t *testing.T) {
  1155. cert := &Certificate{
  1156. Key: testPublicKeys["rsa"],
  1157. ValidBefore: CertTimeInfinity,
  1158. CertType: UserCert,
  1159. }
  1160. cert.SignCert(rand.Reader, testSigners["ecdsa"])
  1161. certSigner, err := NewCertSigner(cert, testSigners["rsa"])
  1162. if err != nil {
  1163. t.Fatalf("NewCertSigner: %v", err)
  1164. }
  1165. clientConfig := &ClientConfig{
  1166. User: "user",
  1167. HostKeyCallback: InsecureIgnoreHostKey(),
  1168. Auth: []AuthMethod{
  1169. // algorithm ssh-rsa-cert-v01@openssh.com and signature format
  1170. // rsa-sha2-256.
  1171. configurablePublicKeyCallback{
  1172. signer: certSigner.(AlgorithmSigner),
  1173. signatureAlgo: CertAlgoRSAv01,
  1174. signatureFormat: KeyAlgoRSASHA256,
  1175. },
  1176. },
  1177. }
  1178. if err := tryAuth(t, clientConfig); err != nil {
  1179. t.Fatalf("unable to dial remote side: %s", err)
  1180. }
  1181. }