mirror of
https://github.com/beerpiss/saekawa.git
synced 2024-11-14 10:37:40 +01:00
fix: free WinVerifyTrust state data
working with Win32 APIs is actually miserable as shit
This commit is contained in:
parent
e5dda7def3
commit
47bb748b3b
@ -1,7 +1,13 @@
|
|||||||
mod defaults;
|
mod defaults;
|
||||||
mod migrate;
|
mod migrate;
|
||||||
|
|
||||||
use std::{collections::HashMap, fs::File, io::Write, path::{Path, PathBuf}, str::FromStr};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fs::File,
|
||||||
|
io::Write,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use migrate::OldSaekawaConfig;
|
use migrate::OldSaekawaConfig;
|
||||||
@ -38,12 +44,12 @@ pub enum MigrationError {
|
|||||||
impl SaekawaConfig {
|
impl SaekawaConfig {
|
||||||
pub fn load() -> Result<SaekawaConfig, ConfigLoadError> {
|
pub fn load() -> Result<SaekawaConfig, ConfigLoadError> {
|
||||||
if !Path::new("saekawa.toml").exists() {
|
if !Path::new("saekawa.toml").exists() {
|
||||||
// We don't really care about the error here, since Confy will autogenerate a
|
// We don't really care about the error here, since Confy will autogenerate a
|
||||||
// default configuration file anyways. That one just doesn't have comments.
|
// default configuration file anyways. That one just doesn't have comments.
|
||||||
let _ = File::create_new("saekawa.toml")
|
let _ = File::create_new("saekawa.toml")
|
||||||
.and_then(|mut file| file.write_all(include_bytes!("../../res/saekawa.toml")));
|
.and_then(|mut file| file.write_all(include_bytes!("../../res/saekawa.toml")));
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = confy::load_path::<SaekawaConfig>("saekawa.toml");
|
let result = confy::load_path::<SaekawaConfig>("saekawa.toml");
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
@ -5,10 +5,18 @@ use widestring::U16CString;
|
|||||||
use winapi::{
|
use winapi::{
|
||||||
ctypes::c_void,
|
ctypes::c_void,
|
||||||
shared::{
|
shared::{
|
||||||
minwindef::{FALSE, HINSTANCE, HMODULE, TRUE}, ntdef::HANDLE, winerror::ERROR_INSUFFICIENT_BUFFER
|
minwindef::{FALSE, HINSTANCE, HMODULE, TRUE},
|
||||||
|
ntdef::HANDLE,
|
||||||
|
winerror::ERROR_INSUFFICIENT_BUFFER,
|
||||||
},
|
},
|
||||||
um::{
|
um::{
|
||||||
errhandlingapi::GetLastError, handleapi::{CloseHandle, DuplicateHandle}, libloaderapi::{FreeLibraryAndExitThread, GetModuleFileNameW}, processthreadsapi::{GetCurrentProcess, GetCurrentThread}, synchapi::WaitForSingleObject, winhttp::{WinHttpQueryOption, HINTERNET}, winnt::SYNCHRONIZE
|
errhandlingapi::GetLastError,
|
||||||
|
handleapi::{CloseHandle, DuplicateHandle},
|
||||||
|
libloaderapi::{FreeLibraryAndExitThread, GetModuleFileNameW},
|
||||||
|
processthreadsapi::{GetCurrentProcess, GetCurrentThread},
|
||||||
|
synchapi::WaitForSingleObject,
|
||||||
|
winhttp::{WinHttpQueryOption, HINTERNET},
|
||||||
|
winnt::SYNCHRONIZE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,7 +29,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
score_import::execute_score_import,
|
score_import::execute_score_import,
|
||||||
sigscan::{self, CryptoKeys},
|
sigscan::{self, CryptoKeys},
|
||||||
types::{chuni::UpsertUserAllRequest, ToBatchManual}, updater::self_update,
|
types::{chuni::UpsertUserAllRequest, ToBatchManual},
|
||||||
|
updater::self_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Snafu)]
|
#[derive(Debug, Snafu)]
|
||||||
|
@ -81,19 +81,25 @@ pub fn execute_score_import(
|
|||||||
return Err(ScoreImportError::MaxRetriesExhausted { max_retries });
|
return Err(ScoreImportError::MaxRetriesExhausted { max_retries });
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Saving batch manual JSON to configured failed import directory for later import.");
|
info!(
|
||||||
|
"Saving batch manual JSON to configured failed import directory for later import."
|
||||||
|
);
|
||||||
|
|
||||||
let current_time = chrono::Local::now().format("%Y-%m-%d_%H-%M-%S");
|
let current_time = chrono::Local::now().format("%Y-%m-%d_%H-%M-%S");
|
||||||
let failed_import_filename =
|
let failed_import_filename =
|
||||||
d.join(format!("saekawa_{}_{}.json", access_code, current_time));
|
d.join(format!("saekawa_{}_{}.json", access_code, current_time));
|
||||||
|
|
||||||
{
|
{
|
||||||
let file = File::create(&failed_import_filename).context(FailedCreatingBackupSnafu)?;
|
let file =
|
||||||
|
File::create(&failed_import_filename).context(FailedCreatingBackupSnafu)?;
|
||||||
serde_json::to_writer_pretty(file, &import).context(FailedWritingBackupSnafu)?;
|
serde_json::to_writer_pretty(file, &import).context(FailedWritingBackupSnafu)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Saved batch manual JSON to {}", failed_import_filename.to_string_lossy());
|
info!(
|
||||||
|
"Saved batch manual JSON to {}",
|
||||||
|
failed_import_filename.to_string_lossy()
|
||||||
|
);
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
|
@ -42,7 +42,7 @@ use winapi::{
|
|||||||
},
|
},
|
||||||
wintrust::{
|
wintrust::{
|
||||||
WinVerifyTrust, WINTRUST_DATA, WINTRUST_FILE_INFO, WTD_CHOICE_FILE, WTD_REVOKE_NONE,
|
WinVerifyTrust, WINTRUST_DATA, WINTRUST_FILE_INFO, WTD_CHOICE_FILE, WTD_REVOKE_NONE,
|
||||||
WTD_STATEACTION_VERIFY, WTD_UI_NONE,
|
WTD_STATEACTION_CLOSE, WTD_STATEACTION_VERIFY, WTD_UI_NONE,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -425,34 +425,40 @@ fn validate_sha256(data: &[u8], expected: &str) -> Result<(), SelfUpdateError> {
|
|||||||
fn verify_signature(file: &str) -> Result<(), VerifySignatureError> {
|
fn verify_signature(file: &str) -> Result<(), VerifySignatureError> {
|
||||||
let file_osstr = U16CString::from_str_truncate(file);
|
let file_osstr = U16CString::from_str_truncate(file);
|
||||||
let mut verification_type = WINTRUST_ACTION_GENERIC_VERIFY_V2;
|
let mut verification_type = WINTRUST_ACTION_GENERIC_VERIFY_V2;
|
||||||
let mut wintrust_data_buf = vec![0u8; mem::size_of::<WINTRUST_DATA>()];
|
|
||||||
let mut fileinfo_buf = vec![0u8; mem::size_of::<WINTRUST_FILE_INFO>()];
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let fileinfo = fileinfo_buf.as_mut_ptr() as *mut WINTRUST_FILE_INFO;
|
let mut fileinfo = mem::zeroed::<WINTRUST_FILE_INFO>();
|
||||||
let wintrust_data = wintrust_data_buf.as_mut_ptr() as *mut WINTRUST_DATA;
|
let mut wintrust_data = mem::zeroed::<WINTRUST_DATA>();
|
||||||
|
|
||||||
(*fileinfo).cbStruct = mem::size_of::<WINTRUST_FILE_INFO>() as u32;
|
fileinfo.cbStruct = mem::size_of::<WINTRUST_FILE_INFO>() as u32;
|
||||||
(*fileinfo).pcwszFilePath = file_osstr.as_ptr();
|
fileinfo.pcwszFilePath = file_osstr.as_ptr();
|
||||||
(*fileinfo).hFile = ptr::null_mut();
|
fileinfo.hFile = ptr::null_mut();
|
||||||
(*fileinfo).pgKnownSubject = ptr::null_mut();
|
fileinfo.pgKnownSubject = ptr::null_mut();
|
||||||
|
|
||||||
(*wintrust_data).pPolicyCallbackData = ptr::null_mut();
|
wintrust_data.pPolicyCallbackData = ptr::null_mut();
|
||||||
(*wintrust_data).pSIPClientData = ptr::null_mut();
|
wintrust_data.pSIPClientData = ptr::null_mut();
|
||||||
(*wintrust_data).cbStruct = mem::size_of::<WINTRUST_DATA>() as u32;
|
wintrust_data.cbStruct = mem::size_of::<WINTRUST_DATA>() as u32;
|
||||||
(*wintrust_data).dwStateAction = WTD_STATEACTION_VERIFY;
|
wintrust_data.dwStateAction = WTD_STATEACTION_VERIFY;
|
||||||
(*wintrust_data).dwUIChoice = WTD_UI_NONE;
|
wintrust_data.dwUIChoice = WTD_UI_NONE;
|
||||||
(*wintrust_data).fdwRevocationChecks = WTD_REVOKE_NONE;
|
wintrust_data.fdwRevocationChecks = WTD_REVOKE_NONE;
|
||||||
(*wintrust_data).dwUnionChoice = WTD_CHOICE_FILE;
|
wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
|
||||||
(*wintrust_data).hWVTStateData = ptr::null_mut();
|
wintrust_data.hWVTStateData = ptr::null_mut();
|
||||||
(*wintrust_data).pwszURLReference = ptr::null_mut();
|
wintrust_data.pwszURLReference = ptr::null_mut();
|
||||||
(*wintrust_data).dwUIContext = 0;
|
wintrust_data.dwUIContext = 0;
|
||||||
*(*wintrust_data).u.pFile_mut() = fileinfo;
|
*wintrust_data.u.pFile_mut() = &mut fileinfo as *mut _;
|
||||||
|
|
||||||
let status = WinVerifyTrust(
|
let status = WinVerifyTrust(
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
&mut verification_type,
|
&mut verification_type,
|
||||||
wintrust_data as *mut _,
|
&mut wintrust_data as *mut _ as _,
|
||||||
|
);
|
||||||
|
|
||||||
|
wintrust_data.dwStateAction = WTD_STATEACTION_CLOSE;
|
||||||
|
|
||||||
|
WinVerifyTrust(
|
||||||
|
ptr::null_mut(),
|
||||||
|
&mut verification_type,
|
||||||
|
&mut wintrust_data as *mut _ as _,
|
||||||
);
|
);
|
||||||
|
|
||||||
match status {
|
match status {
|
||||||
@ -535,13 +541,14 @@ fn get_signature_pubkey(file: &str) -> Result<Vec<u8>, GetSignaturePubkeyError>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cert_search_params_buf = vec![0u8; mem::size_of::<CERT_INFO>()];
|
let cert_search_params = unsafe {
|
||||||
let cert_search_params = cert_search_params_buf.as_mut_ptr() as *mut CERT_INFO;
|
let mut csp = mem::zeroed::<CERT_INFO>();
|
||||||
|
|
||||||
unsafe {
|
csp.Issuer = (*signer_info).Issuer;
|
||||||
(*cert_search_params).Issuer = (*signer_info).Issuer;
|
csp.SerialNumber = (*signer_info).SerialNumber;
|
||||||
(*cert_search_params).SerialNumber = (*signer_info).SerialNumber;
|
|
||||||
}
|
csp
|
||||||
|
};
|
||||||
|
|
||||||
let cert = unsafe {
|
let cert = unsafe {
|
||||||
CertFindCertificateInStore(
|
CertFindCertificateInStore(
|
||||||
@ -549,7 +556,7 @@ fn get_signature_pubkey(file: &str) -> Result<Vec<u8>, GetSignaturePubkeyError>
|
|||||||
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||||
0,
|
0,
|
||||||
CERT_FIND_SUBJECT_CERT,
|
CERT_FIND_SUBJECT_CERT,
|
||||||
cert_search_params as *const _,
|
&cert_search_params as *const _ as _,
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user