Permalink
Browse files

Merge branch 'backport/1.12/campaignd-blacklist' into 1.12

  • Loading branch information...
2 parents 6a2c1a0 + 7b1be34 commit cd2f8ccd0ca7582275bc732efab1c4330474d5ed @shikadilord shikadilord committed Jun 6, 2014
View
@@ -1,4 +1,6 @@
Version 1.11.15+dev:
+ * Add-ons server:
+ * Add-on metadata pattern blacklisting implemented.
* Language and i18n:
* Updated translations:
* Miscellaneous and bug fixes:
View
@@ -1069,6 +1069,7 @@ if(ENABLE_CAMPAIGN_SERVER)
set(campaignd_SRC
network_worker.cpp # NEEDED when compiling with ANA support
addon/validation.cpp
+ campaign_server/blacklist.cpp
campaign_server/campaign_server.cpp
server/input_stream.cpp
${network_implementation_files}
View
@@ -568,6 +568,7 @@ if env["host"] in ["x86_64-nacl", "i686-nacl"]:
client_env.WesnothProgram("wesnoth", wesnoth_objects, have_client_prereqs)
campaignd_sources = Split("""
+ campaign_server/blacklist.cpp
server/input_stream.cpp
""")
@@ -0,0 +1,133 @@
+/*
+ Copyright (C) 2014 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
+ Part of the Battle for Wesnoth Project http://www.wesnoth.org/
+
+ 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.
+
+ See the COPYING file for more details.
+*/
+
+#include "campaign_server/blacklist.hpp"
+
+#include "log.hpp"
+#include "serialization/string_utils.hpp"
+
+#include <boost/foreach.hpp>
+
+static lg::log_domain log_campaignd_bl("campaignd/blacklist");
+#define LOG_BL LOG_STREAM(err, log_campaignd_bl)
+
+namespace campaignd
+{
+
+blacklist::blacklist()
+ : names_()
+ , titles_()
+ , descriptions_()
+ , authors_()
+ , ips_()
+ , emails_()
+{
+}
+
+blacklist::blacklist(const config& cfg)
+ : names_()
+ , titles_()
+ , descriptions_()
+ , authors_()
+ , ips_()
+ , emails_()
+{
+ this->read(cfg);
+}
+
+void blacklist::clear()
+{
+ names_.clear();
+ titles_.clear();
+ descriptions_.clear();
+
+ authors_.clear();
+ ips_.clear();
+ emails_.clear();
+}
+
+void blacklist::read(const config& cfg)
+{
+ parse_str_to_globlist(cfg["name"], names_);
+ parse_str_to_globlist(cfg["title"], titles_);
+ parse_str_to_globlist(cfg["description"], descriptions_);
+
+ parse_str_to_globlist(cfg["author"], authors_);
+ parse_str_to_globlist(cfg["ip"], ips_);
+ parse_str_to_globlist(cfg["email"], emails_);
+}
+
+void blacklist::parse_str_to_globlist(const std::string& str, blacklist::globlist& glist)
+{
+ glist = utils::split(str);
+}
+
+bool blacklist::is_blacklisted(const std::string& name,
+ const std::string& title,
+ const std::string& description,
+ const std::string& author,
+ const std::string& ip,
+ const std::string& email) const
+{
+ // Checks done in increasing order of performance impact and decreasing
+ // order of relevance.
+ return is_in_ip_masklist(ip, ips_) ||
+ is_in_globlist(email, emails_) ||
+ is_in_globlist(name, names_) ||
+ is_in_globlist(title, titles_) ||
+ is_in_globlist(author, authors_) ||
+ is_in_globlist(description, descriptions_);
+}
+
+bool blacklist::is_in_globlist(const std::string& str, const blacklist::globlist& glist) const
+{
+ if (!str.empty())
+ {
+ const std::string& lc_str = utils::lowercase(str);
+ BOOST_FOREACH(const std::string& glob, glist)
+ {
+ const std::string& lc_glob = utils::lowercase(glob);
+ if (utils::wildcard_string_match(lc_str, lc_glob)) {
+ LOG_BL << "Blacklisted field found: " << str << " (" << glob << ")\n";
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool blacklist::is_in_ip_masklist(const std::string& ip, const blacklist::globlist& mlist) const
+{
+ if (!ip.empty())
+ {
+ BOOST_FOREACH(const std::string& ip_mask, mlist)
+ {
+ if (ip_matches(ip, ip_mask)) {
+ LOG_BL << "Blacklisted IP found: " << ip << " (" << ip_mask << ")\n";
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool blacklist::ip_matches(const std::string& ip, const blacklist::glob& ip_mask) const
+{
+ // TODO: we want CIDR subnet mask matching here, not glob matching!
+ return utils::wildcard_string_match(ip, ip_mask);
+}
+
+}
@@ -0,0 +1,101 @@
+/*
+ Copyright (C) 2014 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
+ Part of the Battle for Wesnoth Project http://www.wesnoth.org/
+
+ 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.
+
+ See the COPYING file for more details.
+*/
+
+#ifndef CAMPAIGN_SERVER_BLACKLIST_HPP_INCLUDED
+#define CAMPAIGN_SERVER_BLACKLIST_HPP_INCLUDED
+
+#include "config.hpp"
+
+#include <boost/noncopyable.hpp>
+
+namespace campaignd
+{
+
+/**
+ * Add-on blacklist table.
+ *
+ * A path to a blacklist WML file may be provided in the campaignd
+ * configuration. The file's contents are used to maintain a blacklist to
+ * check certain add-on metadata fields against it every time a new or
+ * existing add-on is uploaded ([upload] request).
+ *
+ * Blacklist entries are glob patterns accepting the '*' and '?' wildcards for
+ * matching any number of characters and a single character, respectively. The
+ * lists are expected to be comma-delimited.
+ *
+ * ip = (net address masks)
+ * email = (email address patterns)
+ * name = (add-on id/dirname patterns)
+ * title = (add-on title patterns)
+ * author = (add-on author patterns)
+ * description = (add-on description patterns)
+ */
+class blacklist : private boost::noncopyable
+{
+public:
+ typedef std::string glob;
+ typedef std::vector<glob> globlist;
+
+ blacklist();
+ explicit blacklist(const config& cfg);
+
+ void clear();
+
+ /**
+ * Initializes the blacklist from WML.
+ *
+ * @param cfg WML node object with the contents of the [blacklist] tag.
+ */
+ void read(const config& cfg);
+
+ /**
+ * Writes the blacklist to a WML node.
+ *
+ * @param cfg WML node object to write to. Any existing contents are
+ * erased by this method.
+ */
+ void write(config& cfg) const;
+
+ /**
+ * Whether an add-on described by these fields is blacklisted.
+ *
+ * Empty parameters are ignored.
+ */
+ bool is_blacklisted(const std::string& name,
+ const std::string& title,
+ const std::string& description,
+ const std::string& author,
+ const std::string& ip,
+ const std::string& email) const;
+
+private:
+ globlist names_;
+ globlist titles_;
+ globlist descriptions_;
+
+ globlist authors_;
+ globlist ips_;
+ globlist emails_;
+
+ void parse_str_to_globlist(const std::string& str, globlist& glist);
+
+ bool is_in_globlist(const std::string& str, const globlist& glist) const;
+
+ bool is_in_ip_masklist(const std::string& ip, const globlist& mlist) const;
+ bool ip_matches(const std::string& ip, const glob& ip_mask) const;
+};
+
+}
+
+#endif
Oops, something went wrong.

0 comments on commit cd2f8cc

Please sign in to comment.