use adhammer_collector::{Collector, LdapConfig};
use anyhow::Result;
use clap::Parser;
#[derive(Parser)]
pub(crate) struct CheckAdcsArgs {
#[command(flatten)]
pub auth: crate::shared_args::LdapAuth,
#[arg(long)]
pub json: bool,
}
pub(crate) async fn check_adcs(a: CheckAdcsArgs) -> Result<()> {
let mut checklist = crate::ui::StageChecklist::new([
"ldap connect",
"collect templates",
"rule pack (ESC1-15)",
"render findings",
]);
let result = check_adcs_impl(a, &mut checklist).await;
match &result {
Ok(()) => checklist.render("check adcs stages"),
Err(_) => checklist.render("check adcs stages (failed)"),
}
result
}
async fn check_adcs_impl(
a: CheckAdcsArgs,
checklist: &mut crate::ui::StageChecklist,
) -> Result<()> {
let json = a.json;
let cfg = LdapConfig {
url: a.auth.url.clone(),
bind_dn: a.auth.user.clone(),
password: a.auth.password.clone(),
base_dn: None,
insecure: a.auth.insecure,
gssapi: false,
};
let collector = match Collector::connect(&cfg).await {
Ok(c) => c,
Err(e) => {
checklist.mark_current_failed(format!("{e:#}"));
return Err(e);
}
};
checklist.record_ok("ldap connect", a.auth.url.clone());
let snap = match collector.collect().await {
Ok(s) => s,
Err(e) => {
checklist.mark_current_failed(format!("{e:#}"));
return Err(e);
}
};
let templates =
adhammer_collector::sources::adcs::templates_from(snap.objects.iter().collect::<Vec<_>>());
checklist.record_ok(
"collect templates",
format!("{} template(s)", templates.len()),
);
let findings = adhammer_checks::rules::esc::detect_all(&templates);
checklist.record_ok(
"rule pack (ESC1-15)",
format!("{} finding(s)", findings.len()),
);
if json {
let j = serde_json::to_string_pretty(&findings)?;
println!("{j}");
} else {
println!(
"== check adcs (ms-crtd ESC rule pack) — {} template(s) scanned, {} finding(s) ==",
templates.len(),
findings.len()
);
for f in &findings {
println!(
"[{:?}] {} — {}\n affected: {}\n {}\n",
f.severity,
f.id,
f.title,
f.affected.join(", "),
f.detail
);
}
}
checklist.record_ok("render findings", if json { "json" } else { "text" });
Ok(())
}