get UI updates working

This commit is contained in:
Michael Mikovsky
2025-06-08 19:17:23 -06:00
parent e2764edfae
commit 6ac1b5214e
7 changed files with 46 additions and 151 deletions
+2 -92
View File
@@ -1,10 +1,7 @@
use std::{ use std::{
error::Error, error::Error,
mem,
net::SocketAddr, net::SocketAddr,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
thread,
time::Duration,
}; };
use crossbeam_channel::{Receiver, Sender}; use crossbeam_channel::{Receiver, Sender};
@@ -14,9 +11,10 @@ use unshell_rs_lib::{
}; };
pub struct UnshellClient { pub struct UnshellClient {
#[allow(dead_code)]
addr: SocketAddr, addr: SocketAddr,
tx: Sender<C2Packet>, tx: Sender<C2Packet>,
rx: Receiver<C2Packet>, pub rx: Receiver<C2Packet>,
parameters: Arc<Mutex<Parameters>>, parameters: Arc<Mutex<Parameters>>,
} }
@@ -26,97 +24,13 @@ impl UnshellClient {
let (tx, rx) = TCPConnection::as_async(client); let (tx, rx) = TCPConnection::as_async(client);
// mpsc
// let poll = Poll::new()?;
// let events = Events::with_capacity(128);
// const SERVER: Token = Token(0);
// poll.registry()
// .register(&mut listener, SERVER, Interest::READABLE)?;
// let client = Arc::new(Mutex::new());
// let outgoing_packets = Arc::new(Mutex::new(Vec::<GuiPacket>::new()));
let parameters = Arc::new(Mutex::new(Parameters::new())); let parameters = Arc::new(Mutex::new(Parameters::new()));
// let tx_client = Arc::clone(&client);
// let tx_packets = Arc::clone(&outgoing_packets);
// // Recieve thread
// thread::spawn(move || {
// loop {
// info!("Lock 2");
// let mut packets_lock = tx_packets.lock().unwrap();
// info!("Lock 2");
// if !packets_lock.is_empty() {
// info!("Lock 3");
// if let Ok(packet) = packets_lock.pop().unwrap().encode() {
// info!("Lock 3");
// info!("Lock 4");
// let mut client_lock = tx_client.lock().unwrap();
// info!("Lock 4");
// info!("Wrote {}", packet.as_str());
// match client_lock.write(packet.as_str()) {
// Err(e) => {
// error!("Failed to send packet: {:?}", e);
// }
// _ => {}
// };
// }
// }
// std::mem::drop(packets_lock);
// thread::sleep(Duration::from_millis(10));
// }
// });
// let rx_client = Arc::clone(&client);
// let rx_params = Arc::clone(&parameters);
// thread::spawn(move || {
// loop {
// info!("Lock 5");
// let mut client = rx_client.lock().unwrap();
// info!("Lock 5");
// if !client.is_alive() {
// error!("Disconnected from {}!", client.get_info());
// }
// if let Ok(data) = client.read() {
// info!("Got {}", data);
// if let Ok(packet) = GuiPacket::decode(data.as_str()) {
// match packet {
// GuiPacket::ParameterUpate(name, parameter) => {
// rx_params.lock().unwrap().insert(name, parameter);
// }
// GuiPacket::Error(error_packet) => {
// error!("Got error: {}", print_type_of(&error_packet))
// }
// GuiPacket::SetAllParameters(parameters) => {
// let mut params_lock = rx_params.lock().unwrap();
// params_lock.clear();
// params_lock.extend(parameters);
// }
// _ => {
// error!("Unsupported packet: {}", data)
// }
// }
// }
// }
// // std::mem::drop(client);
// thread::sleep(Duration::from_millis(10));
// }
// });
Ok(Self { Ok(Self {
addr, addr,
tx, tx,
rx, rx,
// client,
parameters, parameters,
// outgoing_packets,
}) })
} }
@@ -130,7 +44,3 @@ impl UnshellClient {
self.parameters.lock().unwrap().get(key).cloned() self.parameters.lock().unwrap().get(key).cloned()
} }
} }
fn print_type_of<T>(_: &T) -> &'static str {
std::any::type_name::<T>()
}
+38 -33
View File
@@ -1,22 +1,20 @@
use slint::{ComponentHandle, ModelRc, VecModel}; use slint::{ComponentHandle, Weak};
use std::{ use std::{
error::Error, error::Error,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
thread,
}; };
use unshell_rs_lib::{config::campaign::CampaignConfig, connection::Parameter}; use unshell_rs_lib::connection::{C2Packet, Parameter};
use crate::client::UnshellClient; use crate::client::UnshellClient;
pub struct UnshellGui { pub struct UnshellGui {}
client: UnshellClient,
ui: AppWindow,
campaign: Option<Arc<Mutex<CampaignConfig>>>,
}
slint::include_modules!(); slint::include_modules!();
impl UnshellGui { impl UnshellGui {
pub fn start(client: UnshellClient) -> Result<(), Box<dyn Error>> { pub fn start(client: UnshellClient) -> Result<(), Box<dyn Error>> {
let ui = AppWindow::new()?; let ui = AppWindow::new()?;
let rx = client.rx.clone();
let client = Arc::new(Mutex::new(client)); let client = Arc::new(Mutex::new(client));
let ui_handle = ui.as_weak(); let ui_handle = ui.as_weak();
@@ -24,9 +22,7 @@ impl UnshellGui {
ui.on_tab_clicked(move |index| { ui.on_tab_clicked(move |index| {
let ui = ui_handle.unwrap(); let ui = ui_handle.unwrap();
ui.set_current_tab(index); ui.set_current_tab(index);
info!("Lock 1 ");
let mut client_lock = client_clone.lock().unwrap(); let mut client_lock = client_clone.lock().unwrap();
info!("Lock 1 ");
client_lock.set_parameter("Current Tab".to_string(), Parameter::CurrentTab(index)); client_lock.set_parameter("Current Tab".to_string(), Parameter::CurrentTab(index));
trace!("Tab {} selected", index); trace!("Tab {} selected", index);
}); });
@@ -40,32 +36,41 @@ impl UnshellGui {
.into() .into()
}); });
let ui_handle = ui.as_weak();
thread::spawn(move || {
fn on_param_update(ui_handle: Weak<AppWindow>, parameter: &Parameter) {
// info!("{}", name);
match parameter {
Parameter::Test1 => todo!(),
Parameter::CurrentTab(i) => {
let i = i.clone();
slint::invoke_from_event_loop(move || {
ui_handle.unwrap().set_current_tab(i)
})
.unwrap();
}
}
}
loop {
if let Ok(data) = rx.recv() {
match data {
C2Packet::SetAllParameters(parameters) => {
for key in parameters.keys() {
on_param_update(ui_handle.clone(), parameters.get(key).unwrap());
}
}
C2Packet::ParameterUpate(name, parameter) => {
on_param_update(ui_handle.clone(), &parameter);
}
_ => {}
}
}
}
});
ui.run()?; ui.run()?;
Ok(()) Ok(())
} }
fn update(&mut self) {
// self.ui.set_listeners(ModelRc::new(VecModel::from(
// self.campaign
// .listeners
// .iter()
// .map(|l| match l {
// ListenerConfig::Tcp {
// enabled,
// name,
// addr,
// layers,
// ..
// } => UITcpListener {
// enabled: *enabled,
// name: name.clone().into(),
// remote_host: addr.to_string().into(),
// },
// })
// .collect::<Vec<UITcpListener>>(),
// )));
}
} }
// trait
-2
View File
@@ -2,8 +2,6 @@ use lazy_static::lazy_static;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use unshell_rs_lib::config::campaign::CampaignConfig; use unshell_rs_lib::config::campaign::CampaignConfig;
use std::collections::HashMap;
use unshell_rs_lib::connection::Parameters; use unshell_rs_lib::connection::Parameters;
lazy_static! { lazy_static! {
+2 -12
View File
@@ -1,23 +1,19 @@
use std::{ use std::{
collections::HashMap,
error::Error, error::Error,
fs::File, fs::File,
io::Read, io::Read,
net::SocketAddr, net::SocketAddr,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
thread, thread,
time::Duration,
}; };
use crossbeam_channel::{Receiver, Sender}; use crossbeam_channel::Sender;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use unshell_rs_lib::{ use unshell_rs_lib::{
config::campaign::CampaignConfig, config::campaign::CampaignConfig,
connection::{C2Packet, ErrorPacket, Parameters}, connection::{C2Packet, ErrorPacket, Parameters},
networkers::{ networkers::{AsyncConnection, ServerTrait, TCPConnection, TCPServer, run_listener_state},
AsyncConnection, Connection, ServerTrait, TCPConnection, TCPServer, run_listener_state,
},
}; };
use crate::server::{DEFAULT_CAMPAIGN, DEFAULT_USERS, User, config::DEFAULT_PARAMETERS}; use crate::server::{DEFAULT_CAMPAIGN, DEFAULT_USERS, User, config::DEFAULT_PARAMETERS};
@@ -73,12 +69,6 @@ impl UnshellServer {
} }
}); });
// let (broadcast_tx, broadcast_rx) = crossbeam_channel::unbounded::<String>();
// let mut config_lock = s.config.lock().unwrap();
// config_lock.broadcast_tx = Some(broadcast_tx);
// config_lock.broadcast_rx = Some(broadcast_rx);
// std::mem::drop(config_lock);
s s
} }
+1 -4
View File
@@ -1,7 +1,4 @@
use std::{ use std::{collections::HashMap, fmt};
collections::HashMap,
fmt::{self, Display},
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Result; use serde_json::Result;
-2
View File
@@ -113,5 +113,3 @@ use serde::de::DeserializeOwned;
pub use tcp::TCPClient; pub use tcp::TCPClient;
pub use tcp::TCPConnection; pub use tcp::TCPConnection;
pub use tcp::TCPServer; pub use tcp::TCPServer;
use crate::connection;
+3 -6
View File
@@ -1,5 +1,4 @@
use std::{ use std::{
error::Error,
io::{self, BufRead, BufReader, Write}, io::{self, BufRead, BufReader, Write},
net::{SocketAddr, TcpListener, TcpStream}, net::{SocketAddr, TcpListener, TcpStream},
thread, thread,
@@ -62,13 +61,12 @@ impl AsyncConnection<TCPConnection> for TCPConnection {
let (send_tx, send_rx) = crossbeam_channel::unbounded::<T>(); let (send_tx, send_rx) = crossbeam_channel::unbounded::<T>();
let (recv_tx, recv_rx) = crossbeam_channel::unbounded::<T>(); let (recv_tx, recv_rx) = crossbeam_channel::unbounded::<T>();
let tx_clone = send_tx.clone();
thread::spawn(move || { thread::spawn(move || {
let mut reader = connection.reader; let mut reader = connection.reader;
let mut read = || -> Result<String, Self::Error> { let mut read = || -> Result<String, Self::Error> {
let mut line = String::new(); let mut line = String::new();
let n = reader.read_line(&mut line)?; let _ = reader.read_line(&mut line)?;
Ok(line.trim_end().to_string()) Ok(line.trim_end().to_string())
}; };
@@ -80,7 +78,7 @@ impl AsyncConnection<TCPConnection> for TCPConnection {
} }
info!("Got {}", data); info!("Got {}", data);
if let Ok(decoded) = serde_json::from_str::<T>(&data) { if let Ok(decoded) = serde_json::from_str::<T>(&data) {
if let Err(e) = tx_clone.send(decoded) { if let Err(e) = send_tx.send(decoded) {
error!("Got error: {}", e); error!("Got error: {}", e);
} }
} }
@@ -88,7 +86,6 @@ impl AsyncConnection<TCPConnection> for TCPConnection {
} }
}); });
let rx_clone = recv_rx.clone();
thread::spawn(move || { thread::spawn(move || {
let mut stream = connection.stream; let mut stream = connection.stream;
@@ -99,7 +96,7 @@ impl AsyncConnection<TCPConnection> for TCPConnection {
}; };
loop { loop {
if let Ok(data) = rx_clone.recv() { if let Ok(data) = recv_rx.recv() {
if let Ok(encoded) = serde_json::to_string(&data) { if let Ok(encoded) = serde_json::to_string(&data) {
info!("Write {}", encoded); info!("Write {}", encoded);
if let Err(e) = write(encoded) { if let Err(e) = write(encoded) {