diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 02138d3..9090ca9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,10 +10,7 @@ on: env: CARGO_TERM_COLOR: always FILE_ROOTSHELL: ../../rootshell/rootshell - FILE_RAYHUNTER_DAEMON_ORBIC: ../../rayhunter-daemon-orbic/rayhunter-daemon - FILE_RAYHUNTER_DAEMON_TPLINK: ../../rayhunter-daemon-tplink/rayhunter-daemon - FILE_RAYHUNTER_DAEMON_TMOBILE: ../../rayhunter-daemon-tmobile/rayhunter-daemon - FILE_RAYHUNTER_DAEMON_WINGTECH: ../../rayhunter-daemon-wingtech/rayhunter-daemon + FILE_RAYHUNTER_DAEMON: ../../rayhunter-daemon/rayhunter-daemon RUSTFLAGS: "-Dwarnings" jobs: @@ -102,13 +99,6 @@ jobs: check_and_test: needs: files_changed if: needs.files_changed.outputs.code_changed != '0' - strategy: - matrix: - device: - - name: orbic - - name: tplink - - name: wingtech - - name: tmobile runs-on: ubuntu-latest permissions: contents: read @@ -123,13 +113,13 @@ jobs: npm install npm run build popd - NO_FIRMWARE_BIN=true cargo check --verbose --no-default-features --features=${{ matrix.device.name }} + NO_FIRMWARE_BIN=true cargo check --verbose - name: Run tests run: | - NO_FIRMWARE_BIN=true cargo test --verbose --no-default-features --features=${{ matrix.device.name }} + NO_FIRMWARE_BIN=true cargo test --verbose - name: Run clippy run: | - NO_FIRMWARE_BIN=true cargo clippy --verbose --no-default-features --features=${{ matrix.device.name }} + NO_FIRMWARE_BIN=true cargo clippy --verbose test_web_frontend: needs: files_changed @@ -241,13 +231,6 @@ jobs: permissions: contents: read packages: write - strategy: - matrix: - device: - - name: orbic - - name: tplink - - name: wingtech - - name: tmobile runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -269,10 +252,10 @@ jobs: # what the feature selection in rayhunter-daemon is. # # https://github.com/rust-lang/cargo/issues/4463 - cargo build -p rayhunter-daemon --bin rayhunter-daemon --target armv7-unknown-linux-musleabihf --profile=firmware --no-default-features --features ${{ matrix.device.name }} + cargo build -p rayhunter-daemon --bin rayhunter-daemon --target armv7-unknown-linux-musleabihf --profile=firmware - uses: actions/upload-artifact@v4 with: - name: rayhunter-daemon-${{ matrix.device.name }} + name: rayhunter-daemon path: target/armv7-unknown-linux-musleabihf/firmware/rayhunter-daemon if-no-files-found: error diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index 3eec793..eb1d52a 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -3,15 +3,6 @@ name = "rayhunter-daemon" version = "0.4.0" edition = "2024" -[features] -# These feature flags are mutually exclusive, and exactly one must be enabled. -orbic = ["rayhunter/orbic"] -tmobile = ["rayhunter/tmobile"] -tplink = ["rayhunter/tplink"] -wingtech = ["rayhunter/wingtech"] - -default = ["orbic"] - [dependencies] rayhunter = { path = "../lib" } toml = "0.8.8" diff --git a/daemon/src/config.rs b/daemon/src/config.rs index 8818e7c..e53d467 100644 --- a/daemon/src/config.rs +++ b/daemon/src/config.rs @@ -1,3 +1,4 @@ +use log::warn; use serde::{Deserialize, Serialize}; use rayhunter::analysis::analyzer::AnalyzerConfig; @@ -10,18 +11,29 @@ pub struct Config { pub qmdl_store_path: String, pub port: u16, pub debug_mode: bool, + pub display: Display, pub ui_level: u8, pub colorblind_mode: bool, pub key_input_mode: u8, pub analyzers: AnalyzerConfig, } +#[derive(PartialEq, Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "lowercase")] +pub enum Display { + Orbic, + Tplink, + Tmobile, + Wingtech, +} + impl Default for Config { fn default() -> Self { Config { qmdl_store_path: "/data/rayhunter/qmdl".to_string(), port: 8080, debug_mode: false, + display: Display::Orbic, ui_level: 1, colorblind_mode: false, key_input_mode: 0, @@ -37,6 +49,7 @@ where if let Ok(config_file) = tokio::fs::read_to_string(&path).await { Ok(toml::from_str(&config_file).map_err(RayhunterError::ConfigFileParsingError)?) } else { + warn!("unable to read config file, using default config"); Ok(Config::default()) } } diff --git a/daemon/src/display/mod.rs b/daemon/src/display/mod.rs index 1b2fd48..911328a 100644 --- a/daemon/src/display/mod.rs +++ b/daemon/src/display/mod.rs @@ -1,30 +1,11 @@ -#[cfg(any(feature = "orbic", feature = "tplink", feature = "wingtech"))] mod generic_framebuffer; -#[cfg(feature = "tmobile")] -mod tmobile; -#[cfg(feature = "tmobile")] -pub use tmobile::update_ui; - -#[cfg(feature = "tplink")] -mod tplink; -#[cfg(feature = "tplink")] -mod tplink_framebuffer; -#[cfg(feature = "tplink")] -mod tplink_onebit; - -#[cfg(feature = "tplink")] -pub use tplink::update_ui; - -#[cfg(feature = "orbic")] -mod orbic; -#[cfg(feature = "orbic")] -pub use orbic::update_ui; - -#[cfg(feature = "wingtech")] -mod wingtech; -#[cfg(feature = "wingtech")] -pub use wingtech::update_ui; +pub mod orbic; +pub mod tmobile; +pub mod tplink; +pub mod tplink_framebuffer; +pub mod tplink_onebit; +pub mod wingtech; #[derive(Clone, Copy, PartialEq)] pub enum DisplayState { diff --git a/daemon/src/main.rs b/daemon/src/main.rs index 2e2a822..7c8d965 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -13,7 +13,7 @@ use std::net::SocketAddr; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; -use crate::config::{parse_args, parse_config}; +use crate::config::{Display, parse_args, parse_config}; use crate::diag::run_diag_read_thread; use crate::error::RayhunterError; use crate::pcap::get_pcap; @@ -215,7 +215,7 @@ async fn run_with_config( if !config.debug_mode { let (ui_shutdown_tx, ui_shutdown_rx) = oneshot::channel(); maybe_ui_shutdown_tx = Some(ui_shutdown_tx); - let mut dev = DiagDevice::new() + let mut dev = DiagDevice::new(config.display == Display::Tplink) .await .map_err(RayhunterError::DiagInitError)?; dev.config_logs() @@ -233,7 +233,16 @@ async fn run_with_config( config.analyzers.clone(), ); info!("Starting UI"); - display::update_ui(&task_tracker, &config, ui_shutdown_rx, ui_update_rx); + + let display = &config.display; + info!("Display type {display:?}"); + let update_ui = match display { + Display::Orbic => display::orbic::update_ui, + Display::Tplink => display::tplink::update_ui, + Display::Tmobile => display::tmobile::update_ui, + Display::Wingtech => display::wingtech::update_ui, + }; + update_ui(&task_tracker, &config, ui_shutdown_rx, ui_update_rx); info!("Starting Key Input service"); let (key_input_shutdown_tx, key_input_shutdown_rx) = oneshot::channel(); diff --git a/dist/config.toml.example b/dist/config.toml.example index c0c2774..f599db7 100644 --- a/dist/config.toml.example +++ b/dist/config.toml.example @@ -3,6 +3,8 @@ qmdl_store_path = "/data/rayhunter/qmdl" port = 8080 debug_mode = false colorblind_mode = false +# Display module, this will be overwritten by the installer. Defaults to "orbic". +#display = "orbic" # UI Levels: # # Orbic and TP-Link with color display: diff --git a/installer/build.rs b/installer/build.rs index a83f3b0..bf8bbe1 100644 --- a/installer/build.rs +++ b/installer/build.rs @@ -9,26 +9,7 @@ fn main() { "/../target/armv7-unknown-linux-musleabihf/firmware/" )); set_binary_var(include_dir, "FILE_ROOTSHELL", "rootshell"); - set_binary_var( - include_dir, - "FILE_RAYHUNTER_DAEMON_ORBIC", - "rayhunter-daemon", - ); - set_binary_var( - include_dir, - "FILE_RAYHUNTER_DAEMON_TMOBILE", - "rayhunter-daemon", - ); - set_binary_var( - include_dir, - "FILE_RAYHUNTER_DAEMON_TPLINK", - "rayhunter-daemon", - ); - set_binary_var( - include_dir, - "FILE_RAYHUNTER_DAEMON_WINGTECH", - "rayhunter-daemon", - ); + set_binary_var(include_dir, "FILE_RAYHUNTER_DAEMON", "rayhunter-daemon"); } fn set_binary_var(include_dir: &Path, var: &str, file: &str) { diff --git a/installer/src/orbic.rs b/installer/src/orbic.rs index 563b04f..72c48a0 100644 --- a/installer/src/orbic.rs +++ b/installer/src/orbic.rs @@ -91,7 +91,7 @@ async fn setup_rootshell(adb_device: &mut ADBUSBDevice) -> Result<()> { } async fn setup_rayhunter(mut adb_device: ADBUSBDevice) -> Result { - let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON_ORBIC")); + let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON")); adb_at_syscmd(&mut adb_device, "mkdir -p /data/rayhunter").await?; install_file( @@ -103,7 +103,9 @@ async fn setup_rayhunter(mut adb_device: ADBUSBDevice) -> Result { install_file( &mut adb_device, "/data/rayhunter/config.toml", - CONFIG_TOML.as_bytes(), + CONFIG_TOML + .replace("#display = \"orbic\"", "display = \"orbic\"") + .as_bytes(), ) .await?; install_file( @@ -194,11 +196,11 @@ async fn install_file_impl( .stat(dest) .context("Failed to stat transfered file")?; if file_info.file_size == 0 { - bail!("File transfer unseccessful\nFile is empty"); + bail!("File transfer unsuccessful\nFile is empty"); } - let ouput = adb_command(adb_device, &["sha256sum", dest])?; - if !ouput.contains(&file_hash) { - bail!("File transfer unseccessful\nBad hash expected {file_hash} got {ouput}"); + let output = adb_command(adb_device, &["sha256sum", dest])?; + if !output.contains(&file_hash) { + bail!("File transfer unsuccessful\nBad hash expected {file_hash} got {output}"); } Ok(()) } diff --git a/installer/src/tmobile.rs b/installer/src/tmobile.rs index 387b3c3..352fb32 100644 --- a/installer/src/tmobile.rs +++ b/installer/src/tmobile.rs @@ -41,11 +41,13 @@ async fn run_install(admin_ip: String, admin_password: String) -> Result<()> { telnet_send_file( addr, "/data/rayhunter/config.toml", - crate::CONFIG_TOML.as_bytes(), + crate::CONFIG_TOML + .replace("#display = \"orbic\"", "display = \"tmobile\"") + .as_bytes(), ) .await?; - let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON_TMOBILE")); + let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON")); telnet_send_file( addr, "/data/rayhunter/rayhunter-daemon", diff --git a/installer/src/tplink.rs b/installer/src/tplink.rs index 59bd6f7..cfbc644 100644 --- a/installer/src/tplink.rs +++ b/installer/src/tplink.rs @@ -154,11 +154,13 @@ async fn tplink_run_install( telnet_send_file( addr, &format!("{sdcard_path}/config.toml"), - crate::CONFIG_TOML.as_bytes(), + crate::CONFIG_TOML + .replace("#display = \"orbic\"", "display = \"tplink\"") + .as_bytes(), ) .await?; - let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON_TPLINK")); + let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON")); telnet_send_file( addr, diff --git a/installer/src/wingtech.rs b/installer/src/wingtech.rs index 77c92a9..3d22282 100644 --- a/installer/src/wingtech.rs +++ b/installer/src/wingtech.rs @@ -101,11 +101,13 @@ async fn wingtech_run_install(admin_ip: String, admin_password: String) -> Resul telnet_send_file( addr, "/data/rayhunter/config.toml", - crate::CONFIG_TOML.as_bytes(), + crate::CONFIG_TOML + .replace("#display = \"orbic\"", "display = \"wingtech\"") + .as_bytes(), ) .await?; - let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON_WINGTECH")); + let rayhunter_daemon_bin = include_bytes!(env!("FILE_RAYHUNTER_DAEMON")); telnet_send_file( addr, "/data/rayhunter/rayhunter-daemon", diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 8861136..1e80157 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -9,13 +9,6 @@ description = "Realtime cellular data decoding and analysis for IMSI catcher det name = "rayhunter" path = "src/lib.rs" -[features] -default = [] -orbic = [] -tmobile = [] -tplink = [] -wingtech = [] - [dependencies] bytes = "1.5.0" chrono = { version = "0.4.31", features = ["serde"] } diff --git a/lib/src/diag_device.rs b/lib/src/diag_device.rs index 727dd34..bb60865 100644 --- a/lib/src/diag_device.rs +++ b/lib/src/diag_device.rs @@ -86,11 +86,11 @@ pub struct DiagDevice { } impl DiagDevice { - pub async fn new() -> DiagResult { - Self::new_with_retries(Duration::from_secs(30)).await + pub async fn new(tplink: bool) -> DiagResult { + Self::new_with_retries(Duration::from_secs(30), tplink).await } - pub async fn new_with_retries(max_duration: Duration) -> DiagResult { + pub async fn new_with_retries(max_duration: Duration, tplink: bool) -> DiagResult { // For some reason the diag device needs a very long time to become available again with in // the same process, on TP-Link M7350 v3. While process restart would reset it faster. @@ -101,7 +101,7 @@ impl DiagDevice { let mut num_retries = 0; loop { - match Self::try_new().await { + match Self::try_new(tplink).await { Ok(device) => { info!("Diag device initialization succeeded after {num_retries} retries"); return Ok(device); @@ -125,7 +125,7 @@ impl DiagDevice { } } - async fn try_new() -> DiagResult { + async fn try_new(tplink: bool) -> DiagResult { let diag_file = File::options() .read(true) .write(true) @@ -134,7 +134,7 @@ impl DiagDevice { .map_err(DiagDeviceError::OpenDiagDeviceError)?; let fd = diag_file.as_raw_fd(); - enable_frame_readwrite(fd, MEMORY_DEVICE_MODE)?; + enable_frame_readwrite(fd, MEMORY_DEVICE_MODE, tplink)?; let use_mdm = determine_use_mdm(fd)?; Ok(DiagDevice { @@ -300,24 +300,30 @@ struct DiagLoggingModeParam { } // Triggers the diag device's debug logging mode -fn enable_frame_readwrite(fd: i32, mode: u32) -> DiagResult<()> { +fn enable_frame_readwrite(fd: i32, mode: u32, tplink: bool) -> DiagResult<()> { unsafe { if libc::ioctl(fd, DIAG_IOCTL_SWITCH_LOGGING, mode, 0, 0, 0) < 0 { - let try_params: &[DiagLoggingModeParam] = &[ - // tplink M7350 HW revision 3-8 need this mode - #[cfg(feature = "tplink")] - DiagLoggingModeParam { - req_mode: mode, - peripheral_mask: 0, - mode_param: 1, - }, - // tplink M7350 HW revision v9 requires the same parameters as orbic - DiagLoggingModeParam { + let try_params: &[DiagLoggingModeParam] = match tplink { + true => &[ + // tplink M7350 HW revision 3-8 need this mode + DiagLoggingModeParam { + req_mode: mode, + peripheral_mask: 0, + mode_param: 1, + }, + // tplink M7350 HW revision v9 requires the same parameters as orbic + DiagLoggingModeParam { + req_mode: mode, + peripheral_mask: u32::MAX, + mode_param: 0, + }, + ], + false => &[DiagLoggingModeParam { req_mode: mode, peripheral_mask: u32::MAX, mode_param: 0, - }, - ]; + }], + }; let mut ret = 0;