phase 5
This commit is contained in:
+46
-11
@@ -1,7 +1,9 @@
|
||||
use std::ffi::OsString;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use age::ssh::Identity;
|
||||
use flate2::Compression;
|
||||
use flate2::read::GzDecoder;
|
||||
use flate2::write::GzEncoder;
|
||||
use clap::{Parser, Subcommand};
|
||||
use crate::error::DrawerError;
|
||||
@@ -105,7 +107,40 @@ impl DrawerOperation {
|
||||
}
|
||||
|
||||
fn perform_open(&self) -> Result<(), DrawerError> {
|
||||
todo!()
|
||||
let encrypted = std::fs::read(&self.drawer_file)
|
||||
.map_err(|_| DrawerError::DrawerFileNotFound(self.drawer_file.clone()))?;
|
||||
|
||||
let decrypted = self.decrypt(encrypted)?;
|
||||
|
||||
let cursor = std::io::Cursor::new(decrypted);
|
||||
let gz = GzDecoder::new(cursor);
|
||||
let mut archive = tar::Archive::new(gz);
|
||||
archive.unpack(&self.target_path)
|
||||
.map_err(|_| DrawerError::UntarFailed)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn decrypt(&self, encrypted: Vec<u8>) -> Result<Vec<u8>, DrawerError> {
|
||||
let (key_path, identity) = self.identity()?;
|
||||
|
||||
let decryptor = age::Decryptor::new(encrypted.as_slice())
|
||||
.map_err(|_| DrawerError::DecryptFailed(self.drawer_file.clone(), key_path.clone()))?;
|
||||
let mut decrypted: Vec<u8> = Vec::new();
|
||||
let mut stream = decryptor.decrypt(std::iter::once(&identity as &dyn age::Identity))
|
||||
.map_err(|_| DrawerError::DecryptFailed(self.drawer_file.clone(), key_path.clone()))?;
|
||||
std::io::Read::read_to_end(&mut stream, &mut decrypted)
|
||||
.map_err(|_| DrawerError::DecryptFailed(self.drawer_file.clone(), key_path.clone()))?;
|
||||
Ok(decrypted)
|
||||
}
|
||||
|
||||
fn identity(&self) -> Result<(PathBuf, Identity), DrawerError> {
|
||||
let key_path = self.key_path()?;
|
||||
let file = std::fs::File::open(&key_path)
|
||||
.map_err(|_| DrawerError::KeyInvalid(key_path.clone()))?;
|
||||
let reader = std::io::BufReader::new(file);
|
||||
let identity = age::ssh::Identity::from_buffer(reader, None)
|
||||
.map_err(|_| DrawerError::DecryptFailed(self.drawer_file.clone(), key_path.clone()))?;
|
||||
Ok((key_path, identity))
|
||||
}
|
||||
|
||||
fn perform_close(&self) -> Result<(), DrawerError> {
|
||||
@@ -121,12 +156,14 @@ impl DrawerOperation {
|
||||
.map_err(|_| DrawerError::TarFailed)?;
|
||||
}
|
||||
|
||||
let key_path = self.key_path()?;
|
||||
let file = std::fs::File::open(&key_path)
|
||||
.map_err(|_| DrawerError::KeyInvalid(key_path.clone()))?;
|
||||
let reader = std::io::BufReader::new(file);
|
||||
let identity = age::ssh::Identity::from_buffer(reader, None)
|
||||
.map_err(|_| DrawerError::EncryptFailed)?;
|
||||
let encrypted = self.encrypt(&buf)?;
|
||||
|
||||
std::fs::write(&self.drawer_file, &encrypted)
|
||||
.map_err(|_| DrawerError::WriteFailed(self.drawer_file.clone()))
|
||||
}
|
||||
|
||||
fn encrypt(&self, buf: &[u8]) -> Result<Vec<u8>, DrawerError> {
|
||||
let (_, identity) = self.identity()?;
|
||||
let recipient = age::ssh::Recipient::try_from(identity)
|
||||
.map_err(|_| DrawerError::EncryptFailed)?;
|
||||
|
||||
@@ -136,11 +173,9 @@ impl DrawerOperation {
|
||||
).map_err(|_| DrawerError::EncryptFailed)?;
|
||||
let mut writer = encryptor.wrap_output(&mut encrypted)
|
||||
.map_err(|_| DrawerError::EncryptFailed)?;
|
||||
writer.write_all(&buf).map_err(|_| DrawerError::EncryptFailed)?;
|
||||
writer.write_all(buf).map_err(|_| DrawerError::EncryptFailed)?;
|
||||
writer.finish().map_err(|_| DrawerError::EncryptFailed)?;
|
||||
|
||||
std::fs::write(&self.drawer_file, &encrypted)
|
||||
.map_err(|_| DrawerError::WriteFailed(self.drawer_file.clone()))
|
||||
Ok(encrypted)
|
||||
}
|
||||
|
||||
pub fn validate(&self) -> Result<(), DrawerError> {
|
||||
|
||||
Reference in New Issue
Block a user