mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Code consistency improvements (#21)
Fully-qualified namespace accessors Updated function out param order reinterpret_cast
This commit is contained in:
@@ -6,17 +6,17 @@ add_definitions("-std=c++17")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build)
|
||||
|
||||
add_executable(hpcore
|
||||
src/main.cpp
|
||||
src/conf.cpp
|
||||
src/crypto.cpp
|
||||
src/proc.cpp
|
||||
src/usr/usr.cpp
|
||||
src/usr/user_session_handler.cpp
|
||||
src/util.cpp
|
||||
src/p2p/message.pb.cc
|
||||
src/sock/socket_client.cpp
|
||||
src/sock/socket_server.cpp
|
||||
src/sock/socket_session.cpp
|
||||
src/util.cpp
|
||||
src/crypto.cpp
|
||||
src/conf.cpp
|
||||
src/proc.cpp
|
||||
src/usr/user_session_handler.cpp
|
||||
src/usr/usr.cpp
|
||||
src/main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(hpcore
|
||||
|
||||
138
src/conf.cpp
138
src/conf.cpp
@@ -12,9 +12,6 @@
|
||||
#include "crypto.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace rapidjson;
|
||||
|
||||
namespace conf
|
||||
{
|
||||
|
||||
@@ -58,7 +55,7 @@ int rekey()
|
||||
if (save_config() != 0)
|
||||
return -1;
|
||||
|
||||
cout << "New signing keys generated at " << ctx.configFile << endl;
|
||||
std::cout << "New signing keys generated at " << ctx.configFile << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -72,7 +69,7 @@ int create_contract()
|
||||
{
|
||||
if (boost::filesystem::exists(ctx.contractDir))
|
||||
{
|
||||
cerr << "Contract dir already exists. Cannot create contract at the same location.\n";
|
||||
std::cerr << "Contract dir already exists. Cannot create contract at the same location.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -99,7 +96,7 @@ int create_contract()
|
||||
if (save_config() != 0)
|
||||
return -1;
|
||||
|
||||
cout << "Contract directory created at " << ctx.contractDir << endl;
|
||||
std::cout << "Contract directory created at " << ctx.contractDir << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -108,7 +105,7 @@ int create_contract()
|
||||
* Updates the contract context with directory paths based on provided base directory.
|
||||
* This is called after parsing HP command line arg in order to populate the ctx.
|
||||
*/
|
||||
void set_contract_dir_paths(string basedir)
|
||||
void set_contract_dir_paths(std::string basedir)
|
||||
{
|
||||
if (basedir[basedir.size() - 1] == '/')
|
||||
basedir = basedir.substr(0, basedir.size() - 1);
|
||||
@@ -129,42 +126,42 @@ int load_config()
|
||||
{
|
||||
// Read the file into json document object.
|
||||
|
||||
ifstream ifs(ctx.configFile);
|
||||
IStreamWrapper isw(ifs);
|
||||
std::ifstream ifs(ctx.configFile);
|
||||
rapidjson::IStreamWrapper isw(ifs);
|
||||
|
||||
Document d;
|
||||
rapidjson::Document d;
|
||||
if (d.ParseStream(isw).HasParseError())
|
||||
{
|
||||
cerr << "Invalid config file format. Parser error at position " << d.GetErrorOffset() << endl;
|
||||
std::cerr << "Invalid config file format. Parser error at position " << d.GetErrorOffset() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
else if (is_schema_valid(d) != 0)
|
||||
{
|
||||
cerr << "Invalid config file format.\n";
|
||||
std::cerr << "Invalid config file format.\n";
|
||||
return -1;
|
||||
}
|
||||
ifs.close();
|
||||
|
||||
// Check whether the contract version is specified.
|
||||
string cfgversion = d["version"].GetString();
|
||||
std::string cfgversion = d["version"].GetString();
|
||||
if (cfgversion.empty())
|
||||
{
|
||||
cerr << "Contract config version missing.\n";
|
||||
std::cerr << "Contract config version missing.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check whether this contract complies with the min version requirement.
|
||||
int verresult = util::version_compare(cfgversion, string(util::MIN_CONTRACT_VERSION));
|
||||
int verresult = util::version_compare(cfgversion, std::string(util::MIN_CONTRACT_VERSION));
|
||||
if (verresult == -1)
|
||||
{
|
||||
cerr << "Contract version too old. Minimum "
|
||||
<< util::MIN_CONTRACT_VERSION << " required. "
|
||||
<< cfgversion << " found.\n";
|
||||
std::cerr << "Contract version too old. Minimum "
|
||||
<< util::MIN_CONTRACT_VERSION << " required. "
|
||||
<< cfgversion << " found.\n";
|
||||
return -1;
|
||||
}
|
||||
else if (verresult == -2)
|
||||
{
|
||||
cerr << "Malformed version string.\n";
|
||||
std::cerr << "Malformed version string.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -207,31 +204,31 @@ int save_config()
|
||||
{
|
||||
// Popualte json document with 'cfg' values.
|
||||
|
||||
Document d;
|
||||
rapidjson::Document d;
|
||||
d.SetObject();
|
||||
Document::AllocatorType &allocator = d.GetAllocator();
|
||||
d.AddMember("version", StringRef(util::HP_VERSION), allocator);
|
||||
d.AddMember("pubkeyb64", StringRef(cfg.pubkeyb64.data()), allocator);
|
||||
d.AddMember("seckeyb64", StringRef(cfg.seckeyb64.data()), allocator);
|
||||
d.AddMember("keytype", StringRef(cfg.keytype.data()), allocator);
|
||||
d.AddMember("binary", StringRef(cfg.binary.data()), allocator);
|
||||
d.AddMember("binargs", StringRef(cfg.binargs.data()), allocator);
|
||||
d.AddMember("listenip", StringRef(cfg.listenip.data()), allocator);
|
||||
rapidjson::Document::AllocatorType &allocator = d.GetAllocator();
|
||||
d.AddMember("version", rapidjson::StringRef(util::HP_VERSION), allocator);
|
||||
d.AddMember("pubkeyb64", rapidjson::StringRef(cfg.pubkeyb64.data()), allocator);
|
||||
d.AddMember("seckeyb64", rapidjson::StringRef(cfg.seckeyb64.data()), allocator);
|
||||
d.AddMember("keytype", rapidjson::StringRef(cfg.keytype.data()), allocator);
|
||||
d.AddMember("binary", rapidjson::StringRef(cfg.binary.data()), allocator);
|
||||
d.AddMember("binargs", rapidjson::StringRef(cfg.binargs.data()), allocator);
|
||||
d.AddMember("listenip", rapidjson::StringRef(cfg.listenip.data()), allocator);
|
||||
|
||||
Value peers(kArrayType);
|
||||
for (string &peer : cfg.peers)
|
||||
rapidjson::Value peers(rapidjson::kArrayType);
|
||||
for (std::string &peer : cfg.peers)
|
||||
{
|
||||
Value v;
|
||||
v.SetString(StringRef(peer.data()), allocator);
|
||||
rapidjson::Value v;
|
||||
v.SetString(rapidjson::StringRef(peer.data()), allocator);
|
||||
peers.PushBack(v, allocator);
|
||||
}
|
||||
d.AddMember("peers", peers, allocator);
|
||||
|
||||
Value unl(kArrayType);
|
||||
for (string &node : cfg.unl)
|
||||
rapidjson::Value unl(rapidjson::kArrayType);
|
||||
for (std::string &node : cfg.unl)
|
||||
{
|
||||
Value v;
|
||||
v.SetString(StringRef(node.data()), allocator);
|
||||
rapidjson::Value v;
|
||||
v.SetString(rapidjson::StringRef(node.data()), allocator);
|
||||
unl.PushBack(v, allocator);
|
||||
}
|
||||
d.AddMember("unl", unl, allocator);
|
||||
@@ -242,16 +239,15 @@ int save_config()
|
||||
d.AddMember("pubmaxsize", cfg.pubmaxsize, allocator);
|
||||
d.AddMember("pubmaxcpm", cfg.pubmaxcpm, allocator);
|
||||
|
||||
|
||||
// Write the json doc to file.
|
||||
|
||||
ofstream ofs(ctx.configFile);
|
||||
OStreamWrapper osw(ofs);
|
||||
std::ofstream ofs(ctx.configFile);
|
||||
rapidjson::OStreamWrapper osw(ofs);
|
||||
|
||||
PrettyWriter<OStreamWrapper> writer(osw);
|
||||
rapidjson::PrettyWriter<rapidjson::OStreamWrapper> writer(osw);
|
||||
if (!d.Accept(writer))
|
||||
{
|
||||
cerr << "Writing to config file failed. " << ctx.configFile << endl;
|
||||
std::cerr << "Writing to config file failed. " << ctx.configFile << std::endl;
|
||||
return -1;
|
||||
}
|
||||
ofs.close();
|
||||
@@ -266,15 +262,21 @@ int save_config()
|
||||
*/
|
||||
int binpair_to_b64()
|
||||
{
|
||||
if (util::base64_encode((unsigned char *)cfg.pubkey.data(), crypto_sign_PUBLICKEYBYTES, cfg.pubkeyb64) != 0)
|
||||
if (util::base64_encode(
|
||||
cfg.pubkeyb64,
|
||||
reinterpret_cast<const unsigned char *>(cfg.pubkey.data()),
|
||||
crypto_sign_PUBLICKEYBYTES) != 0)
|
||||
{
|
||||
cerr << "Error encoding public key bytes.\n";
|
||||
std::cerr << "Error encoding public key bytes.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (util::base64_encode((unsigned char *)cfg.seckey.data(), crypto_sign_SECRETKEYBYTES, cfg.seckeyb64) != 0)
|
||||
if (util::base64_encode(
|
||||
cfg.seckeyb64,
|
||||
reinterpret_cast<const unsigned char *>(cfg.seckey.data()),
|
||||
crypto_sign_SECRETKEYBYTES) != 0)
|
||||
{
|
||||
cerr << "Error encoding secret key bytes.\n";
|
||||
std::cerr << "Error encoding secret key bytes.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -289,23 +291,25 @@ int binpair_to_b64()
|
||||
int b64pair_to_bin()
|
||||
{
|
||||
unsigned char decoded_pubkey[crypto_sign_PUBLICKEYBYTES];
|
||||
unsigned char decoded_seckey[crypto_sign_SECRETKEYBYTES];
|
||||
|
||||
if (util::base64_decode(cfg.pubkeyb64, decoded_pubkey, crypto_sign_PUBLICKEYBYTES) != 0)
|
||||
if (util::base64_decode(decoded_pubkey, crypto_sign_PUBLICKEYBYTES, cfg.pubkeyb64) != 0)
|
||||
{
|
||||
cerr << "Error decoding base64 public key.\n";
|
||||
std::cerr << "Error decoding base64 public key.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (util::base64_decode(cfg.seckeyb64, decoded_seckey, crypto_sign_SECRETKEYBYTES) != 0)
|
||||
unsigned char decoded_seckey[crypto_sign_SECRETKEYBYTES];
|
||||
if (util::base64_decode(decoded_seckey, crypto_sign_SECRETKEYBYTES, cfg.seckeyb64) != 0)
|
||||
{
|
||||
cerr << "Error decoding base64 secret key.\n";
|
||||
std::cerr << "Error decoding base64 secret key.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Assign the cfg pubkey/seckey fields with the decoded strings.
|
||||
cfg.pubkey = string((char *)decoded_pubkey, crypto_sign_PUBLICKEYBYTES);
|
||||
cfg.seckey = string((char *)decoded_seckey, crypto_sign_SECRETKEYBYTES);
|
||||
|
||||
cfg.pubkey = std::string(reinterpret_cast<char *>(decoded_pubkey), crypto_sign_PUBLICKEYBYTES);
|
||||
|
||||
cfg.seckey = std::string(reinterpret_cast<char *>(decoded_seckey), crypto_sign_SECRETKEYBYTES);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -320,7 +324,7 @@ int validate_config()
|
||||
// We also check for key pair validity as well in the below code.
|
||||
if (cfg.pubkeyb64.empty() || cfg.seckeyb64.empty())
|
||||
{
|
||||
cerr << "Signing keys missing. Run with 'rekey' to generate new keys.\n";
|
||||
std::cerr << "Signing keys missing. Run with 'rekey' to generate new keys.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -328,23 +332,23 @@ int validate_config()
|
||||
if (cfg.binary.empty() || cfg.listenip.empty() ||
|
||||
cfg.peerport == 0 || cfg.roundtime == 0 || cfg.pubport == 0 || cfg.pubmaxsize == 0 || cfg.pubmaxcpm == 0)
|
||||
{
|
||||
cerr << "Required configuration fields missing at " << ctx.configFile << endl;
|
||||
std::cerr << "Required configuration fields missing at " << ctx.configFile << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check whether the contract binary actually exists.
|
||||
if (!boost::filesystem::exists(cfg.binary))
|
||||
{
|
||||
cerr << "Contract binary does not exist: " << cfg.binary << endl;
|
||||
std::cerr << "Contract binary does not exist: " << cfg.binary << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Sign and verify a sample message to ensure we have a matching signing key pair.
|
||||
string msg = "hotpocket";
|
||||
string sigb64 = crypto::sign_b64(msg, cfg.seckeyb64);
|
||||
std::string msg = "hotpocket";
|
||||
std::string sigb64 = crypto::sign_b64(msg, cfg.seckeyb64);
|
||||
if (crypto::verify_b64(msg, sigb64, cfg.pubkeyb64) != 0)
|
||||
{
|
||||
cerr << "Invalid signing keys. Run with 'rekey' to generate new keys.\n";
|
||||
std::cerr << "Invalid signing keys. Run with 'rekey' to generate new keys.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -358,13 +362,13 @@ int validate_config()
|
||||
*/
|
||||
int validate_contract_dir_paths()
|
||||
{
|
||||
string dirs[4] = {ctx.contractDir, ctx.configFile, ctx.histDir, ctx.stateDir};
|
||||
std::string dirs[4] = {ctx.contractDir, ctx.configFile, ctx.histDir, ctx.stateDir};
|
||||
|
||||
for (string &dir : dirs)
|
||||
for (std::string &dir : dirs)
|
||||
{
|
||||
if (!boost::filesystem::exists(dir))
|
||||
{
|
||||
cerr << dir << " does not exist.\n";
|
||||
std::cerr << dir << " does not exist.\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -377,7 +381,7 @@ int validate_contract_dir_paths()
|
||||
*
|
||||
* @return 0 for successful validation. -1 for failure.
|
||||
*/
|
||||
int is_schema_valid(Document &d)
|
||||
int is_schema_valid(rapidjson::Document &d)
|
||||
{
|
||||
const char *cfg_schema =
|
||||
"{"
|
||||
@@ -408,14 +412,14 @@ int is_schema_valid(Document &d)
|
||||
"}"
|
||||
"}";
|
||||
|
||||
Document sd;
|
||||
rapidjson::Document sd;
|
||||
sd.Parse(cfg_schema);
|
||||
SchemaDocument schema(sd);
|
||||
rapidjson::SchemaDocument schema(sd);
|
||||
|
||||
SchemaValidator validator(schema);
|
||||
rapidjson::SchemaValidator validator(schema);
|
||||
if (!d.Accept(validator))
|
||||
return -1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
39
src/conf.hpp
39
src/conf.hpp
@@ -4,9 +4,6 @@
|
||||
#include <rapidjson/document.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace rapidjson;
|
||||
|
||||
/**
|
||||
* Manages the central contract config and context structs.
|
||||
* Contains functions to contract config operations such as create/rekey/load.
|
||||
@@ -17,13 +14,13 @@ namespace conf
|
||||
// Holds contextual information about the currently loaded contract.
|
||||
struct contract_ctx
|
||||
{
|
||||
string command; // The CLI command issued to launch HotPocket
|
||||
std::string command; // The CLI command issued to launch HotPocket
|
||||
|
||||
string contractDir; // Contract base directory
|
||||
string histDir; // Contract history dir
|
||||
string stateDir; // Contract state dir
|
||||
string configDir; // Contract config dir
|
||||
string configFile; // Full path to the contract config file
|
||||
std::string contractDir; // Contract base directory
|
||||
std::string histDir; // Contract history dir
|
||||
std::string stateDir; // Contract state dir
|
||||
std::string configDir; // Contract config dir
|
||||
std::string configFile; // Full path to the contract config file
|
||||
};
|
||||
|
||||
// Holds all the contract config values.
|
||||
@@ -31,19 +28,19 @@ struct contract_config
|
||||
{
|
||||
// Config elements which are initialized in memory (these are not directly loaded from the config file)
|
||||
|
||||
string pubkey; // Contract public key bytes
|
||||
string seckey; // Contract secret key bytes
|
||||
std::string pubkey; // Contract public key bytes
|
||||
std::string seckey; // Contract secret key bytes
|
||||
|
||||
// Config elements which are loaded from the config file.
|
||||
|
||||
string pubkeyb64; // Contract base64 public key
|
||||
string seckeyb64; // Contract base64 secret key
|
||||
string keytype; // Key generation algorithm used by libsodium
|
||||
string binary; // Full path to the contract binary
|
||||
string binargs; // CLI arguments to pass to the contract binary
|
||||
string listenip; // The IPs to listen on for incoming connections
|
||||
vector<string> peers; // List of peers in the format "<ip address>:<port>"
|
||||
vector<string> unl; // Unique node list (list of base64 public keys)
|
||||
std::string pubkeyb64; // Contract base64 public key
|
||||
std::string seckeyb64; // Contract base64 secret key
|
||||
std::string keytype; // Key generation algorithm used by libsodium
|
||||
std::string binary; // Full path to the contract binary
|
||||
std::string binargs; // CLI arguments to pass to the contract binary
|
||||
std::string listenip; // The IPs to listen on for incoming connections
|
||||
std::vector<std::string> peers; // List of peers in the format "<ip address>:<port>"
|
||||
std::vector<std::string> unl; // Unique node list (list of base64 public keys)
|
||||
unsigned short peerport; // Listening port for peer connections
|
||||
int roundtime; // Consensus round time in ms
|
||||
unsigned short pubport; // Listening port for public user connections
|
||||
@@ -65,7 +62,7 @@ int rekey();
|
||||
|
||||
int create_contract();
|
||||
|
||||
void set_contract_dir_paths(string basedir);
|
||||
void set_contract_dir_paths(std::string basedir);
|
||||
|
||||
//------Internal-use functions for this namespace.
|
||||
|
||||
@@ -77,7 +74,7 @@ int validate_config();
|
||||
|
||||
int validate_contract_dir_paths();
|
||||
|
||||
int is_schema_valid(Document &d);
|
||||
int is_schema_valid(rapidjson::Document &d);
|
||||
|
||||
int binpair_to_b64();
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "crypto.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
|
||||
@@ -17,7 +15,7 @@ int init()
|
||||
{
|
||||
if (sodium_init() < 0)
|
||||
{
|
||||
cerr << "sodium_init failed.\n";
|
||||
std::cerr << "sodium_init failed.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -27,7 +25,7 @@ int init()
|
||||
/**
|
||||
* Generates a signing key pair using libsodium and assigns them to the provided strings.
|
||||
*/
|
||||
void generate_signing_keys(string &pubkey, string &seckey, string &keytype)
|
||||
void generate_signing_keys(std::string &pubkey, std::string &seckey, std::string &keytype)
|
||||
{
|
||||
//Generate key pair using libsodium default algorithm. (Currently using ed25519)
|
||||
|
||||
@@ -35,8 +33,8 @@ void generate_signing_keys(string &pubkey, string &seckey, string &keytype)
|
||||
unsigned char seckeychars[crypto_sign_SECRETKEYBYTES];
|
||||
crypto_sign_keypair(pubkeychars, seckeychars);
|
||||
|
||||
pubkey = string((char *)pubkeychars, crypto_sign_PUBLICKEYBYTES);
|
||||
seckey = string((char *)seckeychars, crypto_sign_SECRETKEYBYTES);
|
||||
pubkey = std::string(reinterpret_cast<char *>(pubkeychars), crypto_sign_PUBLICKEYBYTES);
|
||||
seckey = std::string(reinterpret_cast<char *>(seckeychars), crypto_sign_SECRETKEYBYTES);
|
||||
keytype = crypto_sign_primitive();
|
||||
}
|
||||
|
||||
@@ -47,13 +45,19 @@ void generate_signing_keys(string &pubkey, string &seckey, string &keytype)
|
||||
* @param seckey Secret key bytes.
|
||||
* @return Signature bytes.
|
||||
*/
|
||||
string sign(const string &msg, const string &seckey)
|
||||
std::string sign(const std::string &msg, const std::string &seckey)
|
||||
{
|
||||
//Generate the signature using libsodium.
|
||||
|
||||
unsigned char sigchars[crypto_sign_BYTES];
|
||||
crypto_sign_detached(sigchars, NULL, (unsigned char *)msg.data(), msg.length(), (unsigned char *)seckey.data());
|
||||
string sig((char *)sigchars, crypto_sign_BYTES);
|
||||
crypto_sign_detached(
|
||||
sigchars,
|
||||
NULL,
|
||||
reinterpret_cast<const unsigned char *>(msg.data()),
|
||||
msg.length(),
|
||||
reinterpret_cast<const unsigned char *>(seckey.data()));
|
||||
|
||||
std::string sig(reinterpret_cast<char *>(sigchars), crypto_sign_BYTES);
|
||||
return sig;
|
||||
}
|
||||
|
||||
@@ -64,18 +68,23 @@ string sign(const string &msg, const string &seckey)
|
||||
* @param seckeyb64 Base64 secret key string.
|
||||
* @return Base64 signature string.
|
||||
*/
|
||||
string sign_b64(const string &msg, const string &seckeyb64)
|
||||
std::string sign_b64(const std::string &msg, const std::string &seckeyb64)
|
||||
{
|
||||
//Decode b64 string and generate the signature using libsodium.
|
||||
|
||||
unsigned char seckey[crypto_sign_SECRETKEYBYTES];
|
||||
util::base64_decode(seckeyb64, seckey, crypto_sign_SECRETKEYBYTES);
|
||||
util::base64_decode(seckey, crypto_sign_SECRETKEYBYTES, seckeyb64);
|
||||
|
||||
unsigned char sig[crypto_sign_BYTES];
|
||||
crypto_sign_detached(sig, NULL, (unsigned char *)msg.data(), msg.length(), seckey);
|
||||
crypto_sign_detached(
|
||||
sig,
|
||||
NULL,
|
||||
reinterpret_cast<const unsigned char *>(msg.data()),
|
||||
msg.length(),
|
||||
seckey);
|
||||
|
||||
string sigb64;
|
||||
util::base64_encode(sig, crypto_sign_BYTES, sigb64);
|
||||
std::string sigb64;
|
||||
util::base64_encode(sigb64, sig, crypto_sign_BYTES);
|
||||
return sigb64;
|
||||
}
|
||||
|
||||
@@ -87,10 +96,13 @@ string sign_b64(const string &msg, const string &seckeyb64)
|
||||
* @param pubkey Public key bytes.
|
||||
* @return 0 for successful verification. -1 for failure.
|
||||
*/
|
||||
int verify(const string &msg, const string &sig, const string &pubkey)
|
||||
int verify(const std::string &msg, const std::string &sig, const std::string &pubkey)
|
||||
{
|
||||
return crypto_sign_verify_detached(
|
||||
(unsigned char *)sig.data(), (unsigned char *)msg.data(), msg.length(), (unsigned char *)pubkey.data());
|
||||
reinterpret_cast<const unsigned char *>(sig.data()),
|
||||
reinterpret_cast<const unsigned char *>(msg.data()),
|
||||
msg.length(),
|
||||
reinterpret_cast<const unsigned char *>(pubkey.data()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,17 +113,21 @@ int verify(const string &msg, const string &sig, const string &pubkey)
|
||||
* @param pubkeyb64 Base64 secret key.
|
||||
* @return 0 for successful verification. -1 for failure.
|
||||
*/
|
||||
int verify_b64(const string &msg, const string &sigb64, const string &pubkeyb64)
|
||||
int verify_b64(const std::string &msg, const std::string &sigb64, const std::string &pubkeyb64)
|
||||
{
|
||||
//Decode b64 string and verify the signature using libsodium.
|
||||
|
||||
unsigned char decoded_pubkey[crypto_sign_PUBLICKEYBYTES];
|
||||
util::base64_decode(pubkeyb64, decoded_pubkey, crypto_sign_PUBLICKEYBYTES);
|
||||
util::base64_decode(decoded_pubkey, crypto_sign_PUBLICKEYBYTES, pubkeyb64);
|
||||
|
||||
unsigned char decoded_sig[crypto_sign_BYTES];
|
||||
util::base64_decode(sigb64, decoded_sig, crypto_sign_BYTES);
|
||||
util::base64_decode(decoded_sig, crypto_sign_BYTES, sigb64);
|
||||
|
||||
return crypto_sign_verify_detached(decoded_sig, (unsigned char *)msg.data(), msg.length(), decoded_pubkey);
|
||||
return crypto_sign_verify_detached(
|
||||
decoded_sig,
|
||||
reinterpret_cast<const unsigned char *>(msg.data()),
|
||||
msg.length(),
|
||||
decoded_pubkey);
|
||||
}
|
||||
|
||||
} // namespace crypto
|
||||
@@ -1,8 +1,6 @@
|
||||
#ifndef _HP_CRYPTO_H_
|
||||
#define _HP_CRYPTO_H_
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Offers convenience functions for cryptographic operations wrapping libsodium.
|
||||
* These functions are used for contract config and user/peer message authentication.
|
||||
@@ -12,15 +10,15 @@ namespace crypto
|
||||
|
||||
int init();
|
||||
|
||||
void generate_signing_keys(string &pubkey, string &seckey, string &keytype);
|
||||
void generate_signing_keys(std::string &pubkey, std::string &seckey, std::string &keytype);
|
||||
|
||||
string sign(const string &msg, const string &seckey);
|
||||
std::string sign(const std::string &msg, const std::string &seckey);
|
||||
|
||||
string sign_b64(const string &msg, const string &seckeyb64);
|
||||
std::string sign_b64(const std::string &msg, const std::string &seckeyb64);
|
||||
|
||||
int verify(const string &msg, const string &sig, const string &pubkey);
|
||||
int verify(const std::string &msg, const std::string &sig, const std::string &pubkey);
|
||||
|
||||
int verify_b64(const string &msg, const string &sigb64, const string &pubkeyb64);
|
||||
int verify_b64(const std::string &msg, const std::string &sigb64, const std::string &pubkeyb64);
|
||||
|
||||
} // namespace crypto
|
||||
|
||||
|
||||
22
src/main.cpp
22
src/main.cpp
@@ -10,8 +10,6 @@
|
||||
#include "crypto.hpp"
|
||||
#include "usr/usr.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Parses CLI args and extracts hot pocket command and parameters given.
|
||||
* HP command line accepts command and the contract directory(optional)
|
||||
@@ -29,7 +27,7 @@ int parse_cmd(int argc, char **argv)
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
cerr << "Contract directory not specified.\n";
|
||||
std::cerr << "Contract directory not specified.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -49,11 +47,11 @@ int parse_cmd(int argc, char **argv)
|
||||
|
||||
// If all extractions fail display help message.
|
||||
|
||||
cerr << "Arguments mismatch.\n";
|
||||
cout << "Usage:\n";
|
||||
cout << "hpcore version\n";
|
||||
cout << "hpcore <command> <contract dir> (command = run | new | rekey)\n";
|
||||
cout << "Example: hpcore run ~/mycontract\n";
|
||||
std::cerr << "Arguments mismatch.\n";
|
||||
std::cout << "Usage:\n";
|
||||
std::cout << "hpcore version\n";
|
||||
std::cout << "hpcore <command> <contract dir> (command = run | new | rekey)\n";
|
||||
std::cout << "Example: hpcore run ~/mycontract\n";
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -68,7 +66,7 @@ int main(int argc, char **argv)
|
||||
if (conf::ctx.command == "version")
|
||||
{
|
||||
// Print the version
|
||||
cout << util::HP_VERSION << endl;
|
||||
std::cout << util::HP_VERSION << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -104,11 +102,11 @@ int main(int argc, char **argv)
|
||||
// TODO
|
||||
|
||||
// Temp code to avoid exiting.
|
||||
string s;
|
||||
cin >> s;
|
||||
std::string s;
|
||||
std::cin >> s;
|
||||
}
|
||||
}
|
||||
}
|
||||
cout << "exited normally\n";
|
||||
std::cout << "exited normally\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <string>
|
||||
#include "message.pb.h"
|
||||
#include "p2p.h"
|
||||
#include "p2p.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
39
src/proc.cpp
39
src/proc.cpp
@@ -10,9 +10,6 @@
|
||||
#include "proc.hpp"
|
||||
#include "conf.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace util;
|
||||
|
||||
namespace proc
|
||||
{
|
||||
|
||||
@@ -30,7 +27,7 @@ int exec_contract(const ContractExecArgs &args)
|
||||
{
|
||||
if (is_contract_running())
|
||||
{
|
||||
cerr << "Contract process still running.\n";
|
||||
std::cerr << "Contract process still running.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -57,7 +54,7 @@ int exec_contract(const ContractExecArgs &args)
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "fork() failed.\n";
|
||||
std::cerr << "fork() failed.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -80,41 +77,41 @@ int write_to_stdin(const ContractExecArgs &args)
|
||||
{
|
||||
//Populate the json document with contract args.
|
||||
|
||||
Document d;
|
||||
rapidjson::Document d;
|
||||
d.SetObject();
|
||||
Document::AllocatorType &allocator = d.GetAllocator();
|
||||
rapidjson::Document::AllocatorType &allocator = d.GetAllocator();
|
||||
|
||||
d.AddMember("version", StringRef(util::HP_VERSION), allocator);
|
||||
d.AddMember("pubkey", StringRef(conf::cfg.pubkeyb64.data()), allocator);
|
||||
d.AddMember("version", rapidjson::StringRef(util::HP_VERSION), allocator);
|
||||
d.AddMember("pubkey", rapidjson::StringRef(conf::cfg.pubkeyb64.data()), allocator);
|
||||
d.AddMember("ts", args.timestamp, allocator);
|
||||
|
||||
Value users(kObjectType);
|
||||
rapidjson::Value users(rapidjson::kObjectType);
|
||||
for (auto &[sid, user] : args.users)
|
||||
{
|
||||
Value fdlist(kArrayType);
|
||||
rapidjson::Value fdlist(rapidjson::kArrayType);
|
||||
fdlist.PushBack(user.inpipe[0], allocator);
|
||||
fdlist.PushBack(user.outpipe[1], allocator);
|
||||
users.AddMember(StringRef(user.pubkeyb64.data()), fdlist, allocator);
|
||||
users.AddMember(rapidjson::StringRef(user.pubkeyb64.data()), fdlist, allocator);
|
||||
}
|
||||
d.AddMember("usrfd", users, allocator);
|
||||
|
||||
Value peers(kObjectType);
|
||||
rapidjson::Value peers(rapidjson::kObjectType);
|
||||
for (auto &[sid, peer] : args.peers)
|
||||
{
|
||||
Value fdlist(kArrayType);
|
||||
rapidjson::Value fdlist(rapidjson::kArrayType);
|
||||
fdlist.PushBack(peer.inpipe[0], allocator);
|
||||
fdlist.PushBack(peer.outpipe[1], allocator);
|
||||
peers.AddMember(StringRef(peer.pubkeyb64.data()), fdlist, allocator);
|
||||
peers.AddMember(rapidjson::StringRef(peer.pubkeyb64.data()), fdlist, allocator);
|
||||
}
|
||||
d.AddMember("nplfd", peers, allocator);
|
||||
|
||||
Value unl(kArrayType);
|
||||
for (string &node : conf::cfg.unl)
|
||||
unl.PushBack(StringRef(node.data()), allocator);
|
||||
rapidjson::Value unl(rapidjson::kArrayType);
|
||||
for (std::string &node : conf::cfg.unl)
|
||||
unl.PushBack(rapidjson::StringRef(node.data()), allocator);
|
||||
d.AddMember("unl", unl, allocator);
|
||||
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
d.Accept(writer);
|
||||
|
||||
// Get the json string that should be written to contract input pipe.
|
||||
@@ -124,7 +121,7 @@ int write_to_stdin(const ContractExecArgs &args)
|
||||
int stdinpipe[2];
|
||||
if (pipe(stdinpipe) != 0)
|
||||
{
|
||||
cerr << "Failed to create pipe to the contract process.\n";
|
||||
std::cerr << "Failed to create pipe to the contract process.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
#include <map>
|
||||
#include "util.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace util;
|
||||
|
||||
/**
|
||||
* Contains helper functions regarding POSIX process execution and IPC between HP and SC.
|
||||
*/
|
||||
@@ -19,11 +16,11 @@ namespace proc
|
||||
*/
|
||||
struct ContractExecArgs
|
||||
{
|
||||
map<string, contract_user> &users; // Map of authenticated contract users indexed by user pubkey.
|
||||
map<string, peer_node> &peers; // Map of connected peers indexed by node pubkey.
|
||||
std::map<std::string, util::contract_user> &users; // Map of authenticated contract users indexed by user pubkey.
|
||||
std::map<std::string, util::peer_node> &peers; // Map of connected peers indexed by node pubkey.
|
||||
uint64_t timestamp; // Current HotPocket timestamp.
|
||||
|
||||
ContractExecArgs(map<string, contract_user> &_users, map<string, peer_node> &_peers, uint64_t _timestamp)
|
||||
ContractExecArgs(std::map<std::string, util::contract_user> &_users, std::map<std::string, util::peer_node> &_peers, uint64_t _timestamp)
|
||||
: users(_users), peers(_peers)
|
||||
{
|
||||
timestamp = _timestamp;
|
||||
|
||||
@@ -14,8 +14,6 @@ namespace beast = boost::beast;
|
||||
using tcp = net::ip::tcp;
|
||||
using error = boost::system::error_code;
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace usr
|
||||
{
|
||||
|
||||
@@ -24,13 +22,13 @@ namespace usr
|
||||
*/
|
||||
void user_session_handler::on_connect(sock::socket_session *session)
|
||||
{
|
||||
cout << "User client connected " << session->address_ << ":" << session->port_ << endl;
|
||||
std::cout << "User client connected " << session->address_ << ":" << session->port_ << std::endl;
|
||||
|
||||
// As a soon as a user conntects, we issue them a challenge message. We remember the
|
||||
// challenge we issued and later verifies the user's response with it.
|
||||
|
||||
string msg;
|
||||
string challengeb64;
|
||||
std::string msg;
|
||||
std::string challengeb64;
|
||||
usr::create_user_challenge(msg, challengeb64);
|
||||
|
||||
// We init the session unique id to associate with the challenge.
|
||||
@@ -40,7 +38,7 @@ void user_session_handler::on_connect(sock::socket_session *session)
|
||||
usr::pending_challenges[session->uniqueid_] = challengeb64;
|
||||
|
||||
// TODO: This needs to be reviewed to optimise passing the message.
|
||||
session->send(make_shared<string>(msg));
|
||||
session->send(std::make_shared<std::string>(msg));
|
||||
|
||||
// Set the challenge-issued flag to help later checks in on_message.
|
||||
session->flags_.set(util::SESSION_FLAG::USER_CHALLENGE_ISSUED);
|
||||
@@ -59,9 +57,9 @@ void user_session_handler::on_message(sock::socket_session *session, const std::
|
||||
auto itr = usr::pending_challenges.find(session->uniqueid_);
|
||||
if (itr != usr::pending_challenges.end())
|
||||
{
|
||||
string userpubkey;
|
||||
const string &original_challenge = itr->second;
|
||||
if (usr::verify_user_challenge_response(message, original_challenge, userpubkey) == 0)
|
||||
std::string userpubkey;
|
||||
const std::string &original_challenge = itr->second;
|
||||
if (usr::verify_user_challenge_response(userpubkey, message, original_challenge) == 0)
|
||||
{
|
||||
// Challenge verification successful.
|
||||
// Promote the connection from pending-challenges to authenticated users.
|
||||
@@ -71,12 +69,12 @@ void user_session_handler::on_message(sock::socket_session *session, const std::
|
||||
usr::pending_challenges.erase(session->uniqueid_); // Remove the stored challenge
|
||||
usr::add_user(session->uniqueid_, userpubkey); // Add the user to the global authed user list
|
||||
|
||||
cout << "User connection " << session->uniqueid_ << " authenticated.\n";
|
||||
std::cout << "User connection " << session->uniqueid_ << " authenticated.\n";
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Challenge verification failed " << session->uniqueid_ << endl;
|
||||
std::cout << "Challenge verification failed " << session->uniqueid_ << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,16 +89,16 @@ void user_session_handler::on_message(sock::socket_session *session, const std::
|
||||
{
|
||||
// This is an authed user.
|
||||
// Write the message to the user input pipe. SC will read from this pipe when it executes.
|
||||
const contract_user &user = itr->second;
|
||||
const util::contract_user &user = itr->second;
|
||||
write(user.inpipe[1], message.data(), message.length());
|
||||
cout << "User " << user.pubkeyb64 << " wrote " << message.length() << " bytes to contract input.\n";
|
||||
std::cout << "User " << user.pubkeyb64 << " wrote " << message.length() << " bytes to contract input.\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If for any reason we reach this point, we should drop the connection.
|
||||
session->close();
|
||||
cout << "Dropped the user connection " << session->address_ << ":" << session->port_ << endl;
|
||||
std::cout << "Dropped the user connection " << session->address_ << ":" << session->port_ << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,7 +119,7 @@ void user_session_handler::on_close(sock::socket_session *session)
|
||||
usr::remove_user(session->uniqueid_);
|
||||
}
|
||||
|
||||
cout << "User disconnected " << session->uniqueid_ << endl;
|
||||
std::cout << "User disconnected " << session->uniqueid_ << std::endl;
|
||||
}
|
||||
|
||||
} // namespace usr
|
||||
@@ -16,10 +16,6 @@
|
||||
#include "usr.hpp"
|
||||
#include "user_session_handler.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace util;
|
||||
using namespace rapidjson;
|
||||
|
||||
namespace usr
|
||||
{
|
||||
|
||||
@@ -27,18 +23,18 @@ namespace usr
|
||||
* Global user list. (Exposed to other sub systems)
|
||||
* Map key: User socket session id (<ip:port>)
|
||||
*/
|
||||
map<string, contract_user> users;
|
||||
std::map<std::string, util::contract_user> users;
|
||||
|
||||
/**
|
||||
* Keep track of verification-pending challenges issued to newly connected users.
|
||||
* Map key: User socket session id (<ip:port>)
|
||||
*/
|
||||
map<string, string> pending_challenges;
|
||||
std::map<std::string, std::string> pending_challenges;
|
||||
|
||||
/**
|
||||
* User session handler instance. This instance's methods will be fired for any user socket activity.
|
||||
*/
|
||||
user_session_handler global_usr_session_handler;
|
||||
usr::user_session_handler global_usr_session_handler;
|
||||
|
||||
/**
|
||||
* The IO context used by the websocket listener. (not exposed out of this namespace)
|
||||
@@ -48,7 +44,7 @@ net::io_context ioc;
|
||||
/**
|
||||
* The thread the websocket lsitener is running on. (not exposed out of this namespace)
|
||||
*/
|
||||
thread listener_thread;
|
||||
std::thread listener_thread;
|
||||
|
||||
// Challenge response fields.
|
||||
// These fields are used on challenge response validation.
|
||||
@@ -90,7 +86,7 @@ int init()
|
||||
* }
|
||||
* @param challenge String reference to copy the generated base64 challenge string into.
|
||||
*/
|
||||
void create_user_challenge(string &msg, string &challengeb64)
|
||||
void create_user_challenge(std::string &msg, std::string &challengeb64)
|
||||
{
|
||||
//Use libsodium to generate the random challenge bytes.
|
||||
unsigned char challenge_bytes[CHALLENGE_LEN];
|
||||
@@ -99,7 +95,7 @@ void create_user_challenge(string &msg, string &challengeb64)
|
||||
//We pass the b64 challenge string separately to the caller even though
|
||||
//we also include it in the challenge msg as well.
|
||||
|
||||
base64_encode(challenge_bytes, CHALLENGE_LEN, challengeb64);
|
||||
util::base64_encode(challengeb64, challenge_bytes, CHALLENGE_LEN);
|
||||
|
||||
//Construct the challenge msg json.
|
||||
// We do not use RapidJson here in favour of performance because this is a simple json message.
|
||||
@@ -119,6 +115,7 @@ void create_user_challenge(string &msg, string &challengeb64)
|
||||
* Verifies the user challenge response with the original challenge issued to the user
|
||||
* and the user public key contained in the response.
|
||||
*
|
||||
* @param extracted_pubkeyb64 The base64 public key extracted from the response.
|
||||
* @param response The response bytes to verify. This will be parsed as json.
|
||||
* Accepted response format:
|
||||
* {
|
||||
@@ -128,55 +125,54 @@ void create_user_challenge(string &msg, string &challengeb64)
|
||||
* "pubkey": "<Base64 public key of the user>"
|
||||
* }
|
||||
* @param original_challenge The original base64 challenge string issued to the user.
|
||||
* @param extracted_pubkeyb64 The public key extracted from the response.
|
||||
* @return 0 if challenge response is verified. -1 if challenge not met or an error occurs.
|
||||
*/
|
||||
int verify_user_challenge_response(const string &response, const string &original_challenge, string &extracted_pubkeyb64)
|
||||
int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std::string &response, const std::string &original_challenge)
|
||||
{
|
||||
// We load response raw bytes into json document.
|
||||
Document d;
|
||||
rapidjson::Document d;
|
||||
d.Parse(response.data());
|
||||
if (d.HasParseError())
|
||||
{
|
||||
cerr << "Challenge response json parser error.\n";
|
||||
std::cerr << "Challenge response json parser error.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Validate msg type.
|
||||
if (!d.HasMember(CHALLENGE_RESP_TYPE) || d[CHALLENGE_RESP_TYPE] != CHALLENGE_RESP_MSGTYPE)
|
||||
{
|
||||
cerr << "User challenge response type invalid. 'challenge_response' expected.\n";
|
||||
std::cerr << "User challenge response type invalid. 'challenge_response' expected.\n";
|
||||
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())
|
||||
{
|
||||
cerr << "User challenge response challenge invalid.\n";
|
||||
std::cerr << "User challenge response challenge invalid.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check for the 'sig' field existence.
|
||||
if (!d.HasMember(CHALLENGE_RESP_SIG) || !d[CHALLENGE_RESP_SIG].IsString())
|
||||
{
|
||||
cerr << "User challenge response signature invalid.\n";
|
||||
std::cerr << "User challenge response signature invalid.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check for the 'pubkey' field existence.
|
||||
if (!d.HasMember(CHALLENGE_RESP_PUBKEY) || !d[CHALLENGE_RESP_PUBKEY].IsString())
|
||||
{
|
||||
cerr << "User challenge response public key invalid.\n";
|
||||
std::cerr << "User challenge response public key invalid.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Verify the challenge signature. We do this last due to signature verification cost.
|
||||
string sigb64 = d[CHALLENGE_RESP_SIG].GetString();
|
||||
std::string sigb64 = d[CHALLENGE_RESP_SIG].GetString();
|
||||
extracted_pubkeyb64 = d[CHALLENGE_RESP_PUBKEY].GetString();
|
||||
|
||||
if (crypto::verify_b64(original_challenge, sigb64, extracted_pubkeyb64) != 0)
|
||||
{
|
||||
cerr << "User challenge response signature verification failed.\n";
|
||||
std::cerr << "User challenge response signature verification failed.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -191,11 +187,11 @@ int verify_user_challenge_response(const string &response, const string &origina
|
||||
* @param pubkeyb64 User's base64 public key.
|
||||
* @return 0 on successful additions. -1 on failure.
|
||||
*/
|
||||
int add_user(const string &sessionid, const string &pubkeyb64)
|
||||
int add_user(const std::string &sessionid, const std::string &pubkeyb64)
|
||||
{
|
||||
if (users.count(sessionid) == 1)
|
||||
{
|
||||
cerr << sessionid << " already exist. Cannot add user.\n";
|
||||
std::cerr << sessionid << " already exist. Cannot add user.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -205,7 +201,7 @@ int add_user(const string &sessionid, const string &pubkeyb64)
|
||||
int inpipe[2];
|
||||
if (pipe(inpipe) != 0)
|
||||
{
|
||||
cerr << "User in pipe creation failed. sessionid:" << sessionid << endl;
|
||||
std::cerr << "User in pipe creation failed. sessionid:" << sessionid << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -213,7 +209,7 @@ int add_user(const string &sessionid, const string &pubkeyb64)
|
||||
int outpipe[2];
|
||||
if (pipe(outpipe) != 0)
|
||||
{
|
||||
cerr << "User out pipe creation failed. sessionid:" << sessionid << endl;
|
||||
std::cerr << "User out pipe creation failed. sessionid:" << sessionid << std::endl;
|
||||
|
||||
//We need to close 'inpipe' in case outpipe failed.
|
||||
close(inpipe[0]);
|
||||
@@ -222,7 +218,7 @@ int add_user(const string &sessionid, const string &pubkeyb64)
|
||||
return -1;
|
||||
}
|
||||
|
||||
users.emplace(sessionid, contract_user(pubkeyb64, inpipe, outpipe));
|
||||
users.emplace(sessionid, util::contract_user(pubkeyb64, inpipe, outpipe));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -232,17 +228,17 @@ int add_user(const string &sessionid, const string &pubkeyb64)
|
||||
*
|
||||
* @return 0 on successful removals. -1 on failure.
|
||||
*/
|
||||
int remove_user(const string &sessionid)
|
||||
int remove_user(const std::string &sessionid)
|
||||
{
|
||||
auto itr = users.find(sessionid);
|
||||
|
||||
if (itr == users.end())
|
||||
{
|
||||
cerr << sessionid << " does not exist. Cannot remove user.\n";
|
||||
std::cerr << sessionid << " does not exist. Cannot remove user.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const contract_user &user = itr->second;
|
||||
const util::contract_user &user = itr->second;
|
||||
|
||||
//Close the User <--> SC I/O pipes.
|
||||
close(user.inpipe[0]);
|
||||
@@ -282,9 +278,9 @@ int read_contract_user_outputs()
|
||||
read(fdout, data, bytes_available);
|
||||
|
||||
//Populate the user output buffer with new data
|
||||
user.outbuffer = string(data, bytes_available);
|
||||
user.outbuffer = std::string(data, bytes_available);
|
||||
|
||||
cout << "Read " + to_string(bytes_available) << " bytes into user output buffer. user:" + user.pubkeyb64 << endl;
|
||||
std::cout << "Read " + std::to_string(bytes_available) << " bytes into user output buffer. user:" + user.pubkeyb64 << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,15 +293,15 @@ int read_contract_user_outputs()
|
||||
void start_listening()
|
||||
{
|
||||
auto address = net::ip::make_address(conf::cfg.listenip);
|
||||
make_shared<sock::socket_server>(
|
||||
std::make_shared<sock::socket_server>(
|
||||
ioc,
|
||||
tcp::endpoint{address, conf::cfg.pubport},
|
||||
global_usr_session_handler)
|
||||
->run();
|
||||
|
||||
listener_thread = thread([&] { ioc.run(); });
|
||||
listener_thread = std::thread([&] { ioc.run(); });
|
||||
|
||||
cout << "Started listening for incoming user connections...\n";
|
||||
std::cout << "Started listening for incoming user connections...\n";
|
||||
}
|
||||
|
||||
} // namespace usr
|
||||
@@ -6,9 +6,6 @@
|
||||
#include <map>
|
||||
#include "../util.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace util;
|
||||
|
||||
/**
|
||||
* Maintains the global user list with pending input outputs and manages user connections.
|
||||
*/
|
||||
@@ -18,27 +15,27 @@ namespace usr
|
||||
/**
|
||||
* Global authenticated (challenge-verified) user list.
|
||||
*/
|
||||
extern map<string, contract_user> users;
|
||||
extern std::map<std::string, util::contract_user> users;
|
||||
|
||||
/**
|
||||
* Keep track of verification-pending challenges issued to newly connected users.
|
||||
*/
|
||||
extern map<string, string> pending_challenges;
|
||||
extern std::map<std::string, std::string> pending_challenges;
|
||||
|
||||
/**
|
||||
* Keep track of verification-pending challenges issued to newly connected users.
|
||||
*/
|
||||
extern map<string, string> pending_challenges;
|
||||
extern std::map<std::string, std::string> pending_challenges;
|
||||
|
||||
int init();
|
||||
|
||||
void create_user_challenge(string &msg, string &challengeb64);
|
||||
void create_user_challenge(std::string &msg, std::string &challengeb64);
|
||||
|
||||
int verify_user_challenge_response(const string &response, const string &original_challenge, string &extracted_pubkey);
|
||||
int verify_user_challenge_response(std::string &extracted_pubkeyb64, const std::string &response, const std::string &original_challenge);
|
||||
|
||||
int add_user(const string &sessionid, const string &pubkeyb64);
|
||||
int add_user(const std::string &sessionid, const std::string &pubkeyb64);
|
||||
|
||||
int remove_user(const string &sessionid);
|
||||
int remove_user(const std::string &sessionid);
|
||||
|
||||
int read_contract_user_outputs();
|
||||
|
||||
|
||||
20
src/util.cpp
20
src/util.cpp
@@ -2,19 +2,17 @@
|
||||
#include <sodium.h>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
||||
/**
|
||||
* Encodes provided bytes to base64 string.
|
||||
*
|
||||
* @param encoded_string String reference to assign the base64 encoded output.
|
||||
* @param bin Bytes to encode.
|
||||
* @param bin_len Bytes length.
|
||||
* @param encoded_string String reference to assign the base64 encoded output.
|
||||
*/
|
||||
int base64_encode(const unsigned char *bin, size_t bin_len, string &encoded_string)
|
||||
int base64_encode(std::string &encoded_string, const unsigned char *bin, size_t bin_len)
|
||||
{
|
||||
// Get length of encoded result from sodium.
|
||||
const size_t base64_len = sodium_base64_encoded_len(bin_len, sodium_base64_VARIANT_ORIGINAL);
|
||||
@@ -32,23 +30,23 @@ int base64_encode(const unsigned char *bin, size_t bin_len, string &encoded_stri
|
||||
// Assign the encoded char* onto the provided string reference.
|
||||
// "base64_len - 1" because sodium include '\0' in the calculated base64 length.
|
||||
// Therefore we need to omit it when initializing the std::string.
|
||||
encoded_string = string(base64chars, base64_len - 1);
|
||||
encoded_string = std::string(base64chars, base64_len - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes provided base64 string into bytes.
|
||||
*
|
||||
* @param decodedbuf Buffer to assign decoded bytes.
|
||||
* @param decodedbuf_len Decoded buffer size.
|
||||
* @param base64_str Base64 string to decode.
|
||||
* @param decoded Decoded bytes.
|
||||
* @param decoded_len Decoded bytes length.
|
||||
*/
|
||||
int base64_decode(const string &base64_str, unsigned char *decoded, size_t decoded_len)
|
||||
int base64_decode(unsigned char *decodedbuf, size_t decodedbuf_len, const std::string &base64_str)
|
||||
{
|
||||
const char *b64_end;
|
||||
size_t bin_len;
|
||||
if (sodium_base642bin(
|
||||
decoded, decoded_len,
|
||||
decodedbuf, decodedbuf_len,
|
||||
base64_str.data(), base64_str.size() + 1,
|
||||
"", &bin_len, &b64_end,
|
||||
sodium_base64_VARIANT_ORIGINAL))
|
||||
@@ -66,9 +64,9 @@ int base64_decode(const string &base64_str, unsigned char *decoded, size_t decod
|
||||
* v1 > v2 -> returns +1
|
||||
* Error -> returns -2
|
||||
*/
|
||||
int version_compare(const string &x, const string &y)
|
||||
int version_compare(const std::string &x, const std::string &y)
|
||||
{
|
||||
istringstream ix(x), iy(y);
|
||||
std::istringstream ix(x), iy(y);
|
||||
while (ix.good() || iy.good())
|
||||
{
|
||||
int cx = 0, cy = 0;
|
||||
|
||||
18
src/util.hpp
18
src/util.hpp
@@ -4,8 +4,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Contains helper functions and data structures used by multiple other subsystems.
|
||||
*/
|
||||
@@ -39,12 +37,12 @@ enum SESSION_FLAG
|
||||
*/
|
||||
struct contract_user
|
||||
{
|
||||
string pubkeyb64; // Base64 user public key
|
||||
std::string pubkeyb64; // Base64 user public key
|
||||
int inpipe[2]; // Pipe to receive user input
|
||||
int outpipe[2]; // Pipe to receive output produced by the contract
|
||||
string outbuffer; // Holds the contract output to be processed by consensus rounds
|
||||
std::string outbuffer; // Holds the contract output to be processed by consensus rounds
|
||||
|
||||
contract_user(const string &_pubkeyb64, int _inpipe[2], int _outpipe[2])
|
||||
contract_user(const std::string &_pubkeyb64, int _inpipe[2], int _outpipe[2])
|
||||
{
|
||||
pubkeyb64 = _pubkeyb64;
|
||||
inpipe[0] = _inpipe[0];
|
||||
@@ -59,11 +57,11 @@ struct contract_user
|
||||
*/
|
||||
struct peer_node
|
||||
{
|
||||
string pubkeyb64; // Base64 peer public key
|
||||
std::string pubkeyb64; // Base64 peer public key
|
||||
int inpipe[2]; // NPL pipe from HP to SC
|
||||
int outpipe[2]; // NPL pipe from SC to HP
|
||||
|
||||
peer_node(const string &_pubkeyb64, int _inpipe[2], int _outpipe[2])
|
||||
peer_node(const std::string &_pubkeyb64, int _inpipe[2], int _outpipe[2])
|
||||
{
|
||||
pubkeyb64 = _pubkeyb64;
|
||||
inpipe[0] = _inpipe[0];
|
||||
@@ -73,11 +71,11 @@ struct peer_node
|
||||
}
|
||||
};
|
||||
|
||||
int base64_encode(const unsigned char *bin, size_t bin_len, string &encoded_string);
|
||||
int base64_encode(std::string &encoded_string, const unsigned char *bin, size_t bin_len);
|
||||
|
||||
int base64_decode(const string &base64_str, unsigned char *decoded, size_t decoded_len);
|
||||
int base64_decode(unsigned char *decoded, size_t decoded_len, const std::string &base64_str);
|
||||
|
||||
int version_compare(const string &v1, const string &v2);
|
||||
int version_compare(const std::string &v1, const std::string &v2);
|
||||
|
||||
} // namespace util
|
||||
|
||||
|
||||
Reference in New Issue
Block a user