Fix introducer list subcommand

- Add a list of introduced domains to the output.
- Fix `regex_domain_unescape()` to return an error if the regular
  expression differs from a regex for a domain.
This commit is contained in:
Malte Meiboom
2026-06-02 21:36:15 +02:00
parent 0ff4d340cb
commit a4e3bc6b8c
2 changed files with 18 additions and 3 deletions
+4 -2
View File
@@ -3,6 +3,8 @@
use aho_corasick::AhoCorasick; use aho_corasick::AhoCorasick;
use anyhow::Result; use anyhow::Result;
use crate::types::errors::HuskError;
const REGEX_CONTROL_CHARS: &[&str] const REGEX_CONTROL_CHARS: &[&str]
= &[ "\\", ".", "|", "(", ")", "*", "+", "?", "^", "$", "[", "]" ]; = &[ "\\", ".", "|", "(", ")", "*", "+", "?", "^", "$", "[", "]" ];
const REGEX_ESCAPED_CHARS: &[&str] const REGEX_ESCAPED_CHARS: &[&str]
@@ -36,10 +38,10 @@ pub fn regex_domain_unescape(value: &str) -> Result<String> {
if let Some(inner) = stripped.strip_suffix(">$") { if let Some(inner) = stripped.strip_suffix(">$") {
Ok(inner.into()) Ok(inner.into())
} else { } else {
Ok(value) Err(HuskError::InvalidDomainName(value).into())
} }
} else { } else {
Ok(value) Err(HuskError::InvalidDomainName(value).into())
} }
} }
+14 -1
View File
@@ -9,6 +9,7 @@ use sequoia_openpgp::Cert;
use crate::types::husk_context::HuskContext; use crate::types::husk_context::HuskContext;
use crate::common::crypto; use crate::common::crypto;
use crate::common::escape;
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum IntroducerError { pub enum IntroducerError {
@@ -105,16 +106,28 @@ impl Introducer {
} }
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
impl Display for Introducer {
impl Display for Introducer {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
// XXX: This is unsafe as ANSI control chars are not handled. // XXX: This is unsafe as ANSI control chars are not handled.
let uids = self.cert.userids() let uids = self.cert.userids()
.map(|u| String::from_utf8_lossy(u.userid().value()).to_string()) .map(|u| String::from_utf8_lossy(u.userid().value()).to_string())
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(", "); .join(", ");
writeln!(f, "Introducer: {}", self.cert.fingerprint())?; writeln!(f, "Introducer: {}", self.cert.fingerprint())?;
writeln!(f, " UserIDs: {}", uids)?; writeln!(f, " UserIDs: {}", uids)?;
if let Some(regex_set) = self.certification.regular_expressions() {
for regex in regex_set.as_bytes().into_iter() {
let regex = String::from_utf8_lossy(regex);
if let Ok(domain) = escape::regex_domain_unescape(regex.to_string().as_str()) {
writeln!(f," Domain: {}", domain)?;
} else {
writeln!(f," RegEx: {}", regex)?;
}
}
}
Ok(()) Ok(())
} }
} }