/// <summary> /// Given username and other information authenticate the user from local db /// </summary> /// <param name="username">domain\user name or just name</param> /// <param name="password"></param> /// <param name="authmode"> /// -1 - uninitialized or undefined authentication profile /// 0 - active directory user /// 1 - local database user</param> /// <returns> 0 - authenticated, 1 - user doesnt exist, 2 - user info populated but no data, /// 3 - invalid password, 4 - user is set to inactive/no_access</returns> public int AuthenticateUser(string username, string password, out int authmode) { int retval = USER_NONEXISTENT; //Unintialized - undefined user authmode = -1; //Get the data first //$$$ Centalize this - without locking up a connection DataTools dt = new DataTools(); dt.Provider = provider; dt.ConnectionString = connectionString; dt.OpenConnection(); string[] parameter = { "@username", username }; //!!! What is wrong with parameterized query? //dt.GetResultSet(getUserRecordQuery, parameter); string query = string.Format(getHashQueryTok, username); dt.GetResultSet(query); Dictionary <string, string> results = null; if (dt.rowcount < 1) { return(retval); } //assume unique if (dt.rowcount == 1) { results = dt.GetRowStrings(); } else { //TODO handle this situation - check email, return(USER_NOT_UNIQUE); } //inactive? if (!results["active"].Equals("Y", StringComparison.OrdinalIgnoreCase)) { retval = USER_INACTIVE; } //Active Directory returns.... authmode = results["authmode"].IsNullOrEmpty() ? -1 : Convert.ToInt32(results["authmode"]); if (authmode == -1 || string.IsNullOrEmpty(results["hash"])) { return(USER_NO_DATA); } //Given we have data, verify secret //get the hash and salt string salt = results[SaltCol]; byte[] saltAsBytes = Convert.FromBase64String(salt); string storedHash = results[HashCol]; byte[] storedHashBytes = Convert.FromBase64String(storedHash); //hash the salt and the password passed in byte[] PWtoBeHashed = Encoding.ASCII.GetBytes(password); var hashedPW = HashPasswordWithSalt(PWtoBeHashed, saltAsBytes); //compare the hash in the db from the computed value bool match = hashedPW.SequenceEqual(storedHashBytes); // return appropriate information - including authmode // if (match) { return(USER_AUTHENTICATED); //authenticated } else { return(USER_PW_FAIL); //no match in local db } return(retval); }