Escape all reason for revocation messages.

- This is attacker controlled data which must be sanitizied.
This commit is contained in:
Justus Winter 2024-12-16 10:10:28 +01:00
parent 13aa81300a
commit 3692280101
No known key found for this signature in database
GPG Key ID: 686F55B4AB2B3386
6 changed files with 17 additions and 16 deletions

View File

@ -44,6 +44,7 @@ use crate::cli::types::FileOrStdout;
use crate::commands::packet::dump::PacketDumper; use crate::commands::packet::dump::PacketDumper;
use crate::common::NULL_POLICY; use crate::common::NULL_POLICY;
use crate::common::PreferredUserID; use crate::common::PreferredUserID;
use crate::common::ui;
/// Width of the largest key of any key, value pair we emit. /// Width of the largest key of any key, value pair we emit.
const WIDTH: usize = 17; const WIDTH: usize = 17;
@ -570,7 +571,7 @@ fn print_reasons(output: &mut dyn io::Write,
} }
if let Some(msg) = message { if let Some(msg) = message {
writeln!(output, "{:>WIDTH$} Message: {}", "", writeln!(output, "{:>WIDTH$} Message: {}", "",
String::from_utf8_lossy(msg))?; ui::Safe(msg))?;
} }
} }
Ok(()) Ok(())

View File

@ -26,6 +26,7 @@ use crate::Time;
use crate::cli::types::cert_designator; use crate::cli::types::cert_designator;
use crate::cli; use crate::cli;
use crate::common::NULL_POLICY; use crate::common::NULL_POLICY;
use crate::common::ui;
/// Keys may either be grouped into a certificate or be bare. /// Keys may either be grouped into a certificate or be bare.
/// ///
@ -157,8 +158,7 @@ fn key_validity(sq: &Sq, cert: &Cert, key: Option<&Fingerprint>) -> Vec<String>
reason_ = reason.to_string(); reason_ = reason.to_string();
if ! message.is_empty() { if ! message.is_empty() {
reason_.push_str(": "); reason_.push_str(": ");
reason_.push_str(&format!( reason_.push_str(&ui::Safe(message).to_string());
"{:?}", String::from_utf8_lossy(message)));
} }
&reason_ &reason_
} else { } else {

View File

@ -56,6 +56,7 @@ use crate::{
FileOrStdout, FileOrStdout,
active_certification, active_certification,
}, },
common::ui,
output::{ output::{
import::ImportStats, import::ImportStats,
pluralize::Pluralize, pluralize::Pluralize,
@ -834,7 +835,7 @@ impl Response {
{ {
qprintln!(initial_indent = " - ", qprintln!(initial_indent = " - ",
"revoked: {}, {}", reason, "revoked: {}, {}", reason,
String::from_utf8_lossy(message)); ui::Safe(message));
} else { } else {
qprintln!(initial_indent = " - ", qprintln!(initial_indent = " - ",
"revoked"); "revoked");
@ -847,7 +848,7 @@ impl Response {
{ {
qprintln!(initial_indent = " - ", qprintln!(initial_indent = " - ",
"possibly revoked: {}, {}", reason, "possibly revoked: {}, {}", reason,
String::from_utf8_lossy(message)); ui::Safe(message));
} else { } else {
qprintln!(initial_indent = " - ", qprintln!(initial_indent = " - ",
"possibly revoked"); "possibly revoked");

View File

@ -22,6 +22,7 @@ use self::openpgp::parse::{
use crate::Convert; use crate::Convert;
use crate::cli::types::SessionKey; use crate::cli::types::SessionKey;
use crate::common::ui;
use crate::Sq; use crate::Sq;
#[derive(Debug)] #[derive(Debug)]
@ -909,9 +910,9 @@ impl<'a, 'b, 'c> PacketDumper<'a, 'b, 'c> {
write!(output, "{} Signer's User ID: {}", i, write!(output, "{} Signer's User ID: {}", i,
String::from_utf8_lossy(u))?, String::from_utf8_lossy(u))?,
ReasonForRevocation{code, ref reason} => { ReasonForRevocation{code, ref reason} => {
let reason = String::from_utf8_lossy(reason);
write!(output, "{} Reason for revocation: {}{}{}", i, code, write!(output, "{} Reason for revocation: {}{}{}", i, code,
if reason.len() > 0 { ", " } else { "" }, reason)? if reason.len() > 0 { ", " } else { "" },
ui::Safe(reason))?
} }
Features(ref f) => Features(ref f) =>
write!(output, "{} Features: {:?}", i, f)?, write!(output, "{} Features: {:?}", i, f)?,

View File

@ -16,7 +16,10 @@ use cli::types::userid_designator;
use super::output::ConciseHumanReadableOutputNetwork; use super::output::ConciseHumanReadableOutputNetwork;
use super::output::OutputType; use super::output::OutputType;
use crate::Sq; use crate::{
Sq,
common::ui,
};
const TRACE: bool = false; const TRACE: bool = false;
@ -364,12 +367,7 @@ pub fn authenticate<'store, 'rstore>(
weprintln!("Warning: {} is revoked: {}{}", weprintln!("Warning: {} is revoked: {}{}",
cert.fingerprint(), cert.fingerprint(),
reason, reason,
if message.is_empty() { ui::Safe(message));
"".to_string()
} else {
format!(": {:?}",
String::from_utf8_lossy(message))
});
} else { } else {
weprintln!("Warning: {} is revoked: unspecified reason", weprintln!("Warning: {} is revoked: unspecified reason",
cert.fingerprint()); cert.fingerprint());

View File

@ -27,6 +27,7 @@ use crate::Convert;
use crate::Sq; use crate::Sq;
use crate::Time; use crate::Time;
use crate::common::ca_creation_time; use crate::common::ca_creation_time;
use crate::common::ui;
use crate::error_chain; use crate::error_chain;
use crate::output::wrapping::NBSP; use crate::output::wrapping::NBSP;
use super::OutputType; use super::OutputType;
@ -305,8 +306,7 @@ impl OutputType for ConciseHumanReadableOutputNetwork<'_, '_, '_> {
reason_ = reason.to_string(); reason_ = reason.to_string();
if ! message.is_empty() { if ! message.is_empty() {
reason_.push_str(": "); reason_.push_str(": ");
reason_.push_str(&format!( reason_.push_str(&ui::Safe(message).to_string());
"{:?}", String::from_utf8_lossy(message)));
} }
&reason_ &reason_
} else { } else {