Exemplo n.º 1
0
func ReadVMessUDP(buffer []byte, userset user.UserSet) (*VMessUDP, error) {
	userHash := buffer[:user.IDBytesLen]
	userId, timeSec, valid := userset.GetUser(userHash)
	if !valid {
		return nil, errors.NewAuthenticationError(userHash)
	}

	buffer = buffer[user.IDBytesLen:]
	aesCipher, err := aes.NewCipher(userId.CmdKey())
	if err != nil {
		return nil, err
	}
	aesStream := cipher.NewCFBDecrypter(aesCipher, user.Int64Hash(timeSec))
	aesStream.XORKeyStream(buffer, buffer)

	fnvHash := binary.BigEndian.Uint32(buffer[:4])
	fnv1a := fnv.New32a()
	fnv1a.Write(buffer[4:])
	fnvHashActual := fnv1a.Sum32()

	if fnvHash != fnvHashActual {
		log.Warning("Unexpected fhv hash %d, should be %d", fnvHashActual, fnvHash)
		return nil, errors.NewCorruptedPacketError()
	}

	buffer = buffer[4:]

	vmess := &VMessUDP{
		user:    *userId,
		version: buffer[0],
		token:   binary.BigEndian.Uint16(buffer[1:3]),
	}

	// buffer[3] is reserved

	port := binary.BigEndian.Uint16(buffer[4:6])
	addrType := buffer[6]
	var address v2net.Address
	switch addrType {
	case addrTypeIPv4:
		address = v2net.IPAddress(buffer[7:11], port)
		buffer = buffer[11:]
	case addrTypeIPv6:
		address = v2net.IPAddress(buffer[7:23], port)
		buffer = buffer[23:]
	case addrTypeDomain:
		domainLength := buffer[7]
		domain := string(buffer[8 : 8+domainLength])
		address = v2net.DomainAddress(domain, port)
		buffer = buffer[8+domainLength:]
	default:
		log.Warning("Unexpected address type %d", addrType)
		return nil, errors.NewCorruptedPacketError()
	}

	vmess.address = address
	vmess.data = buffer

	return vmess, nil
}
Exemplo n.º 2
0
func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, auth4 Socks4AuthenticationRequest, err error) {
	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()

	nBytes, err := reader.Read(buffer.Value)
	if err != nil {
		return
	}
	if nBytes < 2 {
		log.Info("Socks expected 2 bytes read, but only %d bytes read", nBytes)
		err = errors.NewCorruptedPacketError()
		return
	}

	if buffer.Value[0] == socks4Version {
		auth4.Version = buffer.Value[0]
		auth4.Command = buffer.Value[1]
		auth4.Port = binary.BigEndian.Uint16(buffer.Value[2:4])
		copy(auth4.IP[:], buffer.Value[4:8])
		err = NewSocksVersion4Error()
		return
	}

	auth.version = buffer.Value[0]
	if auth.version != socksVersion {
		err = errors.NewProtocolVersionError(int(auth.version))
		return
	}

	auth.nMethods = buffer.Value[1]
	if auth.nMethods <= 0 {
		log.Info("Zero length of authentication methods")
		err = errors.NewCorruptedPacketError()
		return
	}

	if nBytes-2 != int(auth.nMethods) {
		log.Info("Unmatching number of auth methods, expecting %d, but got %d", auth.nMethods, nBytes)
		err = errors.NewCorruptedPacketError()
		return
	}
	copy(auth.authMethods[:], buffer.Value[2:nBytes])
	return
}
Exemplo n.º 3
0
func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()

	nBytes, err := reader.Read(buffer.Value[:4])
	if err != nil {
		return
	}
	if nBytes < 4 {
		err = errors.NewCorruptedPacketError()
		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:
		nBytes, err = reader.Read(request.IPv4[:])
		if err != nil {
			return
		}
		if nBytes != 4 {
			err = errors.NewCorruptedPacketError()
			return
		}
	case AddrTypeDomain:
		nBytes, err = reader.Read(buffer.Value[0:1])
		if err != nil {
			return
		}
		domainLength := buffer.Value[0]
		nBytes, err = reader.Read(buffer.Value[:domainLength])
		if err != nil {
			return
		}

		if nBytes != int(domainLength) {
			log.Info("Unable to read domain with %d bytes, expecting %d bytes", nBytes, domainLength)
			err = errors.NewCorruptedPacketError()
			return
		}
		request.Domain = string(buffer.Value[:domainLength])
	case AddrTypeIPv6:
		nBytes, err = reader.Read(request.IPv6[:])
		if err != nil {
			return
		}
		if nBytes != 16 {
			err = errors.NewCorruptedPacketError()
			return
		}
	default:
		log.Info("Unexpected address type %d", request.AddrType)
		err = errors.NewCorruptedPacketError()
		return
	}

	nBytes, err = reader.Read(buffer.Value[:2])
	if err != nil {
		return
	}
	if nBytes != 2 {
		err = errors.NewCorruptedPacketError()
		return
	}

	request.Port = binary.BigEndian.Uint16(buffer.Value[:2])
	return
}
Exemplo n.º 4
0
// Read reads a VMessRequest from a byte stream.
func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
	buffer := make([]byte, 256)

	nBytes, err := reader.Read(buffer[:user.IDBytesLen])
	if err != nil {
		return nil, err
	}

	log.Debug("Read user hash: %v", buffer[:nBytes])

	userId, timeSec, valid := r.vUserSet.GetUser(buffer[:nBytes])
	if !valid {
		return nil, errors.NewAuthenticationError(buffer[:nBytes])
	}

	aesCipher, err := aes.NewCipher(userId.CmdKey())
	if err != nil {
		return nil, err
	}
	aesStream := cipher.NewCFBDecrypter(aesCipher, user.Int64Hash(timeSec))
	decryptor := v2io.NewCryptionReader(aesStream, reader)

	if err != nil {
		return nil, err
	}

	nBytes, err = decryptor.Read(buffer[:41])
	if err != nil {
		return nil, err
	}
	bufferLen := nBytes

	request := &VMessRequest{
		UserId:  *userId,
		Version: buffer[0],
	}

	if request.Version != Version {
		return nil, errors.NewProtocolVersionError(int(request.Version))
	}

	copy(request.RequestIV[:], buffer[1:17])       // 16 bytes
	copy(request.RequestKey[:], buffer[17:33])     // 16 bytes
	copy(request.ResponseHeader[:], buffer[33:37]) // 4 bytes
	request.Command = buffer[37]

	port := binary.BigEndian.Uint16(buffer[38:40])

	switch buffer[40] {
	case addrTypeIPv4:
		_, err = decryptor.Read(buffer[41:45]) // 4 bytes
		bufferLen += 4
		if err != nil {
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[41:45], port)
	case addrTypeIPv6:
		_, err = decryptor.Read(buffer[41:57]) // 16 bytes
		bufferLen += 16
		if err != nil {
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[41:57], port)
	case addrTypeDomain:
		_, err = decryptor.Read(buffer[41:42])
		if err != nil {
			return nil, err
		}
		domainLength := int(buffer[41])
		_, err = decryptor.Read(buffer[42 : 42+domainLength])
		if err != nil {
			return nil, err
		}
		bufferLen += 1 + domainLength
		request.Address = v2net.DomainAddress(string(buffer[42:42+domainLength]), port)
	}

	_, err = decryptor.Read(buffer[bufferLen : bufferLen+4])
	if err != nil {
		return nil, err
	}

	fnv1a := fnv.New32a()
	fnv1a.Write(buffer[:bufferLen])
	actualHash := fnv1a.Sum32()
	expectedHash := binary.BigEndian.Uint32(buffer[bufferLen : bufferLen+4])

	if actualHash != expectedHash {
		return nil, errors.NewCorruptedPacketError()
	}

	return request, nil
}