mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-05-24 08:44:45 -07:00
unified rayhunter-daemon binary for all devices
Replace per-device features with config "display" field with the value set at install time.
This commit is contained in:
committed by
Will Greenberg
parent
5b59efa4c8
commit
22d927aa25
29
.github/workflows/main.yml
vendored
29
.github/workflows/main.yml
vendored
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
2
dist/config.toml.example
vendored
2
dist/config.toml.example
vendored
@@ -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:
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -91,7 +91,7 @@ async fn setup_rootshell(adb_device: &mut ADBUSBDevice) -> Result<()> {
|
||||
}
|
||||
|
||||
async fn setup_rayhunter(mut adb_device: ADBUSBDevice) -> Result<ADBUSBDevice> {
|
||||
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<ADBUSBDevice> {
|
||||
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(())
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
@@ -86,11 +86,11 @@ pub struct DiagDevice {
|
||||
}
|
||||
|
||||
impl DiagDevice {
|
||||
pub async fn new() -> DiagResult<Self> {
|
||||
Self::new_with_retries(Duration::from_secs(30)).await
|
||||
pub async fn new(tplink: bool) -> DiagResult<Self> {
|
||||
Self::new_with_retries(Duration::from_secs(30), tplink).await
|
||||
}
|
||||
|
||||
pub async fn new_with_retries(max_duration: Duration) -> DiagResult<Self> {
|
||||
pub async fn new_with_retries(max_duration: Duration, tplink: bool) -> DiagResult<Self> {
|
||||
// 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<Self> {
|
||||
async fn try_new(tplink: bool) -> DiagResult<Self> {
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user