1 use std::{fmt, path::PathBuf}; 2 3 use bytes::Bytes; 4 use rpki::repository::x509::Time; 5 6 use crate::commons::{ 7 api::{Handle, PublisherHandle}, 8 error::KrillIoError, 9 util::file, 10 }; 11 12 /// This type helps to log CMS (RFC8181 and RFC6492) protocol messages 13 /// for auditing purposes. 14 pub struct CmsLogger { 15 path: Option<PathBuf>, 16 now: i64, 17 } 18 19 impl CmsLogger { new(path: Option<PathBuf>) -> Self20 fn new(path: Option<PathBuf>) -> Self { 21 CmsLogger { 22 path, 23 now: Time::now().timestamp_millis(), 24 } 25 } 26 for_rfc6492_rcvd(log_dir: Option<&PathBuf>, ca: &Handle, sender: &Handle) -> Self27 pub fn for_rfc6492_rcvd(log_dir: Option<&PathBuf>, ca: &Handle, sender: &Handle) -> Self { 28 let path = log_dir.map(|dir| { 29 let mut path = dir.clone(); 30 path.push(ca.as_str()); 31 path.push("rcvd"); 32 path.push(sender.as_str()); 33 path 34 }); 35 36 Self::new(path) 37 } 38 for_rfc6492_sent(log_dir: Option<&PathBuf>, ca: &Handle, recipient: &Handle) -> Self39 pub fn for_rfc6492_sent(log_dir: Option<&PathBuf>, ca: &Handle, recipient: &Handle) -> Self { 40 let path = log_dir.map(|dir| { 41 let mut path = dir.clone(); 42 path.push(ca.as_str()); 43 path.push("sent"); 44 path.push(recipient.as_str()); 45 path 46 }); 47 48 Self::new(path) 49 } 50 for_rfc8181_sent(log_dir: Option<&PathBuf>, ca: &Handle) -> Self51 pub fn for_rfc8181_sent(log_dir: Option<&PathBuf>, ca: &Handle) -> Self { 52 let path = log_dir.map(|dir| { 53 let mut path = dir.clone(); 54 path.push(ca.as_str()); 55 path.push("sent"); 56 path 57 }); 58 59 Self::new(path) 60 } 61 for_rfc8181_rcvd(log_dir: Option<&PathBuf>, publisher: &PublisherHandle) -> Self62 pub fn for_rfc8181_rcvd(log_dir: Option<&PathBuf>, publisher: &PublisherHandle) -> Self { 63 let path = log_dir.map(|dir| { 64 let mut path = dir.clone(); 65 path.push(publisher.as_str()); 66 path.push("rcvd"); 67 path 68 }); 69 70 Self::new(path) 71 } 72 received(&self, msg: &Bytes) -> Result<(), KrillIoError>73 pub fn received(&self, msg: &Bytes) -> Result<(), KrillIoError> { 74 self.save(msg, "rcvd") 75 } 76 reply(&self, msg: &Bytes) -> Result<(), KrillIoError>77 pub fn reply(&self, msg: &Bytes) -> Result<(), KrillIoError> { 78 self.save(msg, "repl") 79 } 80 sent(&self, msg: &Bytes) -> Result<(), KrillIoError>81 pub fn sent(&self, msg: &Bytes) -> Result<(), KrillIoError> { 82 self.save(msg, "sent") 83 } 84 err(&self, msg: impl fmt::Display) -> Result<(), KrillIoError>85 pub fn err(&self, msg: impl fmt::Display) -> Result<(), KrillIoError> { 86 self.save(msg.to_string().as_bytes(), "err") 87 } 88 save(&self, content: &[u8], ext: &str) -> Result<(), KrillIoError>89 fn save(&self, content: &[u8], ext: &str) -> Result<(), KrillIoError> { 90 if let Some(path) = self.path.as_ref() { 91 let mut path = path.clone(); 92 path.push(&format!("{}.{}", self.now, ext)); 93 94 file::save(content, &path) 95 } else { 96 Ok(()) 97 } 98 } 99 } 100