Boost log integration. (#37)

This commit is contained in:
Ravin Perera
2019-10-20 21:45:59 +05:30
committed by GitHub
parent 84f43b7549
commit 2d5d8960c0
13 changed files with 266 additions and 61 deletions

View File

@@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.2)
project(HPCore)
add_definitions("-std=c++17" "-fno-exceptions")
add_definitions("-std=c++17" "-DBOOST_LOG_DYN_LINK")
find_package(Boost REQUIRED COMPONENTS system log)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build)
@@ -13,6 +14,7 @@ add_executable(hpcore
src/util.cpp
src/crypto.cpp
src/conf.cpp
src/hplog.cpp
src/proc.cpp
src/usr/user_session_handler.cpp
src/usr/usr.cpp
@@ -29,7 +31,8 @@ set_target_properties(release PROPERTIES EXCLUDE_FROM_ALL TRUE)
target_link_libraries(hpcore
libsodium.a
libboost_system.a
${Boost_SYSTEM_LIBRARY}
${Boost_LOG_LIBRARY}
stdc++fs
pthread
protobuf.a

View File

@@ -1,6 +1,7 @@
#include <cstdio>
#include <iostream>
#include <fstream>
#include <unordered_set>
#include <experimental/filesystem>
#include <sodium.h>
#include <rapidjson/document.h>
@@ -69,7 +70,7 @@ int create_contract()
{
if (std::experimental::filesystem::exists(ctx.contractDir))
{
std::cerr << "Contract dir already exists. Cannot create contract at the same location.\n";
std::cout << "Contract dir already exists. Cannot create contract at the same location.\n";
return -1;
}
@@ -92,6 +93,13 @@ int create_contract()
cfg.pubmaxsize = 65536;
cfg.pubmaxcpm = 100;
#ifndef NDEBUG
cfg.loglevel = "debug";
#else
cfg.loglevel = "warn";
#endif
cfg.loggers.emplace("console");
//Save the default settings into the config file.
if (save_config() != 0)
return -1;
@@ -132,12 +140,12 @@ int load_config()
rapidjson::Document d;
if (d.ParseStream(isw).HasParseError())
{
std::cerr << "Invalid config file format. Parser error at position " << d.GetErrorOffset() << std::endl;
std::cout << "Invalid config file format. Parser error at position " << d.GetErrorOffset() << std::endl;
return -1;
}
else if (is_schema_valid(d) != 0)
{
std::cerr << "Invalid config file format.\n";
std::cout << "Invalid config file format.\n";
return -1;
}
ifs.close();
@@ -146,7 +154,7 @@ int load_config()
std::string_view cfgversion = util::getsv(d["version"]);
if (cfgversion.empty())
{
std::cerr << "Contract config version missing.\n";
std::cout << "Contract config version missing.\n";
return -1;
}
@@ -154,14 +162,14 @@ int load_config()
int verresult = util::version_compare(std::string(cfgversion), std::string(util::MIN_CONTRACT_VERSION));
if (verresult == -1)
{
std::cerr << "Contract version too old. Minimum "
std::cout << "Contract version too old. Minimum "
<< util::MIN_CONTRACT_VERSION << " required. "
<< cfgversion << " found.\n";
return -1;
}
else if (verresult == -2)
{
std::cerr << "Malformed version string.\n";
std::cout << "Malformed version string.\n";
return -1;
}
@@ -187,6 +195,11 @@ int load_config()
cfg.pubmaxsize = d["pubmaxsize"].GetInt();
cfg.pubmaxcpm = d["pubmaxcpm"].GetInt();
cfg.loglevel = d["loglevel"].GetString();
cfg.loggers.clear();
for (auto &v : d["loggers"].GetArray())
cfg.loggers.emplace(v.GetString());
// Convert the hex keys to binary and keep for later use.
if (hexpair_to_bin() != 0)
return -1;
@@ -237,6 +250,16 @@ int save_config()
d.AddMember("pubmaxsize", cfg.pubmaxsize, allocator);
d.AddMember("pubmaxcpm", cfg.pubmaxcpm, allocator);
d.AddMember("loglevel", rapidjson::StringRef(cfg.loglevel.data()), allocator);
rapidjson::Value loggers(rapidjson::kArrayType);
for (const std::string &logger : cfg.loggers)
{
rapidjson::Value v;
v.SetString(rapidjson::StringRef(logger.data()), allocator);
loggers.PushBack(v, allocator);
}
d.AddMember("loggers", loggers, allocator);
// Write the json doc to file.
std::ofstream ofs(ctx.configFile);
@@ -245,7 +268,7 @@ int save_config()
rapidjson::PrettyWriter<rapidjson::OStreamWrapper> writer(osw);
if (!d.Accept(writer))
{
std::cerr << "Writing to config file failed. " << ctx.configFile << std::endl;
std::cout << "Writing to config file failed. " << ctx.configFile << std::endl;
return -1;
}
ofs.close();
@@ -265,7 +288,7 @@ int binpair_to_hex()
reinterpret_cast<const unsigned char *>(cfg.pubkey.data()),
cfg.pubkey.length()) != 0)
{
std::cerr << "Error encoding public key bytes.\n";
std::cout << "Error encoding public key bytes.\n";
return -1;
}
@@ -274,7 +297,7 @@ int binpair_to_hex()
reinterpret_cast<const unsigned char *>(cfg.seckey.data()),
cfg.seckey.length()) != 0)
{
std::cerr << "Error encoding secret key bytes.\n";
std::cout << "Error encoding secret key bytes.\n";
return -1;
}
@@ -294,7 +317,7 @@ int hexpair_to_bin()
cfg.pubkey.length(),
cfg.pubkeyhex) != 0)
{
std::cerr << "Error decoding hex public key.\n";
std::cout << "Error decoding hex public key.\n";
return -1;
}
@@ -304,10 +327,10 @@ int hexpair_to_bin()
cfg.seckey.length(),
cfg.seckeyhex) != 0)
{
std::cerr << "Error decoding hex secret key.\n";
std::cout << "Error decoding hex secret key.\n";
return -1;
}
return 0;
}
@@ -322,22 +345,41 @@ int validate_config()
// We also check for key pair validity as well in the below code.
if (cfg.pubkeyhex.empty() || cfg.seckeyhex.empty())
{
std::cerr << "Signing keys missing. Run with 'rekey' to generate new keys.\n";
std::cout << "Signing keys missing. Run with 'rekey' to generate new keys.\n";
return -1;
}
// Other required fields.
if (cfg.binary.empty() || cfg.listenip.empty() ||
cfg.peerport == 0 || cfg.roundtime == 0 || cfg.pubport == 0 || cfg.pubmaxsize == 0 || cfg.pubmaxcpm == 0)
cfg.peerport == 0 || cfg.roundtime == 0 || cfg.pubport == 0 || cfg.pubmaxsize == 0 || cfg.pubmaxcpm == 0 ||
cfg.loglevel.empty() || cfg.loggers.empty())
{
std::cerr << "Required configuration fields missing at " << ctx.configFile << std::endl;
std::cout << "Required configuration fields missing at " << ctx.configFile << std::endl;
return -1;
}
// Log settings
const std::unordered_set<std::string> valid_loglevels({"debug", "info", "warn", "error"});
if (valid_loglevels.count(cfg.loglevel) != 1)
{
std::cout << "Invalid loglevel configured. Valid values: debug|info|warn|error\n";
return -1;
}
const std::unordered_set<std::string> valid_loggers({"console", "file"});
for (const std::string &logger : cfg.loggers)
{
if (valid_loggers.count(logger) != 1)
{
std::cout << "Invalid logger. Valid values: console|file\n";
return -1;
}
}
// Check whether the contract binary actually exists.
if (!std::experimental::filesystem::exists(cfg.binary))
{
std::cerr << "Contract binary does not exist: " << cfg.binary << std::endl;
std::cout << "Contract binary does not exist: " << cfg.binary << std::endl;
return -1;
}
@@ -346,7 +388,7 @@ int validate_config()
std::string sighex = crypto::sign_hex(msg, cfg.seckeyhex);
if (crypto::verify_hex(msg, sighex, cfg.pubkeyhex) != 0)
{
std::cerr << "Invalid signing keys. Run with 'rekey' to generate new keys.\n";
std::cout << "Invalid signing keys. Run with 'rekey' to generate new keys.\n";
return -1;
}
@@ -366,7 +408,7 @@ int validate_contract_dir_paths()
{
if (!std::experimental::filesystem::exists(dir))
{
std::cerr << dir << " does not exist.\n";
std::cout << dir << " does not exist.\n";
return -1;
}
}
@@ -385,7 +427,8 @@ int is_schema_valid(rapidjson::Document &d)
"{"
"\"type\": \"object\","
"\"required\": [ \"version\", \"pubkeyhex\", \"seckeyhex\", \"binary\", \"binargs\", \"listenip\""
", \"peers\", \"unl\", \"peerport\", \"roundtime\", \"pubport\", \"pubmaxsize\", \"pubmaxcpm\" ],"
", \"peers\", \"unl\", \"peerport\", \"roundtime\", \"pubport\", \"pubmaxsize\", \"pubmaxcpm\""
", \"loglevel\", \"loggers\" ],"
"\"properties\": {"
"\"version\": { \"type\": \"string\" },"
"\"pubkeyhex\": { \"type\": \"string\" },"
@@ -405,7 +448,12 @@ int is_schema_valid(rapidjson::Document &d)
"\"roundtime\": { \"type\": \"integer\" },"
"\"pubport\": { \"type\": \"integer\" },"
"\"pubmaxsize\": { \"type\": \"integer\" },"
"\"pubmaxcpm\": { \"type\": \"integer\" }"
"\"pubmaxcpm\": { \"type\": \"integer\" },"
"\"loglevel\": { \"type\": \"string\" },"
"\"loggers\": {"
"\"type\": \"array\","
"\"items\": { \"type\": \"string\" }"
"},"
"}"
"}";

View File

@@ -3,6 +3,7 @@
#include <rapidjson/document.h>
#include <vector>
#include <unordered_set>
/**
* Manages the central contract config and context structs.
@@ -45,6 +46,8 @@ struct contract_config
unsigned short pubport; // Listening port for public user connections
int pubmaxsize; // User message max size in bytes
int pubmaxcpm; // User message rate
std::string loglevel; // Log severity level (debug, info, warn, error)
std::unordered_set<std::string> loggers; // List of enabled loggers (console, file)
};
// Global contract context struct exposed to the application.

View File

@@ -14,7 +14,7 @@ int init()
{
if (sodium_init() < 0)
{
std::cerr << "sodium_init failed.\n";
std::cout << "sodium_init failed.\n";
return -1;
}

76
src/hplog.cpp Normal file
View File

@@ -0,0 +1,76 @@
#include <iostream>
#include <string>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/expressions/keyword_fwd.hpp>
#include <boost/log/expressions/keyword.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/utility/manipulators/to_log.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/support/date_time.hpp>
#include "conf.hpp"
#include "hplog.hpp"
namespace logging = boost::log;
namespace sinks = boost::log::sinks;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace attrs = boost::log::attributes;
namespace keywords = boost::log::keywords;
namespace hplog
{
/**
* Stream operator overload for converting integer severity vaue to text.
*/
std::ostream &operator<<(std::ostream &os, LOG_SEVERITY level)
{
static std::string_view loglevels[] = {"dbg", "info", "warn", "err"};
os << loglevels[level];
return os;
}
// Severity attribute value tag type
struct severity_tag;
void init()
{
// Set log severity level based on contract config.
LOG_SEVERITY severity = LOG_SEVERITY::WARN;
if (conf::cfg.loglevel == "debug")
severity = LOG_SEVERITY::DEBUG;
else if (conf::cfg.loglevel == "info")
severity = LOG_SEVERITY::INFO;
else if (conf::cfg.loglevel == "warn")
severity = LOG_SEVERITY::WARN;
else if (conf::cfg.loglevel == "error")
severity = LOG_SEVERITY::ERROR;
if (conf::cfg.loggers.count("console") == 1)
{
logging::add_console_log(
std::clog,
keywords::filter = (a_severity >= severity),
keywords::format =
(expr::stream
<< expr::format_date_time<boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d %H:%M:%S")
//<< ":" << expr::attr<boost::log::attributes::current_thread_id::value_type>("ThreadID")
<< " [" << expr::attr<std::string>("Channel")
<< "] [" << expr::attr<LOG_SEVERITY, severity_tag>("Severity")
<< "] " << expr::smessage));
}
if (conf::cfg.loggers.count("file") == 1)
{
// TODO: Add file logger.
}
// Add Boost Log built-in fields for log entries.
logging::add_common_attributes();
}
} // namespace hplog

59
src/hplog.hpp Normal file
View File

@@ -0,0 +1,59 @@
#ifndef _HP_HPLOG_H_
#define _HP_HPLOG_H_
#include <iostream>
#include <string>
#include <boost/log/core.hpp>
#include <boost/log/expressions/keyword.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include "conf.hpp"
namespace src = boost::log::sources;
namespace keywords = boost::log::keywords;
namespace hplog
{
// Log severity levels used in Hot Pocket.
enum LOG_SEVERITY
{
DEBUG,
INFO,
WARN,
ERROR
};
BOOST_LOG_ATTRIBUTE_KEYWORD(a_severity, "Severity", hplog::LOG_SEVERITY);
void init();
} // namespace hplog
// Thread-safe global logger type using custom LOG_SEVERITY enum..
typedef src::severity_channel_logger_mt<hplog::LOG_SEVERITY, std::string> logger;
// hplogger is the log source for Hot Pocket generated logs.
BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(hplogger, logger)
{
return logger(keywords::channel = "hp");
}
// sclogger is the log source for logging captured stdour/stderr from smart contract.
BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(sclogger, logger)
{
return logger(keywords::channel = "sc");
}
// HP logging macros.
#define LOG_DBG BOOST_LOG_SEV(hplogger::get(), hplog::LOG_SEVERITY::DEBUG)
#define LOG_INFO BOOST_LOG_SEV(hplogger::get(), hplog::LOG_SEVERITY::INFO)
#define LOG_WARN BOOST_LOG_SEV(hplogger::get(), hplog::LOG_SEVERITY::WARN)
#define LOG_ERR BOOST_LOG_SEV(hplogger::get(), hplog::LOG_SEVERITY::ERROR)
// SC stdout/err logging macros.
#define LOG_INFO_SC BOOST_LOG_SEV(sclogger::get(), hplog::LOG_SEVERITY::INFO)
#define LOG_ERR_SC BOOST_LOG_SEV(sclogger::get(), hplog::LOG_SEVERITY::ERROR)
#endif

View File

@@ -14,6 +14,7 @@
#include "crypto.hpp"
#include "usr/usr.hpp"
#include "proc.hpp"
#include "hplog.hpp"
/**
* Parses CLI args and extracts hot pocket command and parameters given.
@@ -64,7 +65,7 @@ int parse_cmd(int argc, char **argv)
int main(int argc, char **argv)
{
// Extract the CLI args
// After this call conf::ctx must be populated.
// This call will populate conf::ctx
if (parse_cmd(argc, argv) != 0)
return -1;
@@ -100,7 +101,13 @@ int main(int argc, char **argv)
else if (conf::ctx.command == "run")
{
// In order to host the contract we should init some required sub systems.
if (conf::init() != 0 || usr::init() != 0)
if (conf::init() != 0)
return -1;
hplog::init();
if (usr::init() != 0)
return -1;
// This will start hosting the contract and start consensus rounds.
@@ -143,7 +150,7 @@ int main(int argc, char **argv)
}
if (!hpscbufpair.second.empty())
std::cout << "Message from SC: " << hpscbufpair.second << std::endl;
LOG_DBG << "Message from SC: " << hpscbufpair.second;
userbufs.clear();
}
@@ -153,7 +160,8 @@ int main(int argc, char **argv)
}
}
}
std::cout << "exited normally\n";
LOG_INFO << "exited normally";
return 0;
}
@@ -162,6 +170,6 @@ int main(int argc, char **argv)
*/
void boost::throw_exception(std::exception const &e)
{
std::cerr << "Boost error:" << e.what() << std::endl;
LOG_ERR << "Boost error:" << e.what();
exit(-1);
}

View File

@@ -11,6 +11,7 @@
#include <sys/wait.h>
#include "proc.hpp"
#include "conf.hpp"
#include "hplog.hpp"
namespace proc
{
@@ -47,7 +48,7 @@ int exec_contract(const ContractExecArgs &args)
// Write any hp input messages to hp->sc pipe.
if (write_contract_hp_inputs(args) != 0)
{
std::cerr << "Failed to write HP input to contract.\n";
LOG_ERR << "Failed to write HP input to contract.";
return -1;
}
@@ -55,7 +56,7 @@ int exec_contract(const ContractExecArgs &args)
if (write_contract_user_inputs(args) != 0)
{
cleanup_userfds();
std::cerr << "Failed to write user inputs to contract.\n";
LOG_ERR << "Failed to write user inputs to contract.";
return -1;
}
@@ -70,11 +71,14 @@ int exec_contract(const ContractExecArgs &args)
// Wait for child process (contract process) to complete execution.
LOG_INFO << "Contract process started.";
int presult = await_contract_execution();
LOG_INFO << "Contract process ended.";
contract_pid = 0;
if (presult != 0)
{
std::cerr << "Contract process exited with non-normal status code: " << presult << std::endl;
LOG_ERR << "Contract process exited with non-normal status code: " << presult;
return -1;
}
@@ -107,7 +111,7 @@ int exec_contract(const ContractExecArgs &args)
}
else
{
std::cerr << "fork() failed.\n";
LOG_ERR << "fork() failed.";
return -1;
}
@@ -195,7 +199,7 @@ int write_contract_args(const ContractExecArgs &args)
int stdinpipe[2];
if (pipe(stdinpipe) != 0)
{
std::cerr << "Failed to create pipe to the contract process.\n";
LOG_ERR << "Failed to create pipe to the contract process.";
return -1;
}
@@ -207,7 +211,7 @@ int write_contract_args(const ContractExecArgs &args)
// Write the json message and close write fd.
if (write(stdinpipe[1], json.data(), json.size()) == -1)
{
std::cerr << "Failed to write to stdin of contract process.\n";
LOG_ERR << "Failed to write to stdin of contract process.";
return -1;
}
close(stdinpipe[1]);
@@ -222,8 +226,8 @@ int write_contract_hp_inputs(const ContractExecArgs &args)
{
if (create_and_write_iopipes(hpscfds, args.hpscbufs.first) != 0) // hpscbufs.first is the input buffer.
{
std::cerr << "Error writing HP input to SC (" << args.hpscbufs.first.length()
<< " bytes)" << std::endl;
LOG_ERR << "Error writing HP input to SC (" << args.hpscbufs.first.length()
<< " bytes)";
return -1;
}
return 0;
@@ -243,8 +247,8 @@ int write_contract_user_inputs(const ContractExecArgs &args)
if (create_and_write_iopipes(fds, bufpair.first) != 0) // bufpair.first is the input buffer.
{
std::cerr << "Error writing contract input (" << bufpair.first.length()
<< " bytes) from user" << std::endl;
LOG_ERR << "Error writing contract input (" << bufpair.first.length()
<< " bytes) from user";
return -1;
}
}
@@ -266,7 +270,7 @@ int read_contract_hp_outputs(const ContractExecArgs &args)
if (read_iopipe(hpscfds, args.hpscbufs.second) != 0) // hpscbufs.second is the output buffer.
{
std::cerr << "Error reading HP output";
LOG_ERR << "Error reading HP output";
return -1;
}
return 0;
@@ -291,8 +295,8 @@ int read_contract_user_outputs(const ContractExecArgs &args)
if (read_iopipe(fds, bufpair.second) != 0) // bufpair.second is the output buffer.
{
std::cerr << "Error reading contract output for user "
<< pubkey << std::endl;
LOG_ERR << "Error reading contract output for user "
<< pubkey;
}
}

View File

@@ -1,5 +1,6 @@
#include <iostream>
#include "socket_client.hpp"
#include "../hplog.hpp"
using tcp = net::ip::tcp;
using error = boost::system::error_code;
@@ -86,7 +87,7 @@ void socket_client::on_handshake(error ec)
*/
void socket_client::socket_client_fail(beast::error_code ec, char const *what)
{
std::cerr << what << ": " << ec.message() << "\n";
LOG_ERR << what << ": " << ec.message();
}
} // namespace sock

View File

@@ -5,6 +5,7 @@
#include <boost/beast/websocket.hpp>
#include <boost/asio/strand.hpp>
#include "socket_server.hpp"
#include "../hplog.hpp"
namespace net = boost::asio; // namespace asio
@@ -75,7 +76,7 @@ void socket_server::fail(error_code ec, char const *what)
// Don't report on canceled operations
if (ec == net::error::operation_aborted)
return;
std::cerr << what << ": " << ec.message() << "\n";
LOG_ERR << what << ": " << ec.message();
}
/**

View File

@@ -54,7 +54,7 @@ void socket_session::client_run(const std::string &&address, const std::string &
*/
void socket_session::fail(error_code ec, char const *what)
{
// std::cerr << what << ": " << ec.message() << std::endl;
// LOG_ERR << what << ": " << ec.message();
// Don't report these
if (ec == net::error::operation_aborted ||

View File

@@ -6,6 +6,7 @@
#include "../util.hpp"
#include "../sock/socket_session.hpp"
#include "../proc.hpp"
#include "../hplog.hpp"
#include "usr.hpp"
#include "user_session_handler.hpp"
@@ -23,7 +24,7 @@ namespace usr
*/
void user_session_handler::on_connect(sock::socket_session *session)
{
std::cout << "User client connected " << session->address_ << ":" << session->port_ << std::endl;
LOG_INFO << "User client connected " << session->address_ << ":" << session->port_;
// As soon as a user connects, we issue them a challenge message. We remember the
// challenge we issued and later verifies the user's response with it.
@@ -83,18 +84,18 @@ void user_session_handler::on_message(sock::socket_session *session, std::string
usr::add_user(session, userpubkey); // Add the user to the global authed user list
usr::pending_challenges.erase(session->uniqueid_); // Remove the stored challenge
std::cout << "User connection " << session->uniqueid_ << " authenticated. Public key "
<< userpubkeyhex << std::endl;
LOG_INFO << "User connection " << session->uniqueid_ << " authenticated. Public key "
<< userpubkeyhex;
return;
}
else
{
std::cout << "Duplicate user public key " << session->uniqueid_ << std::endl;
LOG_INFO << "Duplicate user public key " << session->uniqueid_;
}
}
else
{
std::cout << "Challenge verification failed " << session->uniqueid_ << std::endl;
LOG_INFO << "Challenge verification failed " << session->uniqueid_;
}
}
}
@@ -113,14 +114,14 @@ void user_session_handler::on_message(sock::socket_session *session, std::string
//Append the bytes into connected user input buffer.
user.inbuffer.append(message);
std::cout << "Collected " << user.inbuffer.length() << " bytes from user" << std::endl;
LOG_DBG << "Collected " << user.inbuffer.length() << " bytes from user";
return;
}
}
// If for any reason we reach this point, we should drop the connection.
session->close();
std::cout << "Dropped the user connection " << session->address_ << ":" << session->port_ << std::endl;
LOG_INFO << "Dropped the user connection " << session->address_ << ":" << session->port_;
}
/**
@@ -143,7 +144,7 @@ void user_session_handler::on_close(sock::socket_session *session)
usr::remove_user(session->uniqueid_);
}
std::cout << "User disconnected " << session->uniqueid_ << std::endl;
LOG_INFO << "User disconnected " << session->uniqueid_;
}
} // namespace usr

View File

@@ -9,6 +9,7 @@
#include "../util.hpp"
#include "../conf.hpp"
#include "../crypto.hpp"
#include "../hplog.hpp"
#include "usr.hpp"
#include "user_session_handler.hpp"
@@ -145,35 +146,35 @@ int verify_user_challenge_response(std::string &extracted_pubkeyhex, std::string
d.Parse(response.data());
if (d.HasParseError())
{
std::cerr << "Challenge response json parser error.\n";
LOG_INFO << "Challenge response json parsing failed.";
return -1;
}
// Validate msg type.
if (!d.HasMember(CHALLENGE_RESP_TYPE) || d[CHALLENGE_RESP_TYPE] != CHALLENGE_RESP_MSGTYPE)
{
std::cerr << "User challenge response type invalid. 'challenge_response' expected.\n";
LOG_INFO << "User challenge response type invalid. 'challenge_response' expected.";
return -1;
}
// Compare the response challenge string with the original issued challenge.
if (!d.HasMember(CHALLENGE_RESP_CHALLENGE) || d[CHALLENGE_RESP_CHALLENGE] != original_challenge.data())
{
std::cerr << "User challenge response challenge invalid.\n";
LOG_INFO << "User challenge response challenge invalid.";
return -1;
}
// Check for the 'sig' field existence.
if (!d.HasMember(CHALLENGE_RESP_SIG) || !d[CHALLENGE_RESP_SIG].IsString())
{
std::cerr << "User challenge response signature invalid.\n";
LOG_INFO << "User challenge response signature invalid.";
return -1;
}
// Check for the 'pubkey' field existence.
if (!d.HasMember(CHALLENGE_RESP_PUBKEY) || !d[CHALLENGE_RESP_PUBKEY].IsString())
{
std::cerr << "User challenge response public key invalid.\n";
LOG_INFO << "User challenge response public key invalid.";
return -1;
}
@@ -184,7 +185,7 @@ int verify_user_challenge_response(std::string &extracted_pubkeyhex, std::string
util::getsv(d[CHALLENGE_RESP_SIG]),
pubkeysv) != 0)
{
std::cerr << "User challenge response signature verification failed.\n";
LOG_INFO << "User challenge response signature verification failed.";
return -1;
}
@@ -206,7 +207,7 @@ int add_user(sock::socket_session *session, const std::string &pubkey)
const std::string &sessionid = session->uniqueid_;
if (users.count(sessionid) == 1)
{
std::cerr << sessionid << " already exist. Cannot add user.\n";
LOG_INFO << sessionid << " already exist. Cannot add user.";
return -1;
}
@@ -231,7 +232,7 @@ int remove_user(const std::string &sessionid)
if (itr == users.end())
{
std::cerr << sessionid << " does not exist. Cannot remove user.\n";
LOG_INFO << sessionid << " does not exist. Cannot remove user.";
return -1;
}
@@ -256,7 +257,7 @@ void start_listening()
listener_thread = std::thread([&] { ioc.run(); });
std::cout << "Started listening for incoming user connections...\n";
LOG_INFO << "Started listening for incoming user connections...";
}
/**