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
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

client_side_test.go 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. package fake_test
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "io"
  7. "testing"
  8. "time"
  9. "github.com/9seconds/mtg/v2/internal/testlib"
  10. "github.com/9seconds/mtg/v2/mtglib"
  11. "github.com/9seconds/mtg/v2/mtglib/internal/tls"
  12. "github.com/9seconds/mtg/v2/mtglib/internal/tls/fake"
  13. "github.com/stretchr/testify/mock"
  14. "github.com/stretchr/testify/require"
  15. "github.com/stretchr/testify/suite"
  16. )
  17. const (
  18. TolerateTime = 365 * 30 * 24 * time.Hour
  19. )
  20. type parseClientHelloConnMock struct {
  21. testlib.EssentialsConnMock
  22. readBuf *bytes.Buffer
  23. }
  24. func (m *parseClientHelloConnMock) Read(p []byte) (int, error) {
  25. return m.readBuf.Read(p)
  26. }
  27. type ParseClientHelloTestSuite struct {
  28. suite.Suite
  29. secret mtglib.Secret
  30. readBuf *bytes.Buffer
  31. connMock *parseClientHelloConnMock
  32. }
  33. func (suite *ParseClientHelloTestSuite) SetupSuite() {
  34. parsed, err := mtglib.ParseSecret("ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d")
  35. require.NoError(suite.T(), err)
  36. suite.secret = parsed
  37. }
  38. func (suite *ParseClientHelloTestSuite) SetupTest() {
  39. suite.readBuf = &bytes.Buffer{}
  40. suite.connMock = &parseClientHelloConnMock{
  41. readBuf: suite.readBuf,
  42. }
  43. suite.connMock.
  44. On("SetReadDeadline", mock.AnythingOfType("time.Time")).
  45. Twice().
  46. Return(nil)
  47. }
  48. func (suite *ParseClientHelloTestSuite) TearDownTest() {
  49. suite.connMock.AssertExpectations(suite.T())
  50. }
  51. type ParseClientHello_TLSHeaderTestSuite struct {
  52. ParseClientHelloTestSuite
  53. }
  54. func (suite *ParseClientHello_TLSHeaderTestSuite) TestEmpty() {
  55. suite.connMock.ExpectedCalls = []*mock.Call{}
  56. suite.connMock.
  57. On("SetReadDeadline", mock.AnythingOfType("time.Time")).
  58. Once().
  59. Return(errors.New("fail"))
  60. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  61. suite.ErrorContains(err, "fail")
  62. }
  63. func (suite *ParseClientHello_TLSHeaderTestSuite) TestNothing() {
  64. suite.connMock.ExpectedCalls = []*mock.Call{}
  65. suite.connMock.
  66. On("SetReadDeadline", mock.AnythingOfType("time.Time")).
  67. Twice().
  68. Return(nil)
  69. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  70. suite.ErrorIs(err, io.EOF)
  71. }
  72. func (suite *ParseClientHello_TLSHeaderTestSuite) TestUnknownRecord() {
  73. suite.readBuf.Write([]byte{
  74. 10,
  75. 3, 3,
  76. 0, 0,
  77. })
  78. suite.readBuf.WriteByte(10)
  79. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  80. suite.ErrorContains(err, "unexpected record type 0xa")
  81. }
  82. func (suite *ParseClientHello_TLSHeaderTestSuite) TestUnknownProtocolVersion() {
  83. suite.readBuf.Write([]byte{
  84. tls.TypeHandshake,
  85. 3, 3,
  86. 0, 0,
  87. })
  88. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  89. suite.ErrorContains(err, "unexpected protocol version")
  90. }
  91. func (suite *ParseClientHello_TLSHeaderTestSuite) TestCannotReadRestOfRecord() {
  92. suite.readBuf.Write([]byte{
  93. tls.TypeHandshake,
  94. 3, 1,
  95. 0, 10,
  96. })
  97. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  98. suite.ErrorIs(err, io.EOF)
  99. }
  100. type ParseClientHelloHandshakeTestSuite struct {
  101. ParseClientHelloTestSuite
  102. }
  103. func (suite *ParseClientHelloHandshakeTestSuite) SetupTest() {
  104. suite.ParseClientHelloTestSuite.SetupTest()
  105. suite.readBuf.Write([]byte{
  106. tls.TypeHandshake,
  107. 3, 1,
  108. 0,
  109. })
  110. }
  111. func (suite *ParseClientHelloHandshakeTestSuite) TestCannotReadHeader() {
  112. suite.readBuf.Write([]byte{
  113. 1,
  114. 10,
  115. })
  116. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  117. suite.ErrorContains(err, "cannot read handshake header")
  118. }
  119. func (suite *ParseClientHelloHandshakeTestSuite) TestIncorrectHandshakeType() {
  120. suite.readBuf.Write([]byte{
  121. 4,
  122. 10, 0, 0, 0,
  123. })
  124. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  125. suite.ErrorContains(err, "incorrect handshake type")
  126. }
  127. func (suite *ParseClientHelloHandshakeTestSuite) TestCannotReadHandshake() {
  128. suite.readBuf.Write([]byte{
  129. 4 + 3,
  130. 10, 0, 0, 0,
  131. })
  132. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  133. suite.ErrorIs(err, io.EOF)
  134. }
  135. type ParseClientHelloHandshakeBodyTestSuite struct {
  136. ParseClientHelloTestSuite
  137. }
  138. func (suite *ParseClientHelloHandshakeBodyTestSuite) SetupTest() {
  139. suite.ParseClientHelloTestSuite.SetupTest()
  140. suite.readBuf.Write([]byte{
  141. tls.TypeHandshake,
  142. 3, 1,
  143. 0,
  144. })
  145. }
  146. func (suite *ParseClientHelloHandshakeBodyTestSuite) writeBody(body []byte) {
  147. suite.readBuf.WriteByte(byte(4 + len(body)))
  148. suite.readBuf.Write([]byte{
  149. fake.TypeHandshakeClient,
  150. 0, 0, byte(len(body)),
  151. })
  152. suite.readBuf.Write(body)
  153. }
  154. func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadVersion() {
  155. suite.writeBody(nil)
  156. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  157. suite.ErrorContains(err, "cannot read client version")
  158. }
  159. func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadRandom() {
  160. suite.writeBody([]byte{3, 3})
  161. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  162. suite.ErrorContains(err, "cannot read client random")
  163. }
  164. func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadSessionIDLength() {
  165. body := make([]byte, 2+fake.RandomLen)
  166. suite.writeBody(body)
  167. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  168. suite.ErrorContains(err, "cannot read session ID length")
  169. }
  170. func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadSessionID() {
  171. body := make([]byte, 2+fake.RandomLen+1)
  172. body[2+fake.RandomLen] = 32
  173. suite.writeBody(body)
  174. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  175. suite.ErrorContains(err, "cannot read session id")
  176. }
  177. func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadCipherSuiteLength() {
  178. body := make([]byte, 2+fake.RandomLen+1)
  179. suite.writeBody(body)
  180. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  181. suite.ErrorContains(err, "cannot read cipher suite length")
  182. }
  183. func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadFirstCipherSuite() {
  184. body := make([]byte, 2+fake.RandomLen+1+2)
  185. suite.writeBody(body)
  186. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  187. suite.ErrorContains(err, "cannot read first cipher suite")
  188. }
  189. func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotSkipRemainingCipherSuites() {
  190. body := make([]byte, 2+fake.RandomLen+1+2+2)
  191. binary.BigEndian.PutUint16(body[2+fake.RandomLen+1:], 4)
  192. suite.writeBody(body)
  193. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  194. suite.ErrorContains(err, "cannot skip remaining cipher suites")
  195. }
  196. func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadCompressionMethodsLength() {
  197. body := make([]byte, 2+fake.RandomLen+1+2+2)
  198. binary.BigEndian.PutUint16(body[2+fake.RandomLen+1:], 2)
  199. suite.writeBody(body)
  200. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  201. suite.ErrorContains(err, "cannot read compression methods length")
  202. }
  203. func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotSkipCompressionMethods() {
  204. body := make([]byte, 2+fake.RandomLen+1+2+2+1)
  205. binary.BigEndian.PutUint16(body[2+fake.RandomLen+1:], 2)
  206. body[2+fake.RandomLen+1+2+2] = 1
  207. suite.writeBody(body)
  208. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  209. suite.ErrorContains(err, "cannot skip compression methods")
  210. }
  211. type ParseClientHelloSNITestSuite struct {
  212. ParseClientHelloTestSuite
  213. }
  214. func (suite *ParseClientHelloSNITestSuite) SetupTest() {
  215. suite.ParseClientHelloTestSuite.SetupTest()
  216. suite.readBuf.Write([]byte{
  217. tls.TypeHandshake,
  218. 3, 1,
  219. 0,
  220. })
  221. }
  222. func (suite *ParseClientHelloSNITestSuite) writeExtensions(extensions []byte) {
  223. handshakeBodyLen := 41 + len(extensions)
  224. suite.readBuf.WriteByte(byte(4 + handshakeBodyLen))
  225. suite.readBuf.Write([]byte{
  226. fake.TypeHandshakeClient,
  227. 0, 0, byte(handshakeBodyLen),
  228. })
  229. // version(2) + random(32) + sessionIDLen(1) + cipherSuiteLen(2) +
  230. // cipherSuite(2) + compressionLen(1) + compression(1) = 41
  231. body := make([]byte, 41)
  232. binary.BigEndian.PutUint16(body[35:], 2)
  233. body[39] = 1
  234. suite.readBuf.Write(body)
  235. suite.readBuf.Write(extensions)
  236. }
  237. func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionsLength() {
  238. suite.writeExtensions(nil)
  239. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  240. suite.ErrorContains(err, "cannot read length of TLS extensions")
  241. }
  242. func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensions() {
  243. suite.writeExtensions([]byte{0, 10})
  244. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  245. suite.ErrorContains(err, "cannot read extensions")
  246. }
  247. func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionType() {
  248. suite.writeExtensions([]byte{0, 1, 0xAB})
  249. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  250. suite.ErrorContains(err, "cannot read extension type")
  251. }
  252. func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionLength() {
  253. suite.writeExtensions([]byte{0, 2, 0xFF, 0xFF})
  254. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  255. suite.ErrorContains(err, "length:")
  256. }
  257. func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionData() {
  258. suite.writeExtensions([]byte{0, 4, 0xFF, 0xFF, 0, 5})
  259. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  260. suite.ErrorContains(err, "data: len")
  261. }
  262. func (suite *ParseClientHelloSNITestSuite) TestCannotReadSNIRecordLength() {
  263. suite.writeExtensions([]byte{0, 5, 0, 0, 0, 1, 0xAB})
  264. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  265. suite.ErrorContains(err, "cannot read the length of the SNI record")
  266. }
  267. func (suite *ParseClientHelloSNITestSuite) TestCannotReadSNIListType() {
  268. suite.writeExtensions([]byte{0, 6, 0, 0, 0, 2, 0, 1})
  269. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  270. suite.ErrorContains(err, "cannot read SNI list type")
  271. }
  272. func (suite *ParseClientHelloSNITestSuite) TestIncorrectSNIListType() {
  273. suite.writeExtensions([]byte{0, 7, 0, 0, 0, 3, 0, 1, 5})
  274. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  275. suite.ErrorContains(err, "incorrect SNI list type")
  276. }
  277. func (suite *ParseClientHelloSNITestSuite) TestCannotReadHostnameLength() {
  278. suite.writeExtensions([]byte{0, 8, 0, 0, 0, 4, 0, 2, 0, 0xAB})
  279. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  280. suite.ErrorContains(err, "incorrect length of the hostname")
  281. }
  282. func (suite *ParseClientHelloSNITestSuite) TestCannotReadHostname() {
  283. suite.writeExtensions([]byte{0, 9, 0, 0, 0, 5, 0, 3, 0, 0, 5})
  284. _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
  285. suite.ErrorContains(err, "incorrect length of SNI hostname")
  286. }
  287. func TestParseClientHelloTLSHeader(t *testing.T) {
  288. t.Parallel()
  289. suite.Run(t, &ParseClientHello_TLSHeaderTestSuite{})
  290. }
  291. func TestParseClientHelloHandshake(t *testing.T) {
  292. t.Parallel()
  293. suite.Run(t, &ParseClientHelloHandshakeTestSuite{})
  294. }
  295. func TestParseClientHelloHandshakeBody(t *testing.T) {
  296. t.Parallel()
  297. suite.Run(t, &ParseClientHelloHandshakeBodyTestSuite{})
  298. }
  299. func TestParseClientHelloSNI(t *testing.T) {
  300. t.Parallel()
  301. suite.Run(t, &ParseClientHelloSNITestSuite{})
  302. }