mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-30 01:08:33 +00:00
Use shadowsocket's bloomring for shadowsocket's replay protection (#764)
* use shadowsocket's bloomring for shadowsocket's replay protection * added shadowsockets iv check for tcp socket * Rename to shadowsockets iv check * shadowsocks iv check config file * iv check should proceed after decryption * use shadowsocket's bloomring for shadowsocket's replay protection * Chore: format code (#842) Co-authored-by: Shelikhoo <xiaokangwang@outlook.com> Co-authored-by: Loyalsoldier <10487845+Loyalsoldier@users.noreply.github.com>
This commit is contained in:
parent
0f0a424e8c
commit
45dc97e2b6
9 changed files with 138 additions and 53 deletions
|
@ -71,6 +71,7 @@ func ReadTCPSession(validator *Validator, reader io.Reader) (*protocol.RequestHe
|
|||
|
||||
var user *protocol.MemoryUser
|
||||
var ivLen int32
|
||||
var iv []byte
|
||||
var err error
|
||||
|
||||
count := validator.Count()
|
||||
|
@ -91,6 +92,9 @@ func ReadTCPSession(validator *Validator, reader io.Reader) (*protocol.RequestHe
|
|||
user, aead, _, ivLen, err = validator.Get(bs, protocol.RequestCommandTCP)
|
||||
|
||||
if user != nil {
|
||||
if ivLen > 0 {
|
||||
iv = append([]byte(nil), bs[:ivLen]...)
|
||||
}
|
||||
reader = &FullReader{reader, bs[ivLen:]}
|
||||
auth := &crypto.AEADAuthenticator{
|
||||
AEAD: aead,
|
||||
|
@ -108,7 +112,6 @@ func ReadTCPSession(validator *Validator, reader io.Reader) (*protocol.RequestHe
|
|||
user, ivLen = validator.GetOnlyUser()
|
||||
account := user.Account.(*MemoryAccount)
|
||||
hashkdf.Write(account.Key)
|
||||
var iv []byte
|
||||
if ivLen > 0 {
|
||||
if _, err := buffer.ReadFullFrom(reader, ivLen); err != nil {
|
||||
readSizeRemain -= int(buffer.Len())
|
||||
|
@ -154,6 +157,13 @@ func ReadTCPSession(validator *Validator, reader io.Reader) (*protocol.RequestHe
|
|||
return nil, nil, newError("invalid remote address.")
|
||||
}
|
||||
|
||||
account := user.Account.(*MemoryAccount)
|
||||
if ivError := account.CheckIV(iv); ivError != nil {
|
||||
readSizeRemain -= int(buffer.Len())
|
||||
DrainConnN(reader, readSizeRemain)
|
||||
return nil, nil, newError("failed iv check").Base(ivError)
|
||||
}
|
||||
|
||||
return request, br, nil
|
||||
}
|
||||
|
||||
|
@ -171,6 +181,9 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
|
|||
if account.Cipher.IVSize() > 0 {
|
||||
iv = make([]byte, account.Cipher.IVSize())
|
||||
common.Must2(rand.Read(iv))
|
||||
if ivError := account.CheckIV(iv); ivError != nil {
|
||||
return nil, newError("failed to mark outgoing iv").Base(ivError)
|
||||
}
|
||||
if err := buf.WriteAllBytes(writer, iv, nil); err != nil {
|
||||
return nil, newError("failed to write IV")
|
||||
}
|
||||
|
@ -205,6 +218,10 @@ func ReadTCPResponse(user *protocol.MemoryUser, reader io.Reader) (buf.Reader, e
|
|||
}
|
||||
}
|
||||
|
||||
if ivError := account.CheckIV(iv); ivError != nil {
|
||||
return nil, newError("failed iv check").Base(ivError)
|
||||
}
|
||||
|
||||
return account.Cipher.NewDecryptionReader(account.Key, iv, reader)
|
||||
}
|
||||
|
||||
|
@ -216,6 +233,9 @@ func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Wr
|
|||
if account.Cipher.IVSize() > 0 {
|
||||
iv = make([]byte, account.Cipher.IVSize())
|
||||
common.Must2(rand.Read(iv))
|
||||
if ivError := account.CheckIV(iv); ivError != nil {
|
||||
return nil, newError("failed to mark outgoing iv").Base(ivError)
|
||||
}
|
||||
if err := buf.WriteAllBytes(writer, iv, nil); err != nil {
|
||||
return nil, newError("failed to write IV.").Base(err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue