model_mtproto_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package model
  2. import (
  3. "encoding/hex"
  4. "encoding/json"
  5. "strings"
  6. "testing"
  7. )
  8. func TestGenerateFakeTLSSecret(t *testing.T) {
  9. domain := "www.cloudflare.com"
  10. s := GenerateFakeTLSSecret(domain)
  11. if !strings.HasPrefix(s, "ee") {
  12. t.Fatalf("secret must start with ee, got %q", s)
  13. }
  14. wantSuffix := hex.EncodeToString([]byte(domain))
  15. if !strings.HasSuffix(s, wantSuffix) {
  16. t.Fatalf("secret must end with hex(domain) %q, got %q", wantSuffix, s)
  17. }
  18. if len(s) != 2+32+len(wantSuffix) {
  19. t.Fatalf("unexpected secret length %d", len(s))
  20. }
  21. if _, err := hex.DecodeString(s[2:34]); err != nil {
  22. t.Fatalf("middle is not valid hex: %v", err)
  23. }
  24. }
  25. func TestStripMtprotoInboundAdTag(t *testing.T) {
  26. in := `{"adTag":"0123456789abcdef0123456789abcdef","clients":[{"email":"a","adTag":"fedcba9876543210fedcba9876543210"}]}`
  27. out, changed := StripMtprotoInboundAdTag(in)
  28. if !changed {
  29. t.Fatal("expected the inbound-level adTag to be stripped")
  30. }
  31. var parsed map[string]any
  32. if err := json.Unmarshal([]byte(out), &parsed); err != nil {
  33. t.Fatalf("unmarshal: %v", err)
  34. }
  35. if _, ok := parsed["adTag"]; ok {
  36. t.Fatalf("adTag key must be removed, got %s", out)
  37. }
  38. clients := parsed["clients"].([]any)
  39. if clients[0].(map[string]any)["adTag"] != "fedcba9876543210fedcba9876543210" {
  40. t.Fatalf("client adTag must be preserved, got %s", out)
  41. }
  42. if _, changed2 := StripMtprotoInboundAdTag(out); changed2 {
  43. t.Fatal("second strip must be a no-op")
  44. }
  45. }
  46. func TestStripMtprotoInboundSecret(t *testing.T) {
  47. // A multi-client inbound that still carries a dead inbound-level secret has
  48. // it removed while the clients (and every other key) survive untouched.
  49. in := `{"fakeTlsDomain":"a.com","secret":"eedeadbeef","clients":[{"email":"x","secret":"eeaaaa"}]}`
  50. out, changed := StripMtprotoInboundSecret(in)
  51. if !changed {
  52. t.Fatal("expected the inbound-level secret to be stripped")
  53. }
  54. var parsed map[string]any
  55. if err := json.Unmarshal([]byte(out), &parsed); err != nil {
  56. t.Fatalf("stripped settings not valid json: %v", err)
  57. }
  58. if _, ok := parsed["secret"]; ok {
  59. t.Fatalf("inbound-level secret should be gone, got %q", out)
  60. }
  61. if parsed["fakeTlsDomain"] != "a.com" {
  62. t.Fatalf("fakeTlsDomain must survive, got %q", out)
  63. }
  64. clients, ok := parsed["clients"].([]any)
  65. if !ok || len(clients) != 1 {
  66. t.Fatalf("clients must survive untouched, got %q", out)
  67. }
  68. if clients[0].(map[string]any)["secret"] != "eeaaaa" {
  69. t.Fatalf("client secret must survive untouched, got %q", out)
  70. }
  71. // Nothing to strip when there is no inbound-level secret.
  72. if _, changed2 := StripMtprotoInboundSecret(out); changed2 {
  73. t.Fatal("expected no change when there is no inbound-level secret")
  74. }
  75. if _, changed3 := StripMtprotoInboundSecret(`{"clients":[]}`); changed3 {
  76. t.Fatal("expected no change for settings without a secret key")
  77. }
  78. }
  79. func TestHealMtprotoClientSecrets(t *testing.T) {
  80. // An empty client secret is filled from the inbound-level default domain.
  81. in := `{"fakeTlsDomain":"a.com","clients":[{"email":"x","secret":""}]}`
  82. out, changed := HealMtprotoClientSecrets(in)
  83. if !changed {
  84. t.Fatal("expected an empty client secret to be filled")
  85. }
  86. var parsed map[string]any
  87. if err := json.Unmarshal([]byte(out), &parsed); err != nil {
  88. t.Fatalf("healed settings not valid json: %v", err)
  89. }
  90. clients := parsed["clients"].([]any)
  91. got := clients[0].(map[string]any)["secret"].(string)
  92. if !strings.HasPrefix(got, "ee") || !strings.HasSuffix(got, hex.EncodeToString([]byte("a.com"))) {
  93. t.Fatalf("filled client secret malformed: %q", got)
  94. }
  95. // Healing is idempotent once every client secret is valid.
  96. if _, changed2 := HealMtprotoClientSecrets(out); changed2 {
  97. t.Fatal("expected no change for already-valid client secrets")
  98. }
  99. // A client's own embedded domain is preserved even when it differs from the
  100. // inbound-level default (per-client domain fronting).
  101. own := "ee00112233445566778899aabbccddeeff" + hex.EncodeToString([]byte("b.com"))
  102. in3 := `{"fakeTlsDomain":"a.com","clients":[{"email":"y","secret":"` + own + `"}]}`
  103. out3, changed3 := HealMtprotoClientSecrets(in3)
  104. if changed3 {
  105. t.Fatalf("a valid per-client secret must be left untouched, got %q", out3)
  106. }
  107. // No clients array — nothing to heal.
  108. if _, changed4 := HealMtprotoClientSecrets(`{"fakeTlsDomain":"a.com"}`); changed4 {
  109. t.Fatal("expected no change when there are no clients")
  110. }
  111. }