Store NAS challenge in database

This commit is contained in:
Sketch
2023-11-11 12:06:05 -05:00
parent 32c128c0fe
commit 99915ae357
3 changed files with 34 additions and 15 deletions

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}