You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
2.7 KiB

//! Used for resolving autodetects
use super::*;
use std::{
path::{
Path,
},
error,
fmt,
io,
};
use tokio::{
prelude::*,
fs::{
OpenOptions,
File,
},
io::{
BufReader,
},
};
use config::op::KeyFormat;
/// Find the format (Binary, Text, PEM) of this key file.
///
/// # Note
/// This isn't an infallible test as it only parses parts of headers, if it detects a type it doesn't guarantee that the file *actually* is that type. It is just a hint or best-guess.
#[instrument(err, skip(path), fields(path = ?path.as_ref()))]
pub async fn find_key_format(path: impl AsRef<Path>, can_pem: bool) -> eyre::Result<KeyFormat>
{
async fn check_bin(file: &mut File) -> Result<bool, Error>
{
let mut buffer = [0u8; 4];
file.read_exact(&mut buffer[..]).await?;
Ok(&buffer[..] == format::RAE_HEADER_BIT)
}
async fn check_text(file: &mut File) -> Result<bool, Error>
{
let mut buffer = [0u8; 4];
file.read_exact(&mut buffer[..]).await?;
if &buffer[..] != b"--- " {
return Ok(false);
}
file.read_exact(&mut buffer[..]).await?;
Ok(&buffer[..] == format::RAE_HEADER_BIT)
}
async fn check_pem(file: &mut File) -> Result<bool, Error>
{
todo!("I don't remember the PEM format right now")
}
let mut file = {
let path = path.as_ref();
OpenOptions::new()
.read(true)
.open(path).await
.wrap_err(eyre::eyre!("Failed to open file to check"))
.with_section(|| format!("{:?}", path).header("Path was"))?
};
macro_rules! reset {
() => {
file.seek(std::io::SeekFrom::Start(0)).await?
}
}
if can_pem {
if check_pem(&mut file).await
.with_note(|| "With check for PEM")? {
return Ok(KeyFormat::PEM);
} else {
reset!();
}
}
if check_bin(&mut file).await
.with_note(|| "With check for binary")? {
return Ok(KeyFormat::Bin);
} else {
reset!();
}
if check_text(&mut file).await
.with_note(|| "With check for text")? {
return Ok(KeyFormat::Text);
}
return Err(Error::UnknownFormat)?;
}
pub async fn find_file_mode<P: AsRef<Path>>(path: P) -> Result<config::op::Mode, Error>
{
//TODO: we need to calculate mode here
todo!()
}
pub async fn find_key_mode<P: AsRef<Path>>(path: P) -> Result<config::KeyKind, Error>
{
//TODO: we need to calculate mode here
todo!()
}
#[derive(Debug)]
#[non_exhaustive]
pub enum Error
{
UnknownFormat,
IO(io::Error),
Unknown,
}
impl error::Error for Error{}
impl fmt::Display for Error
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
match self {
_ => write!(f, "unknown error"),
}
}
}
impl From<io::Error> for Error
{
#[inline] fn from(from: io::Error) -> Self
{
Self::IO(from)
}
}