fix(gui): add non-Linux stubs for pmkid_hunt/pmf_test and fix Windows warnings
main.rs failed to compile on Windows: pmkid_hunt and pmf_test were only implemented under #[cfg(target_os = "linux")], with no fallback stub, so the Tauri commands calling them did not resolve. - Add #[cfg(not(target_os = "linux"))] stubs for both, matching the existing pattern for every other Linux-only Engine method (returns SabiaError::UnsupportedPlatform). - Mark the DeauthJob/Engine fields and session_ap/client_snapshot helpers that only the Linux-only code paths use with #[cfg_attr(not(target_os = "linux"), allow(dead_code))], same for eviltwin.rs's form_value/url_decode (only called from the #[cfg(target_os = "linux")] HTTP handler) — silences the 5 dead_code warnings a Windows build produced. - .setup(|app| ...) used app only inside unix/linux/macos-gated blocks, so it was unused on Windows; renamed the closure parameter and reintroduce it under the matching cfg. - Add the missing English dictionary entry for the mutation-rules checkbox label in app.js (found by visually reviewing a generated screenshot: it was rendering in Portuguese in the English UI even though check-ui-i18n.mjs reported full coverage). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VAyr8d7HuAdUGB6aA5xmDD
This commit is contained in:
1 parent
2dfbbfc64a
commit
a904723f96
4 files changed
+302
-270
No files matched your search
@@ -1,4 +1,4 @@
|
||||
// Evita a janela de console extra no Windows em release.
|
||||
// Prevents an extra console window on Windows in release builds.
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
use sabia_core::engine::{Engine, ScanOptions};
|
||||
@@ -506,9 +506,9 @@ fn update_apply(state: tauri::State<'_, State>) -> Result<String, String> {
|
||||
state.0.update_apply().map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// `true` quando o processo já tem privilégio suficiente pra tudo que o
|
||||
/// Sabiá faz (modo monitor, captura crua). No Windows o manifesto já
|
||||
/// exige administrador antes mesmo do app abrir, então aqui é sempre `true`.
|
||||
/// `true` when the process already has sufficient privileges for all
|
||||
/// Sabiá operations (monitor mode, raw capture). On Windows the manifest already
|
||||
/// requires administrator privileges before launch, so this is always `true`.
|
||||
#[tauri::command]
|
||||
fn is_elevated() -> bool {
|
||||
#[cfg(unix)]
|
||||
@@ -521,9 +521,9 @@ fn is_elevated() -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reabre o app com privilégios de administrador (Linux/macOS). O app novo
|
||||
/// encerra este quando abre; se a autorização falhar ou for cancelada, a
|
||||
/// janela continua aqui e a interface mostra o motivo.
|
||||
/// Relaunches the app with administrator privileges (Linux/macOS). The new instance
|
||||
/// terminates this one on startup; if authorization fails or is cancelled, the
|
||||
/// window stays open and the UI displays the reason.
|
||||
#[tauri::command]
|
||||
fn relaunch_elevated(app: tauri::AppHandle) -> Result<(), String> {
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
@@ -610,9 +610,9 @@ fn do_relaunch_elevated(app: tauri::AppHandle) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Caminho que o root consegue executar. No AppImage, `current_exe` aponta
|
||||
/// pra dentro de um ponto de montagem FUSE do usuário, inacessível ao root:
|
||||
/// usa o próprio arquivo `.AppImage` (variável `APPIMAGE`).
|
||||
/// Executable path accessible to root. Inside an AppImage, `current_exe` points
|
||||
/// inside a user FUSE mount that root cannot access:
|
||||
/// use the `.AppImage` file itself (`APPIMAGE` environment variable).
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
fn elevated_exe() -> Result<std::path::PathBuf, String> {
|
||||
if let Some(p) = std::env::var_os("APPIMAGE")
|
||||
@@ -628,8 +628,11 @@ fn main() {
|
||||
let engine = Arc::new(Engine::new());
|
||||
tauri::Builder::default()
|
||||
.manage(State(engine))
|
||||
.setup(|app| {
|
||||
// Quando abrimos elevados a pedido do app normal, ele fecha o app antigo.
|
||||
.setup(|_app| {
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
let app = _app;
|
||||
|
||||
// When launched elevated by the unprivileged instance, terminate the old process.
|
||||
#[cfg(unix)]
|
||||
if let Some(pid) = std::env::var("SABIA_REPLACE_PID")
|
||||
.ok()
|
||||
@@ -637,7 +640,7 @@ fn main() {
|
||||
{
|
||||
std::thread::spawn(move || {
|
||||
std::thread::sleep(std::time::Duration::from_millis(1200));
|
||||
// SAFETY: só envia SIGTERM ao processo anterior do próprio usuário.
|
||||
// SAFETY: only sends SIGTERM to the previous process owned by the invoking user.
|
||||
unsafe {
|
||||
if libc::geteuid() == 0 {
|
||||
libc::kill(pid, libc::SIGTERM);
|
||||
@@ -646,10 +649,10 @@ fn main() {
|
||||
});
|
||||
}
|
||||
|
||||
// Captura crua e modo monitor exigem root: pede elevação assim
|
||||
// que o app abre, sem esperar o usuário procurar um botão. Se
|
||||
// a autorização falhar, a janela continua aberta e a interface
|
||||
// mostra o aviso (com um botão pra tentar de novo).
|
||||
// Raw capture and monitor mode require root: request elevation as soon
|
||||
// as the app launches, without waiting for the user to look for a button. If
|
||||
// authorization fails, the window stays open and the UI
|
||||
// displays a warning banner (with a retry button).
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
if unsafe { libc::geteuid() != 0 } && std::env::var("SABIA_REPLACE_PID").is_err() {
|
||||
let handle = app.handle().clone();
|
||||
|
||||
+13
-11
@@ -1,4 +1,4 @@
|
||||
// Dicionário português -> inglês da interface. {n} marca um valor variável.
|
||||
// Portuguese -> English UI dictionary. {n} marks a variable placeholder.
|
||||
export const EN = {
|
||||
// index.html / sidebar
|
||||
'auditoria de Wi-Fi': 'Wi-Fi auditing',
|
||||
@@ -19,7 +19,7 @@ export const EN = {
|
||||
'modo monitor': 'monitor mode',
|
||||
'modo gerenciado': 'managed mode',
|
||||
|
||||
// elevação / avisos
|
||||
// elevation / notices
|
||||
'Pedindo privilégio de administrador — necessário pra modo monitor e captura…':
|
||||
'Requesting administrator privilege — needed for monitor mode and capture…',
|
||||
'tentar de novo': 'try again',
|
||||
@@ -27,13 +27,13 @@ export const EN = {
|
||||
'Use somente em redes próprias ou com autorização explícita do responsável. Toda ativação de modo monitor e sessão de captura fica registrada na trilha de auditoria local.':
|
||||
'Use only on your own networks or with the explicit authorization of the responsible party. Every monitor mode activation and capture session is logged in the local audit trail.',
|
||||
|
||||
// controles
|
||||
// controls
|
||||
'ativar modo monitor': 'enable monitor mode',
|
||||
'desativar modo monitor': 'disable monitor mode',
|
||||
'iniciar captura': 'start capture',
|
||||
'parar captura': 'stop capture',
|
||||
|
||||
// resultados
|
||||
// results
|
||||
'Redes': 'Networks',
|
||||
'Redes vistas': 'Networks seen',
|
||||
'Linha do tempo': 'Timeline',
|
||||
@@ -72,7 +72,7 @@ export const EN = {
|
||||
'Nenhuma rede corresponde ao filtro': 'No network matches the filter',
|
||||
'Ajuste a busca ou limpe o campo de filtro.': 'Adjust the search or clear the filter.',
|
||||
|
||||
// erros de UI
|
||||
// UI errors
|
||||
'Não foi possível trocar o modo:': 'Could not change the mode:',
|
||||
'Não foi possível iniciar a captura:': 'Could not start the capture:',
|
||||
'Não foi possível retomar a captura: {n}': 'Could not resume the capture: {n}',
|
||||
@@ -82,7 +82,7 @@ export const EN = {
|
||||
'erro desconhecido': 'unknown error',
|
||||
'rota desconhecida': 'unknown route',
|
||||
|
||||
// seletor de idioma / configurações
|
||||
// language selector / settings
|
||||
'Configurações': 'Settings',
|
||||
'Tema': 'Theme',
|
||||
'Claro': 'Light',
|
||||
@@ -133,7 +133,7 @@ export const EN = {
|
||||
'quantidade de quadros deve ficar entre 1 e 256': 'frame count must be between 1 and 256',
|
||||
'MAC inválido: {n}': 'invalid MAC: {n}',
|
||||
|
||||
// detalhes do alvo e ataques
|
||||
// target details and attacks
|
||||
'não': 'no',
|
||||
'não anunciado': 'not advertised',
|
||||
'quebrável': 'crackable',
|
||||
@@ -340,7 +340,7 @@ export const EN = {
|
||||
'{n} · canal {n}': '{n} · channel {n}',
|
||||
'{n} ({n})': '{n} ({n})',
|
||||
|
||||
// canais, PMKID/PMF, WPS e relatório
|
||||
// channels, PMKID/PMF, WPS, and report
|
||||
'Ocupação dos canais em {n}': 'Channel occupancy on {n}',
|
||||
'Sem dados de canal ainda': 'No channel data yet',
|
||||
'Inicie a captura para o Sabiá medir ocupação e sugerir canais.':
|
||||
@@ -358,7 +358,7 @@ export const EN = {
|
||||
'Melhor canal': 'Best channel',
|
||||
'Espectro e canais': 'Spectrum and channels',
|
||||
|
||||
// saúde do espectro (canais, estilo SMART)
|
||||
// spectrum health (channels, SMART style)
|
||||
'Boa': 'Good',
|
||||
'Atenção': 'Attention',
|
||||
'Saturado': 'Saturated',
|
||||
@@ -478,7 +478,7 @@ export const EN = {
|
||||
'não foi possível executar {n}: {n}': 'could not run {n}: {n}',
|
||||
'{n} terminou com código {n}': '{n} exited with code {n}',
|
||||
|
||||
// achados do WIDS (analysis.rs)
|
||||
// WIDS findings (analysis.rs)
|
||||
'SSID “{n}” com seguranças diferentes': 'SSID “{n}” with different security levels',
|
||||
'O mesmo nome aparece em BSSIDs com níveis de segurança distintos: {n}. Pode ser um evil twin ou um AP mal configurado.':
|
||||
'The same name appears on BSSIDs with different security levels: {n}. It may be an evil twin or a misconfigured AP.',
|
||||
@@ -525,7 +525,7 @@ export const EN = {
|
||||
'The station did not reassociate in the observed window. PMF may be active, or the client simply stayed idle.',
|
||||
'Inconclusivo': 'Inconclusive',
|
||||
|
||||
// deauth contínuo e identificação de clientes
|
||||
// continuous deauth and client identification
|
||||
'Mantém os quadros saindo em série até você parar (ou até sair o handshake). O canal da captura fica travado no AP durante o job.':
|
||||
'Keeps frames going until you stop (or a handshake appears). The capture channel stays locked to the AP during the job.',
|
||||
'Iniciar contínuo': 'Start continuous',
|
||||
@@ -547,6 +547,8 @@ export const EN = {
|
||||
'The bundled reaver could not be extracted in this run.',
|
||||
'Dicionário (vazio = embutido, 9,7 milhões de senhas)': 'Wordlist (empty = bundled, 9.7 million passwords)',
|
||||
'dicionário próprio, opcional': 'custom wordlist, optional',
|
||||
'Aplicar regras de mutação (maiúscula, sufixos, leet — multiplica o tempo)':
|
||||
'Apply mutation rules (uppercase, suffixes, leetspeak — multiplies run time)',
|
||||
'Dispositivo': 'Device',
|
||||
'MAC aleatório': 'Random MAC',
|
||||
'Cliente {n}': 'Client {n}',
|
||||
|
||||
Reference in new issue
Block a user