diff --git a/src/uu/runcon/locales/en-US.ftl b/src/uu/runcon/locales/en-US.ftl index 37d977a5b..bc3fd4050 100644 --- a/src/uu/runcon/locales/en-US.ftl +++ b/src/uu/runcon/locales/en-US.ftl @@ -8,3 +8,31 @@ runcon-after-help = Run COMMAND with completely-specified CONTEXT, or with curre Note that only carefully-chosen contexts are likely to successfully run. If neither CONTEXT nor COMMAND is specified, the current security context is printed. + +# Help messages +runcon-help-compute = Compute process transition context before modifying. +runcon-help-user = Set user USER in the target security context. +runcon-help-role = Set role ROLE in the target security context. +runcon-help-type = Set type TYPE in the target security context. +runcon-help-range = Set range RANGE in the target security context. + +# Error messages +runcon-error-no-command = No command is specified +runcon-error-selinux-not-enabled = runcon may be used only on a SELinux kernel +runcon-error-operation-failed = { $operation } failed +runcon-error-operation-failed-on = { $operation } failed on { $operand } + +# Operation names +runcon-operation-getting-current-context = Getting security context of the current process +runcon-operation-creating-context = Creating new context +runcon-operation-checking-context = Checking security context +runcon-operation-setting-context = Setting new security context +runcon-operation-getting-process-class = Getting process security class +runcon-operation-getting-file-context = Getting security context of command file +runcon-operation-computing-transition = Computing result of process transition +runcon-operation-getting-context = Getting security context +runcon-operation-setting-user = Setting security context user +runcon-operation-setting-role = Setting security context role +runcon-operation-setting-type = Setting security context type +runcon-operation-setting-range = Setting security context range +runcon-operation-executing-command = Executing command diff --git a/src/uu/runcon/locales/fr-FR.ftl b/src/uu/runcon/locales/fr-FR.ftl new file mode 100644 index 000000000..4503bdfde --- /dev/null +++ b/src/uu/runcon/locales/fr-FR.ftl @@ -0,0 +1,38 @@ +runcon-about = Exécuter une commande avec le contexte de sécurité spécifié sous les systèmes avec SELinux activé. +runcon-usage = runcon CONTEXTE COMMANDE [ARG...] + runcon [-c] [-u UTILISATEUR] [-r RÔLE] [-t TYPE] [-l PLAGE] COMMANDE [ARG...] +runcon-after-help = Exécuter COMMANDE avec un CONTEXTE complètement spécifié, ou avec le contexte de sécurité actuel ou de transition modifié par un ou plusieurs parmi NIVEAU, RÔLE, TYPE et UTILISATEUR. + + Si aucun de --compute, --type, --user, --role ou --range n'est spécifié, alors le premier argument est utilisé comme contexte complet. + + Notez que seuls les contextes soigneusement choisis ont des chances de s'exécuter avec succès. + + Si ni CONTEXTE ni COMMANDE n'est spécifié, le contexte de sécurité actuel est affiché. + +# Messages d'aide +runcon-help-compute = Calculer le contexte de transition de processus avant modification. +runcon-help-user = Définir l'utilisateur UTILISATEUR dans le contexte de sécurité cible. +runcon-help-role = Définir le rôle RÔLE dans le contexte de sécurité cible. +runcon-help-type = Définir le type TYPE dans le contexte de sécurité cible. +runcon-help-range = Définir la plage PLAGE dans le contexte de sécurité cible. + +# Messages d'erreur +runcon-error-no-command = Aucune commande n'est spécifiée +runcon-error-selinux-not-enabled = runcon ne peut être utilisé que sur un noyau SELinux +runcon-error-operation-failed = { $operation } a échoué +runcon-error-operation-failed-on = { $operation } a échoué sur { $operand } + +# Noms d'opération +runcon-operation-getting-current-context = Obtention du contexte de sécurité du processus actuel +runcon-operation-creating-context = Création d'un nouveau contexte +runcon-operation-checking-context = Vérification du contexte de sécurité +runcon-operation-setting-context = Définition du nouveau contexte de sécurité +runcon-operation-getting-process-class = Obtention de la classe de sécurité du processus +runcon-operation-getting-file-context = Obtention du contexte de sécurité du fichier de commande +runcon-operation-computing-transition = Calcul du résultat de la transition de processus +runcon-operation-getting-context = Obtention du contexte de sécurité +runcon-operation-setting-user = Définition de l'utilisateur du contexte de sécurité +runcon-operation-setting-role = Définition du rôle du contexte de sécurité +runcon-operation-setting-type = Définition du type du contexte de sécurité +runcon-operation-setting-range = Définition de la plage du contexte de sécurité +runcon-operation-executing-command = Exécution de la commande diff --git a/src/uu/runcon/src/errors.rs b/src/uu/runcon/src/errors.rs index 4b4a9e1e6..b1ce45fb1 100644 --- a/src/uu/runcon/src/errors.rs +++ b/src/uu/runcon/src/errors.rs @@ -4,6 +4,7 @@ // file that was distributed with this source code. #![cfg(target_os = "linux")] +use std::collections::HashMap; use std::ffi::OsString; use std::fmt::{Display, Formatter, Write}; use std::io; @@ -11,6 +12,7 @@ use std::str::Utf8Error; use uucore::display::Quotable; use uucore::error::UError; +use uucore::locale::{get_message, get_message_with_args}; pub(crate) type Result = std::result::Result; @@ -25,10 +27,10 @@ pub(crate) mod error_exit_status { #[derive(thiserror::Error, Debug)] pub(crate) enum Error { - #[error("No command is specified")] + #[error("{}", get_message("runcon-error-no-command"))] MissingCommand, - #[error("runcon may be used only on a SELinux kernel")] + #[error("{}", get_message("runcon-error-selinux-not-enabled"))] SELinuxNotEnabled, #[error(transparent)] @@ -37,19 +39,19 @@ pub(crate) enum Error { #[error(transparent)] CommandLine(#[from] clap::Error), - #[error("{operation} failed")] + #[error("{}", get_message_with_args("runcon-error-operation-failed", HashMap::from([("operation".to_string(), get_message(.operation))])))] SELinux { operation: &'static str, source: selinux::errors::Error, }, - #[error("{operation} failed")] + #[error("{}", get_message_with_args("runcon-error-operation-failed", HashMap::from([("operation".to_string(), get_message(.operation))])))] Io { operation: &'static str, source: io::Error, }, - #[error("{operation} failed on {}", .operand1.quote())] + #[error("{}", get_message_with_args("runcon-error-operation-failed-on", HashMap::from([("operation".to_string(), get_message(.operation)), ("operand".to_string(), .operand1.quote().to_string())])))] Io1 { operation: &'static str, operand1: OsString, diff --git a/src/uu/runcon/src/runcon.rs b/src/uu/runcon/src/runcon.rs index ee67a9220..7cb2d8e4e 100644 --- a/src/uu/runcon/src/runcon.rs +++ b/src/uu/runcon/src/runcon.rs @@ -7,6 +7,7 @@ use clap::builder::ValueParser; use uucore::error::{UClapError, UError, UResult}; +use uucore::locale::get_message; use clap::{Arg, ArgAction, Command}; use selinux::{OpaqueSecurityContext, SecurityClass, SecurityContext}; @@ -23,8 +24,6 @@ mod errors; use errors::error_exit_status; use errors::{Error, Result, RunconError}; -use uucore::locale::get_message; - pub mod options { pub const COMPUTE: &str = "compute"; @@ -96,7 +95,7 @@ pub fn uu_app() -> Command { Arg::new(options::COMPUTE) .short('c') .long(options::COMPUTE) - .help("Compute process transition context before modifying.") + .help(get_message("runcon-help-compute")) .action(ArgAction::SetTrue), ) .arg( @@ -104,7 +103,7 @@ pub fn uu_app() -> Command { .short('u') .long(options::USER) .value_name("USER") - .help("Set user USER in the target security context.") + .help(get_message("runcon-help-user")) .value_parser(ValueParser::os_string()), ) .arg( @@ -112,7 +111,7 @@ pub fn uu_app() -> Command { .short('r') .long(options::ROLE) .value_name("ROLE") - .help("Set role ROLE in the target security context.") + .help(get_message("runcon-help-role")) .value_parser(ValueParser::os_string()), ) .arg( @@ -120,7 +119,7 @@ pub fn uu_app() -> Command { .short('t') .long(options::TYPE) .value_name("TYPE") - .help("Set type TYPE in the target security context.") + .help(get_message("runcon-help-type")) .value_parser(ValueParser::os_string()), ) .arg( @@ -128,7 +127,7 @@ pub fn uu_app() -> Command { .short('l') .long(options::RANGE) .value_name("RANGE") - .help("Set range RANGE in the target security context.") + .help(get_message("runcon-help-range")) .value_parser(ValueParser::os_string()), ) .arg( @@ -235,12 +234,12 @@ fn parse_command_line(config: Command, args: impl uucore::Args) -> UResult Result<()> { - let op = "Getting security context of the current process"; - let context = SecurityContext::current(false).map_err(|r| Error::from_selinux(op, r))?; + let context = SecurityContext::current(false) + .map_err(|r| Error::from_selinux("runcon-operation-getting-current-context", r))?; let context = context .to_c_string() - .map_err(|r| Error::from_selinux(op, r))?; + .map_err(|r| Error::from_selinux("runcon-operation-getting-current-context", r))?; if let Some(context) = context { let context = context.as_ref().to_str()?; @@ -254,18 +253,22 @@ fn print_current_context() -> Result<()> { fn set_next_exec_context(context: &OpaqueSecurityContext) -> Result<()> { let c_context = context .to_c_string() - .map_err(|r| Error::from_selinux("Creating new context", r))?; + .map_err(|r| Error::from_selinux("runcon-operation-creating-context", r))?; let sc = SecurityContext::from_c_str(&c_context, false); if sc.check() != Some(true) { let ctx = OsStr::from_bytes(c_context.as_bytes()); let err = io::ErrorKind::InvalidInput.into(); - return Err(Error::from_io1("Checking security context", ctx, err)); + return Err(Error::from_io1( + "runcon-operation-checking-context", + ctx, + err, + )); } sc.set_for_next_exec() - .map_err(|r| Error::from_selinux("Setting new security context", r)) + .map_err(|r| Error::from_selinux("runcon-operation-setting-context", r)) } fn get_plain_context(context: &OsStr) -> Result { @@ -276,13 +279,13 @@ fn get_plain_context(context: &OsStr) -> Result { let c_context = os_str_to_c_string(context)?; OpaqueSecurityContext::from_c_str(&c_context) - .map_err(|r| Error::from_selinux("Creating new context", r)) + .map_err(|r| Error::from_selinux("runcon-operation-creating-context", r)) } fn get_transition_context(command: &OsStr) -> Result { // Generate context based on process transition. let sec_class = SecurityClass::from_name("process") - .map_err(|r| Error::from_selinux("Getting process security class", r))?; + .map_err(|r| Error::from_selinux("runcon-operation-getting-process-class", r))?; // Get context of file to be executed. let file_context = match SecurityContext::of_path(command, true, false) { @@ -290,22 +293,24 @@ fn get_transition_context(command: &OsStr) -> Result { Ok(None) => { let err = io::Error::from_raw_os_error(libc::ENODATA); - return Err(Error::from_io1("getfilecon", command, err)); + return Err(Error::from_io1("runcon-operation-getfilecon", command, err)); } Err(r) => { - let op = "Getting security context of command file"; - return Err(Error::from_selinux(op, r)); + return Err(Error::from_selinux( + "runcon-operation-getting-file-context", + r, + )); } }; let process_context = SecurityContext::current(false) - .map_err(|r| Error::from_selinux("Getting security context of the current process", r))?; + .map_err(|r| Error::from_selinux("runcon-operation-getting-current-context", r))?; // Compute result of process transition. process_context .of_labeling_decision(&file_context, sec_class, "") - .map_err(|r| Error::from_selinux("Computing result of process transition", r)) + .map_err(|r| Error::from_selinux("runcon-operation-computing-transition", r)) } fn get_initial_custom_opaque_context( @@ -315,18 +320,17 @@ fn get_initial_custom_opaque_context( let context = if compute_transition_context { get_transition_context(command)? } else { - SecurityContext::current(false).map_err(|r| { - Error::from_selinux("Getting security context of the current process", r) - })? + SecurityContext::current(false) + .map_err(|r| Error::from_selinux("runcon-operation-getting-current-context", r))? }; let c_context = context .to_c_string() - .map_err(|r| Error::from_selinux("Getting security context", r))? + .map_err(|r| Error::from_selinux("runcon-operation-getting-context", r))? .unwrap_or_else(|| Cow::Owned(CString::default())); OpaqueSecurityContext::from_c_str(c_context.as_ref()) - .map_err(|r| Error::from_selinux("Creating new context", r)) + .map_err(|r| Error::from_selinux("runcon-operation-creating-context", r)) } fn get_custom_context( @@ -347,16 +351,16 @@ fn get_custom_context( let osc = get_initial_custom_opaque_context(compute_transition_context, command)?; let list: &[(Option<&OsStr>, SetNewValueProc, &'static str)] = &[ - (user, OSC::set_user, "Setting security context user"), - (role, OSC::set_role, "Setting security context role"), - (the_type, OSC::set_type, "Setting security context type"), - (range, OSC::set_range, "Setting security context range"), + (user, OSC::set_user, "runcon-operation-setting-user"), + (role, OSC::set_role, "runcon-operation-setting-role"), + (the_type, OSC::set_type, "runcon-operation-setting-type"), + (range, OSC::set_range, "runcon-operation-setting-range"), ]; - for &(new_value, method, op) in list { + for &(new_value, method, op_key) in list { if let Some(new_value) = new_value { let c_new_value = os_str_to_c_string(new_value)?; - method(&osc, &c_new_value).map_err(|r| Error::from_selinux(op, r))?; + method(&osc, &c_new_value).map_err(|r| Error::from_selinux(op_key, r))?; } } Ok(osc) @@ -390,11 +394,15 @@ fn execute_command(command: &OsStr, arguments: &[OsString]) -> UResult<()> { error_exit_status::COULD_NOT_EXECUTE }; - let err = Error::from_io1("Executing command", command, err); + let err = Error::from_io1("runcon-operation-executing-command", command, err); Err(RunconError::with_code(exit_status, err).into()) } fn os_str_to_c_string(s: &OsStr) -> Result { - CString::new(s.as_bytes()) - .map_err(|_r| Error::from_io("CString::new()", io::ErrorKind::InvalidInput.into())) + CString::new(s.as_bytes()).map_err(|_r| { + Error::from_io( + "runcon-operation-cstring-new", + io::ErrorKind::InvalidInput.into(), + ) + }) }