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
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

telegram_protocol.go 1.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package newobfuscated2
  2. import (
  3. "crypto/rand"
  4. "github.com/juju/errors"
  5. "github.com/9seconds/mtg/newprotocol"
  6. "github.com/9seconds/mtg/newwrappers"
  7. )
  8. type TelegramProtocol struct {
  9. newprotocol.BaseProtocol
  10. }
  11. func (t *TelegramProtocol) Handshake(socketRaw newwrappers.Wrap, client *ClientProtocol) (newwrappers.StreamReadWriteCloser, error) {
  12. socket := socketRaw.(newwrappers.StreamReadWriteCloser)
  13. fm := generateFrame(client)
  14. data := fm.bytes()
  15. encryptor := makeStreamCipher(fm.key(), fm.iv())
  16. decryptedFrame := fm.invert()
  17. decryptor := makeStreamCipher(decryptedFrame.key(), decryptedFrame.iv())
  18. copyFrame := make([]byte, frameLen)
  19. copy(copyFrame[:frameOffsetIV], data[:frameOffsetIV])
  20. encryptor.XORKeyStream(data, data)
  21. copy(data[:frameOffsetIV], copyFrame[:frameOffsetIV])
  22. if _, err := socket.Write(data); err != nil {
  23. return nil, errors.Annotate(err, "Cannot write handshate frame to Telegram")
  24. }
  25. return newwrappers.NewObfuscated2(socket, encryptor, decryptor), nil
  26. }
  27. func generateFrame(client *ClientProtocol) (fm frame) {
  28. for {
  29. data := fm.bytes()
  30. if _, err := rand.Read(data); err != nil {
  31. continue
  32. }
  33. if data[0] == 0xef {
  34. continue
  35. }
  36. val := (uint32(data[3]) << 24) | (uint32(data[2]) << 16) | (uint32(data[1]) << 8) | uint32(data[0])
  37. if val == 0x44414548 || val == 0x54534f50 || val == 0x20544547 || val == 0x4954504f || val == 0xeeeeeeee {
  38. continue
  39. }
  40. val = (uint32(data[7]) << 24) | (uint32(data[6]) << 16) | (uint32(data[5]) << 8) | uint32(data[4])
  41. if val == 0x00000000 {
  42. continue
  43. }
  44. copy(fm.magic(), client.ConnectionType.Tag())
  45. return
  46. }
  47. }