pull/787/head
Darien Raymond 2017-11-26 14:18:23 +01:00
parent 02ab3f3494
commit 6c0a1439c4
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
1 changed files with 31 additions and 29 deletions

View File

@ -244,10 +244,10 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buff
buffer := buf.New() buffer := buf.New()
ivLen := account.Cipher.IVSize() ivLen := account.Cipher.IVSize()
buffer.AppendSupplier(buf.ReadFullFrom(rand.Reader, ivLen)) common.Must(buffer.Reset(buf.ReadFullFrom(rand.Reader, ivLen)))
iv := buffer.Bytes() iv := buffer.Bytes()
payloadBuffer := buf.NewLocal(512) payloadBuffer := buf.New()
defer payloadBuffer.Release() defer payloadBuffer.Release()
switch request.Address.Family() { switch request.Address.Family() {
@ -264,14 +264,14 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buff
return nil, newError("unsupported address type: ", request.Address.Family()).AtError() return nil, newError("unsupported address type: ", request.Address.Family()).AtError()
} }
payloadBuffer.AppendSupplier(serial.WriteUint16(uint16(request.Port))) common.Must(payloadBuffer.AppendSupplier(serial.WriteUint16(uint16(request.Port))))
payloadBuffer.Append(payload) payloadBuffer.Append(payload)
if request.Option.Has(RequestOptionOneTimeAuth) { if !account.Cipher.IsAEAD() && request.Option.Has(RequestOptionOneTimeAuth) {
authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv)) authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
payloadBuffer.SetByte(0, payloadBuffer.Byte(0)|0x10) payloadBuffer.SetByte(0, payloadBuffer.Byte(0)|0x10)
payloadBuffer.AppendSupplier(authenticator.Authenticate(payloadBuffer.Bytes())) common.Must(payloadBuffer.AppendSupplier(authenticator.Authenticate(payloadBuffer.Bytes())))
} }
w, err := account.Cipher.NewEncryptionWriter(account.Key, iv, buffer) w, err := account.Cipher.NewEncryptionWriter(account.Key, iv, buffer)
@ -293,7 +293,8 @@ func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.Reques
account := rawAccount.(*ShadowsocksAccount) account := rawAccount.(*ShadowsocksAccount)
ivLen := account.Cipher.IVSize() ivLen := account.Cipher.IVSize()
iv := payload.BytesTo(ivLen) iv := make([]byte, ivLen)
copy(iv, payload.BytesTo(ivLen))
payload.SliceFrom(ivLen) payload.SliceFrom(ivLen)
r, err := account.Cipher.NewDecryptionReader(account.Key, iv, payload) r, err := account.Cipher.NewDecryptionReader(account.Key, iv, payload)
@ -315,34 +316,35 @@ func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.Reques
Command: protocol.RequestCommandUDP, Command: protocol.RequestCommandUDP,
} }
addrType := (payload.Byte(0) & 0x0F) if !account.Cipher.IsAEAD() {
if (payload.Byte(0) & 0x10) == 0x10 { if (payload.Byte(0) & 0x10) == 0x10 {
request.Option |= RequestOptionOneTimeAuth request.Option |= RequestOptionOneTimeAuth
}
if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled {
return nil, nil, newError("rejecting packet with OTA enabled, while server disables OTA").AtWarning()
}
if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled {
return nil, nil, newError("rejecting packet with OTA disabled, while server enables OTA").AtWarning()
}
if request.Option.Has(RequestOptionOneTimeAuth) {
payloadLen := payload.Len() - AuthSize
authBytes := payload.BytesFrom(payloadLen)
actualAuth := make([]byte, AuthSize)
authenticator.Authenticate(payload.BytesTo(payloadLen))(actualAuth)
if !bytes.Equal(actualAuth, authBytes) {
return nil, nil, newError("invalid OTA")
} }
payload.Slice(0, payloadLen) if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled {
return nil, nil, newError("rejecting packet with OTA enabled, while server disables OTA").AtWarning()
}
if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled {
return nil, nil, newError("rejecting packet with OTA disabled, while server enables OTA").AtWarning()
}
if request.Option.Has(RequestOptionOneTimeAuth) {
payloadLen := payload.Len() - AuthSize
authBytes := payload.BytesFrom(payloadLen)
actualAuth := make([]byte, AuthSize)
authenticator.Authenticate(payload.BytesTo(payloadLen))(actualAuth)
if !bytes.Equal(actualAuth, authBytes) {
return nil, nil, newError("invalid OTA")
}
payload.Slice(0, payloadLen)
}
} }
addrType := (payload.Byte(0) & 0x0F)
payload.SliceFrom(1) payload.SliceFrom(1)
switch addrType { switch addrType {
case AddrTypeIPv4: case AddrTypeIPv4:
request.Address = net.IPAddress(payload.BytesTo(4)) request.Address = net.IPAddress(payload.BytesTo(4))