1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013 Sadie Powell <sadie@witchery.services>
5  *   Copyright (C) 2012-2014 Attila Molnar <attilamolnar@hush.com>
6  *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
7  *   Copyright (C) 2010 Craig Edwards <brain@inspircd.org>
8  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
9  *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
10  *
11  * This file is part of InspIRCd.  InspIRCd is free software: you can
12  * redistribute it and/or modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation, version 2.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 
25 #include "inspircd.h"
26 
BanCacheHit(const std::string & type,const std::string & reason,time_t seconds)27 BanCacheHit::BanCacheHit(const std::string& type, const std::string& reason, time_t seconds)
28 	: Type(type)
29 	, Reason(reason)
30 	, Expiry(ServerInstance->Time() + seconds)
31 {
32 }
33 
AddHit(const std::string & ip,const std::string & type,const std::string & reason,time_t seconds)34 BanCacheHit *BanCacheManager::AddHit(const std::string &ip, const std::string &type, const std::string &reason, time_t seconds)
35 {
36 	BanCacheHit*& b = BanHash[ip];
37 	if (b != NULL) // can't have two cache entries on the same IP, sorry..
38 		return NULL;
39 
40 	b = new BanCacheHit(type, reason, (seconds ? seconds : 86400));
41 	return b;
42 }
43 
GetHit(const std::string & ip)44 BanCacheHit *BanCacheManager::GetHit(const std::string &ip)
45 {
46 	BanCacheHash::iterator i = this->BanHash.find(ip);
47 
48 	if (i == this->BanHash.end())
49 		return NULL; // free and safe
50 
51 	if (RemoveIfExpired(i))
52 		return NULL; // expired
53 
54 	return i->second; // hit.
55 }
56 
RemoveIfExpired(BanCacheHash::iterator & it)57 bool BanCacheManager::RemoveIfExpired(BanCacheHash::iterator& it)
58 {
59 	if (ServerInstance->Time() < it->second->Expiry)
60 		return false;
61 
62 	ServerInstance->Logs->Log("BANCACHE", LOG_DEBUG, "Hit on " + it->first + " is out of date, removing!");
63 	delete it->second;
64 	it = BanHash.erase(it);
65 	return true;
66 }
67 
RemoveEntries(const std::string & type,bool positive)68 void BanCacheManager::RemoveEntries(const std::string& type, bool positive)
69 {
70 	if (positive)
71 		ServerInstance->Logs->Log("BANCACHE", LOG_DEBUG, "BanCacheManager::RemoveEntries(): Removing positive hits for " + type);
72 	else
73 		ServerInstance->Logs->Log("BANCACHE", LOG_DEBUG, "BanCacheManager::RemoveEntries(): Removing all negative hits");
74 
75 	for (BanCacheHash::iterator i = BanHash.begin(); i != BanHash.end(); )
76 	{
77 		if (RemoveIfExpired(i))
78 			continue; // updates the iterator if expired
79 
80 		BanCacheHit* b = i->second;
81 		bool remove = false;
82 
83 		if (positive)
84 		{
85 			// when removing positive hits, remove only if the type matches
86 			remove = b->IsPositive() && (b->Type == type);
87 		}
88 		else
89 		{
90 			// when removing negative hits, remove all of them
91 			remove = !b->IsPositive();
92 		}
93 
94 		if (remove)
95 		{
96 			/* we need to remove this one. */
97 			ServerInstance->Logs->Log("BANCACHE", LOG_DEBUG, "BanCacheManager::RemoveEntries(): Removing a hit on " + i->first);
98 			delete b;
99 			i = BanHash.erase(i);
100 		}
101 		else
102 			++i;
103 	}
104 }
105 
~BanCacheManager()106 BanCacheManager::~BanCacheManager()
107 {
108 	for (BanCacheHash::iterator n = BanHash.begin(); n != BanHash.end(); ++n)
109 		delete n->second;
110 }
111