From c93dd98b057c5dd9026c4983ee806f2353cd3eeb Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 1 Dec 2020 01:50:37 -0800 Subject: [PATCH] ircd::m::vm: Simplify redaction authority options; fix conditions. --- include/ircd/m/vm.h | 15 +++++--------- matrix/event_conforms.cc | 43 +++++++++++++++------------------------- matrix/vm_execute.cc | 31 +++++++++++------------------ 3 files changed, 33 insertions(+), 56 deletions(-) diff --git a/include/ircd/m/vm.h b/include/ircd/m/vm.h index c99542f41..4e1a9b8bd 100644 --- a/include/ircd/m/vm.h +++ b/include/ircd/m/vm.h @@ -98,7 +98,6 @@ struct ircd::m::vm::eval hook::base *hook {nullptr}; vm::phase phase {vm::phase(0)}; bool room_internal {false}; - bool redacted {false}; void mfetch_keys() const; @@ -235,18 +234,14 @@ struct ircd::m::vm::opts /// done before eval. event::conforms report; - /// True hints that the event is known to be redacted. False hints that - /// the event is not redacted. -1 is automatic, which may make a query. - int8_t redacted {-1}; - - /// When true, the event is expected to have its content; hash mismatch - /// is not permitted. When false, hash mismatch is permitted when the - /// event is known to be redacted (see above). - bool require_content {false}; - /// Supply the room version; overrides/avoids any internal query. string_view room_version; + /// When true, the event is expected to have its content; hash mismatch + /// is not permitted. When false, hash mismatch is permitted. When -1, + /// by default the origin server is allowed to redact the content. + int8_t require_content {-1}; + /// Toggles whether event may be considered a "present event" and may /// update the optimized present state table of the room if it is proper. bool present {true}; diff --git a/matrix/event_conforms.cc b/matrix/event_conforms.cc index f2160f0bc..d3b547dea 100644 --- a/matrix/event_conforms.cc +++ b/matrix/event_conforms.cc @@ -147,38 +147,27 @@ ircd::m::vm::conform_report if(!opts.conforming) return; - eval.redacted = + const bool allow_redaction { - // redacted hint given in options - opts.redacted != -1? - bool(opts.redacted): - - // assume unredacted when user requires content - opts.require_content? - false: - - // assume unredacted for internal rooms - eval.room_internal? - false: - - // assume redacted when hash mismatch already allowed - non_conform.has(event::conforms::MISMATCH_HASHES)? - true: - - // assume no redaction for hash match - !eval.report.has(event::conforms::MISMATCH_HASHES)? - false: - - // case for authoritative redaction + // allowed by origin server eval.report.has(event::conforms::MISMATCH_HASHES) + && opts.require_content <= 0 && opts.node_id == json::get<"origin"_>(event)? true: - // make query + // allowed by my server + eval.room_internal? + true: + + // allowed by options + non_conform.has(event::conforms::MISMATCH_HASHES)? + true: + + // allowed by room auth event.event_id? bool(m::redacted(event.event_id)): - // otherwise deny redacted + // otherwise deny false }; @@ -187,11 +176,11 @@ ircd::m::vm::conform_report eval.report }; - // Allow content hash to fail on redacted events. - if(eval.redacted) + // When allowed, this hook won't throw, but the eval.report will + // still indicate MISMATCH_HASHES. + if(allow_redaction) report.del(event::conforms::MISMATCH_HASHES); - // Otherwise this will kill the eval if(!report.clean()) throw error { diff --git a/matrix/vm_execute.cc b/matrix/vm_execute.cc index cdd92b8f1..9d741156f 100644 --- a/matrix/vm_execute.cc +++ b/matrix/vm_execute.cc @@ -322,11 +322,6 @@ try eval.report, event::conforms{} }; - const scope_restore eval_redacted - { - eval.redacted, false - }; - // These checks only require the event data itself. if(likely(opts.phase[phase::CONFORM]) && !opts.edu) { @@ -335,17 +330,15 @@ try eval.phase, phase::CONFORM }; - const ctx::critical_assertion ca; call_hook(conform_hook, eval, event, eval); } - assert(!eval.buf || size(eval.buf) >= event::MAX_SIZE); const bool redacted { - eval.redacted - || eval.report.has(event::conforms::MISMATCH_HASHES) + eval.report.has(event::conforms::MISMATCH_HASHES) }; + assert(!eval.buf || size(eval.buf) >= event::MAX_SIZE); if(!opts.edu && !eval.buf && (!opts.json_source || redacted)) eval.buf = unique_mutable_buffer { @@ -354,23 +347,23 @@ try const json::object event_source { - // Canonize and redact from some other serialized source. - !opts.edu && !opts.json_source && event.source && redacted? - json::stringify(mutable_buffer{eval.buf}, m::essential(event.source, event::buf[0])): - - // Canonize and redact from no source. - !opts.edu && !opts.json_source && redacted? - json::stringify(mutable_buffer{eval.buf}, m::essential(event, event::buf[0])): - // Canonize from some other serialized source. - likely(!opts.edu && !opts.json_source && event.source)? + likely(!opts.edu && !opts.json_source && event.source && !redacted)? json::stringify(mutable_buffer{eval.buf}, event.source): // Canonize from no source; usually taken when my(event). // XXX elision conditions go here - likely(!opts.edu && !opts.json_source)? + likely(!opts.edu && !opts.json_source && !redacted)? json::stringify(mutable_buffer{eval.buf}, event): + // Canonize and redact from some other serialized source. + !opts.edu && !opts.json_source && event.source? + json::stringify(mutable_buffer{eval.buf}, m::essential(event.source, event::buf[0])): + + // Canonize and redact from no source. + !opts.edu && !opts.json_source? + json::stringify(mutable_buffer{eval.buf}, m::essential(event, event::buf[0])): + // Use the input directly. string_view{event.source} };