1
0

auth_test.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package tuic
  2. import (
  3. "crypto/rand"
  4. "crypto/tls"
  5. "errors"
  6. "net"
  7. "sync"
  8. "testing"
  9. "github.com/google/uuid"
  10. )
  11. func TestUserRegistryBasic(t *testing.T) {
  12. reg := NewUserRegistry()
  13. testUUID := uuid.New()
  14. reg.SetUsers([]TuicClientSettings{
  15. {
  16. UUID: testUUID.String(),
  17. Password: "supersecretpassword",
  18. Email: "[email protected]",
  19. },
  20. })
  21. var fakeUUID [16]byte
  22. copy(fakeUUID[:], testUUID[:])
  23. var unknownUUID [16]byte
  24. _, _ = rand.Read(unknownUUID[:])
  25. _, err := reg.Authenticate(&tls.ConnectionState{}, unknownUUID, [32]byte{})
  26. if !errors.Is(err, ErrUserNotFound) {
  27. t.Fatalf("expected ErrUserNotFound, got %v", err)
  28. }
  29. }
  30. func TestUserRegistryCredentialUpdatesKeepOldCounters(t *testing.T) {
  31. reg := NewUserRegistry()
  32. u1 := uuid.New().String()
  33. u2 := uuid.New().String()
  34. reg.SetUsers([]TuicClientSettings{
  35. {UUID: u1, Password: "pass1", Email: "[email protected]"},
  36. {UUID: u2, Password: "pass2", Email: "[email protected]"},
  37. })
  38. reg.AddTestTraffic("[email protected]", 100, 200)
  39. parsedU1, _ := uuid.Parse(u1)
  40. user1Before := reg.users[parsedU1]
  41. if user1Before == nil {
  42. t.Fatalf("expected user1 in registry")
  43. }
  44. revoked := reg.SetUsers([]TuicClientSettings{
  45. {UUID: u1, Password: "newpassword", Email: "[email protected]"},
  46. {UUID: u2, Password: "pass2", Email: "[email protected]"},
  47. })
  48. if len(revoked) != 1 || revoked[0] != user1Before {
  49. t.Fatalf("expected changed user snapshot to be retired, got %+v", revoked)
  50. }
  51. user1After := reg.users[parsedU1]
  52. if user1Before == user1After {
  53. t.Fatal("expected immutable user snapshot to be replaced")
  54. }
  55. if user1After.Password != "newpassword" || user1After.Email != "[email protected]" {
  56. t.Fatalf("expected updated password and email, got %s, %s", user1After.Password, user1After.Email)
  57. }
  58. deltas := reg.CollectTrafficDeltas()
  59. if len(deltas) != 1 || deltas[0].Email != "[email protected]" || deltas[0].Up != 100 || deltas[0].Down != 200 {
  60. t.Fatalf("expected preserved traffic deltas, got %+v", deltas)
  61. }
  62. }
  63. func TestUserRegistryRevocation(t *testing.T) {
  64. reg := NewUserRegistry()
  65. u1 := uuid.New().String()
  66. u2 := uuid.New().String()
  67. reg.SetUsers([]TuicClientSettings{
  68. {UUID: u1, Password: "pass1", Email: "[email protected]"},
  69. {UUID: u2, Password: "pass2", Email: "[email protected]"},
  70. })
  71. // Remove u1, keep only u2
  72. revoked := reg.SetUsers([]TuicClientSettings{
  73. {UUID: u2, Password: "pass2", Email: "[email protected]"},
  74. })
  75. if len(revoked) != 1 || revoked[0].Email != "[email protected]" {
  76. t.Fatalf("expected u1 revoked, got %+v", revoked)
  77. }
  78. parsedU1, _ := uuid.Parse(u1)
  79. if _, exists := reg.users[parsedU1]; exists {
  80. t.Fatalf("expected u1 removed from registry")
  81. }
  82. }
  83. func TestUserRegistryRetainsRevokedTrafficUntilSessionsFinish(t *testing.T) {
  84. reg := NewUserRegistry()
  85. uuidStr := uuid.New().String()
  86. reg.SetUsers([]TuicClientSettings{{UUID: uuidStr, Password: "p", Email: "[email protected]"}})
  87. parsed, _ := uuid.Parse(uuidStr)
  88. user := reg.users[parsed]
  89. user.sessions.Store(1)
  90. user.Traffic.BytesUp.Store(11)
  91. user.Traffic.BytesDown.Store(22)
  92. reg.SetUsers(nil)
  93. if got := reg.CollectTrafficDeltas(); len(got) != 1 || got[0].Email != user.Email || got[0].Up != 11 || got[0].Down != 22 {
  94. t.Fatalf("revoked traffic delta = %+v", got)
  95. }
  96. user.Traffic.BytesUp.Add(3)
  97. if got := reg.CollectTrafficDeltas(); len(got) != 1 || got[0].Up != 3 {
  98. t.Fatalf("final active-session delta = %+v", got)
  99. }
  100. reg.sessionEnded(user)
  101. if got := reg.CollectTrafficDeltas(); len(got) != 0 {
  102. t.Fatalf("empty retired user produced another delta: %+v", got)
  103. }
  104. if len(reg.retired) != 0 {
  105. t.Fatalf("finished user remained retired: %+v", reg.retired)
  106. }
  107. }
  108. func TestUserRegistryConcurrentCredentialUpdatesAndAuthentication(t *testing.T) {
  109. certPEM, keyPEM := generateTestCert(t)
  110. certificate, err := tls.X509KeyPair(certPEM, keyPEM)
  111. if err != nil {
  112. t.Fatalf("tls.X509KeyPair: %v", err)
  113. }
  114. clientRaw, serverRaw := net.Pipe()
  115. clientConn := tls.Client(clientRaw, &tls.Config{InsecureSkipVerify: true, MinVersion: tls.VersionTLS13})
  116. serverConn := tls.Server(serverRaw, &tls.Config{Certificates: []tls.Certificate{certificate}, MinVersion: tls.VersionTLS13})
  117. serverHandshake := make(chan error, 1)
  118. go func() { serverHandshake <- serverConn.Handshake() }()
  119. if err := clientConn.Handshake(); err != nil {
  120. t.Fatalf("client TLS handshake: %v", err)
  121. }
  122. if err := <-serverHandshake; err != nil {
  123. t.Fatalf("server TLS handshake: %v", err)
  124. }
  125. t.Cleanup(func() {
  126. _ = clientConn.Close()
  127. _ = serverConn.Close()
  128. })
  129. state := clientConn.ConnectionState()
  130. if !state.HandshakeComplete {
  131. t.Fatal("TLS handshake did not complete")
  132. }
  133. reg := NewUserRegistry()
  134. uuidStr := uuid.New().String()
  135. parsed, _ := uuid.Parse(uuidStr)
  136. reg.SetUsers([]TuicClientSettings{{UUID: uuidStr, Password: "initial", Email: "[email protected]"}})
  137. var wg sync.WaitGroup
  138. wg.Add(2)
  139. go func() {
  140. defer wg.Done()
  141. for i := range 1000 {
  142. password := "a"
  143. if i%2 == 0 {
  144. password = "b"
  145. }
  146. reg.SetUsers([]TuicClientSettings{{UUID: uuidStr, Password: password, Email: "[email protected]"}})
  147. }
  148. }()
  149. go func() {
  150. defer wg.Done()
  151. for range 1000 {
  152. _, _ = reg.Authenticate(&state, parsed, [32]byte{})
  153. }
  154. }()
  155. wg.Wait()
  156. }