Пример #1
0
func handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- *alloc.Buffer, finish *sync.Mutex, isUDP bool) {
	defer finish.Unlock()
	defer close(output)
	responseKey := md5.Sum(request.RequestKey[:])
	responseIV := md5.Sum(request.RequestIV[:])

	aesStream, err := v2crypto.NewAesDecryptionStream(responseKey[:], responseIV[:])
	if err != nil {
		log.Error("VMessOut: Failed to create AES encryption stream: %v", err)
		return
	}
	decryptResponseReader := v2crypto.NewCryptionReader(aesStream, conn)

	buffer, err := v2net.ReadFrom(decryptResponseReader, nil)
	if err != nil {
		log.Error("VMessOut: Failed to read VMess response (%d bytes): %v", buffer.Len(), err)
		return
	}
	if buffer.Len() < 4 || !headerMatch(request, buffer.Value[:2]) {
		log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.")
		return
	}
	log.Info("VMessOut received %d bytes from %s", buffer.Len()-4, conn.RemoteAddr().String())

	buffer.SliceFrom(4)
	output <- buffer

	if !isUDP {
		v2net.ReaderToChan(output, decryptResponseReader)
	}

	return
}
Пример #2
0
func (this *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.ResponseHeader, error) {
	aesStream := crypto.NewAesDecryptionStream(this.responseBodyKey, this.responseBodyIV)
	this.responseReader = crypto.NewCryptionReader(aesStream, reader)

	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()

	_, err := io.ReadFull(this.responseReader, buffer.Value[:4])
	if err != nil {
		log.Error("Raw: Failed to read response header: ", err)
		return nil, err
	}

	if buffer.Value[0] != this.responseHeader {
		log.Warning("Raw: Unexpected response header. Expecting %d, but actually %d", this.responseHeader, buffer.Value[0])
		return nil, transport.ErrorCorruptedPacket
	}

	header := new(protocol.ResponseHeader)

	if buffer.Value[2] != 0 {
		cmdId := buffer.Value[2]
		dataLen := int(buffer.Value[3])
		_, err := io.ReadFull(this.responseReader, buffer.Value[:dataLen])
		if err != nil {
			log.Error("Raw: Failed to read response command: ", err)
			return nil, err
		}
		data := buffer.Value[:dataLen]
		command, err := UnmarshalCommand(cmdId, data)
		header.Command = command
	}

	return header, nil
}
Пример #3
0
func (this *AesCfb) NewDecodingStream(key []byte, iv []byte, reader io.Reader) (io.Reader, error) {
	stream, err := crypto.NewAesDecryptionStream(key, iv)
	if err != nil {
		return nil, err
	}
	aesReader := crypto.NewCryptionReader(stream, reader)
	return aesReader, nil
}
Пример #4
0
func handleInput(request *protocol.VMessRequest, reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) {
	defer close(input)
	defer finish.Unlock()

	aesStream, err := v2crypto.NewAesDecryptionStream(request.RequestKey, request.RequestIV)
	if err != nil {
		log.Error("VMessIn: Failed to create AES decryption stream: ", err)
		return
	}
	requestReader := v2crypto.NewCryptionReader(aesStream, reader)
	v2net.ReaderToChan(input, requestReader)
}
Пример #5
0
func (this *VMessOutboundHandler) handleResponse(conn net.Conn, request *protocol.VMessRequest, dest v2net.Destination, output chan<- *alloc.Buffer, finish *sync.Mutex) {
	defer finish.Unlock()
	defer close(output)
	responseKey := md5.Sum(request.RequestKey[:])
	responseIV := md5.Sum(request.RequestIV[:])

	aesStream, err := v2crypto.NewAesDecryptionStream(responseKey[:], responseIV[:])
	if err != nil {
		log.Error("VMessOut: Failed to create AES encryption stream: ", err)
		return
	}
	decryptResponseReader := v2crypto.NewCryptionReader(aesStream, conn)

	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()
	_, err = io.ReadFull(decryptResponseReader, buffer.Value[:4])

	if err != nil {
		log.Error("VMessOut: Failed to read VMess response (", buffer.Len(), " bytes): ", err)
		return
	}
	if !headerMatch(request, buffer.Value[0]) {
		log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.")
		return
	}

	if buffer.Value[2] != 0 {
		command := buffer.Value[2]
		dataLen := int(buffer.Value[3])
		_, err := io.ReadFull(decryptResponseReader, buffer.Value[:dataLen])
		if err != nil {
			log.Error("VMessOut: Failed to read response command: ", err)
			return
		}
		data := buffer.Value[:dataLen]
		go this.handleCommand(dest, command, data)
	}

	var reader v2io.Reader
	if request.IsChunkStream() {
		reader = vmessio.NewAuthChunkReader(decryptResponseReader)
	} else {
		reader = v2io.NewAdaptiveReader(decryptResponseReader)
	}

	v2io.ReaderToChan(output, reader)

	return
}
Пример #6
0
func handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- *alloc.Buffer, finish *sync.Mutex, isUDP bool) {
	defer finish.Unlock()
	defer close(output)
	responseKey := md5.Sum(request.RequestKey[:])
	responseIV := md5.Sum(request.RequestIV[:])

	aesStream, err := v2crypto.NewAesDecryptionStream(responseKey[:], responseIV[:])
	if err != nil {
		log.Error("VMessOut: Failed to create AES encryption stream: ", err)
		return
	}
	decryptResponseReader := v2crypto.NewCryptionReader(aesStream, conn)

	buffer, err := v2net.ReadFrom(decryptResponseReader, nil)
	if err != nil {
		log.Error("VMessOut: Failed to read VMess response (", buffer.Len(), " bytes): ", err)
		buffer.Release()
		return
	}
	if buffer.Len() < 4 || !headerMatch(request, buffer.Value[:2]) {
		log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.")
		return
	}
	log.Info("VMessOut received ", buffer.Len()-4, " bytes from ", conn.RemoteAddr())

	responseBegin := 4
	if buffer.Value[2] != 0 {
		dataLen := int(buffer.Value[3])
		if buffer.Len() < dataLen+4 { // Rare case
			diffBuffer := make([]byte, dataLen+4-buffer.Len())
			v2net.ReadAllBytes(decryptResponseReader, diffBuffer)
			buffer.Append(diffBuffer)
		}
		command := buffer.Value[2]
		data := buffer.Value[4 : 4+dataLen]
		go handleCommand(command, data)
		responseBegin = 4 + dataLen
	}

	buffer.SliceFrom(responseBegin)
	output <- buffer

	if !isUDP {
		v2net.ReaderToChan(output, decryptResponseReader)
	}

	return
}
Пример #7
0
func handleInput(request *protocol.VMessRequest, reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) {
	defer close(input)
	defer finish.Unlock()

	aesStream, err := v2crypto.NewAesDecryptionStream(request.RequestKey, request.RequestIV)
	if err != nil {
		log.Error("VMessIn: Failed to create AES decryption stream: ", err)
		return
	}
	descriptionReader := v2crypto.NewCryptionReader(aesStream, reader)
	var requestReader v2io.Reader
	if request.IsChunkStream() {
		requestReader = vmessio.NewAuthChunkReader(descriptionReader)
	} else {
		requestReader = v2io.NewAdaptiveReader(descriptionReader)
	}
	v2io.ReaderToChan(input, requestReader)
}
Пример #8
0
func (this *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.ResponseHeader, error) {
	aesStream := crypto.NewAesDecryptionStream(this.responseBodyKey, this.responseBodyIV)
	this.responseReader = crypto.NewCryptionReader(aesStream, reader)

	buffer := make([]byte, 256)

	_, err := io.ReadFull(this.responseReader, buffer[:4])
	if err != nil {
		log.Info("Raw: Failed to read response header: ", err)
		return nil, err
	}

	if buffer[0] != this.responseHeader {
		log.Info("Raw: Unexpected response header. Expecting ", this.responseHeader, " but actually ", buffer[0])
		return nil, transport.ErrCorruptedPacket
	}

	header := &protocol.ResponseHeader{
		Option: protocol.ResponseOption(buffer[1]),
	}

	if buffer[2] != 0 {
		cmdId := buffer[2]
		dataLen := int(buffer[3])
		_, err := io.ReadFull(this.responseReader, buffer[:dataLen])
		if err != nil {
			log.Info("Raw: Failed to read response command: ", err)
			return nil, err
		}
		data := buffer[:dataLen]
		command, err := UnmarshalCommand(cmdId, data)
		if err == nil {
			header.Command = command
		}
	}

	return header, nil
}
Пример #9
0
// Read reads a VMessRequest from a byte stream.
func (this *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()

	nBytes, err := io.ReadFull(reader, buffer.Value[:proto.IDBytesLen])
	if err != nil {
		log.Debug("VMess: Failed to read request ID (", nBytes, " bytes): ", err)
		return nil, err
	}

	userObj, timeSec, valid := this.vUserSet.GetUser(buffer.Value[:nBytes])
	if !valid {
		return nil, proxy.ErrorInvalidAuthentication
	}

	timestampHash := TimestampHash()
	timestampHash.Write(timeSec.HashBytes())
	iv := timestampHash.Sum(nil)
	aesStream, err := v2crypto.NewAesDecryptionStream(userObj.ID.CmdKey(), iv)
	if err != nil {
		log.Debug("VMess: Failed to create AES stream: ", err)
		return nil, err
	}

	decryptor := v2crypto.NewCryptionReader(aesStream, reader)

	nBytes, err = io.ReadFull(decryptor, buffer.Value[:41])
	if err != nil {
		log.Debug("VMess: Failed to read request header (", nBytes, " bytes): ", err)
		return nil, err
	}
	bufferLen := nBytes

	request := &VMessRequest{
		User:    userObj,
		Version: buffer.Value[0],
	}

	if request.Version != Version {
		log.Warning("VMess: Invalid protocol version ", request.Version)
		return nil, proxy.ErrorInvalidProtocolVersion
	}

	request.RequestIV = append([]byte(nil), buffer.Value[1:17]...)   // 16 bytes
	request.RequestKey = append([]byte(nil), buffer.Value[17:33]...) // 16 bytes
	request.ResponseHeader = buffer.Value[33]                        // 1 byte
	request.Option = buffer.Value[34]                                // 1 byte + 2 bytes reserved
	request.Command = buffer.Value[37]

	request.Port = v2net.PortFromBytes(buffer.Value[38:40])

	switch buffer.Value[40] {
	case addrTypeIPv4:
		nBytes, err = io.ReadFull(decryptor, buffer.Value[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.Value[41:45])
	case addrTypeIPv6:
		nBytes, err = io.ReadFull(decryptor, buffer.Value[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.Value[41:57])
	case addrTypeDomain:
		nBytes, err = io.ReadFull(decryptor, buffer.Value[41:42])
		if err != nil {
			log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err)
			return nil, err
		}
		domainLength := int(buffer.Value[41])
		if domainLength == 0 {
			return nil, transport.ErrorCorruptedPacket
		}
		nBytes, err = io.ReadFull(decryptor, buffer.Value[42:42+domainLength])
		if err != nil {
			log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err)
			return nil, err
		}
		bufferLen += 1 + domainLength
		domainBytes := append([]byte(nil), buffer.Value[42:42+domainLength]...)
		request.Address = v2net.DomainAddress(string(domainBytes))
	}

	nBytes, err = io.ReadFull(decryptor, buffer.Value[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.Value[:bufferLen])
	actualHash := fnv1a.Sum32()
	expectedHash := binary.BigEndian.Uint32(buffer.Value[bufferLen : bufferLen+4])

	if actualHash != expectedHash {
		return nil, transport.ErrorCorruptedPacket
	}

	return request, nil
}
Пример #10
0
// Read reads a VMessRequest from a byte stream.
func (this *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
	buffer := alloc.NewSmallBuffer()

	nBytes, err := v2net.ReadAllBytes(reader, buffer.Value[:config.IDBytesLen])
	if err != nil {
		return nil, err
	}

	userObj, timeSec, valid := this.vUserSet.GetUser(buffer.Value[:nBytes])
	if !valid {
		return nil, proxyerrors.InvalidAuthentication
	}

	aesStream, err := v2crypto.NewAesDecryptionStream(userObj.ID().CmdKey(), user.Int64Hash(timeSec))
	if err != nil {
		return nil, err
	}

	decryptor := v2crypto.NewCryptionReader(aesStream, reader)

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

	request := &VMessRequest{
		User:    userObj,
		Version: buffer.Value[0],
	}

	if request.Version != Version {
		log.Warning("Invalid protocol version %d", request.Version)
		return nil, proxyerrors.InvalidProtocolVersion
	}

	request.RequestIV = buffer.Value[1:17]       // 16 bytes
	request.RequestKey = buffer.Value[17:33]     // 16 bytes
	request.ResponseHeader = buffer.Value[33:37] // 4 bytes
	request.Command = buffer.Value[37]

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

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

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

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

	if actualHash != expectedHash {
		return nil, transport.CorruptedPacket
	}

	return request, nil
}
Пример #11
0
func (this *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) {
	buffer := alloc.NewSmallBuffer()
	defer buffer.Release()

	_, err := io.ReadFull(reader, buffer.Value[:protocol.IDBytesLen])
	if err != nil {
		log.Error("Raw: Failed to read request header: ", err)
		return nil, err
	}

	user, timestamp, valid := this.userValidator.Get(buffer.Value[:protocol.IDBytesLen])
	if !valid {
		return nil, protocol.ErrorInvalidUser
	}

	timestampHash := md5.New()
	timestampHash.Write(hashTimestamp(timestamp))
	iv := timestampHash.Sum(nil)
	aesStream := crypto.NewAesDecryptionStream(user.ID.CmdKey(), iv)
	decryptor := crypto.NewCryptionReader(aesStream, reader)

	nBytes, err := io.ReadFull(decryptor, buffer.Value[: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.Value[0],
	}

	if request.Version != Version {
		log.Warning("Raw: Invalid protocol version ", request.Version)
		return nil, protocol.ErrorInvalidVersion
	}

	this.requestBodyIV = append([]byte(nil), buffer.Value[1:17]...)   // 16 bytes
	this.requestBodyKey = append([]byte(nil), buffer.Value[17:33]...) // 16 bytes
	this.responseHeader = buffer.Value[33]                            // 1 byte
	request.Option = protocol.RequestOption(buffer.Value[34])         // 1 byte + 2 bytes reserved
	request.Command = protocol.RequestCommand(buffer.Value[37])

	request.Port = v2net.PortFromBytes(buffer.Value[38:40])

	switch buffer.Value[40] {
	case AddrTypeIPv4:
		nBytes, err = io.ReadFull(decryptor, buffer.Value[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.Value[41:45])
	case AddrTypeIPv6:
		nBytes, err = io.ReadFull(decryptor, buffer.Value[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.Value[41:57])
	case AddrTypeDomain:
		nBytes, err = io.ReadFull(decryptor, buffer.Value[41:42])
		if err != nil {
			log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err)
			return nil, err
		}
		domainLength := int(buffer.Value[41])
		if domainLength == 0 {
			return nil, transport.ErrorCorruptedPacket
		}
		nBytes, err = io.ReadFull(decryptor, buffer.Value[42:42+domainLength])
		if err != nil {
			log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err)
			return nil, err
		}
		bufferLen += 1 + domainLength
		domainBytes := append([]byte(nil), buffer.Value[42:42+domainLength]...)
		request.Address = v2net.DomainAddress(string(domainBytes))
	}

	nBytes, err = io.ReadFull(decryptor, buffer.Value[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.Value[:bufferLen])
	actualHash := fnv1a.Sum32()
	expectedHash := serial.BytesLiteral(buffer.Value[bufferLen : bufferLen+4]).Uint32Value()

	if actualHash != expectedHash {
		return nil, transport.ErrorCorruptedPacket
	}

	return request, nil
}
Пример #12
0
func (this *ServerSession) DecodeRequestBody(reader io.Reader) io.Reader {
	aesStream := crypto.NewAesDecryptionStream(this.requestBodyKey, this.requestBodyIV)
	return crypto.NewCryptionReader(aesStream, reader)
}
Пример #13
0
func (this *AesCfb) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
	stream := crypto.NewAesDecryptionStream(key, iv)
	return stream, nil
}