View Single Post
  #1  
Old 03-26-2008, 05:59 PM
TheLieka
Developer
 
Join Date: Oct 2004
Location: THE ATL (wut wut)
Posts: 325
Default Banning IPs at the World Server (Integrated into Rules)

I want to preface that I have not tested this code. I do believe that it will accomplish its goal (and I know that it compiles), but I don't have a dev server up to test it at the moment.

Give it a shot and let me know what you think.

.\common\database.h

Change:

Code:
	bool	CheckNameFilter(const char* name);
	bool	CheckUsedName(const char* name);
	int32	GetAccountIDByChar(const char* charname, int32* oCharID = 0);
	uint32	GetAccountIDByChar(uint32 char_id);
	int32	GetAccountIDByName(const char* accname, sint16* status = 0, int32* lsid = 0);
	void	GetAccountName(int32 accountid, char* name, int32* oLSAccountID = 0);
	void	GetCharName(int32 char_id, char* name);
	int32	GetCharacterInfo(const char* iName, int32* oAccID = 0, int32* oZoneID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
	int32	GetCharacterID(const char *name);
To:

Code:
	bool	CheckNameFilter(const char* name);
	bool	CheckUsedName(const char* name);
	int32	GetAccountIDByChar(const char* charname, int32* oCharID = 0);
	uint32	GetAccountIDByChar(uint32 char_id);
	int32	GetAccountIDByName(const char* accname, sint16* status = 0, int32* lsid = 0);
	void	GetAccountName(int32 accountid, char* name, int32* oLSAccountID = 0);
	void	GetCharName(int32 char_id, char* name);
	int32	GetCharacterInfo(const char* iName, int32* oAccID = 0, int32* oZoneID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
	int32	GetCharacterID(const char *name);
	bool	CheckBannedIPs(int32 loginIP); //Lieka Edit:  Check incomming connection against banned IP table.


.\common\database.cpp


After:

Code:
int32 Database::CheckLogin(const char* name, const char* password, sint16* oStatus) {
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	
	if(strlen(name) >= 50 || strlen(password) >= 50)
		return(0);
	
	char tmpUN[100];
	char tmpPW[100];
	DoEscapeString(tmpUN, name, strlen(name));
	DoEscapeString(tmpPW, password, strlen(password));
	
	if (RunQuery(query, MakeAnyLenString(&query, 
		"SELECT id, status FROM account WHERE name='%s' AND password is not null "
		"and length(password) > 0 and (password='%s' or password=MD5('%s'))", 
		tmpUN, tmpPW, tmpPW), errbuf, &result)) {
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1)
		{
			row = mysql_fetch_row(result);
			int32 id = atoi(row[0]);
			if (oStatus)
				*oStatus = atoi(row[1]);
			mysql_free_result(result);
			return id;
		}
		else
		{
			mysql_free_result(result);
			return 0;
		}
		mysql_free_result(result);
	}
	else
	{
		cerr << "Error in CheckLogin query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return false;
	}
	
	return 0;
}
Add:

Code:
//Lieka Edit:  Get Banned IP Address List - Only return false if the incoming connection's IP address is not present in the banned_ips table.
bool Database::CheckBannedIPs(int32 loginIP)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT ip_address FROM Banned_IPs WHERE ip_address='%i'", loginIP), errbuf, &result)) {
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1)
		{
			mysql_free_result(result);
			return true;
		}
		else
		{
			mysql_free_result(result);
			return false;
		}
		mysql_free_result(result);
	}
	else
	{
		cerr << "Error in CheckBannedIPs query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return true;
	}
	
	return true;
}
//End Lieka Edit
.\world\client.cpp

After:
Code:
		case OP_EnterWorld: // Enter world
		{
			if (GetAccountID() == 0) {
				clog(WORLD__CLIENT_ERR,"Enter world with no logged in account");
				eqs->Close();
				break;
			}
			if(GetAdmin() < 0)
			{
				clog(WORLD__CLIENT,"Account banned or suspended.");
				eqs->Close();
				break;
			}
Add:

Code:
//Lieka Edit Begin
				if (RuleI(World, UseBannedIPsTable) == 1) {
				if (database.CheckBannedIPs(this->GetIP())) {//Lieka Edit: Check banned_ips table against incoming connection
				client_list.RemoveBannedIPs(this->GetIP());	//Lieka Edit:  Terminate all sessions with this IP address.
				clog(WORLD__CLIENT,"IP Address banned.");
				}
			}//Lieka Edit End

.\world\clientlist.h

After:

Code:
ClientListEntry* GetCLE(int32 iID);
Add:

Code:
void	RemoveBannedIPs(int32 bIP); //Lieka Edit


.\world\clientlist.cpp

After:

Code:
ClientListEntry* ClientList::GetCLE(int32 iID) {
	LinkedListIterator<ClientListEntry*> iterator(clientlist);


	iterator.Reset();
	while(iterator.MoreElements()) {
		if (iterator.GetData()->GetID() == iID) {
			return iterator.GetData();
		}
		iterator.Advance();
	}
	return 0;
}
Add:

Code:
 //Lieka Edit Begin:  Terminate all active sessions that exist with a banned IP.
void ClientList::RemoveBannedIPs(int32 bIP) {
	ClientListEntry* countCLEIPs = 0;
	LinkedListIterator<ClientListEntry*> iterator(clientlist);

	iterator.Reset();
	while (iterator.MoreElements()) {
		countCLEIPs = iterator.GetData();
		if (countCLEIPs->GetIP() == bIP) {
			countCLEIPs->SetOnline(CLE_Status_Offline);
			iterator.RemoveCurrent();
		}
		iterator.Advance();
	}
}
//Lieka Edit End
Required SQL:
Code:
CREATE TABLE `Banned_IPs` (
  `ip_address` VARCHAR(32) NOT NULL,
  PRIMARY KEY (`ip_address`)
)
ENGINE = InnoDB;
Code:
Insert into rule_values values (0, 'World:UseBannedIPsTable', 0);
There is 1 new rule created from this:
World:UseBannedIPsTable = Toggle whether or not to check incoming client connections against the Banned_IPs table. Set this value to 0 to disable this feature.

There is 1 table created from this:
Banned_IPs = this table has 1 column "ip_address". Place IP addresses into this field that should be denied access to your server.

If this code works well, I will create an in-game "#ipban <charname>" command to accompany it.

Thanks,
Dax
__________________
Daxum



Former ServerOp - Vallon Zek / Tallon Zek Emu Server - Legit / Guild PvP - (2007 - 2011 RIP)

Last edited by KLS; 06-15-2008 at 01:06 PM..
Reply With Quote