From 2b92caf3b9d77e513a2327b8f312628019f87e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A9=BA=E7=99=BD?= <3440771474@qq.com> Date: Mon, 10 Mar 2025 17:34:00 +0800 Subject: [PATCH] feat: modelvis-app part4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 空白 <3440771474@qq.com> --- .../ModelVis/rust/file-ext/Cargo.toml | 15 ++ .../ModelVis/rust/file-ext/src/lib.rs | 176 ++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 plugins/mindstudio-insight-plugins/ModelVis/rust/file-ext/Cargo.toml create mode 100644 plugins/mindstudio-insight-plugins/ModelVis/rust/file-ext/src/lib.rs diff --git a/plugins/mindstudio-insight-plugins/ModelVis/rust/file-ext/Cargo.toml b/plugins/mindstudio-insight-plugins/ModelVis/rust/file-ext/Cargo.toml new file mode 100644 index 000000000..6dd3a9c82 --- /dev/null +++ b/plugins/mindstudio-insight-plugins/ModelVis/rust/file-ext/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "file-ext" +version = "0.1.0" +edition = "2024" + +[dependencies] +libc.workspace = true + +[dependencies.windows] +workspace = true +features = [ + "Win32_Security", + "Win32_Security_Authorization", + "Win32_System_Threading" +] \ No newline at end of file diff --git a/plugins/mindstudio-insight-plugins/ModelVis/rust/file-ext/src/lib.rs b/plugins/mindstudio-insight-plugins/ModelVis/rust/file-ext/src/lib.rs new file mode 100644 index 000000000..73aa9a445 --- /dev/null +++ b/plugins/mindstudio-insight-plugins/ModelVis/rust/file-ext/src/lib.rs @@ -0,0 +1,176 @@ +//! ### Logging Unimplemented +//! Many error handling in the current module should be logged, +//! and since the log module has not yet been completed, +//! it will return false or mark it as unimplemented + +#![feature(io_error_more)] + +use std::{fs, io::ErrorKind}; + +#[cfg(windows)] +use windows::{ + Win32::{ + Foundation::{CloseHandle, ERROR_SUCCESS, HANDLE, HLOCAL, LocalFree}, + Security::{ + Authorization::{GetNamedSecurityInfoA, SE_FILE_OBJECT}, + EqualSid, GetTokenInformation, OWNER_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, PSID, + TOKEN_QUERY, TOKEN_USER, TokenUser, + }, + System::Threading::{GetCurrentProcess, OpenProcessToken}, + }, + core::PCSTR, +}; + +use self::FileErrorKind::*; + +enum FileErrorKind<'a> { + ErrorNone, + InvalidFileName(&'a str), + NoSuchFile(&'a str), + DirNotSupported(&'a str), + UnknownError(String, &'a str), + UnsupportedFIleType(&'a str), + BadPermission(&'a str), + InconsistentOwner(&'a str), + BadFile(&'a str), +} + +struct FileExt; + +impl FileExt { + fn validate(path: &str) -> FileErrorKind { + let mut metadata = fs::metadata(path); + + match metadata { + Ok(ref mut meta) => { + if meta.is_dir() { + return DirNotSupported(path); + } + + if meta.is_symlink() { + let path = fs::read_link(path).unwrap(); + *meta = fs::metadata(path).unwrap(); + } + + #[cfg(unix)] + { + use std::os::unix::fs::MetadataExt; + + let mode = meta.mode(); + if mode & 0o400 == 0 || mode & 0o022 != 0 { + return BadPermission(path); + } + } + + #[cfg(windows)] + if !check_owner(path) { + return InconsistentOwner(path); + } + + #[cfg(unix)] + if !check_owner(meta) { + return InconsistentOwner(path); + } + } + Err(e) => + return match e.kind() { + ErrorKind::InvalidFilename => InvalidFileName(path), + ErrorKind::NotFound => NoSuchFile(path), + _ => UnknownError(e.to_string(), path), + }, + } + + ErrorNone + } +} + +#[cfg(unix)] +fn check_owner(meta: Metadata) -> bool { + use std::os::unix::fs::MetadataExt; + + let uid = meta.uid(); + let euid = unsafe { libc::geteuid() }; + + uid == euid +} + +#[cfg(windows)] +fn check_owner(path: &str) -> bool { + use std::ptr::null_mut; + + unsafe { + let psd: *mut PSECURITY_DESCRIPTOR = null_mut(); + let psid_owner: *mut PSID = null_mut(); + + if GetNamedSecurityInfoA( + PCSTR(path.as_ptr()), + SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION, + Some(psid_owner), + None, + None, + None, + psd, + ) != ERROR_SUCCESS + { + return false; + } + + let mut token_handle = HANDLE::default(); + if OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut token_handle).is_err() { + return false; + } + + let mut token_info_len = 0; + if GetTokenInformation(token_handle, TokenUser, None, 0, &mut token_info_len).is_err() { + return false; + } + + let token_user = libc::malloc(token_info_len as usize); + + if GetTokenInformation( + token_handle, + TokenUser, + Some(token_user), + token_info_len, + &mut token_info_len, + ) + .is_err() + { + libc::free(token_user); + local_free_rs(psd); + close_handle_rs(token_handle); + + return false; + } + + let process_sid = (*(token_user as *mut TOKEN_USER)).User.Sid; + + let res = EqualSid(*psd.cast(), process_sid).is_ok(); + + libc::free(token_user); + local_free_rs(psd); + close_handle_rs(token_handle); + + res + } +} + +#[cfg(windows)] +fn local_free_rs(ptr: *mut T) { + if !ptr.is_null() { + unsafe { + LocalFree(Some(HLOCAL(ptr.cast()))); + } + } +} + +/// ### Unimplemented +#[cfg(windows)] +fn close_handle_rs(handle: HANDLE) { + unsafe { + if CloseHandle(handle).is_err() { + unimplemented!() + } + } +} -- Gitee