Skip to content
Permalink
Browse files

atomic swap: process invalid credentials

  • Loading branch information...
roman-strilets committed Jun 6, 2019
1 parent 9221a7f commit 53d0c68d2c3446c394ecf56702fe26eac6e4d2e0
@@ -301,6 +301,10 @@ class HttpMessageImpl : public HttpMessage, public HeadersParserStuff {
return _body.data();
}

int get_status() const override {
return response_status;
}

public:
std::vector<uint8_t> _body;
size_t _bodyCursor=0;
@@ -55,6 +55,7 @@ class HttpMessage {
virtual const std::string& get_path() const = 0;
virtual const std::string& get_header(const std::string& headerName) const = 0;
virtual const void* get_body(size_t& size) const = 0;
virtual int get_status() const = 0;
};

/// Extracts individual http messages from stream, performs header/size validation
@@ -31,7 +31,8 @@ namespace beam
None,
InvalidResultFormat,
IOError,
BitcoinError
BitcoinError,
InvalidCredentials
};

struct Error
@@ -445,6 +445,9 @@ namespace beam::wallet
case IBitcoinBridge::IOError:
m_tx.SetParameter(TxParameterID::InternalFailureReason, TxFailureReason::SwapNetworkBridgeError, false, subTxID);
break;
case IBitcoinBridge::InvalidCredentials:
m_tx.SetParameter(TxParameterID::InternalFailureReason, TxFailureReason::InvalidCredentialsOfSideChain, false, subTxID);
break;
default:
m_tx.SetParameter(TxParameterID::InternalFailureReason, TxFailureReason::SwapSecondSideBridgeError, false, subTxID);
}
@@ -424,18 +424,38 @@ namespace beam

if (msg.what == HttpMsgReader::http_message)
{
size_t sz = 0;
const void* body = msg.msg->get_body(sz);
if (sz > 0 && body)
switch (msg.msg->get_status())
{
response = std::string(static_cast<const char*>(body), sz);
LOG_DEBUG() << "Bitcoin response: " << response;
case 200:
{
size_t sz = 0;
const void* body = msg.msg->get_body(sz);
if (sz > 0 && body)
{
response = std::string(static_cast<const char*>(body), sz);
LOG_DEBUG() << "Bitcoin response: " << response;
}
else
{
error.m_type = InvalidResultFormat;
error.m_message = "Empty response.";
}
break;
}
case 401:
{
error.m_type = InvalidCredentials;
error.m_message = "Invalid credentials.";
break;
}
else
default:
{
error.m_type = InvalidResultFormat;
error.m_message = "Empty response. Maybe wrong credentials.";
error.m_type = IOError;
error.m_message = "HTTP status: " + std::to_string(msg.msg->get_status());
break;
}
}

}
else
{
@@ -112,6 +112,7 @@ namespace beam::wallet
MACRO(SwapSecondSideBridgeError, 17, "Side chain bridge has internal error") \
MACRO(SwapNetworkBridgeError, 18, "Side chain bridge has network error") \
MACRO(SwapFormatResponseError, 19, "Side chain bridge has format response error") \
MACRO(InvalidCredentialsOfSideChain, 20, "Invalid credentinals of Side chain") \

enum TxFailureReason : int32_t
{
@@ -20,18 +20,35 @@
#include "utility/helpers.h"
#include "nlohmann/json.hpp"

#include "3rdparty/libbitcoin/include/bitcoin/bitcoin.hpp"

const uint16_t PORT = 13300;
const std::string btcUserName = "Alice";
const std::string btcPass = "123";

using namespace beam;
using json = nlohmann::json;

namespace
{
// TODO roman.strilec: temporary solution
std::string generateAuthorization(const std::string& userName, const std::string& pass)
{
std::string userWithPass(userName + ":" + pass);
libbitcoin::data_chunk t(userWithPass.begin(), userWithPass.end());
return std::string("Basic " + libbitcoin::encode_base64(t));
}
}

class BitcoinHttpServer
{
public:
BitcoinHttpServer()
BitcoinHttpServer(const std::string& userName = btcUserName, const std::string& pass = btcPass)
: m_reactor(io::Reactor::get_Current())
, m_msgCreator(1000)
, m_lastId(0)
, m_userName(userName)
, m_pass(pass)
{
m_server = io::TcpServer::create(
m_reactor,
@@ -119,18 +136,28 @@ class BitcoinHttpServer
{"Server", "BitcoinHttpServer"}
};

size_t sz = 0;
const void* rawReq = msg.msg->get_body(sz);
std::string result;
if (sz > 0 && rawReq)
int responseStatus = 200;

if (msg.msg->get_header("Authorization") == generateAuthorization(m_userName, m_pass))
{
std::string str(static_cast<const char*>(rawReq), sz);
result = generateResponse(str);
size_t sz = 0;
const void* rawReq = msg.msg->get_body(sz);

if (sz > 0 && rawReq)
{
std::string str(static_cast<const char*>(rawReq), sz);
result = generateResponse(str);
}
else
{
LOG_ERROR() << "Request is wrong";
stopServer();
}
}
else
{
LOG_ERROR() << "Request is wrong";
stopServer();
responseStatus = 401;
}

io::SharedBuffer body;
@@ -139,7 +166,7 @@ class BitcoinHttpServer
io::SerializedMsg serialized;

if (m_connections[peerId] && m_msgCreator.create_response(
serialized, 200, message, headers, sizeof(headers) / sizeof(HeaderPair),
serialized, responseStatus, message, headers, sizeof(headers) / sizeof(HeaderPair),
1, "text/plain", body.size))
{
serialized.push_back(body);
@@ -192,4 +219,6 @@ class BitcoinHttpServer
std::map<uint64_t, HttpConnection::Ptr> m_connections;
HttpMsgCreator m_msgCreator;
uint64_t m_lastId;
std::string m_userName;
std::string m_pass;
};
@@ -45,8 +45,8 @@ void testSuccessResponse()
BitcoinOptions options;

options.m_address = addr;
options.m_userName = "Alice";
options.m_pass = "123";
options.m_userName = btcUserName;
options.m_pass = btcPass;

Bitcoind016 bridge(*reactor, options);

@@ -111,6 +111,36 @@ void testSuccessResponse()
reactor->run();
}

void testWrongCredentials()
{
io::Reactor::Ptr reactor = io::Reactor::create();
io::Timer::Ptr timer(io::Timer::create(*reactor));
io::Reactor::Scope scope(*reactor);

timer->start(5000, false, [&reactor]() {
reactor->stop();
});

BitcoinHttpServer httpServer("Bob", "123");

io::Address addr(io::Address::localhost(), PORT);
BitcoinOptions options;

options.m_address = addr;
options.m_userName = btcUserName;
options.m_pass = btcPass;

Bitcoind016 bridge(*reactor, options);

bridge.getBlockCount([](const IBitcoinBridge::Error& error, uint64_t blocks)
{
WALLET_CHECK(error.m_type == IBitcoinBridge::InvalidCredentials);
WALLET_CHECK(blocks == 0);
});

reactor->run();
}

int main()
{
int logLevel = LOG_LEVEL_DEBUG;
@@ -120,5 +150,8 @@ int main()
auto logger = beam::Logger::create(logLevel, logLevel);

testSuccessResponse();
return 0;
testWrongCredentials();

assert(g_failureCount == 0);
return WALLET_CHECK_RESULT;
}

0 comments on commit 53d0c68

Please sign in to comment.
You can’t perform that action at this time.