don't clone

This commit is contained in:
aiden 2023-05-06 03:02:17 +01:00
parent 9be2e72d5f
commit 93274fc906
Signed by: aiden
GPG Key ID: EFA9C74AEBF806E0
2 changed files with 48 additions and 34 deletions

@ -1,6 +1,8 @@
use std::cell::{RefCell, Ref};
use crate::{clean_file::CleanFile, stringify_ser};
#[derive(Debug, Clone)]
#[derive(Debug)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct AccountDetails {
// account key
@ -8,7 +10,7 @@ pub struct AccountDetails {
pub kid: String,
}
#[derive(Debug, Clone)]
#[derive(Debug)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct OrderDetails {
pub url: String,
@ -17,71 +19,71 @@ pub struct OrderDetails {
pub dns_names: Vec<String>,
}
#[derive(Debug, Clone)]
#[derive(Debug)]
#[derive(serde::Serialize, serde::Deserialize)]
struct AcmecConfig {
// account
account_details: Option<AccountDetails>,
account_details: RefCell<Option<AccountDetails>>,
// current pending order
order_details: Option<OrderDetails>,
pkey_pem: Option<Vec<u8>>,
order_details: RefCell<Option<OrderDetails>>,
pkey_pem: RefCell<Option<Vec<u8>>>,
}
impl Default for AcmecConfig {
fn default() -> Self {
return Self {
account_details: None,
account_details: RefCell::new(None),
order_details: None,
pkey_pem: None,
order_details: RefCell::new(None),
pkey_pem: RefCell::new(None),
};
}
}
pub struct ConfigFile {
clean_file: CleanFile,
clean_file: RefCell<CleanFile>,
config: AcmecConfig,
}
impl ConfigFile {
fn write(&mut self) -> Result<(), &'static str> {
return self.clean_file.write(stringify_ser(&(self.config))?.as_bytes());
fn write(&self) -> Result<(), &'static str> {
return self.clean_file.borrow_mut().write(stringify_ser(&(self.config))?.as_bytes());
}
pub fn open(path: String, create: bool) -> Result<Self, &'static str> {
let clean_file = CleanFile::open(path, create)?;
let config: AcmecConfig = serde_json::from_reader(clean_file.file()).unwrap_or_default();
let clean_file = RefCell::new(CleanFile::open(path, create)?);
let config: AcmecConfig = serde_json::from_reader(clean_file.borrow().file()).unwrap_or_default();
return Ok(Self { clean_file, config });
}
pub fn delete(self) -> Result<(), &'static str> {
return self.clean_file.delete();
return self.clean_file.into_inner().delete();
}
pub fn account_details(&self) -> Option<AccountDetails> {
return self.config.account_details.clone();
pub fn account_details(&self) -> Ref<'_, Option<AccountDetails>> {
return self.config.account_details.borrow();
}
pub fn set_account_details(&mut self, account_details: AccountDetails) -> Result<(), &'static str> {
self.config.account_details.replace(account_details);
pub fn set_account_details(&self, account_details: AccountDetails) -> Result<(), &'static str> {
self.config.account_details.borrow_mut().replace(account_details);
return self.write();
}
pub fn order_details(&self) -> Option<OrderDetails> {
return self.config.order_details.clone();
pub fn order_details(&self) -> Ref<'_, Option<OrderDetails>> {
return self.config.order_details.borrow();
}
pub fn set_order_details(&mut self, order_details: OrderDetails) -> Result<(), &'static str> {
self.config.order_details.replace(order_details);
pub fn set_order_details(&self, order_details: OrderDetails) -> Result<(), &'static str> {
self.config.order_details.borrow_mut().replace(order_details);
return self.write();
}
pub fn pkey_pem(&self) -> Option<Vec<u8>> {
return self.config.pkey_pem.clone();
pub fn pkey_pem(&self) -> Ref<'_, Option<Vec<u8>>> {
return self.config.pkey_pem.borrow();
}
pub fn set_pkey_pem(&mut self, pkey_pem: Vec<u8>) -> Result<(), &'static str> {
self.config.pkey_pem.replace(pkey_pem);
pub fn set_pkey_pem(&self, pkey_pem: Vec<u8>) -> Result<(), &'static str> {
self.config.pkey_pem.borrow_mut().replace(pkey_pem);
return self.write();
}
pub fn discard_order(&mut self) -> Result<(), &'static str> {
self.config.order_details.take();
self.config.pkey_pem.take();
self.config.order_details.borrow_mut().take();
self.config.pkey_pem.borrow_mut().take();
return self.write();
}
}

@ -277,7 +277,8 @@ fn main() -> Result<(), &'static str> {
return Ok(());
}
let account_details = config_file.account_details().ok_or("invalid config file")?;
let borrow = config_file.account_details();
let account_details = borrow.as_ref().ok_or("invalid config file")?;
let kp = if let Some(passphrase) = pem_passphrase {
PKey::private_key_from_pem_passphrase(&(account_details.pem_kp), passphrase.as_os_str().as_bytes())
} else {
@ -285,6 +286,7 @@ fn main() -> Result<(), &'static str> {
}.map_err(|_| "failed to decode account keypair pem")?;
let mut context = AcmecContext::new(&(kp));
context.set_key_id(account_details.kid.clone());
drop(borrow);
match action.as_str() {
"delete" => {
@ -293,7 +295,8 @@ fn main() -> Result<(), &'static str> {
}
"order" => match args_iter.next().as_deref() {
Some("place") => {
config_file.order_details().map_or(Ok(()), |_| Err("there is already an order pending"))?;
config_file.order_details().as_ref().map_or(Ok(()), |_| Err("there is already an order pending"))?;
let mut payload = String::from(r#"{"identifiers":["#);
let dns_names: Vec<String> = args_iter.collect();
let mut iter = dns_names.iter();
@ -343,7 +346,8 @@ fn main() -> Result<(), &'static str> {
return Ok(());
},
Some("finalize") => {
let Some(order) = config_file.order_details() else {
let borrow = config_file.order_details();
let Some(order) = borrow.as_ref() else {
return Err("no order pending");
};
@ -365,6 +369,7 @@ fn main() -> Result<(), &'static str> {
"pending" => (),
status => {
eprintln!("order status: {status}");
drop(borrow);
config_file.discard_order()?;
return Err("bad order status");
}
@ -372,7 +377,8 @@ fn main() -> Result<(), &'static str> {
std::thread::sleep(std::time::Duration::from_secs(3));
}
let (cert_kp, pkey_pem) = if let Some(pkey_pem) = config_file.pkey_pem() {
let mut pem_borrow = config_file.pkey_pem();
let (cert_kp, pkey_pem) = if let Some(pkey_pem) = pem_borrow.as_ref() {
let cert_kp = if let Some(passphrase) = &(pkey_passphrase) {
PKey::private_key_from_pem_passphrase(&(pkey_pem), passphrase.as_os_str().as_bytes())
} else {
@ -383,6 +389,7 @@ fn main() -> Result<(), &'static str> {
} else {
let cert_kp = Rsa::generate(2048).and_then(|keypair| PKey::from_rsa(keypair)).map_err(|_| "failed to generate rsa keypair")?;
drop(pem_borrow);
config_file.set_pkey_pem(
if let Some(passphrase) = &(pkey_passphrase) {
cert_kp.private_key_to_pem_pkcs8_passphrase(Cipher::aes_256_cbc(), passphrase.as_os_str().as_bytes())
@ -391,7 +398,8 @@ fn main() -> Result<(), &'static str> {
}.map_err(|_| "failed to serialize private key")?
)?;
(cert_kp, config_file.pkey_pem().unwrap())
pem_borrow = config_file.pkey_pem();
(cert_kp, pem_borrow.as_ref().unwrap())
};
let pkey_pem_view = from_utf8(&(pkey_pem)).map_err(|_| "invalid utf-8 bytes in pem-encoded private key")?;
@ -414,6 +422,8 @@ fn main() -> Result<(), &'static str> {
status => {
eprintln!("order status: {status}");
// safe to discard order i think
drop(borrow);
drop(pem_borrow);
config_file.discard_order()?;
return Err("bad order status");
}
@ -434,6 +444,8 @@ fn main() -> Result<(), &'static str> {
println!("{}", pkey_pem_view);
}
drop(borrow);
drop(pem_borrow);
config_file.discard_order()?;
return Ok(());
},