github.com/imannamdari/v2ray-core/v5@v5.0.5/proxy/shadowsocks/protocol.go (about) 1 package shadowsocks 2 3 import ( 4 "crypto/hmac" 5 "crypto/rand" 6 "crypto/sha256" 7 "hash/crc32" 8 "io" 9 mrand "math/rand" 10 gonet "net" 11 12 "github.com/imannamdari/v2ray-core/v5/common" 13 "github.com/imannamdari/v2ray-core/v5/common/buf" 14 "github.com/imannamdari/v2ray-core/v5/common/drain" 15 "github.com/imannamdari/v2ray-core/v5/common/net" 16 "github.com/imannamdari/v2ray-core/v5/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 // ReadTCPSession reads a Shadowsocks TCP session from the given reader, returns its header and remaining parts. 33 func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) { 34 account := user.Account.(*MemoryAccount) 35 36 hashkdf := hmac.New(sha256.New, []byte("SSBSKDF")) 37 hashkdf.Write(account.Key) 38 39 behaviorSeed := crc32.ChecksumIEEE(hashkdf.Sum(nil)) 40 41 drainer, err := drain.NewBehaviorSeedLimitedDrainer(int64(behaviorSeed), 16+38, 3266, 64) 42 if err != nil { 43 return nil, nil, newError("failed to initialize drainer").Base(err) 44 } 45 46 buffer := buf.New() 47 defer buffer.Release() 48 49 ivLen := account.Cipher.IVSize() 50 var iv []byte 51 if ivLen > 0 { 52 if _, err := buffer.ReadFullFrom(reader, ivLen); err != nil { 53 drainer.AcknowledgeReceive(int(buffer.Len())) 54 return nil, nil, drain.WithError(drainer, reader, newError("failed to read IV").Base(err)) 55 } 56 57 iv = append([]byte(nil), buffer.BytesTo(ivLen)...) 58 } 59 60 r, err := account.Cipher.NewDecryptionReader(account.Key, iv, reader) 61 if err != nil { 62 drainer.AcknowledgeReceive(int(buffer.Len())) 63 return nil, nil, drain.WithError(drainer, reader, newError("failed to initialize decoding stream").Base(err).AtError()) 64 } 65 br := &buf.BufferedReader{Reader: r} 66 67 request := &protocol.RequestHeader{ 68 Version: Version, 69 User: user, 70 Command: protocol.RequestCommandTCP, 71 } 72 73 drainer.AcknowledgeReceive(int(buffer.Len())) 74 buffer.Clear() 75 76 addr, port, err := addrParser.ReadAddressPort(buffer, br) 77 if err != nil { 78 drainer.AcknowledgeReceive(int(buffer.Len())) 79 return nil, nil, drain.WithError(drainer, reader, newError("failed to read address").Base(err)) 80 } 81 82 request.Address = addr 83 request.Port = port 84 85 if request.Address == nil { 86 drainer.AcknowledgeReceive(int(buffer.Len())) 87 return nil, nil, drain.WithError(drainer, reader, newError("invalid remote address.")) 88 } 89 90 if ivError := account.CheckIV(iv); ivError != nil { 91 drainer.AcknowledgeReceive(int(buffer.Len())) 92 return nil, nil, drain.WithError(drainer, reader, newError("failed iv check").Base(ivError)) 93 } 94 95 return request, br, nil 96 } 97 98 // WriteTCPRequest writes Shadowsocks request into the given writer, and returns a writer for body. 99 func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) { 100 user := request.User 101 account := user.Account.(*MemoryAccount) 102 103 var iv []byte 104 if account.Cipher.IVSize() > 0 { 105 iv = make([]byte, account.Cipher.IVSize()) 106 common.Must2(rand.Read(iv)) 107 if account.ReducedIVEntropy { 108 remapToPrintable(iv[:6]) 109 } 110 if ivError := account.CheckIV(iv); ivError != nil { 111 return nil, newError("failed to mark outgoing iv").Base(ivError) 112 } 113 if err := buf.WriteAllBytes(writer, iv); err != nil { 114 return nil, newError("failed to write IV") 115 } 116 } 117 118 w, err := account.Cipher.NewEncryptionWriter(account.Key, iv, writer) 119 if err != nil { 120 return nil, newError("failed to create encoding stream").Base(err).AtError() 121 } 122 123 header := buf.New() 124 125 if err := addrParser.WriteAddressPort(header, request.Address, request.Port); err != nil { 126 return nil, newError("failed to write address").Base(err) 127 } 128 129 if err := w.WriteMultiBuffer(buf.MultiBuffer{header}); err != nil { 130 return nil, newError("failed to write header").Base(err) 131 } 132 133 return w, nil 134 } 135 136 func ReadTCPResponse(user *protocol.MemoryUser, reader io.Reader) (buf.Reader, error) { 137 account := user.Account.(*MemoryAccount) 138 139 hashkdf := hmac.New(sha256.New, []byte("SSBSKDF")) 140 hashkdf.Write(account.Key) 141 142 behaviorSeed := crc32.ChecksumIEEE(hashkdf.Sum(nil)) 143 144 drainer, err := drain.NewBehaviorSeedLimitedDrainer(int64(behaviorSeed), 16+38, 3266, 64) 145 if err != nil { 146 return nil, newError("failed to initialize drainer").Base(err) 147 } 148 149 var iv []byte 150 if account.Cipher.IVSize() > 0 { 151 iv = make([]byte, account.Cipher.IVSize()) 152 if n, err := io.ReadFull(reader, iv); err != nil { 153 return nil, newError("failed to read IV").Base(err) 154 } else { // nolint: revive 155 drainer.AcknowledgeReceive(n) 156 } 157 } 158 159 if ivError := account.CheckIV(iv); ivError != nil { 160 return nil, drain.WithError(drainer, reader, newError("failed iv check").Base(ivError)) 161 } 162 163 return account.Cipher.NewDecryptionReader(account.Key, iv, reader) 164 } 165 166 func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) { 167 user := request.User 168 account := user.Account.(*MemoryAccount) 169 170 var iv []byte 171 if account.Cipher.IVSize() > 0 { 172 iv = make([]byte, account.Cipher.IVSize()) 173 common.Must2(rand.Read(iv)) 174 if ivError := account.CheckIV(iv); ivError != nil { 175 return nil, newError("failed to mark outgoing iv").Base(ivError) 176 } 177 if err := buf.WriteAllBytes(writer, iv); err != nil { 178 return nil, newError("failed to write IV.").Base(err) 179 } 180 } 181 182 return account.Cipher.NewEncryptionWriter(account.Key, iv, writer) 183 } 184 185 func EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buffer, error) { 186 user := request.User 187 account := user.Account.(*MemoryAccount) 188 189 buffer := buf.New() 190 ivLen := account.Cipher.IVSize() 191 if ivLen > 0 { 192 common.Must2(buffer.ReadFullFrom(rand.Reader, ivLen)) 193 } 194 195 if err := addrParser.WriteAddressPort(buffer, request.Address, request.Port); err != nil { 196 return nil, newError("failed to write address").Base(err) 197 } 198 199 buffer.Write(payload) 200 201 if err := account.Cipher.EncodePacket(account.Key, buffer); err != nil { 202 return nil, newError("failed to encrypt UDP payload").Base(err) 203 } 204 205 return buffer, nil 206 } 207 208 func DecodeUDPPacket(user *protocol.MemoryUser, payload *buf.Buffer) (*protocol.RequestHeader, *buf.Buffer, error) { 209 account := user.Account.(*MemoryAccount) 210 211 var iv []byte 212 if !account.Cipher.IsAEAD() && account.Cipher.IVSize() > 0 { 213 // Keep track of IV as it gets removed from payload in DecodePacket. 214 iv = make([]byte, account.Cipher.IVSize()) 215 copy(iv, payload.BytesTo(account.Cipher.IVSize())) 216 } 217 218 if err := account.Cipher.DecodePacket(account.Key, payload); err != nil { 219 return nil, nil, newError("failed to decrypt UDP payload").Base(err) 220 } 221 222 request := &protocol.RequestHeader{ 223 Version: Version, 224 User: user, 225 Command: protocol.RequestCommandUDP, 226 } 227 228 payload.SetByte(0, payload.Byte(0)&0x0F) 229 230 addr, port, err := addrParser.ReadAddressPort(nil, payload) 231 if err != nil { 232 return nil, nil, newError("failed to parse address").Base(err) 233 } 234 235 request.Address = addr 236 request.Port = port 237 238 return request, payload, nil 239 } 240 241 type UDPReader struct { 242 Reader io.Reader 243 User *protocol.MemoryUser 244 } 245 246 func (v *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) { 247 buffer := buf.New() 248 _, err := buffer.ReadFrom(v.Reader) 249 if err != nil { 250 buffer.Release() 251 return nil, err 252 } 253 _, payload, err := DecodeUDPPacket(v.User, buffer) 254 if err != nil { 255 buffer.Release() 256 return nil, err 257 } 258 return buf.MultiBuffer{payload}, nil 259 } 260 261 func (v *UDPReader) ReadFrom(p []byte) (n int, addr gonet.Addr, err error) { 262 buffer := buf.New() 263 _, err = buffer.ReadFrom(v.Reader) 264 if err != nil { 265 buffer.Release() 266 return 0, nil, err 267 } 268 vaddr, payload, err := DecodeUDPPacket(v.User, buffer) 269 if err != nil { 270 buffer.Release() 271 return 0, nil, err 272 } 273 n = copy(p, payload.Bytes()) 274 payload.Release() 275 return n, &gonet.UDPAddr{IP: vaddr.Address.IP(), Port: int(vaddr.Port)}, nil 276 } 277 278 type UDPWriter struct { 279 Writer io.Writer 280 Request *protocol.RequestHeader 281 } 282 283 // Write implements io.Writer. 284 func (w *UDPWriter) Write(payload []byte) (int, error) { 285 packet, err := EncodeUDPPacket(w.Request, payload) 286 if err != nil { 287 return 0, err 288 } 289 _, err = w.Writer.Write(packet.Bytes()) 290 packet.Release() 291 return len(payload), err 292 } 293 294 func (w *UDPWriter) WriteTo(payload []byte, addr gonet.Addr) (n int, err error) { 295 request := *w.Request 296 udpAddr := addr.(*gonet.UDPAddr) 297 request.Command = protocol.RequestCommandUDP 298 request.Address = net.IPAddress(udpAddr.IP) 299 request.Port = net.Port(udpAddr.Port) 300 packet, err := EncodeUDPPacket(&request, payload) 301 if err != nil { 302 return 0, err 303 } 304 _, err = w.Writer.Write(packet.Bytes()) 305 packet.Release() 306 return len(payload), err 307 } 308 309 func remapToPrintable(input []byte) { 310 const charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~\\\"" 311 seed := mrand.New(mrand.NewSource(int64(crc32.ChecksumIEEE(input)))) 312 for i := range input { 313 input[i] = charSet[seed.Intn(len(charSet))] 314 } 315 }