Added start time to bans and made ban_manager store deleted bans...
...in separate list
This commit is contained in:
parent
8fdeb979ad
commit
9fd2e4c203
4 changed files with 107 additions and 30 deletions
|
@ -34,10 +34,11 @@ namespace wesnothd {
|
|||
|
||||
std::ostream& operator<<(std::ostream& o, const banned& n)
|
||||
{
|
||||
return o << "IP: '" << n.get_ip() <<
|
||||
"' end_time: '" << n.get_human_end_time() <<
|
||||
"' reason: '" << n.get_reason() <<
|
||||
"' issuer: "<< n.get_who_banned() << "\n";
|
||||
return o << "IP: " << n.get_ip() <<
|
||||
" reason: '" << n.get_reason() <<
|
||||
"' end_time: " << n.get_human_end_time() <<
|
||||
" start_time: " << n.get_human_start_time() <<
|
||||
" issuer: " << n.get_who_banned();
|
||||
|
||||
}
|
||||
|
||||
|
@ -100,6 +101,7 @@ namespace wesnothd {
|
|||
mask_(0),
|
||||
ip_text_(),
|
||||
end_time_(0),
|
||||
start_time_(0),
|
||||
reason_(),
|
||||
who_banned_(who_banned_default_)
|
||||
|
||||
|
@ -116,6 +118,7 @@ namespace wesnothd {
|
|||
const std::string& group) :
|
||||
ip_text_(ip),
|
||||
end_time_(end_time),
|
||||
start_time_(time(0)),
|
||||
reason_(reason),
|
||||
who_banned_(who_banned),
|
||||
group_(group)
|
||||
|
@ -130,6 +133,7 @@ namespace wesnothd {
|
|||
mask_(0),
|
||||
ip_text_(),
|
||||
end_time_(0),
|
||||
start_time_(0),
|
||||
reason_(),
|
||||
who_banned_(who_banned_default_)
|
||||
{
|
||||
|
@ -190,6 +194,8 @@ namespace wesnothd {
|
|||
|
||||
if (cfg.has_attribute("end_time"))
|
||||
end_time_ = lexical_cast_default<time_t>(cfg["end_time"], 0);
|
||||
if (cfg.has_attribute("start_time"))
|
||||
start_time_ = lexical_cast_default<time_t>(cfg["start_time"], 0);
|
||||
reason_ = cfg["reason"];
|
||||
|
||||
// only overwrite defaults if exists
|
||||
|
@ -208,6 +214,13 @@ namespace wesnothd {
|
|||
ss << end_time_;
|
||||
cfg["end_time"] = ss.str();
|
||||
}
|
||||
if (start_time_ > 0)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << start_time_;
|
||||
cfg["start_time"] = ss.str();
|
||||
}
|
||||
|
||||
cfg["reason"] = reason_;
|
||||
if (who_banned_ != who_banned_default_)
|
||||
{
|
||||
|
@ -219,12 +232,15 @@ namespace wesnothd {
|
|||
}
|
||||
}
|
||||
|
||||
std::string banned::get_human_end_time(const time_t& time)
|
||||
std::string banned::get_human_start_time() const
|
||||
{
|
||||
if (start_time_ == 0)
|
||||
return "unknown";
|
||||
return banned::get_human_time(start_time_);
|
||||
}
|
||||
|
||||
std::string banned::get_human_time(const time_t& time)
|
||||
{
|
||||
if (time == 0)
|
||||
{
|
||||
return "permanent";
|
||||
}
|
||||
char buf[30];
|
||||
struct tm* local;
|
||||
local = localtime(&time);
|
||||
|
@ -235,7 +251,11 @@ namespace wesnothd {
|
|||
|
||||
std::string banned::get_human_end_time() const
|
||||
{
|
||||
return banned::get_human_end_time(end_time_);
|
||||
if (end_time_ == 0)
|
||||
{
|
||||
return "permanent";
|
||||
}
|
||||
return banned::get_human_time(end_time_);
|
||||
}
|
||||
|
||||
bool banned::operator>(const banned& b) const
|
||||
|
@ -256,6 +276,7 @@ namespace wesnothd {
|
|||
config cfg;
|
||||
scoped_istream ban_file = istream_file(filename_);
|
||||
read_gz(cfg, *ban_file);
|
||||
|
||||
const config::child_list& bans = cfg.get_children("ban");
|
||||
for (config::child_list::const_iterator itor = bans.begin();
|
||||
itor != bans.end(); ++itor)
|
||||
|
@ -270,6 +291,25 @@ namespace wesnothd {
|
|||
ERR_SERVER << e.message << " while reading bans\n";
|
||||
}
|
||||
}
|
||||
|
||||
// load deleted too
|
||||
if (cfg.child("deleted"))
|
||||
{
|
||||
const config& cfg_del = *cfg.child("deleted");
|
||||
const config::child_list& del_bans = cfg_del.get_children("ban");
|
||||
for (config::child_list::const_iterator itor = del_bans.begin();
|
||||
itor != del_bans.end(); ++itor)
|
||||
{
|
||||
try {
|
||||
banned_ptr new_ban(new banned(**itor));
|
||||
deleted_bans_.push_back(new_ban);
|
||||
} catch (banned::error& e) {
|
||||
ERR_SERVER << e.message << " while reading deleted bans\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ban_manager::write()
|
||||
|
@ -285,6 +325,14 @@ namespace wesnothd {
|
|||
config& child = cfg.add_child("ban");
|
||||
(*itor)->write(child);
|
||||
}
|
||||
config& deleted = cfg.add_child("deleted");
|
||||
for (deleted_ban_list::const_iterator itor = deleted_bans_.begin();
|
||||
itor != deleted_bans_.end(); ++itor)
|
||||
{
|
||||
config& child = deleted.add_child("ban");
|
||||
(*itor)->write(child);
|
||||
}
|
||||
|
||||
scoped_ostream ban_file = ostream_file(filename_);
|
||||
config_writer writer(*ban_file, true, "");
|
||||
writer.write(cfg);
|
||||
|
@ -407,7 +455,7 @@ namespace wesnothd {
|
|||
if ((ban = bans_.find(banned::create_dummy(ip))) != bans_.end())
|
||||
{
|
||||
// Already exsiting ban for ip. We have to first remove it
|
||||
LOG_SERVER << "Overwriting ban: " << (*ban)->get_ip() << " reason was: " << (*ban)->get_reason() << "\n";
|
||||
LOG_SERVER << "Overwriting ban: " << (**ban) << "\n";
|
||||
bans_.erase(ban);
|
||||
}
|
||||
} catch (banned::error& e) {
|
||||
|
@ -420,7 +468,7 @@ namespace wesnothd {
|
|||
bans_.insert(new_ban);
|
||||
if (end_time != 0)
|
||||
time_queue_.push(new_ban);
|
||||
ret << *new_ban << "\n";
|
||||
ret << *new_ban;
|
||||
} catch (banned::error& e) {
|
||||
ERR_SERVER << e.message << " while banning\n";
|
||||
return e.message;
|
||||
|
@ -436,7 +484,7 @@ namespace wesnothd {
|
|||
ban = bans_.find(banned::create_dummy(ip));
|
||||
} catch (banned::error& e) {
|
||||
ERR_SERVER << e.message << "\n";
|
||||
os << e.message << "\n";
|
||||
os << e.message;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -445,10 +493,12 @@ namespace wesnothd {
|
|||
os << "There is no ban on '" << ip << "'.";
|
||||
return;
|
||||
}
|
||||
// keep ban entry still in memory
|
||||
os << "Ban on '" << **ban << "' removed.";
|
||||
deleted_bans_.push_back(*ban);
|
||||
bans_.erase(ban);
|
||||
dirty_ = true;
|
||||
|
||||
os << "Ban on '" << ip << "' removed.";
|
||||
}
|
||||
|
||||
void ban_manager::unban_group(std::ostringstream& os, const std::string& group)
|
||||
|
@ -486,6 +536,27 @@ namespace wesnothd {
|
|||
write();
|
||||
}
|
||||
|
||||
void ban_manager::list_deleted_bans(std::ostringstream& out) const
|
||||
{
|
||||
if (deleted_bans_.empty())
|
||||
{
|
||||
out << "No removed bans found.";
|
||||
return;
|
||||
}
|
||||
|
||||
for (deleted_ban_list::const_iterator i = deleted_bans_.begin();
|
||||
i != deleted_bans_.end();
|
||||
++i)
|
||||
{
|
||||
if (i != deleted_bans_.begin())
|
||||
out << "\n";
|
||||
out << (**i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ban_manager::list_bans(std::ostringstream& out) const
|
||||
{
|
||||
if (bans_.empty())
|
||||
|
@ -496,13 +567,14 @@ namespace wesnothd {
|
|||
|
||||
std::set<std::string> groups;
|
||||
|
||||
out << "BAN LIST\n";
|
||||
for (ban_set::const_iterator i = bans_.begin();
|
||||
i != bans_.end(); ++i)
|
||||
{
|
||||
if ((*i)->get_group().empty())
|
||||
{
|
||||
out << (**i) << "\n";
|
||||
if (i != bans_.begin())
|
||||
out << "\n";
|
||||
out << (**i);
|
||||
} else {
|
||||
groups.insert((*i)->get_group());
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <ctime>
|
||||
|
||||
|
@ -56,6 +57,7 @@ namespace wesnothd {
|
|||
};
|
||||
|
||||
typedef std::set<banned_ptr,banned_compare_subnet > ban_set;
|
||||
typedef std::list<banned_ptr> deleted_ban_list;
|
||||
typedef std::priority_queue<banned_ptr,std::vector<banned_ptr>, banned_compare> ban_time_queue;
|
||||
typedef std::map<std::string, size_t> default_ban_times;
|
||||
|
||||
|
@ -65,13 +67,17 @@ namespace wesnothd {
|
|||
unsigned int mask_;
|
||||
std::string ip_text_;
|
||||
time_t end_time_;
|
||||
time_t start_time_;
|
||||
std::string reason_;
|
||||
std::string who_banned_;
|
||||
std::string group_;
|
||||
static const std::string who_banned_default_;
|
||||
typedef std::pair<unsigned int, unsigned int> ip_mask;
|
||||
|
||||
ip_mask parse_ip(const std::string&) const;
|
||||
|
||||
banned(const std::string& ip);
|
||||
|
||||
public:
|
||||
banned(const std::string& ip, const time_t end_time, const std::string& reason, const std::string& who_banned=who_banned_default_, const std::string& group="");
|
||||
banned(const config&);
|
||||
|
@ -83,7 +89,8 @@ namespace wesnothd {
|
|||
{ return end_time_; }
|
||||
|
||||
std::string get_human_end_time() const;
|
||||
static std::string get_human_end_time(const time_t&);
|
||||
std::string get_human_start_time() const;
|
||||
static std::string get_human_time(const time_t&);
|
||||
|
||||
std::string get_reason() const
|
||||
{ return reason_; }
|
||||
|
@ -119,6 +126,7 @@ namespace wesnothd {
|
|||
{
|
||||
|
||||
ban_set bans_;
|
||||
deleted_ban_list deleted_bans_;
|
||||
ban_time_queue time_queue_;
|
||||
default_ban_times ban_times_;
|
||||
std::string ban_help_;
|
||||
|
@ -147,6 +155,7 @@ namespace wesnothd {
|
|||
|
||||
void check_ban_times(time_t time_now);
|
||||
|
||||
void list_deleted_bans(std::ostringstream& out) const;
|
||||
void list_bans(std::ostringstream& out) const;
|
||||
|
||||
bool is_ip_banned(std::string ip) const;
|
||||
|
|
|
@ -75,7 +75,8 @@ void metrics::record_sample(const simple_wml::string_span& name,
|
|||
clock_t parsing_time, clock_t processing_time)
|
||||
{
|
||||
std::vector<sample>::iterator isample = std::lower_bound(samples_.begin(), samples_.end(), name,compare_samples_to_stringspan());
|
||||
if(isample->name != name) {
|
||||
if(isample == samples_.end()
|
||||
|| isample->name != name) {
|
||||
//protect against DoS with memory exhaustion
|
||||
if(samples_.size() > 30) {
|
||||
return;
|
||||
|
|
|
@ -981,7 +981,9 @@ std::string server::process_command(const std::string& query, const std::string&
|
|||
} else if (command == "ban" || command == "bans" || command == "kban" || command == "kickban" || command == "gban") {
|
||||
if (parameters == "") {
|
||||
ban_manager_.list_bans(out);
|
||||
} else {
|
||||
} else if (parameters == "deleted") {
|
||||
ban_manager_.list_deleted_bans(out);
|
||||
}else {
|
||||
bool banned_ = false;
|
||||
const bool kick = (command == "kban" || command == "kickban");
|
||||
const bool group_ban = command == "gban";
|
||||
|
@ -1021,17 +1023,14 @@ std::string server::process_command(const std::string& query, const std::string&
|
|||
banned_ = true;
|
||||
|
||||
std::string err = ban_manager_.ban(target, parsed_time, reason, issuer_name, group);
|
||||
if (err.empty())
|
||||
out << "Set ban on '" << target << "' with end time '" << wesnothd::banned::get_human_end_time(parsed_time) << "' with reason: '" << reason << "'.\n";
|
||||
else
|
||||
out << err << "\n";
|
||||
out << err;
|
||||
|
||||
if (kick) {
|
||||
for (wesnothd::player_map::const_iterator pl = players_.begin();
|
||||
pl != players_.end(); ++pl)
|
||||
{
|
||||
if (utils::wildcard_string_match(network::ip_address(pl->first), target)) {
|
||||
out << "Kicked " << pl->second.name() << ".\n";
|
||||
out << "\nKicked " << pl->second.name() << ".";
|
||||
network::queue_disconnect(pl->first);
|
||||
}
|
||||
}
|
||||
|
@ -1045,14 +1044,10 @@ std::string server::process_command(const std::string& query, const std::string&
|
|||
const std::string& ip = network::ip_address(pl->first);
|
||||
if (!is_ip_banned(ip)) {
|
||||
std::string err = ban_manager_.ban(ip,parsed_time, reason, issuer_name, group);
|
||||
if (err.empty())
|
||||
out << "Set ban on '" << ip << "' with end time '" << wesnothd::banned::get_human_end_time(parsed_time) << "' with reason: '"
|
||||
<< reason << "'.\n";
|
||||
else
|
||||
out << err << "\n";
|
||||
out << err;
|
||||
}
|
||||
if (kick) {
|
||||
out << "Kicked " << pl->second.name() << ".\n";
|
||||
out << "\nKicked " << pl->second.name() << ".";
|
||||
network::queue_disconnect(pl->first);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue