From 830a2f478eb137afc103d07245b83f33e4c79f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 19 Jun 2022 20:28:22 +0800 Subject: [PATCH] Fix EIH protocol (break change) --- go.mod | 2 +- go.sum | 4 ++-- shadowaead_2022/protocol.go | 12 ++++++---- shadowaead_2022/relay.go | 39 ++++++++++++++++++-------------- shadowaead_2022/service.go | 9 ++++---- shadowaead_2022/service_multi.go | 11 ++++++++- 6 files changed, 47 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index acf3d69..11aed0e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/sagernet/sing-shadowsocks go 1.18 require ( - github.com/sagernet/sing v0.0.0-20220617062129-c6eb392ecb43 + github.com/sagernet/sing v0.0.0-20220619130320-8793fe5e067d golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e lukechampine.com/blake3 v1.1.7 ) diff --git a/go.sum b/go.sum index e4d7bdf..fdc948c 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/sagernet/sing v0.0.0-20220617062129-c6eb392ecb43 h1:fgG3GGs1pi72+5WWL0WIy+fQY6E1dBkGkH0UQ3zw+DI= -github.com/sagernet/sing v0.0.0-20220617062129-c6eb392ecb43/go.mod h1:I67R/q5f67xDExL2kL3RLIP7kGJBOPkYXkpRAykgC+E= +github.com/sagernet/sing v0.0.0-20220619130320-8793fe5e067d h1:zr8y4wmNIxv6Kkvgqysx8Piy82ATAThEj1jaEf23YQs= +github.com/sagernet/sing v0.0.0-20220619130320-8793fe5e067d/go.mod h1:I67R/q5f67xDExL2kL3RLIP7kGJBOPkYXkpRAykgC+E= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= diff --git a/shadowaead_2022/protocol.go b/shadowaead_2022/protocol.go index 700228a..f1ebe53 100644 --- a/shadowaead_2022/protocol.go +++ b/shadowaead_2022/protocol.go @@ -128,7 +128,8 @@ func New(method string, pskList [][]byte, options ...MethodOption) (shadowsocks. var err error switch method { case "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm": - m.udpBlockCipher, err = aes.NewCipher(pskList[0]) + m.udpBlockEncryptCipher, err = aes.NewCipher(pskList[0]) + m.udpBlockDecryptCipher, err = aes.NewCipher(pskList[len(pskList)-1]) case "2022-blake3-chacha20-poly1305": m.udpCipher, err = chacha20poly1305.NewX(pskList[0]) } @@ -173,7 +174,8 @@ type Method struct { constructor func(key []byte) (cipher.AEAD, error) blockConstructor func(key []byte) (cipher.Block, error) udpCipher cipher.AEAD - udpBlockCipher cipher.Block + udpBlockEncryptCipher cipher.Block + udpBlockDecryptCipher cipher.Block pskList [][]byte pskHash []byte replayFilter replay.Filter @@ -555,7 +557,7 @@ func (c *clientPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksad packetHeader := buffer.To(aes.BlockSize) c.session.cipher.Seal(buffer.Index(dataIndex), packetHeader[4:16], buffer.From(dataIndex), nil) buffer.Extend(shadowaead.Overhead) - c.udpBlockCipher.Encrypt(packetHeader, packetHeader) + c.udpBlockEncryptCipher.Encrypt(packetHeader, packetHeader) } return common.Error(c.Write(buffer.Bytes())) } @@ -577,7 +579,7 @@ func (c *clientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { buffer.Truncate(buffer.Len() - shadowaead.Overhead) } else { packetHeader = buffer.To(aes.BlockSize) - c.udpBlockCipher.Decrypt(packetHeader, packetHeader) + c.udpBlockDecryptCipher.Decrypt(packetHeader, packetHeader) } var sessionId, packetId uint64 @@ -776,7 +778,7 @@ func (c *clientPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { packetHeader := buffer.To(aes.BlockSize) c.session.cipher.Seal(buffer.Index(dataIndex), packetHeader[4:16], buffer.From(dataIndex), nil) buffer.Extend(shadowaead.Overhead) - c.udpBlockCipher.Encrypt(packetHeader, packetHeader) + c.udpBlockEncryptCipher.Encrypt(packetHeader, packetHeader) } err = common.Error(c.Write(buffer.Bytes())) if err != nil { diff --git a/shadowaead_2022/relay.go b/shadowaead_2022/relay.go index dbf4b81..2547eaf 100644 --- a/shadowaead_2022/relay.go +++ b/shadowaead_2022/relay.go @@ -21,7 +21,7 @@ import ( "lukechampine.com/blake3" ) -type Relay[U comparable] struct { +type RelayService[U comparable] struct { name string keySaltLength int handler shadowsocks.Handler @@ -37,7 +37,7 @@ type Relay[U comparable] struct { udpNat *udpnat.Service[uint64] } -func (s *Relay[U]) UpdateUsers(userList []U, keyList [][]byte, destinationList []M.Socksaddr) error { +func (s *RelayService[U]) UpdateUsers(userList []U, keyList [][]byte, destinationList []M.Socksaddr) error { uPSKHash := make(map[[aes.BlockSize]byte]U) uDestination := make(map[U]M.Socksaddr) uCipher := make(map[U]cipher.Block) @@ -69,7 +69,7 @@ func (s *Relay[U]) UpdateUsers(userList []U, keyList [][]byte, destinationList [ return nil } -func (s *Relay[U]) UpdateUsersWithPasswords(userList []U, passwordList []string, destinationList []M.Socksaddr) error { +func (s *RelayService[U]) UpdateUsersWithPasswords(userList []U, passwordList []string, destinationList []M.Socksaddr) error { keyList := make([][]byte, 0, len(passwordList)) for _, password := range passwordList { if password == "" { @@ -84,7 +84,7 @@ func (s *Relay[U]) UpdateUsersWithPasswords(userList []U, passwordList []string, return s.UpdateUsers(userList, keyList, destinationList) } -func NewRelayWithPassword[U comparable](method string, password string, udpTimeout int64, handler shadowsocks.Handler) (*Relay[U], error) { +func NewRelayServiceWithPassword[U comparable](method string, password string, udpTimeout int64, handler shadowsocks.Handler) (*RelayService[U], error) { if password == "" { return nil, ErrMissingPSK } @@ -92,11 +92,11 @@ func NewRelayWithPassword[U comparable](method string, password string, udpTimeo if err != nil { return nil, E.Cause(err, "decode psk") } - return NewRelay[U](method, iPSK, udpTimeout, handler) + return NewRelayService[U](method, iPSK, udpTimeout, handler) } -func NewRelay[U comparable](method string, psk []byte, udpTimeout int64, handler shadowsocks.Handler) (*Relay[U], error) { - s := &Relay[U]{ +func NewRelayService[U comparable](method string, psk []byte, udpTimeout int64, handler shadowsocks.Handler) (*RelayService[U], error) { + s := &RelayService[U]{ name: method, handler: handler, @@ -126,12 +126,13 @@ func NewRelay[U comparable](method string, psk []byte, udpTimeout int64, handler psk = Key(psk, s.keySaltLength) } } + s.iPSK = psk var err error s.udpBlockCipher, err = s.blockConstructor(psk) return s, err } -func (s *Relay[U]) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { +func (s *RelayService[U]) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { err := s.newConnection(ctx, conn, metadata) if err != nil { err = &shadowsocks.ServerConnError{Conn: conn, Source: metadata.Source, Cause: err} @@ -139,7 +140,7 @@ func (s *Relay[U]) NewConnection(ctx context.Context, conn net.Conn, metadata M. return err } -func (s *Relay[U]) newConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { +func (s *RelayService[U]) newConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { _requestHeader := buf.StackNew() defer common.KeepAlive(_requestHeader) requestHeader := common.Dup(_requestHeader) @@ -181,20 +182,20 @@ func (s *Relay[U]) newConnection(ctx context.Context, conn net.Conn, metadata M. copy(requestHeader.Range(aes.BlockSize, aes.BlockSize+s.keySaltLength), requestHeader.To(s.keySaltLength)) requestHeader.Advance(aes.BlockSize) - ctx = shadowsocks.UserContext[U]{ - ctx, - user, - } + var userCtx shadowsocks.UserContext[U] + userCtx.Context = ctx + userCtx.User = user + metadata.Protocol = "shadowsocks-relay" metadata.Destination = s.uDestination[user] conn = bufio.NewCachedConn(conn, requestHeader) - return s.handler.NewConnection(ctx, conn, metadata) + return s.handler.NewConnection(&userCtx, conn, metadata) } -func (s *Relay[U]) WriteIsThreadUnsafe() { +func (s *RelayService[U]) WriteIsThreadUnsafe() { } -func (s *Relay[U]) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata M.Metadata) error { +func (s *RelayService[U]) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata M.Metadata) error { err := s.newPacket(ctx, conn, buffer, metadata) if err != nil { err = &shadowsocks.ServerPacketError{Source: metadata.Source, Cause: err} @@ -202,7 +203,7 @@ func (s *Relay[U]) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf return err } -func (s *Relay[U]) newPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata M.Metadata) error { +func (s *RelayService[U]) newPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata M.Metadata) error { packetHeader := buffer.To(aes.BlockSize) s.udpBlockCipher.Decrypt(packetHeader, packetHeader) @@ -234,3 +235,7 @@ func (s *Relay[U]) newPacket(ctx context.Context, conn N.PacketConn, buffer *buf }) return nil } + +func (s *RelayService[U]) HandleError(err error) { + s.handler.HandleError(err) +} diff --git a/shadowaead_2022/service.go b/shadowaead_2022/service.go index 1ddddd3..655b521 100644 --- a/shadowaead_2022/service.go +++ b/shadowaead_2022/service.go @@ -461,7 +461,7 @@ process: } metadata.Destination = destination s.udpNat.NewPacket(ctx, sessionId, buffer, metadata, func(natConn N.PacketConn) N.PacketWriter { - return &serverPacketWriter{s, conn, natConn, session} + return &serverPacketWriter{s, conn, natConn, session, s.udpBlockCipher} }) return nil } @@ -472,9 +472,10 @@ func (s *Service) HandleError(err error) { type serverPacketWriter struct { *Service - source N.PacketConn - nat N.PacketConn - session *serverUDPSession + source N.PacketConn + nat N.PacketConn + session *serverUDPSession + udpBlockCipher cipher.Block } func (w *serverPacketWriter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { diff --git a/shadowaead_2022/service_multi.go b/shadowaead_2022/service_multi.go index 66f8c96..8339a00 100644 --- a/shadowaead_2022/service_multi.go +++ b/shadowaead_2022/service_multi.go @@ -3,6 +3,7 @@ package shadowaead_2022 import ( "context" "crypto/aes" + "crypto/cipher" "crypto/rand" "encoding/base64" "encoding/binary" @@ -27,6 +28,7 @@ type MultiService[U comparable] struct { uPSK map[U][]byte uPSKHash map[[aes.BlockSize]byte]U + uCipher map[U]cipher.Block } func NewMultiServiceWithPassword[U comparable](method string, password string, udpTimeout int64, handler shadowsocks.Handler) (*MultiService[U], error) { @@ -65,6 +67,7 @@ func NewMultiService[U comparable](method string, iPSK []byte, udpTimeout int64, func (s *MultiService[U]) UpdateUsers(userList []U, keyList [][]byte) error { uPSK := make(map[U][]byte) uPSKHash := make(map[[aes.BlockSize]byte]U) + uCipher := make(map[U]cipher.Block) for i, user := range userList { key := keyList[i] if len(key) < s.keySaltLength { @@ -79,10 +82,16 @@ func (s *MultiService[U]) UpdateUsers(userList []U, keyList [][]byte) error { uPSKHash[hash] = user uPSK[user] = key + var err error + uCipher[user], err = s.blockConstructor(key) + if err != nil { + return err + } } s.uPSK = uPSK s.uPSKHash = uPSKHash + s.uCipher = uCipher return nil } @@ -359,7 +368,7 @@ process: return &shadowsocks.UserContext[U]{ ctx, user, - }, &serverPacketWriter{s.Service, conn, natConn, session} + }, &serverPacketWriter{s.Service, conn, natConn, session, s.uCipher[user]} }) return nil }