github.com/moqsien/xraycore@v1.8.5/proxy/shadowsocks/protocol.go (about) 1 package shadowsocks 2 3 import ( 4 "crypto/hmac" 5 "crypto/rand" 6 "crypto/sha256" 7 "errors" 8 "hash/crc32" 9 "io" 10 11 "github.com/moqsien/xraycore/common" 12 "github.com/moqsien/xraycore/common/buf" 13 "github.com/moqsien/xraycore/common/crypto" 14 "github.com/moqsien/xraycore/common/drain" 15 "github.com/moqsien/xraycore/common/net" 16 "github.com/moqsien/xraycore/common/protocol" 17 ) 18 19 const ( 20 Version = 1 21 ) 22 23 var addrParser = protocol.NewAddressParser( 24 protocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4), 25 protocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6), 26 protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain), 27 protocol.WithAddressTypeParser(func(b byte) byte { 28 return b & 0x0F 29 }), 30 ) 31 32 type FullReader struct { 33 reader io.Reader 34 buffer []byte 35 } 36 37 func (r *FullReader) Read(p []byte) (n int, err error) { 38 if r.buffer != nil { 39 n := copy(p, r.buffer) 40 if n == len(r.buffer) { 41 r.buffer = nil 42 } else { 43 r.buffer = r.buffer[n:] 44 } 45 if n == len(p) { 46 return n, nil 47 } else { 48 m, err := r.reader.Read(p[n:]) 49 return n + m, err 50 } 51 } 52 return r.reader.Read(p) 53 } 54 55 // ReadTCPSession reads a Shadowsocks TCP session from the given reader, returns its header and remaining parts. 56 func ReadTCPSession(validator *Validator, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) { 57 behaviorSeed := validator.GetBehaviorSeed() 58 drainer, errDrain := drain.NewBehaviorSeedLimitedDrainer(int64(behaviorSeed), 16+38, 3266, 64) 59 60 if errDrain != nil { 61 return nil, nil, newError("failed to initialize drainer").Base(errDrain) 62 } 63 64 var r buf.Reader 65 buffer := buf.New() 66 defer buffer.Release() 67 68 if _, err := buffer.ReadFullFrom(reader, 50); err != nil { 69 drainer.AcknowledgeReceive(int(buffer.Len())) 70 return nil, nil, drain.WithError(drainer, reader, newError("failed to read 50 bytes").Base(err)) 71 } 72 73 bs := buffer.Bytes() 74 user, aead, _, ivLen, err := validator.Get(bs, protocol.RequestCommandTCP) 75 76 switch err { 77 case ErrNotFound: 78 drainer.AcknowledgeReceive(int(buffer.Len())) 79 return nil, nil, drain.WithError(drainer, reader, newError("failed to match an user").Base(err)) 80 case ErrIVNotUnique: 81 drainer.AcknowledgeReceive(int(buffer.Len())) 82 return nil, nil, drain.WithError(drainer, reader, newError("failed iv check").Base(err)) 83 default: 84 reader = &FullReader{reader, bs[ivLen:]} 85 drainer.AcknowledgeReceive(int(ivLen)) 86 87 if aead != nil { 88 auth := &crypto.AEADAuthenticator{ 89 AEAD: aead, 90 NonceGenerator: crypto.GenerateAEADNonceWithSize(aead.NonceSize()), 91 } 92 r = crypto.NewAuthenticationReader(auth, &crypto.AEADChunkSizeParser{ 93 Auth: auth, 94 }, reader, protocol.TransferTypeStream, nil) 95 } else { 96 account := user.Account.(*MemoryAccount) 97 iv := append([]byte(nil), buffer.BytesTo(ivLen)...) 98 r, err = account.Cipher.NewDecryptionReader(account.Key, iv, reader) 99 if err != nil { 100 return nil, nil, drain.WithError(drainer, reader, newError("failed to initialize decoding stream").Base(err).AtError()) 101 } 102 } 103 } 104 105 br := &buf.BufferedReader{Reader: r} 106 107 request := &protocol.RequestHeader{ 108 Version: Version, 109 User: user, 110 Command: protocol.RequestCommandTCP, 111 } 112 113 buffer.Clear() 114 115 addr, port, err := addrParser.ReadAddressPort(buffer, br) 116 if err != nil { 117 drainer.AcknowledgeReceive(int(buffer.Len())) 118 return nil, nil, drain.WithError(drainer, reader, newError("failed to read address").Base(err)) 119 } 120 121 request.Address = addr 122 request.Port = port 123 124 if request.Address == nil { 125 drainer.AcknowledgeReceive(int(buffer.Len())) 126 return nil, nil, drain.WithError(drainer, reader, newError("invalid remote address.")) 127 } 128 129 return request, br, nil 130 } 131 132 // WriteTCPRequest writes Shadowsocks request into the given writer, and returns a writer for body. 133 func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) { 134 user := request.User 135 account := user.Account.(*MemoryAccount) 136 137 var iv []byte 138 if account.Cipher.IVSize() > 0 { 139 iv = make([]byte, account.Cipher.IVSize()) 140 common.Must2(rand.Read(iv)) 141 if ivError := account.CheckIV(iv); ivError != nil { 142 return nil, newError("failed to mark outgoing iv").Base(ivError) 143 } 144 if err := buf.WriteAllBytes(writer, iv, nil); err != nil { 145 return nil, newError("failed to write IV") 146 } 147 } 148 149 w, err := account.Cipher.NewEncryptionWriter(account.Key, iv, writer) 150 if err != nil { 151 return nil, newError("failed to create encoding stream").Base(err).AtError() 152 } 153 154 header := buf.New() 155 156 if err := addrParser.WriteAddressPort(header, request.Address, request.Port); err != nil { 157 return nil, newError("failed to write address").Base(err) 158 } 159 160 if err := w.WriteMultiBuffer(buf.MultiBuffer{header}); err != nil { 161 return nil, newError("failed to write header").Base(err) 162 } 163 164 return w, nil 165 } 166 167 func ReadTCPResponse(user *protocol.MemoryUser, reader io.Reader) (buf.Reader, error) { 168 account := user.Account.(*MemoryAccount) 169 170 hashkdf := hmac.New(sha256.New, []byte("SSBSKDF")) 171 hashkdf.Write(account.Key) 172 173 behaviorSeed := crc32.ChecksumIEEE(hashkdf.Sum(nil)) 174 175 drainer, err := drain.NewBehaviorSeedLimitedDrainer(int64(behaviorSeed), 16+38, 3266, 64) 176 if err != nil { 177 return nil, newError("failed to initialize drainer").Base(err) 178 } 179 180 var iv []byte 181 if account.Cipher.IVSize() > 0 { 182 iv = make([]byte, account.Cipher.IVSize()) 183 if n, err := io.ReadFull(reader, iv); err != nil { 184 return nil, newError("failed to read IV").Base(err) 185 } else { // nolint: golint 186 drainer.AcknowledgeReceive(n) 187 } 188 } 189 190 if ivError := account.CheckIV(iv); ivError != nil { 191 return nil, drain.WithError(drainer, reader, newError("failed iv check").Base(ivError)) 192 } 193 194 return account.Cipher.NewDecryptionReader(account.Key, iv, reader) 195 } 196 197 func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) { 198 user := request.User 199 account := user.Account.(*MemoryAccount) 200 201 var iv []byte 202 if account.Cipher.IVSize() > 0 { 203 iv = make([]byte, account.Cipher.IVSize()) 204 common.Must2(rand.Read(iv)) 205 if ivError := account.CheckIV(iv); ivError != nil { 206 return nil, newError("failed to mark outgoing iv").Base(ivError) 207 } 208 if err := buf.WriteAllBytes(writer, iv, nil); err != nil { 209 return nil, newError("failed to write IV.").Base(err) 210 } 211 } 212 213 return account.Cipher.NewEncryptionWriter(account.Key, iv, writer) 214 } 215 216 func EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buffer, error) { 217 user := request.User 218 account := user.Account.(*MemoryAccount) 219 220 buffer := buf.New() 221 ivLen := account.Cipher.IVSize() 222 if ivLen > 0 { 223 common.Must2(buffer.ReadFullFrom(rand.Reader, ivLen)) 224 } 225 226 if err := addrParser.WriteAddressPort(buffer, request.Address, request.Port); err != nil { 227 return nil, newError("failed to write address").Base(err) 228 } 229 230 buffer.Write(payload) 231 232 if err := account.Cipher.EncodePacket(account.Key, buffer); err != nil { 233 return nil, newError("failed to encrypt UDP payload").Base(err) 234 } 235 236 return buffer, nil 237 } 238 239 func DecodeUDPPacket(validator *Validator, payload *buf.Buffer) (*protocol.RequestHeader, *buf.Buffer, error) { 240 rawPayload := payload.Bytes() 241 user, _, d, _, err := validator.Get(rawPayload, protocol.RequestCommandUDP) 242 243 if errors.Is(err, ErrIVNotUnique) { 244 return nil, nil, newError("failed iv check").Base(err) 245 } 246 247 if errors.Is(err, ErrNotFound) { 248 return nil, nil, newError("failed to match an user").Base(err) 249 } 250 251 if err != nil { 252 return nil, nil, newError("unexpected error").Base(err) 253 } 254 255 account, ok := user.Account.(*MemoryAccount) 256 if !ok { 257 return nil, nil, newError("expected MemoryAccount returned from validator") 258 } 259 260 if account.Cipher.IsAEAD() { 261 payload.Clear() 262 payload.Write(d) 263 } else { 264 if account.Cipher.IVSize() > 0 { 265 iv := make([]byte, account.Cipher.IVSize()) 266 copy(iv, payload.BytesTo(account.Cipher.IVSize())) 267 } 268 if err = account.Cipher.DecodePacket(account.Key, payload); err != nil { 269 return nil, nil, newError("failed to decrypt UDP payload").Base(err) 270 } 271 } 272 273 payload.SetByte(0, payload.Byte(0)&0x0F) 274 275 addr, port, err := addrParser.ReadAddressPort(nil, payload) 276 if err != nil { 277 return nil, nil, newError("failed to parse address").Base(err) 278 } 279 280 request := &protocol.RequestHeader{ 281 Version: Version, 282 User: user, 283 Command: protocol.RequestCommandUDP, 284 Address: addr, 285 Port: port, 286 } 287 288 return request, payload, nil 289 } 290 291 type UDPReader struct { 292 Reader io.Reader 293 User *protocol.MemoryUser 294 } 295 296 func (v *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) { 297 buffer := buf.New() 298 _, err := buffer.ReadFrom(v.Reader) 299 if err != nil { 300 buffer.Release() 301 return nil, err 302 } 303 validator := new(Validator) 304 validator.Add(v.User) 305 306 u, payload, err := DecodeUDPPacket(validator, buffer) 307 if err != nil { 308 buffer.Release() 309 return nil, err 310 } 311 dest := u.Destination() 312 payload.UDP = &dest 313 return buf.MultiBuffer{payload}, nil 314 } 315 316 type UDPWriter struct { 317 Writer io.Writer 318 Request *protocol.RequestHeader 319 } 320 321 func (w *UDPWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { 322 for { 323 mb2, b := buf.SplitFirst(mb) 324 mb = mb2 325 if b == nil { 326 break 327 } 328 request := w.Request 329 if b.UDP != nil { 330 request = &protocol.RequestHeader{ 331 User: w.Request.User, 332 Address: b.UDP.Address, 333 Port: b.UDP.Port, 334 } 335 } 336 packet, err := EncodeUDPPacket(request, b.Bytes()) 337 b.Release() 338 if err != nil { 339 buf.ReleaseMulti(mb) 340 return err 341 } 342 _, err = w.Writer.Write(packet.Bytes()) 343 packet.Release() 344 if err != nil { 345 buf.ReleaseMulti(mb) 346 return err 347 } 348 } 349 return nil 350 }