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

streamcipherrwc.go 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package wrappers
  2. import (
  3. "crypto/cipher"
  4. "net"
  5. )
  6. // StreamCipherReadWriteCloser is a ReadWriteCloser which ciphers
  7. // incoming and outgoing data with givem cipher.Stream instances.
  8. type StreamCipherReadWriteCloserWithAddr struct {
  9. encryptor cipher.Stream
  10. decryptor cipher.Stream
  11. conn ReadWriteCloserWithAddr
  12. }
  13. // Read reads from connection
  14. func (c *StreamCipherReadWriteCloserWithAddr) Read(p []byte) (n int, err error) {
  15. n, err = c.conn.Read(p)
  16. c.decryptor.XORKeyStream(p, p[:n])
  17. return
  18. }
  19. // Write writes into connection.
  20. func (c *StreamCipherReadWriteCloserWithAddr) Write(p []byte) (int, error) {
  21. // This is to decrease an amount of allocations. Unfortunately, escape
  22. // analysis in (at least Golang 1.10) is absolutely not perfect. For
  23. // example, it understands that we want to have a slice locally, right?
  24. // But since slice is effectively 2 ints + uintptr to [number]byte, the
  25. // most heavyweight part is placed in heap.
  26. buf := getBuffer()
  27. defer putBuffer(buf)
  28. buf.Grow(len(p))
  29. buf.Write(p)
  30. encrypted := buf.Bytes()
  31. c.encryptor.XORKeyStream(encrypted, p)
  32. return c.conn.Write(encrypted)
  33. }
  34. // Close closes underlying connection.
  35. func (c *StreamCipherReadWriteCloserWithAddr) Close() error {
  36. return c.conn.Close()
  37. }
  38. func (c *StreamCipherReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
  39. return c.conn.LocalAddr()
  40. }
  41. func (c *StreamCipherReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
  42. return c.conn.RemoteAddr()
  43. }
  44. func (c *StreamCipherReadWriteCloserWithAddr) SocketID() string {
  45. return c.conn.SocketID()
  46. }
  47. // NewStreamCipherRWC returns wrapper which transparently
  48. // encrypts/decrypts traffic with obfuscated2 protocol.
  49. func NewStreamCipherRWC(conn ReadWriteCloserWithAddr, encryptor, decryptor cipher.Stream) ReadWriteCloserWithAddr {
  50. return &StreamCipherReadWriteCloserWithAddr{
  51. conn: conn,
  52. encryptor: encryptor,
  53. decryptor: decryptor,
  54. }
  55. }