Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
ae87d0b
Upstream TSIG support.
ximon18 Apr 2, 2026
25fdfe9
Fix RustDoc violations.
ximon18 Apr 2, 2026
8a11e9d
(De)serialize to Base64.
ximon18 Apr 3, 2026
52c88cf
cargo fmt.
ximon18 Apr 3, 2026
79b3308
(de)serialize TSIG algorithm names exactly as defined in the IANA reg…
ximon18 Apr 7, 2026
4b07b11
Use ^ instead of ! and start adding man page content.
ximon18 Apr 7, 2026
4d56ffb
Add a cascade tsig man page.
ximon18 Apr 7, 2026
53f6205
More TSIG related man page updates.
ximon18 Apr 7, 2026
9b50f3c
Try adding an NSD integration page to showcase TSIG support.
ximon18 Apr 7, 2026
5845baf
Expand the NSD example.
ximon18 Apr 7, 2026
7002eb3
Tweak the NSD example.
ximon18 Apr 8, 2026
0750e4e
Advise how to create a TSIG key.
ximon18 Apr 8, 2026
7143a54
Start creating a system test for upstream TSIG.
ximon18 Apr 8, 2026
c0724ee
FIX: allow hmac- when specifying the algorithm name to `tsig key add`.
ximon18 Apr 8, 2026
678d55e
FIX: Wrong `tsig add` subcommand documentation.
ximon18 Apr 8, 2026
0c0d38c
Make the upstream TSIG system test try using TSIG.
ximon18 Apr 8, 2026
432e779
Merge branch 'main' into tsig-upstream-support
ximon18 Apr 10, 2026
75b6ee3
Merge branch 'main' into tsig-upstream-support
ximon18 Apr 10, 2026
b44b805
Fix merge error.
ximon18 Apr 10, 2026
059cd0a
Fix sphinx-build WARNING: Title underline too short.
ximon18 Apr 10, 2026
5c38ef9
Add `tsig list` CLI subcommand.
ximon18 Apr 10, 2026
80b6b3d
Document the tsig list subcommand.
ximon18 Apr 10, 2026
5c5ef7e
Commit updated generated man pages.
ximon18 Apr 10, 2026
1908500
Remove accidentally commited sphinx-build outputs.
ximon18 Apr 10, 2026
0426bc6
Remove accidentally commited sphinx-build outputs.
ximon18 Apr 10, 2026
15d6da2
Add TODO notes.
ximon18 Apr 10, 2026
542d70e
Implement `cascade tsig remove`.
ximon18 Apr 13, 2026
e03487b
Merge branch 'main' into tsig-upstream-support
ximon18 Apr 14, 2026
67becab
Introduce public-nameservers and send it to keyset. Handle TSIG relat…
Philip-NLnetLabs Apr 15, 2026
b8729fb
Merge branch 'tsig-upstream-support' of github.com:NLnetLabs/cascade …
ximon18 Apr 15, 2026
271bfac
Merge branch 'main' into tsig-upstream-support
ximon18 Apr 15, 2026
e6a5192
Fix failing upstream-tsig system test by bumping the dnst version use…
ximon18 Apr 15, 2026
11bf96a
Improve the policy template documentation for send-notify-to.
ximon18 Apr 15, 2026
3331ff9
Add some more comments to the code.
ximon18 Apr 16, 2026
ee907f2
Merge branch 'main' into tsig-upstream-support
ximon18 Apr 17, 2026
855e6ce
Make tsig subcommand help text more consistent with the terminology u…
ximon18 Apr 17, 2026
3756c89
Report the set of supported TSIG algorithms in the CLI detailed help.
ximon18 Apr 17, 2026
78b1db0
Make tsig list output closer in style to the new zone status CLI outp…
ximon18 Apr 17, 2026
f683960
Make error message less confusing.
ximon18 Apr 17, 2026
04cd247
Man page typo correction and remove pondered addition.
ximon18 Apr 17, 2026
16d2619
cascade zone add man page text improvements.
ximon18 Apr 17, 2026
deb0a21
Minor cascade-tsig man page improvement.
ximon18 Apr 17, 2026
e790b75
Rebuild man pages.
ximon18 Apr 17, 2026
b1c599c
Remove sphinx static files.
ximon18 Apr 17, 2026
ee50dd7
Split large block of text into smaller more readable chunks.
ximon18 Apr 17, 2026
41f50cd
More zone transfer documentation.
ximon18 Apr 20, 2026
db29fd4
Add the new publication_nameservers field to the policy template.
ximon18 Apr 20, 2026
2b48138
Merge branch 'main' into tsig-upstream-support
ximon18 Apr 20, 2026
49474f7
Check the mid deletion flag when looking for policies using a TSIG key.
ximon18 Apr 20, 2026
6426c9a
Remove outdated comment.
ximon18 Apr 20, 2026
6fbf719
Fix formatting.
ximon18 Apr 20, 2026
e69c452
Additional comments and whitespace.
ximon18 Apr 20, 2026
bb462b3
Additional comment.
ximon18 Apr 20, 2026
3bf9f91
Use domain::dep::octseq to avoid dependency mismatch.
ximon18 Apr 20, 2026
c338121
Remove addition of downstream specific logic from upstream PR.
ximon18 Apr 20, 2026
f6a7a5c
Remove errant linebreak.
ximon18 Apr 20, 2026
021545e
Remove commented out line.
ximon18 Apr 20, 2026
ad2b492
Impl From<TsigAlgorithm> for Algorithm.
ximon18 Apr 20, 2026
eba3152
Remove unused import.
ximon18 Apr 20, 2026
abf9d92
Make log output more human readable.
ximon18 Apr 20, 2026
787ad2a
Revert "Remove addition of downstream specific logic from upstream PR."
ximon18 Apr 20, 2026
e6d8a5f
Remove outdated comment.
ximon18 Apr 20, 2026
80ac2e7
Revert "Remove outdated comment."
ximon18 Apr 20, 2026
d77e034
Reapply "Remove addition of downstream specific logic from upstream PR."
ximon18 Apr 20, 2026
7228b83
Additional comments on the NOTIFY handler re: ACL enforcement.
ximon18 Apr 20, 2026
9bc4f47
Remove policy comments that relate to downstream TSIG.
ximon18 Apr 20, 2026
773369a
Restore missing line.
ximon18 Apr 20, 2026
0fa77c8
Restore missing line exactly.
ximon18 Apr 20, 2026
1cdf7b0
Add a note about how adding a TSIG key has an effect, even without sp…
ximon18 Apr 20, 2026
d466f35
Document the new policy publication-nameservers setting.
ximon18 Apr 20, 2026
b08bc84
Re-generate rendered man pages.
ximon18 Apr 20, 2026
e2c4681
cargo fmt.
ximon18 Apr 20, 2026
a8ff50c
Various review feedback updates.
ximon18 Apr 22, 2026
342cbfd
Use NameserverCommsSpec instead of String following internal discussion.
ximon18 Apr 22, 2026
42f554d
Various review feedback changes.
ximon18 Apr 22, 2026
5f44999
Review feedback: Remove unnecesary 'tsig' feature dependency.
ximon18 Apr 22, 2026
5ab8b6a
Remove left in debug statements.
ximon18 Apr 22, 2026
8354c5b
Review feedback: use explicit error variant.
ximon18 Apr 22, 2026
c5f7819
Review feedback: be more specific about the arguments to be supplied …
ximon18 Apr 22, 2026
8cdaa29
Review feedback: Note the insecure nature of using a command-line arg…
ximon18 Apr 22, 2026
5da60cb
Review feedback: improvements to the `zone add` documentation.
ximon18 Apr 22, 2026
555b728
Consistently use the :RFC:`NNN` linking mechanism in the docs.
ximon18 Apr 22, 2026
f61ccb7
Regenerate man pages.
ximon18 Apr 22, 2026
bc7db24
Review feedback.
ximon18 Apr 22, 2026
ef966b4
Review feedback: Link to man page.
ximon18 Apr 22, 2026
3056a48
Review feedback.
ximon18 Apr 22, 2026
838b675
Review feedback.
ximon18 Apr 22, 2026
ed68983
Minor tweak.
ximon18 Apr 22, 2026
399b384
More review feedback.
ximon18 Apr 22, 2026
f7529db
More review feedback and tweaks.
ximon18 Apr 22, 2026
4c6c181
Regenerate man pages.
ximon18 Apr 22, 2026
a822c42
Clippy.
ximon18 Apr 22, 2026
880cc3f
Increase note to warning.
ximon18 Apr 22, 2026
44282b9
Regenerate man pages.
ximon18 Apr 22, 2026
ebfc0f3
Fix broken RFC links.
ximon18 Apr 22, 2026
5198800
Remove errant back-tick character in docs.
ximon18 Apr 22, 2026
122e737
Merge branch 'main' into tsig-upstream-support
ximon18 Apr 22, 2026
36f4961
Add last error to zone status
tertsdiepraam Apr 22, 2026
144363a
Add more errors to zone status
tertsdiepraam Apr 22, 2026
d4fc435
Fully remove use of domain::tsig in the api crate.
ximon18 Apr 24, 2026
b625ff5
Support reading TSIG secret from a file.
ximon18 Apr 24, 2026
a2db6be
Also test with TSIG key from file.
ximon18 Apr 24, 2026
154d923
Review feedback: Don't wait 10 seconds, detect the XFR failure ASAP.
ximon18 Apr 24, 2026
ee3cb3d
Review feedback: Use a better zonefile path in NSD examples.
ximon18 Apr 24, 2026
aab66bf
Review feedback: Use RustDoc markdown, not reST markdown.
ximon18 Apr 24, 2026
4a58452
Review feedback: Quote --source argument.
ximon18 Apr 24, 2026
b851e81
Minor correction.
ximon18 Apr 24, 2026
078436e
Review feedback: Refer to authenticating communication in general.
ximon18 Apr 24, 2026
106094b
Review feedback.
ximon18 Apr 24, 2026
239a92a
Review feedback: consistent Display styling.
ximon18 Apr 24, 2026
982274e
Review feedback: Note that we might want a more useful error in future.
ximon18 Apr 24, 2026
27bdc14
Update policy docs and regenerate man pages.
ximon18 Apr 24, 2026
49043f8
Record that a zone uses a TSIG key when adding the zone.
ximon18 Apr 28, 2026
5acd00b
Review feedback: Document why save_now() is invoked.
ximon18 Apr 28, 2026
1453aa6
Review feedback: Use the Hmac prefix consistently.
ximon18 Apr 28, 2026
a82b8a0
Review feedback: Better naming.
ximon18 Apr 28, 2026
df1cfa2
Review feedback: Trim whitespace from TSIG secret value read from file.
ximon18 Apr 28, 2026
52a919c
Review feedback: Errant colon position in docs.
ximon18 Apr 28, 2026
79559a7
Review feedback: Quote to prevent special treatment of '^'.
ximon18 Apr 28, 2026
8be30fb
Indent consistent with the other similar example like this.
ximon18 Apr 28, 2026
3130f62
Review feedback: Avoid unnecessary Vec.
ximon18 Apr 28, 2026
6170704
Merge branch 'main' into tsig-upstream-support
ximon18 Apr 29, 2026
97aea65
Merge branch 'main' into tsig-upstream-support
ximon18 Apr 30, 2026
aecc257
Review feedback: Be less strict about Cascade not supporting zone files.
ximon18 Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ assets = [
["doc/manual/build/man/cascade-config.1", "usr/share/man/man1/cascade-config.1", "644"],
["doc/manual/build/man/cascade-health.1", "usr/share/man/man1/cascade-health.1", "644"],
["doc/manual/build/man/cascade-hsm.1", "usr/share/man/man1/cascade-hsm.1", "644"],
["doc/manual/build/man/cascade-tsig.1", "usr/share/man/man1/cascade-tsig.1", "644"],
["doc/manual/build/man/cascade-keyset.1", "usr/share/man/man1/cascade-keyset.1", "644"],
["doc/manual/build/man/cascade-policy.1", "usr/share/man/man1/cascade-policy.1", "644"],
["doc/manual/build/man/cascade-status.1", "usr/share/man/man1/cascade-status.1", "644"],
Expand Down Expand Up @@ -300,6 +301,7 @@ assets = [
{ source = "doc/manual/build/man/cascade-config.1", dest = "/usr/share/man/man1/cascade-config.1", mode = "644", doc = true },
{ source = "doc/manual/build/man/cascade-health.1", dest = "/usr/share/man/man1/cascade-health.1", mode = "644", doc = true },
{ source = "doc/manual/build/man/cascade-hsm.1", dest = "/usr/share/man/man1/cascade-hsm.1", mode = "644", doc = true },
{ source = "doc/manual/build/man/cascade-tsig.1", dest = "/usr/share/man/man1/cascade-tsig.1", mode = "644", doc = true },
{ source = "doc/manual/build/man/cascade-keyset.1", dest = "/usr/share/man/man1/cascade-keyset.1", mode = "644", doc = true },
{ source = "doc/manual/build/man/cascade-policy.1", dest = "/usr/share/man/man1/cascade-policy.1", mode = "644", doc = true },
{ source = "doc/manual/build/man/cascade-status.1", dest = "/usr/share/man/man1/cascade-status.1", mode = "644", doc = true },
Expand Down
157 changes: 126 additions & 31 deletions crates/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashMap;
use std::fmt::{self, Display};
use std::net::{IpAddr, SocketAddr};
use std::net::SocketAddr;
use std::time::{Duration, SystemTime};

use camino::{Utf8Path, Utf8PathBuf};
Expand All @@ -9,8 +10,6 @@ pub use domain::base::Serial;

pub mod dep;

const DEFAULT_AXFR_PORT: u16 = 53;

//----------- ZoneName ---------------------------------------------------------

/// The name of a zone.
Expand Down Expand Up @@ -187,6 +186,94 @@ pub struct KmipKeyImport {
pub flags: String,
}

//----------- TsigKeyName -----------------------------------------------------

/// The name of a TSIG key.
pub type TsigKeyName = domain::base::Name<domain::dep::octseq::Array<255>>;

//----------- TsigAdd ---------------------------------------------------------

/// Add a TSIG key to Cascade.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TsigAdd {
/// The name of the TSIG key to add.
pub name: TsigKeyName,

/// The algorithm of the TSIG key.
pub alg: TsigAlgorithm,

/// The base64 encoded key material bytes.
pub secret: String,
}

/// The successful result of adding a TSIG key to Cascade.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TsigAddResult;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling this Result might be confusing since it will often be wrapped in a real Result, e.g. Result<TsigAddResult, TsigAddError>. Perhaps the suffix should be Output here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but it uses the same naming pattern as already exists in surrounding code.


/// An error result indicating why an attempt to add a TSIG key to Cascade
/// failed.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub enum TsigAddError {
/// A TSIG key by the given name already exists in Cascade.
AlreadyExists,

/// The provided TSIG key secret was not correctly base64 encoded.
InvalidBase64Secret,
}

impl Display for TsigAddError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TsigAddError::AlreadyExists => write!(f, "TSIG key already exists"),
TsigAddError::InvalidBase64Secret => write!(f, "invalid TSIG base64 encoded secret"),
}
}
}

//------------ TsigRemove ----------------------------------------------------

/// The successful result of removing a TSIG key from Cascade.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TsigRemoveResult;

/// An error result indicating why an attempt to remove a TSIG key from
/// Cascade failed.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub enum TsigRemoveError {
/// The specified TSIG key name was not found in Cascade.
NotFound,

/// The specified TSIG key cannot be removed as it is in use.
InUse,
}

impl fmt::Display for TsigRemoveError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
TsigRemoveError::NotFound => "no such TSIG key was found",
TsigRemoveError::InUse => "the TSIG key cannot be removed as it is in use",
})
}
}

//------------ TsigListResult ------------------------------------------------

/// The successful result of listing TSIG Cascade keys known to Cascade.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TsigListResult {
/// The set of TSIG keys known to Cascade plus information about each key.
pub tsig_keys: HashMap<TsigKeyName, TsigKeyInfo>,
}

/// Information about a single listed TSIG key.
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TsigKeyInfo {
/// The set of zones with which this TSIG key is used.
pub zones: Vec<ZoneName>,
}

//----------- ZoneAdd --------------------------------------------------------

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ZoneAdd {
pub name: ZoneName,
Expand All @@ -206,6 +293,7 @@ pub enum ZoneAddError {
AlreadyExists,
NoSuchPolicy,
PolicyMidDeletion,
NoSuchTsigKey,
Other(String),
}

Expand All @@ -215,6 +303,7 @@ impl fmt::Display for ZoneAddError {
Self::AlreadyExists => "a zone of this name already exists",
Self::NoSuchPolicy => "no policy with that name exists",
Self::PolicyMidDeletion => "the specified policy is being deleted",
Self::NoSuchTsigKey => "no TSIG key with that name exists",
Self::Other(reason) => reason,
})
}
Expand All @@ -240,6 +329,10 @@ impl fmt::Display for ZoneRemoveError {

/// How to load the contents of a zone.
#[derive(Deserialize, Serialize, Debug, Clone)]
// Allow the large enum variant caused by TsigKeyName using Name<Array<255>>
// to avoid the conversions that would be needed if Name<Bytes> were to be
// used instead.
#[allow(clippy::large_enum_variant)]
pub enum ZoneSource {
/// Don't load the zone at all.
None,
Expand All @@ -256,10 +349,7 @@ pub enum ZoneSource {
addr: SocketAddr,

/// The name of a TSIG key, if any.
tsig_key: Option<String>,

/// The XFR status of the zone.
xfr_status: ZoneRefreshStatus,
tsig_key: Option<TsigKeyName>,
},
}

Expand Down Expand Up @@ -290,28 +380,6 @@ impl Display for ZoneSource {
}
}

impl From<&str> for ZoneSource {
fn from(s: &str) -> Self {
if let Ok(addr) = s.parse::<SocketAddr>() {
ZoneSource::Server {
addr,
tsig_key: None,
xfr_status: Default::default(),
}
} else if let Ok(addr) = s.parse::<IpAddr>() {
ZoneSource::Server {
addr: SocketAddr::new(addr, DEFAULT_AXFR_PORT),
tsig_key: None,
xfr_status: Default::default(),
}
} else {
ZoneSource::Zonefile {
path: Utf8PathBuf::from(s).into_boxed_path(),
}
}
}
}

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ZonesListResult {
pub zones: Vec<ZoneName>,
Expand Down Expand Up @@ -503,6 +571,26 @@ impl Display for KeyType {
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub enum TsigAlgorithm {
HmacSha1,
HmacSha256,
HmacSha384,
HmacSha512,
}

impl Display for TsigAlgorithm {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TsigAlgorithm::HmacSha1 => "hmac-sha1",
TsigAlgorithm::HmacSha256 => "hmac-sha256",
TsigAlgorithm::HmacSha384 => "hmac-sha384",
TsigAlgorithm::HmacSha512 => "hmac-sha512",
}
.fmt(f)
}
}

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ZoneHistory {
pub history: Vec<HistoryItem>,
Expand Down Expand Up @@ -675,14 +763,21 @@ pub struct KeyMsg {
}

#[derive(Deserialize, Serialize, Debug, Clone)]
// Allow the large enum variant caused by TsigKeyName using Name<Array<255>>
// to avoid the conversions that would be needed if Name<Bytes> were to be
// used instead.
#[allow(clippy::large_enum_variant)]
pub enum PolicyReloadError {
Io(Utf8PathBuf, String),
NoSuchTsigKey(TsigKeyName),
}

impl Display for PolicyReloadError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let PolicyReloadError::Io(p, e) = self;
format!("{p}: {e}").fmt(f)
match self {
PolicyReloadError::Io(p, e) => write!(f, "{p}: {e}"),
PolicyReloadError::NoSuchTsigKey(k) => write!(f, "no TSIG key with name '{k}' exists"),
}
}
}

Expand Down
10 changes: 6 additions & 4 deletions crates/cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod keyset;
pub mod policy;
pub mod status;
pub mod template;
pub mod tsig;
pub mod zone;

use crate::client::CascadeApiClient;
Expand Down Expand Up @@ -37,10 +38,10 @@ pub enum Command {
/// Execute manual key roll or key removal commands
#[command(name = "keyset")]
KeySet(self::keyset::KeySet),
//
// /// Manage keys
// #[command(name = "key")]
// Key(self::key::Key),

/// Manage TSIG keys
#[command(name = "tsig")]
Tsig(self::tsig::Tsig),
// - Command: add/remove/modify a zone
// - Command: add/remove/modify a key for a zone
// - Command: add/remove/modify a key
Expand Down Expand Up @@ -74,6 +75,7 @@ impl Command {
Self::Policy(policy) => policy.execute(client).await,
Self::KeySet(keyset) => keyset.execute(client).await,
Self::Hsm(hsm) => hsm.execute(client).await,
Self::Tsig(tsig) => tsig.execute(client).await,
Self::Template(template) => template.execute(client).await,
}
}
Expand Down
Loading
Loading