Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 24 additions & 21 deletions src/xrpld/app/misc/CredentialHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ deleteSLE(
}

NotTEC
checkFields(PreflightContext const& ctx)
checkFields(STTx const& tx, beast::Journal j)
{
if (!ctx.tx.isFieldPresent(sfCredentialIDs))
if (!tx.isFieldPresent(sfCredentialIDs))
return tesSUCCESS;

auto const& credentials = ctx.tx.getFieldV256(sfCredentialIDs);
auto const& credentials = tx.getFieldV256(sfCredentialIDs);
if (credentials.empty() || (credentials.size() > maxCredentialsArraySize))
{
JLOG(ctx.j.trace())
JLOG(j.trace())
<< "Malformed transaction: Credentials array size is invalid: "
<< credentials.size();
return temMALFORMED;
Expand All @@ -140,7 +140,7 @@ checkFields(PreflightContext const& ctx)
auto [it, ins] = duplicates.insert(cred);
if (!ins)
{
JLOG(ctx.j.trace())
JLOG(j.trace())
<< "Malformed transaction: duplicates in credentials.";
return temMALFORMED;
}
Expand All @@ -150,32 +150,36 @@ checkFields(PreflightContext const& ctx)
}

TER
valid(PreclaimContext const& ctx, AccountID const& src)
valid(
STTx const& tx,
ReadView const& view,
AccountID const& src,
beast::Journal j)
{
if (!ctx.tx.isFieldPresent(sfCredentialIDs))
if (!tx.isFieldPresent(sfCredentialIDs))
return tesSUCCESS;

auto const& credIDs(ctx.tx.getFieldV256(sfCredentialIDs));
auto const& credIDs(tx.getFieldV256(sfCredentialIDs));
for (auto const& h : credIDs)
{
auto const sleCred = ctx.view.read(keylet::credential(h));
auto const sleCred = view.read(keylet::credential(h));
if (!sleCred)
{
JLOG(ctx.j.trace()) << "Credential doesn't exist. Cred: " << h;
JLOG(j.trace()) << "Credential doesn't exist. Cred: " << h;
return tecBAD_CREDENTIALS;
}

if (sleCred->getAccountID(sfSubject) != src)
{
JLOG(ctx.j.trace())
JLOG(j.trace())
<< "Credential doesn't belong to the source account. Cred: "
<< h;
return tecBAD_CREDENTIALS;
}

if (!(sleCred->getFlags() & lsfAccepted))
{
JLOG(ctx.j.trace()) << "Credential isn't accepted. Cred: " << h;
JLOG(j.trace()) << "Credential isn't accepted. Cred: " << h;
return tecBAD_CREDENTIALS;
}

Expand Down Expand Up @@ -352,35 +356,34 @@ verifyValidDomain(

TER
verifyDepositPreauth(
ApplyContext& ctx,
STTx const& tx,
ApplyView& view,
AccountID const& src,
AccountID const& dst,
std::shared_ptr<SLE> const& sleDst)
std::shared_ptr<SLE> const& sleDst,
beast::Journal j)
{
// If depositPreauth is enabled, then an account that requires
// authorization has at least two ways to get a payment in:
// 1. If src == dst, or
// 2. If src is deposit preauthorized by dst (either by account or by
// credentials).

bool const credentialsPresent = ctx.tx.isFieldPresent(sfCredentialIDs);
bool const credentialsPresent = tx.isFieldPresent(sfCredentialIDs);

if (credentialsPresent &&
credentials::removeExpired(
ctx.view(), ctx.tx.getFieldV256(sfCredentialIDs), ctx.journal))
credentials::removeExpired(view, tx.getFieldV256(sfCredentialIDs), j))
return tecEXPIRED;

if (sleDst && (sleDst->getFlags() & lsfDepositAuth))
{
if (src != dst)
{
if (!ctx.view().exists(keylet::depositPreauth(dst, src)))
if (!view.exists(keylet::depositPreauth(dst, src)))
return !credentialsPresent
? tecNO_PERMISSION
: credentials::authorizedDepositPreauth(
ctx.view(),
ctx.tx.getFieldV256(sfCredentialIDs),
dst);
view, tx.getFieldV256(sfCredentialIDs), dst);
}
}

Expand Down
25 changes: 20 additions & 5 deletions src/xrpld/app/misc/CredentialHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,16 @@
#ifndef RIPPLE_APP_MISC_CREDENTIALHELPERS_H_INCLUDED
#define RIPPLE_APP_MISC_CREDENTIALHELPERS_H_INCLUDED

#include <xrpld/app/tx/detail/Transactor.h>
#include <xrpld/ledger/ApplyView.h>
#include <xrpld/ledger/ReadView.h>

#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>

namespace ripple {
namespace credentials {
Expand Down Expand Up @@ -48,13 +57,17 @@ deleteSLE(

// Amendment and parameters checks for sfCredentialIDs field
NotTEC
checkFields(PreflightContext const& ctx);
checkFields(STTx const& tx, beast::Journal j);

// Accessing the ledger to check if provided credentials are valid. Do not use
// in doApply (only in preclaim) since it does not remove expired credentials.
// If you call it in prelaim, you also must call verifyDepositPreauth in doApply
TER
valid(PreclaimContext const& ctx, AccountID const& src);
valid(
STTx const& tx,
ReadView const& view,
AccountID const& src,
beast::Journal j);

// Check if subject has any credential maching the given domain. If you call it
// in preclaim and it returns tecEXPIRED, you should call verifyValidDomain in
Expand Down Expand Up @@ -93,10 +106,12 @@ verifyValidDomain(
// Check expired credentials and for existing DepositPreauth ledger object
TER
verifyDepositPreauth(
ApplyContext& ctx,
STTx const& tx,
ApplyView& view,
AccountID const& src,
AccountID const& dst,
std::shared_ptr<SLE> const& sleDst);
std::shared_ptr<SLE> const& sleDst,
beast::Journal j);

} // namespace ripple

Expand Down
9 changes: 6 additions & 3 deletions src/xrpld/app/tx/detail/DeleteAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ DeleteAccount::preflight(PreflightContext const& ctx)
// An account cannot be deleted and give itself the resulting XRP.
return temDST_IS_SRC;

if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
!isTesSuccess(err))
return err;

return preflight2(ctx);
Expand Down Expand Up @@ -241,7 +242,8 @@ DeleteAccount::preclaim(PreclaimContext const& ctx)
return tecDST_TAG_NEEDED;

// If credentials are provided - check them anyway
if (auto const err = credentials::valid(ctx, account); !isTesSuccess(err))
if (auto const err = credentials::valid(ctx.tx, ctx.view, account, ctx.j);
!isTesSuccess(err))
return err;

// if credentials then postpone auth check to doApply, to check for expired
Expand Down Expand Up @@ -376,7 +378,8 @@ DeleteAccount::doApply()
if (ctx_.view().rules().enabled(featureDepositAuth) &&
ctx_.tx.isFieldPresent(sfCredentialIDs))
{
if (auto err = verifyDepositPreauth(ctx_, account_, dstID, dst);
if (auto err = verifyDepositPreauth(
ctx_.tx, ctx_.view(), account_, dstID, dst, ctx_.journal);
!isTesSuccess(err))
return err;
}
Expand Down
9 changes: 6 additions & 3 deletions src/xrpld/app/tx/detail/Escrow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,8 @@ EscrowFinish::preflight(PreflightContext const& ctx)
}
}

if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
!isTesSuccess(err))
return err;

return tesSUCCESS;
Expand Down Expand Up @@ -761,7 +762,8 @@ EscrowFinish::preclaim(PreclaimContext const& ctx)
{
if (ctx.view.rules().enabled(featureCredentials))
{
if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]);
if (auto const err =
credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j);
!isTesSuccess(err))
return err;
}
Expand Down Expand Up @@ -1107,7 +1109,8 @@ EscrowFinish::doApply()

if (ctx_.view().rules().enabled(featureDepositAuth))
{
if (auto err = verifyDepositPreauth(ctx_, account_, destID, sled);
if (auto err = verifyDepositPreauth(
ctx_.tx, ctx_.view(), account_, destID, sled, ctx_.journal);
!isTesSuccess(err))
return err;
}
Expand Down
9 changes: 6 additions & 3 deletions src/xrpld/app/tx/detail/PayChan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,8 @@ PayChanClaim::preflight(PreflightContext const& ctx)
return temBAD_SIGNATURE;
}

if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
!isTesSuccess(err))
return err;

return preflight2(ctx);
Expand All @@ -485,7 +486,8 @@ PayChanClaim::preclaim(PreclaimContext const& ctx)
if (!ctx.view.rules().enabled(featureCredentials))
return Transactor::preclaim(ctx);

if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]);
if (auto const err =
credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j);
!isTesSuccess(err))
return err;

Expand Down Expand Up @@ -554,7 +556,8 @@ PayChanClaim::doApply()

if (depositAuth)
{
if (auto err = verifyDepositPreauth(ctx_, txAccount, dst, sled);
if (auto err = verifyDepositPreauth(
ctx_.tx, ctx_.view(), txAccount, dst, sled, ctx_.journal);
!isTesSuccess(err))
return err;
}
Expand Down
33 changes: 25 additions & 8 deletions src/xrpld/app/tx/detail/Payment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ Payment::preflight(PreflightContext const& ctx)
}
}

if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
!isTesSuccess(err))
return err;

return preflight2(ctx);
Expand Down Expand Up @@ -358,7 +359,8 @@ Payment::preclaim(PreclaimContext const& ctx)
}
}

if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]);
if (auto const err =
credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j);
!isTesSuccess(err))
return err;

Expand Down Expand Up @@ -450,8 +452,13 @@ Payment::doApply()
// 1. If Account == Destination, or
// 2. If Account is deposit preauthorized by destination.

if (auto err =
verifyDepositPreauth(ctx_, account_, dstAccountID, sleDst);
if (auto err = verifyDepositPreauth(
ctx_.tx,
ctx_.view(),
account_,
dstAccountID,
sleDst,
ctx_.journal);
!isTesSuccess(err))
return err;
}
Expand Down Expand Up @@ -521,8 +528,13 @@ Payment::doApply()
ter != tesSUCCESS)
return ter;

if (auto err =
verifyDepositPreauth(ctx_, account_, dstAccountID, sleDst);
if (auto err = verifyDepositPreauth(
ctx_.tx,
ctx_.view(),
account_,
dstAccountID,
sleDst,
ctx_.journal);
!isTesSuccess(err))
return err;

Expand Down Expand Up @@ -644,8 +656,13 @@ Payment::doApply()
if (dstAmount > dstReserve ||
sleDst->getFieldAmount(sfBalance) > dstReserve)
{
if (auto err =
verifyDepositPreauth(ctx_, account_, dstAccountID, sleDst);
if (auto err = verifyDepositPreauth(
ctx_.tx,
ctx_.view(),
account_,
dstAccountID,
sleDst,
ctx_.journal);
!isTesSuccess(err))
return err;
}
Expand Down
Loading