Increase dialog exit status parsing safety in the locker
This also stops using -1 as auth failed, and moves all failure statuses to positive numbers. It looks like Exiting with -1 ends up setting the status to 255 on exit, but then in the locker, it sees this as 255 and not -1, since things get coerced into 32-bit integers.
This commit is contained in:
68
util/src/dialog.rs
Normal file
68
util/src/dialog.rs
Normal file
@ -0,0 +1,68 @@
|
||||
use std::{error, fmt, process::ExitStatus, os::unix::prelude::ExitStatusExt};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DialogExitStatusError {
|
||||
NoStatus,
|
||||
Crashed(i32),
|
||||
InvalidStatus(i32),
|
||||
}
|
||||
|
||||
impl fmt::Display for DialogExitStatusError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use DialogExitStatusError::*;
|
||||
match self {
|
||||
InvalidStatus(other) => write!(f, "Unlock dialog exited with unexpected status {}", other),
|
||||
Crashed(signum) => write!(f, "Unlock dialog crashed with signal {}", signum),
|
||||
NoStatus => write!(f, "Unlock dialog exited unexpectedly"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for DialogExitStatusError {}
|
||||
|
||||
#[repr(i32)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum DialogExitStatus {
|
||||
AuthSucceeded = 0,
|
||||
AuthFailed = 1,
|
||||
AuthCanceled = 2,
|
||||
AuthTimedOut = 3,
|
||||
OtherError = 4,
|
||||
}
|
||||
|
||||
impl DialogExitStatus {
|
||||
pub fn exit(&self) -> ! {
|
||||
std::process::exit(*self as i32);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DialogExitStatus {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use DialogExitStatus::*;
|
||||
match self {
|
||||
AuthSucceeded => write!(f, "Authentication succeeded"),
|
||||
AuthFailed => write!(f, "Authentication failed"),
|
||||
AuthCanceled => write!(f, "Authentication canceled"),
|
||||
AuthTimedOut => write!(f, "Authentication timed out"),
|
||||
OtherError => write!(f, "An unexpected error occurred with the unlock dialog"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<ExitStatus> for DialogExitStatus {
|
||||
type Error = DialogExitStatusError;
|
||||
fn try_from(value: ExitStatus) -> Result<Self, Self::Error> {
|
||||
match value.code() {
|
||||
Some(0) => Ok(DialogExitStatus::AuthSucceeded),
|
||||
Some(1) => Ok(DialogExitStatus::AuthFailed),
|
||||
Some(2) => Ok(DialogExitStatus::AuthCanceled),
|
||||
Some(3) => Ok(DialogExitStatus::AuthTimedOut),
|
||||
Some(4) => Ok(DialogExitStatus::OtherError),
|
||||
Some(other) => Err(DialogExitStatusError::InvalidStatus(other)),
|
||||
None => match value.signal() {
|
||||
Some(signum) => Err(DialogExitStatusError::Crashed(signum)),
|
||||
None => Err(DialogExitStatusError::NoStatus),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
@ -2,26 +2,11 @@ use std::{ffi::CStr, io};
|
||||
use xcb::x;
|
||||
|
||||
pub mod desktop;
|
||||
pub mod dialog;
|
||||
pub mod settings;
|
||||
|
||||
pub const BSCREENSAVER_WM_CLASS: &[u8] = b"bscreensaver\0Bscreensaver\0";
|
||||
|
||||
#[repr(i32)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum DialogExitStatus {
|
||||
AuthFailed = -1,
|
||||
AuthSucceeded = 0,
|
||||
AuthCanceled = 1,
|
||||
AuthTimedOut = 2,
|
||||
OtherError = 3,
|
||||
}
|
||||
|
||||
impl DialogExitStatus {
|
||||
pub fn exit(&self) -> ! {
|
||||
std::process::exit(*self as i32);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_logging(env_name: &str) {
|
||||
env_logger::builder()
|
||||
.format_timestamp_millis()
|
||||
|
Reference in New Issue
Block a user