Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

client_hello_test.go 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package faketls_test
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "testing"
  9. "time"
  10. "github.com/9seconds/mtg/v2/mtglib"
  11. "github.com/9seconds/mtg/v2/mtglib/internal/faketls"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/stretchr/testify/suite"
  14. )
  15. type ClientHelloSnapshot struct {
  16. Time int `json:"time"`
  17. Random string `json:"random"`
  18. SessionID string `json:"sessionId"`
  19. Host string `json:"host"`
  20. CipherSuite int `json:"cipherSuite"`
  21. Full string `json:"full"`
  22. }
  23. func (c ClientHelloSnapshot) GetTime() time.Time {
  24. return time.Unix(int64(c.Time), 0)
  25. }
  26. func (c ClientHelloSnapshot) GetRandom() []byte {
  27. data, _ := base64.StdEncoding.DecodeString(c.Random)
  28. return data
  29. }
  30. func (c ClientHelloSnapshot) GetSessionID() []byte {
  31. data, _ := base64.StdEncoding.DecodeString(c.SessionID)
  32. return data
  33. }
  34. func (c ClientHelloSnapshot) GetHost() string {
  35. return c.Host
  36. }
  37. func (c ClientHelloSnapshot) GetCipherSuite() uint16 {
  38. return uint16(c.CipherSuite)
  39. }
  40. func (c ClientHelloSnapshot) GetFull() []byte {
  41. data, _ := base64.StdEncoding.DecodeString(c.Full)
  42. return data
  43. }
  44. type ClientHelloTestSuite struct {
  45. suite.Suite
  46. secret mtglib.Secret
  47. }
  48. func (suite *ClientHelloTestSuite) SetupSuite() {
  49. parsed, err := mtglib.ParseSecret("ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d")
  50. if err != nil {
  51. panic(err)
  52. }
  53. suite.secret = parsed
  54. }
  55. func (suite *ClientHelloTestSuite) TestEmptyHandshake() {
  56. _, err := faketls.ParseClientHello(suite.secret.Key[:], nil)
  57. suite.Error(err)
  58. }
  59. func (suite *ClientHelloTestSuite) TestIncorrectHandshakeType() {
  60. data := make([]byte, 1024)
  61. data[0] = 0x02
  62. _, err := faketls.ParseClientHello(suite.secret.Key[:], data)
  63. suite.Error(err)
  64. }
  65. func (suite *ClientHelloTestSuite) TestIncorrectLength() {
  66. data := make([]byte, 1024)
  67. data[0] = 0x01
  68. data[1] = 0xff
  69. data[2] = 0xff
  70. _, err := faketls.ParseClientHello(suite.secret.Key[:], data)
  71. suite.Error(err)
  72. }
  73. func (suite *ClientHelloTestSuite) TestSnapshotOk() {
  74. files, err := os.ReadDir("testdata")
  75. suite.NoError(err)
  76. testData := []string{}
  77. for _, v := range files {
  78. if strings.HasPrefix(v.Name(), "client-hello-ok") {
  79. testData = append(testData, v.Name())
  80. }
  81. }
  82. for _, name := range testData {
  83. path := filepath.Join("testdata", name)
  84. suite.T().Run(name, func(t *testing.T) {
  85. fileData, err := os.ReadFile(path)
  86. assert.NoError(t, err)
  87. snapshot := &ClientHelloSnapshot{}
  88. assert.NoError(t, json.Unmarshal(fileData, snapshot))
  89. hello, err := faketls.ParseClientHello(suite.secret.Key[:], snapshot.GetFull())
  90. assert.NoError(t, err)
  91. assert.WithinDuration(t, snapshot.GetTime(), hello.Time, time.Second)
  92. assert.Equal(t, snapshot.GetRandom(), hello.Random[:])
  93. assert.Equal(t, snapshot.GetSessionID(), hello.SessionID)
  94. assert.Equal(t, snapshot.GetHost(), hello.Host)
  95. assert.Equal(t, snapshot.GetCipherSuite(), hello.CipherSuite)
  96. })
  97. }
  98. }
  99. func (suite *ClientHelloTestSuite) TestSnapshotBad() {
  100. files, err := os.ReadDir("testdata")
  101. suite.NoError(err)
  102. testData := []string{}
  103. for _, v := range files {
  104. if strings.HasPrefix(v.Name(), "client-hello-bad") {
  105. testData = append(testData, v.Name())
  106. }
  107. }
  108. for _, name := range testData {
  109. path := filepath.Join("testdata", name)
  110. suite.T().Run(name, func(t *testing.T) {
  111. fileData, err := os.ReadFile(path)
  112. assert.NoError(t, err)
  113. snapshot := &ClientHelloSnapshot{}
  114. assert.NoError(t, json.Unmarshal(fileData, snapshot))
  115. _, err = faketls.ParseClientHello(suite.secret.Key[:], snapshot.GetFull())
  116. assert.Error(t, err)
  117. })
  118. }
  119. }
  120. func (suite *ClientHelloTestSuite) TestValidateHostname() {
  121. hello := faketls.ClientHello{
  122. Time: time.Now(),
  123. }
  124. suite.NoError(hello.Valid("hostname", time.Second))
  125. hello.Host = "hostname"
  126. suite.Error(hello.Valid("hostname2", time.Second))
  127. suite.NoError(hello.Valid("hostname", time.Second))
  128. }
  129. func (suite *ClientHelloTestSuite) TestValidateTime() {
  130. testData := []time.Duration{
  131. -2 * time.Second,
  132. 2 * time.Second,
  133. }
  134. for _, v := range testData {
  135. value := v
  136. suite.T().Run(value.String(), func(t *testing.T) {
  137. hello := faketls.ClientHello{
  138. Host: "hostname",
  139. Time: time.Now().Add(value),
  140. }
  141. suite.Error(hello.Valid("hostname", 500*time.Millisecond))
  142. suite.Error(hello.Valid("hostname", time.Second))
  143. suite.NoError(hello.Valid("hostname", 3*time.Second))
  144. })
  145. }
  146. }
  147. func TestClientHello(t *testing.T) {
  148. t.Parallel()
  149. suite.Run(t, &ClientHelloTestSuite{})
  150. }