Add SMTP client code and email verification functions
This commit is contained in:
parent
1ee1068ec0
commit
8daa602a68
19 changed files with 4485 additions and 12 deletions
|
@ -4,7 +4,8 @@ set(OUTPUT_CONFS ad.json anongame_infos.conf address_translation.conf
|
|||
bnissue.txt bnmaps.conf bnxpcalc.conf
|
||||
bnxplevel.conf channel.conf command_groups.conf realm.conf
|
||||
sql_DB_layout.conf supportfile.conf topics.conf
|
||||
tournament.conf versioncheck.json icons.conf)
|
||||
tournament.conf versioncheck.json icons.conf
|
||||
email_verification.conf cacert.pem)
|
||||
foreach(CONF ${OUTPUT_CONFS})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${CONF}.in ${CMAKE_CURRENT_BINARY_DIR}/${CONF} @ONLY)
|
||||
endforeach(CONF)
|
||||
|
@ -20,7 +21,8 @@ if(WITH_BNETD)
|
|||
bnetd_default_user.plain bnissue.txt bnmaps.conf
|
||||
bnxpcalc.conf bnxplevel.conf channel.conf command_groups.conf
|
||||
realm.conf sql_DB_layout.conf supportfile.conf topics.conf
|
||||
tournament.conf versioncheck.json icons.conf)
|
||||
tournament.conf versioncheck.json icons.conf
|
||||
email_verification.conf cacert.pem)
|
||||
endif(WITH_BNETD)
|
||||
|
||||
if(WITH_D2CS)
|
||||
|
|
|
@ -97,6 +97,7 @@ DBlayoutfile = "${SYSCONFDIR}/sql_DB_layout.conf"
|
|||
supportfile = "${SYSCONFDIR}/supportfile.conf"
|
||||
transfile = "${SYSCONFDIR}/address_translation.conf"
|
||||
customicons_file = "${SYSCONFDIR}/icons.conf"
|
||||
email_verification_file = "${SYSCONFDIR}/email_verification.conf"
|
||||
|
||||
|
||||
# #
|
||||
|
@ -370,6 +371,18 @@ passfail_bantime = 300
|
|||
# Max users limit in private channels (0 = unlimited)
|
||||
maxusers_per_channel = 0
|
||||
|
||||
# Verify account email address
|
||||
# Upon account registration, sends an email to the user with a code that will
|
||||
# be used to verify the registered email address.
|
||||
# Set smtp_server_url, smtp_port, smtp_username, and smtp_password before enabling.
|
||||
verify_account_email = false
|
||||
|
||||
# Number of minutes before an account email verification code expires
|
||||
verify_account_email_expiration = 10
|
||||
|
||||
# Email address to use for the 'From' field in email verification emails.
|
||||
verify_account_email_from_address = ""
|
||||
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
|
@ -645,3 +658,37 @@ log_command_groups = 2345678
|
|||
# set empty to log all commands
|
||||
log_command_list = ""
|
||||
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
|
||||
###############################################################################
|
||||
# SMTP #
|
||||
#-----------------------------------------------------------------------------#
|
||||
|
||||
# Path to a CA certificate store file in PEM format, relative to ${SYSCONFDIR},
|
||||
# containing X.509 certificates of public certificate authorities.
|
||||
# See https://curl.haxx.se/docs/caextract.html
|
||||
smtp_ca_cert_store = "${SYSCONFDIR}/cacert.pem"
|
||||
|
||||
# URL to download a new CA certificate store file.
|
||||
smtp_ca_cert_store_remote_url = "https://curl.haxx.se/ca/cacert.pem"
|
||||
|
||||
# Number of days to wait before downloading a new cacert.pem
|
||||
# Recommended value: 30
|
||||
# Set to 0 to disable
|
||||
smtp_ca_cert_store_fetch_interval = 30
|
||||
|
||||
# smtp_server_url = "smtp.gmail.com"
|
||||
smtp_server_url = ""
|
||||
|
||||
smtp_port = 587
|
||||
|
||||
smtp_username = ""
|
||||
|
||||
# If your account has two-factor authentication (2FA) enabled, you will need to
|
||||
# create a token through your SMTP provider.
|
||||
smtp_password = ""
|
||||
|
||||
# #
|
||||
##############################################################################
|
|
@ -81,6 +81,7 @@ anongame_infos_file = conf\anongame_infos.conf
|
|||
DBlayoutfile = conf\sql_DB_layout.conf
|
||||
supportfile = conf\supportfile.conf
|
||||
customicons_file = conf\icons.conf
|
||||
email_verification_file = "conf\email_verification.conf"
|
||||
|
||||
|
||||
# #
|
||||
|
@ -353,6 +354,18 @@ passfail_bantime = 300
|
|||
# Max users limit in private channels (0 = unlimited)
|
||||
maxusers_per_channel = 0
|
||||
|
||||
# Verify account email address
|
||||
# Upon account registration, sends an email to the user with a code that will
|
||||
# be used to verify the registered email address.
|
||||
# Set smtp_server_url, smtp_port, smtp_username, and smtp_password before enabling.
|
||||
verify_account_email = false
|
||||
|
||||
# Number of minutes before an account email verification code expires
|
||||
verify_account_email_expiration = 10
|
||||
|
||||
# Email address to use for the 'From' field in email verification emails.
|
||||
verify_account_email_from_address = ""
|
||||
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
|
@ -632,3 +645,37 @@ log_command_groups = 2345678
|
|||
# set empty to log all commands
|
||||
log_command_list = ""
|
||||
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
|
||||
###############################################################################
|
||||
# SMTP #
|
||||
#-----------------------------------------------------------------------------#
|
||||
|
||||
# Path to a CA certificate store file in PEM format, relative to ${SYSCONFDIR},
|
||||
# containing X.509 certificates of public certificate authorities.
|
||||
# See https://curl.haxx.se/docs/caextract.html
|
||||
smtp_ca_cert_store = "conf\cacert.pem"
|
||||
|
||||
# URL to download a new CA certificate store file.
|
||||
smtp_ca_cert_store_remote_url = "https://curl.haxx.se/ca/cacert.pem"
|
||||
|
||||
# Number of days to wait before downloading a new cacert.pem
|
||||
# Recommended value: 30
|
||||
# Set to 0 to disable
|
||||
smtp_ca_cert_store_fetch_interval = 30
|
||||
|
||||
# smtp_server_url = "smtp.gmail.com"
|
||||
smtp_server_url = ""
|
||||
|
||||
smtp_port = 587
|
||||
|
||||
smtp_username = ""
|
||||
|
||||
# If your account has two-factor authentication (2FA) enabled, you will need to
|
||||
# create a token through your SMTP provider.
|
||||
smtp_password = ""
|
||||
|
||||
# #
|
||||
##############################################################################
|
3466
conf/cacert.pem.in
Normal file
3466
conf/cacert.pem.in
Normal file
File diff suppressed because it is too large
Load diff
9
conf/email_verification.conf.in
Normal file
9
conf/email_verification.conf.in
Normal file
|
@ -0,0 +1,9 @@
|
|||
Hello {{account_name}},
|
||||
|
||||
Your verification code is {{account_email_verification_code}}.
|
||||
This code will expire in {{account_email_verification_expiration}} minutes.
|
||||
|
||||
To verify your email address, enter /email verify {{account_email_verification_code}} in the PvPGN server.
|
||||
|
||||
|
||||
{pvpgn_server_name}
|
|
@ -19,6 +19,7 @@
|
|||
"acct_userid int","NULL"
|
||||
"acct_passhash1 varchar(40)","NULL"
|
||||
"acct_email varchar(128)","NULL"
|
||||
"acct_email_verified varchar(6)","'false'"
|
||||
"auth_admin varchar(6)","'false'"
|
||||
"auth_normallogin varchar(6)","'true'"
|
||||
"auth_changepass varchar(6)","'true'"
|
||||
|
@ -39,6 +40,10 @@
|
|||
"acct_lastlogin_ip varchar(16)","NULL"
|
||||
:"DROP INDEX username"
|
||||
:"CREATE UNIQUE INDEX username2 ON ${prefix}BNET (username)"
|
||||
[${prefix}email_verification]
|
||||
"uid int NOT NULL PRIMARY KEY","'0'"
|
||||
code varchar(64)","NULL"
|
||||
expiration int", "'0'"
|
||||
[${prefix}WOL]
|
||||
"uid int NOT NULL PRIMARY KEY","'0'"
|
||||
"auth_apgar varchar(8)","NULL"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
set(BNETD_SOURCES
|
||||
account.cpp account.h account_wrap.cpp account_wrap.h adbanner.cpp
|
||||
account.cpp account.h account_email_verification.cpp account_email_verification.h
|
||||
account_wrap.cpp account_wrap.h adbanner.cpp
|
||||
adbanner.h alias_command.cpp alias_command.h anongame.cpp
|
||||
anongame_gameresult.cpp anongame_gameresult.h anongame.h
|
||||
anongame_infos.cpp anongame_infos.h anongame_maplists.cpp
|
||||
|
@ -7,8 +8,8 @@ set(BNETD_SOURCES
|
|||
attrlayer.h autoupdate.cpp autoupdate.h channel_conv.cpp channel_conv.h
|
||||
channel.cpp channel.h character.cpp character.h clan.cpp clan.h
|
||||
cmdline.cpp cmdline.h command.cpp command_groups.cpp command_groups.h
|
||||
command.h connection.cpp connection.h file.cpp file.h file_plain.cpp
|
||||
file_plain.h friends.cpp friends.h game_conv.cpp
|
||||
command.h connection.cpp connection.h file.cpp file.h
|
||||
file_plain.cpp file_plain.h friends.cpp friends.h game_conv.cpp
|
||||
game_conv.h game.cpp game.h handle_anongame.cpp handle_anongame.h
|
||||
handle_apireg.cpp handle_apireg.h handle_bnet.cpp handle_bnet.h
|
||||
handle_bot.cpp handle_bot.h handle_d2cs.cpp handle_d2cs.h
|
||||
|
@ -20,9 +21,9 @@ set(BNETD_SOURCES
|
|||
ipban.cpp ipban.h irc.cpp irc.h ladder_calc.cpp ladder_calc.h ladder.cpp
|
||||
ladder.h mail.cpp mail.h main.cpp message.cpp message.h news.cpp news.h
|
||||
output.cpp output.h prefs.cpp prefs.h quota.h realm.cpp realm.h
|
||||
runprog.cpp runprog.h server.cpp server.h sql_common.cpp sql_common.h
|
||||
sql_dbcreator.cpp sql_dbcreator.h sql_mysql.cpp sql_mysql.h sql_odbc.cpp
|
||||
sql_odbc.h sql_pgsql.cpp sql_pgsql.h sql_sqlite3.cpp sql_sqlite3.h
|
||||
runprog.cpp runprog.h server.cpp server.h smtp.cpp smtp.h sql_common.cpp
|
||||
sql_common.h sql_dbcreator.cpp sql_dbcreator.h sql_mysql.cpp sql_mysql.h
|
||||
sql_odbc.cpp sql_odbc.h sql_pgsql.cpp sql_pgsql.h sql_sqlite3.cpp sql_sqlite3.h
|
||||
storage.cpp storage_file.cpp storage_file.h storage.h
|
||||
storage_sql.cpp storage_sql.h support.cpp support.h
|
||||
team.cpp team.h tick.cpp tick.h timer.cpp timer.h topic.cpp topic.h
|
||||
|
@ -51,6 +52,7 @@ endif(WITH_WIN32_GUI)
|
|||
target_include_directories(bnetd
|
||||
PRIVATE
|
||||
${ZLIB_INCLUDE_DIRS}
|
||||
${CURL_INCLUDE_DIRS}
|
||||
${LUA_INCLUDE_DIR}
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${SQLITE3_INCLUDE_DIR}
|
||||
|
@ -58,7 +60,7 @@ target_include_directories(bnetd
|
|||
${ODBC_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(bnetd PRIVATE common compat fmt::fmt win32 ${NETWORK_LIBRARIES} ZLIB::ZLIB ${MYSQL_CLIENT_LIBS} ${SQLITE3_LIBRARIES} ${PGSQL_LIBRARIES} ${ODBC_LIBRARIES} ${LUA_LIBRARIES})
|
||||
target_link_libraries(bnetd PRIVATE common compat fmt::fmt win32 ${NETWORK_LIBRARIES} ZLIB::ZLIB ${CURL_LIBRARIES} ${MYSQL_CLIENT_LIBS} ${SQLITE3_LIBRARIES} ${PGSQL_LIBRARIES} ${ODBC_LIBRARIES} ${LUA_LIBRARIES})
|
||||
|
||||
install(TARGETS bnetd DESTINATION ${SBINDIR})
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
186
src/bnetd/account_email_verification.cpp
Normal file
186
src/bnetd/account_email_verification.cpp
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* 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; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "common/setup_before.h"
|
||||
#include "account_email_verification.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
#include <curl.h>
|
||||
|
||||
#include "common/eventlog.h"
|
||||
|
||||
#include "account.h"
|
||||
#include "account_wrap.h"
|
||||
#include "prefs.h"
|
||||
#include "server.h"
|
||||
#include "smtp.h"
|
||||
#include "common/setup_after.h"
|
||||
|
||||
namespace pvpgn
|
||||
{
|
||||
|
||||
namespace bnetd
|
||||
{
|
||||
|
||||
static std::string message;
|
||||
static std::string verify_account_email_from_address;
|
||||
|
||||
bool account_email_verification_load(const char* filepath, const char* prefs_servername, const char* prefs_verify_account_email_from_address)
|
||||
{
|
||||
if (filepath == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL filepath");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prefs_servername == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL prefs_servername");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prefs_verify_account_email_from_address == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL prefs_verify_account_email_from_address");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream infile{ filepath };
|
||||
if (!infile.is_open())
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Could not open email verification message file ({})", filepath);
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::string raw_message{ std::istreambuf_iterator<char>(infile), std::istreambuf_iterator<char>() };
|
||||
message = fmt::format(raw_message, fmt::arg("pvpgn_server_name", prefs_servername));
|
||||
|
||||
eventlog(eventlog_level_info, __FUNCTION__, "Succesfully loaded email verification message ({} bytes)", message.length());
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to load email verification message ({})", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
verify_account_email_from_address = prefs_verify_account_email_from_address;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void account_email_verification_unload()
|
||||
{
|
||||
message.clear();
|
||||
verify_account_email_from_address.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* If successful, sets "BNET\\acct\\email\\verified" attribute to true and sets "email_verification\\code"
|
||||
* attribute and "email_verification\\expiration" attribute to 0 for the given account.
|
||||
*/
|
||||
AccountVerifyEmailStatus account_verify_email(t_account* account, const std::string& code)
|
||||
{
|
||||
if (account == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
|
||||
return AccountVerifyEmailStatus::FailureOther;
|
||||
}
|
||||
|
||||
const char* account_code = account_get_email_verification_code(account);
|
||||
if (account_code == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Could not retrieve email verification code for account uid {}", account_get_uid(account));
|
||||
return AccountVerifyEmailStatus::FailureOther;
|
||||
}
|
||||
|
||||
unsigned int account_expiration = account_get_email_verification_expiration(account);
|
||||
if (account_expiration == 0)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Could not retrieve email verification expiration date for account uid {}", account_get_uid(account));
|
||||
return AccountVerifyEmailStatus::FailureOther;
|
||||
}
|
||||
|
||||
if (now >= account_expiration)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to verify email for account uid {} (Email verification code expired)", account_get_uid(account));
|
||||
return AccountVerifyEmailStatus::FailureCodeExpired;
|
||||
}
|
||||
|
||||
if (code.compare(account_code) != 0)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to verify email for account uid {} (Incorrect email verification code)", account_get_uid(account));
|
||||
return AccountVerifyEmailStatus::FailureCodeIncorrect;
|
||||
}
|
||||
|
||||
int verified = account_set_email_verified(account, true);
|
||||
if (verified != 1)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Could not verify email code for account uid {}", account_get_uid(account));
|
||||
return AccountVerifyEmailStatus::FailureOther;
|
||||
}
|
||||
|
||||
account_set_email_verification_code(account, 0);
|
||||
account_set_email_verification_expiration(account, 0);
|
||||
|
||||
eventlog(eventlog_level_info, __FUNCTION__, "Succesfully verified email address ({}) account uid {}", account_get_email(account), account_get_uid(account));
|
||||
|
||||
return AccountVerifyEmailStatus::Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an email verification code and saves it in the "email_verification\\code" attribute for the given account. Sets the "email_verification\\expiration" attribute
|
||||
* to X minutes from current time, where X is the value of 'verify_account_email_expiration' in bnetd.conf.
|
||||
* Sends an email containing the email verification code to the registered email address of the account.
|
||||
*/
|
||||
bool account_generate_email_verification_code(t_account* account)
|
||||
{
|
||||
if (account == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::random_device rdevice;
|
||||
static std::default_random_engine rengine(rdevice());
|
||||
static std::uniform_int_distribution<unsigned long long> uniform_dist(std::numeric_limits<unsigned long long>::min(), std::numeric_limits<unsigned long long>::max());
|
||||
|
||||
std::time_t expiration = now + (60ull * prefs_get_verify_account_email_expiration());
|
||||
std::string code = fmt::to_string(uniform_dist(rengine));
|
||||
|
||||
int a = account_set_email_verification_expiration(account, expiration);
|
||||
int b = account_set_email_verification_code(account, code.c_str());
|
||||
if (!(a == 0 && b == 0))
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Could not generate an email verification code for account uid {}", account_get_uid(account));
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string personalized_message = fmt::format(message, fmt::arg("account_name", account_get_name(account)), fmt::arg("account_email_verification_code", code), fmt::arg("account_email_verification_expiration", expiration));
|
||||
|
||||
eventlog(eventlog_level_debug, __FUNCTION__, "Sending email verification code to {} for account uid {}", account_get_email(account), account_get_uid(account));
|
||||
smtp_send_email(account_get_email(account), verify_account_email_from_address, "Email Verification", personalized_message);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
54
src/bnetd/account_email_verification.h
Normal file
54
src/bnetd/account_email_verification.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INCLUDED_EMAIL_VERIFICATION_H
|
||||
#define INCLUDED_EMAIL_VERIFICATION_H
|
||||
|
||||
#ifndef JUST_NEED_TYPES
|
||||
#define JUST_NEED_TYPES
|
||||
|
||||
#include "account.h"
|
||||
|
||||
#undef JUST_NEED_TYPES
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace pvpgn
|
||||
{
|
||||
|
||||
namespace bnetd
|
||||
{
|
||||
|
||||
enum class AccountVerifyEmailStatus
|
||||
{
|
||||
Success,
|
||||
FailureCodeExpired,
|
||||
FailureCodeIncorrect,
|
||||
FailureOther
|
||||
};
|
||||
|
||||
bool account_email_verification_load(const char* filepath, const char* prefs_servername, const char* prefs_verify_account_email_from_address);
|
||||
void account_email_verification_unload();
|
||||
AccountVerifyEmailStatus account_verify_email(t_account* account, const std::string& code);
|
||||
bool account_generate_email_verification_code(t_account* account);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -23,6 +23,8 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "compat/strcasecmp.h"
|
||||
|
||||
#include "common/bnet_protocol.h"
|
||||
|
@ -2641,6 +2643,72 @@ namespace pvpgn
|
|||
return account_set_strattr(account, "BNET\\acct\\email", email.c_str());
|
||||
}
|
||||
|
||||
extern int account_get_email_verified(t_account* account)
|
||||
{
|
||||
if (account == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return account_get_boolattr(account, "BNET\\acct\\email\\verified");
|
||||
}
|
||||
|
||||
extern int account_set_email_verified(t_account* account, bool is_verified)
|
||||
{
|
||||
if (account == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return account_set_boolattr(account, "BNET\\acct\\email\\verified", is_verified ? 1 : 0);
|
||||
}
|
||||
|
||||
extern char const * account_get_email_verification_code(t_account* account)
|
||||
{
|
||||
if (account == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return account_get_strattr(account, "email_verification\\code");
|
||||
}
|
||||
|
||||
extern int account_set_email_verification_code(t_account* account, char const * expiration_date)
|
||||
{
|
||||
if (account == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return account_set_strattr(account, "email_verification\\code", fmt::to_string(expiration_date).c_str());
|
||||
}
|
||||
|
||||
extern unsigned int account_get_email_verification_expiration(t_account* account)
|
||||
{
|
||||
if (account == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return account_get_numattr(account, "email_verification\\expiration");
|
||||
}
|
||||
|
||||
extern int account_set_email_verification_expiration(t_account* account, unsigned int expiration_date)
|
||||
{
|
||||
if (account == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return account_set_numattr(account, "email_verification\\expiration", expiration_date);
|
||||
}
|
||||
|
||||
extern int account_set_userlang(t_account * account, const char * lang)
|
||||
{
|
||||
if (lang)
|
||||
|
|
|
@ -264,6 +264,12 @@ namespace pvpgn
|
|||
|
||||
extern int account_set_email(t_account * account, std::string email);
|
||||
extern char const * account_get_email(t_account * account);
|
||||
extern int account_get_email_verified(t_account* account);
|
||||
extern int account_set_email_verified(t_account* account, bool is_verified);
|
||||
extern char const* account_get_email_verification_code(t_account* account);
|
||||
extern int account_set_email_verification_code(t_account* account, char const * expiration_date);
|
||||
extern unsigned int account_get_email_verification_expiration(t_account* account);
|
||||
extern int account_set_email_verification_expiration(t_account* account, unsigned int expiration_date);
|
||||
|
||||
extern int account_set_userlang(t_account * account, const char * lang);
|
||||
extern int account_set_userlang(t_account * account, std::string lang);
|
||||
|
|
|
@ -88,6 +88,8 @@
|
|||
#include "handle_apireg.h"
|
||||
#include "i18n.h"
|
||||
#include "userlog.h"
|
||||
#include "account_email_verification.h"
|
||||
#include "smtp.h"
|
||||
#ifdef WIN32
|
||||
#include "win32/windump.h"
|
||||
#endif
|
||||
|
@ -373,10 +375,10 @@ int pre_server_startup(void)
|
|||
{
|
||||
AdBannerList.unload();
|
||||
}
|
||||
|
||||
|
||||
AdBannerList.load(prefs_get_adfile());
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "{}", e.what());
|
||||
}
|
||||
|
@ -420,6 +422,26 @@ int pre_server_startup(void)
|
|||
eventlog(eventlog_level_error, __FUNCTION__, "could not load realm list");
|
||||
//topiclist_load(std::string(prefs_get_topicfile()));
|
||||
userlog_init();
|
||||
if (prefs_get_verify_account_email() == 1)
|
||||
{
|
||||
if (!smtp_init(prefs_get_smtp_ca_cert_store(), prefs_get_smtp_server_url(), prefs_get_smtp_port(), prefs_get_smtp_username(), prefs_get_smtp_password()))
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to initialize SMTP client");
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Disabling account email verification");
|
||||
prefs_set_verify_account_email(false);
|
||||
}
|
||||
|
||||
if (!account_email_verification_load(prefs_get_email_verification_file(), prefs_get_servername(), prefs_get_verify_account_email_from_address()))
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to load email verification message");
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Disabling account email verification");
|
||||
prefs_set_verify_account_email(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eventlog(eventlog_level_debug, __FUNCTION__, "Config option 'verify_account_email' is false");
|
||||
}
|
||||
|
||||
#ifdef WITH_LUA
|
||||
lua_load(prefs_get_scriptdir());
|
||||
|
@ -435,6 +457,9 @@ void post_server_shutdown(int status)
|
|||
{
|
||||
case 0:
|
||||
//topiclist_unload();
|
||||
account_email_verification_unload();
|
||||
smtp_cleanup();
|
||||
account_email_verification_unload();
|
||||
realmlist_destroy();
|
||||
teamlist_unload();
|
||||
clanlist_unload();
|
||||
|
|
|
@ -144,6 +144,7 @@ namespace pvpgn
|
|||
char const * command_groups_file;
|
||||
char const * tournament_file;
|
||||
char const * customicons_file;
|
||||
char const * email_verification_file;
|
||||
char const * scriptdir;
|
||||
char const * aliasfile;
|
||||
char const * anongame_infos_file;
|
||||
|
@ -156,6 +157,9 @@ namespace pvpgn
|
|||
unsigned int passfail_count;
|
||||
unsigned int passfail_bantime;
|
||||
unsigned int maxusers_per_channel;
|
||||
unsigned int verify_account_email;
|
||||
unsigned int verify_account_email_expiration;
|
||||
char const* verify_account_email_from_address;
|
||||
char const * supportfile;
|
||||
char const * allowed_clients;
|
||||
char const * ladder_games;
|
||||
|
@ -168,6 +172,13 @@ namespace pvpgn
|
|||
unsigned int log_commands;
|
||||
char const * log_command_groups;
|
||||
char const * log_command_list;
|
||||
char const * smtp_ca_cert_store;
|
||||
char const * smtp_ca_cert_store_remote_url;
|
||||
unsigned int smtp_ca_cert_store_fetch_interval;
|
||||
char const * smtp_server_url;
|
||||
unsigned int smtp_port;
|
||||
char const * smtp_username;
|
||||
char const * smtp_password;
|
||||
|
||||
char const * apiregaddrs;
|
||||
char const * wolv1addrs;
|
||||
|
@ -589,6 +600,10 @@ namespace pvpgn
|
|||
static const char *conf_get_customicons_file(void);
|
||||
static int conf_setdef_customicons_file(void);
|
||||
|
||||
static int conf_set_email_verification_file(const char* valstr);
|
||||
static const char* conf_get_email_verification_file(void);
|
||||
static int conf_setdef_email_verification_file(void);
|
||||
|
||||
static int conf_set_scriptdir(const char *valstr);
|
||||
static const char *conf_get_scriptdir(void);
|
||||
static int conf_setdef_scriptdir(void);
|
||||
|
@ -637,6 +652,18 @@ namespace pvpgn
|
|||
static const char *conf_get_maxusers_per_channel(void);
|
||||
static int conf_setdef_maxusers_per_channel(void);
|
||||
|
||||
static int conf_set_verify_account_email(const char* valstr);
|
||||
static const char* conf_get_verify_account_email(void);
|
||||
static int conf_setdef_verify_account_email(void);
|
||||
|
||||
static int conf_set_verify_account_email_expiration(const char* valstr);
|
||||
static const char* conf_get_verify_account_email_expiration(void);
|
||||
static int conf_setdef_verify_account_email_expiration(void);
|
||||
|
||||
static int conf_set_verify_account_email_from_address(const char* valstr);
|
||||
static const char* conf_get_verify_account_email_from_address(void);
|
||||
static int conf_setdef_verify_account_email_from_address(void);
|
||||
|
||||
static int conf_set_allowed_clients(const char *valstr);
|
||||
static const char *conf_get_allowed_clients(void);
|
||||
static int conf_setdef_allowed_clients(void);
|
||||
|
@ -681,6 +708,34 @@ namespace pvpgn
|
|||
static const char *conf_get_log_command_list(void);
|
||||
static int conf_setdef_log_command_list(void);
|
||||
|
||||
static int conf_set_smtp_ca_cert_store(const char* valstr);
|
||||
static const char* conf_get_smtp_ca_cert_store(void);
|
||||
static int conf_setdef_smtp_ca_cert_store(void);
|
||||
|
||||
static int conf_set_smtp_ca_cert_store_remote_url(const char* valstr);
|
||||
static const char* conf_get_smtp_ca_cert_store_remote_url(void);
|
||||
static int conf_setdef_smtp_ca_cert_store_remote_url(void);
|
||||
|
||||
static int conf_set_smtp_ca_cert_store_fetch_interval(const char* valstr);
|
||||
static const char* conf_get_smtp_ca_cert_store_fetch_interval(void);
|
||||
static int conf_setdef_smtp_ca_cert_store_fetch_interval(void);
|
||||
|
||||
static int conf_set_smtp_server_url(const char* valstr);
|
||||
static const char* conf_get_smtp_server_url(void);
|
||||
static int conf_setdef_smtp_server_url(void);
|
||||
|
||||
static int conf_set_smtp_port(const char* valstr);
|
||||
static const char* conf_get_smtp_port(void);
|
||||
static int conf_setdef_smtp_port(void);
|
||||
|
||||
static int conf_set_smtp_username(const char* valstr);
|
||||
static const char* conf_get_smtp_username(void);
|
||||
static int conf_setdef_smtp_username(void);
|
||||
|
||||
static int conf_set_smtp_password(const char* valstr);
|
||||
static const char* conf_get_smtp_password(void);
|
||||
static int conf_setdef_smtp_password(void);
|
||||
|
||||
|
||||
static int conf_setdef_apireg_addrs(void);
|
||||
static int conf_set_apireg_addrs(const char *valstr);
|
||||
|
@ -827,6 +882,7 @@ namespace pvpgn
|
|||
{ "command_groups_file", conf_set_command_groups_file, conf_get_command_groups_file, conf_setdef_command_groups_file },
|
||||
{ "tournament_file", conf_set_tournament_file, conf_get_tournament_file, conf_setdef_tournament_file },
|
||||
{ "customicons_file", conf_set_customicons_file, conf_get_customicons_file, conf_setdef_customicons_file },
|
||||
{ "email_verification_file", conf_set_email_verification_file, conf_get_email_verification_file, conf_setdef_email_verification_file },
|
||||
{ "scriptdir", conf_set_scriptdir, conf_get_scriptdir, conf_setdef_scriptdir },
|
||||
{ "aliasfile", conf_set_aliasfile, conf_get_aliasfile, conf_setdef_aliasfile },
|
||||
{ "anongame_infos_file", conf_set_anongame_infos_file, conf_get_anongame_infos_file, conf_setdef_anongame_infos_file },
|
||||
|
@ -839,6 +895,9 @@ namespace pvpgn
|
|||
{ "passfail_count", conf_set_passfail_count, conf_get_passfail_count, conf_setdef_passfail_count },
|
||||
{ "passfail_bantime", conf_set_passfail_bantime, conf_get_passfail_bantime, conf_setdef_passfail_bantime },
|
||||
{ "maxusers_per_channel", conf_set_maxusers_per_channel, conf_get_maxusers_per_channel, conf_setdef_maxusers_per_channel },
|
||||
{ "verify_account_email", conf_set_verify_account_email, conf_get_verify_account_email, conf_setdef_verify_account_email },
|
||||
{ "verify_account_email_expiration", conf_set_verify_account_email_expiration, conf_get_verify_account_email_expiration, conf_setdef_verify_account_email_expiration },
|
||||
{ "verify_account_email_from_address", conf_set_verify_account_email_from_address, conf_get_verify_account_email_from_address, conf_setdef_verify_account_email_from_address },
|
||||
{ "allowed_clients", conf_set_allowed_clients, conf_get_allowed_clients, conf_setdef_allowed_clients },
|
||||
{ "ladder_games", conf_set_ladder_games, conf_get_ladder_games, conf_setdef_ladder_games },
|
||||
{ "max_connections", conf_set_max_connections, conf_get_max_connections, conf_setdef_max_connections },
|
||||
|
@ -850,6 +909,13 @@ namespace pvpgn
|
|||
{ "log_commands", conf_set_log_commands, conf_get_log_commands, conf_setdef_log_commands },
|
||||
{ "log_command_groups", conf_set_log_command_groups, conf_get_log_command_groups, conf_setdef_log_command_groups },
|
||||
{ "log_command_list", conf_set_log_command_list, conf_get_log_command_list, conf_setdef_log_command_list },
|
||||
{ "smtp_ca_cert_store", conf_set_smtp_ca_cert_store, conf_get_smtp_ca_cert_store, conf_setdef_smtp_ca_cert_store },
|
||||
{ "smtp_ca_cert_store_remote_url", conf_set_smtp_ca_cert_store_remote_url, conf_get_smtp_ca_cert_store_remote_url, conf_setdef_smtp_ca_cert_store_remote_url },
|
||||
{ "smtp_ca_cert_store_fetch_interval", conf_set_smtp_ca_cert_store_fetch_interval, conf_get_smtp_ca_cert_store_fetch_interval, conf_setdef_smtp_ca_cert_store_fetch_interval },
|
||||
{ "smtp_server_url", conf_set_smtp_server_url, conf_get_smtp_server_url, conf_setdef_smtp_server_url, },
|
||||
{ "smtp_port", conf_set_smtp_port, conf_get_smtp_port, conf_setdef_smtp_port },
|
||||
{ "smtp_username", conf_set_smtp_username, conf_get_smtp_username, conf_setdef_smtp_username },
|
||||
{ "smtp_password", conf_set_smtp_password, conf_get_smtp_password, conf_setdef_smtp_password },
|
||||
|
||||
{ "apiregaddrs", conf_set_apireg_addrs, conf_get_apireg_addrs, conf_setdef_apireg_addrs },
|
||||
{ "wgameresaddrs", conf_set_wgameres_addrs, conf_get_wgameres_addrs, conf_setdef_wgameres_addrs },
|
||||
|
@ -3050,6 +3116,28 @@ namespace pvpgn
|
|||
return prefs_runtime_config.customicons_file;
|
||||
}
|
||||
|
||||
|
||||
extern char const* prefs_get_email_verification_file(void)
|
||||
{
|
||||
return prefs_runtime_config.email_verification_file;
|
||||
}
|
||||
|
||||
static int conf_set_email_verification_file(const char* valstr)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.email_verification_file, valstr, NULL);
|
||||
}
|
||||
|
||||
static const char* conf_get_email_verification_file(void)
|
||||
{
|
||||
return prefs_runtime_config.email_verification_file;
|
||||
}
|
||||
|
||||
static int conf_setdef_email_verification_file(void)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.email_verification_file, NULL, BNETD_EMAIL_VERIFICATION_FILE);
|
||||
}
|
||||
|
||||
|
||||
extern char const * prefs_get_scriptdir(void)
|
||||
{
|
||||
return prefs_runtime_config.scriptdir;
|
||||
|
@ -3312,6 +3400,74 @@ namespace pvpgn
|
|||
}
|
||||
|
||||
|
||||
extern unsigned int prefs_get_verify_account_email(void)
|
||||
{
|
||||
return prefs_runtime_config.verify_account_email;
|
||||
}
|
||||
|
||||
extern void prefs_set_verify_account_email(bool enable)
|
||||
{
|
||||
prefs_runtime_config.verify_account_email = enable ? 1 : 0;
|
||||
}
|
||||
|
||||
static int conf_set_verify_account_email(const char* valstr)
|
||||
{
|
||||
return conf_set_bool(&prefs_runtime_config.verify_account_email, valstr, 0);
|
||||
}
|
||||
|
||||
static const char* conf_get_verify_account_email(void)
|
||||
{
|
||||
return conf_get_bool(prefs_runtime_config.verify_account_email);
|
||||
}
|
||||
|
||||
static int conf_setdef_verify_account_email(void)
|
||||
{
|
||||
return conf_set_bool(&prefs_runtime_config.verify_account_email, nullptr, 0);
|
||||
}
|
||||
|
||||
|
||||
extern unsigned int prefs_get_verify_account_email_expiration(void)
|
||||
{
|
||||
return prefs_runtime_config.verify_account_email_expiration;
|
||||
}
|
||||
|
||||
static int conf_set_verify_account_email_expiration(const char* valstr)
|
||||
{
|
||||
return conf_set_int(&prefs_runtime_config.verify_account_email_expiration, valstr, 0);
|
||||
}
|
||||
|
||||
static const char* conf_get_verify_account_email_expiration(void)
|
||||
{
|
||||
return conf_get_int(prefs_runtime_config.verify_account_email_expiration);
|
||||
}
|
||||
|
||||
static int conf_setdef_verify_account_email_expiration(void)
|
||||
{
|
||||
return conf_set_int(&prefs_runtime_config.verify_account_email_expiration, nullptr, 10);
|
||||
}
|
||||
|
||||
|
||||
extern char const* prefs_get_verify_account_email_from_address(void)
|
||||
{
|
||||
return prefs_runtime_config.verify_account_email_from_address;
|
||||
}
|
||||
|
||||
static int conf_set_verify_account_email_from_address(const char* valstr)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.verify_account_email_from_address, valstr, NULL);
|
||||
}
|
||||
|
||||
static const char* conf_get_verify_account_email_from_address(void)
|
||||
{
|
||||
return prefs_runtime_config.verify_account_email_from_address;
|
||||
}
|
||||
|
||||
static int conf_setdef_verify_account_email_from_address(void)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.verify_account_email_from_address, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
extern char const * prefs_get_supportfile(void)
|
||||
{
|
||||
return prefs_runtime_config.supportfile;
|
||||
|
@ -3563,6 +3719,152 @@ namespace pvpgn
|
|||
}
|
||||
|
||||
|
||||
extern char const * prefs_get_smtp_ca_cert_store(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_ca_cert_store;
|
||||
}
|
||||
|
||||
static int conf_set_smtp_ca_cert_store(const char* valstr)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_ca_cert_store, valstr, NULL);
|
||||
}
|
||||
|
||||
static const char* conf_get_smtp_ca_cert_store(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_ca_cert_store;
|
||||
}
|
||||
|
||||
static int conf_setdef_smtp_ca_cert_store(void)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_ca_cert_store, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
extern char const * prefs_get_smtp_ca_cert_store_remote_url(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_ca_cert_store_remote_url;
|
||||
}
|
||||
|
||||
static int conf_set_smtp_ca_cert_store_remote_url(const char* valstr)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_ca_cert_store_remote_url, valstr, NULL);
|
||||
}
|
||||
|
||||
static const char* conf_get_smtp_ca_cert_store_remote_url(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_ca_cert_store_remote_url;
|
||||
}
|
||||
|
||||
static int conf_setdef_smtp_ca_cert_store_remote_url(void)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_ca_cert_store_remote_url, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
extern unsigned int prefs_get_smtp_ca_cert_store_fetch_interval(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_ca_cert_store_fetch_interval;
|
||||
}
|
||||
|
||||
static int conf_set_smtp_ca_cert_store_fetch_interval(const char* valstr)
|
||||
{
|
||||
return conf_set_int(&prefs_runtime_config.smtp_ca_cert_store_fetch_interval, valstr, NULL);
|
||||
}
|
||||
|
||||
static const char* conf_get_smtp_ca_cert_store_fetch_interval(void)
|
||||
{
|
||||
return conf_get_int(prefs_runtime_config.smtp_ca_cert_store_fetch_interval);
|
||||
}
|
||||
|
||||
static int conf_setdef_smtp_ca_cert_store_fetch_interval(void)
|
||||
{
|
||||
return conf_set_int(&prefs_runtime_config.smtp_ca_cert_store_fetch_interval, NULL, 30);
|
||||
}
|
||||
|
||||
|
||||
extern char const * prefs_get_smtp_server_url(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_server_url;
|
||||
}
|
||||
|
||||
static int conf_set_smtp_server_url(const char* valstr)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_server_url, valstr, NULL);
|
||||
}
|
||||
|
||||
static const char* conf_get_smtp_server_url(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_server_url;
|
||||
}
|
||||
|
||||
static int conf_setdef_smtp_server_url(void)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_server_url, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
extern unsigned int prefs_get_smtp_port(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_port;
|
||||
}
|
||||
|
||||
static int conf_set_smtp_port(const char* valstr)
|
||||
{
|
||||
return conf_set_int(&prefs_runtime_config.smtp_port, valstr, NULL);
|
||||
}
|
||||
|
||||
static const char* conf_get_smtp_port(void)
|
||||
{
|
||||
return conf_get_int(prefs_runtime_config.smtp_port);
|
||||
}
|
||||
|
||||
static int conf_setdef_smtp_port(void)
|
||||
{
|
||||
return conf_set_int(&prefs_runtime_config.smtp_port, NULL, 587);
|
||||
}
|
||||
|
||||
|
||||
extern char const * prefs_get_smtp_username(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_username;
|
||||
}
|
||||
|
||||
static int conf_set_smtp_username(const char* valstr)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_username, valstr, NULL);
|
||||
}
|
||||
|
||||
static const char* conf_get_smtp_username(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_username;
|
||||
}
|
||||
|
||||
static int conf_setdef_smtp_username(void)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_username, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
extern char const * prefs_get_smtp_password(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_password;
|
||||
}
|
||||
|
||||
static int conf_set_smtp_password(const char* valstr)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_password, valstr, NULL);
|
||||
}
|
||||
|
||||
static const char* conf_get_smtp_password(void)
|
||||
{
|
||||
return prefs_runtime_config.smtp_password;
|
||||
}
|
||||
|
||||
static int conf_setdef_smtp_password(void)
|
||||
{
|
||||
return conf_set_str(&prefs_runtime_config.smtp_password, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Westwood Online Extensions
|
||||
|
|
|
@ -153,6 +153,7 @@ namespace pvpgn
|
|||
extern char const * prefs_get_command_groups_file(void);
|
||||
extern char const * prefs_get_tournament_file(void);
|
||||
extern char const * prefs_get_customicons_file(void);
|
||||
extern char const* prefs_get_email_verification_file(void);
|
||||
extern char const * prefs_get_scriptdir(void);
|
||||
extern char const * prefs_get_aliasfile(void);
|
||||
|
||||
|
@ -170,6 +171,10 @@ namespace pvpgn
|
|||
extern unsigned int prefs_get_passfail_count(void);
|
||||
extern unsigned int prefs_get_passfail_bantime(void);
|
||||
extern unsigned int prefs_get_maxusers_per_channel(void);
|
||||
extern unsigned int prefs_get_verify_account_email(void);
|
||||
extern void prefs_set_verify_account_email(bool enable);
|
||||
extern unsigned int prefs_get_verify_account_email_expiration(void);
|
||||
extern char const* prefs_get_verify_account_email_from_address(void);
|
||||
extern char const * prefs_get_supportfile(void);
|
||||
extern char const * prefs_get_allowed_clients(void);
|
||||
extern char const * prefs_get_ladder_games(void);
|
||||
|
@ -182,6 +187,14 @@ namespace pvpgn
|
|||
extern unsigned int prefs_get_log_commands(void);
|
||||
extern char const * prefs_get_log_command_groups(void);
|
||||
extern char const * prefs_get_log_command_list(void);
|
||||
extern char const * prefs_get_smtp_ca_cert_store(void);
|
||||
extern char const * prefs_get_smtp_ca_cert_store_remote_url(void);
|
||||
extern unsigned int prefs_get_smtp_ca_cert_store_fetch_interval(void);
|
||||
extern char const * prefs_get_smtp_server_url(void);
|
||||
extern unsigned int prefs_get_smtp_port(void);
|
||||
extern char const * prefs_get_smtp_username(void);
|
||||
extern char const * prefs_get_smtp_password(void);
|
||||
|
||||
|
||||
/**
|
||||
* Westwood Online Extensions
|
||||
|
|
|
@ -87,6 +87,8 @@
|
|||
#include "anongame_infos.h"
|
||||
#include "topic.h"
|
||||
#include "i18n.h"
|
||||
#include "smtp.h"
|
||||
#include "account_email_verification.h"
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
|
@ -1506,6 +1508,32 @@ namespace pvpgn
|
|||
}
|
||||
#endif
|
||||
|
||||
if (prefs_get_verify_account_email() == 1)
|
||||
{
|
||||
if (do_restart == restart_mode_all || do_restart == restart_mode_smtp)
|
||||
{
|
||||
smtp_cleanup();
|
||||
|
||||
if (!smtp_init(prefs_get_smtp_ca_cert_store(), prefs_get_smtp_server_url(), prefs_get_smtp_port(), prefs_get_smtp_username(), prefs_get_smtp_password()))
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to initialize SMTP client");
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Disabling account email verification");
|
||||
prefs_set_verify_account_email(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_restart == restart_mode_all || do_restart == restart_mode_accountemailverification)
|
||||
{
|
||||
account_email_verification_unload();
|
||||
if (!account_email_verification_load(prefs_get_email_verification_file(), prefs_get_servername(), prefs_get_verify_account_email_from_address()))
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to load email verification message");
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Disabling account email verification");
|
||||
prefs_set_verify_account_email(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eventlog(eventlog_level_info, __FUNCTION__, "done reconfiguring");
|
||||
|
||||
do_restart = 0;
|
||||
|
|
|
@ -92,7 +92,9 @@ namespace pvpgn
|
|||
restart_mode_tournament,
|
||||
restart_mode_icons,
|
||||
restart_mode_anongame,
|
||||
restart_mode_lua
|
||||
restart_mode_lua,
|
||||
restart_mode_smtp,
|
||||
restart_mode_accountemailverification
|
||||
};
|
||||
|
||||
extern unsigned int server_get_uptime(void);
|
||||
|
|
179
src/bnetd/smtp.cpp
Normal file
179
src/bnetd/smtp.cpp
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* 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; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "common/setup_before.h"
|
||||
#include "smtp.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
#include <curl.h>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/chrono.h>
|
||||
|
||||
#include "common/eventlog.h"
|
||||
|
||||
#include "server.h"
|
||||
|
||||
#include "common/setup_after.h"
|
||||
|
||||
namespace pvpgn
|
||||
{
|
||||
|
||||
namespace bnetd
|
||||
{
|
||||
|
||||
static bool is_curl_initialized = false;
|
||||
static std::string smtp_ca_cert_store;
|
||||
static char smtp_server_url[512] = {};
|
||||
static long smtp_port;
|
||||
static std::string smtp_username;
|
||||
static std::string smtp_password;
|
||||
|
||||
static int debug_callback(CURL* handle, curl_infotype type, char* data, size_t size, void* userptr)
|
||||
{
|
||||
char* info = (char*)std::malloc(size + 1);
|
||||
info[size] = '\0';
|
||||
std::memcpy(info, data, size);
|
||||
|
||||
|
||||
eventlog(eventlog_level_debug, __FUNCTION__, "DEBUG: {}", info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::size_t read_callback(char* buffer, std::size_t size, std::size_t nitems, void* message)
|
||||
{
|
||||
std::size_t buffer_size = size * nitems;
|
||||
std::size_t message_size = std::strlen(reinterpret_cast<const char*>(message)) + 1;
|
||||
|
||||
if (message_size <= buffer_size)
|
||||
{
|
||||
std::memcpy(buffer, message, message_size);
|
||||
eventlog(eventlog_level_trace, __FUNCTION__, "buffer: {}", buffer);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(buffer, message, buffer_size);
|
||||
return buffer_size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes libcurl's global context if it hasn't already been initialized.
|
||||
* Initializes smtp_server_url, smtp_port, smtp_username, and smtp_password from the four function parameters.
|
||||
*
|
||||
* On success, returns true.
|
||||
* On failure, returns false. Will fail if libcurl couldn't initialize global context or if prefs_smtp_port is greater than 65535.
|
||||
*/
|
||||
bool smtp_init(const char* prefs_smtp_ca_cert_store, const char* prefs_smtp_server_url, unsigned int prefs_smtp_port, const char* prefs_smtp_username, const char* prefs_smtp_password)
|
||||
{
|
||||
if (!is_curl_initialized)
|
||||
{
|
||||
if (curl_global_init(CURL_GLOBAL_NOTHING) != 0)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to initialize libcurl");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
eventlog(eventlog_level_debug, __FUNCTION__, "Succesfully initialized libcurl");
|
||||
is_curl_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
smtp_ca_cert_store = prefs_smtp_ca_cert_store;
|
||||
std::snprintf(smtp_server_url, sizeof(smtp_server_url), "smtps://%s", prefs_smtp_server_url);
|
||||
if (prefs_smtp_port > 65535)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Received out-of-range port number ({})", prefs_smtp_port);
|
||||
return false;
|
||||
}
|
||||
smtp_port = prefs_smtp_port;
|
||||
smtp_username = prefs_smtp_username;
|
||||
smtp_password = prefs_smtp_password;
|
||||
|
||||
eventlog(eventlog_level_info, __FUNCTION__, "Succesfully initialized SMTP client");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void smtp_cleanup()
|
||||
{
|
||||
if (is_curl_initialized)
|
||||
{
|
||||
curl_global_cleanup();
|
||||
is_curl_initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
void smtp_send_email(const std::string& to_address, const std::string& from_address, const std::string& subject, std::string message)
|
||||
{
|
||||
CURL* curl = curl_easy_init();
|
||||
if (curl == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to initialize CURL easy handle");
|
||||
return;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, smtp_ca_cert_store.c_str());
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, smtp_server_url);
|
||||
curl_easy_setopt(curl, CURLOPT_PORT, smtp_port);
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, smtp_username.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, smtp_password.c_str());
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, fmt::format("<{}>", from_address).c_str());
|
||||
struct curl_slist* recipient = nullptr;
|
||||
{
|
||||
struct curl_slist* recipient_temp = curl_slist_append(recipient, fmt::format("<{}>", to_address).c_str());
|
||||
if (recipient_temp == nullptr)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to append recipient address to recipient list");
|
||||
return;
|
||||
}
|
||||
|
||||
recipient = recipient_temp;
|
||||
}
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipient);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
// \r\nContent-Type: text/plain; charset=\"UTF-8\"
|
||||
message.insert(0, fmt::format("Date: {:%a, %d %b %Y %T %z}\r\nFrom: <{}>\r\nTo: <{}>\r\nSubject: {}\r\n\r\n", *std::localtime(&now), from_address, to_address, subject));
|
||||
message.append("\r\n.\r\n");
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, reinterpret_cast<void *>(const_cast<char*>(message.c_str())));
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debug_callback);
|
||||
|
||||
CURLcode result = curl_easy_perform(curl);
|
||||
if (result != CURLE_OK)
|
||||
{
|
||||
eventlog(eventlog_level_error, __FUNCTION__, "Failed to send email ({})", curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
curl_slist_free_all(recipient);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
31
src/bnetd/smtp.h
Normal file
31
src/bnetd/smtp.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace pvpgn
|
||||
{
|
||||
|
||||
namespace bnetd
|
||||
{
|
||||
|
||||
bool smtp_init(const char* prefs_smtp_ca_cert_store, const char* prefs_smtp_server_url, unsigned int prefs_smtp_port, const char* prefs_smtp_username, const char* prefs_smtp_password);
|
||||
void smtp_cleanup();
|
||||
void smtp_send_email(const std::string& to_address, const std::string& from_address, const std::string& subject, std::string message);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -158,6 +158,7 @@ const char * const BNETD_SUPPORT_FILE = "conf/supportfile.conf";
|
|||
const char * const BNETD_COMMAND_GROUPS_FILE = "conf/command_groups.conf";
|
||||
const char * const BNETD_TOURNAMENT_FILE = "conf/tournament.conf";
|
||||
const char * const BNETD_CUSTOMICONS_FILE = "conf/icons.conf";
|
||||
const char * const BNETD_EMAIL_VERIFICATION_FILE = "conf/email_verification.conf";
|
||||
const char * const BNETD_ALIASFILE = "conf/bnalias.conf";
|
||||
/* time limit for new member as newer(whom cannot be promoted) in clan, (hrs) */
|
||||
const unsigned CLAN_NEWER_TIME = 168;
|
||||
|
|
Loading…
Reference in a new issue