Get rid of unneeded constructor.
We never need to use hardcoded reduced padding parameters during
negotiation cell construction. If we are using reduced padding
parameters, the layers which decide this have netparams to use.
Prompted by
https://gitlab.torproject.org/tpo/core/arti/-/merge_requests/657#note_2826092
The network consensus parameters use (0,0) to mean "no padding"
(which is not the same as (0,0) means in a PADDING_NEGOTIATE cell).
Representing "no padding" this way is actually quite convoluted and
un-Rustic. Ensure that we convert (0,0) to None, and do the primary
logic in Option.
This gets rid of many Result(). Many parameters are renamed.
Test cases of the now-impossible branch are removed.
Deleting the match from padding_parameters will come in a moment.
I've split off that commit since it has much whitespace noise.
for now, change the error type to Void.
A "transient" error is one that does not indicate a true failure,
but rather an _expected_ need to retry. When we hit one of these,
we do not count it against the total number of permitted failures.
(We do impose a higher limit on "real failures plus transient
failures", though, to prevent infinite loops in the event of a
programming error.
Closes#517.
This is actually a general facility for inserting locally-generated
cells into the outgoing stream.
It doesn't seem to be possible to do this without adding an additional
condition check to the reactor, since we need to insert it into the
right place in the stream, giving it priority over data, and only
using it up if there was room in the output.
We don't engage this machinery yet, because nothing sets
special_outgoing.
Now all the information is plumbed to the right place, and we can
actually decide if we're sending padding.
Additionally, we conditionalise sending timing parameters on whether
padding is actually enabled, so in dormant mode we do not generate
updates (broadcast to all channels) just to reconfigure unused timing
parameters.
Change ChannelsParams::initial_update to compare fields with their
default values, and, if they're the same as the default, not to
include them in the returned update.
And if that update is then empty, return None.
The overall effect is to avoid the call to chan.reparameterize if
we're using the builtin default parameters, which is usual.
This arranges that the ChannelsParams we have retain, and which we
send to every newly created channel, actually has the right
parameters, even if they're not the default.
Now that the code that actually handles the netdir information can
cope with its lack, we can change the types of the various netdir
parameters and get rid of the foolish Bugs.
Now we actually honour the configuration variable.
However, when it is set to None, we lack proper handling. This will
be done bh turning None into 0,0 and then treating that as disabled.
There is a TODO for that.
Note that we *still* don't actually do or negotiate padding.
Move some logic out of reconfigure_general into what was
update_padding_parameters_from_netdir, and rename that function.
We're going to want to call this twice, shortly...
* Move out the PaddingParametersBuilder
* Have it handle missing netdir, though we currently always pass Ok
* Have it handle the error cases
It still ignores the config for now.
No overall functional change.
"git show -b" may be a useful way to review the changes in what
becomes "padding_parameters".
Now that we make an extract from the incoming NetDir, we can move the
padding parameters computation to after we take the lock.
This will be necessary for it to be able to depend on the config and
dormancy, records of which are protected by the chanmgr lock.
Channel padding depends on what the channel is being used for. We
therefore need to let the channel code know this information.
The implementation of the per-channel padding control logic will be in
the new note_usage function, which for now is simply a stub.
A future commit will introduce a `PaddingControlState` which lives in
the channel frontend; consult the doc comment for that type to see why
the plumbing through the channel manager terminates in the channel
frontend.
The chanmgr remembers the last dormancy state it was told.
We invent a chanmgr-specific Dormancy which the arti-client code knows
how to convert from the richer top-level dormant status. This avoids
having to have everyone know all the variants of the top-level state.
To call reconfigure_general, we must also obtain and plumb through a
netdir. Right now we must return an internal error if there is in
fact no netdir, because reconfigure_general does not yet cope with a
missing netdir.
Nothing actually *uses* the dormancy yet.
We're going to need to reuse this, so we can plumb the dormancy to
more places. Breaking it out avoids having repeat the initial
dormancy value in two places.
This function is going to become the code for controlling channels, in
general. (Including padding control.) Right now it doesn't do most
of the things.
In this commit:
* Change the prototype and the name now.
* Pass `()` for the dormancy and config, adding TODOs.
* Provide update_netdir method on AbstractChanMgr, and call that,
rather than having the ChanMgr go directly into the channel.
(That will enable us to test that `update_netdir` method
with test cases that don't have a complete ChanMgr.)
Unfortunately, because we don't have derive-adhoc here yet, rustfmt
didn't get to notice that this comma was needed.
We are going to add field(s), so add the comma now.
This will be convenient for managing when to send these negotiation
messages.
While we're here, edit the comment to explain how this is (going to
be) used.
This is more standard. It also provides the ::build() method.
This isn't a config type, and build failures ought not to happen,
so we use Bug for the error.
This is a compile-time feature with an associated configuration
flag, both enabled by default.
When it's turned on, hardening prevents the arti process from
dumping core or being attached to by low-privileged processes.
(This is a defense-in-depth measure, not an absolute way to prevent
attacks. For more information, see
[`secmem_proc`](https://docs.rs/secmem-proc/0.1.1/secmem_proc/).)
Closes#364.
The remaining unconditionally public APIs are those related to our
configuration objects, and the main_main() API.
The rationale for making main_main() public is to have an actual
entry point.
The rationale for making the config APIs public is:
1. We really do intend for others to be able to read our
configuration files using this API.
2. The structure of our configuration files is already part of our
interface.
Closes#530.
This commit implements the round-trip-time estimation algorithm from Tor
proposal 324, validating the implementation against the test vectors
found in C tor. (Note that at the time of writing, the new test vectors
may not be committed to C tor yet, but they will be soon.)
This also adds the necessary consensus parameters to `NetParameters`.
Some of them have been renamed in order to (hopefully) make them more
understandable.
We want to clarify that the tor-proto crate should only know _how_
its objects behave, not _why they behave that way_. (In other
words, we can have a "padding strategy" setting on a channel, but
not a "general usage" setting.)
Closes#531.
This had to become a new internal function, since at the point that
the handshake needs this code, it does not yet have a Channel to use.
This change made the error messages in the handshake code more
informative: and now they require a regex to check. Later, we might
want to defer formatting these strings, but I don't think we need
to do it now.
Doing this will make sure that we fix a correctness issue in netdir that
will be caused if we add more IDs.
(Also add RelayIdType::COUNT in tor-linkspec.)
With this change, each individual identity type becomes optional.
The functions that expose them unconditionally are now in a "legacy"
trait that only some downstream types are expected to implement.
There are new convenience APIs in HasRelayIds:
* to return Option<&keytype>,
* to see if one identity-set contains another.
This commit will break several downstream crates! For the
reviewer's convenience, I will put the fixes for those crates into a
series of squash! commits on this one.
tor-netdir
----------
Revise tor-netdir to accept optional identities. This required some
caveats and workarounds about the cases where we have to deal with a
key type that the tor-netdir code does not currently recognize at
all. If we start to add more identity types in the future, we may
well want more internal indices in this code.
tor-proto
---------
In order to make tor-proto support optional identities, there were
fewer changes than I thought. Some "check" functions needed to start
looking at "all the ids we want" rather than at "the two known IDs";
they also needed to accommodate that case where we don't have an ID
that we demand.
This change will also help with bridges, since we want to be able to
connect to a bridge without knowing all of its IDs up front.
The protocol currently _requires_ the two current ID types in some
places. To deal with that, I added a new `MissingId` error.
I also removed a couple of unconditional identity accessors for
chanmgr; code should use `target().identity(...)` instead.
tor-chanmgr
-----------
This is an incomplete conversion: it does not at all handle channel
targets without Ed25519 identities yet. It still uses those
identities to index its internal map from identity to channel; but
it gives a new `MissingId` error type if it's given a channel target
that doesn't have one.
We'll want to revise the map type again down the road when we
implement bridges, but I'd rather not step on the channel-padding
work in progress right now.
tor-guardmgr
------------
This change is mostly a matter of constructing owned identity types
more sensibly, rather than unwrapping them directly.
There are some places marked with TODOs where we still depend on
particular identity types, because of how the directory protocol
works. This will need revisiting when we add bridge support here.
tor-circmgr
-----------
These changes are just relatively simple API changes in the tests.
The formats used here are backward-compatible with those used by C
tor and those used elsewhere in our code. We need a way to encode
_both_ current kinds of identities as a string that tells you what
kind of ID they are. Traditionally we have used hexadecimal,
sometimes with a $, for RSA ids, and we have used base64 for Ed25519
IDs.
We also introduce a new forward-compatible format for new identity
keys in the future. (The new format is the key identity type, a
colon, and the id encoded as base64.) We will use this new format
_only_ when we need to encode identities in a way where it would be
otherwise unclear what kind of key we are dealing with.
I wonder if these types are correct. I think it makes sense to have
a Ref type like this, rather than just using `&RelayId`, but it
doesn't seems that I can make `RelayId` and `RelayIdRef` implement
Borrow and ToOwned for one another, so maybe I've messed up.
Now we have bus>1 ownership of the crate name `shellexpand`. I have
made a release, and retired `shellexpand-fork`.
The new shellexpand release switches to a (quite similarly) unforked
version of `dirs`.
We want the set of identities supported by a relay to be extensible
in the future with minimal fuss; we'd also like to make working
with these ID sets more convenient. To handle that, this commit
adds a new trait for "Something that has the same IDs as a relay"
and a new object for "an owned representation of a relay's IDs."
This commit introduces a similar trait for "Something with a list of
SocketAddr, like a relay has." There's no owned equivelent for
that, since Vec<SocketAddr> is already a thing.
Closes#428.
Everything that is a secret encryption key, or an input that is used
to produce a secret encryption key, has to get zeroized. And that's
all!
Closes#254.
This does not yet make sure that `SecretBuf` is used where it
_should_ be, but at least it ensures that most uses of `SecretBytes`
will indeed act as intended, and make sure that whatever they
contain is zeroized.
It requires some corresponding changes to method calls for
correctness and type conformance.
This Writer is a simple wrapper around `Vec<u8>` that makes sure
that its contents are cleared whenever they are dropped _or
reallocated_.
The reallocation is the important part here: without that, we risk
not zeroizing the first allocation of the buffer.
Using `zeroize` here tells these crates that they should make
various structures zeroize-on-drop.
(This is not yet implemented in `aes` 0.8.1, but support has been
merged in the repository for `aes`, so it should go out in the next
release.)
No corresponding feature flag is needed to enable zeroize-on-drop
for `rsa` and `*25519-dalek` private keys.
Do _not_ bump the dependency versions on crates that have had no
changes since arti 0.0.5, since those crates do not depend on the
new APIs.
```
cargo set-version -p tor-basic-utils --bump patch
cargo set-version -p tor-llcrypto --bump patch
git restore crates/tor-checkable
git restore crates/tor-consdiff
git restore crates/tor-rtmock
```
This performs the transitive closure of the last operation:
everything that depends on a crate with a breaking change gets the
version which it depends on bumped.
```
cargo set-version -p tor-proto --bump minor
cargo set-version -p tor-netdoc --bump minor
cargo set-version -p arti-hyper --bump minor
cargo set-version -p arti-bench --bump minor
cargo set-version -p arti-testing --bump minor
cargo set-version -p tor-config --bump minor
```
In order to mitigate syntax highlighting issues and a rust-analyzer bug
(https://github.com/rust-analyzer/rust-analyzer/issues/10178), rename
files that are included with the `include!` macro to have a `.rs`
extension.
Make sure the included files are outside `src/`, in order to not confuse
humans and automated editing tools that might mistake them for valid
Rust modules.
fixes arti#381
The other tests wait for 100 milliseconds; this one waits for 100
*microseconds* for some reason, which meant it was understandably flaky
if run on anything less than perfect conditions (arti#515).
This is probably a typo, so just change it.
fixes arti#515
This allows us to give better errors in the case where bootstrapping
succeeds at first, but fails thereafter for long enough to make our
directory expire.
Over the years we've found that most callers who want a netdir want
what C Tor calls a "reasonably live" network directory: One that is
not expired by too much, or too far in the future. But a few want a
_strictly_ live directory: one that says it is valid now, with no
tolerances. And a few want _any_ directory, no matter how expired
it is.
This commit adds net methods to NetDirProvider to provide these
directories. I think that most use cases will want to explicitly
think about what kind of directory they want, so I've made `netdir`
the simplest method. I might remove `timely_netdir` by the end of
this branch; see TODO comments.
Part of #518.
This name is more accurate because we aren't only dealing with
clock skew here: we're also trying to tolerate the case where the
authorities fail to reach consensus for a while.
This logic can now be adjusted via the config object so that it does
its own overriding by looking at the environment as appropriate.
Removing these methods helps simplify the code a bit.
Enabled by #483.
Now that configuring the environment variables related to fs
permissions works properly, we don't need to use the "override"
feature any more: we can just add the option to the configuration
when appropriate.
With this design, `--disable-fs-permission-checks` is now mostly an
alias for
`--option storage.permissions.dangerously_trust_everyone=true`
Enabled by #483.
By default we look at `$FS_MISTRUST_DISABLE_PERMISSIONS_CHECKS`.
Optionally, the user can provide another variable as well, or
disable looking at the environment entirely.
There are going to be some tasks (well, right away, one task) which
will want to go away when the sender is dropped.
The docs in postage are silent, but postage:⌚:Sender does not
have a Drop impl so I don't think we can rely on the Receivers getting
None from their Stream impl.
So we're going to have the watch send Options, which are None only
when the sender is dropped.
We are going to want to be able to wake up other tasks elsewhere in
Arti, that need to know about dormancy. We will give them a postage
watch Receiver.
Right now there are no such things yet.
We need to replace the AtomicBool for dormant mode with something that
can wake up tasks. postage::watch is the right shape.
But we want to be able to update it but suppress no-op updates.
(There is going to be a call site where no-op updates can occur.)
In the absence of a suitable upstream method as requested here
https://github.com/austinjones/postage-rs/issues/56
we introduce this facility via an extension trait.
This interface allows using FilterCount with functions that expect
predicates rather than iterator chains.
I'm about to use it to get meaningful FilterCount results in the
path-selection code in circmgr.
This change was a bit annoying, since most of this code _can't_ fail,
and so the only reasonable response is to wrap the input in an
internal error... except for one case where we're actually encoding
a caller-provided message, so we _do_ want to wrap the EncodeError
from tor_bytes.
This comprises four renames:
```
write_onto -> write_onto_infallible
write_into -> write_into_infallible
write -> write_infallible
writer_and_consume -> write_and_consume_infallible.
```
The rest of this branch will be concerned with replacing these
`_infallible` methods with ones that return a `Result`. This is
part of #513.
This implements a higher-level API for the ntor v3 handshake, in line
with that exposed by the ntor handshake. It does not, however, use the
existing `ClientHandshake` trait, due to fundamental differences in the
handshakes (namely, that the v3 handshake can include some additional
extra extension data).
Currently, the higher-level API assumes circuit extension, and copies
the (undocumented!) magic verification string from c-tor that indicates
this usage.
A rudimentary set of functions for serializing and deserializing
extensions to be sent with the handshake is also included, implementing
the protocol in proposal 332 § A.2. Currently, it only implements the
congestion control extensions specified in proposal 324 § 10.3.
part of arti#88
These errors no longer use Debug to dump the `Option<SourceInfo>`, but
instead produce reasonable text. Also, I've fixed the SourceInfo
Display implementation so that it now says that it got the error
"from $source via $circuit" rather than the other way around.
This is a helper rather than a Display implementation because it
isn't the only logical way to display these values. (In fact,
without context, it isn't even the _most_ logical way)
This is going to make it simpler to write the code in guardmgr (and
later in circmgr) that keeps track of how many relays were rejected
for what reason. The latter, in turn, should improve error messages
when we're unable to pick a guard or a path.