Committing updates.

This commit is contained in:
Преподобный Ален
2021-09-17 15:04:26 +03:00
parent e758e8d8dc
commit f4f4d104cf
136 changed files with 46883 additions and 79 deletions

1441
src/app/Bitcoin.cpp Normal file

File diff suppressed because it is too large Load Diff

733
src/app/Bitcoin.hpp Normal file
View File

@@ -0,0 +1,733 @@
/*++
Module Name:
Bitcoin.hpp
Notices:
Bitcoin library
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_BITCOIN_HPP
#define APOSTOL_BITCOIN_HPP
#ifdef BITCOIN_VERSION_4
//#include <bitcoin/system.hpp>
#include <bitcoin/system/formats/base_10.hpp>
#include <bitcoin/system/formats/base_16.hpp>
#include <bitcoin/system/formats/base_32.hpp>
#include <bitcoin/system/formats/base_58.hpp>
#include <bitcoin/system/formats/base_64.hpp>
#include <bitcoin/system/formats/base_85.hpp>
#include <bitcoin/system/config/base16.hpp>
#include <bitcoin/system/wallet/message.hpp>
#include <bitcoin/system/wallet/payment_address.hpp>
#include <bitcoin/system/wallet/witness_address.hpp>
#include <bitcoin/system/wallet/ek_token.hpp>
#include <bitcoin/system/wallet/ek_public.hpp>
#include <bitcoin/system/wallet/encrypted_keys.hpp>
#include <bitcoin/system/config/script.hpp>
#include <bitcoin/client/history.hpp>
#include <bitcoin/client/stealth.hpp>
using namespace bc;
using namespace bc::system;
using namespace bc::system::config;
using namespace bc::system::wallet;
using namespace bc::client;
#else
#ifdef BITCOIN_VERSION_3_7_x
#include <bitcoin/system.hpp>
#else
#include <bitcoin/bitcoin.hpp>
#endif
#include <bitcoin/protocol.hpp>
#include <bitcoin/client/define.hpp>
#include <bitcoin/client/obelisk_client.hpp>
#include <bitcoin/client/version.hpp>
using namespace bc;
using namespace bc::chain;
using namespace bc::machine;
using namespace bc::config;
using namespace bc::wallet;
using namespace bc::client;
#endif
//----------------------------------------------------------------------------------------------------------------------
#define BX_EK_PUBLIC_TO_EC_INVALID_PASSPHRASE \
"The passphrase is incorrect."
#define BX_EK_ADDRESS_SHORT_SEED \
"The seed is less than 192 bits long."
#define BX_TOKEN_NEW_SHORT_SALT \
"The salt is less than 32 bits long."
#define BX_TOKEN_NEW_REQUIRES_ICU \
"The command requires an ICU build."
#define BX_CONNECTION_FAILURE \
"Could not connect to server: %1%"
#define BX_HD_NEW_SHORT_SEED \
"The seed is less than 128 bits long."
#define BX_HD_NEW_INVALID_KEY \
"The seed produced an invalid key."
//----------------------------------------------------------------------------------------------------------------------
#define BX_NO_TRANSFERS_FOUND "No transfers found on account: %s."
#define BX_INVALID_SECRET_KEY_COUNT "Invalid count of secret keys (2 or 3 expected)."
#define BX_INSUFFICIENT_FUNDS "Insufficient funds on account: %s."
#define BX_INSUFFICIENT_FEE "Insufficient transaction fee on account: %s."
//----------------------------------------------------------------------------------------------------------------------
/**
* The minimum safe length of a seed in bits (multiple of 8).
*/
BC_CONSTEXPR size_t minimum_seed_bits = 128;
/**
* The minimum safe length of a seed in bytes (16).
*/
BC_CONSTEXPR size_t minimum_seed_size = minimum_seed_bits / bc::byte_bits;
//----------------------------------------------------------------------------------------------------------------------
extern "C++" {
namespace Apostol {
namespace Bech32
{
/** Encode a Bech32 string. Returns the empty string in case of failure. */
std::string encode(const std::string& hrp, const std::vector<uint8_t>& values);
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */
std::pair<std::string, std::vector<uint8_t> > decode(const std::string& str);
}
namespace SegWit
{
/** Decode a SegWit address. Returns (witver, witprog). witver = -1 means failure. */
std::pair<int, std::vector<uint8_t> > decode(const std::string& hrp, const std::string& addr);
/** Encode a SegWit address. Empty string means failure. */
std::string encode(const std::string& hrp, int witver, const std::vector<uint8_t>& witprog);
uint32_t checksum(const std::string& hrp, int witver, const std::vector<uint8_t>& witprog);
}
namespace Bitcoin {
typedef TList<ec_private> CPrivateList;
//--------------------------------------------------------------------------------------------------------------
struct CTransactionFee {
CString Fee;
uint_t min;
uint_t max;
};
struct CBitcoinConfig {
std::string endpoint = "tcp://mainnet.libbitcoin.net:9091";
uint64_t version_hd = hd_private::mainnet;
uint16_t version_ec = ec_private::mainnet;
uint8_t version_key = payment_address::mainnet_p2kh;
uint8_t version_script = payment_address::mainnet_p2sh;
CTransactionFee Miner {"1%", 200, 2000};
uint_t min_output = 200;
CString Symbol = "BTC";
};
//--------------------------------------------------------------------------------------------------------------
extern CBitcoinConfig BitcoinConfig;
//--------------------------------------------------------------------------------------------------------------
enum CAddressDecodeType { adtInfo, adtHtml, adtJson };
std::string string_to_hex(const std::string& input);
std::string hex_to_string(const std::string& input);
//--------------------------------------------------------------------------------------------------------------
std::string sha1(const std::string &value);
CString sha1(const CString &Value);
//--------------------------------------------------------------------------------------------------------------
std::string sha256(const std::string &value);
CString sha256(const CString &Value);
//--------------------------------------------------------------------------------------------------------------
std::string ripemd160(const std::string &value);
CString ripemd160(const CString &Value);
//--------------------------------------------------------------------------------------------------------------
double satoshi_to_btc(uint64_t Value);
uint64_t btc_to_satoshi(double Value);
//--------------------------------------------------------------------------------------------------------------
bool valid_address(const CString& Address);
//--------------------------------------------------------------------------------------------------------------
bool valid_public_key(const std::string& key);
bool valid_public_key(const CString& Key);
//--------------------------------------------------------------------------------------------------------------
bool key_belongs_address(const std::string& key, const std::string& address);
bool key_belongs_address(const CString& Key, const CString& Address);
//--------------------------------------------------------------------------------------------------------------
bool address_decode(CAddressDecodeType type, const CString& Address, CString& Result);
//--------------------------------------------------------------------------------------------------------------
bool address_decode(const CString& Address, CJSON& Result);
bool address_decode(const CString& Address, CString& Result);
//--------------------------------------------------------------------------------------------------------------
bool unwrap_legacy(wallet::wrapped_data &data, const wallet::payment_address &address);
bool unwrap_legacy(wallet::wrapped_data &data, const std::string &address);
//--------------------------------------------------------------------------------------------------------------
bool unwrap_segwit(wallet::wrapped_data &data, const std::string &address);
//--------------------------------------------------------------------------------------------------------------
bool IsLegacyAddress(const std::string& address);
bool IsLegacyAddress(const CString& Address);
bool IsSegWitAddress(const std::string& addr);
bool IsSegWitAddress(const CString& Addr);
bool IsBitcoinAddress(const std::string& addr);
bool IsBitcoinAddress(const CString& Addr);
//--------------------------------------------------------------------------------------------------------------
wallet::ek_token token_new(const std::string &passphrase, const data_chunk& salt);
wallet::ek_public ek_public(const wallet::ek_token &token, const data_chunk& seed, uint8_t version = payment_address::mainnet_p2kh);
wallet::ec_public ek_public_to_ec(const std::string &passphrase, const wallet::ek_public &key);
wallet::payment_address ek_address(const wallet::ek_token &token, const data_chunk& seed, uint8_t version = payment_address::mainnet_p2kh);
//--------------------------------------------------------------------------------------------------------------
wallet::hd_private hd_new(const data_chunk& seed, uint64_t prefixes = hd_private::mainnet);
wallet::ec_private hd_to_ec_private(const wallet::hd_key& key, uint64_t prefixes = hd_private::mainnet);
wallet::ec_public hd_to_ec_public(const wallet::hd_key& key, uint32_t prefix = hd_public::mainnet);
//--------------------------------------------------------------------------------------------------------------
bool verify_message(const std::string& msg, const std::string& addr, const std::string& sig);
bool VerifyMessage(const CString& Message, const CString& Address, const CString& Signature);
//--------------------------------------------------------------------------------------------------------------
#ifdef BITCOIN_VERSION_4
std::string address_to_key(const wallet::payment_address &address);
#endif
chain::script get_witness_script(const ec_public& key1, const ec_public& key2, const ec_public& key3);
chain::script get_redeem_script(const ec_public& key1, const ec_public& key2, const ec_public& key3);
std::string script_to_address(const chain::script &script, uint8_t version = payment_address::mainnet_p2sh);
std::string script_to_address(const std::string &script, uint8_t version = payment_address::mainnet_p2sh);
//--------------------------------------------------------------------------------------------------------------
#ifdef WITH_BITCOIN_CLIENT
uint64_t fetch_balance(const wallet::payment_address &address);
//--------------------------------------------------------------------------------------------------------------
void fetch_history(const wallet::payment_address &address, CJSON& Result);
void fetch_header(uint32_t height, CJSON& Result);
void fetch_header(const hash_digest& hash, CJSON& Result);
void send_tx(const chain::transaction& tx, CJSON& Result);
void send_tx(const std::string& hex, CJSON& Result);
//--------------------------------------------------------------------------------------------------------------
//-- CBalance --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CBalance {
private:
uint32_t m_Transfers;
uint32_t m_Height;
uint32_t m_Received;
uint32_t m_Spent;
CDateTime m_TimeStamp;
protected:
CJSON m_History;
CJSON m_Header;
public:
CBalance() {
m_Transfers = 0;
m_Height = 0;
m_Received = 0;
m_Spent = 0;
m_TimeStamp = 0;
}
void Clear();
void Fetch(const CString &Address);
const CJSON &History() const { return m_History; };
const CJSON &Header() const { return m_Header; };
uint32_t Transfers() const { return m_Transfers; }
uint32_t Height() const { return m_Height; }
CDateTime TimeStamp() const { return m_TimeStamp; }
uint32_t Received() const { return m_Received; }
uint32_t Spent() const { return m_Spent; }
uint32_t Balance() const {
return m_Received - m_Spent;
}
};
#endif
//--------------------------------------------------------------------------------------------------------------
//-- CWitness --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CWitness {
private:
std::vector<ec_private> m_secrets;
std::vector<ec_public> m_keys;
uint8_t m_signatures;
hash_digest m_hash;
chain::script m_script;
chain::script m_embedded;
void bind_script();
void bind_embedded();
public:
CWitness();
explicit CWitness(uint8_t signatures);
CWitness(const ec_private& key1, const ec_private& key2);
CWitness(const ec_private& key1, const ec_private& key2, const ec_private& key3);
CWitness(const ec_private& key1, const ec_private& key2, const ec_public& key3);
CWitness(const ec_private& key1, const ec_private& key2, const ec_private& key3, const ec_public& key4);
CWitness(const ec_public& key1, const ec_public& key2, const ec_public& key3);
void make(const ec_private& key1, const ec_private& key2);
void make(const ec_private& key1, const ec_private& key2, const ec_private& key3);
void make(const ec_private& key1, const ec_private& key2, const ec_public& key3);
void make(const ec_private& key1, const ec_private& key2, const ec_private& key3, const ec_public& key4);
void make(const ec_public& key1, const ec_public& key2, const ec_public& key3);
void bind();
const hash_digest& hash() const;
const chain::script& script() const { return m_script; };
const chain::script& embedded() const {return m_embedded; };
payment_address to_address(uint8_t version = payment_address::mainnet_p2sh) const;
const std::vector<ec_private> &secrets() const { return m_secrets; };
const std::vector<ec_public> &keys() const { return m_keys; };
};
//--------------------------------------------------------------------------------------------------------------
//-- CRecipient ------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
typedef struct CRecipient {
CString Address {};
uint64_t Amount;
CRecipient() {
Amount = 0;
}
CRecipient(const CRecipient &Other) {
if (this != &Other) {
this->Address = Other.Address;
this->Amount = Other.Amount;
}
};
CRecipient(const CString &Address, uint64_t Amount) {
this->Address = Address;
this->Amount = Amount;
}
CRecipient &operator=(const CRecipient &Other) {
if (this != &Other) {
this->Address = Other.Address;
this->Amount = Other.Amount;
}
return *this;
};
inline bool operator!=(const CRecipient &Value) { return Address != Value.Address; };
inline bool operator==(const CRecipient &Value) { return Address == Value.Address; };
} CRecipient, *PRecipient;
//--------------------------------------------------------------------------------------------------------------
typedef TList<CRecipient> CRecipients;
//--------------------------------------------------------------------------------------------------------------
//-- raw -------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
/**
* Serialization helper to convert between a byte stream and data_chunk.
*/
class raw
{
public:
/**
* Default constructor.
*/
raw();
/**
* Initialization constructor.
* @param[in] text The value to initialize with.
*/
raw(const std::string& text);
/**
* Initialization constructor.
* @param[in] value The value to initialize with.
*/
raw(data_chunk value);
/**
* Copy constructor.
* @param[in] other The object to copy into self on construct.
*/
raw(const raw& other);
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator const data_chunk&() const;
/**
* Overload cast to generic data reference.
* @return This object's value cast to a generic data reference.
*/
operator data_slice() const;
/**
* Overload stream in. Throws if input is invalid.
* @param[in] input The input stream to read the value from.
* @param[out] argument The object to receive the read value.
* @return The input stream reference.
*/
friend std::istream& operator>>(std::istream& input,
raw& argument);
/**
* Overload stream out.
* @param[in] output The output stream to write the value to.
* @param[out] argument The object from which to obtain the value.
* @return The output stream reference.
*/
friend std::ostream& operator<<(std::ostream& output,
const raw& argument);
private:
/**
* The state of this object's raw data.
*/
data_chunk value_;
};
class wrapper
{
public:
/**
* Default constructor.
*/
wrapper();
/**
* Initialization constructor.
*
* @param[in] wrapped The value to initialize with.
*/
wrapper(const std::string& wrapped);
/**
* Initialization constructor.
* @param[in] wrapped The wrapped value to initialize with.
*/
wrapper(const data_chunk& wrapped);
/**
* Initialization constructor.
* @param[in] wrapped The wrapped value to initialize with.
*/
wrapper(const wallet::wrapped_data& wrapped);
/**
* Initialization constructor.
* @param[in] address The payment address to initialize with.
*/
wrapper(const wallet::payment_address& address);
/**
* Initialization constructor.
* @param[in] version The version for the new wrapped value.
* @param[in] payload The payload for the new wrapped value.
*/
wrapper(uint8_t version, const data_chunk& payload);
/**
* Copy constructor.
* @param[in] other The object to copy into self on construct.
*/
wrapper(const wrapper& other);
/**
* Serialize the wrapper to bytes according to the wire protocol.
* @return The byte serialized copy of the wrapper.
*/
const data_chunk to_data() const;
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator const wallet::wrapped_data&() const;
/**
* Overload stream in. Throws if input is invalid.
* @param[in] input The input stream to read the value from.
* @param[out] argument The object to receive the read value.
* @return The input stream reference.
*/
friend std::istream& operator>>(std::istream& input,
wrapper& argument);
/**
* Overload stream out.
* @param[in] output The output stream to write the value to.
* @param[out] argument The object from which to obtain the value.
* @return The output stream reference.
*/
friend std::ostream& operator<<(std::ostream& output,
const wrapper& argument);
private:
/**
* The state of this object's data.
*/
wallet::wrapped_data value_;
};
/**
* Serialization helper to convert between string and message_signature.
*/
class signature
{
public:
/**
* Default constructor.
*/
signature();
/**
* Initialization constructor.
* @param[in] hexcode The value to initialize with.
*/
signature(const std::string& hexcode);
/**
* Initialization constructor.
* @param[in] value The value to initialize with.
*/
signature(const wallet::message_signature& value);
/**
* Copy constructor.
* @param[in] other The object to copy into self on construct.
*/
signature(const signature& other);
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator wallet::message_signature&();
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator const wallet::message_signature&() const;
/// Serializer.
std::string encoded() const;
/**
* Overload stream in. If input is invalid sets no bytes in argument.
* @param[in] input The input stream to read the value from.
* @param[out] argument The object to receive the read value.
* @return The input stream reference.
*/
friend std::istream& operator>>(std::istream& input, signature& argument);
/**
* Overload stream out.
* @param[in] output The output stream to write the value to.
* @param[out] argument The object from which to obtain the value.
* @return The output stream reference.
*/
friend std::ostream& operator<<(std::ostream& output, const signature& argument);
private:
/**
* The state of this object.
*/
wallet::message_signature value_;
};
/**
* Serialization helper to convert between base16/raw script and script_type.
*/
class script
{
public:
/**
* Default constructor.
*/
script();
/**
* Initialization constructor.
* @param[in] mnemonic The value to initialize with.
*/
script(const std::string& mnemonic);
/**
* Initialization constructor.
* @param[in] value The value to initialize with.
*/
script(const chain::script& value);
/**
* Initialization constructor.
* @param[in] value The value to initialize with.
*/
script(const data_chunk& value);
/**
* Initialization constructor.
* @param[in] tokens The mnemonic tokens to initialize with.
*/
script(const std::vector<std::string>& tokens);
/**
* Copy constructor.
* @param[in] other The object to copy into self on construct.
*/
script(const script& other);
/**
* Serialize the script to bytes according to the wire protocol.
* @return The byte serialized copy of the script.
*/
const bc::data_chunk to_data() const;
/**
* Return a pretty-printed copy of the script.
* @return A mnemonic-printed copy of the internal script.
*/
const std::string to_string() const;
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator const chain::script&() const;
/**
* Overload stream in. Throws if input is invalid.
* @param[in] input The input stream to read the value from.
* @param[out] argument The object to receive the read value.
* @return The input stream reference.
*/
friend std::istream& operator>>(std::istream& input,
script& argument);
/**
* Overload stream out.
* @param[in] output The output stream to write the value to.
* @param[out] argument The object from which to obtain the value.
* @return The output stream reference.
*/
friend std::ostream& operator<<(std::ostream& output,
const script& argument);
private:
/**
* The state of this object.
*/
chain::script value_;
};
} // namespace Bitcoin
} // namespace Apostol
using namespace Apostol::Bitcoin;
using namespace Apostol::Bech32;
using namespace Apostol::SegWit;
}
#endif //APOSTOL_BITCOIN_HPP

532
src/app/Deal.cpp Normal file
View File

@@ -0,0 +1,532 @@
/*++
Program name:
BitDeals
Module Name:
Deal.cpp
Notices:
Apostol Core (Deal)
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#include "Core.hpp"
#include "Deal.hpp"
//----------------------------------------------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C++" {
#endif // __cplusplus
namespace Apostol {
namespace Deal {
CString UTCFormat(const CString& Value) {
return Value.SubString(0, 19) << " UTC";
}
//--------------------------------------------------------------------------------------------------------------
CString BTCFormat(const CString& Value) {
if (Value.Find(BitcoinConfig.Symbol) == CString::npos)
return Value.TrimRight('0') << " " << BitcoinConfig.Symbol;
return Value.TrimRight('0');
}
//--------------------------------------------------------------------------------------------------------------
double BTCToDouble(const CString &Value) {
const size_t Pos = Value.Find(BitcoinConfig.Symbol);
if (Pos == CString::npos)
return StrToDouble(Value.c_str());
return StrToDouble(Value.SubString(0, Pos).TrimRight().c_str());
}
//--------------------------------------------------------------------------------------------------------------
CString DoubleToBTC(const double &Value, const CString &Format) {
TCHAR Buffer[25] = {0};
FloatToStr(Value, Buffer, sizeof(Buffer), Format.c_str());
return Buffer;
}
//--------------------------------------------------------------------------------------------------------------
CDateTime StringToDate(const CString &Value, const CString &Format) {
return StrToDateTimeDef(Value.c_str(), 0, Format.c_str());
}
//--------------------------------------------------------------------------------------------------------------
CString DateToString(const CDateTime &Value, const CString &Format) {
TCHAR Buffer[25] = {0};
DateTimeToStr(Value, Buffer, sizeof(Buffer), Format.c_str());
return Buffer;
}
//--------------------------------------------------------------------------------------------------------------
//-- DealData --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
CString DealData::GetStringData() const {
CString Data;
Data.Format("Type: %d;", (int) Type);
Data.Format("URL: %s;", At.c_str());
Data.Format("Date: %s;", Date.c_str());
Data.Format("Seller: %s;", Seller.Address.c_str());
Data.Format("Customer: %s;", Customer.Address.c_str());
Data.Format("Until: %s;", Payment.Until.c_str());
Data.Format("Sum: %s;", Payment.Sum.c_str());
Data.Format("LeaveBefore: %s", FeedBack.LeaveBefore.c_str());
return Data;
}
//--------------------------------------------------------------------------------------------------------------
//-- CRating ---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
void CRating::Parse(const CString &Value) {
size_t Pos = 0;
TCHAR ch = Value.at(Pos++);
if (Value.Size() < 4 || !IsNumeral(ch))
throw ExceptionFrm("Invalid rating value.");
CString Item;
while (!IsCtl(ch)) {
if (ch == '+' && !Item.IsEmpty()) {
Count = StrToIntDef(Item.c_str(), 0);
Count++;
Item.Clear();
} else if (ch == ',' && !Item.IsEmpty()) {
Count = StrToIntDef(Item.c_str(), 0);
Item.Clear();
} else if (ch == '%' && !Item.IsEmpty()) {
Positive = StrToIntDef(Item.c_str(), 0);
Item.Clear();
} else {
if (!(ch == ' ' || ch == ',')) {
if (!IsNumeral(ch))
throw ExceptionFrm("Invalid rating value.");
Item << ch;
}
}
ch = Value.at(Pos++);
}
}
//--------------------------------------------------------------------------------------------------------------
//-- CDeal -----------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
CDeal::CDeal() {
m_Data.Order = doCreate;
m_Data.FeedBack.Status = fsPositive;
}
//--------------------------------------------------------------------------------------------------------------
CDeal::CDeal(const YAML::Node &node) : CDeal() {
Parse(node);
}
//--------------------------------------------------------------------------------------------------------------
CDealOrder CDeal::StringToOrder(const CString &Value) {
const CString &S = Value.Lower();
if (S == "create") {
return doCreate;
} else if (S == "created") {
return doCreated;
} else if (S == "pay") {
return doPay;
} else if (S == "paid") {
return doPaid;
} else if (S == "complete") {
return doComplete;
} else if (S == "completed") {
return doCompleted;
} else if (S == "cancel") {
return doCancel;
} else if (S == "canceled") {
return doCanceled;
} else if (S == "execute") {
return doExecute;
} else if (S == "executed") {
return doExecuted;
} else if (S == "delete") {
return doDelete;
} else if (S == "deleted") {
return doDeleted;
} else if (S == "fail") {
return doFail;
} else if (S == "failed") {
return doFailed;
} else if (S == "feedback") {
return doFeedback;
} else {
throw ExceptionFrm("Invalid deal order value: \"%s\".", Value.c_str());
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::OrderToString(CDealOrder Order) {
switch (Order) {
case doCreate:
return "Create";
case doCreated:
return "Created";
case doPay:
return "Pay";
case doPaid:
return "Paid";
case doComplete:
return "Complete";
case doCompleted:
return "Completed";
case doCancel:
return "Cancel";
case doCanceled:
return "Canceled";
case doExecute:
return "Execute";
case doExecuted:
return "Executed";
case doDelete:
return "Delete";
case doDeleted:
return "Deleted";
case doFail:
return "Fail";
case doFailed:
return "Failed";
case doFeedback:
return "Feedback";
default:
return "Unknown";
}
}
//--------------------------------------------------------------------------------------------------------------
CDealType CDeal::StringToType(const CString &Value) {
const auto &status = Value.Lower();
if (status.Find("prepaid") != CString::npos || status.Find("prepayment") != CString::npos) {
return dtPrepaid;
} else if (status.Find("postpaid") != CString::npos || status.Find("postpayment") != CString::npos) {
return dtPostpaid;
} else {
throw ExceptionFrm(R"(Invalid order type value: "%s".)", status.c_str());
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::TypeToString(CDealType Type) {
switch (Type) {
case dtPrepaid:
return "Prepaid";
case dtPostpaid:
return "Postpaid";
default:
return "Unknown";
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::TypeCodeToString(const CString &Code) {
if (Code == "prepaid.deal") {
return CString("Prepaid");
} else if (Code == "postpaid.deal") {
return CString("Postpaid");
} else {
throw ExceptionFrm(R"(Invalid type code value: "%s".)", Code.c_str());
}
}
//--------------------------------------------------------------------------------------------------------------
CFeedBackStatus CDeal::StringToFeedBackStatus(const CString &Value) {
const CString &Status = Value.Lower();
if (Status == "negative") {
return fsNegative;
} else if (Status == "neutral") {
return fsNeutral;
} else if (Status == "positive") {
return fsPositive;
} else {
throw ExceptionFrm(R"(Invalid feedback status value: "%s".)", Status.c_str());
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::FeedBackStatusToString(CFeedBackStatus Status) {
switch (Status) {
case fsNegative:
return "Negative";
case fsNeutral:
return "Neutral";
case fsPositive:
return "Positive";
default:
return "Unknown";
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetHashData() {
return m_Data.GetStringData();
}
//--------------------------------------------------------------------------------------------------------------
std::string CDeal::get_hash() {
const std::string str(GetHashData().c_str());
return sha256(str);
}
//--------------------------------------------------------------------------------------------------------------
std::string CDeal::get_code() {
const std::string value(GetHashData().c_str());
const auto& hex = string_to_hex(value);
const config::base16 data(hex);
const auto& hash = ripemd160_hash(sha256_hash(data));
return encode_base16(hash);
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetCode() {
return get_code();
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetHash() {
return sha256(GetHashData());
}
//--------------------------------------------------------------------------------------------------------------
wallet::ec_public CDeal::to_public_ek(uint8_t version) {
const auto& hash = get_hash();
const std::string seed(hash.substr(0, 48));
const std::string salt(hash.substr(48, 16));
const auto& token = Bitcoin::token_new(hash, base16(salt));
const auto& key = Bitcoin::ek_public(token, base16(seed), version);
return ek_public_to_ec(hash, key);
}
//--------------------------------------------------------------------------------------------------------------
wallet::payment_address CDeal::to_address_ek(uint8_t version) {
const auto& hash = get_hash();
const std::string seed(hash.substr(0, 48));
const std::string salt(hash.substr(48, 16));
const auto& token = Bitcoin::token_new(hash, base16(salt));
return Bitcoin::ek_address(token, base16(seed), version);
}
//--------------------------------------------------------------------------------------------------------------
wallet::ec_public CDeal::to_public_hd(uint64_t prefixes) {
const auto& hash = get_hash();
const auto& key = hd_new(base16(hash), prefixes);
const auto& public_key = key.to_public();
return public_key.point();
}
//--------------------------------------------------------------------------------------------------------------
wallet::payment_address CDeal::to_address_hd(uint64_t prefixes) {
const auto& key = to_public_hd(prefixes);
return key.to_payment_address();
}
//--------------------------------------------------------------------------------------------------------------
std::string CDeal::get_payment_ek(const std::string &key1, const std::string &key2, std::string &key3,
uint8_t version_key, uint8_t version_script) {
CWitness Witness(ec_public(key1), ec_public(key2), key3.empty() ? to_public_ek(version_key) : ec_public(key3));
if (key3.empty())
key3 = Witness.keys()[2].encoded();
const auto& address = Witness.to_address(version_script);
return address.encoded();
}
//--------------------------------------------------------------------------------------------------------------
std::string CDeal::get_payment_hd(const std::string &key1, const std::string &key2, std::string &key3,
uint64_t version_key, uint8_t version_script) {
CWitness Witness(ec_public(key1), ec_public(key2), key3.empty() ? to_public_hd(version_key) : ec_public(key3));
if (key3.empty())
key3 = Witness.keys()[2].encoded();
const auto& address = Witness.to_address(version_script);
return address.encoded();
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetPaymentEK(const CString &Key1, const CString &Key2, CString &Key3,
uint8_t version_key, uint8_t version_script) {
std::string key3(Key3);
const auto& payment = get_payment_ek(Key1.c_str(), Key2.c_str(), key3, version_key, version_script);
Key3 = key3;
return payment;
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetPaymentHD(const CString &Key1, const CString &Key2, CString &Key3, uint64_t version_key,
uint8_t version_script) {
std::string key3(Key3);
const auto& payment = get_payment_hd(Key1.c_str(), Key2.c_str(), key3, version_key, version_script);
Key3 = key3;
return payment;
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::Parse(const YAML::Node &node) {
const auto& deal = node["deal"];
if (deal) {
m_Data.Order = StringToOrder(deal["order"].as<std::string>());
m_Data.Type = StringToType(deal["type"].as<std::string>());
m_Data.At = deal["at"].as<std::string>();
m_Data.Date = UTCFormat(deal["date"].as<std::string>());
const auto& seller = deal["seller"];
m_Data.Seller.Address = seller["address"].as<std::string>();
if (!valid_address(m_Data.Seller.Address))
throw ExceptionFrm("Invalid seller address: %s.", m_Data.Seller.Address.c_str());
if (seller["rating"])
m_Data.Seller.Rating = seller["rating"].as<std::string>();
if (seller["signature"])
m_Data.Seller.Signature = seller["signature"].as<std::string>();
const auto& customer = deal["customer"];
m_Data.Customer.Address = customer["address"].as<std::string>();
if (!valid_address(m_Data.Customer.Address))
throw ExceptionFrm("Invalid customer address: %s.", m_Data.Customer.Address.c_str());
if (customer["rating"])
m_Data.Customer.Rating = customer["rating"].as<std::string>();
if (customer["signature"])
m_Data.Customer.Signature = customer["signature"].as<std::string>();
const auto& payment = deal["payment"];
if (payment) {
if (payment["address"])
m_Data.Payment.Address = payment["address"].as<std::string>();
if (payment["until"])
m_Data.Payment.Until = UTCFormat(payment["until"].as<std::string>());
m_Data.Payment.Sum = BTCFormat(payment["sum"].as<std::string>());
}
const auto& feedback = deal["feedback"];
if (feedback) {
if (feedback["leave-before"])
m_Data.FeedBack.LeaveBefore = UTCFormat(feedback["leave-before"].as<std::string>());
if (feedback["status"])
m_Data.FeedBack.Status = StringToFeedBackStatus(feedback["status"].as<std::string>());
if (feedback["refund"])
m_Data.FeedBack.Refund = feedback["refund"].as<std::string>();
if (feedback["comments"])
m_Data.FeedBack.Comments = feedback["comments"].as<std::string>();
}
const auto& transaction = deal["transaction"];
if (transaction) {
m_Data.Transaction.Hex = transaction["hex"].as<std::string>();
}
const auto& error = deal["error"];
if (error) {
m_Data.Error.Message = error["message"].as<std::string>();
}
const CDateTime Date = StringToDate(m_Data.Date);
if (m_Data.Payment.Until.IsEmpty())
m_Data.Payment.Until = DateToString(Date + (CDateTime) 3600 / SecsPerDay); // 60 min
if (m_Data.FeedBack.LeaveBefore.IsEmpty())
m_Data.FeedBack.LeaveBefore = DateToString(Date + 1);
m_Data.Code = GetCode();
} else
throw ExceptionFrm("Invalid YAML format: Need node \"deal\".");
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::SetOrder(YAML::Node &Node, CDealOrder Order) {
Node["deal"]["order"] = CDeal::OrderToString(Order).c_str();
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::AddFeedback(YAML::Node &Node, CFeedBackStatus Status, const CString &Comments) {
YAML::Node Deal = Node["deal"];
YAML::Node Feedback = Deal["feedback"];
Feedback["status"] = CDeal::FeedBackStatusToString(Status).c_str();
if (!Comments.IsEmpty())
Feedback["comments"] = Comments.c_str();
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::AddTransaction(YAML::Node &Node, const transaction &tx) {
YAML::Node Deal = Node["deal"];
YAML::Node Transaction = Deal["transaction"];
const auto& hex = encode_base16(tx.to_data(true, true));
Transaction["hex"] = hex;
DebugMessage("tx: %s\n", hex.c_str());
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::AddError(YAML::Node &Node, const CString &Message) {
YAML::Node Deal = Node["deal"];
YAML::Node Error = Deal["error"];
Error["message"] = Message.c_str();
}
}
}
using namespace Apostol::Deal;
#ifdef __cplusplus
}
#endif // __cplusplus

308
src/app/Deal.hpp Normal file
View File

@@ -0,0 +1,308 @@
/*++
Program name:
BitDeals
Module Name:
Deal.hpp
Notices:
Apostol Core (Deal)
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_DEAL_HPP
#define APOSTOL_DEAL_HPP
#include "yaml-cpp/yaml.h"
//----------------------------------------------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C++" {
#endif // __cplusplus
namespace Apostol {
namespace Deal {
CString UTCFormat(const CString& Value);
CString BTCFormat(const CString& Value);
//--------------------------------------------------------------------------------------------------------------
double BTCToDouble(const CString &Value);
CString DoubleToBTC(const double &Value, const CString &Format = _T("%f BTC"));
CDateTime StringToDate(const CString &Value, const CString &Format = _T("%04d-%02d-%02d %02d:%02d:%02d"));
CString DateToString(const CDateTime &Value, const CString &Format = _T("%Y-%m-%d %H:%M:%S UTC"));
//--------------------------------------------------------------------------------------------------------------
//-- CRating ---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
typedef struct CRating {
int Count;
int Positive;
CRating(): Count(0), Positive(0) {
}
CRating(const CRating &Rating): CRating() {
Assign(Rating);
}
void Assign(const CRating& Rating) {
this->Count = Rating.Count;
this->Positive = Rating.Positive;
};
int Compare(const CRating& Rating) const {
if (this->Count == Rating.Count)
return 0;
if (this->Count > Rating.Count)
return 1;
return -1;
};
void ToString(CString &String) const {
String.Clear();
int q = 1;
int c = Count;
while ((c = div(c, 10).quot > 10))
q++;
c = c * (int) pow(10, q);
if (Count == c)
String.Format("%d, %d%%", c, Positive);
else
String.Format("%d+, %d%%", c, Positive);
}
void Parse(const CString &Value);
CString GetString() const {
CString S;
ToString(S);
return S;
};
bool operator== (const CRating& R) const {
return Compare(R) == 0;
};
bool operator!= (const CRating& R) const {
return Compare(R) != 0;
};
bool operator< (const CRating& R) const {
return Compare(R) < 0;
};
bool operator<= (const CRating& R) const {
return Compare(R) <= 0;
};
bool operator> (const CRating& R) const {
return Compare(R) > 0;
};
bool operator>= (const CRating& R) const {
return Compare(R) >= 0;
};
CRating& operator= (const CRating& R) {
if (this != &R) {
Assign(R);
}
return *this;
};
CRating& operator= (const CString& S) {
Parse(S);
return *this;
};
CRating& operator<< (const CString& S) {
Parse(S);
return *this;
};
friend CString& operator>> (const CRating &LS, CString &RS) {
LS.ToString(RS);
return RS;
}
} CRating;
//--------------------------------------------------------------------------------------------------------------
//-- CDealData -------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
enum CDealType { dtPrepaid = 0, dtPostpaid };
//--------------------------------------------------------------------------------------------------------------
enum CFeedBackStatus { fsNegative = -1, fsNeutral = 0, fsPositive = 1 };
//--------------------------------------------------------------------------------------------------------------
enum CDealOrder { doCreate = 0, doCreated, doPay, doPaid, doComplete, doCompleted, doCancel, doCanceled,
doExecute, doExecuted, doDelete, doDeleted, doFail, doFailed, doFeedback };
//--------------------------------------------------------------------------------------------------------------
typedef struct DealData {
CDealOrder Order = doCreate;
CDealType Type = dtPrepaid;
// Hidden value
CString Code {};
CString At {};
CString Date {};
struct seller {
CString Address;
CRating Rating;
CString Signature;
} Seller;
struct customer {
CString Address;
CRating Rating;
CString Signature;
} Customer;
struct payment {
CString Address {};
CString Until {};
CString Sum {};
} Payment;
struct feedback {
CString LeaveBefore {};
CFeedBackStatus Status = fsNeutral;
CString Refund {};
CString Comments {};
} FeedBack;
struct transaction {
CString Fee {};
CString Key {};
CString Hex {};
} Transaction;
struct error {
CString Message {};
} Error;
CString GetStringData() const;
} CDealData, *PDealData;
//--------------------------------------------------------------------------------------------------------------
//-- CDeal -----------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CDeal {
private:
CDealData m_Data;
CString GetHashData();
protected:
std::string get_hash();
std::string get_code();
wallet::ec_public to_public_ek(uint8_t version = payment_address::mainnet_p2kh);
wallet::payment_address to_address_ek(uint8_t version = payment_address::mainnet_p2kh);
wallet::ec_public to_public_hd(uint64_t prefixes = hd_private::mainnet);
wallet::payment_address to_address_hd(uint64_t prefixes = hd_private::mainnet);
std::string get_payment_ek(const std::string &key1, const std::string &key2, std::string &key3,
uint8_t version_key = payment_address::mainnet_p2kh,
uint8_t version_script = payment_address::mainnet_p2sh);
std::string get_payment_hd(const std::string &key1, const std::string &key2, std::string &key3,
uint64_t version_key = hd_private::mainnet,
uint8_t version_script = payment_address::mainnet_p2sh);
public:
CDeal();
explicit CDeal(const YAML::Node &node);
void Parse(const YAML::Node &node);
CString GetHash();
CString GetCode();
CString GetPaymentEK(const CString &Key1, const CString &Key2, CString &Key3,
uint8_t version_key = payment_address::mainnet_p2kh,
uint8_t version_script = payment_address::mainnet_p2sh);
CString GetPaymentHD(const CString &Key1, const CString &Key2, CString &Key3,
uint64_t version_key = hd_private::mainnet,
uint8_t version_script = payment_address::mainnet_p2sh);
static CDealOrder StringToOrder(const CString &Value);
static CString OrderToString(CDealOrder Order);
static CDealType StringToType(const CString &Value);
static CString TypeToString(CDealType Type);
static CString TypeCodeToString(const CString &Code);
static CFeedBackStatus StringToFeedBackStatus(const CString &Value);
static CString FeedBackStatusToString(CFeedBackStatus Status);
CDealOrder Order() const { return m_Data.Order; }
void Order(CDealOrder Value) { m_Data.Order = Value; }
CDealData &Data() { return m_Data; }
const CDealData &Data() const { return m_Data; }
static void SetOrder(YAML::Node &Node, CDealOrder Order);
static void AddFeedback(YAML::Node &Node, CFeedBackStatus Status, const CString &Comments);
static void AddTransaction(YAML::Node &Node, const transaction &tx);
static void AddError(YAML::Node &Node, const CString &Message);
CDeal& operator<< (const YAML::Node &node) {
Parse(node);
return *this;
}
};
//--------------------------------------------------------------------------------------------------------------
}
}
using namespace Apostol::Deal;
#ifdef __cplusplus
}
#endif // __cplusplus
#endif //APOSTOL_DEAL_HPP

46
src/app/Header.hpp Normal file
View File

@@ -0,0 +1,46 @@
/*++
Program name:
ship-safety
Module Name:
Header.hpp
Notices:
Ship Safety Service
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_HEADER_HPP
#define APOSTOL_HEADER_HPP
//----------------------------------------------------------------------------------------------------------------------
#include <wait.h>
#include <execinfo.h>
//----------------------------------------------------------------------------------------------------------------------
//using namespace std;
//----------------------------------------------------------------------------------------------------------------------
#include "delphi.hpp"
//----------------------------------------------------------------------------------------------------------------------
#include "PGP.hpp"
#include "Bitcoin.hpp"
#include "Deal.hpp"
//----------------------------------------------------------------------------------------------------------------------
#include "Core.hpp"
//----------------------------------------------------------------------------------------------------------------------
#endif //APOSTOL_HEADER_HPP

1050
src/app/PGP.cpp Normal file

File diff suppressed because it is too large Load Diff

403
src/app/PGP.hpp Normal file
View File

@@ -0,0 +1,403 @@
/*++
Module Name:
PGP.hpp
Notices:
PGP library
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#include "OpenPGP.h"
using namespace OpenPGP;
//----------------------------------------------------------------------------------------------------------------------
#ifdef USE_LIB_GCRYPT
#include <gcrypt.h>
//----------------------------------------------------------------------------------------------------------------------
#endif
#ifndef APOSTOL_PGP_HPP
#define APOSTOL_PGP_HPP
extern "C++" {
namespace Apostol {
namespace PGP {
typedef struct CPGPUserId {
CString Name;
CString Mail;
CString Desc;
} CPGPUserId, *PPGPUserId;
typedef TList<CPGPUserId> CPGPUserIdList;
class Key: public OpenPGP::Key {
public:
Key();
Key(const PGP & copy);
Key(const Key & copy);
Key(const std::string & data);
Key(std::istream & stream);
~Key() override = default;
// output style inspired by gpg and SKS Keyserver/pgp.mit.edu
std::string ListKeys(std::size_t indents = 0, std::size_t indent_size = 4) const;
void ExportUID(CPGPUserIdList &List) const;
};
bool TryCleartextSignature(const CString& Key, const CString &Pass, const CString &Hash, const CString& ClearText,
CString& SignText);
void CleartextSignature(const CString& Key, const CString &Pass, const CString &Hash, const CString& ClearText,
CString& SignText);
#ifdef USE_LIB_GCRYPT
class CPGP;
extern CPGP *GPGP;
//--------------------------------------------------------------------------------------------------------------
typedef std::function<void (CPGP *Sender, LPCTSTR AFormat, va_list args)> COnPGPVerboseEvent;
//--------------------------------------------------------------------------------------------------------------
class EPGPError: public Delphi::Exception::Exception {
typedef Delphi::Exception::Exception inherited;
private:
int m_LastError;
public:
EPGPError() : inherited(), m_LastError(GPG_ERR_NO_ERROR) {};
EPGPError(int Error, LPCTSTR lpFormat) : inherited(lpFormat) {
m_LastError = Error;
};
explicit EPGPError(LPCTSTR lpFormat, ...): m_LastError(GPG_ERR_NO_ERROR), inherited() {
va_list argList;
va_start(argList, lpFormat);
FormatMessage(lpFormat, argList);
va_end(argList);
};
~EPGPError() override = default;
int GetLastError() { return m_LastError; }
};
//--------------------------------------------------------------------------------------------------------------
class CPGPComponent {
public:
CPGPComponent();
~CPGPComponent();
}; // CPGPComponent
//--------------------------------------------------------------------------------------------------------------
//-- CPGP ------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGP: public CObject {
private:
COnPGPVerboseEvent m_OnVerbose;
protected:
gcry_error_t m_LastError;
virtual void DoVerbose(LPCTSTR AFormat, va_list args);
public:
CPGP();
~CPGP() override = default;
inline static class CPGP *CreatePGP() { return GPGP = new CPGP(); };
inline static void DeletePGP() { delete GPGP; };
static void Initialize();
bool CheckForCipherError(gcry_error_t err);
bool CheckForCipherError(gcry_error_t err, int const ignore[], int count);
void RaiseCipherError(gcry_error_t err);
void Verbose(LPCSTR AFormat, ...);
void Verbose(LPCSTR AFormat, va_list args);
gcry_error_t LastError() const { return m_LastError; };
const COnPGPVerboseEvent &OnVerbose() const { return m_OnVerbose; }
void OnVerbose(COnPGPVerboseEvent && Value) { m_OnVerbose = Value; }
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPCipher ------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPCipher: public CPGPComponent {
private:
gcry_cipher_hd_t m_Handle;
public:
CPGPCipher();
gcry_cipher_hd_t Handle() { return m_Handle; };
gcry_cipher_hd_t *Ptr() { return &m_Handle; };
bool Open(int algo, int mode, unsigned int flags);
void Close();
bool SetKey(const void *key, size_t keylen);
bool SetIV(const void *iv, size_t ivlen);
bool SetCTR(const void *ctr, size_t ctrlen);
bool Reset();
bool Authenticate(const void *abuf, size_t abuflen);
bool GetTag(void *tag, size_t taglen);
bool CheckTag(gcry_cipher_hd_t h, const void *tag, size_t taglen);
bool Encrypt(unsigned char *out, size_t outsize, const unsigned char *in, size_t inlen);
bool Decrypt(unsigned char *out, size_t outsize, const unsigned char *in, size_t inlen);
bool Final();
bool Sync();
bool Ctl(int cmd, void *buffer, size_t buflen);
bool Info(gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes);
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPAlgo --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPAlgo: public CPGPComponent {
public:
CPGPAlgo();
bool Info(int algo, int what, void *buffer, size_t *nbytes);
size_t KeyLen(int algo);
size_t BlkLen(int algo);
const char *Name(int algo);
int MapName(const char *name);
int ModeFromOid(const char *string);
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPMPI ---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPMPI: public CPGPComponent {
protected:
gcry_mpi_t m_Handle;
public:
CPGPMPI();
CPGPMPI(const CPGPMPI &Value) {
m_Handle = Value.m_Handle;
};
explicit CPGPMPI(gcry_mpi_t AHandle) {
m_Handle = AHandle;
};
~CPGPMPI() = default;
gcry_mpi_t Handle() { return m_Handle; };
void New(unsigned int nbits);
void SNew(unsigned int nbits);
void Copy(const gcry_mpi_t a);
void Release();
gcry_mpi_t Set(const gcry_mpi_t u);
gcry_mpi_t SetUI(unsigned long u);
void Swap(gcry_mpi_t b);
void Snatch(const gcry_mpi_t u);
void Neg(gcry_mpi_t u);
void Abs();
int Cmp(const gcry_mpi_t v) const;
int CmpUI(unsigned long v) const;
int IsNeg() const;
bool Scan (enum gcry_mpi_format format, const unsigned char *buffer, size_t buflen, size_t *nscanned);
bool Print (enum gcry_mpi_format format, unsigned char *buffer, size_t buflen, size_t *nwritten) const;
bool APrint(enum gcry_mpi_format format, unsigned char **buffer, size_t *nbytes) const;
void Dump();
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPSexp --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPSexp: public CPGPComponent {
protected:
gcry_sexp_t m_Handle;
public:
CPGPSexp();
CPGPSexp(const CPGPSexp& Value) {
m_Handle = Value.m_Handle;
};
explicit CPGPSexp(gcry_sexp_t AHandle) {
m_Handle = AHandle;
};
~CPGPSexp();
gcry_sexp_t Handle() { return m_Handle; };
bool New(const void *buffer, size_t length, int autodetect);
bool Create(void *buffer, size_t length, int autodetect, void (*freefnc)(void*));
bool Sscan(size_t *erroff, const char *buffer, size_t length);
bool Build(size_t *erroff, const char *format, ...);
size_t Sprint(int mode, char *buffer, size_t maxlength);
void Release();
void Dump();
static size_t CanonLen(const unsigned char *buffer, size_t length, size_t *erroff, gcry_error_t *errcode);
gcry_sexp_t FindToken(const char *token, size_t toklen);
int Length();
gcry_sexp_t Nth(int number);
gcry_sexp_t Car();
gcry_sexp_t Cdr();
const char *NthData(int number, size_t *datalen);
void *NthBuffer(int number, size_t *rlength);
char *NthString(int number);
gcry_mpi_t NthMPI(int number, int mpifmt);
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPKey ---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPKey: public CPGPSexp {
public:
CPGPKey(): CPGPSexp() {
};
CPGPKey(const CPGPKey& Value) = default;
explicit CPGPKey(gcry_sexp_t AHandle): CPGPSexp(AHandle) {
};
bool TestKey ();
static bool AlgoInfo (int algo, int what, void *buffer, size_t *nbytes);
static bool Ctl (int cmd, void *buffer, size_t buflen);
bool GenKey (gcry_sexp_t parms);
bool PubKeyGetSexp(int mode, gcry_ctx_t ctx);
unsigned int GetNBits ();
unsigned char * KeyGrip (unsigned char *array);
bool Encrypt(gcry_sexp_t data, gcry_sexp_t pkey);
bool Decrypt(gcry_sexp_t data, gcry_sexp_t skey);
bool Sign(gcry_sexp_t data, gcry_sexp_t skey);
bool Verify(gcry_sexp_t data, gcry_sexp_t pkey);
static const char * AlgoName(int algo);
static int MapName (const char *name);
static int TestAlgo (int algo);
};
//--------------------------------------------------------------------------------------------------------------
void check_rsa_keys(COnPGPVerboseEvent && Verbose = nullptr);
void load_key(const char *KeyFile, const char* Passwd, COnPGPVerboseEvent &&Verbose = nullptr);
#endif
}
}
using namespace Apostol::PGP;
}
#endif //APOSTOL_PGP_HPP

264
src/app/dm.cpp Normal file
View File

@@ -0,0 +1,264 @@
/*++
Program name:
deal-module
Module Name:
DealModule.cpp
Notices:
Bitcoin Payment Service (Deal Module)
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#include "dm.hpp"
//----------------------------------------------------------------------------------------------------------------------
#define exit_failure(msg) { \
if (GLog != nullptr) \
GLog->Error(APP_LOG_EMERG, 0, msg); \
else \
std::cerr << APP_NAME << ": " << (msg) << std::endl; \
exitcode = EXIT_FAILURE; \
}
//----------------------------------------------------------------------------------------------------------------------
extern "C++" {
namespace Apostol {
namespace DealModule {
void CDealModule::ShowVersionInfo() {
std::cerr << APP_NAME " version: " APP_VERSION " (" APP_DESCRIPTION ")" LINEFEED << std::endl;
if (Config()->Flags().show_help) {
std::cerr << "Usage: " APP_NAME << " [-?hvVt] [-s signal] [-c filename]"
" [-p prefix] [-g directives]" LINEFEED
LINEFEED
"Options:" LINEFEED
" -?,-h : this help" LINEFEED
" -v : show version and exit" LINEFEED
" -V : show version and configure options then exit" LINEFEED
" -t : test configuration and exit" LINEFEED
" -s signal : send signal to a master process: stop, quit, reopen, reload" LINEFEED
#ifdef APP_PREFIX
" -p prefix : set prefix path (default: " APP_PREFIX ")" LINEFEED
#else
" -p prefix : set prefix path (default: NONE)" LINEFEED
#endif
" -c filename : set configuration file (default: " APP_CONF_FILE ")" LINEFEED
" -g directives : set global directives out of configuration file" LINEFEED
" -l locale : set locale (default: " APP_DEFAULT_LOCALE ")" LINEFEED
<< std::endl;
}
}
//--------------------------------------------------------------------------------------------------------------
void CDealModule::ParseCmdLine() {
LPCTSTR P;
for (int i = 1; i < argc(); ++i) {
P = argv()[i].c_str();
if (*P++ != '-') {
throw Delphi::Exception::ExceptionFrm(_T("invalid option: \"%s\""), P);
}
while (*P) {
switch (*P++) {
case '?':
case 'h':
Config()->Flags().show_version = true;
Config()->Flags().show_help = true;
break;
case 'v':
Config()->Flags().show_version = true;
break;
case 'V':
Config()->Flags().show_version = true;
Config()->Flags().show_configure = true;
break;
case 't':
Config()->Flags().test_config = true;
break;
case 'p':
if (*P) {
Config()->Prefix(P);
goto next;
}
if (!argv()[++i].empty()) {
Config()->Prefix(argv()[i]);
goto next;
}
throw Delphi::Exception::Exception(_T("option \"-p\" requires directory name"));
case 'c':
if (*P) {
Config()->ConfFile(P);
goto next;
}
if (!argv()[++i].empty()) {
Config()->ConfFile(argv()[i]);
goto next;
}
throw Delphi::Exception::Exception(_T("option \"-c\" requires file name"));
case 'g':
if (*P) {
Config()->ConfParam(P);
goto next;
}
if (!argv()[++i].empty()) {
Config()->ConfParam(argv()[i]);
goto next;
}
throw Delphi::Exception::Exception(_T("option \"-g\" requires parameter"));
case 's':
if (*P) {
Config()->Signal(P);
} else if (!argv()[++i].empty()) {
Config()->Signal(argv()[i]);
} else {
throw Delphi::Exception::Exception(_T("option \"-s\" requires parameter"));
}
if ( Config()->Signal() == "stop"
|| Config()->Signal() == "quit"
|| Config()->Signal() == "reopen"
|| Config()->Signal() == "reload")
{
ProcessType(ptSignaller);
goto next;
}
throw Delphi::Exception::ExceptionFrm(_T("invalid option: \"-s %s\""), Config()->Signal().c_str());
case 'l':
if (*P) {
Config()->Locale(P);
goto next;
}
if (!argv()[++i].empty()) {
Config()->Locale(argv()[i]);
goto next;
}
throw Delphi::Exception::Exception(_T("option \"-l\" requires locale"));
default:
throw Delphi::Exception::ExceptionFrm(_T("invalid option: \"%c\""), *(P - 1));
}
}
next:
continue;
}
}
//--------------------------------------------------------------------------------------------------------------
void CDealModule::StartProcess() {
if (Config()->Helper()) {
m_ProcessType = ptHelper;
}
CIniFile Bitcoin(Config()->ConfPrefix() + "bitcoin.conf");
if (Bitcoin.ReadBool("main", "testnet", false)) {
BitcoinConfig.endpoint = "tcp://testnet.libbitcoin.net:19091";
BitcoinConfig.version_hd = hd_private::testnet;
BitcoinConfig.version_ec = ec_private::testnet;
BitcoinConfig.version_key = payment_address::testnet_p2kh;
BitcoinConfig.version_script = payment_address::testnet_p2sh;
BitcoinConfig.min_output = 1000;
BitcoinConfig.Miner.Fee = "3000";
BitcoinConfig.Symbol = "tBTC";
} else {
BitcoinConfig.endpoint = Bitcoin.ReadString("endpoint", "url", BitcoinConfig.endpoint);
BitcoinConfig.Miner.Fee = Bitcoin.ReadString("miner", "fee", "1%");
BitcoinConfig.Miner.min = Bitcoin.ReadInteger("miner", "min", 200);
BitcoinConfig.Miner.max = Bitcoin.ReadInteger("miner", "max", 2000);
BitcoinConfig.min_output = Bitcoin.ReadInteger("transaction", "min_output", 200);
if (BitcoinConfig.Miner.min < 0)
BitcoinConfig.Miner.min = 0;
if (BitcoinConfig.Miner.max < 0)
BitcoinConfig.Miner.max = 0;
if (BitcoinConfig.Miner.min > BitcoinConfig.Miner.max)
BitcoinConfig.Miner.min = BitcoinConfig.Miner.max;
}
CApplication::StartProcess();
}
//--------------------------------------------------------------------------------------------------------------
void CDealModule::Run() {
CApplication::Run();
}
//--------------------------------------------------------------------------------------------------------------
}
}
}
//----------------------------------------------------------------------------------------------------------------------
int main(int argc, char *argv[]) {
int exitcode;
DefaultLocale.SetLocale("");
CDealModule dm(argc, argv);
try
{
dm.Name() = APP_NAME;
dm.Description() = APP_DESCRIPTION;
dm.Version() = APP_VERSION;
dm.Title() = APP_VER;
dm.Run();
exitcode = dm.ExitCode();
}
catch (std::exception& e)
{
exit_failure(e.what());
}
catch (...)
{
exit_failure("Unknown error...");
}
exit(exitcode);
}
//----------------------------------------------------------------------------------------------------------------------

75
src/app/dm.hpp Normal file
View File

@@ -0,0 +1,75 @@
/*++
Program name:
dm
Module Name:
dm.hpp
Notices:
BitDeals Payment Service (Deal Module)
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_APOSTOL_HPP
#define APOSTOL_APOSTOL_HPP
#include "../../version.h"
//----------------------------------------------------------------------------------------------------------------------
#define APP_VERSION AUTO_VERSION
#define APP_VER APP_NAME "/" APP_VERSION
//----------------------------------------------------------------------------------------------------------------------
#include "Header.hpp"
//----------------------------------------------------------------------------------------------------------------------
extern "C++" {
namespace Apostol {
namespace DealModule {
class CDealModule: public CApplication {
protected:
void ParseCmdLine() override;
void ShowVersionInfo() override;
void StartProcess() override;
public:
CDealModule(int argc, char *const *argv): CApplication(argc, argv) {
};
~CDealModule() override = default;
static class CDealModule *Create(int argc, char *const *argv) {
return new CDealModule(argc, argv);
};
inline void Destroy() override { delete this; };
void Run() override;
};
}
}
using namespace Apostol::DealModule;
}
#endif //APOSTOL_APOSTOL_HPP

1
src/core Submodule

Submodule src/core added at a748414372

210
src/lib/jwt-cpp/base.h Normal file
View File

@@ -0,0 +1,210 @@
#pragma once
#include <string>
#include <array>
#ifdef __has_cpp_attribute
#if __has_cpp_attribute(fallthrough)
#define JWT_FALLTHROUGH [[fallthrough]]
#endif
#endif
#ifndef JWT_FALLTHROUGH
#define JWT_FALLTHROUGH
#endif
namespace jwt {
namespace alphabet {
struct base64 {
static const std::array<char, 64>& data() {
static std::array<char, 64> data = {
{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}};
return data;
};
static const std::string& fill() {
static std::string fill = "=";
return fill;
}
};
struct base64url {
static const std::array<char, 64>& data() {
static std::array<char, 64> data = {
{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'}};
return data;
};
static const std::string& fill() {
static std::string fill = "%3d";
return fill;
}
};
}
class base {
public:
template<typename T>
static std::string encode(const std::string& bin) {
return encode(bin, T::data(), T::fill());
}
template<typename T>
static std::string decode(const std::string& base) {
return decode(base, T::data(), T::fill());
}
template<typename T>
static std::string pad(const std::string& base) {
return pad(base, T::fill());
}
template<typename T>
static std::string trim(const std::string& base) {
return trim(base, T::fill());
}
private:
static std::string encode(const std::string& bin, const std::array<char, 64>& alphabet, const std::string& fill) {
size_t size = bin.size();
std::string res;
// clear incomplete bytes
size_t fast_size = size - size % 3;
for (size_t i = 0; i < fast_size;) {
uint32_t octet_a = (unsigned char)bin[i++];
uint32_t octet_b = (unsigned char)bin[i++];
uint32_t octet_c = (unsigned char)bin[i++];
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
res += alphabet[(triple >> 3 * 6) & 0x3F];
res += alphabet[(triple >> 2 * 6) & 0x3F];
res += alphabet[(triple >> 1 * 6) & 0x3F];
res += alphabet[(triple >> 0 * 6) & 0x3F];
}
if (fast_size == size)
return res;
size_t mod = size % 3;
uint32_t octet_a = fast_size < size ? (unsigned char)bin[fast_size++] : 0;
uint32_t octet_b = fast_size < size ? (unsigned char)bin[fast_size++] : 0;
uint32_t octet_c = fast_size < size ? (unsigned char)bin[fast_size++] : 0;
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
switch (mod) {
case 1:
res += alphabet[(triple >> 3 * 6) & 0x3F];
res += alphabet[(triple >> 2 * 6) & 0x3F];
res += fill;
res += fill;
break;
case 2:
res += alphabet[(triple >> 3 * 6) & 0x3F];
res += alphabet[(triple >> 2 * 6) & 0x3F];
res += alphabet[(triple >> 1 * 6) & 0x3F];
res += fill;
break;
default:
break;
}
return res;
}
static std::string decode(const std::string& base, const std::array<char, 64>& alphabet, const std::string& fill) {
size_t size = base.size();
size_t fill_cnt = 0;
while (size > fill.size()) {
if (base.substr(size - fill.size(), fill.size()) == fill) {
fill_cnt++;
size -= fill.size();
if(fill_cnt > 2)
throw std::runtime_error("Invalid input");
}
else break;
}
if ((size + fill_cnt) % 4 != 0)
throw std::runtime_error("Invalid input");
size_t out_size = size / 4 * 3;
std::string res;
res.reserve(out_size);
auto get_sextet = [&](size_t offset) {
for (size_t i = 0; i < alphabet.size(); i++) {
if (alphabet[i] == base[offset])
return static_cast<uint32_t>(i);
}
throw std::runtime_error("Invalid input");
};
size_t fast_size = size - size % 4;
for (size_t i = 0; i < fast_size;) {
uint32_t sextet_a = get_sextet(i++);
uint32_t sextet_b = get_sextet(i++);
uint32_t sextet_c = get_sextet(i++);
uint32_t sextet_d = get_sextet(i++);
uint32_t triple = (sextet_a << 3 * 6)
+ (sextet_b << 2 * 6)
+ (sextet_c << 1 * 6)
+ (sextet_d << 0 * 6);
res += (triple >> 2 * 8) & 0xFF;
res += (triple >> 1 * 8) & 0xFF;
res += (triple >> 0 * 8) & 0xFF;
}
if (fill_cnt == 0)
return res;
uint32_t triple = (get_sextet(fast_size) << 3 * 6)
+ (get_sextet(fast_size + 1) << 2 * 6);
switch (fill_cnt) {
case 1:
triple |= (get_sextet(fast_size + 2) << 1 * 6);
res += (triple >> 2 * 8) & 0xFF;
res += (triple >> 1 * 8) & 0xFF;
break;
case 2:
res += (triple >> 2 * 8) & 0xFF;
break;
default:
break;
}
return res;
}
static std::string pad(const std::string& base, const std::string& fill) {
std::string padding;
switch (base.size() % 4) {
case 1:
padding += fill;
JWT_FALLTHROUGH;
case 2:
padding += fill;
JWT_FALLTHROUGH;
case 3:
padding += fill;
JWT_FALLTHROUGH;
default:
break;
}
return base + padding;
}
static std::string trim(const std::string& base, const std::string& fill) {
auto pos = base.find(fill);
return base.substr(0, pos);
}
};
}

1612
src/lib/jwt-cpp/jwt.h Normal file

File diff suppressed because it is too large Load Diff

1174
src/lib/picojson/picojson.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
Use of this software is granted under one of the following two licenses,
to be chosen freely by the user.
1. Boost Software License - Version 1.0 - August 17th, 2003
===============================================================================
Copyright (c) 2006, 2007 Marcin Kalicinski
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
2. The MIT License
===============================================================================
Copyright (c) 2006, 2007 Marcin Kalicinski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED
#define RAPIDXML_ITERATORS_HPP_INCLUDED
// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_iterators.hpp This file contains rapidxml iterators
#include "rapidxml.hpp"
namespace rapidxml
{
//! Iterator of child nodes of xml_node
template<class Ch>
class node_iterator
{
public:
typedef typename xml_node<Ch> value_type;
typedef typename xml_node<Ch> &reference;
typedef typename xml_node<Ch> *pointer;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
node_iterator()
: m_node(0)
{
}
node_iterator(xml_node<Ch> *node)
: m_node(node->first_node())
{
}
reference operator *() const
{
assert(m_node);
return *m_node;
}
pointer operator->() const
{
assert(m_node);
return m_node;
}
node_iterator& operator++()
{
assert(m_node);
m_node = m_node->next_sibling();
return *this;
}
node_iterator operator++(int)
{
node_iterator tmp = *this;
++this;
return tmp;
}
node_iterator& operator--()
{
assert(m_node && m_node->previous_sibling());
m_node = m_node->previous_sibling();
return *this;
}
node_iterator operator--(int)
{
node_iterator tmp = *this;
++this;
return tmp;
}
bool operator ==(const node_iterator<Ch> &rhs)
{
return m_node == rhs.m_node;
}
bool operator !=(const node_iterator<Ch> &rhs)
{
return m_node != rhs.m_node;
}
private:
xml_node<Ch> *m_node;
};
//! Iterator of child attributes of xml_node
template<class Ch>
class attribute_iterator
{
public:
typedef typename xml_attribute<Ch> value_type;
typedef typename xml_attribute<Ch> &reference;
typedef typename xml_attribute<Ch> *pointer;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
attribute_iterator()
: m_attribute(0)
{
}
attribute_iterator(xml_node<Ch> *node)
: m_attribute(node->first_attribute())
{
}
reference operator *() const
{
assert(m_attribute);
return *m_attribute;
}
pointer operator->() const
{
assert(m_attribute);
return m_attribute;
}
attribute_iterator& operator++()
{
assert(m_attribute);
m_attribute = m_attribute->next_attribute();
return *this;
}
attribute_iterator operator++(int)
{
attribute_iterator tmp = *this;
++this;
return tmp;
}
attribute_iterator& operator--()
{
assert(m_attribute && m_attribute->previous_attribute());
m_attribute = m_attribute->previous_attribute();
return *this;
}
attribute_iterator operator--(int)
{
attribute_iterator tmp = *this;
++this;
return tmp;
}
bool operator ==(const attribute_iterator<Ch> &rhs)
{
return m_attribute == rhs.m_attribute;
}
bool operator !=(const attribute_iterator<Ch> &rhs)
{
return m_attribute != rhs.m_attribute;
}
private:
xml_attribute<Ch> *m_attribute;
};
}
#endif

View File

@@ -0,0 +1,421 @@
#ifndef RAPIDXML_PRINT_HPP_INCLUDED
#define RAPIDXML_PRINT_HPP_INCLUDED
// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_print.hpp This file contains rapidxml printer implementation
#include "rapidxml.hpp"
// Only include streams if not disabled
#ifndef RAPIDXML_NO_STREAMS
#include <ostream>
#include <iterator>
#endif
namespace rapidxml
{
///////////////////////////////////////////////////////////////////////
// Printing flags
const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function.
///////////////////////////////////////////////////////////////////////
// Internal
//! \cond internal
namespace internal
{
///////////////////////////////////////////////////////////////////////////
// Internal character operations
// Copy characters from given range to given output iterator
template<class OutIt, class Ch>
inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out)
{
while (begin != end)
*out++ = *begin++;
return out;
}
// Copy characters from given range to given output iterator and expand
// characters into references (&lt; &gt; &apos; &quot; &amp;)
template<class OutIt, class Ch>
inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out)
{
while (begin != end)
{
if (*begin == noexpand)
{
*out++ = *begin; // No expansion, copy character
}
else
{
switch (*begin)
{
case Ch('<'):
*out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';');
break;
case Ch('>'):
*out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';');
break;
case Ch('\''):
*out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';');
break;
case Ch('"'):
*out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';');
break;
case Ch('&'):
*out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';');
break;
default:
*out++ = *begin; // No expansion, copy character
}
}
++begin; // Step to next character
}
return out;
}
// Fill given output iterator with repetitions of the same character
template<class OutIt, class Ch>
inline OutIt fill_chars(OutIt out, int n, Ch ch)
{
for (int i = 0; i < n; ++i)
*out++ = ch;
return out;
}
// Find character
template<class Ch, Ch ch>
inline bool find_char(const Ch *begin, const Ch *end)
{
while (begin != end)
if (*begin++ == ch)
return true;
return false;
}
///////////////////////////////////////////////////////////////////////////
// Internal printing operations
// Print node
template<class OutIt, class Ch>
inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
// Print proper node type
switch (node->type())
{
// Document
case node_document:
out = print_children(out, node, flags, indent);
break;
// Element
case node_element:
out = print_element_node(out, node, flags, indent);
break;
// Data
case node_data:
out = print_data_node(out, node, flags, indent);
break;
// CDATA
case node_cdata:
out = print_cdata_node(out, node, flags, indent);
break;
// Declaration
case node_declaration:
out = print_declaration_node(out, node, flags, indent);
break;
// Comment
case node_comment:
out = print_comment_node(out, node, flags, indent);
break;
// Doctype
case node_doctype:
out = print_doctype_node(out, node, flags, indent);
break;
// Pi
case node_pi:
out = print_pi_node(out, node, flags, indent);
break;
// Unknown
default:
assert(0);
break;
}
// If indenting not disabled, add line break after node
if (!(flags & print_no_indenting))
*out = Ch('\n'), ++out;
// Return modified iterator
return out;
}
// Print children of the node
template<class OutIt, class Ch>
inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
for (xml_node<Ch> *child = node->first_node(); child; child = child->next_sibling())
out = print_node(out, child, flags, indent);
return out;
}
// Print attributes of the node
template<class OutIt, class Ch>
inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags)
{
for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute())
{
if (attribute->name() && attribute->value())
{
// Print attribute name
*out = Ch(' '), ++out;
out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out);
*out = Ch('='), ++out;
// Print attribute value using appropriate quote type
if (find_char<Ch, Ch('"')>(attribute->value(), attribute->value() + attribute->value_size()))
{
*out = Ch('\''), ++out;
out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out);
*out = Ch('\''), ++out;
}
else
{
*out = Ch('"'), ++out;
out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out);
*out = Ch('"'), ++out;
}
}
}
return out;
}
// Print data node
template<class OutIt, class Ch>
inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_data);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
return out;
}
// Print data node
template<class OutIt, class Ch>
inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_cdata);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'); ++out;
*out = Ch('!'); ++out;
*out = Ch('['); ++out;
*out = Ch('C'); ++out;
*out = Ch('D'); ++out;
*out = Ch('A'); ++out;
*out = Ch('T'); ++out;
*out = Ch('A'); ++out;
*out = Ch('['); ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch(']'); ++out;
*out = Ch(']'); ++out;
*out = Ch('>'); ++out;
return out;
}
// Print element node
template<class OutIt, class Ch>
inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_element);
// Print element name and attributes, if any
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
out = copy_chars(node->name(), node->name() + node->name_size(), out);
out = print_attributes(out, node, flags);
// If node is childless
if (node->value_size() == 0 && !node->first_node())
{
// Print childless node tag ending
*out = Ch('/'), ++out;
*out = Ch('>'), ++out;
}
else
{
// Print normal node tag ending
*out = Ch('>'), ++out;
// Test if node contains a single data node only (and no other nodes)
xml_node<Ch> *child = node->first_node();
if (!child)
{
// If node has no children, only print its value without indenting
out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
}
else if (child->next_sibling() == 0 && child->type() == node_data)
{
// If node has a sole data child, only print its value without indenting
out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out);
}
else
{
// Print all children with full indenting
if (!(flags & print_no_indenting))
*out = Ch('\n'), ++out;
out = print_children(out, node, flags, indent + 1);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
}
// Print node end
*out = Ch('<'), ++out;
*out = Ch('/'), ++out;
out = copy_chars(node->name(), node->name() + node->name_size(), out);
*out = Ch('>'), ++out;
}
return out;
}
// Print declaration node
template<class OutIt, class Ch>
inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
// Print declaration start
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('?'), ++out;
*out = Ch('x'), ++out;
*out = Ch('m'), ++out;
*out = Ch('l'), ++out;
// Print attributes
out = print_attributes(out, node, flags);
// Print declaration end
*out = Ch('?'), ++out;
*out = Ch('>'), ++out;
return out;
}
// Print comment node
template<class OutIt, class Ch>
inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_comment);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('!'), ++out;
*out = Ch('-'), ++out;
*out = Ch('-'), ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch('-'), ++out;
*out = Ch('-'), ++out;
*out = Ch('>'), ++out;
return out;
}
// Print doctype node
template<class OutIt, class Ch>
inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_doctype);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('!'), ++out;
*out = Ch('D'), ++out;
*out = Ch('O'), ++out;
*out = Ch('C'), ++out;
*out = Ch('T'), ++out;
*out = Ch('Y'), ++out;
*out = Ch('P'), ++out;
*out = Ch('E'), ++out;
*out = Ch(' '), ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch('>'), ++out;
return out;
}
// Print pi node
template<class OutIt, class Ch>
inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_pi);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('?'), ++out;
out = copy_chars(node->name(), node->name() + node->name_size(), out);
*out = Ch(' '), ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch('?'), ++out;
*out = Ch('>'), ++out;
return out;
}
}
//! \endcond
///////////////////////////////////////////////////////////////////////////
// Printing
//! Prints XML to given output iterator.
//! \param out Output iterator to print to.
//! \param node Node to be printed. Pass xml_document to print entire document.
//! \param flags Flags controlling how XML is printed.
//! \return Output iterator pointing to position immediately after last character of printed text.
template<class OutIt, class Ch>
inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0)
{
return internal::print_node(out, &node, flags, 0);
}
#ifndef RAPIDXML_NO_STREAMS
//! Prints XML to given output stream.
//! \param out Output stream to print to.
//! \param node Node to be printed. Pass xml_document to print entire document.
//! \param flags Flags controlling how XML is printed.
//! \return Output stream.
template<class Ch>
inline std::basic_ostream<Ch> &print(std::basic_ostream<Ch> &out, const xml_node<Ch> &node, int flags = 0)
{
print(std::ostream_iterator<Ch>(out), node, flags);
return out;
}
//! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.
//! \param out Output stream to print to.
//! \param node Node to be printed.
//! \return Output stream.
template<class Ch>
inline std::basic_ostream<Ch> &operator <<(std::basic_ostream<Ch> &out, const xml_node<Ch> &node)
{
return print(out, node);
}
#endif
}
#endif

View File

@@ -0,0 +1,122 @@
#ifndef RAPIDXML_UTILS_HPP_INCLUDED
#define RAPIDXML_UTILS_HPP_INCLUDED
// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful
//! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective.
#include "rapidxml.hpp"
#include <vector>
#include <string>
#include <fstream>
#include <stdexcept>
namespace rapidxml
{
//! Represents data loaded from a file
template<class Ch = char>
class file
{
public:
//! Loads file into the memory. Data will be automatically destroyed by the destructor.
//! \param filename Filename to load.
file(const char *filename)
{
using namespace std;
// Open stream
basic_ifstream<Ch> stream(filename, ios::binary);
if (!stream)
throw runtime_error(string("cannot open file ") + filename);
stream.unsetf(ios::skipws);
// Determine stream size
stream.seekg(0, ios::end);
size_t size = stream.tellg();
stream.seekg(0);
// Load data and add terminating 0
m_data.resize(size + 1);
stream.read(&m_data.front(), static_cast<streamsize>(size));
m_data[size] = 0;
}
//! Loads file into the memory. Data will be automatically destroyed by the destructor
//! \param stream Stream to load from
file(std::basic_istream<Ch> &stream)
{
using namespace std;
// Load data and add terminating 0
stream.unsetf(ios::skipws);
m_data.assign(istreambuf_iterator<Ch>(stream), istreambuf_iterator<Ch>());
if (stream.fail() || stream.bad())
throw runtime_error("error reading stream");
m_data.push_back(0);
}
//! Gets file data.
//! \return Pointer to data of file.
Ch *data()
{
return &m_data.front();
}
//! Gets file data.
//! \return Pointer to data of file.
const Ch *data() const
{
return &m_data.front();
}
//! Gets file data size.
//! \return Size of file data, in characters.
std::size_t size() const
{
return m_data.size();
}
private:
std::vector<Ch> m_data; // File data
};
//! Counts children of node. Time complexity is O(n).
//! \return Number of children of node
template<class Ch>
inline std::size_t count_children(xml_node<Ch> *node)
{
xml_node<Ch> *child = node->first_node();
std::size_t count = 0;
while (child)
{
++count;
child = child->next_sibling();
}
return count;
}
//! Counts attributes of node. Time complexity is O(n).
//! \return Number of attributes of node
template<class Ch>
inline std::size_t count_attributes(xml_node<Ch> *node)
{
xml_attribute<Ch> *attr = node->first_attribute();
std::size_t count = 0;
while (attr)
{
++count;
attr = attr->next_attribute();
}
return count;
}
}
#endif

View File

@@ -0,0 +1,32 @@
/*++
Program name:
apostol
Module Name:
Helpers.hpp
Notices:
Apostol Web Service
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_HELPERS_HPP
#define APOSTOL_HELPERS_HPP
//----------------------------------------------------------------------------------------------------------------------
static inline void CreateHelpers(CModuleProcess *AProcess) {
}
#endif //APOSTOL_HELPERS_HPP

35
src/modules/Modules.hpp Normal file
View File

@@ -0,0 +1,35 @@
/*++
Library name:
apostol-core
Module Name:
Workers.hpp
Notices:
Add-ons: Workers
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_MODULES_HPP
#define APOSTOL_MODULES_HPP
//----------------------------------------------------------------------------------------------------------------------
#include "Header.hpp"
//----------------------------------------------------------------------------------------------------------------------
#include "Workers/Workers.hpp"
#include "Helpers/Helpers.hpp"
//----------------------------------------------------------------------------------------------------------------------
#endif //APOSTOL_MODULES_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,199 @@
/*++
Library name:
apostol-module
Module Name:
WebService.hpp
Notices:
WebService - Deal Module Web Service
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_WEBSERVICE_HPP
#define APOSTOL_WEBSERVICE_HPP
//----------------------------------------------------------------------------------------------------------------------
#define BPS_DEFAULT_SYNC_PERIOD 30
#define BPS_SERVER_PORT 4988
#define BPS_SERVER_URL "http://65.21.101.151:4988"
#define BPS_BM_SERVER_ADDRESS "BM-2cX8y9u9yEi3fdqQfndx9F6NdR5Hv79add"
//----------------------------------------------------------------------------------------------------------------------
extern "C++" {
namespace Apostol {
namespace Workers {
struct CKeyContext {
CString Name;
CString Key;
enum CKeyStatus {
ksUnknown = -1,
ksFetching,
ksSuccess,
ksError,
} Status;
CDateTime StatusTime;
CKeyContext(): Status(ksUnknown), StatusTime(Now()) {
Name = "DEFAULT";
}
CKeyContext(const CString& Name, const CString& Key): CKeyContext() {
this->Name = Name;
this->Key = Key;
}
};
struct CServerContext {
CString URI;
CKeyContext PGP;
CServerContext() = default;
explicit CServerContext(const CString& URI) {
this->URI = URI;
}
};
typedef TPair<CServerContext> CServer;
typedef TPairs<CServerContext> CServerList;
//--------------------------------------------------------------------------------------------------------------
//-- CWebService -----------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CWebService: public CApostolModule {
private:
CProcessStatus m_Status;
CServer m_DefaultServer;
int m_SyncPeriod;
int m_ServerIndex;
int m_KeyIndex;
CDateTime m_FixedDate;
CDateTime m_RandomDate;
CKeyContext m_PGP;
CServerList m_Servers;
CStringList m_BTCKeys;
CProviders m_Providers;
CStringListPairs m_Tokens;
CHTTPProxyManager m_ProxyManager;
CHTTPProxy *GetProxy(CHTTPServerConnection *AConnection);
void InitMethods() override;
void FetchCerts(CProvider &Provider, const CString &Application);
void FetchProviders();
void CheckProviders();
void RouteUser(CHTTPServerConnection *AConnection, const CString &Method, const CString &URI);
void RouteDeal(CHTTPServerConnection *AConnection, const CString &Method, const CString &URI, const CString &Action);
void RouteSignature(CHTTPServerConnection *AConnection);
void FetchAccessToken(const CString &URI, const CString &Assertion,
COnSocketExecuteEvent && OnDone, COnSocketExceptionEvent && OnFailed = nullptr);
void CreateAccessToken(const CProvider &Provider, const CString &Application, CStringList &Tokens);
static CString CreateToken(const CProvider& Provider, const CString &Application);
protected:
int NextServerIndex();
const CServer &CurrentServer() const;
void FetchPGP(CKeyContext& PGP);
void FetchBTC(CKeyContext& BTC);
static int CheckFee(const CString& Fee);
static void CheckKeyForNull(LPCTSTR Key, LPCTSTR Value);
void DoAPI(CHTTPServerConnection *AConnection);
void DoGet(CHTTPServerConnection *AConnection) override;
void DoPost(CHTTPServerConnection *AConnection);
void DoVerbose(CSocketEvent *Sender, CTCPConnection *AConnection, LPCTSTR AFormat, va_list args);
bool DoProxyExecute(CTCPConnection *AConnection);
void DoProxyException(CTCPConnection *AConnection, const Delphi::Exception::Exception &E);
void DoEventHandlerException(CPollEventHandler *AHandler, const Delphi::Exception::Exception &E);
void DoProxyConnected(CObject *Sender);
void DoProxyDisconnected(CObject *Sender);
public:
explicit CWebService(CModuleProcess *AProcess);
~CWebService() override = default;
static class CWebService *CreateModule(CModuleProcess *AProcess) {
return new CWebService(AProcess);
}
void Initialization(CModuleProcess *AProcess) override;
void Heartbeat() override;
bool Enabled() override;
void FetchKeys();
void Reload();
static void JsonStringToKey(const CString& jsonString, CString& Key);
void ParsePGPKey(const CString& Key, CStringPairs& ServerList, CStringList& BTCKeys);
static void CheckDeal(const CDeal& Deal);
static bool CheckVerifyPGPSignature(int VerifyPGPSignature, CString &Message);
static int VerifyPGPSignature(const CString &ClearText, const CString &Key, CString &Message);
static bool FindURLInLine(const CString &Line, CStringList &List);
static void ExceptionToJson(int ErrorCode, const std::exception &AException, CString& Json);
static CDateTime GetRandomDate(int a, int b, CDateTime Date = Now());
static void LoadOAuth2(const CString &FileName, const CString &ProviderName, const CString &ApplicationName,
CProviders &Providers);
};
}
}
using namespace Apostol::Workers;
}
#endif //APOSTOL_WEBSERVICE_HPP

View File

@@ -0,0 +1,35 @@
/*++
Library name:
apostol-core
Module Name:
Workers.hpp
Notices:
Add-ons: Workers
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_WORKERS_HPP
#define APOSTOL_WORKERS_HPP
//----------------------------------------------------------------------------------------------------------------------
#include "WebService/WebService.hpp"
//----------------------------------------------------------------------------------------------------------------------
static inline void CreateWorkers(CModuleProcess *AProcess) {
CWebService::CreateModule(AProcess);
}
#endif //APOSTOL_WORKERS_HPP

View File

@@ -0,0 +1,32 @@
/*++
Library name:
apostol-core
Module Name:
Processes.hpp
Notices:
Application others processes
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_PROCESSES_HPP
#define APOSTOL_PROCESSES_HPP
//----------------------------------------------------------------------------------------------------------------------
static inline void CreateProcesses(CCustomProcess *AParent, CApplication *AApplication) {
}
#endif //APOSTOL_PROCESSES_HPP