Handle truncated start login frame (#400)
This commit is contained in:
+2
-2
@@ -55,12 +55,12 @@ func DecodeLoginStart(data interface{}) (*LoginStart, error) {
|
|||||||
|
|
||||||
loginStart.Name, err = ReadString(buffer)
|
loginStart.Name, err = ReadString(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to read username")
|
return loginStart, errors.Wrap(err, "failed to read username")
|
||||||
}
|
}
|
||||||
|
|
||||||
loginStart.PlayerUuid, err = ReadUuid(buffer)
|
loginStart.PlayerUuid, err = ReadUuid(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to read player uuid")
|
return loginStart, errors.Wrap(err, "failed to read player uuid")
|
||||||
}
|
}
|
||||||
|
|
||||||
return loginStart, nil
|
return loginStart, nil
|
||||||
|
|||||||
+4
-2
@@ -1,3 +1,5 @@
|
|||||||
|
// Package mcproto provides functions to read types and decode frames declared
|
||||||
|
// at https://minecraft.wiki/w/Java_Edition_protocol
|
||||||
package mcproto
|
package mcproto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -27,7 +29,7 @@ const MaxFrameLength = 2097151
|
|||||||
func ReadPacket(reader *bufio.Reader, addr net.Addr, state State) (*Packet, error) {
|
func ReadPacket(reader *bufio.Reader, addr net.Addr, state State) (*Packet, error) {
|
||||||
logrus.
|
logrus.
|
||||||
WithField("client", addr).
|
WithField("client", addr).
|
||||||
Debug("Reading packet")
|
Trace("Reading packet")
|
||||||
|
|
||||||
if state == StateHandshaking {
|
if state == StateHandshaking {
|
||||||
data, err := reader.Peek(1)
|
data, err := reader.Peek(1)
|
||||||
@@ -158,7 +160,7 @@ func ReadUTF16BEString(reader io.Reader, symbolLen uint16) (string, error) {
|
|||||||
func ReadFrame(reader io.Reader, addr net.Addr) (*Frame, error) {
|
func ReadFrame(reader io.Reader, addr net.Addr) (*Frame, error) {
|
||||||
logrus.
|
logrus.
|
||||||
WithField("client", addr).
|
WithField("client", addr).
|
||||||
Debug("Reading frame")
|
Trace("Reading frame")
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
frame := &Frame{}
|
frame := &Frame{}
|
||||||
|
|||||||
+18
-9
@@ -4,6 +4,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"io"
|
"io"
|
||||||
@@ -227,7 +228,7 @@ func (c *Connector) HandleConnection(ctx context.Context, frontendConn net.Conn)
|
|||||||
|
|
||||||
logrus.
|
logrus.
|
||||||
WithField("client", clientAddr).
|
WithField("client", clientAddr).
|
||||||
Info("Got connection")
|
Debug("Got connection")
|
||||||
defer logrus.WithField("client", clientAddr).Debug("Closing frontend connection")
|
defer logrus.WithField("client", clientAddr).Debug("Closing frontend connection")
|
||||||
|
|
||||||
// Tee-off the inspected content to a buffer so that we can retransmit it to the backend connection
|
// Tee-off the inspected content to a buffer so that we can retransmit it to the backend connection
|
||||||
@@ -273,14 +274,22 @@ func (c *Connector) HandleConnection(ctx context.Context, frontendConn net.Conn)
|
|||||||
|
|
||||||
var playerInfo *PlayerInfo = nil
|
var playerInfo *PlayerInfo = nil
|
||||||
if handshake.NextState == mcproto.StateLogin {
|
if handshake.NextState == mcproto.StateLogin {
|
||||||
playerInfo, err = c.readUserInfo(bufferedReader, clientAddr, handshake.NextState)
|
playerInfo, err = c.readPlayerInfo(bufferedReader, clientAddr, handshake.NextState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.
|
if errors.Is(err, io.EOF) {
|
||||||
WithError(err).
|
logrus.
|
||||||
WithField("clientAddr", clientAddr).
|
WithError(err).
|
||||||
Error("Failed to read user info")
|
WithField("clientAddr", clientAddr).
|
||||||
c.metrics.Errors.With("type", "read").Add(1)
|
WithField("player", playerInfo).
|
||||||
return
|
Warn("Truncated buffer while reading player info")
|
||||||
|
} else {
|
||||||
|
logrus.
|
||||||
|
WithError(err).
|
||||||
|
WithField("clientAddr", clientAddr).
|
||||||
|
Error("Failed to read user info")
|
||||||
|
c.metrics.Errors.With("type", "read").Add(1)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
logrus.
|
logrus.
|
||||||
WithField("client", clientAddr).
|
WithField("client", clientAddr).
|
||||||
@@ -319,7 +328,7 @@ func (c *Connector) HandleConnection(ctx context.Context, frontendConn net.Conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Connector) readUserInfo(bufferedReader *bufio.Reader, clientAddr net.Addr, state mcproto.State) (*PlayerInfo, error) {
|
func (c *Connector) readPlayerInfo(bufferedReader *bufio.Reader, clientAddr net.Addr, state mcproto.State) (*PlayerInfo, error) {
|
||||||
loginPacket, err := mcproto.ReadPacket(bufferedReader, clientAddr, state)
|
loginPacket, err := mcproto.ReadPacket(bufferedReader, clientAddr, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read login packet: %w", err)
|
return nil, fmt.Errorf("failed to read login packet: %w", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user