fabaccess-bffh/bffhd/keylog.rs

71 lines
1.8 KiB
Rust

use std::fmt::Formatter;
use std::fs::{File, OpenOptions};
use std::io::Write;
use std::path::Path;
use std::sync::Mutex;
use std::{fmt, io};
// Internal mutable state for KeyLogFile
struct KeyLogFileInner {
file: File,
buf: Vec<u8>,
}
impl fmt::Debug for KeyLogFileInner {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.file, f)
}
}
impl KeyLogFileInner {
fn new(path: impl AsRef<Path>) -> io::Result<Self> {
let file = OpenOptions::new().append(true).create(true).open(path)?;
Ok(Self {
file,
buf: Vec::new(),
})
}
fn try_write(&mut self, label: &str, client_random: &[u8], secret: &[u8]) -> io::Result<()> {
self.buf.truncate(0);
write!(self.buf, "{} ", label)?;
for b in client_random.iter() {
write!(self.buf, "{:02x}", b)?;
}
write!(self.buf, " ")?;
for b in secret.iter() {
write!(self.buf, "{:02x}", b)?;
}
writeln!(self.buf)?;
self.file.write_all(&self.buf)
}
}
#[derive(Debug)]
/// [`KeyLog`] implementation that opens a file at the given path
pub struct KeyLogFile(Mutex<KeyLogFileInner>);
impl KeyLogFile {
/// Makes a new `KeyLogFile`. The environment variable is
/// inspected and the named file is opened during this call.
pub fn new(path: impl AsRef<Path>) -> io::Result<Self> {
Ok(Self(Mutex::new(KeyLogFileInner::new(path)?)))
}
}
impl rustls::KeyLog for KeyLogFile {
fn log(&self, label: &str, client_random: &[u8], secret: &[u8]) {
match self
.0
.lock()
.unwrap()
.try_write(label, client_random, secret)
{
Ok(()) => {}
Err(e) => {
tracing::warn!("error writing to key log file: {}", e);
}
}
}
}