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
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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