NAS: Handle acctcreate

This commit is contained in:
TheLordScruffy 2023-10-18 19:23:47 -04:00
parent d66a2a3f70
commit 270a728d02
13 changed files with 63 additions and 28 deletions

View File

@ -2,7 +2,7 @@ package common
import "fmt"
func Base32Encode(value int) string {
func Base32Encode(value int64) string {
alpha := "0123456789abcdefghijklmnopqrstuv"
encoded := ""

View File

@ -19,7 +19,7 @@ const (
GetUserAuthToken = `SELECT auth_token FROM logins WHERE user_id = $1 AND gsbrcd = $2`
)
func GenerateAuthToken(pool *pgxpool.Pool, ctx context.Context, userId int, gsbrcd string) string {
func GenerateAuthToken(pool *pgxpool.Pool, ctx context.Context, userId int64, gsbrcd string) string {
var authToken string
err := pool.QueryRow(ctx, GetUserAuthToken, userId, gsbrcd).Scan(&authToken)
@ -63,8 +63,8 @@ func GenerateAuthToken(pool *pgxpool.Pool, ctx context.Context, userId int, gsbr
return authToken
}
func GetNASLogin(pool *pgxpool.Pool, ctx context.Context, authToken string) (int, string) {
var userId int
func GetNASLogin(pool *pgxpool.Pool, ctx context.Context, authToken string) (int64, string) {
var userId int64
var gsbrcd string
err := pool.QueryRow(ctx, GetNASUserLogin, authToken).Scan(&userId, &gsbrcd)
if err != nil {

View File

@ -3,6 +3,7 @@ package database
import (
"context"
"errors"
"math/rand"
"wwfc/common"
"github.com/jackc/pgx/v4"
@ -20,8 +21,8 @@ const (
)
type User struct {
ProfileId int
UserId int
ProfileId int64
UserId int64
GsbrCode string
Password string
Email string
@ -37,7 +38,12 @@ func (user *User) CreateUser(pool *pgxpool.Pool, ctx context.Context) {
}
}
func UpdateUser(pool *pgxpool.Pool, ctx context.Context, firstName string, lastName string, userId int) User {
func GetUniqueUserID() int64 {
// Not guaranteed unique but doesn't matter in practice if multiple people have the same user ID.
return rand.Int63n(100000000000000)
}
func UpdateUser(pool *pgxpool.Pool, ctx context.Context, firstName string, lastName string, userId int64) User {
user := User{}
_, err := pool.Exec(ctx, UpdateUserTable, firstName, lastName, userId)
if err != nil {
@ -47,7 +53,7 @@ func UpdateUser(pool *pgxpool.Pool, ctx context.Context, firstName string, lastN
return user
}
func CreateSession(pool *pgxpool.Pool, ctx context.Context, profileId int, loginTicket string) string {
func CreateSession(pool *pgxpool.Pool, ctx context.Context, profileId int64, loginTicket string) string {
// Delete session first.
deleteSession(pool, ctx, profileId)
@ -60,14 +66,14 @@ func CreateSession(pool *pgxpool.Pool, ctx context.Context, profileId int, login
return sessionKey
}
func deleteSession(pool *pgxpool.Pool, ctx context.Context, profileId int) {
func deleteSession(pool *pgxpool.Pool, ctx context.Context, profileId int64) {
_, err := pool.Exec(ctx, DeleteUserSession, profileId)
if err != nil && !errors.Is(err, pgx.ErrNoRows) {
panic(err)
}
}
func GetProfile(pool *pgxpool.Pool, ctx context.Context, profileId int) User {
func GetProfile(pool *pgxpool.Pool, ctx context.Context, profileId int64) User {
user := User{}
row := pool.QueryRow(ctx, GetUser, profileId)
err := row.Scan(&user.UserId, &user.GsbrCode, &user.Password, &user.Email, &user.UniqueNick, &user.FirstName, &user.LastName)

View File

@ -58,8 +58,8 @@ func login(pool *pgxpool.Pool, ctx context.Context, command common.GameSpyComman
OtherValues: map[string]string{
"sesskey": "199714190",
"proof": proof,
"userid": strconv.Itoa(user.UserId),
"profileid": strconv.Itoa(user.ProfileId),
"userid": strconv.FormatInt(user.UserId, 10),
"profileid": strconv.FormatInt(user.ProfileId, 10),
"uniquenick": user.UniqueNick,
"lt": loginTicket,
"id": command.OtherValues["id"],

View File

@ -20,7 +20,7 @@ import (
var (
ctx = context.Background()
pool *pgxpool.Pool
userId int
userId int64
)
func checkError(err error) {

View File

@ -10,7 +10,7 @@ import (
func getProfile(pool *pgxpool.Pool, ctx context.Context, command common.GameSpyCommand) string {
strProfileId := command.OtherValues["profileid"]
profileId, _ := strconv.Atoi(strProfileId)
profileId, _ := strconv.ParseInt(strProfileId, 10, 0)
user := database.GetProfile(pool, ctx, profileId)
@ -21,7 +21,7 @@ func getProfile(pool *pgxpool.Pool, ctx context.Context, command common.GameSpyC
OtherValues: map[string]string{
"profileid": command.OtherValues["profileid"],
"nick": user.UniqueNick,
"userid": strconv.Itoa(user.UserId),
"userid": strconv.FormatInt(user.UserId, 10),
"email": user.Email,
"sig": "b126556e5ee62d4da9629dfad0f6b2a8",
"uniquenick": user.UniqueNick,

View File

@ -58,8 +58,8 @@ func login(pool *pgxpool.Pool, ctx context.Context, command common.GameSpyComman
OtherValues: map[string]string{
"sesskey": "199714190",
"proof": proof,
"userid": strconv.Itoa(user.UserId),
"profileid": strconv.Itoa(user.ProfileId),
"userid": strconv.FormatInt(user.UserId, 10),
"profileid": strconv.FormatInt(user.ProfileId, 10),
"uniquenick": user.UniqueNick,
"lt": loginTicket,
"id": command.OtherValues["id"],

View File

@ -20,7 +20,7 @@ import (
var (
ctx = context.Background()
pool *pgxpool.Pool
userId int
userId int64
)
func checkError(err error) {

View File

@ -13,7 +13,7 @@ import (
func getProfile(pool *pgxpool.Pool, ctx context.Context, command common.GameSpyCommand) string {
strProfileId := command.OtherValues["profileid"]
profileId, _ := strconv.Atoi(strProfileId)
profileId, _ := strconv.ParseInt(strProfileId, 10, 0)
user := database.GetProfile(pool, ctx, profileId)
@ -24,7 +24,7 @@ func getProfile(pool *pgxpool.Pool, ctx context.Context, command common.GameSpyC
OtherValues: map[string]string{
"profileid": command.OtherValues["profileid"],
"nick": user.UniqueNick,
"userid": strconv.Itoa(user.UserId),
"userid": strconv.FormatInt(user.UserId, 10),
"email": user.Email,
"sig": "b126556e5ee62d4da9629dfad0f6b2a8",
"uniquenick": user.UniqueNick,

20
nas/acctcreate.go Normal file
View File

@ -0,0 +1,20 @@
package nas
import (
"encoding/base64"
"net/url"
"strconv"
"strings"
"wwfc/database"
)
func acctcreate(r *Response) {
param := url.Values{}
param.Set("retry", strings.Replace(base64.StdEncoding.EncodeToString([]byte("0")), "=", "*", -1))
param.Set("returncd", strings.Replace(base64.StdEncoding.EncodeToString([]byte("002")), "=", "*", -1))
param.Set("userid", strings.Replace(base64.StdEncoding.EncodeToString([]byte(strconv.FormatInt(database.GetUniqueUserID(), 10))), "=", "*", -1))
// Encode and send off to be written!
r.payload = []byte(param.Encode())
r.payload = []byte(strings.Replace(string(r.payload), "%2A", "*", -1))
}

View File

@ -14,7 +14,7 @@ const Challenge = "0qUekMb4"
func login(r *Response) {
// Validate the user id. It must be an integer.
strUserId, _ := base64.StdEncoding.DecodeString(strings.Replace(r.request.PostForm.Get("userid"), "*", "=", -1))
userId, err := strconv.Atoi(string(strUserId))
userId, err := strconv.ParseInt(string(strUserId), 10, 0)
if err != nil {
panic(err)
}
@ -32,6 +32,5 @@ func login(r *Response) {
// Encode and send off to be written!
r.payload = []byte(param.Encode())
r.payload = []byte(param.Encode())
r.payload = []byte(strings.Replace(string(r.payload), "%2A", "*", -1))
}

View File

@ -36,6 +36,7 @@ func StartServer() {
r := NewRoute()
ac := r.HandleGroup("ac")
{
ac.HandleAction("acctcreate", acctcreate)
ac.HandleAction("login", login)
}

View File

@ -3,10 +3,10 @@ package nas
import (
"encoding/base64"
"github.com/logrusorgru/aurora/v3"
"log"
"net/http"
"strconv"
"strings"
"wwfc/logging"
)
type Route struct {
@ -48,17 +48,26 @@ func (r *RoutingGroup) HandleAction(action string, function func(*Response)) {
func (route *Route) Handle() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s via %s", aurora.Yellow(r.Method), aurora.Cyan(r.URL), aurora.Cyan(r.Host))
logging.Notice("NAS", aurora.Yellow(r.Method).String(), aurora.Cyan(r.URL).String(), "via", aurora.Cyan(r.Host).String())
err := r.ParseForm()
if err != nil {
log.Printf(aurora.Red("failed to parse form").String())
logging.Notice("NAS", aurora.Red("Failed to parse form").String())
return
}
// While generally a bad idea, we can only have a path with a depth of one.
path := strings.Replace(r.URL.Path, "/", "", -1)
if !strings.HasPrefix(r.URL.Path, "/") {
logging.Notice("NAS", aurora.Red("Invalid URL").String())
return
}
path := r.URL.Path[1:]
actionName, _ := base64.StdEncoding.DecodeString(strings.Replace(r.PostForm.Get("action"), "*", "=", -1))
if string(actionName) == "" {
logging.Notice("NAS", aurora.Red("No action in form").String())
return
}
var action Action
for _, _action := range route.Actions {
if path == _action.ServiceType && string(actionName) == _action.ActionName {
@ -68,7 +77,7 @@ func (route *Route) Handle() http.Handler {
// Make sure we found an action
if action.ActionName == "" && action.ServiceType == "" {
log.Printf(aurora.Red("no action found").String())
logging.Notice("NAS", aurora.Red("No action for").String(), aurora.Yellow(string(actionName)).String())
return
}