func handleLoginForgotPassword(loginConfig *loginConfigDef, res http.ResponseWriter, req *http.Request, userName string) { var forgotPasswordData forgotPasswordDataDef var gkErr *gkerr.GkErrDef forgotPasswordData.Title = "forgotPassword" forgotPasswordData.LoginWebAddressPrefix = loginConfig.LoginWebAddressPrefix forgotPasswordData.UserName = userName forgotPasswordData.ErrorList = make([]string, 0, 0) var gotError bool if userName == "" { forgotPasswordData.ErrorList = append(forgotPasswordData.ErrorList, "user name cannot be blank") forgotPasswordData.UserNameError = genErrorMarker() gotError = true } var dbUser *database.DbUserDef if !gotError { var gkDbCon *database.GkDbConDef gkDbCon, gkErr = database.NewGkDbCon(loginConfig.DatabaseUserName, loginConfig.DatabasePassword, loginConfig.DatabaseHost, loginConfig.DatabasePort, loginConfig.DatabaseDatabase) if gkErr != nil { gklog.LogGkErr("database.NewGkDbCon", gkErr) redirectToError("database.NewGkDbCon", res, req) return } defer gkDbCon.Close() dbUser, gkErr = gkDbCon.GetUser( forgotPasswordData.UserName) if gkErr != nil { if gkErr.GetErrorId() == database.ERROR_ID_NO_ROWS_FOUND { forgotPasswordData.ErrorList = append(forgotPasswordData.ErrorList, "no such user") forgotPasswordData.UserNameError = genErrorMarker() gotError = true } else { gklog.LogGkErr("gbDbCon.GetUser", gkErr) redirectToError("gbDbCon.GetUser", res, req) return } } } var err error if !gotError { // create temporary forgot password token //var token []byte var forgotPasswordEmailData forgotPasswordEmailDataDef forgotPasswordEmailData.LoginWebAddressPrefix = loginConfig.LoginWebAddressPrefix forgotPasswordEmailData.UserName = userName var token []byte token, err = sec.GenForgotPasswordToken() if err != nil { gkErr = gkerr.GenGkErr("GenForgotPasswordToken", err, ERROR_ID_GEN_TOKEN) gklog.LogGkErr("GenForgotPasswordToken", gkErr) redirectToError("GenForgotPasswordToken", res, req) return } forgotPasswordEmailData.Token = string(token) gkErr = _forgotPasswordEmailTemplate.Build(forgotPasswordEmailData) if gkErr != nil { gklog.LogGkErr("_forgotPasswordEmailTemplate.Build", gkErr) redirectToError("_forgotPasswordEmailTemplate.Build", res, req) return } var message []byte message, gkErr = _forgotPasswordEmailTemplate.GetBytes() if gkErr != nil { gklog.LogGkErr("_forgotPasswordEmailTemplate.GetBytes", gkErr) redirectToError("_forgotPasswordEmailTemplate.GetBytes", res, req) return } toArray := make([]string, 1, 1) toArray[0] = dbUser.Email var sendId string AddNewToken(string(token), userName) sendId, gkErr = gknet.SendEmail(loginConfig.EmailServer, loginConfig.ServerFromEmail, toArray, "gourdian knot forgotten password", message) if gkErr != nil { gklog.LogGkErr("gknet.SendEmail", gkErr) } else { gklog.LogTrace("forgot email sent to: " + toArray[0] + " sendId: [" + sendId + "]") } } if gotError { gkErr = _forgotPasswordTemplate.Build(forgotPasswordData) if gkErr != nil { gklog.LogGkErr("_forgotPasswordTemplate.Build", gkErr) redirectToError("_forgotPasswordTemplate.Build", res, req) return } gkErr = _forgotPasswordTemplate.Send(res, req) if gkErr != nil { gklog.LogGkErr("_forgotPasswordTemplate.send", gkErr) } } else { http.Redirect(res, req, _loginServer, http.StatusFound) } }
func handleLoginLogin(loginConfig *loginConfigDef, res http.ResponseWriter, req *http.Request, userName string, password string) { var loginData loginDataDef var gkErr *gkerr.GkErrDef var gotError bool loginData.Title = "login" loginData.UserName = userName loginData.LoginWebAddressPrefix = loginConfig.LoginWebAddressPrefix if loginData.UserName == "" { loginData.ErrorList = append(loginData.ErrorList, "invalid user name") loginData.UserNameError = genErrorMarker() gotError = true } if password == "" { loginData.ErrorList = append(loginData.ErrorList, "invalid password") loginData.PasswordError = genErrorMarker() gotError = true } var passwordHashFromUser []byte var dbUser *database.DbUserDef var gkDbCon *database.GkDbConDef if !gotError { gkDbCon, gkErr = database.NewGkDbCon(loginConfig.DatabaseUserName, loginConfig.DatabasePassword, loginConfig.DatabaseHost, loginConfig.DatabasePort, loginConfig.DatabaseDatabase) if gkErr != nil { gklog.LogGkErr("database.NewGkDbCon", gkErr) redirectToError("database.NewGkDbCon", res, req) return } defer gkDbCon.Close() dbUser, gkErr = gkDbCon.GetUser(loginData.UserName) if gkErr != nil { if gkErr.GetErrorId() == database.ERROR_ID_NO_ROWS_FOUND { var passwordSalt string password = "******" passwordSalt = "abc123QWE." // make it take the same amount of time // between no user and invalid password passwordHashFromUser = sec.GenPasswordHashSlow([]byte(password), []byte(passwordSalt)) loginData.ErrorList = append(loginData.ErrorList, "invalid username/password") loginData.UserNameError = genErrorMarker() loginData.PasswordError = genErrorMarker() gotError = true } else { gklog.LogGkErr("gkDbCon.GetPasswordHashAndSalt", gkErr) redirectToError("gkDbCon.GetPasswordhashAndSalt", res, req) return } } } if !gotError { passwordHashFromUser = sec.GenPasswordHashSlow([]byte(password), []byte(dbUser.PasswordSalt)) gklog.LogTrace(fmt.Sprintf("dbUser: %v fromUser: %s", dbUser, passwordHashFromUser)) if dbUser.PasswordHash != string(passwordHashFromUser) { loginData.ErrorList = append(loginData.ErrorList, "invalid username/password") loginData.UserNameError = genErrorMarker() loginData.PasswordError = genErrorMarker() gotError = true } } if gotError { // for security, to slow down an attack that is guessing passwords, // sleep between 100 and 190 milliseconds time.Sleep(sec.GetSleepDurationPasswordInvalid()) gkErr = _loginTemplate.Build(loginData) if gkErr != nil { gklog.LogGkErr("_loginTemplate.Build", gkErr) redirectToError("_loginTemplate.Build", res, req) return } gkErr = _loginTemplate.Send(res, req) if gkErr != nil { gklog.LogGkErr("_loginTemplate.Send", gkErr) return } } else { gkErr = gkDbCon.UpdateUserLoginDate(dbUser.UserName) if gkErr != nil { // this error is going to be logged // but the user is not going to be redirected to an error // because they are going to be redirected to the game server // and it is not critical that their login date be updated. gklog.LogGkErr("_loginTemplate.Send", gkErr) } var gameRedirect string gameRedirect, gkErr = getGameRedirect(loginConfig, loginData.UserName) if gkErr != nil { gklog.LogGkErr("getGameRedirect", gkErr) return } http.Redirect(res, req, gameRedirect, http.StatusFound) } }