mirror of
https://github.com/PretendoNetwork/friends.git
synced 2026-03-21 18:04:11 -05:00
Merge pull request #33 from PretendoNetwork/token-validation
feat: Implement token validation from common protocols
This commit is contained in:
commit
bba53eb3ef
28
go.mod
28
go.mod
|
|
@ -7,35 +7,33 @@ toolchain go1.23.6
|
|||
require (
|
||||
github.com/PretendoNetwork/grpc-go v1.0.2
|
||||
github.com/PretendoNetwork/nex-go/v2 v2.1.3
|
||||
github.com/PretendoNetwork/nex-protocols-common-go/v2 v2.2.2
|
||||
github.com/PretendoNetwork/nex-protocols-common-go/v2 v2.4.0
|
||||
github.com/PretendoNetwork/nex-protocols-go/v2 v2.2.1
|
||||
github.com/PretendoNetwork/plogger-go v1.0.4
|
||||
github.com/PretendoNetwork/plogger-go v1.1.0
|
||||
github.com/PretendoNetwork/sql-manager v1.0.0
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/lib/pq v1.10.9
|
||||
google.golang.org/grpc v1.70.0
|
||||
google.golang.org/grpc v1.71.1
|
||||
)
|
||||
|
||||
replace google.golang.org/genproto => google.golang.org/genproto v0.0.0-20240520151616-dc85e6b867a5
|
||||
|
||||
require (
|
||||
github.com/dolthub/maphash v0.1.0 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/jwalton/go-supportscolor v1.2.0 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/lxzan/gws v1.8.8 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/rasky/go-lzo v0.0.0-20200203143853-96a758eda86e // indirect
|
||||
github.com/superwhiskers/crunch/v3 v3.5.7 // indirect
|
||||
golang.org/x/exp v0.0.0-20250215185904-eff6e970281f // indirect
|
||||
golang.org/x/mod v0.23.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/term v0.29.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/sync v0.13.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/term v0.31.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
)
|
||||
|
|
|
|||
76
go.sum
76
go.sum
|
|
@ -1,15 +1,13 @@
|
|||
github.com/PretendoNetwork/grpc-go v1.0.2 h1:9TvKmX7dCOANyoHEra1MMYqS1N/RGav66TRG4SHInvo=
|
||||
github.com/PretendoNetwork/grpc-go v1.0.2/go.mod h1:XZjEsij9lL7HJBNkH6JPbBIkUSq/1rjflvjGdv+DAj0=
|
||||
github.com/PretendoNetwork/nex-go/v2 v2.1.2 h1:OJFAS6U6VNzZ4YzteKqUEZ5aJMwWIHODeRrLwNbN7nw=
|
||||
github.com/PretendoNetwork/nex-go/v2 v2.1.2/go.mod h1:3LyJzsv3AataJW8D0binp15Q8ZH22MWTYly1VNtXi64=
|
||||
github.com/PretendoNetwork/nex-go/v2 v2.1.3 h1:hdi8PbJIWbpr3WOc1fGJ5ssF76kTxFJ3Wnz46WJYvVs=
|
||||
github.com/PretendoNetwork/nex-go/v2 v2.1.3/go.mod h1:3LyJzsv3AataJW8D0binp15Q8ZH22MWTYly1VNtXi64=
|
||||
github.com/PretendoNetwork/nex-protocols-common-go/v2 v2.2.2 h1:rBJNZDJ92pa9fU3Og0sanyizJTWnELPoGR0Tjz8zlws=
|
||||
github.com/PretendoNetwork/nex-protocols-common-go/v2 v2.2.2/go.mod h1:iuNMuBK/zww+44d6ajfLsOusXx/6Llj3zSkmhJwMuuM=
|
||||
github.com/PretendoNetwork/nex-protocols-common-go/v2 v2.4.0 h1:EhXj1EDbNgdg40BPx/7n1HHsAy/DayGIWthu81UNyvI=
|
||||
github.com/PretendoNetwork/nex-protocols-common-go/v2 v2.4.0/go.mod h1:tNtZly5sL3wfy4LVgybS2efm00L/wNgyvcrBV59S/YM=
|
||||
github.com/PretendoNetwork/nex-protocols-go/v2 v2.2.1 h1:/dsuP0W7bZNvrXoXH0ZRdxpxonfbWmmson51WCQdpEQ=
|
||||
github.com/PretendoNetwork/nex-protocols-go/v2 v2.2.1/go.mod h1:+soBHmwX6ixGxj6cphLuCvfJqxcZPuowc/5e7Qi9Bz0=
|
||||
github.com/PretendoNetwork/plogger-go v1.0.4 h1:PF7xHw9eDRHH+RsAP9tmAE7fG0N0p6H4iPwHKnsoXwc=
|
||||
github.com/PretendoNetwork/plogger-go v1.0.4/go.mod h1:7kD6M4vPq1JL4LTuPg6kuB1OvUBOwQOtAvTaUwMbwvU=
|
||||
github.com/PretendoNetwork/plogger-go v1.1.0 h1:x2XgyeeM8zDFGy+NcIZd3SYC2fNrVWpBBbkqTejOfiM=
|
||||
github.com/PretendoNetwork/plogger-go v1.1.0/go.mod h1:wpltahp91IXr9nOvWgwep8zGtUKDeCVwm+/Wa484lQ4=
|
||||
github.com/PretendoNetwork/sql-manager v1.0.0 h1:g0SYpQgi6Kk4ptufrLTSmDxvqaYioTcfXaDH+uXC+a0=
|
||||
github.com/PretendoNetwork/sql-manager v1.0.0/go.mod h1:NaEdDC0S/9J8eoxCDvuHB8fofv0svh44lWvgCdtuMq0=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
|
@ -32,8 +30,8 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
|||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/jwalton/go-supportscolor v1.2.0 h1:g6Ha4u7Vm3LIsQ5wmeBpS4gazu0UP1DRDE8y6bre4H8=
|
||||
github.com/jwalton/go-supportscolor v1.2.0/go.mod h1:hFVUAZV2cWg+WFFC4v8pT2X/S2qUUBYMioBD9AINXGs=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lxzan/gws v1.8.8 h1:st193ZG8qN8sSw8/g/UituFhs7etmKzS7jUqhijg5wM=
|
||||
|
|
@ -50,39 +48,41 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
|
|||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/superwhiskers/crunch/v3 v3.5.7 h1:N9RLxaR65C36i26BUIpzPXGy2f6pQ7wisu2bawbKNqg=
|
||||
github.com/superwhiskers/crunch/v3 v3.5.7/go.mod h1:4ub2EKgF1MAhTjoOCTU4b9uLMsAweHEa89aRrfAypXA=
|
||||
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
|
||||
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
|
||||
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
|
||||
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
|
||||
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
|
||||
golang.org/x/exp v0.0.0-20250215185904-eff6e970281f h1:oFMYAjX0867ZD2jcNiLBrI9BdpmEkvPyi5YrBGXbamg=
|
||||
golang.org/x/exp v0.0.0-20250215185904-eff6e970281f/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
|
||||
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
|
||||
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b h1:FQtJ1MxbXoIIrZHZ33M+w5+dAP9o86rgpjoKr/ZmT7k=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
|
||||
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e h1:ztQaXfzEXTmCBvbtWYRhJxW+0iJcz2qXfd38/e9l7bA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
|
||||
google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
|
|
@ -3,56 +3,26 @@ package nex_account_management
|
|||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
"github.com/PretendoNetwork/friends/globals"
|
||||
"github.com/PretendoNetwork/friends/utility"
|
||||
nex "github.com/PretendoNetwork/nex-go/v2"
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
account_management "github.com/PretendoNetwork/nex-protocols-go/v2/account-management"
|
||||
account_management_types "github.com/PretendoNetwork/nex-protocols-go/v2/account-management/types"
|
||||
)
|
||||
|
||||
func NintendoCreateAccount(err error, packet nex.PacketInterface, callID uint32, strPrincipalName types.String, strKey types.String, uiGroups types.UInt32, strEmail types.String, oAuthData types.DataHolder) (*nex.RMCMessage, *nex.Error) {
|
||||
if err != nil {
|
||||
globals.Logger.Error(err.Error())
|
||||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, "") // TODO - Add error message
|
||||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
var tokenBase64 string
|
||||
|
||||
oAuthDataType := oAuthData.Object.DataObjectID().(types.String)
|
||||
|
||||
switch oAuthDataType {
|
||||
case "NintendoCreateAccountData": // * Wii U
|
||||
nintendoCreateAccountData := oAuthData.Object.Copy().(account_management_types.NintendoCreateAccountData)
|
||||
|
||||
tokenBase64 = string(nintendoCreateAccountData.Token)
|
||||
case "AccountExtraInfo": // * 3DS
|
||||
accountExtraInfo := oAuthData.Object.Copy().(account_management_types.AccountExtraInfo)
|
||||
|
||||
tokenBase64 = string(accountExtraInfo.NEXToken)
|
||||
tokenBase64 = strings.Replace(tokenBase64, ".", "+", -1)
|
||||
tokenBase64 = strings.Replace(tokenBase64, "-", "/", -1)
|
||||
tokenBase64 = strings.Replace(tokenBase64, "*", "=", -1)
|
||||
default:
|
||||
globals.Logger.Errorf("Invalid oAuthData data type %s!", oAuthDataType)
|
||||
return nil, nex.NewError(nex.ResultCodes.Authentication.TokenParseError, "") // TODO - Add error message
|
||||
}
|
||||
|
||||
encryptedToken, err := base64.StdEncoding.DecodeString(tokenBase64)
|
||||
if err != nil {
|
||||
globals.Logger.Error(err.Error())
|
||||
return nil, nex.NewError(nex.ResultCodes.Authentication.TokenParseError, "") // TODO - Add error message
|
||||
}
|
||||
|
||||
decryptedToken, err := utility.DecryptToken(encryptedToken)
|
||||
if err != nil {
|
||||
globals.Logger.Error(err.Error())
|
||||
return nil, nex.NewError(nex.ResultCodes.Authentication.TokenParseError, "") // TODO - Add error message
|
||||
decryptedToken, nexError := utility.ValidateNintendoCreateAccountToken(oAuthData)
|
||||
if nexError != nil {
|
||||
globals.Logger.Error(nexError.Error())
|
||||
return nil, nexError
|
||||
}
|
||||
|
||||
pid := types.NewPID(uint64(decryptedToken.UserPID))
|
||||
|
|
@ -64,7 +34,7 @@ func NintendoCreateAccount(err error, packet nex.PacketInterface, callID uint32,
|
|||
_, err = mac.Write(pidByteArray)
|
||||
if err != nil {
|
||||
globals.Logger.Error(err.Error())
|
||||
return nil, nex.NewError(nex.ResultCodes.Authentication.Unknown, "") // TODO - Add error message
|
||||
return nil, nex.NewError(nex.ResultCodes.Authentication.Unknown, err.Error())
|
||||
}
|
||||
|
||||
pidHmac := types.NewString(hex.EncodeToString(mac.Sum(nil)))
|
||||
|
|
|
|||
|
|
@ -9,8 +9,12 @@ import (
|
|||
|
||||
func registerCommonSecureServerProtocols() {
|
||||
secureConnectionProtocol := secure_connection.NewProtocol()
|
||||
common_secure_connection.NewCommonProtocol(secureConnectionProtocol)
|
||||
commonSecureConnectionProtocol := common_secure_connection.NewCommonProtocol(secureConnectionProtocol)
|
||||
|
||||
// * On account creation the console logs in with a guest account and uses the Register method
|
||||
commonSecureConnectionProtocol.EnableInsecureRegister()
|
||||
|
||||
// * Override RegisterEx so that we can register the user into the ConnectedUsers map
|
||||
secureConnectionProtocol.RegisterEx = nex_secure_connection.RegisterEx
|
||||
|
||||
globals.SecureEndpoint.RegisterServiceProtocol(secureConnectionProtocol)
|
||||
|
|
|
|||
|
|
@ -3,77 +3,144 @@ package nex_secure_connection
|
|||
import (
|
||||
"net"
|
||||
|
||||
"github.com/PretendoNetwork/nex-go/v2"
|
||||
"github.com/PretendoNetwork/nex-go/v2/constants"
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
secure_connection "github.com/PretendoNetwork/nex-protocols-go/v2/secure-connection"
|
||||
common_globals "github.com/PretendoNetwork/nex-protocols-common-go/v2/globals"
|
||||
|
||||
database_3ds "github.com/PretendoNetwork/friends/database/3ds"
|
||||
database_wiiu "github.com/PretendoNetwork/friends/database/wiiu"
|
||||
"github.com/PretendoNetwork/friends/globals"
|
||||
friends_types "github.com/PretendoNetwork/friends/types"
|
||||
nex "github.com/PretendoNetwork/nex-go/v2"
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
secure_connection "github.com/PretendoNetwork/nex-protocols-go/v2/secure-connection"
|
||||
)
|
||||
|
||||
func RegisterEx(err error, packet nex.PacketInterface, callID uint32, vecMyURLs types.List[types.StationURL], hCustomData types.DataHolder) (*nex.RMCMessage, *nex.Error) {
|
||||
if err != nil {
|
||||
globals.Logger.Error(err.Error())
|
||||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, "")
|
||||
common_globals.Logger.Error(err.Error())
|
||||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
connection := packet.Sender().(*nex.PRUDPConnection)
|
||||
endpoint := connection.Endpoint()
|
||||
|
||||
retval := types.NewQResultSuccess(nex.ResultCodes.Core.Unknown)
|
||||
|
||||
// TODO - Validate loginData
|
||||
pid := uint32(connection.PID())
|
||||
|
||||
user := friends_types.NewConnectedUser()
|
||||
user.PID = pid
|
||||
user.Connection = connection
|
||||
|
||||
lastOnline := types.NewDateTime(0).Now()
|
||||
loginDataType := hCustomData.Object.DataObjectID().(types.String)
|
||||
|
||||
switch loginDataType {
|
||||
case "NintendoLoginData":
|
||||
user.Platform = friends_types.WUP // * Platform is Wii U
|
||||
|
||||
err = database_wiiu.UpdateUserLastOnlineTime(pid, lastOnline)
|
||||
if err != nil {
|
||||
globals.Logger.Critical(err.Error())
|
||||
retval = types.NewQResultError(nex.ResultCodes.Authentication.Unknown)
|
||||
}
|
||||
case "AccountExtraInfo":
|
||||
user.Platform = friends_types.CTR // * Platform is 3DS
|
||||
|
||||
err = database_3ds.UpdateUserLastOnlineTime(pid, lastOnline)
|
||||
if err != nil {
|
||||
globals.Logger.Critical(err.Error())
|
||||
retval = types.NewQResultError(nex.ResultCodes.Authentication.Unknown)
|
||||
}
|
||||
default:
|
||||
globals.Logger.Errorf("Unknown loginData data type %s!", loginDataType)
|
||||
retval = types.NewQResultError(nex.ResultCodes.Authentication.ValidationFailed)
|
||||
}
|
||||
|
||||
var retval types.QResult
|
||||
pidConnectionID := types.NewUInt32(0)
|
||||
urlPublic := types.NewString("")
|
||||
|
||||
if retval.IsSuccess() {
|
||||
globals.ConnectedUsers.Set(pid, user)
|
||||
errorCode := common_globals.ValidatePretendoLoginData(connection.PID(), hCustomData, globals.AESKey)
|
||||
if errorCode != nil {
|
||||
common_globals.Logger.Error(errorCode.Message)
|
||||
retval = types.NewQResultError(errorCode.ResultCode)
|
||||
} else {
|
||||
// * vecMyURLs may contain multiple StationURLs. Search them all
|
||||
var localStation *types.StationURL
|
||||
var publicStation *types.StationURL
|
||||
|
||||
localStation := vecMyURLs[0]
|
||||
for _, stationURL := range vecMyURLs {
|
||||
natf, ok := stationURL.NATFiltering()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
address := connection.Address().(*net.UDPAddr)
|
||||
natm, ok := stationURL.NATMapping()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
localStation.SetAddress(address.IP.String())
|
||||
localStation.SetPortNumber(uint16(address.Port))
|
||||
// * Station reports itself as being non-public (local)
|
||||
if localStation == nil && !stationURL.IsPublic() {
|
||||
localStation = &stationURL
|
||||
}
|
||||
|
||||
localStationURL := localStation.URL()
|
||||
// * Still did not find the station, trying heuristics
|
||||
if localStation == nil && natf == constants.UnknownNATFiltering && natm == constants.UnknownNATMapping {
|
||||
localStation = &stationURL
|
||||
}
|
||||
|
||||
pidConnectionID = types.NewUInt32(connection.ID)
|
||||
urlPublic = types.NewString(localStationURL)
|
||||
if publicStation == nil && stationURL.IsPublic() {
|
||||
publicStation = &stationURL
|
||||
}
|
||||
}
|
||||
|
||||
if localStation == nil {
|
||||
common_globals.Logger.Error("Failed to find local station")
|
||||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, "change_error")
|
||||
}
|
||||
|
||||
if publicStation == nil {
|
||||
publicStation = localStation
|
||||
|
||||
var address string
|
||||
var port uint16
|
||||
|
||||
// * We have to duplicate this because Go automatically breaks on switch statements
|
||||
switch clientAddress := connection.Address().(type) {
|
||||
case *net.UDPAddr:
|
||||
address = clientAddress.IP.String()
|
||||
port = uint16(clientAddress.Port)
|
||||
case *net.TCPAddr:
|
||||
address = clientAddress.IP.String()
|
||||
port = uint16(clientAddress.Port)
|
||||
}
|
||||
|
||||
publicStation.SetAddress(address)
|
||||
publicStation.SetPortNumber(port)
|
||||
publicStation.SetNATFiltering(constants.UnknownNATFiltering)
|
||||
publicStation.SetNATMapping(constants.UnknownNATMapping)
|
||||
publicStation.SetType(uint8(constants.StationURLFlagPublic) | uint8(constants.StationURLFlagBehindNAT))
|
||||
}
|
||||
|
||||
localStation.SetPrincipalID(connection.PID())
|
||||
publicStation.SetPrincipalID(connection.PID())
|
||||
|
||||
localStation.SetRVConnectionID(connection.ID)
|
||||
publicStation.SetRVConnectionID(connection.ID)
|
||||
|
||||
connection.StationURLs = append(connection.StationURLs, *localStation)
|
||||
connection.StationURLs = append(connection.StationURLs, *publicStation)
|
||||
|
||||
pid := uint32(connection.PID())
|
||||
|
||||
user := friends_types.NewConnectedUser()
|
||||
user.PID = pid
|
||||
user.Connection = connection
|
||||
|
||||
lastOnline := types.NewDateTime(0).Now()
|
||||
loginDataType := hCustomData.Object.DataObjectID().(types.String)
|
||||
|
||||
switch loginDataType {
|
||||
case "NintendoLoginData":
|
||||
user.Platform = friends_types.WUP // * Platform is Wii U
|
||||
|
||||
err = database_wiiu.UpdateUserLastOnlineTime(pid, lastOnline)
|
||||
if err != nil {
|
||||
globals.Logger.Critical(err.Error())
|
||||
retval = types.NewQResultError(nex.ResultCodes.Authentication.Unknown)
|
||||
}
|
||||
case "AccountExtraInfo":
|
||||
user.Platform = friends_types.CTR // * Platform is 3DS
|
||||
|
||||
err = database_3ds.UpdateUserLastOnlineTime(pid, lastOnline)
|
||||
if err != nil {
|
||||
globals.Logger.Critical(err.Error())
|
||||
retval = types.NewQResultError(nex.ResultCodes.Authentication.Unknown)
|
||||
}
|
||||
default:
|
||||
globals.Logger.Errorf("Unknown loginData data type %s!", loginDataType)
|
||||
retval = types.NewQResultError(nex.ResultCodes.Authentication.ValidationFailed)
|
||||
}
|
||||
|
||||
if !retval.IsError() {
|
||||
globals.ConnectedUsers.Set(pid, user)
|
||||
|
||||
retval = types.NewQResultSuccess(nex.ResultCodes.Core.Unknown)
|
||||
pidConnectionID = types.NewUInt32(connection.ID)
|
||||
urlPublic = types.NewString(publicStation.URL())
|
||||
}
|
||||
}
|
||||
|
||||
rmcResponseStream := nex.NewByteStreamOut(globals.SecureEndpoint.LibraryVersions(), globals.SecureEndpoint.ByteStreamSettings())
|
||||
rmcResponseStream := nex.NewByteStreamOut(endpoint.LibraryVersions(), endpoint.ByteStreamSettings())
|
||||
|
||||
retval.WriteTo(rmcResponseStream)
|
||||
pidConnectionID.WriteTo(rmcResponseStream)
|
||||
|
|
@ -81,7 +148,7 @@ func RegisterEx(err error, packet nex.PacketInterface, callID uint32, vecMyURLs
|
|||
|
||||
rmcResponseBody := rmcResponseStream.Bytes()
|
||||
|
||||
rmcResponse := nex.NewRMCSuccess(globals.SecureEndpoint, rmcResponseBody)
|
||||
rmcResponse := nex.NewRMCSuccess(endpoint, rmcResponseBody)
|
||||
rmcResponse.ProtocolID = secure_connection.ProtocolID
|
||||
rmcResponse.MethodID = secure_connection.MethodRegisterEx
|
||||
rmcResponse.CallID = callID
|
||||
|
|
|
|||
70
utility/authentication.go
Normal file
70
utility/authentication.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package utility
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/PretendoNetwork/nex-go/v2"
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
common_globals "github.com/PretendoNetwork/nex-protocols-common-go/v2/globals"
|
||||
account_management_types "github.com/PretendoNetwork/nex-protocols-go/v2/account-management/types"
|
||||
|
||||
"github.com/PretendoNetwork/friends/globals"
|
||||
)
|
||||
|
||||
// ValidateNintendoCreateAccountToken validates the given Pretendo token for account creation
|
||||
func ValidateNintendoCreateAccountToken(token types.DataHolder) (*common_globals.NEXToken, *nex.Error) {
|
||||
var tokenBase64 string
|
||||
|
||||
tokenDataType := token.Object.DataObjectID().(types.String)
|
||||
|
||||
switch tokenDataType {
|
||||
case "NintendoCreateAccountData": // * Wii U
|
||||
nintendoCreateAccountData := token.Object.Copy().(account_management_types.NintendoCreateAccountData)
|
||||
|
||||
tokenBase64 = string(nintendoCreateAccountData.Token)
|
||||
case "AccountExtraInfo": // * 3DS
|
||||
accountExtraInfo := token.Object.Copy().(account_management_types.AccountExtraInfo)
|
||||
|
||||
tokenBase64 = string(accountExtraInfo.NEXToken)
|
||||
tokenBase64 = strings.Replace(tokenBase64, ".", "+", -1)
|
||||
tokenBase64 = strings.Replace(tokenBase64, "-", "/", -1)
|
||||
tokenBase64 = strings.Replace(tokenBase64, "*", "=", -1)
|
||||
default:
|
||||
globals.Logger.Errorf("Invalid token data type %s!", tokenDataType)
|
||||
return nil, nex.NewError(nex.ResultCodes.Authentication.ValidationFailed, fmt.Sprintf("Invalid token data type %s!", tokenDataType))
|
||||
}
|
||||
|
||||
encryptedToken, err := base64.StdEncoding.DecodeString(tokenBase64)
|
||||
if err != nil {
|
||||
globals.Logger.Error(err.Error())
|
||||
return nil, nex.NewError(nex.ResultCodes.Authentication.ValidationFailed, err.Error())
|
||||
}
|
||||
|
||||
decryptedToken, nexError := common_globals.DecryptToken(encryptedToken, globals.AESKey)
|
||||
if nexError != nil {
|
||||
return nil, nexError
|
||||
}
|
||||
|
||||
// Check for NEX token type
|
||||
if decryptedToken.TokenType != 3 {
|
||||
return nil, nex.NewError(nex.ResultCodes.Authentication.ValidationFailed, "Invalid token type")
|
||||
}
|
||||
|
||||
// Expire time is in milliseconds
|
||||
expireTime := time.Unix(int64(decryptedToken.ExpireTime / 1000), 0)
|
||||
|
||||
if expireTime.Before(time.Now()) {
|
||||
return nil, nex.NewError(nex.ResultCodes.Authentication.TokenExpired, "Token expired")
|
||||
}
|
||||
|
||||
// PID isn't checked since account creation is done with a guest account
|
||||
|
||||
if decryptedToken.AccessLevel < 0 {
|
||||
return nil, nex.NewError(nex.ResultCodes.RendezVous.AccountDisabled, fmt.Sprintf("Account %d is banned", decryptedToken.UserPID))
|
||||
}
|
||||
|
||||
return decryptedToken, nil
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
package utility
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
|
||||
"github.com/PretendoNetwork/friends/globals"
|
||||
"github.com/PretendoNetwork/friends/types"
|
||||
)
|
||||
|
||||
func DecryptToken(encryptedToken []byte) (*types.NEXToken, error) {
|
||||
// Decrypt the token body
|
||||
block, err := aes.NewCipher(globals.AESKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(encryptedToken) < 20 {
|
||||
return nil, fmt.Errorf("token too short (%v)", len(encryptedToken))
|
||||
}
|
||||
|
||||
expectedChecksum := binary.BigEndian.Uint32(encryptedToken[0:4])
|
||||
encryptedBody := encryptedToken[4:]
|
||||
|
||||
decrypted := make([]byte, len(encryptedBody))
|
||||
iv := make([]byte, 16)
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(decrypted, encryptedBody)
|
||||
|
||||
paddingSize := int(decrypted[len(decrypted)-1])
|
||||
|
||||
if paddingSize < 0 || paddingSize >= len(decrypted) {
|
||||
return nil, fmt.Errorf("Invalid padding size %d for token %x", paddingSize, encryptedToken)
|
||||
}
|
||||
|
||||
decrypted = decrypted[:len(decrypted)-paddingSize]
|
||||
|
||||
table := crc32.MakeTable(crc32.IEEE)
|
||||
calculatedChecksum := crc32.Checksum(decrypted, table)
|
||||
|
||||
if expectedChecksum != calculatedChecksum {
|
||||
return nil, errors.New("Checksum did not match. Failed decrypt. Are you using the right key?")
|
||||
}
|
||||
|
||||
// Unpack the token body to struct
|
||||
token := &types.NEXToken{}
|
||||
tokenReader := bytes.NewBuffer(decrypted)
|
||||
|
||||
err = binary.Read(tokenReader, binary.LittleEndian, token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user