api_wireguard_test.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package xray
  2. import (
  3. "encoding/base64"
  4. "encoding/hex"
  5. "testing"
  6. wireguard "github.com/xtls/xray-core/proxy/wireguard"
  7. "google.golang.org/protobuf/proto"
  8. )
  9. func b64Key(seed byte) string {
  10. raw := make([]byte, 32)
  11. for i := range raw {
  12. raw[i] = seed + byte(i)
  13. }
  14. return base64.StdEncoding.EncodeToString(raw)
  15. }
  16. func decodeWgAccount(t *testing.T, user map[string]any) *wireguard.PeerConfig {
  17. t.Helper()
  18. tm, err := buildUserAccount("wireguard", user)
  19. if err != nil {
  20. t.Fatalf("buildUserAccount: %v", err)
  21. }
  22. if tm == nil {
  23. t.Fatal("buildUserAccount returned nil account for wireguard")
  24. }
  25. var pc wireguard.PeerConfig
  26. if err := proto.Unmarshal(tm.Value, &pc); err != nil {
  27. t.Fatalf("unmarshal PeerConfig: %v", err)
  28. }
  29. return &pc
  30. }
  31. func assertHexKey(t *testing.T, label, value string) {
  32. t.Helper()
  33. if len(value) != 64 {
  34. t.Fatalf("%s = %q, want 64-char hex", label, value)
  35. }
  36. if raw, err := hex.DecodeString(value); err != nil || len(raw) != 32 {
  37. t.Fatalf("%s is not a 32-byte hex key: err=%v len=%d", label, err, len(raw))
  38. }
  39. }
  40. func TestBuildUserAccountWireGuardHexConversion(t *testing.T) {
  41. pub := b64Key(1)
  42. psk := b64Key(100)
  43. user := map[string]any{
  44. "email": "[email protected]",
  45. "publicKey": pub,
  46. "preSharedKey": psk,
  47. "allowedIPs": []any{"10.0.0.2/32", "fd00::2/128"},
  48. "keepAlive": "25",
  49. }
  50. pc := decodeWgAccount(t, user)
  51. assertHexKey(t, "PublicKey", pc.PublicKey)
  52. assertHexKey(t, "PreSharedKey", pc.PreSharedKey)
  53. wantPubHex, _ := hex.DecodeString(pc.PublicKey)
  54. gotPub, _ := base64.StdEncoding.DecodeString(pub)
  55. if string(wantPubHex) != string(gotPub) {
  56. t.Fatal("PublicKey hex does not match the base64 input bytes")
  57. }
  58. if len(pc.AllowedIps) != 2 || pc.AllowedIps[0] != "10.0.0.2/32" || pc.AllowedIps[1] != "fd00::2/128" {
  59. t.Fatalf("AllowedIps = %v, want [10.0.0.2/32 fd00::2/128]", pc.AllowedIps)
  60. }
  61. if pc.KeepAlive != "25" {
  62. t.Fatalf("KeepAlive = %q, want %q", pc.KeepAlive, "25")
  63. }
  64. }
  65. func TestBuildUserAccountWireGuardNoPSK(t *testing.T) {
  66. user := map[string]any{
  67. "email": "[email protected]",
  68. "publicKey": b64Key(2),
  69. "allowedIPs": []string{"10.0.0.3/32"},
  70. }
  71. pc := decodeWgAccount(t, user)
  72. if pc.PreSharedKey != "" {
  73. t.Fatalf("PreSharedKey = %q, want empty", pc.PreSharedKey)
  74. }
  75. if pc.KeepAlive != "" {
  76. t.Fatalf("KeepAlive = %q, want empty", pc.KeepAlive)
  77. }
  78. }
  79. func TestBuildUserAccountWireGuardMissingPublicKey(t *testing.T) {
  80. user := map[string]any{
  81. "email": "[email protected]",
  82. "allowedIPs": []any{"10.0.0.4/32"},
  83. }
  84. if _, err := buildUserAccount("wireguard", user); err == nil {
  85. t.Fatal("expected error for missing publicKey")
  86. }
  87. }
  88. func TestBuildUserAccountWireGuardMissingAllowedIPs(t *testing.T) {
  89. user := map[string]any{
  90. "email": "[email protected]",
  91. "publicKey": b64Key(3),
  92. }
  93. if _, err := buildUserAccount("wireguard", user); err == nil {
  94. t.Fatal("expected error for missing allowedIPs")
  95. }
  96. }
  97. func TestBuildUserAccountWireGuardBadKey(t *testing.T) {
  98. user := map[string]any{
  99. "email": "[email protected]",
  100. "publicKey": "not-a-valid-key",
  101. "allowedIPs": []any{"10.0.0.5/32"},
  102. }
  103. if _, err := buildUserAccount("wireguard", user); err == nil {
  104. t.Fatal("expected error for invalid publicKey")
  105. }
  106. }
  107. func TestBuildUserAccountUnknownProtocolReturnsNil(t *testing.T) {
  108. tm, err := buildUserAccount("mtproto", map[string]any{"email": "[email protected]"})
  109. if err != nil {
  110. t.Fatalf("unexpected error: %v", err)
  111. }
  112. if tm != nil {
  113. t.Fatal("expected nil account for unsupported protocol")
  114. }
  115. }