diff --git a/src/keyfile.rs b/src/keyfile.rs index 300d851c..e13f7e46 100644 --- a/src/keyfile.rs +++ b/src/keyfile.rs @@ -2,7 +2,9 @@ use std::collections::HashMap; use std::env; use std::fs; use std::io::{Read, Write}; +#[cfg(unix)] use std::os::unix::fs::PermissionsExt; +// No extra imports needed for Windows use std::path::PathBuf; use std::str::from_utf8; @@ -549,16 +551,23 @@ impl Keyfile { return Ok(false); } - // get file metadata - let metadata = fs::metadata(&self._path).map_err(|e| { - KeyFileError::MetadataError(format!("Failed to get metadata for file: {}.", e)) - })?; - - // check permissions - let permissions = metadata.permissions(); - let readable = permissions.mode() & 0o444 != 0; // check readability - - Ok(readable) + #[cfg(unix)] + { + let metadata = fs::metadata(&self._path).map_err(|e| { + KeyFileError::MetadataError(format!("Failed to get metadata for file: {}.", e)) + })?; + let permissions = metadata.permissions(); + let readable = permissions.mode() & 0o444 != 0; // check readability + Ok(readable) + } + #[cfg(windows)] + { + // On Windows, check if the file is readable by trying to open it for reading + match fs::File::open(&self._path) { + Ok(_) => Ok(true), + Err(_) => Ok(false), + } + } } /// Returns ``True`` if the file under path is writable. @@ -568,16 +577,23 @@ impl Keyfile { return Ok(false); } - // get file metadata - let metadata = fs::metadata(&self._path).map_err(|e| { - KeyFileError::MetadataError(format!("Failed to get metadata for file: {}", e)) - })?; - - // check the permissions - let permissions = metadata.permissions(); - let writable = permissions.mode() & 0o222 != 0; // check if file is writable - - Ok(writable) + #[cfg(unix)] + { + let metadata = fs::metadata(&self._path).map_err(|e| { + KeyFileError::MetadataError(format!("Failed to get metadata for file: {}", e)) + })?; + let permissions = metadata.permissions(); + let writable = permissions.mode() & 0o222 != 0; // check if file is writable + Ok(writable) + } + #[cfg(windows)] + { + // On Windows, check if the file is writable by trying to open it for writing + match fs::OpenOptions::new().write(true).open(&self._path) { + Ok(_) => Ok(true), + Err(_) => Ok(false), + } + } } /// Returns ``True`` if the file under path is encrypted. @@ -881,15 +897,22 @@ impl Keyfile { .map_err(|e| KeyFileError::FileWrite(format!("Failed to write to file: {}.", e)))?; // set permissions - let mut permissions = fs::metadata(&self._path) - .map_err(|e| { - KeyFileError::MetadataError(format!("Failed to get metadata for file: {}.", e)) - })? - .permissions(); - permissions.set_mode(0o600); // just for owner - fs::set_permissions(&self._path, permissions).map_err(|e| { - KeyFileError::PermissionError(format!("Failed to set permissions: {}.", e)) - })?; + #[cfg(unix)] + { + let mut permissions = fs::metadata(&self._path) + .map_err(|e| { + KeyFileError::MetadataError(format!("Failed to get metadata for file: {}.", e)) + })? + .permissions(); + permissions.set_mode(0o600); // just for owner + fs::set_permissions(&self._path, permissions).map_err(|e| { + KeyFileError::PermissionError(format!("Failed to set permissions: {}.", e)) + })?; + } + #[cfg(windows)] + { + // On Windows, do nothing for now (permissions are handled differently) + } Ok(()) } diff --git a/src/python_bindings.rs b/src/python_bindings.rs index 7aab3bc9..446c187b 100644 --- a/src/python_bindings.rs +++ b/src/python_bindings.rs @@ -142,7 +142,7 @@ impl PyKeyfile { } #[getter(data)] - fn data_py(&self) -> PyResult>> { + fn data_py(&self) -> PyResult>> { self.inner .data() .map(|vec| Some(Cow::Owned(vec))) @@ -266,7 +266,7 @@ impl PyKeypair { } #[pyo3(signature = (data))] - fn sign(&self, data: Py, py: Python) -> PyResult> { + fn sign(&self, data: Py, py: Python) -> PyResult> { // Convert data to bytes (data can be a string, hex, or bytes) let data_bound = data.bind(py); let data_bytes = if let Ok(s) = data_bound.extract::() { @@ -348,7 +348,7 @@ impl PyKeypair { } #[getter] - fn public_key(&self) -> PyResult>> { + fn public_key(&self) -> PyResult>> { self.inner .public_key() .map(|opt| opt.map(Cow::from)) @@ -555,7 +555,10 @@ fn py_get_password_from_environment(env_var_name: String) -> PyResult) -> PyResult> { +fn py_encrypt_keyfile_data( + keyfile_data: &[u8], + password: Option, +) -> PyResult> { keyfile::encrypt_keyfile_data(keyfile_data, password) .map(Cow::from) .map_err(|e| PyErr::new::(e)) @@ -567,7 +570,7 @@ fn py_decrypt_keyfile_data( keyfile_data: &[u8], password: Option, password_env_var: Option, -) -> PyResult> { +) -> PyResult> { keyfile::decrypt_keyfile_data(keyfile_data, password, password_env_var) .map(Cow::from) .map_err(|e| PyErr::new::(e))