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ů.

telegram_protocol.go 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package obfuscated2
  2. import (
  3. "crypto/rand"
  4. "github.com/juju/errors"
  5. "github.com/9seconds/mtg/protocol"
  6. "github.com/9seconds/mtg/telegram"
  7. "github.com/9seconds/mtg/utils"
  8. "github.com/9seconds/mtg/wrappers"
  9. )
  10. type TelegramProtocol struct {
  11. protocol.BaseProtocol
  12. dialer telegram.Telegram
  13. }
  14. func (t *TelegramProtocol) Handshake(req *protocol.TelegramRequest) (wrappers.Wrap, error) {
  15. socket, err := t.dialer.Dial(req.Ctx,
  16. req.Cancel,
  17. req.ClientProtocol.GetDC(),
  18. req.ClientProtocol.GetConnectionProtocol())
  19. if err != nil {
  20. return nil, errors.Annotate(err, "Cannot dial to Telegram")
  21. }
  22. fm := generateFrame(req.ClientProtocol)
  23. data := fm.Bytes()
  24. encryptor := utils.MakeStreamCipher(fm.Key(), fm.IV())
  25. decryptedFrame := fm.Invert()
  26. decryptor := utils.MakeStreamCipher(decryptedFrame.Key(), decryptedFrame.IV())
  27. copyFrame := make([]byte, frameLen)
  28. copy(copyFrame[:frameOffsetIV], data[:frameOffsetIV])
  29. encryptor.XORKeyStream(data, data)
  30. copy(data[:frameOffsetIV], copyFrame[:frameOffsetIV])
  31. if _, err := socket.Write(data); err != nil {
  32. return nil, errors.Annotate(err, "Cannot write handshate frame to Telegram")
  33. }
  34. return wrappers.NewObfuscated2(socket, encryptor, decryptor), nil
  35. }
  36. func MakeTelegramProtocol(dialer telegram.Telegram) protocol.TelegramProtocol {
  37. return &TelegramProtocol{
  38. dialer: dialer,
  39. }
  40. }
  41. func generateFrame(cp protocol.ClientProtocol) (fm Frame) {
  42. data := fm.Bytes()
  43. for {
  44. if _, err := rand.Read(data); err != nil {
  45. continue
  46. }
  47. if data[0] == 0xef {
  48. continue
  49. }
  50. val := (uint32(data[3]) << 24) | (uint32(data[2]) << 16) | (uint32(data[1]) << 8) | uint32(data[0])
  51. if val == 0x44414548 || val == 0x54534f50 || val == 0x20544547 || val == 0x4954504f || val == 0xeeeeeeee {
  52. continue
  53. }
  54. val = (uint32(data[7]) << 24) | (uint32(data[6]) << 16) | (uint32(data[5]) << 8) | uint32(data[4])
  55. if val == 0x00000000 {
  56. continue
  57. }
  58. copy(fm.Magic(), cp.GetConnectionType().Tag())
  59. return
  60. }
  61. }