validator.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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) GetAEAD(userHash []byte) (*protocol.MemoryUser, bool, error) {
  48. v.RLock()
  49. defer v.RUnlock()
  50. var userHashFL [16]byte
  51. copy(userHashFL[:], userHash)
  52. userd, err := v.aeadDecoderHolder.Match(userHashFL)
  53. if err != nil {
  54. return nil, false, err
  55. }
  56. return userd.(*protocol.MemoryUser), true, err
  57. }
  58. func (v *TimedUserValidator) Remove(email string) bool {
  59. v.Lock()
  60. defer v.Unlock()
  61. email = strings.ToLower(email)
  62. idx := -1
  63. for i, u := range v.users {
  64. if strings.EqualFold(u.Email, email) {
  65. idx = i
  66. var cmdkeyfl [16]byte
  67. copy(cmdkeyfl[:], u.Account.(*MemoryAccount).ID.CmdKey())
  68. v.aeadDecoderHolder.RemoveUser(cmdkeyfl)
  69. break
  70. }
  71. }
  72. if idx == -1 {
  73. return false
  74. }
  75. ulen := len(v.users)
  76. v.users[idx] = v.users[ulen-1]
  77. v.users[ulen-1] = nil
  78. v.users = v.users[:ulen-1]
  79. return true
  80. }
  81. func (v *TimedUserValidator) GetBehaviorSeed() uint64 {
  82. v.Lock()
  83. defer v.Unlock()
  84. v.behaviorFused = true
  85. if v.behaviorSeed == 0 {
  86. v.behaviorSeed = dice.RollUint64()
  87. }
  88. return v.behaviorSeed
  89. }
  90. var ErrNotFound = errors.New("Not Found")
  91. var ErrTainted = errors.New("ErrTainted")