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
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

client_protocol.go 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package faketls
  2. import (
  3. "bufio"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "net"
  9. "strconv"
  10. "sync"
  11. "time"
  12. "mtg/antireplay"
  13. "mtg/config"
  14. "mtg/conntypes"
  15. "mtg/obfuscated2"
  16. "mtg/protocol"
  17. "mtg/stats"
  18. "mtg/tlstypes"
  19. "mtg/wrappers/stream"
  20. )
  21. type ClientProtocol struct {
  22. obfuscated2.ClientProtocol
  23. }
  24. func (c *ClientProtocol) Handshake(socket conntypes.StreamReadWriteCloser) (conntypes.StreamReadWriteCloser, error) {
  25. rewinded := stream.NewRewind(socket)
  26. bufferedReader := bufio.NewReader(rewinded)
  27. for _, expected := range faketlsStartBytes {
  28. if actual, err := bufferedReader.ReadByte(); err != nil || actual != expected {
  29. rewinded.Rewind()
  30. c.cloakHost(rewinded)
  31. return nil, errors.New("failed first bytes of tls handshake")
  32. }
  33. }
  34. rewinded.Rewind()
  35. rewinded = stream.NewRewind(rewinded)
  36. if err := c.tlsHandshake(rewinded); err != nil {
  37. rewinded.Rewind()
  38. c.cloakHost(rewinded)
  39. return nil, fmt.Errorf("failed tls handshake: %w", err)
  40. }
  41. conn := stream.NewFakeTLS(socket)
  42. conn, err := c.ClientProtocol.Handshake(conn)
  43. if err != nil {
  44. return nil, err
  45. }
  46. return conn, err
  47. }
  48. func (c *ClientProtocol) tlsHandshake(conn io.ReadWriter) error {
  49. helloRecord, err := tlstypes.ReadRecord(conn)
  50. if err != nil {
  51. return fmt.Errorf("cannot read initial record: %w", err)
  52. }
  53. clientHello, err := tlstypes.ParseClientHello(helloRecord.Data.Bytes())
  54. if err != nil {
  55. return fmt.Errorf("cannot parse client hello: %w", err)
  56. }
  57. digest := clientHello.Digest()
  58. for i := 0; i < len(digest)-4; i++ {
  59. if digest[i] != 0 {
  60. return errBadDigest
  61. }
  62. }
  63. timestamp := int64(binary.LittleEndian.Uint32(digest[len(digest)-4:]))
  64. createdAt := time.Unix(timestamp, 0)
  65. timeDiff := time.Since(createdAt)
  66. if (timeDiff > TimeSkew || timeDiff < -TimeSkew) && timestamp > TimeFromBoot {
  67. return errBadTime
  68. }
  69. if antireplay.Cache.HasTLS(clientHello.Random[:]) {
  70. stats.Stats.ReplayDetected()
  71. return errors.New("replay attack is detected")
  72. }
  73. antireplay.Cache.AddTLS(clientHello.Random[:])
  74. serverHello := tlstypes.NewServerHello(clientHello)
  75. serverHelloPacket := serverHello.WelcomePacket()
  76. if _, err := conn.Write(serverHelloPacket); err != nil {
  77. return fmt.Errorf("cannot send welcome packet: %w", err)
  78. }
  79. return nil
  80. }
  81. func (c *ClientProtocol) cloakHost(clientConn io.ReadWriteCloser) {
  82. addr := net.JoinHostPort(config.C.CloakHost, strconv.Itoa(config.C.CloakPort))
  83. hostConn, err := net.Dial("tcp", addr)
  84. if err != nil {
  85. return
  86. }
  87. defer hostConn.Close()
  88. wg := &sync.WaitGroup{}
  89. wg.Add(2)
  90. go c.pipe(hostConn, clientConn, wg)
  91. go c.pipe(clientConn, hostConn, wg)
  92. wg.Wait()
  93. }
  94. func (c *ClientProtocol) pipe(dst io.WriteCloser, src io.Reader, wg *sync.WaitGroup) {
  95. defer func() {
  96. wg.Done()
  97. dst.Close()
  98. }()
  99. io.Copy(dst, src) // nolint: errcheck
  100. }
  101. func MakeClientProtocol() protocol.ClientProtocol {
  102. return &ClientProtocol{}
  103. }