Add local credential validation logic

This commit is contained in:
Akkadius 2019-08-04 04:16:14 -05:00
parent 5ff0f4851e
commit b0d33f094d
8 changed files with 189 additions and 9 deletions

View File

@ -143,6 +143,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General); log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Notice].log_to_console = static_cast<uint8>(Logs::General); log_settings[Logs::Notice].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General); log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Debug].log_to_console = static_cast<uint8>(Logs::General);
/** /**
* Set Category enabled status on defaults * Set Category enabled status on defaults

View File

@ -134,3 +134,58 @@ bool AccountManagement::CreateLoginserverWorldAdminAccount(
return false; return false;
} }
/**
* @param in_account_username
* @param in_account_password
* @return
*/
bool AccountManagement::CheckLoginserverUserCredentials(
const std::string &in_account_username,
const std::string &in_account_password,
const std::string &source_loginserver
)
{
auto mode = server.options.GetEncryptionMode();
Database::DbLoginServerAccount
login_server_admin = server.db->GetLoginServerAccountByAccountName(
in_account_username,
source_loginserver
);
if (!login_server_admin.loaded) {
LogError(
"CheckLoginUserCredentials account [{0}] source_loginserver [{1}] not found!",
in_account_username,
source_loginserver
);
return false;
}
bool validated_credentials = eqcrypt_verify_hash(
in_account_username,
in_account_password,
login_server_admin.account_password,
mode
);
if (!validated_credentials) {
LogError(
"CheckLoginUserCredentials account [{0}] source_loginserver [{1}] invalid credentials!",
in_account_username,
source_loginserver
);
return false;
}
LogDebug(
"CheckLoginUserCredentials account [{0}] source_loginserver [{1}] credentials validated success!",
in_account_username,
source_loginserver
);
return validated_credentials;
}

View File

@ -48,6 +48,17 @@ public:
const std::string &last_name = "", const std::string &last_name = "",
const std::string &ip_address = "" const std::string &ip_address = ""
); );
/**
* @param in_account_username
* @param in_account_password
* @return
*/
static bool CheckLoginserverUserCredentials(
const std::string &in_account_username,
const std::string &in_account_password,
const std::string &source_loginserver = "local"
);
}; };

View File

@ -730,3 +730,40 @@ Database::DbLoginServerAdmin Database::GetLoginServerAdmin(const std::string &ac
return login_server_admin; return login_server_admin;
} }
/**
* @param account_name
* @return
*/
Database::DbLoginServerAccount Database::GetLoginServerAccountByAccountName(
const std::string &account_name,
const std::string &source_loginserver
)
{
auto query = fmt::format(
"SELECT id, account_name, account_password, account_email, source_loginserver, last_ip_address, last_login_date, "
"created_at, updated_at"
" FROM login_accounts WHERE account_name = '{0}' and source_loginserver = '{1}' LIMIT 1",
EscapeString(account_name),
EscapeString(source_loginserver)
);
auto results = QueryDatabase(query);
Database::DbLoginServerAccount login_server_account{};
if (results.RowCount() == 1) {
auto row = results.begin();
login_server_account.loaded = true;
login_server_account.id = std::stoi(row[0]);
login_server_account.account_name = row[1];
login_server_account.account_password = row[2];
login_server_account.account_email = row[3];
login_server_account.source_loginserver = row[4];
login_server_account.last_ip_address = row[5];
login_server_account.last_login_date = row[6];
login_server_account.created_at = row[7];
login_server_account.updated_at = row[8];
}
return login_server_account;
}

View File

@ -248,6 +248,24 @@ public:
Database::DbLoginServerAdmin GetLoginServerAdmin(const std::string &account_name); Database::DbLoginServerAdmin GetLoginServerAdmin(const std::string &account_name);
struct DbLoginServerAccount {
bool loaded = false;
uint32 id;
std::string account_name;
std::string account_password;
std::string account_email;
std::string source_loginserver;
std::string last_login_date;
std::string last_ip_address;
std::string created_at;
std::string updated_at;
};
Database::DbLoginServerAccount GetLoginServerAccountByAccountName(
const std::string &account_name,
const std::string &source_loginserver = "local"
);
/** /**
* @param name * @param name
* @param password * @param password

View File

@ -51,6 +51,7 @@ namespace LoginserverCommandHandler {
* Register commands * Register commands
*/ */
function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount;
function_map["login-user:check-credentials"] = &LoginserverCommandHandler::CheckLoginserverUserCredentials;
function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken; function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken;
function_map["web-api-token:list"] = &LoginserverCommandHandler::ListLoginserverApiTokens; function_map["web-api-token:list"] = &LoginserverCommandHandler::ListLoginserverApiTokens;
function_map["world-admin:create"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; function_map["world-admin:create"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount;
@ -179,4 +180,31 @@ namespace LoginserverCommandHandler {
); );
} }
/**
* @param argc
* @param argv
* @param cmd
* @param description
*/
void CheckLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description)
{
description = "Check user login credentials";
std::vector<std::string> arguments = {
"--username",
"--password"
};
std::vector<std::string> options = {};
if (cmd[{"-h", "--help"}]) {
return;
}
EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv);
AccountManagement::CheckLoginserverUserCredentials(
cmd("--username").str(),
cmd("--password").str()
);
}
} }

View File

@ -30,6 +30,7 @@ namespace LoginserverCommandHandler {
void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd, std::string &description); void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd, std::string &description);
void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd, std::string &description); void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd, std::string &description);
void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd, std::string &description); void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd, std::string &description);
void CheckLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description);
}; };

View File

@ -87,6 +87,37 @@ namespace LoginserverWebserver {
LoginserverWebserver::SendResponse(response, res); LoginserverWebserver::SendResponse(response, res);
} }
); );
api.Post(
"/account/credentials/validate/local", [](const httplib::Request &request, httplib::Response &res) {
LoginserverWebserver::TokenManager::AuthCanRead(request, res);
Json::Value request_body = LoginserverWebserver::ParseRequestBody(request);
std::string username = request_body.get("username", "").asString();
std::string password = request_body.get("password", "").asString();
std::string email = request_body.get("email", "").asString();
Json::Value response;
if (username.empty() || password.empty()) {
response["message"] = "Username or password not set";
LoginserverWebserver::SendResponse(response, res);
return;
}
bool credentials_valid = AccountManagement::CheckLoginserverUserCredentials(
username,
password
);
if (credentials_valid) {
response["message"] = "Credentials valid!";
}
else {
response["error"] = "Credentials invalid!";
}
LoginserverWebserver::SendResponse(response, res);
}
);
} }
/** /**
@ -146,8 +177,7 @@ namespace LoginserverWebserver {
res.set_header("response_set", "true"); res.set_header("response_set", "true");
LogWarning( LogWarning(
"AuthCanRead access failure | token [{0}] remote_address [{1}] user_agent [{2}]", "AuthCanRead access failure remote_address [{0}] user_agent [{1}]",
user_token.token,
user_token.remote_address, user_token.remote_address,
user_token.user_agent user_token.user_agent
); );
@ -174,8 +204,7 @@ namespace LoginserverWebserver {
res.set_header("response_set", "true"); res.set_header("response_set", "true");
LogWarning( LogWarning(
"AuthCanWrite access failure | token [{0}] remote_address [{1}] user_agent [{2}]", "AuthCanWrite access failure remote_address [{0}] user_agent [{1}]",
user_token.token,
user_token.remote_address, user_token.remote_address,
user_token.user_agent user_token.user_agent
); );