knownhosts_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // Copyright 2017 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 knownhosts
  5. import (
  6. "bytes"
  7. "fmt"
  8. "net"
  9. "reflect"
  10. "testing"
  11. "golang.org/x/crypto/ssh"
  12. )
  13. const edKeyStr = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGBAarftlLeoyf+v+nVchEZII/vna2PCV8FaX4vsF5BX"
  14. const alternateEdKeyStr = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIXffBYeYL+WVzVru8npl5JHt2cjlr4ornFTWzoij9sx"
  15. const ecKeyStr = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNLCu01+wpXe3xB5olXCN4SqU2rQu0qjSRKJO4Bg+JRCPU+ENcgdA5srTU8xYDz/GEa4dzK5ldPw4J/gZgSXCMs="
  16. var ecKey, alternateEdKey, edKey ssh.PublicKey
  17. var testAddr = &net.TCPAddr{
  18. IP: net.IP{198, 41, 30, 196},
  19. Port: 22,
  20. }
  21. var testAddr6 = &net.TCPAddr{
  22. IP: net.IP{198, 41, 30, 196,
  23. 1, 2, 3, 4,
  24. 1, 2, 3, 4,
  25. 1, 2, 3, 4,
  26. },
  27. Port: 22,
  28. }
  29. func init() {
  30. var err error
  31. ecKey, _, _, _, err = ssh.ParseAuthorizedKey([]byte(ecKeyStr))
  32. if err != nil {
  33. panic(err)
  34. }
  35. edKey, _, _, _, err = ssh.ParseAuthorizedKey([]byte(edKeyStr))
  36. if err != nil {
  37. panic(err)
  38. }
  39. alternateEdKey, _, _, _, err = ssh.ParseAuthorizedKey([]byte(alternateEdKeyStr))
  40. if err != nil {
  41. panic(err)
  42. }
  43. }
  44. func testDB(t *testing.T, s string) *hostKeyDB {
  45. db := newHostKeyDB()
  46. if err := db.Read(bytes.NewBufferString(s), "testdb"); err != nil {
  47. t.Fatalf("Read: %v", err)
  48. }
  49. return db
  50. }
  51. func TestRevoked(t *testing.T) {
  52. db := testDB(t, "\n\n@revoked * "+edKeyStr+"\n")
  53. want := &RevokedError{
  54. Revoked: KnownKey{
  55. Key: edKey,
  56. Filename: "testdb",
  57. Line: 3,
  58. },
  59. }
  60. if err := db.check("", &net.TCPAddr{
  61. Port: 42,
  62. }, edKey); err == nil {
  63. t.Fatal("no error for revoked key")
  64. } else if !reflect.DeepEqual(want, err) {
  65. t.Fatalf("got %#v, want %#v", want, err)
  66. }
  67. }
  68. func TestBracket(t *testing.T) {
  69. db := testDB(t, `[git.eclipse.org]:29418,[198.41.30.196]:29418 `+edKeyStr)
  70. if err := db.check("git.eclipse.org:29418", &net.TCPAddr{
  71. IP: net.IP{198, 41, 30, 196},
  72. Port: 29418,
  73. }, edKey); err != nil {
  74. t.Errorf("got error %v, want none", err)
  75. }
  76. if err := db.check("git.eclipse.org:29419", &net.TCPAddr{
  77. Port: 42,
  78. }, edKey); err == nil {
  79. t.Fatalf("no error for unknown address")
  80. } else if ke, ok := err.(*KeyError); !ok {
  81. t.Fatalf("got type %T, want *KeyError", err)
  82. } else if len(ke.Want) > 0 {
  83. t.Fatalf("got Want %v, want []", ke.Want)
  84. }
  85. }
  86. func TestNewKeyType(t *testing.T) {
  87. str := fmt.Sprintf("%s %s", testAddr, edKeyStr)
  88. db := testDB(t, str)
  89. if err := db.check("", testAddr, ecKey); err == nil {
  90. t.Fatalf("no error for unknown address")
  91. } else if ke, ok := err.(*KeyError); !ok {
  92. t.Fatalf("got type %T, want *KeyError", err)
  93. } else if len(ke.Want) == 0 {
  94. t.Fatalf("got empty KeyError.Want")
  95. }
  96. }
  97. func TestSameKeyType(t *testing.T) {
  98. str := fmt.Sprintf("%s %s", testAddr, edKeyStr)
  99. db := testDB(t, str)
  100. if err := db.check("", testAddr, alternateEdKey); err == nil {
  101. t.Fatalf("no error for unknown address")
  102. } else if ke, ok := err.(*KeyError); !ok {
  103. t.Fatalf("got type %T, want *KeyError", err)
  104. } else if len(ke.Want) == 0 {
  105. t.Fatalf("got empty KeyError.Want")
  106. } else if got, want := ke.Want[0].Key.Marshal(), edKey.Marshal(); !bytes.Equal(got, want) {
  107. t.Fatalf("got key %q, want %q", got, want)
  108. }
  109. }
  110. func TestIPAddress(t *testing.T) {
  111. str := fmt.Sprintf("%s %s", testAddr, edKeyStr)
  112. db := testDB(t, str)
  113. if err := db.check("", testAddr, edKey); err != nil {
  114. t.Errorf("got error %q, want none", err)
  115. }
  116. }
  117. func TestIPv6Address(t *testing.T) {
  118. str := fmt.Sprintf("%s %s", testAddr6, edKeyStr)
  119. db := testDB(t, str)
  120. if err := db.check("", testAddr6, edKey); err != nil {
  121. t.Errorf("got error %q, want none", err)
  122. }
  123. }
  124. func TestBasic(t *testing.T) {
  125. str := fmt.Sprintf("#comment\n\nserver.org,%s %s\notherhost %s", testAddr, edKeyStr, ecKeyStr)
  126. db := testDB(t, str)
  127. if err := db.check("server.org:22", testAddr, edKey); err != nil {
  128. t.Errorf("got error %q, want none", err)
  129. }
  130. want := KnownKey{
  131. Key: edKey,
  132. Filename: "testdb",
  133. Line: 3,
  134. }
  135. if err := db.check("server.org:22", testAddr, ecKey); err == nil {
  136. t.Errorf("succeeded, want KeyError")
  137. } else if ke, ok := err.(*KeyError); !ok {
  138. t.Errorf("got %T, want *KeyError", err)
  139. } else if len(ke.Want) != 1 {
  140. t.Errorf("got %v, want 1 entry", ke)
  141. } else if !reflect.DeepEqual(ke.Want[0], want) {
  142. t.Errorf("got %v, want %v", ke.Want[0], want)
  143. }
  144. }
  145. func TestNegate(t *testing.T) {
  146. str := fmt.Sprintf("%s,!server.org %s", testAddr, edKeyStr)
  147. db := testDB(t, str)
  148. if err := db.check("server.org:22", testAddr, ecKey); err == nil {
  149. t.Errorf("succeeded")
  150. } else if ke, ok := err.(*KeyError); !ok {
  151. t.Errorf("got error type %T, want *KeyError", err)
  152. } else if len(ke.Want) != 0 {
  153. t.Errorf("got expected keys %d (first of type %s), want []", len(ke.Want), ke.Want[0].Key.Type())
  154. }
  155. }
  156. func TestWildcard(t *testing.T) {
  157. str := fmt.Sprintf("server*.domain %s", edKeyStr)
  158. db := testDB(t, str)
  159. want := &KeyError{
  160. Want: []KnownKey{{
  161. Filename: "testdb",
  162. Line: 1,
  163. Key: edKey,
  164. }},
  165. }
  166. got := db.check("server.domain:22", &net.TCPAddr{}, ecKey)
  167. if !reflect.DeepEqual(got, want) {
  168. t.Errorf("got %s, want %s", got, want)
  169. }
  170. }
  171. func TestLine(t *testing.T) {
  172. for in, want := range map[string]string{
  173. "server.org": "server.org " + edKeyStr,
  174. "server.org:22": "server.org " + edKeyStr,
  175. "server.org:23": "[server.org]:23 " + edKeyStr,
  176. "[c629:1ec4:102:304:102:304:102:304]:22": "[c629:1ec4:102:304:102:304:102:304] " + edKeyStr,
  177. "[c629:1ec4:102:304:102:304:102:304]:23": "[c629:1ec4:102:304:102:304:102:304]:23 " + edKeyStr,
  178. } {
  179. if got := Line([]string{in}, edKey); got != want {
  180. t.Errorf("Line(%q) = %q, want %q", in, got, want)
  181. }
  182. }
  183. }
  184. func TestWildcardMatch(t *testing.T) {
  185. for _, c := range []struct {
  186. pat, str string
  187. want bool
  188. }{
  189. {"a?b", "abb", true},
  190. {"ab", "abc", false},
  191. {"abc", "ab", false},
  192. {"a*b", "axxxb", true},
  193. {"a*b", "axbxb", true},
  194. {"a*b", "axbxbc", false},
  195. {"a*?", "axbxc", true},
  196. {"a*b*", "axxbxxxxxx", true},
  197. {"a*b*c", "axxbxxxxxxc", true},
  198. {"a*b*?", "axxbxxxxxxc", true},
  199. {"a*b*z", "axxbxxbxxxz", true},
  200. {"a*b*z", "axxbxxzxxxz", true},
  201. {"a*b*z", "axxbxxzxxx", false},
  202. } {
  203. got := wildcardMatch([]byte(c.pat), []byte(c.str))
  204. if got != c.want {
  205. t.Errorf("wildcardMatch(%q, %q) = %v, want %v", c.pat, c.str, got, c.want)
  206. }
  207. }
  208. }
  209. // TODO(hanwen): test coverage for certificates.