mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2025-01-03 12:39:35 +00:00
main: add [zeroize] and implement sudo input/test screen for xmrig
This commit is contained in:
parent
31f23d9d58
commit
f988e4224c
9 changed files with 169 additions and 9 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -37,6 +37,7 @@ dependencies = [
|
||||||
"tor-rtcompat",
|
"tor-rtcompat",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"winres",
|
"winres",
|
||||||
|
"zeroize",
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ tokio = { version = "1.21.2", features = ["rt", "time", "macros", "process"] }
|
||||||
toml = { version = "0.5.9", features = ["preserve_order"] }
|
toml = { version = "0.5.9", features = ["preserve_order"] }
|
||||||
tor-rtcompat = "0.7.0"
|
tor-rtcompat = "0.7.0"
|
||||||
walkdir = "2.3.2"
|
walkdir = "2.3.2"
|
||||||
|
zeroize = "1.5.7"
|
||||||
|
|
||||||
# Unix dependencies
|
# Unix dependencies
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
|
BIN
images/ferris/cute.png
Normal file
BIN
images/ferris/cute.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
BIN
images/ferris/gesture.png
Normal file
BIN
images/ferris/gesture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
BIN
images/ferris/sudo.png
Normal file
BIN
images/ferris/sudo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 214 KiB |
|
@ -67,6 +67,7 @@ pub const SPACE: f32 = 10.0;
|
||||||
pub const RED: egui::Color32 = egui::Color32::from_rgb(230, 50, 50);
|
pub const RED: egui::Color32 = egui::Color32::from_rgb(230, 50, 50);
|
||||||
pub const GREEN: egui::Color32 = egui::Color32::from_rgb(100, 230, 100);
|
pub const GREEN: egui::Color32 = egui::Color32::from_rgb(100, 230, 100);
|
||||||
pub const YELLOW: egui::Color32 = egui::Color32::from_rgb(230, 230, 100);
|
pub const YELLOW: egui::Color32 = egui::Color32::from_rgb(230, 230, 100);
|
||||||
|
pub const BRIGHT_YELLOW: egui::Color32 = egui::Color32::from_rgb(250, 250, 100);
|
||||||
pub const GRAY: egui::Color32 = egui::Color32::GRAY;
|
pub const GRAY: egui::Color32 = egui::Color32::GRAY;
|
||||||
pub const LIGHT_GRAY: egui::Color32 = egui::Color32::LIGHT_GRAY;
|
pub const LIGHT_GRAY: egui::Color32 = egui::Color32::LIGHT_GRAY;
|
||||||
pub const BLACK: egui::Color32 = egui::Color32::BLACK;
|
pub const BLACK: egui::Color32 = egui::Color32::BLACK;
|
||||||
|
@ -78,6 +79,16 @@ pub const ZERO_SECONDS: std::time::Duration = std::time::Duration::from_secs(0);
|
||||||
pub const MILLI_900: std::time::Duration = std::time::Duration::from_millis(900);
|
pub const MILLI_900: std::time::Duration = std::time::Duration::from_millis(900);
|
||||||
pub const TOKIO_SECOND: tokio::time::Duration = std::time::Duration::from_secs(1);
|
pub const TOKIO_SECOND: tokio::time::Duration = std::time::Duration::from_secs(1);
|
||||||
|
|
||||||
|
// The explaination given to the user on why XMRig needs sudo.
|
||||||
|
pub const XMRIG_ADMIN_REASON: &str =
|
||||||
|
r#"The large hashrate difference between XMRig and other miners like Monero and P2Pool's built-in miners is mostly due to XMRig configuring CPU MSRs and setting up hugepages. Other miners like Monero or P2Pool's built-in miner do not do this. It can be done manually but it isn't recommended since XMRig does this for you automatically, but only if it has the proper admin priviledges."#;
|
||||||
|
// Password buttons
|
||||||
|
pub const PASSWORD_TEXT: &str = "Enter sudo/admin password here...";
|
||||||
|
pub const PASSWORD_LEAVE: &str = "Return to the previous screen";
|
||||||
|
pub const PASSWORD_ENTER: &str = "Attempt with the current password";
|
||||||
|
pub const PASSWORD_HIDE: &str = "Toggle hiding/showing the password";
|
||||||
|
|
||||||
|
|
||||||
// OS specific
|
// OS specific
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub const OS: &'static str = " Windows";
|
pub const OS: &'static str = " Windows";
|
||||||
|
|
|
@ -21,6 +21,7 @@ pub const FERRIS_HAPPY: &[u8] = include_bytes!("../images/ferris/happy.png");
|
||||||
pub const FERRIS_OOPS: &[u8] = include_bytes!("../images/ferris/oops.png");
|
pub const FERRIS_OOPS: &[u8] = include_bytes!("../images/ferris/oops.png");
|
||||||
pub const FERRIS_ERROR: &[u8] = include_bytes!("../images/ferris/error.png");
|
pub const FERRIS_ERROR: &[u8] = include_bytes!("../images/ferris/error.png");
|
||||||
pub const FERRIS_PANIC: &[u8] = include_bytes!("../images/ferris/panic.png"); // This isnt technically ferris but its ok since its spooky
|
pub const FERRIS_PANIC: &[u8] = include_bytes!("../images/ferris/panic.png"); // This isnt technically ferris but its ok since its spooky
|
||||||
|
pub const FERRIS_SUDO: &[u8] = include_bytes!("../images/ferris/sudo.png");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
89
src/main.rs
89
src/main.rs
|
@ -24,11 +24,12 @@ use egui::{
|
||||||
TextStyle::*,
|
TextStyle::*,
|
||||||
color::Color32,
|
color::Color32,
|
||||||
FontFamily::Proportional,
|
FontFamily::Proportional,
|
||||||
TextStyle,
|
TextStyle,Spinner,
|
||||||
Layout,Align,
|
Layout,Align,
|
||||||
FontId,Label,RichText,Stroke,Vec2,Button,SelectableLabel,
|
FontId,Label,RichText,Stroke,Vec2,Button,SelectableLabel,
|
||||||
Key,Modifiers,
|
Key,Modifiers,TextEdit,
|
||||||
CentralPanel,TopBottomPanel,
|
CentralPanel,TopBottomPanel,
|
||||||
|
Hyperlink,
|
||||||
};
|
};
|
||||||
use egui_extras::RetainedImage;
|
use egui_extras::RetainedImage;
|
||||||
use eframe::{egui,NativeOptions};
|
use eframe::{egui,NativeOptions};
|
||||||
|
@ -61,6 +62,12 @@ mod update;
|
||||||
mod helper;
|
mod helper;
|
||||||
use {ferris::*,constants::*,node::*,disk::*,status::*,update::*,gupax::*,helper::*};
|
use {ferris::*,constants::*,node::*,disk::*,status::*,update::*,gupax::*,helper::*};
|
||||||
|
|
||||||
|
// Sudo (unix only)
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
mod sudo;
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
use sudo::*;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Struct + Impl
|
//---------------------------------------------------------------------------------------------------- Struct + Impl
|
||||||
// The state of the outer main [App].
|
// The state of the outer main [App].
|
||||||
// See the [State] struct in [state.rs] for the
|
// See the [State] struct in [state.rs] for the
|
||||||
|
@ -113,6 +120,9 @@ pub struct App {
|
||||||
xmrig_img: Arc<Mutex<ImgXmrig>>, // A one-time snapshot of what data XMRig started with
|
xmrig_img: Arc<Mutex<ImgXmrig>>, // A one-time snapshot of what data XMRig started with
|
||||||
// Buffer State
|
// Buffer State
|
||||||
p2pool_console: String, // The buffer between the p2pool console and the [Helper]
|
p2pool_console: String, // The buffer between the p2pool console and the [Helper]
|
||||||
|
// Sudo State
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
sudo: Arc<Mutex<SudoState>>,
|
||||||
// State from [--flags]
|
// State from [--flags]
|
||||||
no_startup: bool,
|
no_startup: bool,
|
||||||
// Static stuff
|
// Static stuff
|
||||||
|
@ -174,6 +184,8 @@ impl App {
|
||||||
p2pool_img,
|
p2pool_img,
|
||||||
xmrig_img,
|
xmrig_img,
|
||||||
p2pool_console: String::with_capacity(10),
|
p2pool_console: String::with_capacity(10),
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
sudo: Arc::new(Mutex::new(SudoState::new())),
|
||||||
resizing: false,
|
resizing: false,
|
||||||
alpha: 0,
|
alpha: 0,
|
||||||
no_startup: false,
|
no_startup: false,
|
||||||
|
@ -366,6 +378,7 @@ pub enum ErrorButtons {
|
||||||
ResetNode,
|
ResetNode,
|
||||||
Okay,
|
Okay,
|
||||||
Quit,
|
Quit,
|
||||||
|
Sudo,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
@ -374,6 +387,7 @@ pub enum ErrorFerris {
|
||||||
Oops,
|
Oops,
|
||||||
Error,
|
Error,
|
||||||
Panic,
|
Panic,
|
||||||
|
Sudo,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ErrorState {
|
pub struct ErrorState {
|
||||||
|
@ -412,6 +426,23 @@ impl ErrorState {
|
||||||
buttons,
|
buttons,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Just sets the current state to new, resetting it.
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
*self = Self::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instead of creating a whole new screen and system, this (ab)uses ErrorState
|
||||||
|
// to ask for the [sudo] when starting XMRig. Yes, yes I know, it's called "ErrorState"
|
||||||
|
// but rewriting the UI code and button stuff might be worse.
|
||||||
|
pub fn ask_sudo(&mut self) {
|
||||||
|
*self = Self {
|
||||||
|
error: true,
|
||||||
|
msg: String::new(),
|
||||||
|
ferris: ErrorFerris::Sudo,
|
||||||
|
buttons: ErrorButtons::Sudo,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- [Images] struct
|
//---------------------------------------------------------------------------------------------------- [Images] struct
|
||||||
|
@ -421,6 +452,7 @@ struct Images {
|
||||||
oops: RetainedImage,
|
oops: RetainedImage,
|
||||||
error: RetainedImage,
|
error: RetainedImage,
|
||||||
panic: RetainedImage,
|
panic: RetainedImage,
|
||||||
|
sudo: RetainedImage,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Images {
|
impl Images {
|
||||||
|
@ -431,6 +463,7 @@ impl Images {
|
||||||
oops: RetainedImage::from_image_bytes("oops.png", FERRIS_OOPS).unwrap(),
|
oops: RetainedImage::from_image_bytes("oops.png", FERRIS_OOPS).unwrap(),
|
||||||
error: RetainedImage::from_image_bytes("error.png", FERRIS_ERROR).unwrap(),
|
error: RetainedImage::from_image_bytes("error.png", FERRIS_ERROR).unwrap(),
|
||||||
panic: RetainedImage::from_image_bytes("panic.png", FERRIS_PANIC).unwrap(),
|
panic: RetainedImage::from_image_bytes("panic.png", FERRIS_PANIC).unwrap(),
|
||||||
|
sudo: RetainedImage::from_image_bytes("panic.png", FERRIS_SUDO).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -804,6 +837,7 @@ impl eframe::App for App {
|
||||||
Oops => &self.img.oops,
|
Oops => &self.img.oops,
|
||||||
Error => &self.img.error,
|
Error => &self.img.error,
|
||||||
Panic => &self.img.panic,
|
Panic => &self.img.panic,
|
||||||
|
ErrorFerris::Sudo => &self.img.sudo,
|
||||||
};
|
};
|
||||||
ferris.show_max_size(ui, Vec2::new(width, height));
|
ferris.show_max_size(ui, Vec2::new(width, height));
|
||||||
|
|
||||||
|
@ -825,6 +859,14 @@ impl eframe::App for App {
|
||||||
ui.add_sized([width, height], Label::new(format!("--- Gupax has encountered an error! ---\n{}", &self.error_state.msg)));
|
ui.add_sized([width, height], Label::new(format!("--- Gupax has encountered an error! ---\n{}", &self.error_state.msg)));
|
||||||
ui.add_sized([width, height], Label::new("Reset the manual node list?"))
|
ui.add_sized([width, height], Label::new("Reset the manual node list?"))
|
||||||
},
|
},
|
||||||
|
ErrorButtons::Sudo => {
|
||||||
|
let text = format!("Why does XMRig need admin priviledge?\n{}", XMRIG_ADMIN_REASON);
|
||||||
|
let height = height/4.0;
|
||||||
|
ui.add_sized([width, height], Label::new(format!("--- Gupax needs sudo/admin priviledge for XMRig! ---\n{}", &self.error_state.msg)));
|
||||||
|
ui.style_mut().override_text_style = Some(Name("MonospaceSmall".into()));
|
||||||
|
ui.add_sized([width/2.0, height], Label::new(text));
|
||||||
|
ui.add_sized([width, height], Hyperlink::from_label_and_url("Click here for more info.", "https://xmrig.com/docs/miner/randomx-optimization-guide"))
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
match self.error_state.ferris {
|
match self.error_state.ferris {
|
||||||
Panic => ui.add_sized([width, height], Label::new("--- Gupax has encountered an un-recoverable error! ---")),
|
Panic => ui.add_sized([width, height], Label::new("--- Gupax has encountered an un-recoverable error! ---")),
|
||||||
|
@ -841,7 +883,7 @@ impl eframe::App for App {
|
||||||
|
|
||||||
match self.error_state.buttons {
|
match self.error_state.buttons {
|
||||||
YesNo => {
|
YesNo => {
|
||||||
if ui.add_sized([width, height/2.0], Button::new("Yes")).clicked() { self.error_state = ErrorState::new(); }
|
if ui.add_sized([width, height/2.0], Button::new("Yes")).clicked() { self.error_state.reset() }
|
||||||
// If [Esc] was pressed, assume [No]
|
// If [Esc] was pressed, assume [No]
|
||||||
if esc || ui.add_sized([width, height/2.0], Button::new("No")).clicked() { exit(0); }
|
if esc || ui.add_sized([width, height/2.0], Button::new("No")).clicked() { exit(0); }
|
||||||
},
|
},
|
||||||
|
@ -871,7 +913,7 @@ impl eframe::App for App {
|
||||||
Err(e) => self.error_state.set(format!("State reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Err(e) => self.error_state.set(format!("State reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if esc || ui.add_sized([width, height/2.0], Button::new("No")).clicked() { self.error_state = ErrorState::new() }
|
if esc || ui.add_sized([width, height/2.0], Button::new("No")).clicked() { self.error_state.reset() }
|
||||||
},
|
},
|
||||||
ResetNode => {
|
ResetNode => {
|
||||||
if ui.add_sized([width, height/2.0], Button::new("Yes")).clicked() {
|
if ui.add_sized([width, height/2.0], Button::new("Yes")).clicked() {
|
||||||
|
@ -889,9 +931,38 @@ impl eframe::App for App {
|
||||||
Err(e) => self.error_state.set(format!("Node reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Err(e) => self.error_state.set(format!("Node reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if esc || ui.add_sized([width, height/2.0], Button::new("No")).clicked() { self.error_state = ErrorState::new() }
|
if esc || ui.add_sized([width, height/2.0], Button::new("No")).clicked() { self.error_state.reset() }
|
||||||
},
|
},
|
||||||
Okay => if esc || ui.add_sized([width, height], Button::new("Okay")).clicked() { self.error_state = ErrorState::new(); },
|
ErrorButtons::Sudo => {
|
||||||
|
let sudo_width = (width/10.0);
|
||||||
|
let height = ui.available_height()/4.0;
|
||||||
|
let mut sudo = self.sudo.lock().unwrap();
|
||||||
|
let hide = sudo.hide.clone();
|
||||||
|
ui.style_mut().override_text_style = Some(Monospace);
|
||||||
|
if sudo.testing {
|
||||||
|
ui.add_sized([width, height], Spinner::new().size(height));
|
||||||
|
ui.set_enabled(false);
|
||||||
|
} else {
|
||||||
|
ui.add_sized([width, height], Label::new(&sudo.msg));
|
||||||
|
}
|
||||||
|
ui.add_space(height);
|
||||||
|
let height = ui.available_height()/5.0;
|
||||||
|
// Password input box with a hider.
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
let response = ui.add_sized([sudo_width*8.0, height], TextEdit::hint_text(TextEdit::singleline(&mut sudo.pass).password(hide), PASSWORD_TEXT));
|
||||||
|
let box_width = (ui.available_width()/2.0)-5.0;
|
||||||
|
if (response.lost_focus() && ui.input().key_pressed(Key::Enter)) ||
|
||||||
|
ui.add_sized([box_width, height], Button::new("Enter")).on_hover_text(PASSWORD_ENTER).clicked() {
|
||||||
|
if !sudo.testing {
|
||||||
|
SudoState::test_sudo(Arc::clone(&self.sudo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let color = if hide { BLACK } else { BRIGHT_YELLOW };
|
||||||
|
if ui.add_sized([box_width, height], Button::new(RichText::new("👁").color(color))).on_hover_text(PASSWORD_HIDE).clicked() { sudo.hide = !sudo.hide; }
|
||||||
|
});
|
||||||
|
if esc || ui.add_sized([width, height*4.0], Button::new("Leave")).clicked() { self.error_state.reset(); };
|
||||||
|
},
|
||||||
|
Okay => if esc || ui.add_sized([width, height], Button::new("Okay")).clicked() { self.error_state.reset(); },
|
||||||
Quit => if ui.add_sized([width, height], Button::new("Quit")).clicked() { exit(1); },
|
Quit => if ui.add_sized([width, height], Button::new("Quit")).clicked() { exit(1); },
|
||||||
}
|
}
|
||||||
})});
|
})});
|
||||||
|
@ -1079,10 +1150,10 @@ impl eframe::App for App {
|
||||||
let width = (ui.available_width()/3.0)-5.0;
|
let width = (ui.available_width()/3.0)-5.0;
|
||||||
if self.xmrig.lock().unwrap().is_alive() {
|
if self.xmrig.lock().unwrap().is_alive() {
|
||||||
if ui.add_sized([width, height], Button::new("⟲")).on_hover_text("Restart XMRig").clicked() {
|
if ui.add_sized([width, height], Button::new("⟲")).on_hover_text("Restart XMRig").clicked() {
|
||||||
self.xmrig.lock().unwrap().state = ProcessState::Middle;
|
self.error_state.ask_sudo();
|
||||||
}
|
}
|
||||||
if ui.add_sized([width, height], Button::new("⏹")).on_hover_text("Stop XMRig").clicked() {
|
if ui.add_sized([width, height], Button::new("⏹")).on_hover_text("Stop XMRig").clicked() {
|
||||||
self.xmrig.lock().unwrap().state = ProcessState::Dead;
|
self.error_state.ask_sudo();
|
||||||
}
|
}
|
||||||
ui.add_enabled_ui(false, |ui| {
|
ui.add_enabled_ui(false, |ui| {
|
||||||
ui.add_sized([width, height], Button::new("⏺")).on_hover_text("Start XMRig");
|
ui.add_sized([width, height], Button::new("⏺")).on_hover_text("Start XMRig");
|
||||||
|
@ -1093,7 +1164,7 @@ impl eframe::App for App {
|
||||||
ui.add_sized([width, height], Button::new("⏹")).on_hover_text("Stop XMRig");
|
ui.add_sized([width, height], Button::new("⏹")).on_hover_text("Stop XMRig");
|
||||||
});
|
});
|
||||||
if ui.add_sized([width, height], Button::new("⏺")).on_hover_text("Start XMRig").clicked() {
|
if ui.add_sized([width, height], Button::new("⏺")).on_hover_text("Start XMRig").clicked() {
|
||||||
// Helper::spawn_xmrig(&self.helper, &self.state.xmrig, self.state.gupax.absolute_xmrig_path.clone());
|
self.error_state.ask_sudo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
75
src/sudo.rs
Normal file
75
src/sudo.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// Gupax - GUI Uniting P2Pool And XMRig
|
||||||
|
//
|
||||||
|
// Copyright (c) 2022 hinto-janaiyo
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Handling of [sudo] for XMRig.
|
||||||
|
// [zeroize] is used to wipe the memory after use.
|
||||||
|
// Only gets imported in [main.rs] for Unix.
|
||||||
|
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
use std::sync::{Arc,Mutex};
|
||||||
|
use std::thread;
|
||||||
|
use log::*;
|
||||||
|
|
||||||
|
#[derive(Debug,Clone)]
|
||||||
|
pub struct SudoState {
|
||||||
|
pub testing: bool, // Are we attempting a sudo test right now?
|
||||||
|
pub success: bool, // Was the sudo test a success?
|
||||||
|
pub hide: bool, // Are we hiding the password?
|
||||||
|
pub msg: String, // The message shown to the user if unsuccessful
|
||||||
|
pub pass: String, // The actual password wrapped in a [SecretVec]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SudoState {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
testing: false,
|
||||||
|
success: false,
|
||||||
|
hide: true,
|
||||||
|
msg: "".to_string(),
|
||||||
|
pass: String::with_capacity(256),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swaps the pass with another 256-capacity String,
|
||||||
|
// zeroizes the old and drops it.
|
||||||
|
pub fn wipe(state: &Arc<Mutex<Self>>) {
|
||||||
|
info!("Sudo | Wiping password with zeros and dropping from memory...");
|
||||||
|
let mut new = String::with_capacity(256);
|
||||||
|
let mut state = state.lock().unwrap();
|
||||||
|
// new is now == old, and vice-versa.
|
||||||
|
std::mem::swap(&mut new, &mut state.pass);
|
||||||
|
// we're wiping & dropping the old pass here.
|
||||||
|
new.zeroize();
|
||||||
|
std::mem::drop(new);
|
||||||
|
info!("Sudo ... Password Wipe OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test_sudo(state: Arc<Mutex<Self>>) {
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
state.lock().unwrap().testing = true;
|
||||||
|
info!("in test_sudo()");
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(3));
|
||||||
|
state.lock().unwrap().testing = false;
|
||||||
|
if state.lock().unwrap().pass == "secret" {
|
||||||
|
state.lock().unwrap().msg = "Correct!".to_string();
|
||||||
|
} else {
|
||||||
|
state.lock().unwrap().msg = "Incorrect password!".to_string();
|
||||||
|
}
|
||||||
|
Self::wipe(&state);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue