diff options
Diffstat (limited to 'src/access')
| -rw-r--r-- | src/access/bans.rs | 4 | ||||
| -rw-r--r-- | src/access/token.rs | 18 |
2 files changed, 19 insertions, 3 deletions
diff --git a/src/access/bans.rs b/src/access/bans.rs index c4fad1f..a314f49 100644 --- a/src/access/bans.rs +++ b/src/access/bans.rs @@ -2,8 +2,8 @@ //! user who may write there, as any protocol data: a node refuses a banned node's //! handshake, so it neither syncs with it nor counts it a member (`swarm::peer`), and //! with the swarm's policy every node refuses the changes a banned node commits -//! (`access::rules`, judged as the ban stood when they were made). Deleting the entry -//! lifts the ban. +//! (`access::rules`, judged as the ban stood when they were made), and the tokens it +//! issued (`access::token`). Deleting the entry lifts the ban. use crate::document::{ReadDoc, meta, store}; diff --git a/src/access/token.rs b/src/access/token.rs index 3af8672..d33a3fe 100644 --- a/src/access/token.rs +++ b/src/access/token.rs @@ -75,6 +75,8 @@ pub(crate) enum Refused { OtherSwarm, #[error("issued by a node that isn't a member here (not yet, or no longer)")] UnknownIssuer, + #[error("issued by a node the swarm banned")] + BannedIssuer, #[error("its signature doesn't hold")] BadSignature, #[error("expired")] @@ -90,7 +92,7 @@ pub(crate) enum Refused { } /// The claims of `token` if this node takes it: well formed, for `swarm`, signed by a -/// node that is a member in `doc`, not expired at `now` (Unix ms), nor issued later +/// node that is a member in `doc` and not banned, not expired at `now` (Unix ms), nor issued later /// than a clock off by `SKEW_MS` would; and in a swarm with a registry, for a /// registered user that is enabled, issued after its tokens were last revoked /// (`registry::User::tokens_not_before`). @@ -126,6 +128,9 @@ pub(crate) fn verify( if !member { return Err(Refused::UnknownIssuer); } + if super::bans::banned(doc, &claims.issuer) { + return Err(Refused::BannedIssuer); + } let mut signed = LABEL.to_vec(); signed.extend_from_slice(&payload); if !identity::verify(&key, &signed, &signature) { @@ -236,6 +241,17 @@ mod tests { verify(&doc, &forged, "s", 1_500), Err(Refused::BadSignature) ); + // By a member banned since. + let token = issue(&key, &claims(&key)); + let ban = crate::access::bans::path(&key.id()); + let mut banned = doc.fork(); + change(&mut banned, |tx| { + store::write_path(tx, &ban, &json!({"reason": "lost"})).unwrap() + }); + assert_eq!( + verify(&banned, &token, "s", 1_500), + Err(Refused::BannedIssuer) + ); // Changed claims, the signature kept. let token = issue(&key, &claims(&key)); let (_, signature) = token.rsplit_once('.').unwrap(); |
