Skip to content

Commit 9a3f0ba

Browse files
committed
refactor (#386)
1 parent de5ff1b commit 9a3f0ba

File tree

2 files changed

+110
-112
lines changed

2 files changed

+110
-112
lines changed

git-sec/src/identity.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
2+
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
3+
/// An account based identity
4+
pub struct Account {
5+
/// The user's name
6+
pub username: String,
7+
/// The user's password
8+
pub password: String,
9+
}
10+
11+
use std::borrow::Cow;
12+
use std::path::Path;
13+
14+
/// Returns true if the given `path` is owned by the user who is executing the current process.
15+
///
16+
/// Note that this method is very specific to avoid having to deal with any operating system types.
17+
pub fn is_path_owned_by_current_user(path: Cow<'_, Path>) -> std::io::Result<bool> {
18+
impl_::is_path_owned_by_current_user(path)
19+
}
20+
21+
#[cfg(not(windows))]
22+
mod impl_ {
23+
use std::borrow::Cow;
24+
use std::path::Path;
25+
26+
pub fn is_path_owned_by_current_user(path: Cow<'_, Path>) -> std::io::Result<bool> {
27+
fn from_path(path: Cow<'_, Path>) -> std::io::Result<u32> {
28+
use std::os::unix::fs::MetadataExt;
29+
let meta = std::fs::symlink_metadata(path)?;
30+
Ok(meta.uid())
31+
}
32+
33+
fn from_process() -> std::io::Result<u32> {
34+
// SAFETY: there is no documented possibility for failure
35+
#[allow(unsafe_code)]
36+
let uid = unsafe { libc::geteuid() };
37+
Ok(uid)
38+
}
39+
40+
Ok(from_path(path)? == from_process()?)
41+
}
42+
}
43+
44+
#[cfg(windows)]
45+
mod impl_ {
46+
use std::borrow::Cow;
47+
use std::path::Path;
48+
49+
fn err(msg: impl Into<String>) -> std::io::Error {
50+
std::io::Error::new(std::io::ErrorKind::Other, msg.into())
51+
}
52+
53+
pub fn is_path_owned_by_current_user(path: Cow<'_, Path>) -> std::io::Result<bool> {
54+
use windows::{
55+
core::PCWSTR,
56+
Win32::{
57+
Foundation::{BOOL, ERROR_SUCCESS, HANDLE, PSID},
58+
Security::{
59+
Authorization::{GetNamedSecurityInfoW, SE_FILE_OBJECT},
60+
CheckTokenMembershipEx, OWNER_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR,
61+
},
62+
System::Memory::LocalFree,
63+
},
64+
};
65+
66+
let mut err_msg = None;
67+
let mut is_owned = false;
68+
69+
#[allow(unsafe_code)]
70+
unsafe {
71+
let mut psid = PSID::default();
72+
let mut pdescriptor = PSECURITY_DESCRIPTOR::default();
73+
let wpath = to_wide_path(&path);
74+
75+
let result = GetNamedSecurityInfoW(
76+
PCWSTR(wpath.as_ptr()),
77+
SE_FILE_OBJECT,
78+
OWNER_SECURITY_INFORMATION,
79+
&mut psid,
80+
std::ptr::null_mut(),
81+
std::ptr::null_mut(),
82+
std::ptr::null_mut(),
83+
&mut pdescriptor,
84+
);
85+
86+
if result == ERROR_SUCCESS.0 {
87+
let mut is_member = BOOL(0);
88+
if CheckTokenMembershipEx(HANDLE::default(), psid, 0, &mut is_member).as_bool() {
89+
is_owned = is_member.as_bool();
90+
} else {
91+
err_msg = String::from("Could not check token membership").into();
92+
}
93+
} else {
94+
err_msg = format!("Could not get security information for path with err: {}", result).into();
95+
}
96+
97+
LocalFree(pdescriptor.0 as isize);
98+
}
99+
100+
err_msg.map(|msg| Err(err(msg))).unwrap_or(Ok(is_owned))
101+
}
102+
103+
fn to_wide_path(path: &Path) -> Vec<u16> {
104+
use std::os::windows::ffi::OsStrExt;
105+
let mut wide_path: Vec<_> = path.as_os_str().encode_wide().collect();
106+
wide_path.push(0);
107+
wide_path
108+
}
109+
}

git-sec/src/lib.rs

Lines changed: 1 addition & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -2,115 +2,4 @@
22
//! A shared trust model for `gitoxide` crates.
33
44
/// Various types to identify entities.
5-
pub mod identity {
6-
7-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
8-
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
9-
/// An account based identity
10-
pub struct Account {
11-
/// The user's name
12-
pub username: String,
13-
/// The user's password
14-
pub password: String,
15-
}
16-
17-
use std::borrow::Cow;
18-
use std::path::Path;
19-
20-
/// Returns true if the given `path` is owned by the user who is executing the current process.
21-
///
22-
/// Note that this method is very specific to avoid having to deal with any operating system types.
23-
pub fn is_path_owned_by_current_user(path: Cow<'_, Path>) -> std::io::Result<bool> {
24-
impl_::is_path_owned_by_current_user(path)
25-
}
26-
27-
#[cfg(not(windows))]
28-
mod impl_ {
29-
use std::borrow::Cow;
30-
use std::path::Path;
31-
32-
pub fn is_path_owned_by_current_user(path: Cow<'_, Path>) -> std::io::Result<bool> {
33-
fn from_path(path: Cow<'_, Path>) -> std::io::Result<u32> {
34-
use std::os::unix::fs::MetadataExt;
35-
let meta = std::fs::symlink_metadata(path)?;
36-
Ok(meta.uid())
37-
}
38-
39-
fn from_process() -> std::io::Result<u32> {
40-
// SAFETY: there is no documented possibility for failure
41-
#[allow(unsafe_code)]
42-
let uid = unsafe { libc::geteuid() };
43-
Ok(uid)
44-
}
45-
46-
Ok(from_path(path)? == from_process()?)
47-
}
48-
}
49-
50-
#[cfg(windows)]
51-
mod impl_ {
52-
use std::borrow::Cow;
53-
use std::path::Path;
54-
55-
fn err(msg: impl Into<String>) -> std::io::Error {
56-
std::io::Error::new(std::io::ErrorKind::Other, msg.into())
57-
}
58-
59-
pub fn is_path_owned_by_current_user(path: Cow<'_, Path>) -> std::io::Result<bool> {
60-
use windows::{
61-
core::PCWSTR,
62-
Win32::{
63-
Foundation::{BOOL, ERROR_SUCCESS, HANDLE, PSID},
64-
Security::{
65-
Authorization::{GetNamedSecurityInfoW, SE_FILE_OBJECT},
66-
CheckTokenMembershipEx, OWNER_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR,
67-
},
68-
System::Memory::LocalFree,
69-
},
70-
};
71-
72-
let mut err_msg = None;
73-
let mut is_owned = false;
74-
75-
#[allow(unsafe_code)]
76-
unsafe {
77-
let mut psid = PSID::default();
78-
let mut pdescriptor = PSECURITY_DESCRIPTOR::default();
79-
let wpath = to_wide_path(&path);
80-
81-
let result = GetNamedSecurityInfoW(
82-
PCWSTR(wpath.as_ptr()),
83-
SE_FILE_OBJECT,
84-
OWNER_SECURITY_INFORMATION,
85-
&mut psid,
86-
std::ptr::null_mut(),
87-
std::ptr::null_mut(),
88-
std::ptr::null_mut(),
89-
&mut pdescriptor,
90-
);
91-
92-
if result == ERROR_SUCCESS.0 {
93-
let mut is_member = BOOL(0);
94-
if CheckTokenMembershipEx(HANDLE::default(), psid, 0, &mut is_member).as_bool() {
95-
is_owned = is_member.as_bool();
96-
} else {
97-
err_msg = String::from("Could not check token membership").into();
98-
}
99-
} else {
100-
err_msg = format!("Could not get security information for path with err: {}", result).into();
101-
}
102-
103-
LocalFree(pdescriptor.0 as isize);
104-
}
105-
106-
err_msg.map(|msg| Err(err(msg))).unwrap_or(Ok(is_owned))
107-
}
108-
109-
fn to_wide_path(path: &Path) -> Vec<u16> {
110-
use std::os::windows::ffi::OsStrExt;
111-
let mut wide_path: Vec<_> = path.as_os_str().encode_wide().collect();
112-
wide_path.push(0);
113-
wide_path
114-
}
115-
}
116-
}
5+
pub mod identity;

0 commit comments

Comments
 (0)