From 6b1e90ecee9dc745ce94f5bdfdfb8715f8f89738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=92=9F=E8=92=BB?= Date: Sun, 30 Apr 2023 00:30:13 +0800 Subject: [PATCH] Support the session-server/auth-server mode --- GMMAuth/auth.go | 9 +- accounts.example.txt | 2 +- go.mod | 25 +++- go.sum | 70 +++++++++- main.go | 303 +++++++++++++++++++++++++++++++++++++------ 5 files changed, 354 insertions(+), 55 deletions(-) diff --git a/GMMAuth/auth.go b/GMMAuth/auth.go index 81451e4..1a97cb6 100644 --- a/GMMAuth/auth.go +++ b/GMMAuth/auth.go @@ -73,15 +73,12 @@ func RefreshMSCode(code, cid string) (auth *MSauth, err error) { return } -func AuthMSLogin(cid, username, password string) (string, error) { +func AuthMSLogin(username, password string) (string, error) { client := http.DefaultClient ppft := regexp.MustCompile("sFTTag:[ ]?'.*value=\"(.*)\"/>'") urlPost := regexp2.MustCompile("urlPost:[ ]?'(.+?(?='))", 0) code := regexp2.MustCompile("[?|&]code=([\\w.-]+)", 0) loginEndpoint := fmt.Sprintf("https://login.live.com/oauth20_authorize.srf?redirect_uri=https://login.live.com/oauth20_desktop.srf&scope=service::user.auth.xboxlive.com::MBI_SSL&display=touch&response_type=code&locale=en&client_id=%v", "000000004C12AE6F") - if cid == "" { - cid = os.Getenv(AzureClientIDEnvVar) - } req, _ := http.NewRequest("GET", loginEndpoint, nil) result, err := client.Do(req) if err != nil { @@ -348,9 +345,9 @@ func GetMCprofile(token string) (Auth, error) { } // GetMCcredentialsByPassword From 0 to Minecraft Auth with cache using password flow -func GetMCcredentialsByPassword(cid, username, password string) (Auth, error) { +func GetMCcredentialsByPassword(username, password string) (Auth, error) { var resauth Auth - refreshToken, err := AuthMSLogin(cid, username, password) + refreshToken, err := AuthMSLogin(username, password) if err != nil { return Auth{}, err } diff --git a/accounts.example.txt b/accounts.example.txt index de9f115..10f72ac 100644 --- a/accounts.example.txt +++ b/accounts.example.txt @@ -1,2 +1,2 @@ bot email@example.com:password -bot email1@example.com:password2 \ No newline at end of file +bot2 email2@example.com:password2 \ No newline at end of file diff --git a/go.mod b/go.mod index 1c208d3..c16b9cd 100644 --- a/go.mod +++ b/go.mod @@ -4,13 +4,34 @@ go 1.18 require ( github.com/dlclark/regexp2 v1.4.0 - github.com/gorilla/mux v1.8.0 + github.com/gin-gonic/gin v1.9.0 github.com/pion/mdns v0.0.7 github.com/zserge/lorca v0.1.10 - golang.org/x/net v0.5.0 + golang.org/x/net v0.7.0 ) require ( + github.com/bytedance/sonic v1.8.0 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.11.2 // indirect + github.com/goccy/go-json v0.10.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pion/logging v0.2.2 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.9 // indirect + golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect + golang.org/x/crypto v0.5.0 // indirect golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.7.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index c8afe4e..162730b 100644 --- a/go.sum +++ b/go.sum @@ -1,35 +1,88 @@ +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA= +github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= +github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= +github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= +github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= +github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U= github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8= github.com/pion/transport/v2 v2.0.0 h1:bsMYyqHCbkvHwj+eNCFBuxtlKndKfyGI2vaQmM3fIE4= github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU= +github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zserge/lorca v0.1.10 h1:f/xBJ3D3ipcVRCcvN8XqZnpoKcOXV8I4vwqlFyw7ruc= github.com/zserge/lorca v0.1.10/go.mod h1:bVmnIbIRlOcoV285KIRSe4bUABKi7R7384Ycuum6e4A= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -37,6 +90,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -51,10 +105,20 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 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.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/main.go b/main.go index f3fc959..8e795e2 100644 --- a/main.go +++ b/main.go @@ -3,10 +3,11 @@ package main import ( "auth-server/Auth" "auth-server/GMMAuth" + "bytes" "context" "encoding/json" "fmt" - "github.com/gorilla/mux" + "github.com/gin-gonic/gin" "github.com/pion/mdns" "golang.org/x/net/ipv4" "io" @@ -19,27 +20,13 @@ import ( "time" ) -type ReqBody struct { - User string `json:"user"` - ShareSecret string `json:"shareSecret"` - ServerID string `json:"serverID"` - PublicKey string `json:"publicKey"` - VerifyToken string `json:"verifyToken"` -} - -const ( - //cid = "389b1b32-b5d5-43b2-bddc-84ce938d6737" // Konjac - cid = "389b1b32-b5d5-43b2-bddc-84ce938d6737" // token from https://github.com/microsoft/Office365APIEditor -) - var ( - accountsData = map[string][]string{} - //timeData = map[string]time.Time{} - authTemp = map[string]Auth.Auth{} + accountsData = map[string][]string{} + authTemp = map[string]Auth.Auth{} + acccountRegex = regexp.MustCompile("(\\w+) (\\S+):(\\S+)") ) -func init() { - acccountRegex := regexp.MustCompile("(\\w+) (\\S+):(\\S+)") +func reloadAccount() { file, err := os.ReadFile("accounts.txt") if err != nil { panic("accounts.txt not found") @@ -53,68 +40,298 @@ func init() { } } +type ReqBody struct { + User string `json:"user"` + ShareSecret string `json:"shareSecret"` + ServerID string `json:"serverID"` + PublicKey string `json:"publicKey"` + VerifyToken string `json:"verifyToken"` +} + +type Error struct { + Err string `json:"error"` + ErrMsg string `json:"errorMessage"` + Cause string `json:"cause"` +} + +func (e Error) Error() string { + return e.Err + ": " + e.ErrMsg + ", " + e.Cause +} + +// agent is a struct of auth +type agent struct { + Name string `json:"name"` + Version int `json:"version"` +} + +type proof struct { + UserName string `json:"username"` + Password string `json:"password"` +} + +// Tokens store AccessToken and ClientToken +type Tokens struct { + AccessToken string `json:"accessToken"` + ClientToken string `json:"clientToken"` +} + +var defaultAgent = agent{ + Name: "Minecraft", + Version: 1, +} + +// authPayload is a yggdrasil request struct +type authPayload struct { + Agent agent `json:"agent"` + proof + ClientToken string `json:"clientToken,omitempty"` + RequestUser bool `json:"requestUser"` +} + +// authResp is the response from Mojang's auth server +type authResp struct { + Tokens + AvailableProfiles []Profile `json:"availableProfiles"` // only present if the agent field was received + + SelectedProfile Profile `json:"selectedProfile"` // only present if the agent field was received + User struct { + // only present if requestUser was true in the request authPayload + ID string `json:"id"` // hexadecimal + Properties []struct { + Name string `json:"name"` + Value string `json:"value"` + } + } `json:"user"` + + *Error +} + +type Profile struct { + ID string `json:"id"` + Name string `json:"name"` + // Legacy bool `json:"legacy"` // we don't care +} +type refreshPayload struct { + Tokens + SelectedProfile *Profile `json:"selectedProfile,omitempty"` + + RequestUser bool `json:"requestUser"` +} + +type profile struct { + ID string `json:"id"` + Name string `json:"name"` +} + +type request struct { + AccessToken string `json:"accessToken"` + SelectedProfile string `json:"selectedProfile"` + ServerID string `json:"serverId"` +} + func main() { + reloadAccount() + gin.SetMode(gin.ReleaseMode) + r := gin.Default() + as := r.Group("/as") + as.POST("/authenticate", func(c *gin.Context) { + log.Printf("[session auth]\n") + reloadAccount() + var payload authPayload + c.BindJSON(&payload) + ac, ok := accountsData[payload.UserName] + if !ok { + c.AbortWithStatusJSON(403, gin.H{ + "error": "ForbiddenOperationException", + "errorMessage": "Invalid credentials. Invalid username or password.", + }) + return + } + auth, err := GMMAuth.GetMCcredentialsByPassword(ac[0], ac[1]) + if err != nil { + c.AbortWithStatusJSON(400, gin.H{ + "error": "ForbiddenOperationException", + "errorMessage": "Forbidden", + }) + return + } + authTemp[payload.UserName] = auth + profile := Profile{ + ID: auth.UUID, + Name: auth.Name, + } + c.JSON(200, authResp{ + Tokens: Tokens{ + AccessToken: payload.UserName, + ClientToken: payload.UserName, + }, + AvailableProfiles: []Profile{profile}, + SelectedProfile: profile, + }) + }) + + as.POST("/refresh", func(c *gin.Context) { + var re refreshPayload + c.BindJSON(&re) + + c.JSON(200, authResp{ + Tokens: Tokens{ + AccessToken: re.AccessToken, + ClientToken: re.AccessToken, + }, + AvailableProfiles: []Profile{ + *re.SelectedProfile, + }, + SelectedProfile: *re.SelectedProfile, + }) + }) + as.POST("/validate", func(c *gin.Context) { + c.Status(204) + }) + as.POST("/signout", func(c *gin.Context) { + c.Status(200) + }) + as.POST("/invalidate", func(c *gin.Context) { + c.Status(200) + }) + ss := r.Group("/ss") + ss.POST("/session/minecraft/join", func(c *gin.Context) { + + var req request + err := c.BindJSON(&req) + if err != nil { + fmt.Println(err) + } + ac, ok := accountsData[req.AccessToken] + if !ok { + c.AbortWithStatusJSON(403, gin.H{ + "error": "ForbiddenOperationException", + "errorMessage": "Invalid credentials. Invalid username or password.", + }) + return + } - router := mux.NewRouter() - router.HandleFunc("/getUser", func(w http.ResponseWriter, r *http.Request) { - userRaw, _ := io.ReadAll(r.Body) - user := string(userRaw) - log.Printf("[getUser] Request Code [%v] Username\n", user) - if _, ok := accountsData[user]; !ok { - w.WriteHeader(404) + log.Printf("[session join]: %v\n", req.AccessToken) + if _, ok := authTemp[req.AccessToken]; ok { + err := LoginRemote(request{ + AccessToken: authTemp[req.AccessToken].AsTk, + SelectedProfile: strings.ReplaceAll(authTemp[req.AccessToken].UUID, "-", ""), + ServerID: req.ServerID, + }) + if err != nil { + c.AbortWithStatus(403) + return + } + c.Status(204) + log.Printf("[login] Code [%v]: %v\n", req.AccessToken, "Successful(cache)") return } + auth, err := GMMAuth.GetMCcredentialsByPassword(ac[0], ac[1]) + if err != nil { + c.AbortWithStatusJSON(400, gin.H{ + "error": "ForbiddenOperationException", + "errorMessage": "Forbidden", + }) + return + } + authTemp[req.AccessToken] = auth + err = LoginRemote(request{ + AccessToken: authTemp[req.AccessToken].AsTk, + SelectedProfile: strings.ReplaceAll(authTemp[req.AccessToken].UUID, "-", ""), + ServerID: req.ServerID, + }) + if err != nil { + c.AbortWithStatus(403) + return + } + c.Status(204) + + }) + + r.GET("/getUser", func(c *gin.Context) { + reloadAccount() + buf := new(bytes.Buffer) + buf.ReadFrom(c.Request.Body) + user := buf.String() ac := accountsData[user] - auth, err := GMMAuth.GetMCcredentialsByPassword(cid, ac[0], ac[1]) + auth, err := GMMAuth.GetMCcredentialsByPassword(ac[0], ac[1]) if err != nil { - w.WriteHeader(400) + c.AbortWithStatus(400) return } authTemp[user] = auth - w.WriteHeader(200) - w.Write([]byte(auth.Name)) + c.String(200, "text/plain", auth.Name) log.Printf("[getUser] Code [%v]: %v\n", user, auth.Name) - return - }).Methods(http.MethodPost) - router.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) { - result, _ := io.ReadAll(r.Body) + }) + r.GET("/login", func(c *gin.Context) { + reloadAccount() + result, _ := io.ReadAll(c.Request.Body) var req ReqBody err := json.Unmarshal(result, &req) if err != nil { log.Printf("[login] Request with bad payload\n") - w.WriteHeader(403) + c.Status(403) return } log.Printf("[login] Request Code [%v] login\n", req.User) if _, ok := accountsData[req.User]; !ok { log.Printf("[login] Request Code [%v] not found\n", req.User) - w.WriteHeader(404) + c.Status(403) return } if _, ok := authTemp[req.User]; ok { err = Auth.LoginAuth(authTemp[req.User], req.ShareSecret, req.ServerID, req.PublicKey, req.VerifyToken) - w.WriteHeader(200) + c.Status(200) log.Printf("[login] Code [%v]: %v\n", req.User, "Successful(cache)") delete(authTemp, req.User) return } ac := accountsData[req.User] - auth, err := GMMAuth.GetMCcredentialsByPassword(cid, ac[0], ac[1]) + auth, err := GMMAuth.GetMCcredentialsByPassword(ac[0], ac[1]) if err != nil { go failedLogin(ac[0], ac[1]) - w.WriteHeader(400) + c.Status(400) return } authTemp[req.User] = auth err = Auth.LoginAuth(auth, req.ShareSecret, req.ServerID, req.PublicKey, req.VerifyToken) if err != nil { - w.WriteHeader(400) + c.Status(400) return } - w.WriteHeader(200) + c.Status(200) log.Printf("[login] Code [%v]: %v\n", req.User, "Successful(refresh)") - }).Methods(http.MethodPost) - http.ListenAndServe("127.0.0.1:37565", router) + }) + r.Run("127.0.0.1:37565") +} +func LoginRemote(req request) error { + client := http.Client{} + requestPacket, err := json.Marshal( + req, + ) + if err != nil { + return fmt.Errorf("create request packet to yggdrasil faile: %v", err) + } + + PostRequest, err := http.NewRequest(http.MethodPost, "https://sessionserver.mojang.com/session/minecraft/join", + bytes.NewReader(requestPacket)) + if err != nil { + return fmt.Errorf("make request error: %v", err) + } + PostRequest.Header.Set("User-agent", "go-mc") + PostRequest.Header.Set("Connection", "keep-alive") + PostRequest.Header.Set("Content-Type", "application/json") + resp, err := client.Do(PostRequest) + if err != nil { + return fmt.Errorf("post fail: %v", err) + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + if resp.StatusCode != http.StatusNoContent { + return fmt.Errorf("auth fail: %s", string(body)) + } + return nil }