You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
401 lines
8.5 KiB
401 lines
8.5 KiB
/***************************************************************************
|
|
* Copyright (C) 2005 by Joris Guisson *
|
|
* joris.guisson@gmail.com *
|
|
* ivasic@gmail.com *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
***************************************************************************/
|
|
|
|
#include "ipblocklist.h"
|
|
#include <tqmap.h>
|
|
#include <tqstring.h>
|
|
#include <tqstringlist.h>
|
|
#include <util/constants.h>
|
|
#include <util/log.h>
|
|
#include "globals.h"
|
|
#include <interfaces/ipblockinginterface.h>
|
|
|
|
|
|
namespace bt
|
|
{
|
|
Uint32 toUint32(const TQString& ip, bool* ok)
|
|
{
|
|
bool test;
|
|
*ok = true;
|
|
|
|
Uint32 ret = ip.section('.',0,0).toULongLong(&test);
|
|
if(!test) *ok=false;
|
|
ret <<= 8;
|
|
ret |= ip.section('.',1,1).toULong(&test);
|
|
if(!test) *ok=false;
|
|
ret <<= 8;
|
|
ret |= ip.section('.',2,2).toULong(&test);
|
|
if(!test) *ok=false;
|
|
ret <<= 8;
|
|
ret |= ip.section('.',3,3).toULong(&test);
|
|
if(!test) *ok=false;
|
|
|
|
if(*ok)
|
|
{
|
|
// Out() << "IP: " << ip << " parsed: " << ret << endl;
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
// Out() << "Could not parse IP " << ip << ". IP blocklist might not be working." << endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
IPBlocklist::IPBlocklist()
|
|
{
|
|
this->pluginInterface = 0;
|
|
insert("0.0.0.0",3);
|
|
addRange("3.*.*.*");
|
|
}
|
|
|
|
IPBlocklist::IPBlocklist(const IPBlocklist & ) {}
|
|
|
|
void IPBlocklist::insert( TQString ip, int state )
|
|
{
|
|
bool ok;
|
|
Uint32 ipi = toUint32(ip, &ok);
|
|
if(!ok)
|
|
return;
|
|
IPKey key(ipi,0xFFFFFFFF); //-- you can test ranges here. Just specify your mask.
|
|
insertRangeIP(key, state);
|
|
Out(SYS_IPF|LOG_NOTICE) << "IP " << ip << " banned." << endl;
|
|
}
|
|
|
|
void IPBlocklist::addRange(TQString ip)
|
|
{
|
|
bool ok;
|
|
int tmp = 0;
|
|
Uint32 addr = 0;
|
|
Uint32 mask = 0xFFFFFFFF;
|
|
|
|
tmp = ip.section('.',0,0).toInt(&ok);
|
|
if(!ok)
|
|
{
|
|
if(ip.section('.',0,0) == "*")
|
|
mask &= 0x00FFFFFF;
|
|
else return; //illegal character
|
|
}
|
|
else
|
|
addr = tmp;
|
|
|
|
tmp = ip.section('.',1,1).toInt(&ok);
|
|
if(!ok)
|
|
{
|
|
addr <<= 8;
|
|
if(ip.section('.',1,1) == "*")
|
|
mask &= 0xFF00FFFF;
|
|
else return; //illegal character
|
|
}
|
|
else
|
|
{
|
|
addr <<= 8;
|
|
addr |= tmp;
|
|
}
|
|
|
|
tmp = ip.section('.',2,2).toInt(&ok);
|
|
if(!ok)
|
|
{
|
|
addr <<= 8;
|
|
if(ip.section('.',2,2) == "*")
|
|
mask &= 0xFFFF00FF;
|
|
else return; //illegal character
|
|
}
|
|
else
|
|
{
|
|
addr <<= 8;
|
|
addr |= tmp;
|
|
}
|
|
|
|
tmp = ip.section('.',3,3).toInt(&ok);
|
|
if(!ok)
|
|
{
|
|
addr <<= 8;
|
|
if(ip.section('.',3,3) == "*")
|
|
mask &=0xFFFFFF00;
|
|
else return; //illegal character
|
|
}
|
|
else
|
|
{
|
|
addr <<= 8;
|
|
addr |= tmp;
|
|
}
|
|
|
|
IPKey key(addr, mask);
|
|
this->insertRangeIP(key);
|
|
}
|
|
|
|
void IPBlocklist::insertRangeIP(IPKey& key, int state)
|
|
{
|
|
// Out() << "Blocked range: " << key.m_ip << " - " << key.m_mask << endl;
|
|
TQMap<IPKey, int>::iterator it;
|
|
if ((it = m_peers.find(key)) != m_peers.end())
|
|
{
|
|
|
|
if(it.key().m_mask != key.m_mask)
|
|
{
|
|
int st = it.data();
|
|
IPKey key1(key.m_ip, it.key().m_mask | key.m_mask);
|
|
m_peers.insert(key1, state+st);
|
|
return;
|
|
}
|
|
m_peers[key]+= state;
|
|
}
|
|
else
|
|
m_peers.insert(key,state);
|
|
}
|
|
|
|
void IPBlocklist::removeRange(TQString ip)
|
|
{
|
|
bool ok;
|
|
int tmp = 0;
|
|
Uint32 addr = 0;
|
|
Uint32 mask = 0xFFFFFFFF;
|
|
|
|
tmp = ip.section('.',0,0).toInt(&ok);
|
|
if(!ok)
|
|
{
|
|
if(ip.section('.',0,0) == "*")
|
|
mask &= 0x00FFFFFF;
|
|
else return; //illegal character
|
|
}
|
|
else
|
|
addr = tmp;
|
|
|
|
tmp = ip.section('.',1,1).toInt(&ok);
|
|
if(!ok)
|
|
{
|
|
addr <<= 8;
|
|
if(ip.section('.',1,1) == "*")
|
|
mask &= 0xFF00FFFF;
|
|
else return; //illegal character
|
|
}
|
|
else
|
|
{
|
|
addr <<= 8;
|
|
addr |= tmp;
|
|
}
|
|
|
|
tmp = ip.section('.',2,2).toInt(&ok);
|
|
if(!ok)
|
|
{
|
|
addr <<= 8;
|
|
if(ip.section('.',2,2) == "*")
|
|
mask &= 0xFFFF00FF;
|
|
else return; //illegal character
|
|
}
|
|
else
|
|
{
|
|
addr <<= 8;
|
|
addr |= tmp;
|
|
}
|
|
|
|
tmp = ip.section('.',3,3).toInt(&ok);
|
|
if(!ok)
|
|
{
|
|
addr <<= 8;
|
|
if(ip.section('.',3,3) == "*")
|
|
mask &=0xFFFFFF00;
|
|
else return; //illegal character
|
|
}
|
|
else
|
|
{
|
|
addr <<= 8;
|
|
addr |= tmp;
|
|
}
|
|
|
|
IPKey key(addr, mask);
|
|
|
|
TQMap<IPKey, int>::iterator it = m_peers.find(key);
|
|
if (it == m_peers.end())
|
|
return;
|
|
|
|
m_peers.remove(key);
|
|
}
|
|
|
|
void IPBlocklist::setPluginInterfacePtr( kt::IPBlockingInterface* ptr )
|
|
{
|
|
this->pluginInterface = ptr;
|
|
}
|
|
|
|
bool IPBlocklist::isBlocked(const TQString& ip )
|
|
{
|
|
//First check local filter list
|
|
if(isBlockedLocal(ip))
|
|
{
|
|
Out(SYS_IPF|LOG_NOTICE) << "IP " << ip << " is blacklisted. Connection denied." << endl;
|
|
return true;
|
|
}
|
|
|
|
//Then we ask plugin
|
|
if(isBlockedPlugin(ip))
|
|
{
|
|
Out(SYS_IPF|LOG_NOTICE) << "IP " << ip << " is blacklisted. Connection denied." << endl;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool IPBlocklist::isBlockedLocal(const TQString& ip )
|
|
{
|
|
bool ok;
|
|
Uint32 ipi = toUint32(ip,&ok);
|
|
if (!ok)
|
|
return false;
|
|
IPKey key(ipi);
|
|
|
|
TQMap<IPKey, int>::iterator it;
|
|
it = m_peers.find(key);
|
|
if (it==m_peers.end())
|
|
return false;
|
|
|
|
return m_peers[key] >= 3;
|
|
}
|
|
|
|
bool IPBlocklist::isBlockedPlugin(const TQString& ip )
|
|
{
|
|
if (pluginInterface == 0) //the plugin is not loaded
|
|
return false;
|
|
else
|
|
return pluginInterface->isBlockedIP(ip);
|
|
}
|
|
|
|
TQStringList* IPBlocklist::getBlocklist()
|
|
{
|
|
TQStringList* ret = new TQStringList();
|
|
TQMap<IPKey,int>::iterator it = m_peers.begin();
|
|
for( ;it!=m_peers.end();++it)
|
|
{
|
|
IPKey key = it.key();
|
|
*ret << key.toString();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void IPBlocklist::setBlocklist(TQStringList* list)
|
|
{
|
|
m_peers.clear();
|
|
for (TQStringList::Iterator it = list->begin(); it != list->end(); ++it )
|
|
addRange(*it);
|
|
}
|
|
|
|
/*** IPKey *****************************************************************************************************************/
|
|
|
|
IPKey::IPKey()
|
|
{
|
|
m_ip = 0;
|
|
m_mask = 0xFFFFFFFF;
|
|
}
|
|
|
|
IPKey::IPKey(TQString& ip, Uint32 mask)
|
|
: m_mask(mask)
|
|
{
|
|
bool ok;
|
|
this->m_ip = toUint32(ip, &ok);
|
|
}
|
|
|
|
IPKey::IPKey(const IPKey& ip)
|
|
{
|
|
m_ip = ip.m_ip;
|
|
m_mask = ip.m_mask;
|
|
}
|
|
|
|
IPKey::IPKey(Uint32 ip, Uint32 mask)
|
|
: m_ip(ip), m_mask(mask)
|
|
{}
|
|
|
|
TQString IPKey::toString()
|
|
{
|
|
Uint32 tmp, tmpmask;
|
|
Uint32 ip = m_ip;
|
|
Uint32 mask = m_mask;
|
|
TQString out;
|
|
|
|
tmp = ip;
|
|
tmpmask = mask;
|
|
tmp &= 0x000000FF;
|
|
tmpmask &= 0x000000FF;
|
|
if(tmpmask == 0)
|
|
out.prepend("*");
|
|
else
|
|
out.prepend(TQString("%1").arg(tmp));
|
|
ip >>= 8;
|
|
mask >>= 8;
|
|
tmp = ip;
|
|
tmpmask = mask;
|
|
tmp &= 0x000000FF;
|
|
tmpmask &= 0x000000FF;
|
|
if(tmpmask == 0)
|
|
out.prepend("*.");
|
|
else
|
|
out.prepend(TQString("%1.").arg(tmp));
|
|
ip >>= 8;
|
|
mask >>= 8;
|
|
tmp = ip;
|
|
tmpmask = mask;
|
|
tmp &= 0x000000FF;
|
|
tmpmask &= 0x000000FF;
|
|
if(tmpmask == 0)
|
|
out.prepend("*.");
|
|
else
|
|
out.prepend(TQString("%1.").arg(tmp));
|
|
ip >>= 8;
|
|
mask >>= 8;
|
|
tmp = ip;
|
|
tmpmask = mask;
|
|
tmp &= 0x000000FF;
|
|
tmpmask &= 0x000000FF;
|
|
if(tmpmask == 0)
|
|
out.prepend("*.");
|
|
else
|
|
out.prepend(TQString("%1.").arg(tmp));
|
|
|
|
return out;
|
|
}
|
|
|
|
bool IPKey::operator ==(const IPKey& ip) const
|
|
{
|
|
return (m_ip & m_mask) == m_mask & ip.m_ip;
|
|
}
|
|
|
|
bool IPKey::operator !=(const IPKey& ip) const
|
|
{
|
|
return (m_ip & m_mask) != m_mask & ip.m_ip;
|
|
}
|
|
|
|
bool IPKey::operator < (const IPKey& ip) const
|
|
{
|
|
return (m_ip & m_mask) < (m_mask & ip.m_ip);
|
|
}
|
|
|
|
IPKey& IPKey::operator =(const IPKey& ip)
|
|
{
|
|
m_ip = ip.m_ip;
|
|
m_mask = ip.m_mask;
|
|
return *this;
|
|
}
|
|
|
|
IPKey::~ IPKey()
|
|
{}
|
|
}
|