Skip to content

Commit

Permalink
+ refine codes
Browse files Browse the repository at this point in the history
  • Loading branch information
oluceps committed Nov 18, 2024
1 parent 1653ef5 commit 3236850
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 86 deletions.
6 changes: 0 additions & 6 deletions module/templateType.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ in
{
templateType = types.submodule (submod: {
options = {
type = mkOption {
type = types.str;
default = "template";
readOnly = true;
description = "Identifier of option type";
};
content = mkOption {
type = types.str;
default = "";
Expand Down
115 changes: 46 additions & 69 deletions src/cmd/deploy.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use std::{
collections::HashMap,
fs::{self, OpenOptions, Permissions, ReadDir},
io::{self, ErrorKind, Write},
fs::{self, Permissions, ReadDir},
io::{self, ErrorKind},
os::unix::fs::PermissionsExt,
path::PathBuf,
rc::Rc,
};

use crate::{
helper::{
self,
secret_buf::{Plain, SecBuf},
stored::{InStore, SecMap, SecPath},
},
Expand Down Expand Up @@ -37,44 +36,23 @@ impl HostKey {

const KEY_TYPE: &str = "ed25519";

fn deploy_to_fs(
ctx: SecBuf<Plain>,
item: impl crate::profile::DeployFactor,
dst: PathBuf,
) -> Result<()> {
let mut the_file = {
let mode = crate::parser::parse_octal_str(item.mode())
.map_err(|e| eyre!("parse octal permission err: {}", e))?;
let permissions = Permissions::from_mode(mode);

let file = OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.open(dst)?;

file.set_permissions(permissions)?;

helper::set_owner_group::set_owner_and_group(&file, item.owner(), item.group())?;

file
macro_rules! impl_get_settings {
([ $($field:ident),+ $(,)? ]) => {
impl Profile {
$(
fn $field(&self) -> &str {
self.settings.$field.as_str()
}
)+
}
};
the_file.write_all(ctx.buf_ref())?;
Ok(())
}

impl_get_settings!([decrypted_mount_point, decrypted_dir, decrypted_dir_for_user]);

impl Profile {
pub fn get_decrypted_mount_point_path(&self) -> String {
self.settings.decrypted_mount_point.to_string()
}
pub fn get_decrypt_dir_path(&self) -> String {
self.settings.decrypted_dir.to_string()
}
pub fn get_decrypt_dir_path_for_user(&self) -> String {
self.settings.decrypted_dir_for_user.to_string()
}
pub fn read_decrypted_mount_point(&self) -> std::io::Result<ReadDir> {
fs::read_dir(self.get_decrypted_mount_point_path())
fs::read_dir(self.decrypted_mount_point())
}

pub fn get_host_key_identity(&self) -> Result<age::ssh::Identity> {
Expand Down Expand Up @@ -108,20 +86,20 @@ impl Profile {
error!("{}", err);
return Err(eyre!(err));
}
let path = self.get_decrypted_mount_point_path();
info!("creating mount point {}", path.clone());
fs::create_dir_all(path.clone()).wrap_err_with(|| {
let path = self.decrypted_mount_point();
info!("creating mount point {}", path);
fs::create_dir_all(path).wrap_err_with(|| {
format!(
"creating decrypted mountpoint: {:?}",
self.get_decrypted_mount_point_path()
self.decrypted_mount_point()
)
})?;
Mount::builder()
.fstype("ramfs")
.flags(MountFlags::NOSUID)
.data("relatime")
.data("mode=751")
.mount(String::default(), self.get_decrypted_mount_point_path())
.mount(String::default(), self.decrypted_mount_point())
.map(|_| ()) // not needed.
.wrap_err(eyre!("mount tmpfs error"))
}
Expand Down Expand Up @@ -166,27 +144,26 @@ impl Profile {

let if_early = |i: &String| -> bool { self.before_userborn.contains(i) == early };

let secrets_to_deploy = self.secrets.iter().filter(|i| if_early(i.0));
let secrets = self.secrets.values().filter(|i| if_early(&i.id));

let templates_map_iter = self.templates.iter().filter(|i| if_early(i.0));
let templates = self.templates.iter().filter(|i| if_early(i.0));

let plain_map: SecMap<Vec<u8>> =
SecMap::<SecPath<_, InStore>>::from_iter(secrets_to_deploy.into_iter().map(|(_, v)| v))
.renced_stored(
self.settings.cache_in_store.clone().into(),
self.settings.host_pubkey.as_str(),
)
.bake_ctx()?
.inner()
.into_iter()
.map(|(s, c)| (s, c.decrypt(host_prv_key).expect("err").inner()))
.collect();
let plain_map: SecMap<Vec<u8>> = SecMap::<SecPath<_, InStore>>::from_iter(secrets)
.renced_stored(
self.settings.cache_in_store.clone().into(),
self.settings.host_pubkey.as_str(),
)
.bake()?
.inner()
.iter()
.map(|(s, c)| (*s, c.decrypt(host_prv_key).expect("err").inner()))
.collect();

let generation_count = self.init_decrypted_mount_point()?;
let generation = self.init_decrypted_mount_point()?;

let target_extract_dir_with_gen = {
let mut p = PathBuf::from(self.get_decrypted_mount_point_path());
p.push(generation_count.to_string());
let mut p = PathBuf::from(self.decrypted_mount_point());
p.push(generation.to_string());

debug!("target extract dir with generation number: {:?}", p);

Expand Down Expand Up @@ -229,13 +206,13 @@ impl Profile {
.inner_ref()
.iter()
.map(|(n, c)| {
let ctx = SecBuf::<Plain>::new(c.clone());
let plain = SecBuf::<Plain>::new(c.clone());
let item = n as &dyn DeployFactor;
let dst: PathBuf = generate_dst!(item, self.settings, target_extract_dir_with_gen);

info!("secret {} -> {}", item.name(), dst.display(),);

deploy_to_fs(ctx, *n, dst)
plain.deploy_to_fs(*n, dst)
})
.for_each(|res| {
if let Err(e) = res {
Expand All @@ -246,8 +223,8 @@ impl Profile {

if !self.templates.is_empty() {
info!("start templates deployment");
// new map with {{ hash }} String as key, ctx as value
let hashstr_ctx_map: HashMap<&str, &Vec<u8>> = plain_map
// new map with {{ hash }} String as key, content as value
let hashstr_content_map: HashMap<&str, &Vec<u8>> = plain_map
.inner_ref()
.iter()
.map(|(k, v)| {
Expand All @@ -261,14 +238,14 @@ impl Profile {
})
.collect();

templates_map_iter
templates
.map(|(_, t)| {
let mut template = t.content.clone();
let hashstrs_of_it = t.parse_hash_str_list().expect("parse template");

let trim_the_insertial = t.trim;

hashstr_ctx_map
hashstr_content_map
.iter()
.filter(|(k, _)| {
let mut v = Vec::new();
Expand Down Expand Up @@ -297,29 +274,29 @@ impl Profile {
let dst = generate_dst!(item, self.settings, target_extract_dir_with_gen);

info!("template {} -> {}", item.name(), dst.display(),);
deploy_to_fs(SecBuf::<Plain>::new(template.into_bytes()), t, dst)
SecBuf::<Plain>::new(template.into_bytes()).deploy_to_fs(t, dst)
})
.for_each(|res| {
if let Err(e) = res {
error!("{}", e);
}
});

} else {
info!("no template found. deploy finished");
}

let symlink_dst = if early {
self.get_decrypt_dir_path_for_user()
self.decrypted_dir_for_user()
} else {
self.get_decrypt_dir_path()
self.decrypted_dir()
};
info!(
"link decrypted dir {} to {}",
target_extract_dir_with_gen.display(),
symlink_dst.as_str()
symlink_dst
);

match std::fs::remove_file(&symlink_dst) {
match std::fs::remove_file(symlink_dst) {
Err(e) if e.kind() == io::ErrorKind::NotFound => {}
Err(e) => Err(eyre!("{}", e))?,
Ok(_) => {
Expand Down
44 changes: 38 additions & 6 deletions src/helper/secret_buf.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use std::fs::{OpenOptions, Permissions};
use std::io::Write;
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;
use std::rc::Rc;
use std::{io::Read, iter, marker::PhantomData};

Expand Down Expand Up @@ -38,13 +42,13 @@ impl<T> SecBuf<T> {
let buffer = self.buf_ref();
let decryptor = age::Decryptor::new(&buffer[..])?;

let mut dec_ctx = vec![];
let mut dec_content = vec![];
let mut reader = decryptor.decrypt(iter::once(ident))?;
let res = reader.read_to_end(&mut dec_ctx);
let res = reader.read_to_end(&mut dec_content);
if let Ok(b) = res {
debug!("decrypted secret {} bytes", b);
}
Ok(SecBuf::new(dec_ctx))
Ok(SecBuf::new(dec_content))
}
}

Expand All @@ -68,6 +72,8 @@ impl SecBuf<AgeEnc> {
}
use eyre::eyre;

use super::set_owner_group;

impl SecBuf<Plain> {
/// encrypt with host pub key, ssh key
pub fn encrypt(self, recips: Vec<Rc<dyn Recipient>>) -> Result<SecBuf<HostEnc>> {
Expand All @@ -76,14 +82,40 @@ impl SecBuf<Plain> {
.map_err(|_| eyre!("create encryptor err"))?;

let buf = self.buf_ref();
let mut enc_ctx = vec![];
let mut enc_content = vec![];

let mut writer = encryptor.wrap_output(&mut enc_ctx)?;
let mut writer = encryptor.wrap_output(&mut enc_content)?;

use std::io::Write;
writer.write_all(buf)?;
writer.finish()?;
Ok(SecBuf::new(enc_ctx))
Ok(SecBuf::new(enc_content))
}

pub fn deploy_to_fs(
&self,
item: impl crate::profile::DeployFactor,
dst: PathBuf,
) -> Result<()> {
let mut the_file = {
let mode = crate::parser::parse_octal_str(item.mode())
.map_err(|e| eyre!("parse octal permission err: {}", e))?;
let permissions = Permissions::from_mode(mode);

let file = OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.open(dst)?;

file.set_permissions(permissions)?;

set_owner_group::set_owner_and_group(&file, item.owner(), item.group())?;

file
};
the_file.write_all(self.buf_ref())?;
Ok(())
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/helper/stored.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl<'a> SecMap<'a, SecPBWith<InStore>> {
}

/// read secret file
pub fn bake_ctx(self) -> Result<SecMap<'a, SecBuf<HostEnc>>> {
pub fn bake(self) -> Result<SecMap<'a, SecBuf<HostEnc>>> {
self.inner()
.into_iter()
.map(|(k, v)| v.read_buffer().map(|b| (k, SecBuf::from(b))))
Expand Down Expand Up @@ -261,11 +261,11 @@ impl SecMap<'_, UniPath> {
use std::io::Write;

trace!("re-encrypted output path {}", real.path.display());
let enc_ctx = store.read_buffer().expect("read buffer in store err");
let enc = store.read_buffer().expect("read buffer in store err");
// rencrypt
let renc_ctx = SecBuf::<AgeEnc>::new(enc_ctx)
let agenc = SecBuf::<AgeEnc>::new(enc)
.renc(ident, recips.clone())
.expect("renc_ctx err");
.expect("renc err");

let mut target_file = fs::OpenOptions::new()
.write(true)
Expand All @@ -274,7 +274,7 @@ impl SecMap<'_, UniPath> {
.open(real.path.clone())?;

target_file
.write_all(renc_ctx.buf_ref())
.write_all(agenc.buf_ref())
.wrap_err_with(|| eyre!("write renc file error"))
})
}
Expand Down

0 comments on commit 3236850

Please sign in to comment.