Initial Commit

Signed-off-by: jolheiser <john.olheiser@gmail.com>
main
jolheiser 2021-12-06 16:43:07 -06:00
parent 6155f28671
commit eb9162d44b
Signed by: jolheiser
GPG Key ID: B853ADA5DA7BBF7A
7 changed files with 153 additions and 33 deletions

View File

@ -1,4 +1,4 @@
Copyright 2020 Etzelia
Copyright 2021 John Olheiser
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

67
_hooks/mcm/mcm.go 100644
View File

@ -0,0 +1,67 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"net/http"
"net/url"
"os"
"strings"
"github.com/peterbourgon/ff/v3"
)
type profile struct {
ID string `json:"id"`
Name string `json:"name"`
IP string `json:"ip"`
}
func (p *profile) UUID() string {
return fmt.Sprintf("%s-%s-%s-%s-%s", p.ID[:8], p.ID[8:12], p.ID[12:16], p.ID[16:20], p.ID[20:32])
}
func main() {
fs := flag.NewFlagSet("mcm", flag.ExitOnError)
baseFlag := fs.String("base", "", "Base URL for MCM API")
tokenFlag := fs.String("token", "", "MCM API Token")
if err := ff.Parse(fs, os.Args[1:],
ff.WithEnvVarPrefix("MCM_REGISTER"),
); err != nil {
panic(err)
}
var profile profile
if err := json.NewDecoder(os.Stdin).Decode(&profile); err != nil {
panic(err)
}
baseURL := strings.TrimSuffix(*baseFlag, "/")
u := fmt.Sprintf("%s/plugin/register", baseURL)
resp, err := http.PostForm(u, url.Values{
"api": []string{*tokenFlag},
"uuid": []string{profile.UUID()},
"username": []string{profile.Name},
"ip": []string{profile.IP},
})
if err != nil {
panic(err)
}
if resp.StatusCode != 200 {
panic("invalid response from MCM")
}
s := struct {
Status bool `json:"status"`
Message string `json:"message"`
}{}
if err := json.NewDecoder(resp.Body).Decode(&s); err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(s.Message)
}

4
go.mod
View File

@ -1,4 +1,4 @@
module git.canopymc.net/Etzelia/mineauth
module git.jojodev.com/Canopy/mineauth
go 1.16
@ -6,5 +6,5 @@ require (
github.com/Tnze/go-mc v1.17.1-0.20210806203433-99081e1b9cfb
github.com/google/uuid v1.1.1
github.com/peterbourgon/ff/v3 v3.1.0
go.jolheiser.com/beaver v1.1.2
github.com/rs/zerolog v1.26.0
)

33
go.sum
View File

@ -2,8 +2,10 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Tnze/go-mc v1.17.1-0.20210806203433-99081e1b9cfb h1:jf5lM8mkIpYLFF2cORRGYVK9Mv/xuomG1hmR0b4EzXU=
github.com/Tnze/go-mc v1.17.1-0.20210806203433-99081e1b9cfb/go.mod h1:t0AI38F1BEmmy8/uLhr9RCOUeDbBj3oUNQH9akjzMc0=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/iancoleman/strcase v0.1.3 h1:dJBk1m2/qjL1twPLf68JND55vvivMupZ4wIzE8CTdBw=
@ -14,12 +16,35 @@ github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzI
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
github.com/peterbourgon/ff/v3 v3.1.0 h1:5JAeDK5j/zhKFjyHEZQXwXBoDijERaos10RE+xamOsY=
github.com/peterbourgon/ff/v3 v3.1.0/go.mod h1:XNJLY8EIl6MjMVjBS4F0+G0LYoAqs0DTa4rmHHukKDE=
go.jolheiser.com/beaver v1.1.2 h1:X8voMSTy+8QUFzHlvG89EUVZY/xPQe6fQLVjUPjTvWY=
go.jolheiser.com/beaver v1.1.2/go.mod h1:7X4F5+XOGSC3LejTShoBdqtRCnPWcnRgmYGmG3EKW8g=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.26.0 h1:ORM4ibhEZeTeQlCojCK2kPz1ogAY4bGs4tD+SaAdGaE=
github.com/rs/zerolog v1.26.0/go.mod h1:yBiM87lvSqX8h0Ww4sdzNSkVYZ8dL2xjZJG1lAuGZEo=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

26
main.go
View File

@ -2,14 +2,16 @@ package main
import (
"flag"
"git.canopymc.net/Etzelia/mineauth/server"
"net/http"
"os"
"time"
"git.jojodev.com/Canopy/mineauth/server"
"github.com/peterbourgon/ff/v3"
"github.com/peterbourgon/ff/v3/fftoml"
"go.jolheiser.com/beaver"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
@ -18,23 +20,30 @@ func main() {
timeoutFlag := fs.Int("timeout", 15, "HTTP timeout")
pingMessageFlag := fs.String("ping", "Login to authenticate!", "Message for the server list")
communityFlag := fs.String("community", "", "URL to community")
faviconFlag := fs.String("favicon", "", "Path to a favicon image for server list ping")
hooksFlag := make([]string, 0)
fs.Func("hook", "Hook to run", func(hook string) error {
hooksFlag = append(hooksFlag, hook)
return nil
})
debugFlag := fs.Bool("debug", false, "Debug Logging")
jsonFlag := fs.Bool("json", false, "JSON Logging")
if err := ff.Parse(fs, os.Args[1:],
ff.WithEnvVarPrefix("MCM_REGISTER"),
ff.WithEnvVarPrefix("MINEAUTH"),
ff.WithConfigFileFlag("config"),
ff.WithAllowMissingConfigFile(true),
ff.WithConfigFileParser(fftoml.New().Parse),
); err != nil {
beaver.Fatal(err)
panic(err)
return
}
if *debugFlag {
beaver.Console.Level = beaver.DEBUG
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
if !*jsonFlag {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout})
}
http.DefaultClient.Timeout = time.Second * time.Duration(*timeoutFlag)
@ -42,15 +51,16 @@ func main() {
serv, err := server.New(server.Options{
PingMessage: *pingMessageFlag,
CommunityURL: *communityFlag,
FaviconPath: *faviconFlag,
Hooks: hooksFlag,
})
if err != nil {
beaver.Error(err)
log.Err(err).Msg("")
return
}
beaver.Infof("Listening on http://localhost:%d", *portFlag)
log.Info().Msgf("Listening on http://localhost:%d", *portFlag)
if err := serv.Start(*portFlag); err != nil {
beaver.Error(err)
log.Err(err).Msg("")
}
}

View File

@ -10,7 +10,7 @@ import (
"github.com/Tnze/go-mc/net"
pk "github.com/Tnze/go-mc/net/packet"
"github.com/google/uuid"
"go.jolheiser.com/beaver"
"github.com/rs/zerolog/log"
)
func (s *Server) acceptListPing(conn net.Conn) {
@ -64,7 +64,7 @@ func (s *Server) listResp() string {
data, err := json.Marshal(list)
if err != nil {
beaver.Errorf("could not marshal JSON: %v", err)
log.Err(err).Msg("could not marshal JSON")
}
return string(data)
}

View File

@ -8,14 +8,17 @@ import (
_ "embed"
"encoding/json"
"fmt"
"io"
gonet "net"
"os"
"os/exec"
"strings"
"github.com/Tnze/go-mc/chat"
"github.com/Tnze/go-mc/net"
pk "github.com/Tnze/go-mc/net/packet"
"github.com/google/uuid"
"go.jolheiser.com/beaver"
gonet "net"
"os/exec"
"strings"
"github.com/rs/zerolog/log"
)
//go:embed favicon.png
@ -24,12 +27,14 @@ var favicon []byte
type Server struct {
privateKey *rsa.PrivateKey
publicKey []byte
favicon []byte
opts Options
}
type Options struct {
CommunityURL string
PingMessage string
FaviconPath string
Hooks []string
}
@ -46,9 +51,23 @@ func New(opts Options) (*Server, error) {
private.Precompute()
icon := favicon
if opts.FaviconPath != "" {
fi, err := os.Open(opts.FaviconPath)
if err != nil {
return nil, err
}
defer fi.Close()
icon, err = io.ReadAll(fi)
if err != nil {
return nil, err
}
}
return &Server{
privateKey: private,
publicKey: public,
favicon: icon,
opts: opts,
}, nil
}
@ -62,7 +81,7 @@ func (s *Server) Start(port int) error {
for {
conn, err := l.Accept()
if err != nil {
beaver.Errorf("Accept error: %v", err)
log.Err(err).Msg("accept error")
}
go s.acceptConn(conn)
}
@ -73,13 +92,13 @@ func (s *Server) acceptConn(conn net.Conn) {
// handshake
_, intention, err := s.handshake(conn)
if err != nil {
beaver.Errorf("Handshake error: %v", err)
log.Err(err).Msg("handshake error")
return
}
switch intention {
default:
beaver.Errorf("Unknown handshake intention: %v", intention)
log.Err(err).Msg("unknown handshake intention")
case 1:
s.acceptListPing(conn)
case 2:
@ -90,31 +109,31 @@ func (s *Server) acceptConn(conn net.Conn) {
func (s *Server) handlePlaying(conn net.Conn) {
info, err := s.acceptLogin(conn)
if err != nil {
beaver.Errorf("login failed: %v", err)
log.Err(err).Msg("login failed")
return
}
verify, err := s.encryptionRequest(conn)
if err != nil {
beaver.Errorf("could not send encryption request: %v", err)
log.Err(err).Msg("could not send encryption request")
return
}
profile, secret, err := s.encryptionResponse(conn, info.Name, verify)
if err != nil {
beaver.Errorf("could not get encryption response: %v", err)
log.Err(err).Msg("could not get encryption response")
return
}
profile.IP, _, err = gonet.SplitHostPort(conn.Socket.RemoteAddr().String())
if err != nil {
beaver.Errorf("could not get user IP: %v", err)
log.Err(err).Msg("could not get user IP")
return
}
payload, err := json.Marshal(profile)
if err != nil {
beaver.Errorf("could not marshal payload: %v", err)
log.Err(err).Msg("could not marshal payload")
return
}
@ -129,15 +148,14 @@ func (s *Server) handlePlaying(conn net.Conn) {
cmd.Stdin = bytes.NewReader(payload)
out, err := cmd.CombinedOutput()
if err != nil {
beaver.Errorf("could not run hook `%s`: %v", h, err)
beaver.Warn(string(out))
log.Err(err).Str("hook", h).Str("output", string(out)).Msg("could not run hook")
}
}(hook)
}
econn, err := encryptedConn(conn, secret)
if err != nil {
beaver.Errorf("could not create encrypted connection: %v", err)
log.Err(err).Msg("could not create encrypted connection")
return
}
@ -149,7 +167,7 @@ func (s *Server) handlePlaying(conn net.Conn) {
chat.Message{Text: msg},
)
if err := packet.Pack(econn, 0); err != nil {
beaver.Errorf("could not disconnect player: %v", err)
log.Err(err).Msg("could not disconnect player")
}
}