summaryrefslogtreecommitdiff
path: root/src/secure.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/secure.rs')
-rw-r--r--src/secure.rs109
1 files changed, 71 insertions, 38 deletions
diff --git a/src/secure.rs b/src/secure.rs
index 1fc3a11..7c85ece 100644
--- a/src/secure.rs
+++ b/src/secure.rs
@@ -1,51 +1,84 @@
-use std::{os::{unix::prelude::PermissionsExt, linux::fs::MetadataExt}, fs, io::ErrorKind};
-use nix::unistd;
+use std::{os::{unix::prelude::PermissionsExt, linux::fs::MetadataExt}, fs, io::{self, ErrorKind}, path::Path};
+use nix::unistd::{self, Uid, Gid};
-pub fn write_file(dir: &str, file: &str, data: &str) -> Result<(), Box<dyn std::error::Error>> {
- std::fs::create_dir_all(dir)?;
- make_file_root(dir)?;
- let path = path(dir, file);
- std::fs::write(&path, "")?;
- make_file_root(&path)?;
- std::fs::write(&path, data)?;
- Ok(())
+
+/// Writes a file securly to a specified path with given data
+/// #### Arguments
+/// * `dir` - The directory of the secure folder
+/// * `file` - The file name to write
+/// * `data` - The data to write
+/// #### Returns
+/// A ``io::Result<()>`` if the write succeded or failed
+pub fn write_file(dir: &str, file: &str, data: &str) -> Result<(), io::Error> {
+ fs::create_dir_all(dir)?;
+ set_file_permissions(0, 0, 0o100600, dir)?;
+ let path = path(dir, file);
+ fs::write(&path, data)?;
+ set_file_permissions(0, 0, 0o100600, &path)?;
+ Ok(())
}
+
+/// Reads the file secutly to a specified path. If the file has
+/// been tampered (permissions have been changed), it ignores the
+/// file.
+/// #### Arguments
+/// * `dir` - The directory of the secure folder
+/// * `file` - The file name to write
+/// #### Returns
+/// * `None` - If the files doesnt exist or isnt trusted
+/// * `Some(String) - If the file is trusted, it returns the file's contents
pub fn read_file(dir: &str, file: &str) -> Option<String> {
- let path = path(dir,file);
- if !is_file_root(&path) {
- return None;
- }
- match std::fs::read_to_string(&path) {
- Ok(data) => return Some(data),
- Err(_) => return None
- };
+ let path = path(dir,file);
+ if !check_file_permissions(0, 0, 0o100600, &path) {
+ return None;
+ }
+ match fs::read_to_string(&path) {
+ Ok(data) => return Some(data),
+ Err(_) => return None
+ };
}
-fn make_file_root(path: &str) -> Result<(), Box<dyn std::error::Error>> {
- unistd::chown(std::path::Path::new(path), Some(unistd::Uid::from(0)), Some(unistd::Gid::from(0)))?;
- let metadata = std::fs::metadata(path)?;
- let mut perms = metadata.permissions();
- perms.set_mode(0o100600);
- fs::set_permissions(path, perms)?;
- Ok(())
-}
-fn is_file_root(path: &str) -> bool {
- return check_file_permissions(0, 0, 0o100600, path);
+/// Sets the permission for a secure file
+/// #### Arguments
+/// * `uid` - The user to own the file
+/// * `gid` - The group to own the file
+/// * `mode` - The mode permissions of the file
+/// * `path` - The path of the secure file
+/// #### Returns
+/// A ``io::Result<()>`` if the write succeded or failed
+fn set_file_permissions(uid: u32, gid: u32, mode: u32, path: &str) -> Result<(), io::Error> {
+ unistd::chown(Path::new(path), Some(Uid::from(uid)), Some(Gid::from(gid)))?;
+ let metadata = fs::metadata(path)?;
+ let mut perms = metadata.permissions();
+ perms.set_mode(mode);
+ fs::set_permissions(path, perms)?;
+ Ok(())
}
+
+/// Checks if the files permissions equals the given parameters
+/// #### Arguments
+/// * `uid` - The user to own the file
+/// * `gid` - The group to own the file
+/// * `mode` - The mode permissions of the file
+/// * `path` - The path of the secure file
+/// #### Returns
+/// True or false if the files permissions match
fn check_file_permissions(uid: u32, gid: u32, mode: u32, path: &str) -> bool {
- let metadata = match std::fs::metadata(path) {
- Ok(data) => data,
- Err(e) => {
- return e.kind() == ErrorKind::NotFound
- }
- };
- let perms = metadata.permissions();
- return perms.mode() == mode && metadata.st_uid() == uid && metadata.st_gid() == gid;
+ let metadata = match fs::metadata(path) {
+ Ok(data) => data,
+ Err(e) => {
+ return e.kind() == ErrorKind::NotFound;
+ }
+ };
+ let perms = metadata.permissions();
+ return perms.mode() == mode && metadata.st_uid() == uid && metadata.st_gid() == gid;
}
+
+/// Get the path of a file given a directory and file name
fn path(dir: &str, file: &str) -> String {
- return format!("{}/{}", dir, file);
-} \ No newline at end of file
+ return format!("{}/{}.persist", dir, file);
+}