Skip to content

Commit

Permalink
wesnothd: Report different user_handler ban types
Browse files Browse the repository at this point in the history
This enables reporting back to the client the specific type of ban that
affects the account. This information is already normally provided by
phpBB when trying to view a page while banned, so we are not leaking any
new information here.

There isn't an API to retrieve the (user-visible) ban reason from the
ban list yet. It's probably not worth worrying about it since affected
users can see it when navigating to forums.wesnoth.org anyway.

(cherry-picked from commit 749e684)
  • Loading branch information
irydacea committed Oct 7, 2018
1 parent aa8c179 commit 3dc31e6
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 17 deletions.
4 changes: 3 additions & 1 deletion src/multiplayer_error_codes.hpp
Expand Up @@ -26,7 +26,9 @@
#define MP_NAME_RESERVED_ERROR "104"
#define MP_NAME_UNREGISTERED_ERROR "105"
#define MP_NAME_INACTIVE_WARNING "106"
#define MP_NAME_AUTH_BAN_ERROR "107"
#define MP_NAME_AUTH_BAN_USER_ERROR "107"
#define MP_NAME_AUTH_BAN_IP_ERROR "108"
#define MP_NAME_AUTH_BAN_EMAIL_ERROR "109"

#define MP_PASSWORD_REQUEST "200"
#define MP_PASSWORD_REQUEST_FOR_LOGGED_IN_NAME "201"
Expand Down
10 changes: 5 additions & 5 deletions src/server/forum_user_handler.cpp
Expand Up @@ -172,7 +172,7 @@ void fuh::set_is_moderator(const std::string& name, const bool& is_moderator) {
}
}

bool fuh::user_is_banned(const std::string& name, const std::string& addr)
fuh::BAN_TYPE fuh::user_is_banned(const std::string& name, const std::string& addr)
{
if(!user_exists(name)) {
throw error("No user with the name '" + name + "' exists.");
Expand All @@ -185,26 +185,26 @@ bool fuh::user_is_banned(const std::string& name, const std::string& addr)
ERR_UH << "Invalid user id for user '" << name << "'\n";
} else if(prepared_statement<bool>("SELECT 1 FROM `" + db_banlist_table_ + "` WHERE ban_userid = ? AND ban_exclude = 0", uid)) {
LOG_UH << "User '" << name << "' uid " << uid << " banned by uid\n";
return true;
return BAN_USER;
}

if(!addr.empty() && prepared_statement<bool>("SELECT 1 FROM `" + db_banlist_table_ + "` WHERE UPPER(ban_ip) = UPPER(?) AND ban_exclude = 0", addr)) {
LOG_UH << "User '" << name << "' ip " << addr << " banned by IP address\n";
return true;
return BAN_IP;
}

auto email = get_detail_for_user<std::string>(name, "user_email");

if(!email.empty() && prepared_statement<bool>("SELECT 1 FROM `" + db_banlist_table_ + "` WHERE UPPER(ban_email) = UPPER(?) AND ban_exclude = 0", email)) {
LOG_UH << "User '" << name << "' email " << email << " banned by email address\n";
return true;
return BAN_EMAIL;
}

} catch(sql_error& e) {
ERR_UH << "Could not check forum bans on user '" << name << "' :" << e.message << '\n';
}

return false;
return BAN_NONE;
}

std::string fuh::user_info(const std::string& name) {
Expand Down
2 changes: 1 addition & 1 deletion src/server/forum_user_handler.hpp
Expand Up @@ -69,7 +69,7 @@ class fuh : public user_handler {
bool user_is_moderator(const std::string& name);
void set_is_moderator(const std::string& name, const bool& is_moderator);

bool user_is_banned(const std::string& name, const std::string& addr);
BAN_TYPE user_is_banned(const std::string& name, const std::string& addr);

// Throws user_handler::error
std::string user_info(const std::string& name);
Expand Down
4 changes: 2 additions & 2 deletions src/server/sample_user_handler.cpp
Expand Up @@ -95,9 +95,9 @@ void suh::set_is_moderator(const std::string& name, const bool& is_moderator) {
users_[name].is_moderator = is_moderator;
}

bool suh::user_is_banned(const std::string&, const std::string&) {
suh::BAN_TYPE suh::user_is_banned(const std::string&, const std::string&) {
// FIXME: stub
return false;
return BAN_NONE;
}

void suh::set_mail(const std::string& user, const std::string& mail) {
Expand Down
2 changes: 1 addition & 1 deletion src/server/sample_user_handler.hpp
Expand Up @@ -43,7 +43,7 @@ class suh : public user_handler {
bool user_is_moderator(const std::string& name);
void set_is_moderator(const std::string& name, const bool& is_moderator);

bool user_is_banned(const std::string& name, const std::string&);
BAN_TYPE user_is_banned(const std::string& name, const std::string&);

std::string user_info(const std::string& name);

Expand Down
41 changes: 35 additions & 6 deletions src/server/server.cpp
Expand Up @@ -650,17 +650,46 @@ bool server::is_login_allowed(socket_ptr socket, const simple_wml::node* const l
}

const bool is_moderator = user_handler_ && user_handler_->user_is_moderator(username);
const bool is_auth_banned = user_handler_ && user_handler_->user_is_banned(username, client_address(socket));
const user_handler::BAN_TYPE auth_ban = user_handler_
? user_handler_->user_is_banned(username, client_address(socket))
: user_handler::BAN_NONE;

if(auth_ban) {
std::string ban_type_desc;
std::string ban_reason;
const char* msg_numeric;

switch(auth_ban) {
case user_handler::BAN_USER:
ban_type_desc = "account";
msg_numeric = MP_NAME_AUTH_BAN_USER_ERROR;
ban_reason = "a ban has been issued on your user account.";
break;
case user_handler::BAN_IP:
ban_type_desc = "IP address";
msg_numeric = MP_NAME_AUTH_BAN_IP_ERROR;
ban_reason = "a ban has been issued on your IP address.";
break;
case user_handler::BAN_EMAIL:
ban_type_desc = "email address";
msg_numeric = MP_NAME_AUTH_BAN_EMAIL_ERROR;
ban_reason = "a ban has been issued on your email address.";
break;
default:
ban_type_desc = "<unknown ban type>";
msg_numeric = "";
ban_reason = ban_type_desc;
}

if(is_auth_banned) {
if(!is_moderator) {
LOG_SERVER << client_address(socket) << "\t" << username
<< "\tis banned by user_handler\n";
async_send_error(socket, "The nickname '" + username + "' is banned on this server.", MP_NAME_AUTH_BAN_ERROR);
<< "\tis banned by user_handler (" << ban_type_desc << ")\n";
async_send_error(socket, "You are banned from this server: " + ban_reason, msg_numeric);
return false;
} else {
LOG_SERVER << client_address(socket) << "\t" << username
<< "\tis banned by user_handler, ignoring due to moderator flag\n";
<< "\tis banned by user_handler (" << ban_type_desc << "), "
<< "ignoring due to moderator flag\n";
}
}

Expand Down Expand Up @@ -694,7 +723,7 @@ bool server::is_login_allowed(socket_ptr socket, const simple_wml::node* const l
"If you no longer want to be automatically authenticated use '/query signout'.");
}

if(is_auth_banned) {
if(auth_ban) {
send_server_message(socket, "You are currently banned by the forum administration.");
}

Expand Down
10 changes: 9 additions & 1 deletion src/server/user_handler.hpp
Expand Up @@ -108,14 +108,22 @@ class user_handler {
/** Mark this user as a moderator */
virtual void set_is_moderator(const std::string& name, const bool& is_moderator) =0;

enum BAN_TYPE
{
BAN_NONE,
BAN_USER,
BAN_IP,
BAN_EMAIL,
};

/**
* Returns true if this user account or IP address is banned.
*
* @note The IP address is only used by the @a forum_user_handler
* subclass. Regular IP ban checks are done by @a server_base
* instead.
*/
virtual bool user_is_banned(const std::string& name, const std::string& addr="") = 0;
virtual BAN_TYPE user_is_banned(const std::string& name, const std::string& addr="") = 0;

struct error : public game::error {
error(const std::string& message) : game::error(message) {}
Expand Down

0 comments on commit 3dc31e6

Please sign in to comment.