Skip to content

Commit

Permalink
refactor(core): load APPIMAGE and APPDIR env vars on startup [TRI-007…
Browse files Browse the repository at this point in the history
…] [TRI-041]
  • Loading branch information
lucasfernog committed Jan 9, 2022
1 parent 4de285c commit 7209fdf
Show file tree
Hide file tree
Showing 16 changed files with 193 additions and 100 deletions.
5 changes: 5 additions & 0 deletions .changes/core-env.md
@@ -0,0 +1,5 @@
---
"tauri": patch
---

The `process`, `path` and `updater` APIs now takes a `tauri::Env` argument, used to force environment variables load on startup to prevent env var update attacks.
22 changes: 22 additions & 0 deletions core/tauri-utils/src/lib.rs
Expand Up @@ -37,6 +37,28 @@ impl PackageInfo {
}
}

/// Information about environment variables.
#[derive(Debug, Clone)]
pub struct Env {
/// The APPIMAGE environment variable.
#[cfg(target_os = "linux")]
pub appimage: Option<std::ffi::OsString>,
/// The APPDIR environment variable.
#[cfg(target_os = "linux")]
pub appdir: Option<std::ffi::OsString>,
}

impl Default for Env {
fn default() -> Self {
Self {
#[cfg(target_os = "linux")]
appimage: std::env::var_os("APPIMAGE"),
#[cfg(target_os = "linux")]
appdir: std::env::var_os("APPDIR"),
}
}
}

/// The result type of `tauri-utils`.
pub type Result<T> = std::result::Result<T, Error>;

Expand Down
14 changes: 6 additions & 8 deletions core/tauri-utils/src/platform.rs
Expand Up @@ -4,12 +4,9 @@

//! Platform helper functions.

use std::{
env,
path::{PathBuf, MAIN_SEPARATOR},
};
use std::path::{PathBuf, MAIN_SEPARATOR};

use crate::PackageInfo;
use crate::{Env, PackageInfo};

/// Try to determine the current target triple.
///
Expand Down Expand Up @@ -76,7 +73,7 @@ pub fn target_triple() -> crate::Result<String> {
/// `${exe_dir}/../lib/${exe_name}`.
///
/// On MacOS, it's `${exe_dir}../Resources` (inside .app).
pub fn resource_dir(package_info: &PackageInfo) -> crate::Result<PathBuf> {
pub fn resource_dir(package_info: &PackageInfo, env: &Env) -> crate::Result<PathBuf> {
let exe = std::env::current_exe()?;
let exe_dir = exe.parent().expect("failed to get exe directory");
let curr_dir = exe_dir.display().to_string();
Expand All @@ -93,10 +90,11 @@ pub fn resource_dir(package_info: &PackageInfo) -> crate::Result<PathBuf> {
if curr_dir.ends_with("/data/usr/bin") {
// running from the deb bundle dir
Ok(exe_dir.join(format!("../lib/{}", package_info.package_name())))
} else if let Ok(appdir) = env::var("APPDIR") {
} else if let Some(appdir) = &env.appdir {
let appdir: &std::path::Path = appdir.as_ref();
Ok(PathBuf::from(format!(
"{}/usr/lib/{}",
appdir,
appdir.display(),
package_info.package_name()
)))
} else {
Expand Down
10 changes: 6 additions & 4 deletions core/tauri/src/api/path.rs
Expand Up @@ -9,7 +9,7 @@ use std::{
path::{Component, Path, PathBuf},
};

use crate::{Config, PackageInfo};
use crate::{Config, Env, PackageInfo};

use serde_repr::{Deserialize_repr, Serialize_repr};

Expand Down Expand Up @@ -83,6 +83,7 @@ pub enum BaseDirectory {
/// authors: "tauri",
/// description: "a tauri test",
/// },
/// &Default::default(),
/// "path/to/something",
/// Some(BaseDirectory::Config)
/// ).expect("failed to resolve path");
Expand All @@ -91,6 +92,7 @@ pub enum BaseDirectory {
pub fn resolve_path<P: AsRef<Path>>(
config: &Config,
package_info: &PackageInfo,
env: &Env,
path: P,
dir: Option<BaseDirectory>,
) -> crate::api::Result<PathBuf> {
Expand All @@ -113,7 +115,7 @@ pub fn resolve_path<P: AsRef<Path>>(
BaseDirectory::Runtime => runtime_dir(),
BaseDirectory::Template => template_dir(),
BaseDirectory::Video => video_dir(),
BaseDirectory::Resource => resource_dir(package_info),
BaseDirectory::Resource => resource_dir(package_info, env),
BaseDirectory::App => app_dir(config),
BaseDirectory::Current => Some(env::current_dir()?),
BaseDirectory::Log => log_dir(config),
Expand Down Expand Up @@ -229,8 +231,8 @@ pub fn video_dir() -> Option<PathBuf> {
}

/// Returns the path to the resource directory of this app.
pub fn resource_dir(package_info: &PackageInfo) -> Option<PathBuf> {
crate::utils::platform::resource_dir(package_info).ok()
pub fn resource_dir(package_info: &PackageInfo, env: &Env) -> Option<PathBuf> {
crate::utils::platform::resource_dir(package_info, env).ok()
}

/// Returns the path to the suggested directory for your app config files.
Expand Down
11 changes: 7 additions & 4 deletions core/tauri/src/api/process.rs
Expand Up @@ -4,6 +4,8 @@

//! Types and functions related to child processes management.

use crate::Env;

use std::{
env,
path::PathBuf,
Expand All @@ -16,12 +18,13 @@ mod command;
pub use command::*;

/// Gets the current binary.
pub fn current_binary() -> Option<PathBuf> {
#[allow(unused_variables)]
pub fn current_binary(env: &Env) -> Option<PathBuf> {
let mut current_binary = None;

// if we are running with an APP Image, we should return the app image path
#[cfg(target_os = "linux")]
if let Some(app_image_path) = env::var_os("APPIMAGE") {
if let Some(app_image_path) = &env.appimage {
current_binary = Some(PathBuf::from(app_image_path));
}

Expand All @@ -37,8 +40,8 @@ pub fn current_binary() -> Option<PathBuf> {
}

/// Restarts the process.
pub fn restart() {
if let Some(path) = current_binary() {
pub fn restart(env: &Env) {
if let Some(path) = current_binary(env) {
StdCommand::new(path)
.spawn()
.expect("application failed to start");
Expand Down
13 changes: 11 additions & 2 deletions core/tauri/src/app.rs
Expand Up @@ -19,8 +19,8 @@ use crate::{
Dispatch, ExitRequestedEventAction, RunEvent, Runtime,
},
sealed::{ManagerBase, RuntimeOrDispatch},
utils::assets::Assets,
utils::config::{Config, WindowUrl},
utils::{assets::Assets, Env},
Context, Invoke, InvokeError, InvokeResponse, Manager, StateManager, Window,
};

Expand Down Expand Up @@ -150,14 +150,15 @@ impl<R: Runtime> GlobalWindowEvent<R> {
/// The path resolver is a helper for the application-specific [`crate::api::path`] APIs.
#[derive(Debug, Clone)]
pub struct PathResolver {
env: Env,
config: Arc<Config>,
package_info: PackageInfo,
}

impl PathResolver {
/// Returns the path to the resource directory of this app.
pub fn resource_dir(&self) -> Option<PathBuf> {
crate::api::path::resource_dir(&self.package_info)
crate::api::path::resource_dir(&self.package_info, &self.env)
}

/// Returns the path to the suggested directory for your app config files.
Expand Down Expand Up @@ -407,6 +408,7 @@ macro_rules! shared_app_impl {
/// The path resolver for the application.
pub fn path_resolver(&self) -> PathResolver {
PathResolver {
env: self.state::<Env>().inner().clone(),
config: self.manager.config(),
package_info: self.manager.package_info().clone(),
}
Expand All @@ -432,6 +434,11 @@ macro_rules! shared_app_impl {
self.manager.package_info()
}

/// Gets the managed [`Env`].
pub fn env(&self) -> Env {
self.state::<Env>().inner().clone()
}

/// The application's asset resolver.
pub fn asset_resolver(&self) -> AssetResolver<R> {
AssetResolver {
Expand Down Expand Up @@ -990,6 +997,8 @@ impl<R: Runtime> Builder<R> {
},
};

app.manage(Env::default());

#[cfg(feature = "system-tray")]
if let Some(system_tray) = self.system_tray {
let mut ids = HashMap::new();
Expand Down
12 changes: 8 additions & 4 deletions core/tauri/src/endpoints.rs
Expand Up @@ -75,17 +75,21 @@ impl Module {
.and_then(|r| r.json)
.map_err(InvokeError::from)
}),
Self::Process(cmd) => resolver
.respond_async(async move { cmd.run().and_then(|r| r.json).map_err(InvokeError::from) }),
Self::Process(cmd) => resolver.respond_async(async move {
cmd
.run(window)
.and_then(|r| r.json)
.map_err(InvokeError::from)
}),
Self::Fs(cmd) => resolver.respond_async(async move {
cmd
.run(config, &package_info)
.run(window, config, &package_info)
.and_then(|r| r.json)
.map_err(InvokeError::from)
}),
Self::Path(cmd) => resolver.respond_async(async move {
cmd
.run(config, &package_info)
.run(window, config, &package_info)
.and_then(|r| r.json)
.map_err(InvokeError::from)
}),
Expand Down

0 comments on commit 7209fdf

Please sign in to comment.