Exemple #1
0
        public void GenerateBackups()
        {
            StringBuilder res = new StringBuilder();

            for (int i = 0; i < 5; i++)
            {
                res.Append(ForumUtilities.GetRandomHex(8)).Append("|");
            }
            Update(Builders <BsonDocument> .Update.Set(TFA_BACKUPS, res.ToString()));
        }
Exemple #2
0
        public SetupCode GenerateTFA()
        {
            TwoFactorAuthenticator tfao = new TwoFactorAuthenticator();
            string    ihex = ForumUtilities.GetRandomB64(6);
            SetupCode sc   = tfao.GenerateSetupCode("Frenetic LLC", UserName, ihex, 300, 300, true);

            Update(Builders <BsonDocument> .Update.Set(TFA_INTERNAL, ihex));
            GenerateBackups();
            return(sc);
        }
        public BsonDocument GenerateNewUser(string uname, string pw, string email)
        {
            uname = uname.ToLowerInvariant();
            BsonDocument bd = CreateEmptyUserDocument();

            bd[Account.USERNAME]        = uname;
            bd[Account.PASSWORD]        = ForumUtilities.Hash(pw, uname);
            bd[Account.EMAIL]           = email;
            bd[Account.UID]             = getIDFor(TF_USERS);
            bd[Account.ACTIVATION_CODE] = ForumUtilities.GetRandomHex(32);
            return(bd);
        }
Exemple #4
0
        public string GenerateSession()
        {
            string sess = ForumUtilities.GetRandomHex(32);
            FilterDefinition <BsonDocument> fd = Builders <BsonDocument> .Filter.Eq(UID, UserID);

            UpdateDefinition <BsonDocument> ud = Builders <BsonDocument> .Update.AddToSet(WEBSESS_CODES, sess);

            FindOneAndUpdateOptions <BsonDocument> foauo = new FindOneAndUpdateOptions <BsonDocument>();

            foauo.IsUpsert = true;
            UserBase.FindOneAndUpdate(fd, ud, foauo);
            return(sess);
        }
Exemple #5
0
        public string GenerateOneUseSess(string typ)
        {
            if (!IsValidSessType(typ))
            {
                return(null);
            }
            string sess = ForumUtilities.GetRandomHex(32);
            FilterDefinition <BsonDocument> fd = Builders <BsonDocument> .Filter.Eq(UID, UserID);

            UpdateDefinition <BsonDocument> ud = Builders <BsonDocument> .Update.Set(PREFIX_ONE_USE_SESS + typ, sess + "/" + DateTimeOffset.UtcNow.ToUnixTimeSeconds());

            FindOneAndUpdateOptions <BsonDocument> foauo = new FindOneAndUpdateOptions <BsonDocument>();

            foauo.IsUpsert = true;
            UserBase.FindOneAndUpdate(fd, ud, foauo);
            return(sess);
        }
Exemple #6
0
        public string GenerateSessMaster(string typ)
        {
            if (!IsValidSessType(typ))
            {
                return(null);
            }
            string sess = ForumUtilities.GetRandomHex(32);
            FilterDefinition <BsonDocument> fd = Builders <BsonDocument> .Filter.Eq(UID, UserID);

            UpdateDefinition <BsonDocument> ud = Builders <BsonDocument> .Update.AddToSet(PREFIX_SESS_MASTER + typ, sess);

            FindOneAndUpdateOptions <BsonDocument> foauo = new FindOneAndUpdateOptions <BsonDocument>();

            foauo.IsUpsert = true;
            UserBase.FindOneAndUpdate(fd, ud, foauo);
            return(sess);
        }
Exemple #7
0
        public LoginResult CanLogin(string pw, string tfa, bool checkTFA = true)
        {
            BsonDocument acc = Projected(PASSWORD, BANNED, USES_TFA, ACCOUNT_TYPE);

            if (acc == null)
            {
                return(LoginResult.MISSING);
            }
            if (acc[ACCOUNT_TYPE].AsInt32 != AT_VALID)
            {
                return(LoginResult.NOT_COMPLETED_REGISTRATION);
            }
            if (acc[BANNED].AsBoolean)
            {
                return(LoginResult.BANNED);
            }
            string opass = acc[PASSWORD].AsString;

            string[] dat = opass.Split(':');
            if (dat[0] == "v2")
            {
                string hash = ForumUtilities.HashV2(pw, UserName, dat[1]);
                byte[] b1   = ForumUtilities.Enc.GetBytes(hash);
                byte[] b2   = ForumUtilities.Enc.GetBytes(opass);
                if (!ForumUtilities.SlowEquals(b1, b2))
                {
                    return(LoginResult.BAD_PASSWORD);
                }
            }
            else
            {
                // TODO: Error log upload! "Invalid password for " + UserName + ": unrecognized version, they will be unable to login without a reset!"
                return(LoginResult.BAD_PASSWORD);
            }
            if (checkTFA && acc[USES_TFA].AsBoolean)
            {
                if (!CheckTFA(tfa))
                {
                    return(LoginResult.BAD_TFA);
                }
            }
            return(LoginResult.ALLOWED);
        }
        public void InstallDefaultUser(string pw)
        {
            IMongoCollection <BsonDocument> userbase = Database.GetCollection <BsonDocument>(TF_USERS);
            BsonDocument user = CreateEmptyUserDocument();

            user[Account.UID]          = (long)0;
            user[Account.USERNAME]     = "admin";
            user[Account.DISPLAY_NAME] = "Administrator";
            user[Account.PASSWORD]     = ForumUtilities.Hash(pw, "admin");
            user[Account.ACTIVE]       = true;
            user[Account.ACCOUNT_TYPE] = Account.AT_VALID;
            FilterDefinition <BsonDocument> fd = Builders <BsonDocument> .Filter.Eq(Account.UID, (long)0);

            UpdateOptions uo = new UpdateOptions()
            {
                IsUpsert = true
            };

            userbase.ReplaceOneAsync(fd, user, uo).Wait();
        }
        public LoginResult AttemptLogin(string username, string password, string tfa)
        {
            Account acc = Database.GetAccount(username);

            if (acc == null)
            {
                return(LoginResult.MISSING);
            }
            LoginResult res = acc.CanLogin(password, tfa);

            if (res != LoginResult.ALLOWED)
            {
                return(res);
            }
            acc.Update(Builders <BsonDocument> .Update.Set(Account.LAST_LOGIN_DATE, ForumUtilities.DateNow()));
            CookieOptions co_uid = new CookieOptions();

            co_uid.HttpOnly = true; // NOTE: Microsoft HttpOnly documentation appears to be backwards?
            co_uid.Expires  = DateTimeOffset.Now.AddYears(1);
            Response.Cookies.Append("session_uid", acc.UserID.ToString(), co_uid);
            Response.Cookies.Append("session_val", acc.GenerateSession(), co_uid);
            return(LoginResult.ALLOWED);
        }
        public BsonDocument CreateEmptyUserDocument()
        {
            BsonDocument user = new BsonDocument();

            user[Account.UID]             = (long)-1;
            user[Account.USERNAME]        = "example";
            user[Account.PASSWORD]        = "This Won't Be Usable";
            user[Account.EMAIL]           = "*****@*****.**";
            user[Account.DISPLAY_NAME]    = "Example";
            user[Account.BANNED]          = false;
            user[Account.BANNED_UNTIL]    = "";
            user[Account.BAN_REASON]      = "";
            user[Account.ACTIVE]          = false;
            user[Account.ACTIVATION_CODE] = "<Unusable>?";
            user[Account.REGISTER_DATE]   = ForumUtilities.DateNow();
            user[Account.LAST_LOGIN_DATE] = "Never";
            user[Account.USES_TFA]        = false;
            user[Account.TFA_BACKUPS]     = "";
            user[Account.TFA_INTERNAL]    = "";
            user[Account.ACCOUNT_TYPE]    = Account.AT_INCOMPLETE;
            user[Account.ROLES]           = new BsonArray(new BsonValue[] { });
            return(user);
        }
Exemple #11
0
 public bool IsValidSessType(string inp)
 {
     // TODO: Match against database list
     return(ForumUtilities.ValidateUsername(inp) && inp.ToLowerInvariant() == inp);
 }