func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) { if len(packet) < 5 { return nil, errors.New("Socks|UDP: Insufficient length of packet.") } request := new(Socks5UDPRequest) // packet[0] and packet[1] are reserved request.Fragment = packet[2] addrType := packet[3] var dataBegin int switch addrType { case AddrTypeIPv4: if len(packet) < 10 { return nil, errors.New("Socks|UDP: Insufficient length of packet.") } ip := packet[4:8] request.Port = v2net.PortFromBytes(packet[8:10]) request.Address = v2net.IPAddress(ip) dataBegin = 10 case AddrTypeIPv6: if len(packet) < 22 { return nil, errors.New("Socks|UDP: Insufficient length of packet.") } ip := packet[4:20] request.Port = v2net.PortFromBytes(packet[20:22]) request.Address = v2net.IPAddress(ip) dataBegin = 22 case AddrTypeDomain: domainLength := int(packet[4]) if len(packet) < 5+domainLength+2 { return nil, errors.New("Socks|UDP: Insufficient length of packet.") } domain := string(packet[5 : 5+domainLength]) request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2]) request.Address = v2net.ParseAddress(domain) dataBegin = 5 + domainLength + 2 default: return nil, errors.Format("Socks|UDP: Unknown address type %d", addrType) } if len(packet) > dataBegin { b := buf.NewSmall() b.Append(packet[dataBegin:]) request.Data = b } return request, nil }
func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) { if len(packet) < 5 { return nil, transport.ErrCorruptedPacket } request := new(Socks5UDPRequest) // packet[0] and packet[1] are reserved request.Fragment = packet[2] addrType := packet[3] var dataBegin int switch addrType { case AddrTypeIPv4: if len(packet) < 10 { return nil, transport.ErrCorruptedPacket } ip := packet[4:8] request.Port = v2net.PortFromBytes(packet[8:10]) request.Address = v2net.IPAddress(ip) dataBegin = 10 case AddrTypeIPv6: if len(packet) < 22 { return nil, transport.ErrCorruptedPacket } ip := packet[4:20] request.Port = v2net.PortFromBytes(packet[20:22]) request.Address = v2net.IPAddress(ip) dataBegin = 22 case AddrTypeDomain: domainLength := int(packet[4]) if len(packet) < 5+domainLength+2 { return nil, transport.ErrCorruptedPacket } domain := string(packet[5 : 5+domainLength]) request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2]) request.Address = v2net.ParseAddress(domain) dataBegin = 5 + domainLength + 2 default: log.Warning("Unknown address type ", addrType) return nil, ErrorUnknownAddressType } if len(packet) > dataBegin { request.Data = alloc.NewBuffer().Clear().Append(packet[dataBegin:]) } return request, nil }
func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) { if len(packet) < 5 { return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.") } request := &protocol.RequestHeader{ Version: socks5Version, Command: protocol.RequestCommandUDP, } // packet[0] and packet[1] are reserved if packet[2] != 0 /* fragments */ { return nil, nil, errors.New("Socks|UDP: Fragmented payload.") } addrType := packet[3] var dataBegin int switch addrType { case addrTypeIPv4: if len(packet) < 10 { return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.") } ip := packet[4:8] request.Port = v2net.PortFromBytes(packet[8:10]) request.Address = v2net.IPAddress(ip) dataBegin = 10 case addrTypeIPv6: if len(packet) < 22 { return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.") } ip := packet[4:20] request.Port = v2net.PortFromBytes(packet[20:22]) request.Address = v2net.IPAddress(ip) dataBegin = 22 case addrTypeDomain: domainLength := int(packet[4]) if len(packet) < 5+domainLength+2 { return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.") } domain := string(packet[5 : 5+domainLength]) request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2]) request.Address = v2net.ParseAddress(domain) dataBegin = 5 + domainLength + 2 default: return nil, nil, errors.New("Socks|UDP: Unknown address type ", addrType) } return request, packet[dataBegin:], nil }
func RetrieveOriginalDest(oob []byte) v2net.Destination { msgs, err := syscall.ParseSocketControlMessage(oob) if err != nil { return v2net.Destination{} } for _, msg := range msgs { if msg.Header.Level == syscall.SOL_IP && msg.Header.Type == syscall.IP_RECVORIGDSTADDR { ip := v2net.IPAddress(msg.Data[4:8]) port := v2net.PortFromBytes(msg.Data[2:4]) return v2net.UDPDestination(ip, port) } else if msg.Header.Level == syscall.SOL_IPV6 && msg.Header.Type == syscall.IP_RECVORIGDSTADDR { ip := v2net.IPAddress(msg.Data[8:24]) port := v2net.PortFromBytes(msg.Data[2:4]) return v2net.UDPDestination(ip, port) } } return v2net.Destination{} }
func ReadRequest(reader io.Reader) (request *Socks5Request, err error) { buffer := buf.NewLocal(512) defer buffer.Release() err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)) if err != nil { return } request = &Socks5Request{ Version: buffer.Byte(0), Command: buffer.Byte(1), // buffer[2] is a reserved field AddrType: buffer.Byte(3), } switch request.AddrType { case AddrTypeIPv4: _, err = io.ReadFull(reader, request.IPv4[:]) if err != nil { return } case AddrTypeDomain: buffer.Clear() err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)) if err != nil { return } domainLength := int(buffer.Byte(0)) err = buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength)) if err != nil { return } request.Domain = string(buffer.BytesFrom(-domainLength)) case AddrTypeIPv6: _, err = io.ReadFull(reader, request.IPv6[:]) if err != nil { return } default: err = errors.Format("Socks: Unexpected address type %d", request.AddrType) return } err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)) if err != nil { return } request.Port = v2net.PortFromBytes(buffer.BytesFrom(-2)) return }
func ReadRequest(reader io.Reader) (request *Socks5Request, err error) { buffer := alloc.NewSmallBuffer() defer buffer.Release() _, err = io.ReadFull(reader, buffer.Value[:4]) if err != nil { return } request = &Socks5Request{ Version: buffer.Value[0], Command: buffer.Value[1], // buffer[2] is a reserved field AddrType: buffer.Value[3], } switch request.AddrType { case AddrTypeIPv4: _, err = io.ReadFull(reader, request.IPv4[:]) if err != nil { return } case AddrTypeDomain: _, err = io.ReadFull(reader, buffer.Value[0:1]) if err != nil { return } domainLength := buffer.Value[0] _, err = io.ReadFull(reader, buffer.Value[:domainLength]) if err != nil { return } request.Domain = string(append([]byte(nil), buffer.Value[:domainLength]...)) case AddrTypeIPv6: _, err = io.ReadFull(reader, request.IPv6[:]) if err != nil { return } default: log.Warning("Socks: Unexpected address type ", request.AddrType) err = transport.ErrCorruptedPacket return } _, err = io.ReadFull(reader, buffer.Value[:2]) if err != nil { return } request.Port = v2net.PortFromBytes(buffer.Value[:2]) return }
func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, auth4 Socks4AuthenticationRequest, err error) { buffer := make([]byte, 256) nBytes, err := reader.Read(buffer) if err != nil { return } if nBytes < 2 { log.Warning("Socks: expected 2 bytes read, but only ", nBytes, " bytes read") err = transport.ErrCorruptedPacket return } if buffer[0] == socks4Version { auth4.Version = buffer[0] auth4.Command = buffer[1] auth4.Port = v2net.PortFromBytes(buffer[2:4]) copy(auth4.IP[:], buffer[4:8]) err = Socks4Downgrade return } auth.version = buffer[0] if auth.version != socksVersion { log.Warning("Socks: Unknown protocol version ", auth.version) err = proxy.ErrInvalidProtocolVersion return } auth.nMethods = buffer[1] if auth.nMethods <= 0 { log.Warning("Socks: Zero length of authentication methods") err = proxy.ErrInvalidAuthentication return } if nBytes-2 != int(auth.nMethods) { log.Warning("Socks: Unmatching number of auth methods, expecting ", auth.nMethods, ", but got ", nBytes) err = proxy.ErrInvalidAuthentication return } copy(auth.authMethods[:], buffer[2:nBytes]) return }
func (v *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) { cmd := new(protocol.CommandSwitchAccount) if len(data) == 0 { return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.") } lenHost := int(data[0]) if len(data) < lenHost+1 { return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.") } if lenHost > 0 { cmd.Host = net.ParseAddress(string(data[1 : 1+lenHost])) } portStart := 1 + lenHost if len(data) < portStart+2 { return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.") } cmd.Port = net.PortFromBytes(data[portStart : portStart+2]) idStart := portStart + 2 if len(data) < idStart+16 { return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.") } cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16]) alterIDStart := idStart + 16 if len(data) < alterIDStart+2 { return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.") } cmd.AlterIds = serial.BytesToUint16(data[alterIDStart : alterIDStart+2]) levelStart := alterIDStart + 2 if len(data) < levelStart+1 { return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.") } cmd.Level = uint32(data[levelStart]) timeStart := levelStart + 1 if len(data) < timeStart { return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.") } cmd.ValidMin = data[timeStart] return cmd, nil }
func (this *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) { cmd := new(protocol.CommandSwitchAccount) if len(data) == 0 { return nil, transport.ErrCorruptedPacket } lenHost := int(data[0]) if len(data) < lenHost+1 { return nil, transport.ErrCorruptedPacket } if lenHost > 0 { cmd.Host = v2net.ParseAddress(string(data[1 : 1+lenHost])) } portStart := 1 + lenHost if len(data) < portStart+2 { return nil, transport.ErrCorruptedPacket } cmd.Port = v2net.PortFromBytes(data[portStart : portStart+2]) idStart := portStart + 2 if len(data) < idStart+16 { return nil, transport.ErrCorruptedPacket } cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16]) alterIdStart := idStart + 16 if len(data) < alterIdStart+2 { return nil, transport.ErrCorruptedPacket } cmd.AlterIds = serial.BytesToUint16(data[alterIdStart : alterIdStart+2]) levelStart := alterIdStart + 2 if len(data) < levelStart+1 { return nil, transport.ErrCorruptedPacket } cmd.Level = protocol.UserLevel(data[levelStart]) timeStart := levelStart + 1 if len(data) < timeStart { return nil, transport.ErrCorruptedPacket } cmd.ValidMin = data[timeStart] return cmd, nil }
func (this *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) { buffer := make([]byte, 512) _, err := io.ReadFull(reader, buffer[:protocol.IDBytesLen]) if err != nil { log.Info("Raw: Failed to read request header: ", err) return nil, io.EOF } user, timestamp, valid := this.userValidator.Get(buffer[:protocol.IDBytesLen]) if !valid { return nil, protocol.ErrInvalidUser } timestampHash := md5.New() timestampHash.Write(hashTimestamp(timestamp)) iv := timestampHash.Sum(nil) account := user.Account.(*vmess.Account) aesStream := crypto.NewAesDecryptionStream(account.ID.CmdKey(), iv) decryptor := crypto.NewCryptionReader(aesStream, reader) nBytes, err := io.ReadFull(decryptor, buffer[:41]) if err != nil { log.Debug("Raw: Failed to read request header (", nBytes, " bytes): ", err) return nil, err } bufferLen := nBytes request := &protocol.RequestHeader{ User: user, Version: buffer[0], } if request.Version != Version { log.Info("Raw: Invalid protocol version ", request.Version) return nil, protocol.ErrInvalidVersion } this.requestBodyIV = append([]byte(nil), buffer[1:17]...) // 16 bytes this.requestBodyKey = append([]byte(nil), buffer[17:33]...) // 16 bytes this.responseHeader = buffer[33] // 1 byte request.Option = protocol.RequestOption(buffer[34]) // 1 byte + 2 bytes reserved request.Command = protocol.RequestCommand(buffer[37]) request.Port = v2net.PortFromBytes(buffer[38:40]) switch buffer[40] { case AddrTypeIPv4: nBytes, err = io.ReadFull(decryptor, buffer[41:45]) // 4 bytes bufferLen += 4 if err != nil { log.Debug("VMess: Failed to read target IPv4 (", nBytes, " bytes): ", err) return nil, err } request.Address = v2net.IPAddress(buffer[41:45]) case AddrTypeIPv6: nBytes, err = io.ReadFull(decryptor, buffer[41:57]) // 16 bytes bufferLen += 16 if err != nil { log.Debug("VMess: Failed to read target IPv6 (", nBytes, " bytes): ", nBytes, err) return nil, err } request.Address = v2net.IPAddress(buffer[41:57]) case AddrTypeDomain: nBytes, err = io.ReadFull(decryptor, buffer[41:42]) if err != nil { log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err) return nil, err } domainLength := int(buffer[41]) if domainLength == 0 { return nil, transport.ErrCorruptedPacket } nBytes, err = io.ReadFull(decryptor, buffer[42:42+domainLength]) if err != nil { log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err) return nil, err } bufferLen += 1 + domainLength request.Address = v2net.DomainAddress(string(buffer[42 : 42+domainLength])) } nBytes, err = io.ReadFull(decryptor, buffer[bufferLen:bufferLen+4]) if err != nil { log.Debug("VMess: Failed to read checksum (", nBytes, " bytes): ", nBytes, err) return nil, err } fnv1a := fnv.New32a() fnv1a.Write(buffer[:bufferLen]) actualHash := fnv1a.Sum32() expectedHash := serial.BytesToUint32(buffer[bufferLen : bufferLen+4]) if actualHash != expectedHash { return nil, transport.ErrCorruptedPacket } return request, nil }
func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) { buffer := make([]byte, 512) _, err := io.ReadFull(reader, buffer[:protocol.IDBytesLen]) if err != nil { log.Info("VMess|Server: Failed to read request header: ", err) return nil, io.EOF } user, timestamp, valid := v.userValidator.Get(buffer[:protocol.IDBytesLen]) if !valid { return nil, errors.New("VMess|Server: Invalid user.") } timestampHash := md5.New() timestampHash.Write(hashTimestamp(timestamp)) iv := timestampHash.Sum(nil) account, err := user.GetTypedAccount() if err != nil { return nil, errors.Base(err).Message("VMess|Server: Failed to get user account.") } aesStream := crypto.NewAesDecryptionStream(account.(*vmess.InternalAccount).ID.CmdKey(), iv) decryptor := crypto.NewCryptionReader(aesStream, reader) nBytes, err := io.ReadFull(decryptor, buffer[:41]) if err != nil { return nil, errors.Base(err).Message("VMess|Server: Failed to read request header.") } bufferLen := nBytes request := &protocol.RequestHeader{ User: user, Version: buffer[0], } if request.Version != Version { return nil, errors.New("VMess|Server: Invalid protocol version ", request.Version) } v.requestBodyIV = append([]byte(nil), buffer[1:17]...) // 16 bytes v.requestBodyKey = append([]byte(nil), buffer[17:33]...) // 16 bytes v.responseHeader = buffer[33] // 1 byte request.Option = protocol.RequestOption(buffer[34]) // 1 byte padingLen := int(buffer[35] >> 4) request.Security = protocol.NormSecurity(protocol.Security(buffer[35] & 0x0F)) // 1 bytes reserved request.Command = protocol.RequestCommand(buffer[37]) request.Port = v2net.PortFromBytes(buffer[38:40]) switch buffer[40] { case AddrTypeIPv4: _, err = io.ReadFull(decryptor, buffer[41:45]) // 4 bytes bufferLen += 4 if err != nil { return nil, errors.Base(err).Message("VMess|Server: Failed to read IPv4.") } request.Address = v2net.IPAddress(buffer[41:45]) case AddrTypeIPv6: _, err = io.ReadFull(decryptor, buffer[41:57]) // 16 bytes bufferLen += 16 if err != nil { return nil, errors.Base(err).Message("VMess|Server: Failed to read IPv6 address.") } request.Address = v2net.IPAddress(buffer[41:57]) case AddrTypeDomain: _, err = io.ReadFull(decryptor, buffer[41:42]) if err != nil { return nil, errors.Base(err).Message("VMess:Server: Failed to read domain.") } domainLength := int(buffer[41]) if domainLength == 0 { return nil, errors.New("VMess|Server: Zero length domain.") } _, err = io.ReadFull(decryptor, buffer[42:42+domainLength]) if err != nil { return nil, errors.Base(err).Message("VMess|Server: Failed to read domain.") } bufferLen += 1 + domainLength request.Address = v2net.DomainAddress(string(buffer[42 : 42+domainLength])) } if padingLen > 0 { _, err = io.ReadFull(decryptor, buffer[bufferLen:bufferLen+padingLen]) if err != nil { return nil, errors.New("VMess|Server: Failed to read padding.") } bufferLen += padingLen } _, err = io.ReadFull(decryptor, buffer[bufferLen:bufferLen+4]) if err != nil { return nil, errors.Base(err).Message("VMess|Server: Failed to read checksum.") } fnv1a := fnv.New32a() fnv1a.Write(buffer[:bufferLen]) actualHash := fnv1a.Sum32() expectedHash := serial.BytesToUint32(buffer[bufferLen : bufferLen+4]) if actualHash != expectedHash { return nil, errors.New("VMess|Server: Invalid auth.") } if request.Address == nil { return nil, errors.New("VMess|Server: Invalid remote address.") } return request, nil }
func DecodeUDPPacket(user *protocol.User, payload *alloc.Buffer) (*protocol.RequestHeader, *alloc.Buffer, error) { rawAccount, err := user.GetTypedAccount() if err != nil { return nil, nil, errors.New("Shadowsocks|UDP: Failed to parse account: " + err.Error()) } account := rawAccount.(*ShadowsocksAccount) ivLen := account.Cipher.IVSize() iv := payload.Value[:ivLen] payload.SliceFrom(ivLen) stream, err := account.Cipher.NewDecodingStream(account.Key, iv) if err != nil { return nil, nil, errors.New("Shadowsocks|UDP: Failed to initialize decoding stream: " + err.Error()) } stream.XORKeyStream(payload.Value, payload.Value) authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv)) request := &protocol.RequestHeader{ Version: Version, User: user, Command: protocol.RequestCommandUDP, } addrType := (payload.Value[0] & 0x0F) if (payload.Value[0] & 0x10) == 0x10 { request.Option |= RequestOptionOneTimeAuth } if request.Option.Has(RequestOptionOneTimeAuth) { payloadLen := payload.Len() - AuthSize authBytes := payload.Value[payloadLen:] actualAuth := authenticator.Authenticate(nil, payload.Value[0:payloadLen]) if !bytes.Equal(actualAuth, authBytes) { return nil, nil, errors.New("Shadowsocks|UDP: Invalid OTA.") } payload.Slice(0, payloadLen) } payload.SliceFrom(1) switch addrType { case AddrTypeIPv4: request.Address = v2net.IPAddress(payload.Value[:4]) payload.SliceFrom(4) case AddrTypeIPv6: request.Address = v2net.IPAddress(payload.Value[:16]) payload.SliceFrom(16) case AddrTypeDomain: domainLength := int(payload.Value[0]) request.Address = v2net.DomainAddress(string(payload.Value[1 : 1+domainLength])) payload.SliceFrom(1 + domainLength) default: return nil, nil, errors.New("Shadowsocks|UDP: Unknown address type") } request.Port = v2net.PortFromBytes(payload.Value[:2]) payload.SliceFrom(2) return request, payload, nil }
func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHeader, v2io.Reader, error) { rawAccount, err := user.GetTypedAccount() if err != nil { return nil, nil, errors.New("Shadowsocks|TCP: Failed to parse account: " + err.Error()) } account := rawAccount.(*ShadowsocksAccount) buffer := alloc.NewLocalBuffer(512) defer buffer.Release() ivLen := account.Cipher.IVSize() _, err = io.ReadFull(reader, buffer.Value[:ivLen]) if err != nil { return nil, nil, errors.New("Shadowsocks|TCP: Failed to read IV: " + err.Error()) } iv := append([]byte(nil), buffer.Value[:ivLen]...) stream, err := account.Cipher.NewDecodingStream(account.Key, iv) if err != nil { return nil, nil, errors.New("Shadowsocks|TCP: Failed to initialize decoding stream: " + err.Error()) } reader = crypto.NewCryptionReader(stream, reader) authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv)) request := &protocol.RequestHeader{ Version: Version, User: user, Command: protocol.RequestCommandTCP, } lenBuffer := 1 _, err = io.ReadFull(reader, buffer.Value[:1]) if err != nil { return nil, nil, errors.New("Sahdowsocks|TCP: Failed to read address type: " + err.Error()) } addrType := (buffer.Value[0] & 0x0F) if (buffer.Value[0] & 0x10) == 0x10 { request.Option |= RequestOptionOneTimeAuth } switch addrType { case AddrTypeIPv4: _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+4]) if err != nil { return nil, nil, errors.New("Shadowsocks|TCP: Failed to read IPv4 address: " + err.Error()) } request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+4]) lenBuffer += 4 case AddrTypeIPv6: _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+16]) if err != nil { return nil, nil, errors.New("Shadowsocks|TCP: Failed to read IPv6 address: " + err.Error()) } request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+16]) lenBuffer += 16 case AddrTypeDomain: _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+1]) if err != nil { return nil, nil, errors.New("Shadowsocks|TCP: Failed to read domain lenth: " + err.Error()) } domainLength := int(buffer.Value[lenBuffer]) lenBuffer++ _, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+domainLength]) if err != nil { return nil, nil, errors.New("Shadowsocks|TCP: Failed to read domain: " + err.Error()) } request.Address = v2net.DomainAddress(string(buffer.Value[lenBuffer : lenBuffer+domainLength])) lenBuffer += domainLength default: return nil, nil, errors.New("Shadowsocks|TCP: Unknown address type.") } _, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+2]) if err != nil { return nil, nil, errors.New("Shadowsocks|TCP: Failed to read port: " + err.Error()) } request.Port = v2net.PortFromBytes(buffer.Value[lenBuffer : lenBuffer+2]) lenBuffer += 2 if request.Option.Has(RequestOptionOneTimeAuth) { authBytes := buffer.Value[lenBuffer : lenBuffer+AuthSize] _, err = io.ReadFull(reader, authBytes) if err != nil { return nil, nil, errors.New("Shadowsocks|TCP: Failed to read OTA: " + err.Error()) } actualAuth := authenticator.Authenticate(nil, buffer.Value[0:lenBuffer]) if !bytes.Equal(actualAuth, authBytes) { return nil, nil, errors.New("Shadowsocks|TCP: Invalid OTA") } } var chunkReader v2io.Reader if request.Option.Has(RequestOptionOneTimeAuth) { chunkReader = NewChunkReader(reader, NewAuthenticator(ChunkKeyGenerator(iv))) } else { chunkReader = v2io.NewAdaptiveReader(reader) } return request, chunkReader, nil }
func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) { buffer := buf.NewLocal(512) request := new(protocol.RequestHeader) if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { return nil, errors.Base(err).Message("Socks|Server: Insufficient header.") } version := buffer.Byte(0) if version == socks4Version { if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 6)); err != nil { return nil, errors.Base(err).Message("Socks|Server: Insufficient header.") } port := v2net.PortFromBytes(buffer.BytesRange(2, 4)) address := v2net.IPAddress(buffer.BytesRange(4, 8)) _, err := readUntilNull(reader) // user id if err != nil { return nil, err } if address.IP()[0] == 0x00 { domain, err := readUntilNull(reader) if err != nil { return nil, errors.Base(err).Message("Socks|Server: Failed to read domain for socks 4a.") } address = v2net.DomainAddress(domain) } switch buffer.Byte(1) { case cmdTCPConnect: request.Command = protocol.RequestCommandTCP request.Address = address request.Port = port request.Version = socks4Version if err := writeSocks4Response(writer, socks4RequestGranted, v2net.AnyIP, v2net.Port(0)); err != nil { return nil, err } return request, nil default: writeSocks4Response(writer, socks4RequestRejected, v2net.AnyIP, v2net.Port(0)) return nil, errors.New("Socks|Server: Unsupported command: ", buffer.Byte(1)) } } if version == socks5Version { nMethod := int(buffer.Byte(1)) if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nMethod)); err != nil { return nil, err } var expectedAuth byte = authNotRequired if s.config.AuthType == AuthType_PASSWORD { expectedAuth = authPassword } if !hasAuthMethod(expectedAuth, buffer.BytesRange(2, 2+nMethod)) { writeSocks5AuthenticationResponse(writer, authNoMatchingMethod) return nil, errors.New("Socks|Server: No matching auth method.") } if err := writeSocks5AuthenticationResponse(writer, expectedAuth); err != nil { return nil, err } if expectedAuth == authPassword { username, password, err := readUsernamePassword(reader) if err != nil { return nil, errors.Base(err).Message("Socks|Server: Failed to read username and password for authentication.") } if !s.config.HasAccount(username, password) { writeSocks5AuthenticationResponse(writer, 0xFF) return nil, errors.New("Socks|Server: Invalid username or password.") } if err := writeSocks5AuthenticationResponse(writer, 0x00); err != nil { return nil, err } } buffer.Clear() if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil { return nil, err } cmd := buffer.Byte(1) if cmd == cmdTCPBind || (cmd == cmdUDPPort && !s.config.UdpEnabled) { writeSocks5Response(writer, statusCmdNotSupport, v2net.AnyIP, v2net.Port(0)) return nil, errors.New("Socks|Server: Unsupported command: ", cmd) } switch cmd { case cmdTCPConnect: request.Command = protocol.RequestCommandTCP case cmdUDPPort: request.Command = protocol.RequestCommandUDP } addrType := buffer.Byte(3) buffer.Clear() request.Version = socks5Version switch addrType { case addrTypeIPv4: if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil { return nil, err } request.Address = v2net.IPAddress(buffer.Bytes()) case addrTypeIPv6: if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 16)); err != nil { return nil, err } request.Address = v2net.IPAddress(buffer.Bytes()) case addrTypeDomain: if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil { return nil, err } domainLength := int(buffer.Byte(0)) if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength)); err != nil { return nil, err } request.Address = v2net.DomainAddress(string(buffer.BytesFrom(-domainLength))) default: return nil, errors.New("Socks|Server: Unknown address type: ", addrType) } if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { return nil, err } request.Port = v2net.PortFromBytes(buffer.BytesFrom(-2)) responseAddress := v2net.AnyIP responsePort := v2net.Port(1717) if request.Command == protocol.RequestCommandUDP { addr := s.config.Address.AsAddress() if addr == nil { addr = v2net.LocalHostIP } responseAddress = addr responsePort = s.port } if err := writeSocks5Response(writer, statusSuccess, responseAddress, responsePort); err != nil { return nil, err } return request, nil } return nil, errors.New("Socks|Server: Unknown Socks version: ", version) }
func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) { authByte := byte(authNotRequired) if request.User != nil { authByte = byte(authPassword) } authRequest := []byte{socks5Version, 0x01, authByte} if _, err := writer.Write(authRequest); err != nil { return nil, err } b := buf.NewLocal(64) if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { return nil, err } if b.Byte(0) != socks5Version { return nil, errors.New("Socks|Client: Unexpected server version: ", b.Byte(0)) } if b.Byte(1) != authByte { return nil, errors.New("Socks|Client: auth method not supported.") } if authByte == authPassword { rawAccount, err := request.User.GetTypedAccount() if err != nil { return nil, err } account := rawAccount.(*Account) b.Clear() b.AppendBytes(socks5Version, byte(len(account.Username))) b.Append([]byte(account.Username)) b.AppendBytes(byte(len(account.Password))) b.Append([]byte(account.Password)) if _, err := writer.Write(b.Bytes()); err != nil { return nil, err } b.Clear() if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { return nil, err } if b.Byte(1) != 0x00 { return nil, errors.New("Socks|Client: Server rejects account: ", b.Byte(1)) } } b.Clear() command := byte(cmdTCPConnect) if request.Command == protocol.RequestCommandUDP { command = byte(cmdUDPPort) } b.AppendBytes(socks5Version, command, 0x00 /* reserved */) appendAddress(b, request.Address, request.Port) if _, err := writer.Write(b.Bytes()); err != nil { return nil, err } b.Clear() if err := b.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil { return nil, err } resp := b.Byte(1) if resp != 0x00 { return nil, errors.New("Socks|Client: Server rejects request: ", resp) } addrType := b.Byte(3) b.Clear() var address v2net.Address switch addrType { case addrTypeIPv4: if err := b.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil { return nil, err } address = v2net.IPAddress(b.Bytes()) case addrTypeIPv6: if err := b.AppendSupplier(buf.ReadFullFrom(reader, 16)); err != nil { return nil, err } address = v2net.IPAddress(b.Bytes()) case addrTypeDomain: if err := b.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil { return nil, err } domainLength := int(b.Byte(0)) if err := b.AppendSupplier(buf.ReadFullFrom(reader, domainLength)); err != nil { return nil, err } address = v2net.DomainAddress(string(b.BytesFrom(-domainLength))) default: return nil, errors.New("Socks|Server: Unknown address type: ", addrType) } if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { return nil, err } port := v2net.PortFromBytes(b.BytesFrom(-2)) if request.Command == protocol.RequestCommandUDP { udpRequest := &protocol.RequestHeader{ Version: socks5Version, Command: protocol.RequestCommandUDP, Address: address, Port: port, } return udpRequest, nil } return nil, nil }
func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) { rawAccount, err := user.GetTypedAccount() if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to parse account.") } account := rawAccount.(*ShadowsocksAccount) buffer := buf.NewLocal(512) defer buffer.Release() ivLen := account.Cipher.IVSize() err = buffer.AppendSupplier(buf.ReadFullFrom(reader, ivLen)) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IV.") } iv := append([]byte(nil), buffer.BytesTo(ivLen)...) stream, err := account.Cipher.NewDecodingStream(account.Key, iv) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to initialize decoding stream.") } reader = crypto.NewCryptionReader(stream, reader) authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv)) request := &protocol.RequestHeader{ Version: Version, User: user, Command: protocol.RequestCommandTCP, } buffer.Clear() err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read address type.") } addrType := (buffer.Byte(0) & 0x0F) if (buffer.Byte(0) & 0x10) == 0x10 { request.Option |= RequestOptionOneTimeAuth } if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled { return nil, nil, errors.New("Shadowsocks|TCP: Rejecting connection with OTA enabled, while server disables OTA.") } if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled { return nil, nil, errors.New("Shadowsocks|TCP: Rejecting connection with OTA disabled, while server enables OTA.") } switch addrType { case AddrTypeIPv4: err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv4 address.") } request.Address = v2net.IPAddress(buffer.BytesFrom(-4)) case AddrTypeIPv6: err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 16)) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv6 address.") } request.Address = v2net.IPAddress(buffer.BytesFrom(-16)) case AddrTypeDomain: err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain lenth.") } domainLength := int(buffer.BytesFrom(-1)[0]) err = buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength)) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain.") } request.Address = v2net.DomainAddress(string(buffer.BytesFrom(-domainLength))) default: // Check address validity after OTA verification. } err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read port.") } request.Port = v2net.PortFromBytes(buffer.BytesFrom(-2)) if request.Option.Has(RequestOptionOneTimeAuth) { actualAuth := make([]byte, AuthSize) authenticator.Authenticate(buffer.Bytes())(actualAuth) err := buffer.AppendSupplier(buf.ReadFullFrom(reader, AuthSize)) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read OTA.") } if !bytes.Equal(actualAuth, buffer.BytesFrom(-AuthSize)) { return nil, nil, errors.New("Shadowsocks|TCP: Invalid OTA") } } if request.Address == nil { return nil, nil, errors.New("Shadowsocks|TCP: Invalid remote address.") } var chunkReader buf.Reader if request.Option.Has(RequestOptionOneTimeAuth) { chunkReader = NewChunkReader(reader, NewAuthenticator(ChunkKeyGenerator(iv))) } else { chunkReader = buf.NewReader(reader) } return request, chunkReader, nil }
func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.RequestHeader, *buf.Buffer, error) { rawAccount, err := user.GetTypedAccount() if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|UDP: Failed to parse account.") } account := rawAccount.(*ShadowsocksAccount) ivLen := account.Cipher.IVSize() iv := payload.BytesTo(ivLen) payload.SliceFrom(ivLen) stream, err := account.Cipher.NewDecodingStream(account.Key, iv) if err != nil { return nil, nil, errors.Base(err).Message("Shadowsocks|UDP: Failed to initialize decoding stream.") } stream.XORKeyStream(payload.Bytes(), payload.Bytes()) authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv)) request := &protocol.RequestHeader{ Version: Version, User: user, Command: protocol.RequestCommandUDP, } addrType := (payload.Byte(0) & 0x0F) if (payload.Byte(0) & 0x10) == 0x10 { request.Option |= RequestOptionOneTimeAuth } if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled { return nil, nil, errors.New("Shadowsocks|UDP: Rejecting packet with OTA enabled, while server disables OTA.") } if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled { return nil, nil, errors.New("Shadowsocks|UDP: Rejecting packet with OTA disabled, while server enables OTA.") } 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, errors.New("Shadowsocks|UDP: Invalid OTA.") } payload.Slice(0, payloadLen) } payload.SliceFrom(1) switch addrType { case AddrTypeIPv4: request.Address = v2net.IPAddress(payload.BytesTo(4)) payload.SliceFrom(4) case AddrTypeIPv6: request.Address = v2net.IPAddress(payload.BytesTo(16)) payload.SliceFrom(16) case AddrTypeDomain: domainLength := int(payload.Byte(0)) request.Address = v2net.DomainAddress(string(payload.BytesRange(1, 1+domainLength))) payload.SliceFrom(1 + domainLength) default: return nil, nil, errors.New("Shadowsocks|UDP: Unknown address type: ", addrType) } request.Port = v2net.PortFromBytes(payload.BytesTo(2)) payload.SliceFrom(2) return request, payload, nil }
func ReadRequest(reader io.Reader, auth *Authenticator, udp bool) (*Request, error) { buffer := alloc.NewSmallBuffer() defer buffer.Release() _, err := io.ReadFull(reader, buffer.Value[:1]) if err != nil { if err != io.EOF { log.Warning("Shadowsocks: Failed to read address type: ", err) return nil, transport.ErrCorruptedPacket } return nil, err } lenBuffer := 1 request := new(Request) addrType := (buffer.Value[0] & 0x0F) if (buffer.Value[0] & 0x10) == 0x10 { request.OTA = true } switch addrType { case AddrTypeIPv4: _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+4]) if err != nil { log.Warning("Shadowsocks: Failed to read IPv4 address: ", err) return nil, transport.ErrCorruptedPacket } request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+4]) lenBuffer += 4 case AddrTypeIPv6: _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+16]) if err != nil { log.Warning("Shadowsocks: Failed to read IPv6 address: ", err) return nil, transport.ErrCorruptedPacket } request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+16]) lenBuffer += 16 case AddrTypeDomain: _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+1]) if err != nil { log.Warning("Shadowsocks: Failed to read domain lenth: ", err) return nil, transport.ErrCorruptedPacket } domainLength := int(buffer.Value[lenBuffer]) lenBuffer++ _, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+domainLength]) if err != nil { log.Warning("Shadowsocks: Failed to read domain: ", err) return nil, transport.ErrCorruptedPacket } request.Address = v2net.DomainAddress(string(buffer.Value[lenBuffer : lenBuffer+domainLength])) lenBuffer += domainLength default: log.Warning("Shadowsocks: Unknown address type: ", addrType) return nil, transport.ErrCorruptedPacket } _, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+2]) if err != nil { log.Warning("Shadowsocks: Failed to read port: ", err) return nil, transport.ErrCorruptedPacket } request.Port = v2net.PortFromBytes(buffer.Value[lenBuffer : lenBuffer+2]) lenBuffer += 2 var authBytes []byte if udp { nBytes, err := reader.Read(buffer.Value[lenBuffer:]) if err != nil { log.Warning("Shadowsocks: Failed to read UDP payload: ", err) return nil, transport.ErrCorruptedPacket } buffer.Slice(0, lenBuffer+nBytes) if request.OTA { authBytes = buffer.Value[lenBuffer+nBytes-AuthSize:] request.UDPPayload = alloc.NewSmallBuffer().Clear().Append(buffer.Value[lenBuffer : lenBuffer+nBytes-AuthSize]) lenBuffer = lenBuffer + nBytes - AuthSize } else { request.UDPPayload = alloc.NewSmallBuffer().Clear().Append(buffer.Value[lenBuffer:]) } } else { if request.OTA { authBytes = buffer.Value[lenBuffer : lenBuffer+AuthSize] _, err = io.ReadFull(reader, authBytes) if err != nil { log.Warning("Shadowsocks: Failed to read OTA: ", err) return nil, transport.ErrCorruptedPacket } } } if request.OTA { actualAuth := auth.Authenticate(nil, buffer.Value[0:lenBuffer]) if !bytes.Equal(actualAuth, authBytes) { log.Warning("Shadowsocks: Invalid OTA.") return nil, proxy.ErrInvalidAuthentication } } return request, nil }