File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -37,6 +37,29 @@ const PASS_ENV: &[&str] = &[
3737 "KASUMI_SKIP_ELEVATION" ,
3838] ;
3939
40+ /// Whether the process already has the privileges the tun data-path needs (root on
41+ /// Linux, admin on Windows), or elevation was explicitly waived. Drives the
42+ /// relaunch-into-tun decision: a `false` here on a tun start means we must re-exec.
43+ #[ cfg( target_os = "linux" ) ]
44+ pub fn is_privileged ( ) -> bool {
45+ let root = unsafe { libc:: geteuid ( ) == 0 } ;
46+ root || std:: env:: var_os ( "KASUMI_SKIP_ELEVATION" ) . is_some ( )
47+ }
48+
49+ /// See the Linux variant.
50+ #[ cfg( target_os = "windows" ) ]
51+ pub fn is_privileged ( ) -> bool {
52+ use windows_sys:: Win32 :: UI :: Shell :: IsUserAnAdmin ;
53+ let admin = unsafe { IsUserAnAdmin ( ) != 0 } ;
54+ admin || std:: env:: var_os ( "KASUMI_SKIP_ELEVATION" ) . is_some ( )
55+ }
56+
57+ /// Other desktops (macOS) have no elevation path yet; treat as privileged.
58+ #[ cfg( not( any( target_os = "linux" , target_os = "windows" ) ) ) ]
59+ pub fn is_privileged ( ) -> bool {
60+ true
61+ }
62+
4063/// Re-exec the process as root if it isn't already. Returns on the elevated side
4164/// (or when no elevator is available — the data-path then fails loudly at start,
4265/// which the UI surfaces). Must run before any GTK/Tauri init.
Original file line number Diff line number Diff line change @@ -270,6 +270,14 @@ impl Platform for DesktopPlatform {
270270 // Only `tun` mode brings up a tun device + routing; the other modes run the
271271 // core with just its local socks/http inbound.
272272 let tun = mode == ProxyMode :: Tun ;
273+ // Tun needs root. If the process started unprivileged (a proxy-only/system/pac
274+ // launch) and the user switched to tun, relaunch elevated now — this prompts
275+ // pkexec and, on success, never returns (the elevated copy takes over). We only
276+ // reach the line below if elevation was declined/unavailable.
277+ if tun && !crate :: desktop:: elevate:: is_privileged ( ) {
278+ crate :: desktop:: elevate:: ensure_elevated ( ) ;
279+ return self . fail ( "TUN mode needs administrator rights" ) . await ;
280+ }
273281 let result = if engine == CoreEngine :: SingBox {
274282 self . start_singbox ( tun) . await
275283 } else {
Original file line number Diff line number Diff line change @@ -255,6 +255,14 @@ impl Platform for DesktopPlatform {
255255 // Only `tun` mode brings up a wintun device + routing; the other modes run
256256 // the core with just its local socks/http inbound.
257257 let tun = mode == ProxyMode :: Tun ;
258+ // Tun needs admin. If the process started unprivileged (a proxy-only/system/pac
259+ // launch) and the user switched to tun, relaunch elevated now — this prompts
260+ // UAC and, on success, never returns (the elevated copy takes over). We only
261+ // reach the line below if elevation was declined/unavailable.
262+ if tun && !crate :: desktop:: elevate:: is_privileged ( ) {
263+ crate :: desktop:: elevate:: ensure_elevated ( ) ;
264+ return self . fail ( "TUN mode needs administrator rights" ) . await ;
265+ }
258266 let result = if engine == CoreEngine :: SingBox {
259267 self . start_singbox ( tun) . await
260268 } else {
You can’t perform that action at this time.
0 commit comments