32 #define ERR_SERVER LOG_STREAM(err, log_server)
33 #define LOG_SERVER LOG_STREAM(info, log_server)
34 #define DBG_SERVER LOG_STREAM(debug, log_server)
38 return o <<
"IP: " << n.
get_ip() <<
60 return a->get_int_ip() < b->get_int_ip();
78 who_banned_(who_banned_default_),
88 const time_t end_time,
99 who_banned_(who_banned),
115 who_banned_(who_banned_default_),
129 std::vector<std::string> split_ip =
utils::split(ip,
'.');
130 if (split_ip.size() > 4)
throw banned::error(
"Malformed ip address: " + ip);
132 unsigned int shift = 4*8;
133 unsigned int mask = 0xFF000000;
134 const unsigned int complete_part_mask = 0xFF;
135 std::vector<std::string>::const_iterator part = split_ip.begin();
136 bool wildcard =
false;
140 if (part == split_ip.end())
154 unsigned int part_ip = lexical_cast_default<unsigned int>(*part, complete_part_mask + 1);
155 if (part_ip > complete_part_mask)
157 ret.first |= (part_ip << shift);
158 ret.second |= (complete_part_mask << shift);
175 nick_ = cfg[
"nick"].str();
177 end_time_ = lexical_cast_default<time_t>(cfg[
"end_time"], 0);
179 start_time_ = lexical_cast_default<time_t>(cfg[
"start_time"], 0);
186 group_ = cfg[
"group"].str();
195 std::stringstream ss;
197 cfg[
"end_time"] = ss.str();
201 std::stringstream ss;
203 cfg[
"start_time"] = ss.str();
258 return (
ip_ &
mask_ & pair.second) == (pair.first & pair.second &
mask_);
274 assert(
bans_.insert(new_ban).second);
276 if (new_ban->get_end_time() != 0)
307 for (ban_set::const_iterator
itor =
bans_.begin();
311 (*itor)->write(child);
318 (*itor)->write(child);
328 if (!time)
return false;
330 if (duration.substr(0,4) ==
"TIME") {
332 loc = localtime(time);
335 for (std::string::const_iterator
i = duration.begin() + 4;
336 i != duration.end(); ++
i) {
364 LOG_SERVER <<
"Invalid time modifier given: '" << *
i <<
"'.\n";
373 default_ban_times::const_iterator time_itor =
ban_times_.find(duration);
379 ERR_SERVER <<
"While parsing ban command duration string, caught an invalid utf8 exception: " << e.what() << std::endl;
383 if (dur_lower ==
"permanent" || duration ==
"0") {
386 *time += time_itor->second;
388 std::string::const_iterator
i = duration.begin();
390 for (std::string::const_iterator d_end = duration.end(); i != d_end; ++
i) {
393 if (number == -1) number = 0;
394 number = number * 10 +
to_digit(*i);
396 if (number == -1) number = 1;
401 if (++i != d_end && tolower(*i) ==
'e'
402 && ++i != d_end && tolower(*i) ==
'a'
403 && ++i != d_end && tolower(*i) ==
'r'
404 && ++i != d_end && tolower(*i) ==
's') {
406 *time += number * 365*24*60*60;
409 if (++i != d_end && tolower(*i) ==
'i') {
410 if (++i != d_end && tolower(*i) ==
'n'
411 && ++i != d_end && tolower(*i) ==
'u'
412 && ++i != d_end && tolower(*i) ==
't'
413 && ++i != d_end && tolower(*i) ==
'e'
414 && ++i != d_end && tolower(*i) ==
's') {
416 *time += number * 60;
420 if (++i != d_end && tolower(*i) ==
'o'
421 && ++i != d_end && tolower(*i) ==
'n'
422 && ++i != d_end && tolower(*i) ==
't'
423 && ++i != d_end && tolower(*i) ==
'h'
424 && ++i != d_end && tolower(*i) ==
's') {
426 *time += number * 30*24*60*60;
430 if (++i != d_end && tolower(*i) ==
'a'
431 && ++i != d_end && tolower(*i) ==
'y'
432 && ++i != d_end && tolower(*i) ==
's') {
434 *time += number * 24*60*60;
438 if (++i != d_end && tolower(*i) ==
'o'
439 && ++i != d_end && tolower(*i) ==
'u'
440 && ++i != d_end && tolower(*i) ==
'r'
441 && ++i != d_end && tolower(*i) ==
's') {
443 *time += number * 60*60;
446 if (++i != d_end && tolower(*i) ==
'o') {
447 if (++i != d_end && tolower(*i) ==
'n'
448 && ++i != d_end && tolower(*i) ==
't'
449 && ++i != d_end && tolower(*i) ==
'h'
450 && ++i != d_end && tolower(*i) ==
's') {
452 *time += number * 30*24*60*60;
456 if (++i != d_end && tolower(*i) ==
'i'
457 && ++i != d_end && tolower(*i) ==
'n'
458 && ++i != d_end && tolower(*i) ==
'u'
459 && ++i != d_end && tolower(*i) ==
't'
460 && ++i != d_end && tolower(*i) ==
'e'
461 && ++i != d_end && tolower(*i) ==
's') {
463 *time += number * 60;
467 if (++i != d_end && tolower(*i) ==
'e'
468 && ++i != d_end && tolower(*i) ==
'c'
469 && ++i != d_end && tolower(*i) ==
'o'
470 && ++i != d_end && tolower(*i) ==
'n'
471 && ++i != d_end && tolower(*i) ==
'd'
472 && ++i != d_end && tolower(*i) ==
's') {
484 *time += number * 60;
491 const time_t& end_time,
497 std::ostringstream ret;
503 ret <<
"Overwriting ban: " << (**ban) <<
"\n";
507 ERR_SERVER << e.
message <<
" while creating dummy ban for finding existing ban" << std::endl;
511 banned_ptr new_ban(
new banned(ip, end_time, reason,who_banned, group, nick));
512 bans_.insert(new_ban);
535 if (ban ==
bans_.end())
537 os <<
"There is no ban on '" << ip <<
"'.";
541 os <<
"Ban on '" << **ban <<
"' removed.";
543 if ((*ban)->get_group().empty())
deleted_bans_.push_back(*ban);
552 std::insert_iterator<ban_set> temp_inserter(temp, temp.begin());
555 os <<
"Removed " << (
bans_.size() - temp.size()) <<
" bans";
566 if (ban->get_end_time() > time_now)
569 DBG_SERVER <<
"ban " << ban->get_ip() <<
" not removed. time: " << time_now <<
" end_time " << ban->get_end_time() <<
"\n";
574 LOG_SERVER <<
"Remove a ban " << ban->get_ip() <<
". time: " << time_now <<
" end_time " << ban->get_end_time() <<
"\n";
575 std::ostringstream os;
576 unban(os, ban->get_ip());
588 out <<
"No removed bans found.";
596 out <<
"parse error: " << e.
message;
600 out <<
"DELETED BANS LIST";
605 if ((*i)->match_ipmask(pair)) out <<
"\n" << (**
i);
616 out <<
"No bans set.";
624 out <<
"parse error: " << e.
message;
629 std::set<std::string>
groups;
631 for (ban_set::const_iterator
i =
bans_.begin();
634 if ((*i)->get_group().empty())
636 if ((*i)->match_ipmask(pair)) out <<
"\n" << (**
i);
638 groups.insert((*i)->get_group());
643 if (!groups.empty() && mask ==
"*")
645 out <<
"\nban groups: ";
647 out << *groups.begin();
648 std::ostream& (*fn)(std::ostream&,
const std::string&) = &std::operator<<;
649 std::for_each( ++groups.begin(), groups.end(), std::bind(fn,std::bind(fn,
std::ref(out),
std::string(
", ")),_1));
664 if (ban ==
bans_.end())
return "";
666 return (*ban)->get_reason() + (nick.empty() ?
"" :
" (" + nick +
")") +
" (" + (*ban)->get_human_time_span() +
")";
671 ban_help_ =
"ban <mask> <time> <reason>\n"
672 "The time format is: %d[%s[%d[%s[...]]]] where %s is a time"
673 " modifier: s or S (seconds), m (minutes), h or H (hours), d"
674 " or D (days), M (months) or y or Y (years) and %d is a number.\n"
675 "Permanent bans can be set with 'permanent' or '0' as the time"
680 ban_help_ +=
"You can also use " + itor->first;
689 ban_help_ +=
" for standard ban times. (not combinable)\n";
691 ban_help_ +=
"ban 127.0.0.1 2h20m flooded lobby\n"
692 "kban suokko 5D flooded again\n"
693 "kban suokko Y One year ban for constant flooding";
702 ban_times_.insert(default_ban_times::value_type(bt[
"name"], duration));
size_t to_digit(const char &c) const
child_itors child_range(const std::string &key)
void write(const config &cfg)
unsigned int get_mask_ip(unsigned int) const
default_ban_times ban_times_
void list_deleted_bans(std::ostringstream &out, const std::string &mask="*") const
void load_config(const config &)
std::string get_timestamp(const time_t &t, const std::string &format)
bool match_group(const std::string &group) const
std::string ban(const std::string &, const time_t &, const std::string &, const std::string &, const std::string &, const std::string &="")
std::string get_human_time_span() const
static l_noret error(LoadState *S, const char *why)
deleted_ban_list deleted_bans_
bool(banned_compare_subnet::* compare_fn)(const banned_ptr &a, const banned_ptr &b) const
utf8::string lowercase(const utf8::string &s)
Returns a lowercased version of the string.
std::string get_human_start_time() const
const std::string number
template to number regex
Definitions for the interface to Wesnoth Markup Language (WML).
std::set< banned_ptr, banned_compare_subnet > ban_set
bool match_ip(const ip_mask &ip) const
void read_gz(config &cfg, std::istream &file, abstract_validator *validator)
might throw a std::ios_base::failure especially a gzip_error
static compare_fn active_
std::string is_ip_banned(const std::string &ip) const
std::pair< unsigned int, unsigned int > ip_mask
GLdouble GLdouble GLdouble b
void read(const config &)
bool operator()(const banned_ptr &a, const banned_ptr &b) const
time_t get_end_time() const
bool parse_time(const std::string &duration, time_t *time) const
Parses the given duration and adds it to *time except if the duration is '0' or 'permanent' in which ...
static lg::log_domain log_server("server")
void unban_group(std::ostringstream &os, const std::string &group)
Class for writing a config out to a file in pieces.
bool less(const banned_ptr &a, const banned_ptr &b) const
std::string get_human_end_time() const
std::istream * istream_file(const std::string &fname, bool treat_failure_as_error=true)
GLboolean GLboolean GLboolean GLboolean a
std::ostream * ostream_file(std::string const &fname, bool create_directory=true)
config & add_child(const std::string &key)
ip_mask parse_ip(const std::string &ip)
banned(const std::string &ip)
Templates and utility-routines for strings and numbers.
bool match_ipmask(const ip_mask &ip) const
ban_time_queue time_queue_
static banned_ptr create_dummy(const std::string &ip)
std::map< std::string, tfilter >::iterator itor
std::string get_nick() const
Thrown by operations encountering invalid UTF-8 data.
void unban(std::ostringstream &os, const std::string &ip)
std::ostream & operator<<(std::ostream &o, const banned &n)
bool operator>(const banned &b) const
static const std::string who_banned_default_
std::string get_timespan(const time_t &t)
Declarations for File-IO.
static int writer(lua_State *L, const void *b, size_t size, void *B)
void list_bans(std::ostringstream &out, const std::string &mask="*") const
void check_ban_times(time_t time_now)
bool has_attribute(const std::string &key) const
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
std::string get_who_banned() const
Standard logging facilities (interface).
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
A config object defines a single node in a WML file, with access to child nodes.
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
GLsizei const GLcharARB ** string
void write(config &) const
std::string get_reason() const
bool operator()(const banned_ptr &a, const banned_ptr &b) const
bool is_digit(const char &c) const
std::string get_ip() const