Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Ref #7: Check all declared auths get required
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanielhourt committed Aug 3, 2017
1 parent 83b309b commit 91b7800
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 4 deletions.
10 changes: 7 additions & 3 deletions libraries/chain/chain_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,11 @@ void chain_controller::process_message( const ProcessedTransaction& trx, Account
apply_context apply_ctx(*this, _db, trx, message, code);
apply_message(apply_ctx);

// process_message recurses for each notified account, but we only want to run this check at the top level
if (code == message.code && (_skip_flags & skip_authority_check) == false)
EOS_ASSERT(apply_ctx.all_authorizations_used(), tx_irrelevant_auth,
"Message declared an authority it did not need", ("message", message));

output.notify.reserve( apply_ctx.notified.size() );

for( uint32_t i = 0; i < apply_ctx.notified.size(); ++i ) {
Expand Down Expand Up @@ -832,11 +837,10 @@ void chain_controller::initialize_chain(chain_initializer_interface& starter)
std::for_each(messages.begin(), messages.end(), [&](const Message& m) {
MessageOutput output;
ProcessedTransaction trx; /// dummy tranaction required for scope validation
trx.scope = { config::EosContractName, "inita" };
std::sort(trx.scope.begin(), trx.scope.end() );
with_skip_flags( skip_scope_check, [&](){
with_skip_flags(skip_scope_check | skip_transaction_signatures | skip_authority_check, [&](){
process_message(trx,m.code,m,output);
} );
});
});
});
}
Expand Down
16 changes: 15 additions & 1 deletion libraries/chain/include/eos/chain/message_handling_contexts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class apply_context {
const chain::Transaction& t,
const chain::Message& m,
const types::AccountName& code)
:controller(con),db(db),trx(t),msg(m),code(code),mutable_controller(con),mutable_db(db){}
: controller(con), db(db), trx(t), msg(m), code(code), mutable_controller(con),
mutable_db(db), used_authorizations(msg.authorization.size(), false){}

int32_t store_i64( Name scope, Name table, Name key, const char* data, uint32_t len);
int32_t remove_i64( Name scope, Name table, Name key );
Expand All @@ -44,11 +45,22 @@ class apply_context {
int32_t lowerbound_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );

/**
* @brief Require @ref account to have approved of this message
* @param account The account whose approval is required
*
* This method will check that @ref account is listed in the message's declared authorizations, and marks the
* authorization as used. Note that all authorizations on a message must be used, or the message is invalid.
*
* @throws tx_missing_auth If no sufficient permission was found
*/
void require_authorization(const types::AccountName& account);
void require_scope(const types::AccountName& account)const;
bool has_recipient( const types::AccountName& account )const;
void require_recipient(const types::AccountName& account);

bool all_authorizations_used() const;

const chain_controller& controller;
const chainbase::database& db; ///< database where state is stored
const chain::Transaction& trx; ///< used to gather the valid read/write scopes
Expand All @@ -62,6 +74,8 @@ class apply_context {
std::deque<ProcessedTransaction> sync_transactions; ///< sync calls made
std::deque<GeneratedTransaction> async_transactions; ///< async calls requested

///< Parallel to msg.authorization; tracks which permissions have been used while processing the message
vector<bool> used_authorizations;
};

using apply_handler = std::function<void(apply_context&)>;
Expand Down
5 changes: 5 additions & 0 deletions libraries/chain/message_handling_contexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ void apply_context::require_authorization(const types::AccountName& account) {
auto itr = boost::find_if(msg.authorization, [&account](const auto& auth) { return auth.account == account; });
EOS_ASSERT(itr != msg.authorization.end(), tx_missing_auth,
"Transaction is missing required authorization from ${acct}", ("acct", account));
used_authorizations[itr - msg.authorization.begin()] = true;
}

void apply_context::require_scope(const types::AccountName& account)const {
Expand All @@ -26,6 +27,10 @@ void apply_context::require_scope(const types::AccountName& account)const {
}
}

bool apply_context::all_authorizations_used() const {
return boost::algorithm::all_of_equal(used_authorizations, true);
}

bool apply_context::has_recipient( const types::AccountName& account )const {
if( msg.code == account ) return true;

Expand Down
22 changes: 22 additions & 0 deletions tests/tests/block_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,28 @@ BOOST_FIXTURE_TEST_CASE(trx_variant, testing_fixture) {
}
}

BOOST_FIXTURE_TEST_CASE(irrelevant_auth, testing_fixture) {
try {
Make_Blockchain(chain)
Make_Account(chain, joe);
chain.produce_blocks();

ProcessedTransaction trx;
trx.scope = sort_names({"joe", "inita"});
trx.emplaceMessage(config::EosContractName, vector<types::AccountPermission>{{"inita", "active"}},
"transfer", types::transfer{"inita", "joe", 50});
trx.expiration = chain.head_block_time() + 100;
trx.set_reference_block(chain.head_block_id());
chain.push_transaction(trx, chain_controller::skip_transaction_signatures);

chain.clear_pending();
chain.push_transaction(trx, chain_controller::skip_transaction_signatures);
chain.clear_pending();

trx.messages.front().authorization.emplace_back(types::AccountPermission{"initb", "active"});
BOOST_CHECK_THROW(chain.push_transaction(trx, chain_controller::skip_transaction_signatures), tx_irrelevant_auth);
} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(name_test) {
using eos::types::Name;
Name temp;
Expand Down

0 comments on commit 91b7800

Please sign in to comment.