mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
Implement Loginserver auto account creation via login.ini option auto_create_accounts = TRUE
This commit is contained in:
parent
d7ca2440d3
commit
ffe46bd4d2
@ -175,83 +175,91 @@ void Client::Handle_SessionReady(const char* data, unsigned int size)
|
||||
|
||||
void Client::Handle_Login(const char* data, unsigned int size)
|
||||
{
|
||||
if(status != cs_waiting_for_login)
|
||||
{
|
||||
if(status != cs_waiting_for_login) {
|
||||
Log.Out(Logs::General, Logs::Error, "Login received after already having logged in.");
|
||||
return;
|
||||
}
|
||||
|
||||
if((size - 12) % 8 != 0)
|
||||
{
|
||||
if((size - 12) % 8 != 0) {
|
||||
Log.Out(Logs::General, Logs::Error, "Login received packet of size: %u, this would cause a block corruption, discarding.", size);
|
||||
return;
|
||||
}
|
||||
|
||||
status = cs_logged_in;
|
||||
|
||||
string e_user;
|
||||
string e_hash;
|
||||
char *e_buffer = nullptr;
|
||||
unsigned int d_account_id = 0;
|
||||
string d_pass_hash;
|
||||
string entered_username;
|
||||
string entered_password_hash_result;
|
||||
|
||||
char *login_packet_buffer = nullptr;
|
||||
|
||||
unsigned int db_account_id = 0;
|
||||
string db_account_password_hash;
|
||||
|
||||
#ifdef WIN32
|
||||
e_buffer = server.eq_crypto->DecryptUsernamePassword(data, size, server.options.GetEncryptionMode());
|
||||
login_packet_buffer = server.eq_crypto->DecryptUsernamePassword(data, size, server.options.GetEncryptionMode());
|
||||
|
||||
int buffer_len = strlen(e_buffer);
|
||||
e_hash.assign(e_buffer, buffer_len);
|
||||
e_user.assign((e_buffer + buffer_len + 1), strlen(e_buffer + buffer_len + 1));
|
||||
int login_packet_buffer_length = strlen(login_packet_buffer);
|
||||
entered_password_hash_result.assign(login_packet_buffer, login_packet_buffer_length);
|
||||
entered_username.assign((login_packet_buffer + login_packet_buffer_length + 1), strlen(login_packet_buffer + login_packet_buffer_length + 1));
|
||||
|
||||
if(server.options.IsTraceOn())
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Debug, "User: %s", e_user.c_str());
|
||||
Log.Out(Logs::General, Logs::Debug, "Hash: %s", e_hash.c_str());
|
||||
if(server.options.IsTraceOn()) {
|
||||
Log.Out(Logs::General, Logs::Debug, "User: %s", entered_username.c_str());
|
||||
Log.Out(Logs::General, Logs::Debug, "Hash: %s", entered_password_hash_result.c_str());
|
||||
}
|
||||
|
||||
server.eq_crypto->DeleteHeap(e_buffer);
|
||||
server.eq_crypto->DeleteHeap(login_packet_buffer);
|
||||
#else
|
||||
e_buffer = DecryptUsernamePassword(data, size, server.options.GetEncryptionMode());
|
||||
login_packet_buffer = DecryptUsernamePassword(data, size, server.options.GetEncryptionMode());
|
||||
|
||||
int buffer_len = strlen(e_buffer);
|
||||
e_hash.assign(e_buffer, buffer_len);
|
||||
e_user.assign((e_buffer + buffer_len + 1), strlen(e_buffer + buffer_len + 1));
|
||||
int login_packet_buffer_length = strlen(login_packet_buffer);
|
||||
entered_password_hash_result.assign(login_packet_buffer, login_packet_buffer_length);
|
||||
entered_username.assign((login_packet_buffer + login_packet_buffer_length + 1), strlen(login_packet_buffer + login_packet_buffer_length + 1));
|
||||
|
||||
if(server.options.IsTraceOn())
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Debug, "User: %s", e_user.c_str());
|
||||
Log.Out(Logs::General, Logs::Debug, "Hash: %s", e_hash.c_str());
|
||||
if(server.options.IsTraceOn()) {
|
||||
Log.Out(Logs::General, Logs::Debug, "User: %s", entered_username.c_str());
|
||||
Log.Out(Logs::General, Logs::Debug, "Hash: %s", entered_password_hash_result.c_str());
|
||||
}
|
||||
|
||||
_HeapDeleteCharBuffer(e_buffer);
|
||||
_HeapDeleteCharBuffer(login_packet_buffer);
|
||||
#endif
|
||||
|
||||
bool result;
|
||||
if(server.db->GetLoginDataFromAccountName(e_user, d_pass_hash, d_account_id) == false)
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Error, "Error logging in, user %s does not exist in the database.", e_user.c_str());
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(d_pass_hash.compare(e_hash) == 0)
|
||||
{
|
||||
if(server.db->GetLoginDataFromAccountName(entered_username, db_account_password_hash, db_account_id) == false) {
|
||||
/* If we have auto_create_accounts enabled in the login.ini, we will process the creation of an account on our own*/
|
||||
if (
|
||||
server.config->GetVariable("options", "auto_create_accounts").compare("TRUE") == 0 &&
|
||||
server.db->CreateLoginData(entered_username, entered_password_hash_result, db_account_id) == true
|
||||
){
|
||||
Log.Out(Logs::General, Logs::Error, "User %s does not exist in the database, so we created it...", entered_username.c_str());
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
else{
|
||||
Log.Out(Logs::General, Logs::Error, "Error logging in, user %s does not exist in the database.", entered_username.c_str());
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(db_account_password_hash.compare(entered_password_hash_result) == 0) {
|
||||
result = true;
|
||||
}
|
||||
else {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(result)
|
||||
{
|
||||
server.client_manager->RemoveExistingClient(d_account_id);
|
||||
/* Login Accepted */
|
||||
if(result) {
|
||||
|
||||
server.client_manager->RemoveExistingClient(db_account_id);
|
||||
|
||||
in_addr in;
|
||||
in.s_addr = connection->GetRemoteIP();
|
||||
server.db->UpdateLSAccountData(d_account_id, string(inet_ntoa(in)));
|
||||
|
||||
server.db->UpdateLSAccountData(db_account_id, string(inet_ntoa(in)));
|
||||
GenerateKey();
|
||||
account_id = d_account_id;
|
||||
account_name = e_user;
|
||||
|
||||
account_id = db_account_id;
|
||||
account_name = entered_username;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80);
|
||||
const LoginLoginRequest_Struct* llrs = (const LoginLoginRequest_Struct *)data;
|
||||
@ -267,7 +275,7 @@ void Client::Handle_Login(const char* data, unsigned int size)
|
||||
|
||||
login_failed_attempts->failed_attempts = 0;
|
||||
login_failed_attempts->message = 0x01;
|
||||
login_failed_attempts->lsid = d_account_id;
|
||||
login_failed_attempts->lsid = db_account_id;
|
||||
login_failed_attempts->unknown3[3] = 0x03;
|
||||
login_failed_attempts->unknown4[3] = 0x02;
|
||||
login_failed_attempts->unknown5[0] = 0xe7;
|
||||
@ -304,8 +312,7 @@ void Client::Handle_Login(const char* data, unsigned int size)
|
||||
connection->QueuePacket(outapp);
|
||||
delete outapp;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct));
|
||||
const LoginLoginRequest_Struct* llrs = (const LoginLoginRequest_Struct *)data;
|
||||
LoginLoginFailed_Struct* llas = (LoginLoginFailed_Struct *)outapp->pBuffer;
|
||||
|
||||
@ -44,6 +44,8 @@ public:
|
||||
*/
|
||||
virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id) { return false; }
|
||||
|
||||
virtual bool CreateLoginData(std::string name, std::string &password, unsigned int &id) { return false; }
|
||||
|
||||
/**
|
||||
* Retrieves the world registration from the long and short names provided.
|
||||
* Needed for world login procedure.
|
||||
|
||||
@ -96,6 +96,33 @@ bool DatabaseMySQL::GetLoginDataFromAccountName(string name, string &password, u
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool DatabaseMySQL::CreateLoginData(string name, string &password, unsigned int &id)
|
||||
{
|
||||
if (!database) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
stringstream query(stringstream::in | stringstream::out);
|
||||
|
||||
query << "INSERT INTO " << server.options.GetAccountTable() << " (AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) ";
|
||||
query << " VALUES('" << name << "', '" << password << "', 'local_creation', NOW(), '127.0.0.1'); ";
|
||||
|
||||
if (mysql_query(database, query.str().c_str()) != 0) {
|
||||
Log.Out(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str());
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
id = mysql_insert_id(database);
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Error, "Mysql query returned no result: %s", query.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, unsigned int &id, string &desc, unsigned int &list_id,
|
||||
unsigned int &trusted, string &list_desc, string &account, string &password)
|
||||
{
|
||||
|
||||
@ -59,6 +59,8 @@ public:
|
||||
*/
|
||||
virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id);
|
||||
|
||||
virtual bool CreateLoginData(std::string name, std::string &password, unsigned int &id);
|
||||
|
||||
/**
|
||||
* Retrieves the world registration from the long and short names provided.
|
||||
* Needed for world login procedure.
|
||||
|
||||
@ -47,7 +47,7 @@ struct LoginAccepted_Struct {
|
||||
char encrypt[80];
|
||||
};
|
||||
|
||||
struct LoginFailedReply_Struct
|
||||
struct LoginFailedAttempts_Struct
|
||||
{
|
||||
char message; //0x01
|
||||
char unknown2[7]; //0x00
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user