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
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

client_protocol.go 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package faketls
  2. import (
  3. "bufio"
  4. "bytes"
  5. "encoding/binary"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "net"
  10. "strconv"
  11. "time"
  12. "github.com/9seconds/mtg/antireplay"
  13. "github.com/9seconds/mtg/config"
  14. "github.com/9seconds/mtg/conntypes"
  15. "github.com/9seconds/mtg/obfuscated2"
  16. "github.com/9seconds/mtg/protocol"
  17. "github.com/9seconds/mtg/stats"
  18. "github.com/9seconds/mtg/tlstypes"
  19. "github.com/9seconds/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 //nolint: wrapcheck
  45. }
  46. return conn, err //nolint: wrapcheck
  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. buf := &bytes.Buffer{}
  54. helloRecord.Data.WriteBytes(buf)
  55. clientHello, err := tlstypes.ParseClientHello(buf.Bytes())
  56. if err != nil {
  57. return fmt.Errorf("cannot parse client hello: %w", err)
  58. }
  59. digest := clientHello.Digest()
  60. for i := 0; i < len(digest)-4; i++ {
  61. if digest[i] != 0 {
  62. return errBadDigest
  63. }
  64. }
  65. timestamp := int64(binary.LittleEndian.Uint32(digest[len(digest)-4:]))
  66. createdAt := time.Unix(timestamp, 0)
  67. timeDiff := time.Since(createdAt)
  68. if (timeDiff > TimeSkew || timeDiff < -TimeSkew) && timestamp > TimeFromBoot {
  69. return errBadTime
  70. }
  71. if antireplay.Cache.HasTLS(clientHello.Random[:]) {
  72. stats.Stats.ReplayDetected()
  73. return errors.New("replay attack is detected")
  74. }
  75. antireplay.Cache.AddTLS(clientHello.Random[:])
  76. serverHello := tlstypes.NewServerHello(clientHello)
  77. serverHelloPacket := serverHello.WelcomePacket()
  78. if _, err := conn.Write(serverHelloPacket); err != nil {
  79. return fmt.Errorf("cannot send welcome packet: %w", err)
  80. }
  81. return nil
  82. }
  83. func (c *ClientProtocol) cloakHost(clientConn io.ReadWriteCloser) {
  84. stats.Stats.CloakedRequest()
  85. addr := net.JoinHostPort(config.C.CloakHost, strconv.Itoa(config.C.CloakPort))
  86. hostConn, err := net.Dial("tcp", addr)
  87. if err != nil {
  88. return
  89. }
  90. cloak(clientConn, hostConn)
  91. }
  92. func MakeClientProtocol() protocol.ClientProtocol {
  93. return &ClientProtocol{}
  94. }