Skip to content

Commit

Permalink
add Login packets
Browse files Browse the repository at this point in the history
  • Loading branch information
zyxkad committed Oct 18, 2023
1 parent 096ef7a commit a918c00
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 18 deletions.
4 changes: 2 additions & 2 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ A Minecraft proxy that can extended with JavaScript.

## Applications

[liter-proxy](./cmds/liter-proxy/README.MD): The minecraft forward proxy which support socks5
[liter-server](./cmds/liter-server/README.MD): The minecraft reverse proxy with a simple manage dashboard
- [liter-proxy](./cmds/liter-proxy/README.MD): The minecraft forward proxy which support socks5
- [liter-server](./cmds/liter-server/README.MD): The minecraft reverse proxy with a simple manage dashboard
11 changes: 8 additions & 3 deletions cmds/liter-server/api_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ func registerPlayerAPI(s *Server, g *gin.RouterGroup){
ctx.Next()
})
gu.GET("/head", func(ctx *gin.Context){
ctx.Header("Cache-Control", "no-cache")
uid := ctx.Value(uuidKey).(uuid.UUID)
profile, err := AuthClient.GetPlayerProfile(uid)
if err != nil {
Expand Down Expand Up @@ -511,9 +512,9 @@ func registerPlayerAPI(s *Server, g *gin.RouterGroup){
func registerStatus(s *Server, g *gin.RouterGroup){
g.GET("/conns", func(ctx *gin.Context){
type resT struct {
Id int `json:"id"`
Addr string `json:"addr"`
When int64 `json:"when"`
Id int `json:"id"`
Addr string `json:"addr"`
When int64 `json:"when"`
LocalAddr string `json:"localAddr"`
Server string `json:"server"`
Player *liter.PlayerInfo `json:"player,omitempty"`
Expand All @@ -536,6 +537,10 @@ func registerStatus(s *Server, g *gin.RouterGroup){
})
})
ctx.Header("Last-Modified", lm)
if lm2 := ctx.GetHeader("Last-Modified"); len(lm2) != 0 && lm2 == lm {
ctx.Status(http.StatusNotModified)
return
}
ctx.JSON(http.StatusOK, gin.H{
"status": "ok",
"data": data,
Expand Down
2 changes: 1 addition & 1 deletion cmds/liter-server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (s *Server)handle(c *liter.Conn, cfg *Config){
c0.SetLocalServer(hp.Addr, svr.Id)
ploger.Infof("Connected with address [%s:%d], passing to server %q[%s]", hp.Addr, hp.Port, svr.Id, svr.Target)

var lp liter.LoginStartPacket
var lp liter.LoginStartPkt

if isPing {
if svr.HandlePing {
Expand Down
11 changes: 10 additions & 1 deletion cmds/liter-server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package main

import (
"context"
crand "crypto/rand"
"crypto/rsa"
"errors"
"net"
"net/http"
Expand Down Expand Up @@ -52,6 +54,7 @@ type Server struct{
scripts *script.Manager
handler http.Handler
users *UserStorage
rsaKey *rsa.PrivateKey

inShutdown atomic.Bool
mux sync.Mutex
Expand All @@ -64,8 +67,14 @@ func NewServer(sm *script.Manager)(s *Server){
scripts: sm,
users: NewUserStorage(filepath.Join(configDir, "users.json")),
}
var err error

if s.rsaKey, err = rsa.GenerateKey(crand.Reader, 1024); err != nil {
loger.Fatalf("Cannot generate RSA key: %v", err)
}

s.initHandler()
if err := s.users.Load(); errors.Is(err, os.ErrNotExist) {
if err = s.users.Load(); errors.Is(err, os.ErrNotExist) {
s.users.Save()
}
return
Expand Down
160 changes: 151 additions & 9 deletions preset_packets.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
package liter

import (
"strings"
"crypto/rsa"
"crypto/x509"
"fmt"
"io"
"strings"
)

const (
Expand Down Expand Up @@ -61,6 +63,9 @@ func (p *HandshakePkt)Decode(r *PacketReader)(err error){
return
}

////////////////////////////
//// BEGIN PING PACKETS ////
////////////////////////////

type StatusRequestPkt struct{}

Expand Down Expand Up @@ -160,6 +165,13 @@ func (p *PingResponsePkt)DecodeFrom(r *PacketReader)(err error){
return
}

/////////////////////////////
//// BEGIN LOGIN PACKETS ////
/////////////////////////////

// See: https://wiki.vg/Protocol#Login
// See: https://wiki.vg/Protocol_Encryption

type DisconnectPkt struct {
Reason *Chat
}
Expand All @@ -177,8 +189,7 @@ func (p *DisconnectPkt)DecodeFrom(r *PacketReader)(err error){
return
}


type LoginStartPacket struct {
type LoginStartPkt struct {
Name string

// if protocol >= 1.19 && protocol <= 1.19.2
Expand All @@ -191,16 +202,16 @@ type LoginStartPacket struct {
Id Optional[UUID]
}

var _ Packet = (*LoginStartPacket)(nil)
var _ Packet = (*LoginStartPkt)(nil)

func (p LoginStartPacket)String()(string){
func (p LoginStartPkt)String()(string){
if p.Id.Ok {
return fmt.Sprintf("<LoginStartPacket name=%s uuid=%v>", p.Name, p.Id.V)
return fmt.Sprintf("<LoginStartPkt name=%s uuid=%v>", p.Name, p.Id.V)
}
return fmt.Sprintf("<LoginStartPacket name=%s>", p.Name)
return fmt.Sprintf("<LoginStartPkt name=%s>", p.Name)
}

func (p LoginStartPacket)Encode(b *PacketBuilder){
func (p LoginStartPkt)Encode(b *PacketBuilder){
protocol := b.Protocol()
b.String(p.Name)
if protocol >= V1_19 {
Expand All @@ -224,7 +235,7 @@ func (p LoginStartPacket)Encode(b *PacketBuilder){
}
}

func (p *LoginStartPacket)DecodeFrom(r *PacketReader)(err error){
func (p *LoginStartPkt)DecodeFrom(r *PacketReader)(err error){
protocol := r.Protocol()
var ok bool
if p.Name, ok = r.String(); !ok {
Expand Down Expand Up @@ -269,3 +280,134 @@ func (p *LoginStartPacket)DecodeFrom(r *PacketReader)(err error){
}
return
}

type LoginEncryptionRequestPkt struct {
ServerID string // Appears to be empty.
PublicKey *rsa.PublicKey // encoded in ASN.1 DER format
/* A sequence of random bytes generated by the server.
* Length of Verify Token is always 4 for Notchian servers. */
VerifyToken ByteArray
}

var _ Packet = (*LoginEncryptionRequestPkt)(nil)

func (p LoginEncryptionRequestPkt)Encode(b *PacketBuilder){
b.String(p.ServerID)
pubKey, _ := x509.MarshalPKIXPublicKey(p.PublicKey)
b.VarInt((VarInt)(len(pubKey)))
b.ByteArray(pubKey)
b.VarInt((VarInt)(len(p.VerifyToken)))
b.ByteArray(p.VerifyToken)
}

func (p *LoginEncryptionRequestPkt)DecodeFrom(r *PacketReader)(err error){
var ok bool
var n VarInt
if p.ServerID, ok = r.String(); !ok {
return io.EOF
}
if n, ok = r.VarInt(); !ok {
return io.EOF
}
pubKey := make(ByteArray, n)
if ok = r.ByteArray(pubKey); !ok {
return io.EOF
}
var key any
if key, err = x509.ParsePKIXPublicKey(pubKey); err != nil {
return
}
if p.PublicKey, ok = key.(*rsa.PublicKey); !ok {
return fmt.Errorf("Unexpected public key type %T when parsing login encryption request", key)
}
if n, ok = r.VarInt(); !ok {
return io.EOF
}
p.VerifyToken = make(ByteArray, n)
if ok = r.ByteArray(p.VerifyToken); !ok {
return io.EOF
}
return
}

type LoginEncryptionResponsePkt struct {
SharedSecret ByteArray // Shared Secret value, encrypted with the server's public key.
VerifyToken ByteArray // Verify Token value, encrypted with the same public key as the shared secret.
}

var _ Packet = (*LoginEncryptionResponsePkt)(nil)

func (p LoginEncryptionResponsePkt)Encode(b *PacketBuilder){
b.VarInt((VarInt)(len(p.SharedSecret)))
b.ByteArray(p.SharedSecret)
b.VarInt((VarInt)(len(p.VerifyToken)))
b.ByteArray(p.VerifyToken)
}

func (p *LoginEncryptionResponsePkt)DecodeFrom(r *PacketReader)(err error){
var ok bool
var n VarInt
if n, ok = r.VarInt(); !ok {
return io.EOF
}
p.SharedSecret = make(ByteArray, n)
if ok = r.ByteArray(p.SharedSecret); !ok {
return io.EOF
}
if n, ok = r.VarInt(); !ok {
return io.EOF
}
p.VerifyToken = make(ByteArray, n)
if ok = r.ByteArray(p.VerifyToken); !ok {
return io.EOF
}
return
}

type LoginSuccessPkt struct {
UUID UUID
Username string
Properties []*Property
}

var _ Packet = (*LoginSuccessPkt)(nil)

func (p *LoginSuccessPkt)Encode(b *PacketBuilder){
b.UUID(p.UUID)
b.String(p.Username)
b.VarInt((VarInt)(len(p.Properties)))
for _, v := range p.Properties {
v.Encode(b)
}
}

func (p *LoginSuccessPkt)DecodeFrom(r *PacketReader)(err error){
var ok bool
if p.UUID, ok = r.UUID(); !ok {
return io.EOF
}
if p.Username, ok = r.String(); !ok {
return io.EOF
}
var n VarInt
if n, ok = r.VarInt(); !ok {
return io.EOF
}
p.Properties = make([]*Property, n)
for i, _ := range p.Properties {
v := new(Property)
if err = v.DecodeFrom(r); err != nil {
return
}
p.Properties[i] = v
}
return
}

type LoginAcknowledgedPkt struct{}

var _ Packet = (*LoginAcknowledgedPkt)(nil)

func (p LoginAcknowledgedPkt)String()(string){ return "<LoginAcknowledgedPkt>" }
func (p LoginAcknowledgedPkt)Encode(b *PacketBuilder){}
func (p *LoginAcknowledgedPkt)DecodeFrom(r *PacketReader)(err error){ return }
38 changes: 36 additions & 2 deletions profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (
"image"
"image/color"
"image/png"
"io"
"net/http"
"sync"
)

type Property struct {
Name string `json:"name"`
Value string `json:"value"`
Sign string `json:"signature,omitempty"`
}

func (p *Property)UnmarshalJSONValue(ptr any)(err error){
Expand All @@ -25,11 +27,43 @@ func (p *Property)UnmarshalJSONValue(ptr any)(err error){
return json.Unmarshal(buf, ptr)
}

func (p *Property)Encode(b *PacketBuilder){
b.String(p.Name)
b.String(p.Value)
hasSign := len(p.Sign) > 0
b.Bool(hasSign)
if hasSign {
b.String(p.Sign)
}
}

func (p *Property)DecodeFrom(r *PacketReader)(err error){
var ok bool
if p.Name, ok = r.String(); !ok {
return io.EOF
}
if p.Value, ok = r.String(); !ok {
return io.EOF
}
var hasSign bool
if hasSign, ok = r.Bool(); !ok {
return io.EOF
}
if hasSign {
if p.Sign, ok = r.String(); !ok {
return io.EOF
}
}else{
p.Sign = ""
}
return
}

type PlayerProfile struct {
Id UUID `json:"id"`
Id UUID `json:"id"`
Name string `json:"name"`
Properties []*Property `json:"properties`
ProfileActions []string `json:"profileActions"`
ProfileActions []string `json:"profileActions"`
}

func (p *PlayerProfile)GetProp(name string)(t *Property){
Expand Down

0 comments on commit a918c00

Please sign in to comment.