mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
## Issue Addressed Resolves #2438 Resolves #2437 ## Proposed Changes Changes the permissions for validator client http server api token file and secret key to 600 from 644. Also changes the permission for logfiles generated using the `--logfile` cli option to 600. Logs the path to the api token instead of the actual api token. Updates docs to reflect the change.
145 lines
5.1 KiB
Rust
145 lines
5.1 KiB
Rust
use std::fs::File;
|
|
use std::io;
|
|
use std::io::Write;
|
|
use std::path::Path;
|
|
#[cfg(windows)]
|
|
use winapi::um::winnt::{FILE_GENERIC_READ, FILE_GENERIC_WRITE, STANDARD_RIGHTS_ALL};
|
|
|
|
/// This is the security identifier in Windows for the owner of a file. See:
|
|
/// - https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows#well-known-sids-all-versions-of-windows
|
|
#[cfg(windows)]
|
|
const OWNER_SID_STR: &str = "S-1-3-4";
|
|
/// We don't need any of the `AceFlags` listed here:
|
|
/// - https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
|
|
#[cfg(windows)]
|
|
const OWNER_ACL_ENTRY_FLAGS: u8 = 0;
|
|
/// Generic Rights:
|
|
/// - https://docs.microsoft.com/en-us/windows/win32/fileio/file-security-and-access-rights
|
|
/// Individual Read/Write/Execute Permissions (referenced in generic rights link):
|
|
/// - https://docs.microsoft.com/en-us/windows/win32/wmisdk/file-and-directory-access-rights-constants
|
|
/// STANDARD_RIGHTS_ALL
|
|
/// - https://docs.microsoft.com/en-us/windows/win32/secauthz/access-mask
|
|
#[cfg(windows)]
|
|
const OWNER_ACL_ENTRY_MASK: u32 = FILE_GENERIC_READ | FILE_GENERIC_WRITE | STANDARD_RIGHTS_ALL;
|
|
|
|
#[derive(Debug)]
|
|
pub enum Error {
|
|
/// The file could not be created
|
|
UnableToCreateFile(io::Error),
|
|
/// The file could not be copied
|
|
UnableToCopyFile(io::Error),
|
|
/// The file could not be opened
|
|
UnableToOpenFile(io::Error),
|
|
/// The file could not be renamed
|
|
UnableToRenameFile(io::Error),
|
|
/// Failed to set permissions
|
|
UnableToSetPermissions(io::Error),
|
|
/// Failed to retrieve file metadata
|
|
UnableToRetrieveMetadata(io::Error),
|
|
/// Failed to write bytes to file
|
|
UnableToWriteFile(io::Error),
|
|
/// Failed to obtain file path
|
|
UnableToObtainFilePath,
|
|
/// Failed to convert string to SID
|
|
UnableToConvertSID(u32),
|
|
/// Failed to retrieve ACL for file
|
|
UnableToRetrieveACL(u32),
|
|
/// Failed to enumerate ACL entries
|
|
UnableToEnumerateACLEntries(u32),
|
|
/// Failed to add new ACL entry
|
|
UnableToAddACLEntry(String),
|
|
/// Failed to remove ACL entry
|
|
UnableToRemoveACLEntry(String),
|
|
}
|
|
|
|
/// Creates a file with `600 (-rw-------)` permissions and writes the specified bytes to file.
|
|
pub fn create_with_600_perms<P: AsRef<Path>>(path: P, bytes: &[u8]) -> Result<(), Error> {
|
|
let path = path.as_ref();
|
|
let mut file = File::create(&path).map_err(Error::UnableToCreateFile)?;
|
|
|
|
#[cfg(unix)]
|
|
{
|
|
use std::os::unix::fs::PermissionsExt;
|
|
let mut perm = file
|
|
.metadata()
|
|
.map_err(Error::UnableToRetrieveMetadata)?
|
|
.permissions();
|
|
perm.set_mode(0o600);
|
|
file.set_permissions(perm)
|
|
.map_err(Error::UnableToSetPermissions)?;
|
|
}
|
|
|
|
file.write_all(bytes).map_err(Error::UnableToWriteFile)?;
|
|
#[cfg(windows)]
|
|
{
|
|
restrict_file_permissions(path)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn restrict_file_permissions<P: AsRef<Path>>(path: P) -> Result<(), Error> {
|
|
#[cfg(unix)]
|
|
{
|
|
use std::os::unix::fs::PermissionsExt;
|
|
let file = File::open(path.as_ref()).map_err(Error::UnableToOpenFile)?;
|
|
let mut perm = file
|
|
.metadata()
|
|
.map_err(Error::UnableToRetrieveMetadata)?
|
|
.permissions();
|
|
perm.set_mode(0o600);
|
|
file.set_permissions(perm)
|
|
.map_err(Error::UnableToSetPermissions)?;
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
{
|
|
use winapi::um::winnt::PSID;
|
|
use windows_acl::acl::{AceType, ACL};
|
|
use windows_acl::helper::sid_to_string;
|
|
|
|
let path_str = path
|
|
.as_ref()
|
|
.to_str()
|
|
.ok_or(Error::UnableToObtainFilePath)?;
|
|
let mut acl = ACL::from_file_path(&path_str, false).map_err(Error::UnableToRetrieveACL)?;
|
|
|
|
let owner_sid =
|
|
windows_acl::helper::string_to_sid(OWNER_SID_STR).map_err(Error::UnableToConvertSID)?;
|
|
|
|
let entries = acl.all().map_err(Error::UnableToEnumerateACLEntries)?;
|
|
|
|
// add single entry for file owner
|
|
acl.add_entry(
|
|
owner_sid.as_ptr() as PSID,
|
|
AceType::AccessAllow,
|
|
OWNER_ACL_ENTRY_FLAGS,
|
|
OWNER_ACL_ENTRY_MASK,
|
|
)
|
|
.map_err(|code| {
|
|
Error::UnableToAddACLEntry(format!(
|
|
"Failed to add ACL entry for SID {} error={}",
|
|
OWNER_SID_STR, code
|
|
))
|
|
})?;
|
|
// remove all AccessAllow entries from the file that aren't the owner_sid
|
|
for entry in &entries {
|
|
if let Some(ref entry_sid) = entry.sid {
|
|
let entry_sid_str = sid_to_string(entry_sid.as_ptr() as PSID)
|
|
.unwrap_or_else(|_| "BadFormat".to_string());
|
|
if entry_sid_str != OWNER_SID_STR {
|
|
acl.remove(entry_sid.as_ptr() as PSID, Some(AceType::AccessAllow), None)
|
|
.map_err(|_| {
|
|
Error::UnableToRemoveACLEntry(format!(
|
|
"Failed to remove ACL entry for SID {}",
|
|
entry_sid_str
|
|
))
|
|
})?;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|