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 символов.

protocol.go 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package mtproto
  2. import (
  3. "fmt"
  4. "github.com/9seconds/mtg/conntypes"
  5. "github.com/9seconds/mtg/mtproto/rpc"
  6. "github.com/9seconds/mtg/protocol"
  7. "github.com/9seconds/mtg/telegram"
  8. "github.com/9seconds/mtg/wrappers/packet"
  9. "github.com/9seconds/mtg/wrappers/stream"
  10. )
  11. func TelegramProtocol(req *protocol.TelegramRequest) (conntypes.PacketReadWriteCloser, error) {
  12. conn, err := telegram.Middle.Dial(req.ClientProtocol.DC(),
  13. req.ClientProtocol.ConnectionProtocol())
  14. if err != nil {
  15. return nil, fmt.Errorf("cannot connect to telegram: %w", err)
  16. }
  17. rpcNonceConn := packet.NewMtprotoFrame(conn, rpc.SeqNoNonce)
  18. rpcNonceReq, err := doRPCNonceRequest(rpcNonceConn)
  19. if err != nil {
  20. return nil, fmt.Errorf("cannot do nonce request: %w", err)
  21. }
  22. rpcNonceResp, err := getRPCNonceResponse(rpcNonceConn, rpcNonceReq)
  23. if err != nil {
  24. return nil, fmt.Errorf("cannot get nonce response: %w", err)
  25. }
  26. secureConn := stream.NewMiddleProxyCipher(conn, rpcNonceReq, rpcNonceResp, telegram.Middle.Secret())
  27. frameConn := packet.NewMtprotoFrame(secureConn, rpc.SeqNoHandshake)
  28. if err := doRPCHandshakeRequest(frameConn); err != nil {
  29. return nil, fmt.Errorf("cannot do handshake request: %w", err)
  30. }
  31. if err := getRPCHandshakeResponse(frameConn); err != nil {
  32. return nil, fmt.Errorf("cannot get handshake response: %w", err)
  33. }
  34. return frameConn, nil
  35. }
  36. func doRPCNonceRequest(conn conntypes.BasePacketWriter) (*rpc.NonceRequest, error) {
  37. rpcNonceReq, err := rpc.NewNonceRequest(telegram.Middle.Secret())
  38. if err != nil {
  39. panic(err)
  40. }
  41. if err := conn.Write(rpcNonceReq.Bytes()); err != nil {
  42. return nil, err
  43. }
  44. return rpcNonceReq, nil
  45. }
  46. func getRPCNonceResponse(conn conntypes.BasePacketReader, req *rpc.NonceRequest) (*rpc.NonceResponse, error) {
  47. packet, err := conn.Read()
  48. if err != nil {
  49. return nil, fmt.Errorf("cannot read from connection: %w", err)
  50. }
  51. resp, err := rpc.NewNonceResponse(packet)
  52. if err != nil {
  53. return nil, fmt.Errorf("cannot build rpc nonce response: %w", err)
  54. }
  55. if err = resp.Valid(req); err != nil {
  56. return nil, fmt.Errorf("invalid nonce response: %w", err)
  57. }
  58. return resp, nil
  59. }
  60. func doRPCHandshakeRequest(conn conntypes.BasePacketWriter) error {
  61. if err := conn.Write(rpc.HandshakeRequest); err != nil {
  62. return fmt.Errorf("cannot make a request: %w", err)
  63. }
  64. return nil
  65. }
  66. func getRPCHandshakeResponse(conn conntypes.BasePacketReader) error {
  67. packet, err := conn.Read()
  68. if err != nil {
  69. return fmt.Errorf("cannot read a response: %w", err)
  70. }
  71. resp, err := rpc.NewHandshakeResponse(packet)
  72. if err != nil {
  73. return fmt.Errorf("cannot build a handshake response: %w", err)
  74. }
  75. if err := resp.Valid(); err != nil {
  76. return fmt.Errorf("invalid handshake response: %w", err)
  77. }
  78. return nil
  79. }