You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

254 lines
5.5 KiB

  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. "math/big"
  8. "math/rand"
  9. "reflect"
  10. "testing"
  11. "testing/quick"
  12. )
  13. var intLengthTests = []struct {
  14. val, length int
  15. }{
  16. {0, 4 + 0},
  17. {1, 4 + 1},
  18. {127, 4 + 1},
  19. {128, 4 + 2},
  20. {-1, 4 + 1},
  21. }
  22. func TestIntLength(t *testing.T) {
  23. for _, test := range intLengthTests {
  24. v := new(big.Int).SetInt64(int64(test.val))
  25. length := intLength(v)
  26. if length != test.length {
  27. t.Errorf("For %d, got length %d but expected %d", test.val, length, test.length)
  28. }
  29. }
  30. }
  31. type msgAllTypes struct {
  32. Bool bool `sshtype:"21"`
  33. Array [16]byte
  34. Uint64 uint64
  35. Uint32 uint32
  36. Uint8 uint8
  37. String string
  38. Strings []string
  39. Bytes []byte
  40. Int *big.Int
  41. Rest []byte `ssh:"rest"`
  42. }
  43. func (t *msgAllTypes) Generate(rand *rand.Rand, size int) reflect.Value {
  44. m := &msgAllTypes{}
  45. m.Bool = rand.Intn(2) == 1
  46. randomBytes(m.Array[:], rand)
  47. m.Uint64 = uint64(rand.Int63n(1<<63 - 1))
  48. m.Uint32 = uint32(rand.Intn((1 << 31) - 1))
  49. m.Uint8 = uint8(rand.Intn(1 << 8))
  50. m.String = string(m.Array[:])
  51. m.Strings = randomNameList(rand)
  52. m.Bytes = m.Array[:]
  53. m.Int = randomInt(rand)
  54. m.Rest = m.Array[:]
  55. return reflect.ValueOf(m)
  56. }
  57. func TestMarshalUnmarshal(t *testing.T) {
  58. rand := rand.New(rand.NewSource(0))
  59. iface := &msgAllTypes{}
  60. ty := reflect.ValueOf(iface).Type()
  61. n := 100
  62. if testing.Short() {
  63. n = 5
  64. }
  65. for j := 0; j < n; j++ {
  66. v, ok := quick.Value(ty, rand)
  67. if !ok {
  68. t.Errorf("failed to create value")
  69. break
  70. }
  71. m1 := v.Elem().Interface()
  72. m2 := iface
  73. marshaled := Marshal(m1)
  74. if err := Unmarshal(marshaled, m2); err != nil {
  75. t.Errorf("Unmarshal %#v: %s", m1, err)
  76. break
  77. }
  78. if !reflect.DeepEqual(v.Interface(), m2) {
  79. t.Errorf("got: %#v\nwant:%#v\n%x", m2, m1, marshaled)
  80. break
  81. }
  82. }
  83. }
  84. func TestUnmarshalEmptyPacket(t *testing.T) {
  85. var b []byte
  86. var m channelRequestSuccessMsg
  87. if err := Unmarshal(b, &m); err == nil {
  88. t.Fatalf("unmarshal of empty slice succeeded")
  89. }
  90. }
  91. func TestUnmarshalUnexpectedPacket(t *testing.T) {
  92. type S struct {
  93. I uint32 `sshtype:"43"`
  94. S string
  95. B bool
  96. }
  97. s := S{11, "hello", true}
  98. packet := Marshal(s)
  99. packet[0] = 42
  100. roundtrip := S{}
  101. err := Unmarshal(packet, &roundtrip)
  102. if err == nil {
  103. t.Fatal("expected error, not nil")
  104. }
  105. }
  106. func TestMarshalPtr(t *testing.T) {
  107. s := struct {
  108. S string
  109. }{"hello"}
  110. m1 := Marshal(s)
  111. m2 := Marshal(&s)
  112. if !bytes.Equal(m1, m2) {
  113. t.Errorf("got %q, want %q for marshaled pointer", m2, m1)
  114. }
  115. }
  116. func TestBareMarshalUnmarshal(t *testing.T) {
  117. type S struct {
  118. I uint32
  119. S string
  120. B bool
  121. }
  122. s := S{42, "hello", true}
  123. packet := Marshal(s)
  124. roundtrip := S{}
  125. Unmarshal(packet, &roundtrip)
  126. if !reflect.DeepEqual(s, roundtrip) {
  127. t.Errorf("got %#v, want %#v", roundtrip, s)
  128. }
  129. }
  130. func TestBareMarshal(t *testing.T) {
  131. type S2 struct {
  132. I uint32
  133. }
  134. s := S2{42}
  135. packet := Marshal(s)
  136. i, rest, ok := parseUint32(packet)
  137. if len(rest) > 0 || !ok {
  138. t.Errorf("parseInt(%q): parse error", packet)
  139. }
  140. if i != s.I {
  141. t.Errorf("got %d, want %d", i, s.I)
  142. }
  143. }
  144. func TestUnmarshalShortKexInitPacket(t *testing.T) {
  145. // This used to panic.
  146. // Issue 11348
  147. packet := []byte{0x14, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xff, 0xff, 0xff, 0xff}
  148. kim := &kexInitMsg{}
  149. if err := Unmarshal(packet, kim); err == nil {
  150. t.Error("truncated packet unmarshaled without error")
  151. }
  152. }
  153. func randomBytes(out []byte, rand *rand.Rand) {
  154. for i := 0; i < len(out); i++ {
  155. out[i] = byte(rand.Int31())
  156. }
  157. }
  158. func randomNameList(rand *rand.Rand) []string {
  159. ret := make([]string, rand.Int31()&15)
  160. for i := range ret {
  161. s := make([]byte, 1+(rand.Int31()&15))
  162. for j := range s {
  163. s[j] = 'a' + uint8(rand.Int31()&15)
  164. }
  165. ret[i] = string(s)
  166. }
  167. return ret
  168. }
  169. func randomInt(rand *rand.Rand) *big.Int {
  170. return new(big.Int).SetInt64(int64(int32(rand.Uint32())))
  171. }
  172. func (*kexInitMsg) Generate(rand *rand.Rand, size int) reflect.Value {
  173. ki := &kexInitMsg{}
  174. randomBytes(ki.Cookie[:], rand)
  175. ki.KexAlgos = randomNameList(rand)
  176. ki.ServerHostKeyAlgos = randomNameList(rand)
  177. ki.CiphersClientServer = randomNameList(rand)
  178. ki.CiphersServerClient = randomNameList(rand)
  179. ki.MACsClientServer = randomNameList(rand)
  180. ki.MACsServerClient = randomNameList(rand)
  181. ki.CompressionClientServer = randomNameList(rand)
  182. ki.CompressionServerClient = randomNameList(rand)
  183. ki.LanguagesClientServer = randomNameList(rand)
  184. ki.LanguagesServerClient = randomNameList(rand)
  185. if rand.Int31()&1 == 1 {
  186. ki.FirstKexFollows = true
  187. }
  188. return reflect.ValueOf(ki)
  189. }
  190. func (*kexDHInitMsg) Generate(rand *rand.Rand, size int) reflect.Value {
  191. dhi := &kexDHInitMsg{}
  192. dhi.X = randomInt(rand)
  193. return reflect.ValueOf(dhi)
  194. }
  195. var (
  196. _kexInitMsg = new(kexInitMsg).Generate(rand.New(rand.NewSource(0)), 10).Elem().Interface()
  197. _kexDHInitMsg = new(kexDHInitMsg).Generate(rand.New(rand.NewSource(0)), 10).Elem().Interface()
  198. _kexInit = Marshal(_kexInitMsg)
  199. _kexDHInit = Marshal(_kexDHInitMsg)
  200. )
  201. func BenchmarkMarshalKexInitMsg(b *testing.B) {
  202. for i := 0; i < b.N; i++ {
  203. Marshal(_kexInitMsg)
  204. }
  205. }
  206. func BenchmarkUnmarshalKexInitMsg(b *testing.B) {
  207. m := new(kexInitMsg)
  208. for i := 0; i < b.N; i++ {
  209. Unmarshal(_kexInit, m)
  210. }
  211. }
  212. func BenchmarkMarshalKexDHInitMsg(b *testing.B) {
  213. for i := 0; i < b.N; i++ {
  214. Marshal(_kexDHInitMsg)
  215. }
  216. }
  217. func BenchmarkUnmarshalKexDHInitMsg(b *testing.B) {
  218. m := new(kexDHInitMsg)
  219. for i := 0; i < b.N; i++ {
  220. Unmarshal(_kexDHInit, m)
  221. }
  222. }