diff options
| author | auth <[email protected]> | 2020-07-13 23:05:20 +0200 |
|---|---|---|
| committer | auth <[email protected]> | 2020-07-13 23:05:20 +0200 |
| commit | e177151308cbdfb2b96119389cf5bf7c2659b94e (patch) | |
| tree | 7e5737aca17322bf3d39ee5643b3ae2d5deea8f3 /server/src | |
| parent | Small changes. (diff) | |
| download | loader-e177151308cbdfb2b96119389cf5bf7c2659b94e.tar.xz loader-e177151308cbdfb2b96119389cf5bf7c2659b94e.zip | |
Forum integration.
Added separate packet ids for login request/response.
Added login responses.
Small code changes.
Diffstat (limited to 'server/src')
| -rw-r--r-- | server/src/client/blacklist.h | 100 | ||||
| -rw-r--r-- | server/src/client/client.h | 14 | ||||
| -rw-r--r-- | server/src/forum/forum.cpp | 47 | ||||
| -rw-r--r-- | server/src/forum/forum.h | 24 | ||||
| -rw-r--r-- | server/src/main.cpp | 57 | ||||
| -rw-r--r-- | server/src/server/packet.h | 4 | ||||
| -rw-r--r-- | server/src/server/server.h | 5 |
7 files changed, 194 insertions, 57 deletions
diff --git a/server/src/client/blacklist.h b/server/src/client/blacklist.h index 397dc6c..70f5c7a 100644 --- a/server/src/client/blacklist.h +++ b/server/src/client/blacklist.h @@ -1,60 +1,54 @@ #pragma once -namespace tcp { - struct blacklist_data { - std::string ip; - std::string hwid; + std::string ip; + std::string hwid; }; class blacklist { - -nlohmann::json m_data; -std::string m_name; - -public: - void init(const std::string_view file = "blacklist") { - m_name = file; - - std::string data; - if(!io::read_file(file, data)) - return; - - if(!nlohmann::json::accept(data)) { - io::logger->error("blacklist file isnt valid json."); - return; - } - - m_data = nlohmann::json::parse(data); - } - - void add(const blacklist_data &data) { - m_data["ips"].emplace_back(data.ip); - m_data["hwids"].emplace_back(data.hwid); - - save(); - } - - void save() { - std::ofstream o(m_name, std::ios::trunc); - o << std::setw(4) << m_data; - o.close(); - } - - bool find(const std::string &key) { - for(auto &item : m_data["ips"]) { - if(item.get<std::string>() == key) { - return true; - } - } - - for(auto &item : m_data["hwids"]) { - if(item.get<std::string>() == key) { - return true; - } - } - return false; - } + nlohmann::json m_data; + std::string m_name; + + public: + void init(const std::string_view file = "blacklist") { + m_name = file; + + std::string data; + if (!io::read_file(file, data)) return; + + if (!nlohmann::json::accept(data)) { + io::logger->error("blacklist file isnt valid json."); + return; + } + + m_data = nlohmann::json::parse(data); + } + + void add(const blacklist_data &data) { + m_data["ips"].emplace_back(data.ip); + m_data["hwids"].emplace_back(data.hwid); + + save(); + } + + void save() { + std::ofstream o(m_name, std::ios::trunc); + o << std::setw(4) << m_data; + o.close(); + } + + bool find(const std::string &key) { + for (auto &item : m_data["ips"]) { + if (item.get<std::string>() == key) { + return true; + } + } + + for (auto &item : m_data["hwids"]) { + if (item.get<std::string>() == key) { + return true; + } + } + return false; + } }; - -};
\ No newline at end of file diff --git a/server/src/client/client.h b/server/src/client/client.h index a3d558d..2777a0d 100644 --- a/server/src/client/client.h +++ b/server/src/client/client.h @@ -3,6 +3,17 @@ namespace tcp { +enum client_state { + idle = 0, logged_in, waiting, injected +}; + +enum login_result { + login_fail = 15494, + hwid_mismatch = 11006, + login_success = 61539, + banned = 28618 +}; + class client { int m_socket; SSL* m_ssl; @@ -14,10 +25,11 @@ class client { public: std::string hwid; + int state; client() : m_socket{-1} {}; client(const int& socket, const std::string_view ip) - : m_socket{std::move(socket)}, m_ip{ip}, m_ssl{nullptr} {} + : m_socket{std::move(socket)}, m_ip{ip}, m_ssl{nullptr}, state{-1} {} ~client() = default; bool init_ssl(SSL_CTX* server_ctx); diff --git a/server/src/forum/forum.cpp b/server/src/forum/forum.cpp new file mode 100644 index 0000000..57eff72 --- /dev/null +++ b/server/src/forum/forum.cpp @@ -0,0 +1,47 @@ +#include "../include.h" +#include "../util/io.h" +#include "forum.h" + +void xenforo_forum::init(const std::string_view link, const std::string_view key) { + m_link = link; + m_api = key; + + m_header = cpr::Header{{"Content-Type", "application/x-www-form-urlencoded"}, + {"XF-Api-Key", m_api.data()}, + {"XF-Api-User", "1"}, + {"api_bypass_permissions", "1"}}; +} + +int xenforo_forum::check_login(const std::string_view username, + const std::string_view password, user_data &data) { + auto url = fmt::format("{}{}", m_link, "/auth/"); + auto post_data = fmt::format("login={}&password={}", username, password); + + auto req = cpr::Post(cpr::Url{url}, cpr::Body{post_data}, cpr::Timeout{10000}, + m_header); + + if (req.elapsed >= 10) { + io::logger->warn("login request on {} timed out.", username); + return forum_response::api_timeout; + } + + int status_code = req.status_code; + auto response = req.text; + + if (!nlohmann::json::accept(response)) { + io::logger->error("login response on {} isnt valid json.", username); + return forum_response::api_fail; + } + + if (status_code >= 400) { + return forum_response::api_error; + } + + auto j = nlohmann::json::parse(response); + + data.banned = j["user"]["is_banned"].get<bool>(); + // data.active = check user group + data.hwid = j["user"]["custom_fields"]["hwid"].get<std::string>(); + + return forum_response::api_success; +}
\ No newline at end of file diff --git a/server/src/forum/forum.h b/server/src/forum/forum.h new file mode 100644 index 0000000..df18cb4 --- /dev/null +++ b/server/src/forum/forum.h @@ -0,0 +1,24 @@ +#pragma once +#include <cpr/cpr.h> +#include <json.hpp> +// XenForo forum api wrapper + +struct user_data { + std::string hwid; + bool banned; + bool active; +}; + +enum forum_response { api_fail = 0, api_error, api_timeout, api_success }; + +class xenforo_forum { + std::string m_link; + std::string m_api; + + cpr::Header m_header; + + public: + void init(const std::string_view link, const std::string_view key); + int check_login(const std::string_view username, + const std::string_view password, user_data &data); +};
\ No newline at end of file diff --git a/server/src/main.cpp b/server/src/main.cpp index 779b610..0947b75 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -21,6 +21,8 @@ int main(int argc, char* argv[]) { client.gen_session(); client.write(tcp::packet_t(version, tcp::packet_type::write, client(), tcp::packet_id::session)); + + client.state = tcp::client_state::idle; }); client_server.disconnect_event.add([&](tcp::client& client) { @@ -76,6 +78,61 @@ int main(int argc, char* argv[]) { } } + if (id == tcp::packet_id::login_req) { + if (client.state != tcp::client_state::idle) { + return; + } + + auto pos = message.find(","); + if (pos != std::string::npos) { + auto user = message.substr(0, pos); + auto pass = message.substr(pos + 1); + + user_data data{}; + //int ret = client_server.forum().check_login(user, pass, data); + int ret = forum_response::api_success; + if (ret == forum_response::api_success) { + + nlohmann::json j; + + if (data.banned) { + io::logger->warn("{} is forum banned, dropping...", user); + + j["result"] = tcp::login_result::banned; + + client.write(tcp::packet_t(j.dump(), tcp::packet_type::write, + session, tcp::packet_id::login_resp)); + + client_server.disconnect_event.call(client); + return; + } + // new user/no hwid, register the hwid on the forums + if (data.hwid.empty()) { + data.hwid = client.hwid; + } + + // invalid hwid + if (data.hwid != client.hwid) { + + j["result"] = tcp::login_result::hwid_mismatch; + + client.write(tcp::packet_t(j.dump(), tcp::packet_type::write, + session, tcp::packet_id::login_resp)); + + client_server.disconnect_event.call(client); + return; + } + + j["result"] = tcp::login_result::banned; + + client.write(tcp::packet_t(j.dump(), tcp::packet_type::write, + session, tcp::packet_id::login_resp)); + + client.state = tcp::client_state::logged_in; + } + } + } + client.write(tcp::packet_t(message, tcp::packet_type::write, session)); }); diff --git a/server/src/server/packet.h b/server/src/server/packet.h index 261109d..c0aab12 100644 --- a/server/src/server/packet.h +++ b/server/src/server/packet.h @@ -7,9 +7,9 @@ namespace tcp { constexpr size_t session_id_len = 10; constexpr size_t message_len = 512; -enum packet_type : int { write = 0, read }; +enum packet_type { write = 0, read }; -enum packet_id : int { message = 0, hwid, session }; +enum packet_id { message = 0, hwid, session, login_req, login_resp, process_list }; struct packet_t { std::string message; diff --git a/server/src/server/server.h b/server/src/server/server.h index ede0683..7fa5dc4 100644 --- a/server/src/server/server.h +++ b/server/src/server/server.h @@ -2,12 +2,13 @@ #include "../client/client.h" #include "../util/events.h" #include "../client/blacklist.h" +#include "../forum/forum.h" #include "ssl.h" namespace tcp { constexpr uint8_t server_version = 0; -enum select_status : int { error = 0, standby, ready }; +enum select_status { error = 0, standby, ready }; class server { int m_socket; @@ -21,6 +22,7 @@ class server { std::vector<tcp::client> client_stack; blacklist m_blacklist; + xenforo_forum m_forum; public: event<client&> connect_event; event<packet_t&, client&> receive_event; @@ -41,6 +43,7 @@ class server { auto &operator()() { return client_stack; } auto &bl() { return m_blacklist; } + auto &forum() { return m_forum; } static void monitor(server& srv) { while (srv) { |