model_mtproto_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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 TestHealMtprotoSecret(t *testing.T) {
  26. domain := "example.com"
  27. suffix := hex.EncodeToString([]byte(domain))
  28. in := `{"fakeTlsDomain":"example.com","secret":""}`
  29. out, changed := HealMtprotoSecret(in)
  30. if !changed {
  31. t.Fatal("expected heal to populate an empty secret")
  32. }
  33. var parsed map[string]any
  34. if err := json.Unmarshal([]byte(out), &parsed); err != nil {
  35. t.Fatalf("healed settings not valid json: %v", err)
  36. }
  37. got, _ := parsed["secret"].(string)
  38. if !strings.HasPrefix(got, "ee") || !strings.HasSuffix(got, suffix) {
  39. t.Fatalf("healed secret malformed: %q", got)
  40. }
  41. if _, changed2 := HealMtprotoSecret(out); changed2 {
  42. t.Fatal("expected no change for an already-valid secret")
  43. }
  44. mid := got[2:34]
  45. newDomain := "telegram.org"
  46. in3 := `{"fakeTlsDomain":"telegram.org","secret":"` + got + `"}`
  47. out3, changed3 := HealMtprotoSecret(in3)
  48. if !changed3 {
  49. t.Fatal("expected heal to rewrite the domain suffix")
  50. }
  51. if err := json.Unmarshal([]byte(out3), &parsed); err != nil {
  52. t.Fatalf("healed settings not valid json: %v", err)
  53. }
  54. got3, _ := parsed["secret"].(string)
  55. if got3[2:34] != mid {
  56. t.Fatalf("random middle should be preserved on domain change: %q vs %q", got3[2:34], mid)
  57. }
  58. if !strings.HasSuffix(got3, hex.EncodeToString([]byte(newDomain))) {
  59. t.Fatalf("suffix not updated for new domain: %q", got3)
  60. }
  61. if _, changed4 := HealMtprotoSecret(`{"secret":"ee"}`); changed4 {
  62. t.Fatal("expected no change when fakeTlsDomain is missing")
  63. }
  64. }
  65. func TestHealMtprotoClientSecrets(t *testing.T) {
  66. // An empty client secret is filled from the inbound-level default domain.
  67. in := `{"fakeTlsDomain":"a.com","clients":[{"email":"x","secret":""}]}`
  68. out, changed := HealMtprotoClientSecrets(in)
  69. if !changed {
  70. t.Fatal("expected an empty client secret to be filled")
  71. }
  72. var parsed map[string]any
  73. if err := json.Unmarshal([]byte(out), &parsed); err != nil {
  74. t.Fatalf("healed settings not valid json: %v", err)
  75. }
  76. clients := parsed["clients"].([]any)
  77. got := clients[0].(map[string]any)["secret"].(string)
  78. if !strings.HasPrefix(got, "ee") || !strings.HasSuffix(got, hex.EncodeToString([]byte("a.com"))) {
  79. t.Fatalf("filled client secret malformed: %q", got)
  80. }
  81. // Healing is idempotent once every client secret is valid.
  82. if _, changed2 := HealMtprotoClientSecrets(out); changed2 {
  83. t.Fatal("expected no change for already-valid client secrets")
  84. }
  85. // A client's own embedded domain is preserved even when it differs from the
  86. // inbound-level default (per-client domain fronting).
  87. own := "ee00112233445566778899aabbccddeeff" + hex.EncodeToString([]byte("b.com"))
  88. in3 := `{"fakeTlsDomain":"a.com","clients":[{"email":"y","secret":"` + own + `"}]}`
  89. out3, changed3 := HealMtprotoClientSecrets(in3)
  90. if changed3 {
  91. t.Fatalf("a valid per-client secret must be left untouched, got %q", out3)
  92. }
  93. // No clients array — nothing to heal.
  94. if _, changed4 := HealMtprotoClientSecrets(`{"fakeTlsDomain":"a.com"}`); changed4 {
  95. t.Fatal("expected no change when there are no clients")
  96. }
  97. }