mirror of
				https://github.com/XRPLF/clio.git
				synced 2025-11-04 11:55:51 +00:00 
			
		
		
		
	@@ -66,7 +66,7 @@
 | 
			
		||||
        // Max number of requests to queue up before rejecting further requests.
 | 
			
		||||
        // Defaults to 0, which disables the limit.
 | 
			
		||||
        "max_queue_size": 500,
 | 
			
		||||
        // If request contains header with authorization, Clio will check if it matches this value's sha256 hash
 | 
			
		||||
        // If request contains header with authorization, Clio will check if it matches the prefix 'Password ' + this value's sha256 hash
 | 
			
		||||
        // If matches, the request will be considered as admin request
 | 
			
		||||
        "admin_password": "xrp",
 | 
			
		||||
        // If local_admin is true, Clio will consider requests come from 127.0.0.1 as admin requests
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
#include <rpc/RPCHelpers.h>
 | 
			
		||||
#include <rpc/common/Types.h>
 | 
			
		||||
#include <rpc/common/Validators.h>
 | 
			
		||||
#include <util/JsonUtils.h>
 | 
			
		||||
 | 
			
		||||
namespace rpc {
 | 
			
		||||
 | 
			
		||||
@@ -224,8 +225,10 @@ private:
 | 
			
		||||
        if (jsonObject.contains(JS(transaction)))
 | 
			
		||||
            input.transaction = jv.at(JS(transaction)).as_string().c_str();
 | 
			
		||||
 | 
			
		||||
        if (jsonObject.contains(JS(ctid)))
 | 
			
		||||
        if (jsonObject.contains(JS(ctid))) {
 | 
			
		||||
            input.ctid = jv.at(JS(ctid)).as_string().c_str();
 | 
			
		||||
            input.ctid = util::toUpper(*input.ctid);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (jsonObject.contains(JS(binary)))
 | 
			
		||||
            input.binary = jv.at(JS(binary)).as_bool();
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,13 @@ toLower(std::string str)
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline std::string
 | 
			
		||||
toUpper(std::string str)
 | 
			
		||||
{
 | 
			
		||||
    std::transform(std::begin(str), std::end(str), std::begin(str), [](unsigned char c) { return std::toupper(c); });
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Removes any detected secret information from a response JSON object.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <fmt/format.h>
 | 
			
		||||
#include <util/JsonUtils.h>
 | 
			
		||||
#include <web/impl/AdminVerificationStrategy.h>
 | 
			
		||||
 | 
			
		||||
#include <ripple/protocol/digest.h>
 | 
			
		||||
@@ -39,7 +40,7 @@ PasswordAdminVerificationStrategy::PasswordAdminVerificationStrategy(std::string
 | 
			
		||||
    std::memcpy(sha256.data(), d.data(), d.size());
 | 
			
		||||
    passwordSha256_ = ripple::to_string(sha256);
 | 
			
		||||
    // make sure it's uppercase
 | 
			
		||||
    std::transform(passwordSha256_.begin(), passwordSha256_.end(), passwordSha256_.begin(), ::toupper);
 | 
			
		||||
    passwordSha256_ = util::toUpper(std::move(passwordSha256_));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
@@ -55,11 +56,9 @@ PasswordAdminVerificationStrategy::isAdmin(RequestType const& request, std::stri
 | 
			
		||||
        // Invalid Authorization header
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    userAuth.remove_prefix(passwordPrefix.size());
 | 
			
		||||
    std::string userPasswordHash;
 | 
			
		||||
    userPasswordHash.reserve(userAuth.size());
 | 
			
		||||
    std::transform(userAuth.begin(), userAuth.end(), std::back_inserter(userPasswordHash), ::toupper);
 | 
			
		||||
    return passwordSha256_ == userPasswordHash;
 | 
			
		||||
    return passwordSha256_ == util::toUpper(userAuth);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<AdminVerificationStrategy>
 | 
			
		||||
 
 | 
			
		||||
@@ -913,3 +913,42 @@ TEST_F(RPCTxTest, ViaCTID)
 | 
			
		||||
        EXPECT_EQ(*output, json::parse(OUT));
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(RPCTxTest, ViaLowercaseCTID)
 | 
			
		||||
{
 | 
			
		||||
    auto const rawBackendPtr = dynamic_cast<MockBackend*>(mockBackendPtr.get());
 | 
			
		||||
    TransactionAndMetadata tx1;
 | 
			
		||||
    tx1.metadata = CreateMetaDataForCreateOffer(CURRENCY, ACCOUNT, 1, 200, 300).getSerializer().peekData();
 | 
			
		||||
    tx1.transaction =
 | 
			
		||||
        CreateCreateOfferTransactionObject(ACCOUNT, 2, 100, CURRENCY, ACCOUNT2, 200, 300).getSerializer().peekData();
 | 
			
		||||
    tx1.date = 123456;
 | 
			
		||||
    tx1.ledgerSequence = SEQ_FROM_CTID;
 | 
			
		||||
 | 
			
		||||
    TransactionAndMetadata tx2;
 | 
			
		||||
    tx2.transaction = CreatePaymentTransactionObject(ACCOUNT, ACCOUNT2, 2, 3, 300).getSerializer().peekData();
 | 
			
		||||
    tx2.metadata = CreatePaymentTransactionMetaObject(ACCOUNT, ACCOUNT2, 110, 30).getSerializer().peekData();
 | 
			
		||||
    tx2.ledgerSequence = SEQ_FROM_CTID;
 | 
			
		||||
 | 
			
		||||
    EXPECT_CALL(*rawBackendPtr, fetchAllTransactionsInLedger(SEQ_FROM_CTID, _)).WillOnce(Return(std::vector{tx1, tx2}));
 | 
			
		||||
 | 
			
		||||
    auto const rawETLPtr = dynamic_cast<MockETLService*>(mockETLServicePtr.get());
 | 
			
		||||
    ASSERT_NE(rawETLPtr, nullptr);
 | 
			
		||||
    EXPECT_CALL(*rawETLPtr, getETLState).WillOnce(Return(etl::ETLState{.networkID = 2}));
 | 
			
		||||
 | 
			
		||||
    std::string ctid(CTID);
 | 
			
		||||
    std::transform(ctid.begin(), ctid.end(), ctid.begin(), ::tolower);
 | 
			
		||||
 | 
			
		||||
    runSpawn([&, this](auto yield) {
 | 
			
		||||
        auto const handler = AnyHandler{TestTxHandler{mockBackendPtr, mockETLServicePtr}};
 | 
			
		||||
        auto const req = json::parse(fmt::format(
 | 
			
		||||
            R"({{ 
 | 
			
		||||
                "command": "tx",
 | 
			
		||||
                "ctid": "{}"
 | 
			
		||||
            }})",
 | 
			
		||||
            ctid
 | 
			
		||||
        ));
 | 
			
		||||
        auto const output = handler.process(req, Context{yield});
 | 
			
		||||
        ASSERT_TRUE(output);
 | 
			
		||||
        EXPECT_EQ(output->at("ctid").as_string(), CTID);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user