1
0

validator.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package vmess
  2. import (
  3. "crypto/hmac"
  4. "crypto/sha256"
  5. "hash/crc64"
  6. "strings"
  7. "sync"
  8. "github.com/xtls/xray-core/common/dice"
  9. "github.com/xtls/xray-core/common/errors"
  10. "github.com/xtls/xray-core/common/protocol"
  11. "github.com/xtls/xray-core/proxy/vmess/aead"
  12. )
  13. // TimedUserValidator is a user Validator based on time.
  14. type TimedUserValidator struct {
  15. sync.RWMutex
  16. users []*protocol.MemoryUser
  17. behaviorSeed uint64
  18. behaviorFused bool
  19. aeadDecoderHolder *aead.AuthIDDecoderHolder
  20. }
  21. // NewTimedUserValidator creates a new TimedUserValidator.
  22. func NewTimedUserValidator() *TimedUserValidator {
  23. tuv := &TimedUserValidator{
  24. users: make([]*protocol.MemoryUser, 0, 16),
  25. aeadDecoderHolder: aead.NewAuthIDDecoderHolder(),
  26. }
  27. return tuv
  28. }
  29. func (v *TimedUserValidator) Add(u *protocol.MemoryUser) error {
  30. v.Lock()
  31. defer v.Unlock()
  32. v.users = append(v.users, u)
  33. account, ok := u.Account.(*MemoryAccount)
  34. if !ok {
  35. return errors.New("account type is incorrect")
  36. }
  37. if !v.behaviorFused {
  38. hashkdf := hmac.New(sha256.New, []byte("VMESSBSKDF"))
  39. hashkdf.Write(account.ID.Bytes())
  40. v.behaviorSeed = crc64.Update(v.behaviorSeed, crc64.MakeTable(crc64.ECMA), hashkdf.Sum(nil))
  41. }
  42. var cmdkeyfl [16]byte
  43. copy(cmdkeyfl[:], account.ID.CmdKey())
  44. v.aeadDecoderHolder.AddUser(cmdkeyfl, u)
  45. return nil
  46. }
  47. func (v *TimedUserValidator) GetUsers() []*protocol.MemoryUser {
  48. v.Lock()
  49. defer v.Unlock()
  50. dst := make([]*protocol.MemoryUser, len(v.users))
  51. copy(dst, v.users)
  52. return dst
  53. }
  54. func (v *TimedUserValidator) GetCount() int64 {
  55. v.Lock()
  56. defer v.Unlock()
  57. return int64(len(v.users))
  58. }
  59. func (v *TimedUserValidator) GetAEAD(userHash []byte) (*protocol.MemoryUser, bool, error) {
  60. v.RLock()
  61. defer v.RUnlock()
  62. var userHashFL [16]byte
  63. copy(userHashFL[:], userHash)
  64. userd, err := v.aeadDecoderHolder.Match(userHashFL)
  65. if err != nil {
  66. return nil, false, err
  67. }
  68. return userd.(*protocol.MemoryUser), true, nil
  69. }
  70. func (v *TimedUserValidator) Remove(email string) bool {
  71. v.Lock()
  72. defer v.Unlock()
  73. email = strings.ToLower(email)
  74. idx := -1
  75. for i, u := range v.users {
  76. if strings.EqualFold(u.Email, email) {
  77. idx = i
  78. var cmdkeyfl [16]byte
  79. copy(cmdkeyfl[:], u.Account.(*MemoryAccount).ID.CmdKey())
  80. v.aeadDecoderHolder.RemoveUser(cmdkeyfl)
  81. break
  82. }
  83. }
  84. if idx == -1 {
  85. return false
  86. }
  87. ulen := len(v.users)
  88. v.users[idx] = v.users[ulen-1]
  89. v.users[ulen-1] = nil
  90. v.users = v.users[:ulen-1]
  91. return true
  92. }
  93. func (v *TimedUserValidator) GetBehaviorSeed() uint64 {
  94. v.Lock()
  95. defer v.Unlock()
  96. v.behaviorFused = true
  97. if v.behaviorSeed == 0 {
  98. v.behaviorSeed = dice.RollUint64()
  99. }
  100. return v.behaviorSeed
  101. }
  102. var ErrNotFound = errors.New("Not Found")
  103. var ErrTainted = errors.New("ErrTainted")