Fix crashes when entering an empty or incorrect password

This commit is contained in:
Jakub Hlusička 2026-03-01 01:10:52 +01:00
parent 014b099986
commit 18d8443891

View file

@ -55,11 +55,18 @@ pub mod window_adapter;
slint::include_modules!();
#[derive(Clone, Copy)]
struct EmptyPassword;
fn spectre_derive_user_key(
username: &CStr,
password: &CStr,
encrypted_key: Option<Key>,
) -> SpectreUserKey {
) -> Result<SpectreUserKey, EmptyPassword> {
if password.is_empty() {
return Err(EmptyPassword);
}
if let Some(encrypted_key) = encrypted_key {
ACTIVE_ENCRYPTED_USER_KEY.lock(|user_key| {
user_key.set(encrypted_key);
@ -84,7 +91,7 @@ fn spectre_derive_user_key(
// TODO: Erase memory before freeing
__spre_free(user_key as *const _ as *mut _);
user_key_stack
Ok(user_key_stack)
}
}
@ -338,14 +345,16 @@ impl State {
fn process_callback_message(
state_rc: &Rc<RefCell<State>, PsramAllocator>,
message: CallbackMessage,
mut message: CallbackMessage,
) {
let view = state_rc.borrow().view;
match view {
while let Some(next_message) = match view {
AppState::Login => StateLogin::process_callback_message(state_rc, message),
AppState::Users => StateUsers::process_callback_message(state_rc, message),
AppState::UserEdit => StateUserEdit::process_callback_message(state_rc, message),
AppState::UserSites => StateUserSites::process_callback_message(state_rc, message),
} {
message = next_message
}
}
@ -392,7 +401,8 @@ trait AppViewTrait {
fn process_callback_message(
_state_rc: &Rc<RefCell<State>, PsramAllocator>,
_message: CallbackMessage,
) {
) -> Option<CallbackMessage> {
None
}
}
@ -403,7 +413,7 @@ impl AppViewTrait for StateLogin {
fn process_callback_message(
state_rc: &Rc<RefCell<State>, PsramAllocator>,
message: CallbackMessage,
) {
) -> Option<CallbackMessage> {
let mut state = state_rc.borrow_mut();
match message {
CallbackMessage::Login(CallbackMessageLogin::PwAccepted {
@ -413,14 +423,18 @@ impl AppViewTrait for StateLogin {
}) => {
let Some(user) = state.users.users.row_data(user_index as usize) else {
error!("Failed to find a user with index {user_index}.");
return;
return None;
};
let username_c = CString::new(&*user.username)
.expect("Username cannot be converted to a C string.");
let password_c =
CString::new(&*password).expect("Password cannot be converted to a C string.");
let user_key =
spectre_derive_user_key(&username_c, &password_c, Some(user.encrypted_key));
let Ok(user_key) =
spectre_derive_user_key(&username_c, &password_c, Some(user.encrypted_key))
else {
error!("Password empty.");
return None;
};
// {
// let mut write = db.write_transaction().await;
@ -459,14 +473,10 @@ impl AppViewTrait for StateLogin {
// }
if user.key_id != user_key.keyID.bytes {
State::process_callback_message(
state_rc,
CallbackMessage::Login(CallbackMessageLogin::LoginResult {
username: user.username,
result: LoginResult::Failure,
}),
);
return;
return Some(CallbackMessage::Login(CallbackMessageLogin::LoginResult {
username: user.username,
result: LoginResult::Failure,
}));
}
slint::spawn_local({
@ -549,6 +559,8 @@ impl AppViewTrait for StateLogin {
}
_ => (),
}
None
}
}
@ -559,7 +571,7 @@ impl AppViewTrait for StateUsers {
fn process_callback_message(
state_rc: &Rc<RefCell<State>, PsramAllocator>,
message: CallbackMessage,
) {
) -> Option<CallbackMessage> {
let mut state = state_rc.borrow_mut();
match message {
CallbackMessage::Escape => {
@ -577,6 +589,8 @@ impl AppViewTrait for StateUsers {
}
_ => (),
}
None
}
}
@ -592,7 +606,7 @@ impl AppViewTrait for StateUserEdit {
fn process_callback_message(
state_rc: &Rc<RefCell<State>, PsramAllocator>,
message: CallbackMessage,
) {
) -> Option<CallbackMessage> {
let state = state_rc.clone();
let mut state = state.borrow_mut();
match message {
@ -630,7 +644,7 @@ impl AppViewTrait for StateUserEdit {
}) => {
let Some(password) = state.state_user_edit.password.as_ref() else {
warn!("Attempted to compute a key ID when no password has been entered.");
return;
return None;
};
let mut key: Key = [0; _];
@ -654,14 +668,18 @@ impl AppViewTrait for StateUserEdit {
}
};
state.window.set_user_edit_key_error(message);
return;
return None;
}
let username_c = CString::new(&*state.state_user_edit.username)
.expect("Username cannot be converted to a C string.");
let password_c =
CString::new(&**password).expect("Password cannot be converted to a C string.");
let user_key = spectre_derive_user_key(&username_c, &password_c, Some(key));
let Ok(user_key) = spectre_derive_user_key(&username_c, &password_c, Some(key))
else {
error!("Password empty.");
return None;
};
state.window.set_user_edit_key_error(SharedString::new());
state.window.set_user_edit_key_id(
@ -683,7 +701,7 @@ impl AppViewTrait for StateUserEdit {
)) = state.state_user_edit.encrypted_key.take()
else {
warn!("Encrypted key is not set.");
return;
return None;
};
// If a user with that username already exists, overwrite it.
@ -730,6 +748,8 @@ impl AppViewTrait for StateUserEdit {
}
_ => (),
}
None
}
}
@ -745,7 +765,7 @@ impl AppViewTrait for StateUserSites {
fn process_callback_message(
state_rc: &Rc<RefCell<State>, PsramAllocator>,
message: CallbackMessage,
) {
) -> Option<CallbackMessage> {
let state = state_rc.clone();
let mut state = state.borrow_mut();
match message {
@ -763,12 +783,12 @@ impl AppViewTrait for StateUserSites {
}) => {
let Some(user_sites) = state.state_user_sites.as_mut() else {
error!("User sites uninitialized.");
return;
return None;
};
let Some(site_list_entry) = user_sites.site_list.row_data(site_list_index as usize)
else {
error!("Invalid site list entry index: {site_list_index}");
return;
return None;
};
warn!("Site name accepted: {site_list_entry:?}");
let site_name = match site_list_entry {
@ -809,6 +829,8 @@ impl AppViewTrait for StateUserSites {
}
_ => (),
}
None
}
}