Пример #1
0
func ReadUserPassRequest(reader io.Reader) (request Socks5UserPassRequest, err error) {
	buffer := buf.NewLocal(512)
	defer buffer.Release()

	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 2))
	if err != nil {
		return
	}
	request.version = buffer.Byte(0)
	nUsername := int(buffer.Byte(1))

	buffer.Clear()
	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, nUsername))
	if err != nil {
		return
	}
	request.username = buffer.String()

	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 1))
	if err != nil {
		return
	}
	nPassword := int(buffer.Byte(0))
	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, nPassword))
	if err != nil {
		return
	}
	request.password = buffer.String()
	return
}
Пример #2
0
func (v *ChunkReader) Read() (*buf.Buffer, error) {
	buffer := buf.New()
	if err := buffer.AppendSupplier(buf.ReadFullFrom(v.reader, 2)); err != nil {
		buffer.Release()
		return nil, err
	}
	// There is a potential buffer overflow here. Large buffer is 64K bytes,
	// while uin16 + 10 will be more than that
	length := serial.BytesToUint16(buffer.BytesTo(2)) + AuthSize
	if length > buf.Size {
		// Theoretically the size of a chunk is 64K, but most Shadowsocks implementations used <4K buffer.
		buffer.Release()
		buffer = buf.NewLocal(int(length) + 128)
	}

	buffer.Clear()
	if err := buffer.AppendSupplier(buf.ReadFullFrom(v.reader, int(length))); err != nil {
		buffer.Release()
		return nil, err
	}

	authBytes := buffer.BytesTo(AuthSize)
	payload := buffer.BytesFrom(AuthSize)

	actualAuthBytes := make([]byte, AuthSize)
	v.auth.Authenticate(payload)(actualAuthBytes)
	if !bytes.Equal(authBytes, actualAuthBytes) {
		buffer.Release()
		return nil, errors.New("Shadowsocks|AuthenticationReader: Invalid auth.")
	}
	buffer.SliceFrom(AuthSize)

	return buffer, nil
}
Пример #3
0
func readUsernamePassword(reader io.Reader) (string, string, error) {
	buffer := buf.NewLocal(512)
	defer buffer.Release()

	if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
		return "", "", err
	}
	nUsername := int(buffer.Byte(1))

	buffer.Clear()
	if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nUsername)); err != nil {
		return "", "", err
	}
	username := buffer.String()
	buffer.Clear()

	if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil {
		return "", "", err
	}
	nPassword := int(buffer.Byte(0))
	buffer.Clear()
	if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nPassword)); err != nil {
		return "", "", err
	}
	password := buffer.String()
	return username, password, nil
}
Пример #4
0
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
}
Пример #5
0
func EncodeUDPPacket(request *protocol.RequestHeader, payload *buf.Buffer) (*buf.Buffer, error) {
	user := request.User
	rawAccount, err := user.GetTypedAccount()
	if err != nil {
		return nil, errors.Base(err).Message("Shadowsocks|UDP: Failed to parse account.")
	}
	account := rawAccount.(*ShadowsocksAccount)

	buffer := buf.NewSmall()
	ivLen := account.Cipher.IVSize()
	buffer.AppendSupplier(buf.ReadFullFrom(rand.Reader, ivLen))
	iv := buffer.Bytes()

	switch request.Address.Family() {
	case v2net.AddressFamilyIPv4:
		buffer.AppendBytes(AddrTypeIPv4)
		buffer.Append([]byte(request.Address.IP()))
	case v2net.AddressFamilyIPv6:
		buffer.AppendBytes(AddrTypeIPv6)
		buffer.Append([]byte(request.Address.IP()))
	case v2net.AddressFamilyDomain:
		buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain())))
		buffer.Append([]byte(request.Address.Domain()))
	default:
		return nil, errors.New("Shadowsocks|UDP: Unsupported address type: ", request.Address.Family())
	}

	buffer.AppendSupplier(serial.WriteUint16(uint16(request.Port)))
	buffer.Append(payload.Bytes())

	if request.Option.Has(RequestOptionOneTimeAuth) {
		authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
		buffer.SetByte(ivLen, buffer.Byte(ivLen)|0x10)

		buffer.AppendSupplier(authenticator.Authenticate(buffer.BytesFrom(ivLen)))
	}

	stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
	if err != nil {
		return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to create encoding stream.")
	}

	stream.XORKeyStream(buffer.BytesFrom(ivLen), buffer.BytesFrom(ivLen))
	return buffer, nil
}
Пример #6
0
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
}
Пример #7
0
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)
}
Пример #8
0
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
}