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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package mtglib
  2. import (
  3. "crypto/rand"
  4. "encoding/base64"
  5. "encoding/hex"
  6. "fmt"
  7. "strings"
  8. )
  9. const (
  10. SecretKeyLength = 16
  11. secretFakeTLSFirstByte byte = 238
  12. )
  13. var secretEmptyKey [SecretKeyLength]byte
  14. type Secret struct {
  15. Key [SecretKeyLength]byte
  16. Host string
  17. }
  18. func (s Secret) MarshalText() ([]byte, error) {
  19. if s.Valid() {
  20. return []byte(s.String()), nil
  21. }
  22. return nil, nil
  23. }
  24. func (s *Secret) UnmarshalText(data []byte) error {
  25. text := string(data)
  26. if text == "" {
  27. return ErrSecretEmpty
  28. }
  29. var (
  30. decoded []byte
  31. err error
  32. )
  33. if strings.HasPrefix(text, "ee") {
  34. decoded, err = hex.DecodeString(strings.TrimPrefix(text, "ee"))
  35. }
  36. if err != nil || len(decoded) <= SecretKeyLength {
  37. decoded, err = base64.RawURLEncoding.DecodeString(text)
  38. if err != nil {
  39. return fmt.Errorf("incorrect secret format: %w", err)
  40. }
  41. if len(decoded) <= SecretKeyLength {
  42. return fmt.Errorf("secret has incorrect length %d", len(text))
  43. }
  44. if decoded[0] != secretFakeTLSFirstByte {
  45. return fmt.Errorf("incorrect first byte: %v", decoded[0])
  46. }
  47. decoded = decoded[1:]
  48. }
  49. copy(s.Key[:], decoded[:SecretKeyLength])
  50. s.Host = string(decoded[SecretKeyLength:])
  51. if s.Host == "" {
  52. return fmt.Errorf("hostname cannot be empty: %s", text)
  53. }
  54. return nil
  55. }
  56. func (s Secret) Valid() bool {
  57. return s.Key != secretEmptyKey && s.Host != ""
  58. }
  59. func (s Secret) String() string {
  60. return s.Base64()
  61. }
  62. func (s Secret) Base64() string {
  63. return base64.RawURLEncoding.EncodeToString(s.makeBytes())
  64. }
  65. func (s Secret) Hex() string {
  66. return hex.EncodeToString(s.makeBytes())
  67. }
  68. func (s *Secret) makeBytes() []byte {
  69. data := append([]byte{secretFakeTLSFirstByte}, s.Key[:]...)
  70. data = append(data, s.Host...)
  71. return data
  72. }
  73. func GenerateSecret(hostname string) Secret {
  74. s := Secret{
  75. Host: hostname,
  76. }
  77. if _, err := rand.Read(s.Key[:]); err != nil {
  78. panic(err)
  79. }
  80. return s
  81. }
  82. func ParseSecret(secret string) (Secret, error) {
  83. s := Secret{}
  84. return s, s.UnmarshalText([]byte(secret))
  85. }