Skip to content

Commit

Permalink
Add TSIG middleware. (#380)
Browse files Browse the repository at this point in the history
- Add TSIG response signing middleware.
- Update Stelline server integration tests to use the new TSIG middleware.
- Add TSIG Stelline test recipe.
- TSIG module changes:
  - Derive Clone for Key.
  - Added Key::compose_len() for determining how many response bytes to reserve.
  - Added ClientTransaction::wrapped_key(), ClientSequence::wrapped_key() and SigningContext::wrapped_key() to access the real underlying "wrapped" key type.
  - Added From<ServerTransaction<K>> for ServerSequence<K>.
  - Various minor RustDoc improvements.
 - Make Time48 obey mock (predictable and controllable) time so that TSIG signing uses mock time during Stelline tests.

Other:
- Remove unnecessary Unpin bounds on net::server::message::Request.
- Remove unnecessary Clone bound on impl SendRequest for net::client::dgram::Connection.
- Remove unnecessary mutex lock on middleware post-processing response state and rename PostprocessingConfig to PostprocessingState to better reflect its mutable nature.
- Don't set the AA flag on test service responses as (a) actual zone serving doesn't do this yet and this still needs fixing, and (b) it violates the expectations of the TSIG Stelline test that verifies at a byte level the TSIG response signature.

---------

Co-authored-by: Philip Homburg <[email protected]>
Co-authored-by: Philip-NLnetLabs <[email protected]>
Co-authored-by: Terts Diepraam <[email protected]>
  • Loading branch information
4 people authored Sep 16, 2024
1 parent 1d022f4 commit 400843e
Show file tree
Hide file tree
Showing 14 changed files with 863 additions and 98 deletions.
4 changes: 2 additions & 2 deletions examples/server-transports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ impl<Svc> StatsMiddlewareSvc<Svc> {
fn postprocess<RequestOctets>(
request: &Request<RequestOctets>,
response: &AdditionalBuilder<StreamTarget<Svc::Target>>,
stats: Arc<RwLock<Stats>>,
stats: &RwLock<Stats>,
) where
RequestOctets: Octets + Send + Sync + Unpin,
Svc: Service<RequestOctets>,
Expand All @@ -512,7 +512,7 @@ impl<Svc> StatsMiddlewareSvc<Svc> {
fn map_stream_item<RequestOctets>(
request: Request<RequestOctets>,
stream_item: ServiceResult<Svc::Target>,
stats: Arc<RwLock<Stats>>,
stats: &mut Arc<RwLock<Stats>>,
) -> ServiceResult<Svc::Target>
where
RequestOctets: Octets + Send + Sync + Unpin,
Expand Down
2 changes: 1 addition & 1 deletion src/net/client/dgram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ where
S: AsyncConnect + Clone + Send + Sync + 'static,
S::Connection:
AsyncDgramRecv + AsyncDgramSend + Send + Sync + Unpin + 'static,
Req: ComposeRequest + Clone + Send + Sync + 'static,
Req: ComposeRequest + Send + Sync + 'static,
{
fn send_request(
&self,
Expand Down
4 changes: 2 additions & 2 deletions src/net/server/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ where

impl<Octs, Metadata> Request<Octs, Metadata>
where
Octs: AsRef<[u8]> + Send + Sync + Unpin,
Octs: AsRef<[u8]> + Send + Sync,
{
/// Creates a new request wrapper around a message along with its context.
pub fn new(
Expand Down Expand Up @@ -270,7 +270,7 @@ where

impl<Octs, Metadata> Clone for Request<Octs, Metadata>
where
Octs: AsRef<[u8]> + Send + Sync + Unpin,
Octs: AsRef<[u8]> + Send + Sync,
Metadata: Clone,
{
fn clone(&self) -> Self {
Expand Down
2 changes: 1 addition & 1 deletion src/net/server/middleware/edns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ where
fn map_stream_item(
request: Request<RequestOctets, RequestMeta>,
mut stream_item: ServiceResult<NextSvc::Target>,
_pp_meta: (),
_pp_meta: &mut (),
) -> ServiceResult<NextSvc::Target> {
if let Ok(cr) = &mut stream_item {
if let Some(response) = cr.response_mut() {
Expand Down
4 changes: 2 additions & 2 deletions src/net/server/middleware/mandatory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,11 @@ where
fn map_stream_item(
request: Request<RequestOctets, RequestMeta>,
mut stream_item: ServiceResult<NextSvc::Target>,
strict: bool,
strict: &mut bool,
) -> ServiceResult<NextSvc::Target> {
if let Ok(cr) = &mut stream_item {
if let Some(response) = cr.response_mut() {
Self::postprocess(&request, response, strict);
Self::postprocess(&request, response, *strict);
}
}
stream_item
Expand Down
16 changes: 7 additions & 9 deletions src/net/server/middleware/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,19 @@
//! post-processing the resulting responses and propagating them back down
//! through the layers to the server.
//!
//! Currently the following middleware are available:
//! If needed middleware services can pass service specific data to upstream
//! services for consumption, via the `RequestMeta` custom data support of
//! the [`Service`] trait. An example of this can be seen in the
//! [`TsigMiddlewareSvc`][tsig::TsigMiddlewareSvc].
//!
//! - [`MandatoryMiddlewareSvc`]: Core DNS RFC standards based message
//! processing for MUST requirements.
//! - [`EdnsMiddlewareSvc`]: RFC 6891 and related EDNS message processing.
//! - [`CookiesMiddlewareSvc`]: RFC 7873 DNS Cookies related message
//! processing.
//! Currently the following middleware are available:
//!
//! [`MandatoryMiddlewareSvc`]: mandatory::MandatoryMiddlewareSvc
//! [`EdnsMiddlewareSvc`]: edns::EdnsMiddlewareSvc
//! [`CookiesMiddlewareSvc`]: cookies::CookiesMiddlewareSvc
//! [`Service`]: crate::net::server::service::Service

#[cfg(feature = "siphasher")]
pub mod cookies;
pub mod edns;
pub mod mandatory;
pub mod stream;
#[cfg(feature = "tsig")]
pub mod tsig;
12 changes: 5 additions & 7 deletions src/net/server/middleware/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ type PostprocessingStreamCallback<
> = fn(
Request<RequestOctets, RequestMeta>,
StreamItem,
PostProcessingMeta,
&mut PostProcessingMeta,
) -> StreamItem;

//------------ PostprocessingStream ------------------------------------------
Expand Down Expand Up @@ -153,7 +153,7 @@ where
pub fn new(
svc_call_fut: Future,
request: Request<RequestOctets, RequestMeta>,
metadata: PostProcessingMeta,
pp_meta: PostProcessingMeta,
cb: PostprocessingStreamCallback<
RequestOctets,
Stream::Item,
Expand All @@ -165,7 +165,7 @@ where
state: PostprocessingStreamState::Pending(svc_call_fut),
request,
cb,
pp_meta: metadata,
pp_meta,
}
}
}
Expand All @@ -187,7 +187,6 @@ where
Stream: futures_util::stream::Stream + Unpin,
Self: Unpin,
RequestMeta: Clone,
PostProcessingMeta: Clone,
{
type Item = Stream::Item;

Expand All @@ -206,9 +205,8 @@ where
let stream_item = ready!(stream.poll_next_unpin(cx));
trace!("Stream item retrieved, mapping to downstream type");
let request = self.request.clone();
let pp_meta = self.pp_meta.clone();
let map =
stream_item.map(|item| (self.cb)(request, item, pp_meta));
let map = stream_item
.map(|item| (self.cb)(request, item, &mut self.pp_meta));
Poll::Ready(map)
}
}
Expand Down
Loading

0 comments on commit 400843e

Please sign in to comment.