mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-19 12:21:34 +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)
|
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.");
|
Log.Out(Logs::General, Logs::Error, "Login received after already having logged in.");
|
||||||
return;
|
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);
|
Log.Out(Logs::General, Logs::Error, "Login received packet of size: %u, this would cause a block corruption, discarding.", size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = cs_logged_in;
|
status = cs_logged_in;
|
||||||
|
|
||||||
string e_user;
|
string entered_username;
|
||||||
string e_hash;
|
string entered_password_hash_result;
|
||||||
char *e_buffer = nullptr;
|
|
||||||
unsigned int d_account_id = 0;
|
char *login_packet_buffer = nullptr;
|
||||||
string d_pass_hash;
|
|
||||||
|
unsigned int db_account_id = 0;
|
||||||
|
string db_account_password_hash;
|
||||||
|
|
||||||
#ifdef WIN32
|
#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);
|
int login_packet_buffer_length = strlen(login_packet_buffer);
|
||||||
e_hash.assign(e_buffer, buffer_len);
|
entered_password_hash_result.assign(login_packet_buffer, login_packet_buffer_length);
|
||||||
e_user.assign((e_buffer + buffer_len + 1), strlen(e_buffer + buffer_len + 1));
|
entered_username.assign((login_packet_buffer + login_packet_buffer_length + 1), strlen(login_packet_buffer + login_packet_buffer_length + 1));
|
||||||
|
|
||||||
if(server.options.IsTraceOn())
|
if(server.options.IsTraceOn()) {
|
||||||
{
|
Log.Out(Logs::General, Logs::Debug, "User: %s", entered_username.c_str());
|
||||||
Log.Out(Logs::General, Logs::Debug, "User: %s", e_user.c_str());
|
Log.Out(Logs::General, Logs::Debug, "Hash: %s", entered_password_hash_result.c_str());
|
||||||
Log.Out(Logs::General, Logs::Debug, "Hash: %s", e_hash.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
server.eq_crypto->DeleteHeap(e_buffer);
|
server.eq_crypto->DeleteHeap(login_packet_buffer);
|
||||||
#else
|
#else
|
||||||
e_buffer = DecryptUsernamePassword(data, size, server.options.GetEncryptionMode());
|
login_packet_buffer = DecryptUsernamePassword(data, size, server.options.GetEncryptionMode());
|
||||||
|
|
||||||
int buffer_len = strlen(e_buffer);
|
int login_packet_buffer_length = strlen(login_packet_buffer);
|
||||||
e_hash.assign(e_buffer, buffer_len);
|
entered_password_hash_result.assign(login_packet_buffer, login_packet_buffer_length);
|
||||||
e_user.assign((e_buffer + buffer_len + 1), strlen(e_buffer + buffer_len + 1));
|
entered_username.assign((login_packet_buffer + login_packet_buffer_length + 1), strlen(login_packet_buffer + login_packet_buffer_length + 1));
|
||||||
|
|
||||||
if(server.options.IsTraceOn())
|
if(server.options.IsTraceOn()) {
|
||||||
{
|
Log.Out(Logs::General, Logs::Debug, "User: %s", entered_username.c_str());
|
||||||
Log.Out(Logs::General, Logs::Debug, "User: %s", e_user.c_str());
|
Log.Out(Logs::General, Logs::Debug, "Hash: %s", entered_password_hash_result.c_str());
|
||||||
Log.Out(Logs::General, Logs::Debug, "Hash: %s", e_hash.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_HeapDeleteCharBuffer(e_buffer);
|
_HeapDeleteCharBuffer(login_packet_buffer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool result;
|
bool result;
|
||||||
if(server.db->GetLoginDataFromAccountName(e_user, d_pass_hash, d_account_id) == false)
|
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*/
|
||||||
Log.Out(Logs::General, Logs::Error, "Error logging in, user %s does not exist in the database.", e_user.c_str());
|
if (
|
||||||
result = false;
|
server.config->GetVariable("options", "auto_create_accounts").compare("TRUE") == 0 &&
|
||||||
}
|
server.db->CreateLoginData(entered_username, entered_password_hash_result, db_account_id) == true
|
||||||
else
|
){
|
||||||
{
|
Log.Out(Logs::General, Logs::Error, "User %s does not exist in the database, so we created it...", entered_username.c_str());
|
||||||
if(d_pass_hash.compare(e_hash) == 0)
|
|
||||||
{
|
|
||||||
result = true;
|
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;
|
result = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result)
|
/* Login Accepted */
|
||||||
{
|
if(result) {
|
||||||
server.client_manager->RemoveExistingClient(d_account_id);
|
|
||||||
|
server.client_manager->RemoveExistingClient(db_account_id);
|
||||||
|
|
||||||
in_addr in;
|
in_addr in;
|
||||||
in.s_addr = connection->GetRemoteIP();
|
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();
|
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);
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80);
|
||||||
const LoginLoginRequest_Struct* llrs = (const LoginLoginRequest_Struct *)data;
|
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->failed_attempts = 0;
|
||||||
login_failed_attempts->message = 0x01;
|
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->unknown3[3] = 0x03;
|
||||||
login_failed_attempts->unknown4[3] = 0x02;
|
login_failed_attempts->unknown4[3] = 0x02;
|
||||||
login_failed_attempts->unknown5[0] = 0xe7;
|
login_failed_attempts->unknown5[0] = 0xe7;
|
||||||
@ -304,8 +312,7 @@ void Client::Handle_Login(const char* data, unsigned int size)
|
|||||||
connection->QueuePacket(outapp);
|
connection->QueuePacket(outapp);
|
||||||
delete outapp;
|
delete outapp;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct));
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct));
|
||||||
const LoginLoginRequest_Struct* llrs = (const LoginLoginRequest_Struct *)data;
|
const LoginLoginRequest_Struct* llrs = (const LoginLoginRequest_Struct *)data;
|
||||||
LoginLoginFailed_Struct* llas = (LoginLoginFailed_Struct *)outapp->pBuffer;
|
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 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.
|
* Retrieves the world registration from the long and short names provided.
|
||||||
* Needed for world login procedure.
|
* Needed for world login procedure.
|
||||||
|
|||||||
@ -96,6 +96,33 @@ bool DatabaseMySQL::GetLoginDataFromAccountName(string name, string &password, u
|
|||||||
return false;
|
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,
|
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)
|
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 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.
|
* Retrieves the world registration from the long and short names provided.
|
||||||
* Needed for world login procedure.
|
* Needed for world login procedure.
|
||||||
|
|||||||
@ -47,7 +47,7 @@ struct LoginAccepted_Struct {
|
|||||||
char encrypt[80];
|
char encrypt[80];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoginFailedReply_Struct
|
struct LoginFailedAttempts_Struct
|
||||||
{
|
{
|
||||||
char message; //0x01
|
char message; //0x01
|
||||||
char unknown2[7]; //0x00
|
char unknown2[7]; //0x00
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user