fix(core): prevent certain commands from being run as root on macOS. Fix #648

This commit is contained in:
Federico Terzi 2021-11-01 21:00:51 +01:00
parent 3034dbe122
commit 846d0a2be3
5 changed files with 31 additions and 1 deletions

View File

@ -28,7 +28,7 @@ use espanso_path::Paths;
use log::{error, info, warn}; use log::{error, info, warn};
use crate::{ use crate::{
cli::util::CommandExt, cli::util::{prevent_running_as_root_on_macos, CommandExt},
common_flags::*, common_flags::*,
exit_code::{ exit_code::{
DAEMON_ALREADY_RUNNING, DAEMON_FATAL_CONFIG_ERROR, DAEMON_GENERAL_ERROR, DAEMON_ALREADY_RUNNING, DAEMON_FATAL_CONFIG_ERROR, DAEMON_GENERAL_ERROR,
@ -60,6 +60,8 @@ pub fn new() -> CliModule {
} }
fn daemon_main(args: CliModuleArgs) -> i32 { fn daemon_main(args: CliModuleArgs) -> i32 {
prevent_running_as_root_on_macos();
let paths = args.paths.expect("missing paths in daemon main"); let paths = args.paths.expect("missing paths in daemon main");
let paths_overrides = args let paths_overrides = args
.paths_overrides .paths_overrides

View File

@ -23,12 +23,16 @@ use std::process::Command;
use std::{fs::create_dir_all, process::ExitStatus}; use std::{fs::create_dir_all, process::ExitStatus};
use thiserror::Error; use thiserror::Error;
use crate::cli::util::prevent_running_as_root_on_macos;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
const SERVICE_PLIST_CONTENT: &str = include_str!("../../res/macos/com.federicoterzi.espanso.plist"); const SERVICE_PLIST_CONTENT: &str = include_str!("../../res/macos/com.federicoterzi.espanso.plist");
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
const SERVICE_PLIST_FILE_NAME: &str = "com.federicoterzi.espanso.plist"; const SERVICE_PLIST_FILE_NAME: &str = "com.federicoterzi.espanso.plist";
pub fn register() -> Result<()> { pub fn register() -> Result<()> {
prevent_running_as_root_on_macos();
let home_dir = dirs::home_dir().expect("could not get user home directory"); let home_dir = dirs::home_dir().expect("could not get user home directory");
let library_dir = home_dir.join("Library"); let library_dir = home_dir.join("Library");
let agents_dir = library_dir.join("LaunchAgents"); let agents_dir = library_dir.join("LaunchAgents");
@ -94,6 +98,8 @@ pub enum RegisterError {
} }
pub fn unregister() -> Result<()> { pub fn unregister() -> Result<()> {
prevent_running_as_root_on_macos();
let home_dir = dirs::home_dir().expect("could not get user home directory"); let home_dir = dirs::home_dir().expect("could not get user home directory");
let library_dir = home_dir.join("Library"); let library_dir = home_dir.join("Library");
let agents_dir = library_dir.join("LaunchAgents"); let agents_dir = library_dir.join("LaunchAgents");

View File

@ -53,3 +53,19 @@ impl CommandExt for Command {
self self
} }
} }
// For context, see also this issue: https://github.com/federico-terzi/espanso/issues/648
#[cfg(target_os = "macos")]
pub fn prevent_running_as_root_on_macos() {
use crate::{error_eprintln, exit_code::UNEXPECTED_RUN_AS_ROOT};
if unsafe { libc::geteuid() } == 0 {
error_eprintln!("Espanso is being run as root, but this can create unwanted side-effects. Please run it as a normal user.");
std::process::exit(UNEXPECTED_RUN_AS_ROOT);
}
}
#[cfg(not(target_os = "macos"))]
pub fn prevent_running_as_root_on_macos() {
// Do nothing on other platforms
}

View File

@ -22,6 +22,7 @@ use espanso_engine::event::ExitMode;
use log::{debug, error, info}; use log::{debug, error, info};
use crate::{ use crate::{
cli::util::prevent_running_as_root_on_macos,
exit_code::{ exit_code::{
WORKER_ALREADY_RUNNING, WORKER_EXIT_ALL_PROCESSES, WORKER_GENERAL_ERROR, WORKER_ALREADY_RUNNING, WORKER_EXIT_ALL_PROCESSES, WORKER_GENERAL_ERROR,
WORKER_LEGACY_ALREADY_RUNNING, WORKER_RESTART, WORKER_SUCCESS, WORKER_LEGACY_ALREADY_RUNNING, WORKER_RESTART, WORKER_SUCCESS,
@ -58,6 +59,8 @@ pub fn new() -> CliModule {
} }
fn worker_main(args: CliModuleArgs) -> i32 { fn worker_main(args: CliModuleArgs) -> i32 {
prevent_running_as_root_on_macos();
let paths = args.paths.expect("missing paths in worker main"); let paths = args.paths.expect("missing paths in worker main");
let cli_args = args.cli_args.expect("missing cli_args in worker main"); let cli_args = args.cli_args.expect("missing cli_args in worker main");

View File

@ -68,6 +68,9 @@ pub const PACKAGE_LIST_FAILED: i32 = 4;
pub const PACKAGE_UPDATE_FAILED: i32 = 5; pub const PACKAGE_UPDATE_FAILED: i32 = 5;
pub const PACKAGE_UPDATE_PARTIAL_FAILURE: i32 = 6; pub const PACKAGE_UPDATE_PARTIAL_FAILURE: i32 = 6;
#[allow(dead_code)]
pub const UNEXPECTED_RUN_AS_ROOT: i32 = 42;
use std::sync::Mutex; use std::sync::Mutex;
use crate::error_eprintln; use crate::error_eprintln;