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_protocol.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package obfuscated2
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "encoding/binary"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "time"
  10. "github.com/9seconds/mtg/antireplay"
  11. "github.com/9seconds/mtg/config"
  12. "github.com/9seconds/mtg/conntypes"
  13. "github.com/9seconds/mtg/protocol"
  14. "github.com/9seconds/mtg/stats"
  15. "github.com/9seconds/mtg/utils"
  16. "github.com/9seconds/mtg/wrappers/stream"
  17. )
  18. const clientProtocolHandshakeTimeout = 10 * time.Second
  19. type ClientProtocol struct {
  20. connectionType conntypes.ConnectionType
  21. connectionProtocol conntypes.ConnectionProtocol
  22. dc conntypes.DC
  23. }
  24. func (c *ClientProtocol) ConnectionType() conntypes.ConnectionType {
  25. return c.connectionType
  26. }
  27. func (c *ClientProtocol) ConnectionProtocol() conntypes.ConnectionProtocol {
  28. return c.connectionProtocol
  29. }
  30. func (c *ClientProtocol) DC() conntypes.DC {
  31. return c.dc
  32. }
  33. func (c *ClientProtocol) Handshake(socket conntypes.StreamReadWriteCloser) (conntypes.StreamReadWriteCloser, error) {
  34. fm, err := c.ReadFrame(socket)
  35. if err != nil {
  36. return nil, fmt.Errorf("cannot make a client handshake: %w", err)
  37. }
  38. decHasher := sha256.New()
  39. decHasher.Write(fm.Key()) // nolint: errcheck
  40. decHasher.Write(config.C.Secret) // nolint: errcheck
  41. decryptor := utils.MakeStreamCipher(decHasher.Sum(nil), fm.IV())
  42. invertedFrame := fm.Invert()
  43. encHasher := sha256.New()
  44. encHasher.Write(invertedFrame.Key()) // nolint: errcheck
  45. encHasher.Write(config.C.Secret) // nolint: errcheck
  46. encryptor := utils.MakeStreamCipher(encHasher.Sum(nil), invertedFrame.IV())
  47. decryptedFrame := Frame{}
  48. decryptor.XORKeyStream(decryptedFrame.Bytes(), fm.Bytes())
  49. magic := decryptedFrame.Magic()
  50. switch {
  51. case bytes.Equal(magic, conntypes.ConnectionTagAbridged):
  52. c.connectionType = conntypes.ConnectionTypeAbridged
  53. case bytes.Equal(magic, conntypes.ConnectionTagIntermediate):
  54. c.connectionType = conntypes.ConnectionTypeIntermediate
  55. case bytes.Equal(magic, conntypes.ConnectionTagSecure):
  56. c.connectionType = conntypes.ConnectionTypeSecure
  57. default:
  58. return nil, errors.New("unknown connection type")
  59. }
  60. c.connectionProtocol = conntypes.ConnectionProtocolIPv4
  61. if socket.LocalAddr().IP.To4() == nil {
  62. c.connectionProtocol = conntypes.ConnectionProtocolIPv6
  63. }
  64. buf := bytes.NewReader(decryptedFrame.DC())
  65. if err := binary.Read(buf, binary.LittleEndian, &c.dc); err != nil {
  66. c.dc = conntypes.DCDefaultIdx
  67. }
  68. replayKey := decryptedFrame.Unique()
  69. if antireplay.Cache.HasObfuscated2(replayKey) {
  70. stats.Stats.ReplayDetected()
  71. return nil, errors.New("replay attack is detected")
  72. }
  73. antireplay.Cache.AddObfuscated2(replayKey)
  74. return stream.NewObfuscated2(socket, encryptor, decryptor), nil
  75. }
  76. func (c *ClientProtocol) ReadFrame(socket conntypes.StreamReader) (fm Frame, err error) {
  77. if _, err = io.ReadFull(handshakeReader{socket}, fm.Bytes()); err != nil {
  78. err = fmt.Errorf("cannot extract obfuscated2 frame: %w", err)
  79. }
  80. return
  81. }
  82. type handshakeReader struct {
  83. parent conntypes.StreamReader
  84. }
  85. func (h handshakeReader) Read(p []byte) (int, error) {
  86. return h.parent.ReadTimeout(p, clientProtocolHandshakeTimeout)
  87. }
  88. func MakeClientProtocol() protocol.ClientProtocol {
  89. return &ClientProtocol{}
  90. }