fix compatibility with nexus dash (#1011)

* add some more utility to the masterserver -a command
fix compatability with nexus dash

* cleanup code some more
user logger where it makes sense
only take in password if it is needed
log a better error if account cannot be created

* update message

* return before success statement if catching error
This commit is contained in:
Aaron Kimbrell 2023-03-05 13:11:32 -06:00 committed by GitHub
parent e524b86e12
commit 9d65d871d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 25 deletions

View File

@ -212,43 +212,81 @@ int main(int argc, char** argv) {
std::cout << "Enter a username: "; std::cout << "Enter a username: ";
std::cin >> username; std::cin >> username;
std::unique_ptr<sql::PreparedStatement> userLookupStatement(Database::CreatePreppedStmt("SELECT id FROM accounts WHERE name=? LIMIT 1;"));
userLookupStatement->setString(1, username.c_str());
std::unique_ptr<sql::ResultSet> res(userLookupStatement->executeQuery());
if (res->rowsCount() > 0) {
Game::logger->Log("MasterServer", "Account with name \"%s\" already exists", username.c_str());
std::cout << "Do you want to change the password of that account? [y/n]?";
std::string prompt = "";
std::cin >> prompt;
if (prompt == "y" || prompt == "yes"){
uint32_t accountId = 0;
res->next();
accountId = res->getUInt(1);
if (accountId == 0) return EXIT_FAILURE;
//Read the password from the console without echoing it. //Read the password from the console without echoing it.
#ifdef __linux__ #ifdef __linux__
//This function is obsolete, but it only meant to be used by the //This function is obsolete, but it only meant to be used by the
//sysadmin to create their first account. //sysadmin to create their first account.
password = getpass("Enter a password: "); password = getpass("Enter a password: ");
#else #else
std::cout << "Enter a password: "; std::cout << "Enter a password: ";
std::cin >> password; std::cin >> password;
#endif #endif
//Generate new hash for bcrypt
// Regenerate hash based on new password
char salt[BCRYPT_HASHSIZE]; char salt[BCRYPT_HASHSIZE];
char hash[BCRYPT_HASHSIZE]; char hash[BCRYPT_HASHSIZE];
int32_t bcryptState = ::bcrypt_gensalt(12, salt); int32_t bcryptState = ::bcrypt_gensalt(12, salt);
assert(bcryptState == 0);
bcryptState = ::bcrypt_hashpw(password.c_str(), salt, hash);
assert(bcryptState == 0); assert(bcryptState == 0);
bcryptState = ::bcrypt_hashpw(password.c_str(), salt, hash); std::unique_ptr<sql::PreparedStatement> userUpdateStatement(Database::CreatePreppedStmt("UPDATE accounts SET password = ? WHERE id = ?;"));
userUpdateStatement->setString(1, std::string(hash, BCRYPT_HASHSIZE).c_str());
userUpdateStatement->setUInt(2, accountId);
userUpdateStatement->execute();
Game::logger->Log("MasterServer", "Account \"%s\" password updated successfully!", username.c_str());
} else {
Game::logger->Log("MasterServer", "Account \"%s\" was not updated.", username.c_str());
}
return EXIT_SUCCESS;
}
//Read the password from the console without echoing it.
#ifdef __linux__
//This function is obsolete, but it only meant to be used by the
//sysadmin to create their first account.
password = getpass("Enter a password: ");
#else
std::cout << "Enter a password: ";
std::cin >> password;
#endif
//Generate new hash for bcrypt
char salt[BCRYPT_HASHSIZE];
char hash[BCRYPT_HASHSIZE];
int32_t bcryptState = ::bcrypt_gensalt(12, salt);
assert(bcryptState == 0);
bcryptState = ::bcrypt_hashpw(password.c_str(), salt, hash);
assert(bcryptState == 0); assert(bcryptState == 0);
//Create account //Create account
try {
auto* statement = Database::CreatePreppedStmt("INSERT INTO accounts (name, password, ""gm_level) VALUES (?, ?, ?);"); std::unique_ptr<sql::PreparedStatement> statement(Database::CreatePreppedStmt("INSERT INTO accounts (name, password, gm_level) VALUES (?, ?, ?);"));
statement->setString(1, username.c_str()); statement->setString(1, username.c_str());
statement->setString(2, std::string(hash, BCRYPT_HASHSIZE).c_str()); statement->setString(2, std::string(hash, BCRYPT_HASHSIZE).c_str());
statement->setInt(3, 9); statement->setInt(3, 9);
statement->execute(); statement->execute();
} catch(sql::SQLException& e) {
Game::logger->Log("MasterServer", "A SQL error occurred!:\n %s", e.what());
return EXIT_FAILURE;
}
delete statement; Game::logger->Log("MasterServer", "Account created successfully!");
std::cout << "Account created successfully!\n";
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -0,0 +1 @@
ALTER TABLE accounts MODIFY play_key_id INT DEFAULT NULL;