validator.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package shadowsocks
  2. import (
  3. "crypto/cipher"
  4. "crypto/hmac"
  5. "crypto/sha256"
  6. "hash/crc64"
  7. "strings"
  8. "sync"
  9. "github.com/xtls/xray-core/common/dice"
  10. "github.com/xtls/xray-core/common/errors"
  11. "github.com/xtls/xray-core/common/protocol"
  12. )
  13. // Validator stores valid Shadowsocks users.
  14. type Validator struct {
  15. sync.RWMutex
  16. users []*protocol.MemoryUser
  17. behaviorSeed uint64
  18. behaviorFused bool
  19. }
  20. var ErrNotFound = errors.New("Not Found")
  21. // Add a Shadowsocks user.
  22. func (v *Validator) Add(u *protocol.MemoryUser) error {
  23. v.Lock()
  24. defer v.Unlock()
  25. account := u.Account.(*MemoryAccount)
  26. if !account.Cipher.IsAEAD() && len(v.users) > 0 {
  27. return errors.New("The cipher is not support Single-port Multi-user")
  28. }
  29. v.users = append(v.users, u)
  30. if !v.behaviorFused {
  31. hashkdf := hmac.New(sha256.New, []byte("SSBSKDF"))
  32. hashkdf.Write(account.Key)
  33. v.behaviorSeed = crc64.Update(v.behaviorSeed, crc64.MakeTable(crc64.ECMA), hashkdf.Sum(nil))
  34. }
  35. return nil
  36. }
  37. // Del a Shadowsocks user with a non-empty Email.
  38. func (v *Validator) Del(email string) error {
  39. if email == "" {
  40. return errors.New("Email must not be empty.")
  41. }
  42. v.Lock()
  43. defer v.Unlock()
  44. email = strings.ToLower(email)
  45. idx := -1
  46. for i, u := range v.users {
  47. if strings.EqualFold(u.Email, email) {
  48. idx = i
  49. break
  50. }
  51. }
  52. if idx == -1 {
  53. return errors.New("User ", email, " not found.")
  54. }
  55. ulen := len(v.users)
  56. v.users[idx] = v.users[ulen-1]
  57. v.users[ulen-1] = nil
  58. v.users = v.users[:ulen-1]
  59. return nil
  60. }
  61. // GetByEmail Get a Shadowsocks user with a non-empty Email.
  62. func (v *Validator) GetByEmail(email string) *protocol.MemoryUser {
  63. if email == "" {
  64. return nil
  65. }
  66. v.Lock()
  67. defer v.Unlock()
  68. email = strings.ToLower(email)
  69. for _, u := range v.users {
  70. if strings.EqualFold(u.Email, email) {
  71. return u
  72. }
  73. }
  74. return nil
  75. }
  76. // GetAll get all users
  77. func (v *Validator) GetAll() []*protocol.MemoryUser {
  78. v.Lock()
  79. defer v.Unlock()
  80. dst := make([]*protocol.MemoryUser, len(v.users))
  81. copy(dst, v.users)
  82. return dst
  83. }
  84. // GetCount get users count
  85. func (v *Validator) GetCount() int64 {
  86. v.Lock()
  87. defer v.Unlock()
  88. return int64(len(v.users))
  89. }
  90. // Get a Shadowsocks user.
  91. func (v *Validator) Get(bs []byte, command protocol.RequestCommand) (u *protocol.MemoryUser, aead cipher.AEAD, ret []byte, ivLen int32, err error) {
  92. v.RLock()
  93. defer v.RUnlock()
  94. for _, user := range v.users {
  95. if account := user.Account.(*MemoryAccount); account.Cipher.IsAEAD() {
  96. // AEAD payload decoding requires the payload to be over 32 bytes
  97. if len(bs) < 32 {
  98. continue
  99. }
  100. aeadCipher := account.Cipher.(*AEADCipher)
  101. ivLen = aeadCipher.IVSize()
  102. iv := bs[:ivLen]
  103. subkey := make([]byte, 32)
  104. subkey = subkey[:aeadCipher.KeyBytes]
  105. hkdfSHA1(account.Key, iv, subkey)
  106. aead = aeadCipher.AEADAuthCreator(subkey)
  107. var matchErr error
  108. switch command {
  109. case protocol.RequestCommandTCP:
  110. data := make([]byte, 4+aead.NonceSize())
  111. ret, matchErr = aead.Open(data[:0], data[4:], bs[ivLen:ivLen+18], nil)
  112. case protocol.RequestCommandUDP:
  113. data := make([]byte, 8192)
  114. ret, matchErr = aead.Open(data[:0], data[8192-aead.NonceSize():8192], bs[ivLen:], nil)
  115. }
  116. if matchErr == nil {
  117. u = user
  118. err = account.CheckIV(iv)
  119. return
  120. }
  121. } else {
  122. u = user
  123. ivLen = user.Account.(*MemoryAccount).Cipher.IVSize()
  124. // err = user.Account.(*MemoryAccount).CheckIV(bs[:ivLen]) // The IV size of None Cipher is 0.
  125. return
  126. }
  127. }
  128. return nil, nil, nil, 0, ErrNotFound
  129. }
  130. func (v *Validator) GetBehaviorSeed() uint64 {
  131. v.Lock()
  132. defer v.Unlock()
  133. v.behaviorFused = true
  134. if v.behaviorSeed == 0 {
  135. v.behaviorSeed = dice.RollUint64()
  136. }
  137. return v.behaviorSeed
  138. }