From 99915ae35771a169afe96c599786d540979fabf1 Mon Sep 17 00:00:00 2001 From: Sketch <75850871+SketchMaster2001@users.noreply.github.com> Date: Sat, 11 Nov 2023 12:06:05 -0500 Subject: [PATCH] Store NAS challenge in database --- database/login.go | 31 ++++++++++++++++++++++++------- gpcm/login.go | 11 ++++++++--- nas/login.go | 7 ++----- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/database/login.go b/database/login.go index b003281..8e75355 100644 --- a/database/login.go +++ b/database/login.go @@ -16,15 +16,16 @@ import ( const ( DoesAuthTokenExist = `SELECT EXISTS(SELECT 1 FROM logins WHERE auth_token = $1)` DoesNASUserExist = `SELECT EXISTS(SELECT 1 FROM logins WHERE user_id = $1 AND gsbrcd = $2)` - UpdateUserLogin = `UPDATE logins SET auth_token = $1 WHERE user_id = $2 AND gsbrcd = $3` - InsertUserLogin = `INSERT INTO logins (auth_token, user_id, gsbrcd) VALUES ($1, $2, $3)` + UpdateUserLogin = `UPDATE logins SET auth_token = $1, challenge = $2 WHERE user_id = $3 AND gsbrcd = $4` + InsertUserLogin = `INSERT INTO logins (auth_token, user_id, gsbrcd, challenge) VALUES ($1, $2, $3, $4)` GetNASUserLogin = `SELECT user_id, gsbrcd FROM logins WHERE auth_token = $1 LIMIT 1` - GetUserAuthToken = `SELECT auth_token FROM logins WHERE user_id = $1 AND gsbrcd = $2` + GetNASChallenge = `SELECT challenge FROM logins WHERE auth_token = $1` ) var salt []byte -func GenerateAuthToken(pool *pgxpool.Pool, ctx context.Context, userId int64, gsbrcd string) string { +// GenerateAuthToken generates and stores the auth token for this user as well as a challenge. +func GenerateAuthToken(pool *pgxpool.Pool, ctx context.Context, userId int64, gsbrcd string) (string, string) { var userExists bool err := pool.QueryRow(ctx, DoesNASUserExist, userId, gsbrcd).Scan(&userExists) if err != nil { @@ -47,20 +48,21 @@ func GenerateAuthToken(pool *pgxpool.Pool, ctx context.Context, userId int64, gs authToken = "NDS" + common.RandomString(80) } + challenge := common.RandomString(8) if userExists { // UPDATE rather than INSERT - _, err = pool.Exec(ctx, UpdateUserLogin, authToken, userId, gsbrcd) + _, err = pool.Exec(ctx, UpdateUserLogin, authToken, challenge, userId, gsbrcd) if err != nil { panic(err) } } else { - _, err = pool.Exec(ctx, InsertUserLogin, authToken, userId, gsbrcd) + _, err = pool.Exec(ctx, InsertUserLogin, authToken, userId, gsbrcd, challenge) if err != nil { panic(err) } } - return authToken + return authToken, challenge } func GetNASLogin(pool *pgxpool.Pool, ctx context.Context, authToken string) (int64, string) { @@ -128,3 +130,18 @@ func LoginUserToGPCM(pool *pgxpool.Pool, ctx context.Context, authToken string) return user, true } + +func GetChallenge(pool *pgxpool.Pool, ctx context.Context, authToken string) string { + var challenge string + err := pool.QueryRow(ctx, GetNASChallenge, authToken).Scan(&challenge) + if err != nil { + if err == pgx.ErrNoRows { + // Invalid auth token + return "" + } else { + panic(err) + } + } + + return challenge +} diff --git a/gpcm/login.go b/gpcm/login.go index d970149..8fbf820 100644 --- a/gpcm/login.go +++ b/gpcm/login.go @@ -35,15 +35,20 @@ func (g *GameSpySession) login(command common.GameSpyCommand) { log.Fatalf("Attempt to login twice") } - // TODO: Validate login token with one in database authToken := command.OtherValues["authtoken"] - response := generateResponse(g.Challenge, "0qUekMb4", authToken, command.OtherValues["challenge"]) + challenge := database.GetChallenge(pool, ctx, authToken) + if challenge == "" { + // TODO: Error out + log.Fatalf("Invalid auth token") + } + + response := generateResponse(g.Challenge, challenge, authToken, command.OtherValues["challenge"]) if response != command.OtherValues["response"] { // TODO: Return an error log.Fatalf("response mismatch") } - proof := generateProof(g.Challenge, "0qUekMb4", command.OtherValues["authtoken"], command.OtherValues["challenge"]) + proof := generateProof(g.Challenge, challenge, command.OtherValues["authtoken"], command.OtherValues["challenge"]) // Perform the login with the database. // TODO: Check valid result diff --git a/nas/login.go b/nas/login.go index 7831083..3de5ae3 100644 --- a/nas/login.go +++ b/nas/login.go @@ -6,9 +6,6 @@ import ( "wwfc/logging" ) -// TODO: Generate and store in database!!! -const Challenge = "0qUekMb4" - func login(r *Response, fields map[string]string) map[string]string { moduleName := "NAS:" + r.request.RemoteAddr @@ -38,10 +35,10 @@ func login(r *Response, fields map[string]string) map[string]string { return param } - authToken := database.GenerateAuthToken(pool, ctx, userId, string(gsbrcd)) + authToken, challenge := database.GenerateAuthToken(pool, ctx, userId, gsbrcd) param["returncd"] = "001" - param["challenge"] = Challenge + param["challenge"] = challenge param["token"] = authToken return param }