From 9b2429c393ca470c115f4a6ea258cc5e67f3d8e6 Mon Sep 17 00:00:00 2001 From: Pentarctagon Date: Mon, 8 Mar 2021 23:24:13 -0600 Subject: [PATCH] Add validation for the feedback topic id. --- src/addon/validation.cpp | 8 ++++++++ src/addon/validation.hpp | 2 ++ src/server/campaignd/server.cpp | 15 +++++++++++++++ src/server/common/dbconn.cpp | 14 ++++++++++++++ src/server/common/dbconn.hpp | 7 +++++++ src/server/common/forum_user_handler.cpp | 4 ++++ src/server/common/forum_user_handler.hpp | 8 ++++++++ src/server/common/user_handler.hpp | 1 + utils/mp-server/table_definitions.sql | 7 +++++++ 9 files changed, 66 insertions(+) diff --git a/src/addon/validation.cpp b/src/addon/validation.cpp index e4dbf216aac8..9b292fd321a7 100644 --- a/src/addon/validation.cpp +++ b/src/addon/validation.cpp @@ -541,6 +541,14 @@ std::string addon_check_status_desc(unsigned int code) ADDON_CHECK_STATUS::VERSION_NOT_INCREMENTED, N_("Version number not greater than the latest uploaded version.") }, + { + ADDON_CHECK_STATUS::BAD_FEEDBACK_TOPIC_ID, + N_("Feedback topic id is not a number.") + }, + { + ADDON_CHECK_STATUS::FEEDBACK_TOPIC_ID_NOT_FOUND, + N_("Feedback topic does not exist.") + }, { ADDON_CHECK_STATUS::INVALID_UTF8_ATTRIBUTE, N_("The add-on publish information contains an invalid UTF-8 sequence.") diff --git a/src/addon/validation.hpp b/src/addon/validation.hpp index ce160a545cd3..bf98fce0ad30 100644 --- a/src/addon/validation.hpp +++ b/src/addon/validation.hpp @@ -60,6 +60,8 @@ enum class ADDON_CHECK_STATUS : unsigned int BAD_TYPE = 0x207, /**< Bad add-on type */ VERSION_NOT_INCREMENTED = 0x208, /**< Version number is not an increment */ INVALID_UTF8_ATTRIBUTE = 0x2FF, /**< Invalid UTF-8 sequence in add-on metadata */ + BAD_FEEDBACK_TOPIC_ID = 0x209, /**< The provided topic ID for the addon's feedback forum thread is invalid */ + FEEDBACK_TOPIC_ID_NOT_FOUND = 0x2A0, /**< The provided topic ID for the addon's feedback forum thread wasn't found in the forum database */ // // Server errors // diff --git a/src/server/campaignd/server.cpp b/src/server/campaignd/server.cpp index 97e2d709efcd..6b5722f9833a 100644 --- a/src/server/campaignd/server.cpp +++ b/src/server/campaignd/server.cpp @@ -1372,6 +1372,21 @@ ADDON_CHECK_STATUS server::validate_addon(const server::request& req, config*& e return ADDON_CHECK_STATUS::UNEXPECTED_DELTA; } + if(const config& url_params = upload.child("feedback")) { + try { + int topic_id = std::stoi(url_params["topic_id"].str("0")); + if(user_handler_ && topic_id != 0) { + if(!user_handler_->db_topic_id_exists(topic_id)) { + LOG_CS << "Validation error: feedback topic ID does not exist in forum database\n"; + return ADDON_CHECK_STATUS::FEEDBACK_TOPIC_ID_NOT_FOUND; + } + } + } catch(...) { + LOG_CS << "Validation error: feedback topic ID is not a valid number\n"; + return ADDON_CHECK_STATUS::BAD_FEEDBACK_TOPIC_ID; + } + } + return ADDON_CHECK_STATUS::SUCCESS; } diff --git a/src/server/common/dbconn.cpp b/src/server/common/dbconn.cpp index 00085d39e2d4..2878e05e61b4 100644 --- a/src/server/common/dbconn.cpp +++ b/src/server/common/dbconn.cpp @@ -34,6 +34,7 @@ dbconn::dbconn(const config& c) , db_game_content_info_table_(c["db_game_content_info_table"].str()) , db_user_group_table_(c["db_user_group_table"].str()) , db_tournament_query_(c["db_tournament_query"].str()) + , db_topics_table_(c["db_topics_table"].str()) { try { @@ -344,6 +345,19 @@ void dbconn::set_oos_flag(const std::string& uuid, int game_id) } } +bool dbconn::topic_id_exists(int topic_id) { + try + { + return exists(connection_, "SELECT 1 FROM `"+db_topics_table_+"` WHERE TOPIC_ID = ?", + topic_id); + } + catch(const mariadb::exception::base& e) + { + log_sql_exception("Unable to check whether `"+std::to_string(topic_id)+"` exists.", e); + return true; + } +} + // // handle complex query results // diff --git a/src/server/common/dbconn.hpp b/src/server/common/dbconn.hpp index dc18157d7aa5..a860f7041f2b 100644 --- a/src/server/common/dbconn.hpp +++ b/src/server/common/dbconn.hpp @@ -143,6 +143,11 @@ class dbconn */ void set_oos_flag(const std::string& uuid, int game_id); + /** + * @see forum_user_handler::db_topic_id_exists(). + */ + bool topic_id_exists(int topic_id); + private: /** * The account used to connect to the database. @@ -169,6 +174,8 @@ class dbconn std::string db_user_group_table_; /** The text of the SQL query to use to retrieve any currently active tournaments. */ std::string db_tournament_query_; + /** The name of the table that contains phpbb forum thread information */ + std::string db_topics_table_; /** * This is used to write out error text when an SQL-related exception occurs. diff --git a/src/server/common/forum_user_handler.cpp b/src/server/common/forum_user_handler.cpp index 2eadc62eb1e5..be35e401a7c0 100644 --- a/src/server/common/forum_user_handler.cpp +++ b/src/server/common/forum_user_handler.cpp @@ -243,4 +243,8 @@ void fuh::async_test_query(boost::asio::io_service& io_service, int limit) { }); } +bool fuh::db_topic_id_exists(int topic_id) { + return conn_.topic_id_exists(topic_id); +} + #endif //HAVE_MYSQLPP diff --git a/src/server/common/forum_user_handler.hpp b/src/server/common/forum_user_handler.hpp index f16d6461723b..9a741d3c2cbd 100644 --- a/src/server/common/forum_user_handler.hpp +++ b/src/server/common/forum_user_handler.hpp @@ -200,6 +200,14 @@ class fuh : public user_handler */ void async_test_query(boost::asio::io_service& io_service, int limit); + /** + * Checks whether a forum thread with @a topic_id exists. + * + * @param topic_id The topic id to check for. + * @return True if the thread exists or there was a database failure, false if the topic wasn't found. + */ + bool db_topic_id_exists(int topic_id); + private: /** An instance of the class responsible for executing the queries and handling the database connection. */ dbconn conn_; diff --git a/src/server/common/user_handler.hpp b/src/server/common/user_handler.hpp index 00c5b8cda356..817443aae576 100644 --- a/src/server/common/user_handler.hpp +++ b/src/server/common/user_handler.hpp @@ -142,4 +142,5 @@ class user_handler virtual void db_insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version) = 0; virtual void db_set_oos_flag(const std::string& uuid, int game_id) = 0; virtual void async_test_query(boost::asio::io_service& io_service, int limit) = 0; + virtual bool db_topic_id_exists(int topic_id) = 0; }; diff --git a/utils/mp-server/table_definitions.sql b/utils/mp-server/table_definitions.sql index 89d04b54e5bc..85c74178fc3c 100644 --- a/utils/mp-server/table_definitions.sql +++ b/utils/mp-server/table_definitions.sql @@ -18,6 +18,13 @@ -- PRIMARY KEY (USER_ID, GROUP_ID) -- ) ENGINE=InnoDB; +-- a minimal topics table, if not using a phpbb3 installation +-- create table topics +-- ( +-- TOPIC_ID MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, +-- PRIMARY KEY (TOPIC_ID) +-- ) ENGINE=InnoDB; + -- table which the forum inserts bans into, which wesnothd checks during login -- create table ban -- (