Skip to content

Commit

Permalink
Make SD test work in CI..?
Browse files Browse the repository at this point in the history
  • Loading branch information
kotauskas committed Apr 2, 2024
1 parent 0dc4720 commit 43904af
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 43 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ windows-sys = { version = "0.52.0", features = [
"Win32_System_Threading",
"Win32_System_Memory",
"Win32_System_SystemServices",
"Win32_System_LibraryLoader",
] }
recvmsg = "1.0.0"
widestring = "1.0.2"
Expand Down
108 changes: 65 additions & 43 deletions tests/os/windows/local_socket_security_descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ use crate::{
BorrowedSecurityDescriptor, LocalBox, SecurityDescriptor,
},
tests::util::*,
TryClone,
OrErrno, TryClone,
};
use std::{io, os::windows::prelude::*, ptr, sync::Arc};
use std::{ffi::OsString, fs::File, io, mem::MaybeUninit, os::windows::prelude::*, ptr, sync::Arc};
use widestring::{U16CStr, U16Str};
use windows_sys::Win32::{
Foundation::STATUS_SUCCESS,
Foundation::{MAX_PATH, STATUS_SUCCESS},
Security::{
Authorization::{GetSecurityInfo, SE_KERNEL_OBJECT, SE_OBJECT_TYPE},
DACL_SECURITY_INFORMATION, GROUP_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION,
},
System::LibraryLoader::GetModuleFileNameW,
};

const SECINFO: u32 =
Expand Down Expand Up @@ -45,39 +46,18 @@ fn get_sd(handle: BorrowedHandle<'_>, ot: SE_OBJECT_TYPE) -> TestResult<Security
.opname("security descriptor clone")
}

fn get_process_sd() -> TestResult<SecurityDescriptor> {
get_sd(
unsafe { BorrowedHandle::borrow_raw(-1 as _) },
SE_KERNEL_OBJECT,
)
.opname("get_process_sd()")
fn count_opening_parentheses(s: &U16Str) -> u32 {
let mut cpa = 0;
for c in s.as_slice().iter().copied() {
if c == '(' as u16 {
cpa += 1;
}
}
cpa
}

#[test]
fn local_socket_security_descriptor() -> TestResult {
let sd = get_process_sd()?;
let (name, listener) =
listen_and_pick_name(&mut namegen_local_socket(make_id!(), false), |nm| {
ListenerOptions::new()
.name(nm.borrow())
.security_descriptor(sd.try_clone()?)
.create_sync()
})?;
let _ = Stream::connect(Arc::try_unwrap(name).unwrap()).opname("client connect")?;

let listener_handle = OwnedHandle::from(listener);
let listener_sd =
get_sd(listener_handle.as_handle(), SE_KERNEL_OBJECT).opname("get listener SD")?;

sd.serialize(SECINFO, |old_s| {
listener_sd.serialize(SECINFO, |new_s| {
let start = ensure_equal_non_acl_part(old_s, new_s)?;
ensure_equal_number_of_opening_parentheses(&old_s[start..], &new_s[start..])?;
TestResult::Ok(())
})
})
.opname("serialize")???;

fn ensure_equal_number_of_opening_parentheses(a: &U16Str, b: &U16Str) -> TestResult {
ensure_eq!(count_opening_parentheses(a), count_opening_parentheses(b));
Ok(())
}

Expand All @@ -99,17 +79,59 @@ fn ensure_equal_non_acl_part(a: &U16CStr, b: &U16CStr) -> TestResult<usize> {
Ok(idx)
}

fn count_opening_parentheses(s: &U16Str) -> u32 {
let mut cpa = 0;
for c in s.as_slice().iter().copied() {
if c == '(' as u16 {
cpa += 1;
}
fn get_self_exe(obuf: &mut [MaybeUninit<u16>]) -> io::Result<&U16CStr> {
if obuf.is_empty() {
return Ok(Default::default());
}
cpa
let base = obuf.as_mut_ptr().cast();
let cap = obuf.len().try_into().unwrap_or(u32::MAX);
unsafe { GetModuleFileNameW(0, base, cap) != 0 }
.true_val_or_errno(())
.and_then(|()| unsafe {
U16CStr::from_ptr_truncate(base.cast_const(), cap as usize).map_err(io::Error::other)
})
}

fn ensure_equal_number_of_opening_parentheses(a: &U16Str, b: &U16Str) -> TestResult {
ensure_eq!(count_opening_parentheses(a), count_opening_parentheses(b));
#[test]
fn local_socket_security_descriptor() -> TestResult {
let sd = {
let mut pathbuf = [MaybeUninit::uninit(); MAX_PATH as _];
let path: OsString = get_self_exe(&mut pathbuf)
.opname("query of path to own executable")?
.into();
let file = File::open(path).opname("own executable open")?;
get_sd(file.as_handle(), SE_KERNEL_OBJECT)
.opname("query of own executable's security descriptor")?
};

let (name, listener) =
listen_and_pick_name(&mut namegen_local_socket(make_id!(), false), |nm| {
ListenerOptions::new()
.name(nm.borrow())
.security_descriptor(sd.try_clone()?)
.create_sync()
})?;
let _ = Stream::connect(Arc::try_unwrap(name).unwrap()).opname("client connect")?;

let listener_handle = OwnedHandle::from(listener);
let listener_sd =
get_sd(listener_handle.as_handle(), SE_KERNEL_OBJECT).opname("get listener SD")?;

sd.serialize(SECINFO, |old_s| {
listener_sd.serialize(SECINFO, |new_s| {
eprintln!(
"\
SDDL of the running executable\t: {}
SDDL of the local socket listener\t: {}",
old_s.display(),
new_s.display()
);
let start = ensure_equal_non_acl_part(old_s, new_s)?;
ensure_equal_number_of_opening_parentheses(&old_s[start..], &new_s[start..])?;
TestResult::Ok(())
})
})
.opname("serialize and check")???;

Ok(())
}

0 comments on commit 43904af

Please sign in to comment.