2016-08-27 00:51:00 -04:00
|
|
|
#include "STDInclude.hpp"
|
|
|
|
|
|
|
|
#ifndef DISABLE_BITMESSAGE
|
|
|
|
|
|
|
|
#include <Shlwapi.h>
|
|
|
|
|
|
|
|
using namespace Utils;
|
|
|
|
|
|
|
|
namespace Components
|
|
|
|
{
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMRC* BitMessage::BMClient;
|
2016-08-27 00:51:00 -04:00
|
|
|
|
|
|
|
BitMessage::BitMessage()
|
|
|
|
{
|
2016-08-31 09:29:59 -04:00
|
|
|
#ifdef DEBUG
|
|
|
|
Logger::Print("Initializing BitMessage...\n");
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
2016-08-27 00:51:00 -04:00
|
|
|
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient = new BitMRC(BITMESSAGE_OBJECT_STORAGE_FILENAME, BITMESSAGE_KEYS_FILENAME);
|
|
|
|
BitMessage::BMClient->init();
|
|
|
|
BitMessage::BMClient->defaultTTL = 1 * 60 * 60; // 1 hour
|
|
|
|
|
|
|
|
if (BitMessage::BMClient->PrivAddresses.empty())
|
2016-08-27 00:51:00 -04:00
|
|
|
{
|
|
|
|
if (!this->InitAddr())
|
|
|
|
{
|
|
|
|
// Generate a random address ready to use
|
|
|
|
throw std::runtime_error("Failed to prepare source address for exception handling");
|
|
|
|
}
|
2016-08-30 06:23:53 -04:00
|
|
|
|
|
|
|
BitMessage::BMClient->save();
|
2016-08-27 00:51:00 -04:00
|
|
|
}
|
|
|
|
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->start();
|
2016-08-27 00:51:00 -04:00
|
|
|
|
2016-08-31 06:26:47 -04:00
|
|
|
#ifdef DEBUG
|
2016-08-30 06:23:53 -04:00
|
|
|
Command::Add("bm_send", [](Command::Params params)
|
|
|
|
{
|
2016-08-27 05:24:26 -04:00
|
|
|
if (params.Length() < 3) return;
|
|
|
|
|
|
|
|
ustring pubAddrString;
|
|
|
|
pubAddrString.fromString(params[1]);
|
2016-08-30 06:23:53 -04:00
|
|
|
|
2016-08-27 05:24:26 -04:00
|
|
|
PubAddr pubAddr;
|
|
|
|
if (pubAddr.loadAddr(pubAddrString))
|
|
|
|
{
|
|
|
|
ustring msg;
|
|
|
|
msg.fromString(params.Join(2));
|
|
|
|
|
|
|
|
Logger::Print("Sending message (this may take a while)...\n");
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->sendMessage(msg, pubAddr, BitMessage::BMClient->PrivAddresses[0]);
|
2016-08-27 05:24:26 -04:00
|
|
|
Logger::Print("Message sent.\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Logger::Print("Address not correct!\n");
|
|
|
|
}
|
|
|
|
});
|
2016-08-30 06:23:53 -04:00
|
|
|
|
|
|
|
Command::Add("bm_sendb", [](Command::Params params)
|
|
|
|
{
|
2016-08-27 04:16:12 -04:00
|
|
|
if (params.Length() < 2) return;
|
|
|
|
|
2016-08-27 00:51:00 -04:00
|
|
|
ustring msg;
|
2016-08-27 04:16:12 -04:00
|
|
|
msg.appendVarString(params.Join(1));
|
|
|
|
Logger::Print("Sending broadcast...\n");
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->sendBroadcast(msg, BitMessage::BMClient->PrivAddresses[0]);
|
2016-08-27 04:16:12 -04:00
|
|
|
Logger::Print("Broadcast done.\n");
|
2016-08-27 00:51:00 -04:00
|
|
|
});
|
2016-08-30 06:23:53 -04:00
|
|
|
|
|
|
|
Command::Add("bm_check_messages", [](Command::Params)
|
|
|
|
{
|
|
|
|
while (BitMessage::BMClient->new_messages.size() > 0)
|
2016-08-27 00:51:00 -04:00
|
|
|
{
|
2016-08-30 06:23:53 -04:00
|
|
|
auto msg = BitMessage::BMClient->new_messages.pop();
|
|
|
|
Logger::Print("New message:\nFrom: %s\nTo: %s\nMessage:\n%s\n", msg.from.data(), msg.to.data(), msg.info.data());
|
2016-08-27 00:51:00 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-08-30 06:23:53 -04:00
|
|
|
Command::Add("bm_check_connections", [](Command::Params)
|
|
|
|
{
|
|
|
|
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_nodes);
|
|
|
|
|
|
|
|
for (auto& node : BitMessage::BMClient->Nodes)
|
2016-08-27 00:51:00 -04:00
|
|
|
{
|
|
|
|
switch (node->state) {
|
|
|
|
case 0: // Not connected
|
2016-08-30 06:23:53 -04:00
|
|
|
Logger::Print("%s: Disconnected\n", node->Ip.data());
|
2016-08-27 00:51:00 -04:00
|
|
|
break;
|
|
|
|
case 1: // Connecting
|
2016-08-30 06:23:53 -04:00
|
|
|
Logger::Print("%s: Connecting\n", node->Ip.data());
|
2016-08-27 00:51:00 -04:00
|
|
|
break;
|
|
|
|
case 2: // Connected
|
2016-08-30 06:23:53 -04:00
|
|
|
Logger::Print("%s: Connected\n", node->Ip.data());
|
2016-08-27 00:51:00 -04:00
|
|
|
break;
|
|
|
|
case 3: // Reconnecting
|
2016-08-30 06:23:53 -04:00
|
|
|
Logger::Print("%s: Reconnecting\n", node->Ip.data());
|
2016-08-27 00:51:00 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mlock.unlock();
|
|
|
|
});
|
|
|
|
|
2016-08-30 06:23:53 -04:00
|
|
|
Command::Add("bm_check_privatekey", [](Command::Params)
|
|
|
|
{
|
|
|
|
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_priv);
|
|
|
|
|
|
|
|
if (BitMessage::BMClient->PrivAddresses.empty())
|
|
|
|
{
|
2016-08-27 00:51:00 -04:00
|
|
|
Logger::Print("No private key\n");
|
|
|
|
}
|
|
|
|
else
|
2016-08-30 06:23:53 -04:00
|
|
|
{
|
|
|
|
for (auto& addr : BitMessage::BMClient->PrivAddresses)
|
2016-08-27 00:51:00 -04:00
|
|
|
{
|
2016-08-30 06:23:53 -04:00
|
|
|
Logger::Print("%s\n", addr.getAddress().data());
|
2016-08-27 00:51:00 -04:00
|
|
|
}
|
2016-08-30 06:23:53 -04:00
|
|
|
}
|
2016-08-27 00:51:00 -04:00
|
|
|
|
|
|
|
mlock.unlock();
|
|
|
|
});
|
|
|
|
|
2016-08-30 06:23:53 -04:00
|
|
|
Command::Add("bm_check_publickey", [](Command::Params)
|
|
|
|
{
|
|
|
|
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_pub);
|
|
|
|
|
|
|
|
if (BitMessage::BMClient->PubAddresses.empty())
|
|
|
|
{
|
2016-08-27 00:51:00 -04:00
|
|
|
Logger::Print("No public key\n");
|
|
|
|
}
|
|
|
|
else
|
2016-08-30 06:23:53 -04:00
|
|
|
for (auto& addr : BitMessage::BMClient->PubAddresses)
|
2016-08-27 00:51:00 -04:00
|
|
|
{
|
2016-08-30 06:23:53 -04:00
|
|
|
Logger::Print("%s (waiting for public key: %s)\n", addr.getAddress().data(), addr.waitingPubKey() ? "yes" : "no");
|
2016-08-27 00:51:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
mlock.unlock();
|
|
|
|
});
|
2016-08-30 06:23:53 -04:00
|
|
|
|
|
|
|
Command::Add("bm_save", [](Command::Params)
|
|
|
|
{
|
|
|
|
BitMessage::Save();
|
2016-08-27 00:51:00 -04:00
|
|
|
});
|
2016-08-30 06:23:53 -04:00
|
|
|
|
|
|
|
Command::Add("bm_address_public", [](Command::Params params)
|
|
|
|
{
|
2016-08-27 04:16:12 -04:00
|
|
|
if (params.Length() < 2) return;
|
2016-08-27 00:51:00 -04:00
|
|
|
|
|
|
|
ustring addre;
|
2016-08-27 04:16:12 -04:00
|
|
|
addre.fromString(params.Join(1));
|
2016-08-30 06:23:53 -04:00
|
|
|
|
2016-08-27 00:51:00 -04:00
|
|
|
PubAddr address;
|
|
|
|
if (address.loadAddr(addre))
|
|
|
|
{
|
|
|
|
Logger::Print("Asking public key!\n");
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->getPubKey(address);
|
2016-08-27 00:51:00 -04:00
|
|
|
Logger::Print("Asked! check publickey for news on that address!\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Logger::Print("Address not correct!\n");
|
|
|
|
}
|
|
|
|
});
|
2016-08-30 06:23:53 -04:00
|
|
|
|
|
|
|
Command::Add("bm_address_broadcast", [](Command::Params params)
|
|
|
|
{
|
2016-08-27 04:16:12 -04:00
|
|
|
if (params.Length() < 2) return;
|
2016-08-27 00:51:00 -04:00
|
|
|
|
|
|
|
ustring addre;
|
2016-08-27 04:16:12 -04:00
|
|
|
addre.fromString(params.Join(1));
|
2016-08-27 00:51:00 -04:00
|
|
|
PubAddr address;
|
|
|
|
if (address.loadAddr(addre))
|
|
|
|
{
|
|
|
|
Logger::Print("Adding subscription!\n");
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->addSubscription(address);
|
2016-08-27 00:51:00 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Logger::Print("Address not correct!\n");
|
|
|
|
}
|
|
|
|
});
|
2016-08-31 06:26:47 -04:00
|
|
|
#endif
|
2016-08-27 00:51:00 -04:00
|
|
|
}
|
|
|
|
|
2016-08-28 13:38:16 -04:00
|
|
|
BitMessage::~BitMessage()
|
|
|
|
{
|
2016-08-30 06:23:53 -04:00
|
|
|
delete BitMessage::BMClient;
|
|
|
|
BitMessage::BMClient = nullptr;
|
2016-08-28 13:38:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void BitMessage::SetDefaultTTL(time_t ttl)
|
|
|
|
{
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->defaultTTL = ttl;
|
2016-08-28 13:38:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool BitMessage::RequestPublicKey(std::string targetAddress)
|
|
|
|
{
|
|
|
|
// Convert to ustring
|
|
|
|
ustring targetAddressU;
|
|
|
|
targetAddressU.fromString(targetAddress);
|
|
|
|
|
|
|
|
// Convert to PubAddr
|
|
|
|
PubAddr pubAddr;
|
|
|
|
if (!pubAddr.loadAddr(targetAddressU))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Request public key!
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->getPubKey(pubAddr);
|
2016-08-28 13:38:16 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-29 04:10:37 -04:00
|
|
|
PubAddr* BitMessage::FindPublicKey(PubAddr address)
|
|
|
|
{
|
2016-08-30 06:23:53 -04:00
|
|
|
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_pub);
|
2016-08-29 04:10:37 -04:00
|
|
|
|
|
|
|
PubAddr* retval = nullptr;
|
|
|
|
|
2016-08-30 06:23:53 -04:00
|
|
|
for (auto& pubKey : BitMessage::BMClient->PubAddresses)
|
2016-08-29 04:10:37 -04:00
|
|
|
{
|
|
|
|
if (pubKey.getVersion() == address.getVersion()) //check same version
|
|
|
|
{
|
|
|
|
if ((address.getVersion() >= 4 && pubKey.getTag() == address.getTag()) // version 4+ equality check
|
|
|
|
|| (pubKey.getRipe() == address.getRipe())) // version 3- equality check
|
|
|
|
{
|
|
|
|
retval = &pubKey;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-30 06:23:53 -04:00
|
|
|
|
2016-08-29 04:10:37 -04:00
|
|
|
mlock.unlock();
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool BitMessage::WaitForPublicKey(std::string targetAddress)
|
2016-08-29 02:58:04 -04:00
|
|
|
{
|
|
|
|
// Convert to ustring
|
|
|
|
ustring targetAddressU;
|
|
|
|
targetAddressU.fromString(targetAddress);
|
|
|
|
|
|
|
|
// Convert to PubAddr
|
2016-08-29 04:10:37 -04:00
|
|
|
PubAddr address;
|
|
|
|
if (!address.loadAddr(targetAddressU))
|
2016-08-29 02:58:04 -04:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-29 04:10:37 -04:00
|
|
|
// Resolve our own copy to the registered PubAddr copy in BitMRC if possible
|
|
|
|
auto resolvedAddress = FindPublicKey(address);
|
|
|
|
if (resolvedAddress != nullptr &&
|
|
|
|
!resolvedAddress->waitingPubKey() && !resolvedAddress->getPubEncryptionKey().empty())
|
|
|
|
return true;
|
2016-08-29 02:58:04 -04:00
|
|
|
|
2016-08-29 04:10:37 -04:00
|
|
|
if (resolvedAddress == nullptr ||
|
|
|
|
(!resolvedAddress->waitingPubKey() && resolvedAddress->getPubEncryptionKey().empty()))
|
2016-08-29 02:58:04 -04:00
|
|
|
{
|
2016-08-29 04:10:37 -04:00
|
|
|
// Request public key
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->getPubKey(address);
|
2016-08-29 04:10:37 -04:00
|
|
|
resolvedAddress = FindPublicKey(address);
|
|
|
|
}
|
2016-08-30 06:23:53 -04:00
|
|
|
|
|
|
|
BitMessage::Save();
|
2016-08-29 04:10:37 -04:00
|
|
|
|
|
|
|
// TODO: Wait for public key by using signaling in BitMRC, needs to be done directly in the fork.
|
|
|
|
while (resolvedAddress->waitingPubKey())
|
|
|
|
{
|
2016-08-30 06:23:53 -04:00
|
|
|
std::this_thread::sleep_for(1500ms);
|
2016-08-29 04:10:37 -04:00
|
|
|
}
|
2016-08-30 06:23:53 -04:00
|
|
|
|
|
|
|
BitMessage::Save();
|
2016-08-29 02:58:04 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-28 13:38:16 -04:00
|
|
|
bool BitMessage::Subscribe(std::string targetAddress)
|
|
|
|
{
|
|
|
|
// Convert to ustring
|
|
|
|
ustring targetAddressU;
|
|
|
|
targetAddressU.fromString(targetAddress);
|
|
|
|
|
|
|
|
// Convert to PubAddr
|
|
|
|
PubAddr pubAddr;
|
|
|
|
if (!pubAddr.loadAddr(targetAddressU))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Subscribe!
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->addSubscription(pubAddr);
|
2016-08-28 13:38:16 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool BitMessage::SendMsg(std::string targetAddress, std::string message, time_t ttl)
|
|
|
|
{
|
|
|
|
// Convert target address to ustring
|
|
|
|
ustring targetAddressU;
|
|
|
|
targetAddressU.fromString(targetAddress);
|
|
|
|
|
|
|
|
// Convert target address to PubAddr
|
|
|
|
PubAddr pubAddr;
|
|
|
|
if (!pubAddr.loadAddr(targetAddressU))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert message to ustring
|
|
|
|
ustring messageU;
|
|
|
|
messageU.fromString(message);
|
|
|
|
|
|
|
|
// Send the message
|
|
|
|
// TODO - Set mutex on priv when accessing first private address
|
|
|
|
if (ttl > 0)
|
2016-08-30 06:23:53 -04:00
|
|
|
{
|
|
|
|
BitMessage::BMClient->sendMessage(messageU, pubAddr, BitMessage::BMClient->PrivAddresses[0], ttl);
|
|
|
|
}
|
2016-08-28 13:38:16 -04:00
|
|
|
else
|
2016-08-30 06:23:53 -04:00
|
|
|
{
|
|
|
|
BitMessage::BMClient->sendMessage(messageU, pubAddr, BitMessage::BMClient->PrivAddresses[0]);
|
|
|
|
}
|
|
|
|
|
2016-08-28 13:38:16 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool BitMessage::SendBroadcast(std::string message, time_t ttl)
|
|
|
|
{
|
|
|
|
// Convert message to ustring
|
|
|
|
ustring messageU;
|
|
|
|
messageU.fromString(message);
|
|
|
|
|
|
|
|
// TODO - Set mutex on priv when accessing first private address
|
|
|
|
if (ttl > 0)
|
2016-08-30 06:23:53 -04:00
|
|
|
{
|
|
|
|
BitMessage::BMClient->sendBroadcast(messageU, BitMessage::BMClient->PrivAddresses[0], ttl);
|
|
|
|
}
|
2016-08-28 13:38:16 -04:00
|
|
|
else
|
2016-08-30 06:23:53 -04:00
|
|
|
{
|
|
|
|
BitMessage::BMClient->sendBroadcast(messageU, BitMessage::BMClient->PrivAddresses[0]);
|
|
|
|
}
|
|
|
|
|
2016-08-28 13:38:16 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-27 00:51:00 -04:00
|
|
|
bool BitMessage::InitAddr()
|
|
|
|
{
|
2016-08-31 09:29:59 -04:00
|
|
|
#ifdef DEBUG
|
2016-08-27 00:51:00 -04:00
|
|
|
Logger::Print("Generating BM address...\n");
|
2016-08-31 09:29:59 -04:00
|
|
|
#endif
|
2016-08-27 00:51:00 -04:00
|
|
|
Addr myAddress;
|
|
|
|
if (!myAddress.generateRandom())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-30 06:23:53 -04:00
|
|
|
|
|
|
|
BitMessage::BMClient->addAddr(myAddress);
|
2016-08-27 00:51:00 -04:00
|
|
|
return true;
|
|
|
|
}
|
2016-08-29 02:58:04 -04:00
|
|
|
|
|
|
|
void BitMessage::Save()
|
|
|
|
{
|
2016-08-30 06:23:53 -04:00
|
|
|
BitMessage::BMClient->save();
|
2016-08-29 02:58:04 -04:00
|
|
|
}
|
2016-08-27 00:51:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|