allow embassy-cli not as root (#1501)

* allow embassy-cli not as root
* clean up merge
This commit is contained in:
Aiden McClelland
2022-06-07 11:11:01 -06:00
committed by GitHub
parent 334437f677
commit 4286edd78f
22 changed files with 242 additions and 89 deletions

92
backend/Cargo.lock generated
View File

@@ -197,9 +197,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]] [[package]]
name = "base64ct" name = "base64ct"
version = "1.0.1" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179"
[[package]] [[package]]
name = "basic-cookies" name = "basic-cookies"
@@ -530,6 +530,12 @@ dependencies = [
"tracing-error", "tracing-error",
] ]
[[package]]
name = "const-oid"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661"
[[package]] [[package]]
name = "const_fn" name = "const_fn"
version = "0.4.9" version = "0.4.9"
@@ -694,9 +700,9 @@ dependencies = [
[[package]] [[package]]
name = "curve25519-dalek" name = "curve25519-dalek"
version = "3.2.1" version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"digest 0.9.0", "digest 0.9.0",
@@ -856,6 +862,17 @@ dependencies = [
"syn 1.0.96", "syn 1.0.96",
] ]
[[package]]
name = "der"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f"
dependencies = [
"const-oid",
"pem-rfc7468",
"zeroize",
]
[[package]] [[package]]
name = "derive_more" name = "derive_more"
version = "0.99.17" version = "0.99.17"
@@ -892,6 +909,7 @@ checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
dependencies = [ dependencies = [
"block-buffer 0.10.2", "block-buffer 0.10.2",
"crypto-common", "crypto-common",
"subtle",
] ]
[[package]] [[package]]
@@ -965,6 +983,7 @@ version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369"
dependencies = [ dependencies = [
"pkcs8",
"serde", "serde",
"signature", "signature",
] ]
@@ -1002,6 +1021,7 @@ dependencies = [
"avahi-sys", "avahi-sys",
"base32", "base32",
"base64 0.13.0", "base64 0.13.0",
"base64ct",
"basic-cookies", "basic-cookies",
"bollard", "bollard",
"chrono", "chrono",
@@ -1009,8 +1029,10 @@ dependencies = [
"clap", "clap",
"color-eyre", "color-eyre",
"cookie_store", "cookie_store",
"digest 0.10.3",
"digest 0.9.0", "digest 0.9.0",
"divrem", "divrem",
"ed25519",
"ed25519-dalek", "ed25519-dalek",
"emver", "emver",
"fd-lock-rs", "fd-lock-rs",
@@ -1018,7 +1040,7 @@ dependencies = [
"git-version", "git-version",
"helpers", "helpers",
"hex", "hex",
"hmac", "hmac 0.12.1",
"http", "http",
"hyper", "hyper",
"hyper-ws-listener", "hyper-ws-listener",
@@ -1041,6 +1063,7 @@ dependencies = [
"patch-db", "patch-db",
"pbkdf2", "pbkdf2",
"pin-project", "pin-project",
"pkcs8",
"platforms", "platforms",
"prettytable-rs", "prettytable-rs",
"proptest", "proptest",
@@ -1057,6 +1080,7 @@ dependencies = [
"serde_json", "serde_json",
"serde_with", "serde_with",
"serde_yaml", "serde_yaml",
"sha2 0.10.2",
"sha2 0.9.9", "sha2 0.9.9",
"simple-logging", "simple-logging",
"sqlx", "sqlx",
@@ -1552,6 +1576,15 @@ dependencies = [
"digest 0.9.0", "digest 0.9.0",
] ]
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest 0.10.3",
]
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.7" version = "0.2.7"
@@ -2502,9 +2535,9 @@ dependencies = [
[[package]] [[package]]
name = "password-hash" name = "password-hash"
version = "0.3.2" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" checksum = "e029e94abc8fb0065241c308f1ac6bc8d20f450e8f7c5f0b25cd9b8d526ba294"
dependencies = [ dependencies = [
"base64ct", "base64ct",
"rand_core 0.6.3", "rand_core 0.6.3",
@@ -2560,14 +2593,14 @@ dependencies = [
[[package]] [[package]]
name = "pbkdf2" name = "pbkdf2"
version = "0.9.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
dependencies = [ dependencies = [
"crypto-mac", "digest 0.10.3",
"hmac", "hmac 0.12.1",
"password-hash", "password-hash",
"sha2 0.9.9", "sha2 0.10.2",
] ]
[[package]] [[package]]
@@ -2576,6 +2609,15 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pem-rfc7468"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac"
dependencies = [
"base64ct",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.1.0" version = "2.1.0"
@@ -2680,6 +2722,16 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs8"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba"
dependencies = [
"der",
"spki",
]
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.25" version = "0.3.25"
@@ -3583,6 +3635,16 @@ dependencies = [
"lock_api", "lock_api",
] ]
[[package]]
name = "spki"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b"
dependencies = [
"base64ct",
"der",
]
[[package]] [[package]]
name = "sqlformat" name = "sqlformat"
version = "0.1.8" version = "0.1.8"
@@ -4584,7 +4646,7 @@ dependencies = [
"derive_more", "derive_more",
"ed25519-dalek", "ed25519-dalek",
"hex", "hex",
"hmac", "hmac 0.11.0",
"rand 0.7.3", "rand 0.7.3",
"serde", "serde",
"serde_derive", "serde_derive",
@@ -5152,9 +5214,9 @@ dependencies = [
[[package]] [[package]]
name = "zeroize" name = "zeroize"
version = "1.3.0" version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07"
dependencies = [ dependencies = [
"zeroize_derive", "zeroize_derive",
] ]

View File

@@ -53,21 +53,25 @@ avahi-sys = { git = "https://github.com/Start9Labs/avahi-sys", version = "0.10.0
], optional = true } ], optional = true }
base32 = "0.4.0" base32 = "0.4.0"
base64 = "0.13.0" base64 = "0.13.0"
base64ct = "1.5.0"
basic-cookies = "0.1.4" basic-cookies = "0.1.4"
bollard = "0.11.0" bollard = "0.11.0"
chrono = { version = "0.4.19", features = ["serde"] } chrono = { version = "0.4.19", features = ["serde"] }
clap = "2.33" clap = "2.33"
color-eyre = "0.5" color-eyre = "0.5"
cookie_store = "0.15.0" cookie_store = "0.15.0"
digest = "0.9.0" digest = "0.10.3"
digest-old = { package = "digest", version = "0.9.0" }
divrem = "1.0.0" divrem = "1.0.0"
ed25519 = { version = "1.5.2", features = ["pkcs8", "pem", "alloc"] }
ed25519-dalek = { version = "1.0.1", features = ["serde"] } ed25519-dalek = { version = "1.0.1", features = ["serde"] }
emver = { version = "0.1.6", features = ["serde"] } emver = { version = "0.1.6", features = ["serde"] }
fd-lock-rs = "0.1.3" fd-lock-rs = "0.1.3"
futures = "0.3.17" futures = "0.3.17"
git-version = "0.3.5" git-version = "0.3.5"
helpers = { path = "../libs/helpers" }
hex = "0.4.3" hex = "0.4.3"
hmac = "0.11.0" hmac = "0.12.1"
http = "0.2.5" http = "0.2.5"
hyper = "0.14.13" hyper = "0.14.13"
hyper-ws-listener = { git = "https://github.com/Start9Labs/hyper-ws-listener.git", branch = "main" } hyper-ws-listener = { git = "https://github.com/Start9Labs/hyper-ws-listener.git", branch = "main" }
@@ -75,24 +79,24 @@ imbl = "1.0.1"
indexmap = { version = "1.8.1", features = ["serde"] } indexmap = { version = "1.8.1", features = ["serde"] }
isocountry = "0.3.2" isocountry = "0.3.2"
itertools = "0.10.1" itertools = "0.10.1"
js_engine = { path = '../libs/js_engine', optional = true }
jsonpath_lib = "0.3.0" jsonpath_lib = "0.3.0"
lazy_static = "1.4" lazy_static = "1.4"
libc = "0.2.103" libc = "0.2.103"
log = "0.4.14" log = "0.4.14"
models = { version = "*", path = "../libs/models" }
nix = "0.23.0" nix = "0.23.0"
nom = "7.0.0" nom = "7.0.0"
helpers = {path = "../libs/helpers"}
num = "0.4.0" num = "0.4.0"
num_enum = "0.5.4" num_enum = "0.5.4"
models = {version = "*", path = "../libs/models"}
js_engine = {path = '../libs/js_engine', optional = true}
openssh-keys = "0.5.0" openssh-keys = "0.5.0"
openssl = { version = "0.10.36", features = ["vendored"] } openssl = { version = "0.10.36", features = ["vendored"] }
patch-db = { version = "*", path = "../patch-db/patch-db", features = [ patch-db = { version = "*", path = "../patch-db/patch-db", features = [
"trace", "trace",
] } ] }
pbkdf2 = "0.9.0" pbkdf2 = "0.11.0"
pin-project = "1.0.8" pin-project = "1.0.8"
pkcs8 = { version = "0.9.0", features = ["std"] }
platforms = "1.1.0" platforms = "1.1.0"
prettytable-rs = "0.8.0" prettytable-rs = "0.8.0"
proptest = "1.0.0" proptest = "1.0.0"
@@ -110,7 +114,8 @@ serde_cbor = { package = "ciborium", version = "0.2.0" }
serde_json = "1.0.68" serde_json = "1.0.68"
serde_toml = { package = "toml", version = "0.5.8" } serde_toml = { package = "toml", version = "0.5.8" }
serde_yaml = "0.8.21" serde_yaml = "0.8.21"
sha2 = "0.9.8" sha2 = "0.10.2"
sha2-old = { package = "sha2", version = "0.9.8" }
simple-logging = "2.0" simple-logging = "2.0"
sqlx = { version = "0.5.11", features = [ sqlx = { version = "0.5.11", features = [
"chrono", "chrono",

View File

@@ -8,4 +8,4 @@ if [ "$0" != "./install-sdk.sh" ]; then
exit 1 exit 1
fi fi
cargo install --bin=embassy-sdk --path=. --no-default-features --features=js_engine cargo install --bin=embassy-sdk --bin=embassy-cli --path=. --no-default-features --features=js_engine

View File

@@ -6,7 +6,7 @@ use chrono::{DateTime, Utc};
use clap::ArgMatches; use clap::ArgMatches;
use color_eyre::eyre::eyre; use color_eyre::eyre::eyre;
use digest::generic_array::GenericArray; use digest::generic_array::GenericArray;
use digest::Digest; use digest::{Digest, OutputSizeUser};
use rpc_toolkit::command; use rpc_toolkit::command;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
@@ -119,7 +119,9 @@ impl FileSystem for BackupTargetFS {
BackupTargetFS::Cifs(a) => a.mount(mountpoint, mount_type).await, BackupTargetFS::Cifs(a) => a.mount(mountpoint, mount_type).await,
} }
} }
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> { async fn source_hash(
&self,
) -> Result<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>, Error> {
match self { match self {
BackupTargetFS::Disk(a) => a.source_hash().await, BackupTargetFS::Disk(a) => a.source_hash().await,
BackupTargetFS::Cifs(a) => a.source_hash().await, BackupTargetFS::Cifs(a) => a.source_hash().await,

View File

@@ -15,6 +15,7 @@ use rpc_toolkit::Context;
use serde::Deserialize; use serde::Deserialize;
use tracing::instrument; use tracing::instrument;
use crate::util::config::{load_config_from_paths, local_config_path};
use crate::ResultExt; use crate::ResultExt;
#[derive(Debug, Default, Deserialize)] #[derive(Debug, Default, Deserialize)]
@@ -60,16 +61,16 @@ impl CliContext {
/// BLOCKING /// BLOCKING
#[instrument(skip(matches))] #[instrument(skip(matches))]
pub fn init(matches: &ArgMatches) -> Result<Self, crate::Error> { pub fn init(matches: &ArgMatches) -> Result<Self, crate::Error> {
let cfg_path = Path::new(matches.value_of("config").unwrap_or(crate::CONFIG_PATH)); let local_config_path = local_config_path();
let base = if cfg_path.exists() { let base: CliContextConfig = load_config_from_paths(
serde_yaml::from_reader( matches
File::open(cfg_path) .values_of("config")
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?, .into_iter()
) .flatten()
.with_kind(crate::ErrorKind::Deserialization)? .map(|p| Path::new(p))
} else { .chain(local_config_path.as_deref().into_iter())
CliContextConfig::default() .chain(std::iter::once(Path::new(crate::util::config::CONFIG_PATH))),
}; )?;
let mut url = if let Some(host) = matches.value_of("host") { let mut url = if let Some(host) = matches.value_of("host") {
host.parse()? host.parse()?
} else if let Some(host) = base.host { } else if let Some(host) = base.host {
@@ -88,7 +89,9 @@ impl CliContext {
}; };
let cookie_path = base.cookie_path.unwrap_or_else(|| { let cookie_path = base.cookie_path.unwrap_or_else(|| {
cfg_path local_config_path
.as_deref()
.unwrap_or_else(|| Path::new(crate::util::config::CONFIG_PATH))
.parent() .parent()
.unwrap_or(Path::new("/")) .unwrap_or(Path::new("/"))
.join(".cookies.json") .join(".cookies.json")

View File

@@ -28,7 +28,7 @@ impl DiagnosticContextConfig {
let cfg_path = path let cfg_path = path
.as_ref() .as_ref()
.map(|p| p.as_ref()) .map(|p| p.as_ref())
.unwrap_or(Path::new(crate::CONFIG_PATH)); .unwrap_or(Path::new(crate::util::config::CONFIG_PATH));
if let Some(f) = File::maybe_open(cfg_path) if let Some(f) = File::maybe_open(cfg_path)
.await .await
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))? .with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?

View File

@@ -7,8 +7,8 @@ use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use bollard::Docker; use bollard::Docker;
use patch_db::{json_ptr::JsonPointer, LockReceipt}; use patch_db::json_ptr::JsonPointer;
use patch_db::{DbHandle, LockType, PatchDb, Revision}; use patch_db::{DbHandle, LockReceipt, LockType, PatchDb, Revision};
use reqwest::Url; use reqwest::Url;
use rpc_toolkit::url::Host; use rpc_toolkit::url::Host;
use rpc_toolkit::Context; use rpc_toolkit::Context;
@@ -20,9 +20,10 @@ use tokio::process::Command;
use tokio::sync::{broadcast, oneshot, Mutex, RwLock}; use tokio::sync::{broadcast, oneshot, Mutex, RwLock};
use tracing::instrument; use tracing::instrument;
use crate::core::rpc_continuations::{RequestGuid, RpcContinuation};
use crate::db::model::{Database, InstalledPackageDataEntry, PackageDataEntry}; use crate::db::model::{Database, InstalledPackageDataEntry, PackageDataEntry};
use crate::hostname::{derive_hostname, derive_id, get_product_key}; use crate::hostname::{derive_hostname, derive_id, get_product_key};
use crate::install::cleanup::{cleanup_failed, uninstall}; use crate::install::cleanup::{cleanup_failed, uninstall, CleanupFailedReceipts};
use crate::manager::ManagerMap; use crate::manager::ManagerMap;
use crate::middleware::auth::HashSessionToken; use crate::middleware::auth::HashSessionToken;
use crate::net::tor::os_key; use crate::net::tor::os_key;
@@ -34,10 +35,6 @@ use crate::shutdown::Shutdown;
use crate::status::{MainStatus, Status}; use crate::status::{MainStatus, Status};
use crate::util::io::from_yaml_async_reader; use crate::util::io::from_yaml_async_reader;
use crate::util::{AsyncFileExt, Invoke}; use crate::util::{AsyncFileExt, Invoke};
use crate::{
core::rpc_continuations::{RequestGuid, RpcContinuation},
install::cleanup::CleanupFailedReceipts,
};
use crate::{Error, ResultExt}; use crate::{Error, ResultExt};
#[derive(Debug, Default, Deserialize)] #[derive(Debug, Default, Deserialize)]
@@ -57,7 +54,7 @@ impl RpcContextConfig {
let cfg_path = path let cfg_path = path
.as_ref() .as_ref()
.map(|p| p.as_ref()) .map(|p| p.as_ref())
.unwrap_or(Path::new(crate::CONFIG_PATH)); .unwrap_or(Path::new(crate::util::config::CONFIG_PATH));
if let Some(f) = File::maybe_open(cfg_path) if let Some(f) = File::maybe_open(cfg_path)
.await .await
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))? .with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?

View File

@@ -1,5 +1,3 @@
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::Arc; use std::sync::Arc;
@@ -9,6 +7,7 @@ use rpc_toolkit::Context;
use serde::Deserialize; use serde::Deserialize;
use tracing::instrument; use tracing::instrument;
use crate::util::config::{load_config_from_paths, local_config_path};
use crate::{Error, ResultExt}; use crate::{Error, ResultExt};
#[derive(Debug, Default, Deserialize)] #[derive(Debug, Default, Deserialize)]
@@ -28,22 +27,24 @@ impl SdkContext {
/// BLOCKING /// BLOCKING
#[instrument(skip(matches))] #[instrument(skip(matches))]
pub fn init(matches: &ArgMatches) -> Result<Self, crate::Error> { pub fn init(matches: &ArgMatches) -> Result<Self, crate::Error> {
let cfg_path = Path::new(matches.value_of("config").unwrap_or(crate::CONFIG_PATH)); let local_config_path = local_config_path();
let base = if cfg_path.exists() { let base: SdkContextConfig = load_config_from_paths(
serde_yaml::from_reader( matches
File::open(cfg_path) .values_of("config")
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?, .into_iter()
) .flatten()
.with_kind(crate::ErrorKind::Deserialization)? .map(|p| Path::new(p))
} else { .chain(local_config_path.as_deref().into_iter())
SdkContextConfig::default() .chain(std::iter::once(Path::new(crate::util::config::CONFIG_PATH))),
}; )?;
Ok(SdkContext(Arc::new(SdkContextSeed { Ok(SdkContext(Arc::new(SdkContextSeed {
developer_key_path: base.developer_key_path.unwrap_or_else(|| { developer_key_path: base.developer_key_path.unwrap_or_else(|| {
cfg_path local_config_path
.as_deref()
.unwrap_or_else(|| Path::new(crate::util::config::CONFIG_PATH))
.parent() .parent()
.unwrap_or(Path::new("/")) .unwrap_or(Path::new("/"))
.join(".developer_key") .join("developer.key.pem")
}), }),
}))) })))
} }
@@ -53,9 +54,17 @@ impl SdkContext {
if !self.developer_key_path.exists() { if !self.developer_key_path.exists() {
return Err(Error::new(eyre!("Developer Key does not exist! Please run `embassy-sdk init` before running this command."), crate::ErrorKind::Uninitialized)); return Err(Error::new(eyre!("Developer Key does not exist! Please run `embassy-sdk init` before running this command."), crate::ErrorKind::Uninitialized));
} }
let mut keypair_buf = [0; ed25519_dalek::KEYPAIR_LENGTH]; let pair = <ed25519::KeypairBytes as ed25519::pkcs8::DecodePrivateKey>::from_pkcs8_pem(
File::open(&self.developer_key_path)?.read_exact(&mut keypair_buf)?; &std::fs::read_to_string(&self.developer_key_path)?,
Ok(ed25519_dalek::Keypair::from_bytes(&keypair_buf)?) )
.with_kind(crate::ErrorKind::Pem)?;
let secret = ed25519_dalek::SecretKey::from_bytes(&pair.secret_key[..])?;
let public = if let Some(public) = pair.public_key {
ed25519_dalek::PublicKey::from_bytes(&public[..])?
} else {
(&secret).into()
};
Ok(ed25519_dalek::Keypair { secret, public })
} }
} }
impl std::ops::Deref for SdkContext { impl std::ops::Deref for SdkContext {

View File

@@ -45,7 +45,7 @@ impl SetupContextConfig {
let cfg_path = path let cfg_path = path
.as_ref() .as_ref()
.map(|p| p.as_ref()) .map(|p| p.as_ref())
.unwrap_or(Path::new(crate::CONFIG_PATH)); .unwrap_or(Path::new(crate::util::config::CONFIG_PATH));
if let Some(f) = File::maybe_open(cfg_path) if let Some(f) = File::maybe_open(cfg_path)
.await .await
.with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))? .with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))?

View File

@@ -2,6 +2,7 @@ use std::fs::File;
use std::io::Write; use std::io::Write;
use std::path::Path; use std::path::Path;
use ed25519::pkcs8::EncodePrivateKey;
use ed25519_dalek::Keypair; use ed25519_dalek::Keypair;
use rpc_toolkit::command; use rpc_toolkit::command;
use tracing::instrument; use tracing::instrument;
@@ -22,8 +23,17 @@ pub fn init(#[context] ctx: SdkContext) -> Result<(), Error> {
tracing::info!("Generating new developer key..."); tracing::info!("Generating new developer key...");
let keypair = Keypair::generate(&mut rand::thread_rng()); let keypair = Keypair::generate(&mut rand::thread_rng());
tracing::info!("Writing key to {}", ctx.developer_key_path.display()); tracing::info!("Writing key to {}", ctx.developer_key_path.display());
let keypair_bytes = ed25519::KeypairBytes {
secret_key: keypair.secret.to_bytes(),
public_key: Some(keypair.public.to_bytes()),
};
let mut dev_key_file = File::create(&ctx.developer_key_path)?; let mut dev_key_file = File::create(&ctx.developer_key_path)?;
dev_key_file.write_all(&keypair.to_bytes())?; dev_key_file.write_all(
keypair_bytes
.to_pkcs8_pem(base64ct::LineEnding::default())
.with_kind(crate::ErrorKind::Pem)?
.as_bytes(),
)?;
dev_key_file.sync_all()?; dev_key_file.sync_all()?;
} }
Ok(()) Ok(())

View File

@@ -3,7 +3,7 @@ use std::path::Path;
use async_trait::async_trait; use async_trait::async_trait;
use digest::generic_array::GenericArray; use digest::generic_array::GenericArray;
use digest::Digest; use digest::{Digest, OutputSizeUser};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
@@ -45,7 +45,9 @@ impl<LogicalName: AsRef<Path> + Send + Sync> FileSystem for BlockDev<LogicalName
) -> Result<(), Error> { ) -> Result<(), Error> {
mount(self.logicalname.as_ref(), mountpoint, mount_type).await mount(self.logicalname.as_ref(), mountpoint, mount_type).await
} }
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> { async fn source_hash(
&self,
) -> Result<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>, Error> {
let mut sha = Sha256::new(); let mut sha = Sha256::new();
sha.update("BlockDev"); sha.update("BlockDev");
sha.update( sha.update(

View File

@@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
use async_trait::async_trait; use async_trait::async_trait;
use digest::generic_array::GenericArray; use digest::generic_array::GenericArray;
use digest::Digest; use digest::{Digest, OutputSizeUser};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
use tokio::process::Command; use tokio::process::Command;
@@ -93,7 +93,9 @@ impl FileSystem for Cifs {
) )
.await .await
} }
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> { async fn source_hash(
&self,
) -> Result<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>, Error> {
let mut sha = Sha256::new(); let mut sha = Sha256::new();
sha.update("Cifs"); sha.update("Cifs");
sha.update(self.hostname.as_bytes()); sha.update(self.hostname.as_bytes());

View File

@@ -4,7 +4,7 @@ use std::path::Path;
use async_trait::async_trait; use async_trait::async_trait;
use color_eyre::eyre::eyre; use color_eyre::eyre::eyre;
use digest::generic_array::GenericArray; use digest::generic_array::GenericArray;
use digest::Digest; use digest::{Digest, OutputSizeUser};
use sha2::Sha256; use sha2::Sha256;
use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::io::{AsyncReadExt, AsyncWriteExt};
@@ -63,7 +63,9 @@ impl<EncryptedDir: AsRef<Path> + Send + Sync, Key: AsRef<str> + Send + Sync> Fil
) -> Result<(), Error> { ) -> Result<(), Error> {
mount_ecryptfs(self.encrypted_dir.as_ref(), mountpoint, self.key.as_ref()).await mount_ecryptfs(self.encrypted_dir.as_ref(), mountpoint, self.key.as_ref()).await
} }
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> { async fn source_hash(
&self,
) -> Result<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>, Error> {
let mut sha = Sha256::new(); let mut sha = Sha256::new();
sha.update("EcryptFS"); sha.update("EcryptFS");
sha.update( sha.update(

View File

@@ -2,7 +2,7 @@ use std::path::Path;
use async_trait::async_trait; use async_trait::async_trait;
use digest::generic_array::GenericArray; use digest::generic_array::GenericArray;
use digest::Digest; use digest::{Digest, OutputSizeUser};
use sha2::Sha256; use sha2::Sha256;
use super::{FileSystem, MountType, ReadOnly}; use super::{FileSystem, MountType, ReadOnly};
@@ -41,7 +41,9 @@ impl<S: AsRef<str> + Send + Sync> FileSystem for Label<S> {
) -> Result<(), Error> { ) -> Result<(), Error> {
mount_label(self.label.as_ref(), mountpoint, mount_type).await mount_label(self.label.as_ref(), mountpoint, mount_type).await
} }
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> { async fn source_hash(
&self,
) -> Result<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>, Error> {
let mut sha = Sha256::new(); let mut sha = Sha256::new();
sha.update("Label"); sha.update("Label");
sha.update(self.label.as_ref().as_bytes()); sha.update(self.label.as_ref().as_bytes());

View File

@@ -2,7 +2,7 @@ use std::path::Path;
use async_trait::async_trait; use async_trait::async_trait;
use digest::generic_array::GenericArray; use digest::generic_array::GenericArray;
use digest::Digest; use digest::{Digest, OutputSizeUser};
use sha2::Sha256; use sha2::Sha256;
use crate::Error; use crate::Error;
@@ -27,5 +27,7 @@ pub trait FileSystem {
mountpoint: P, mountpoint: P,
mount_type: MountType, mount_type: MountType,
) -> Result<(), Error>; ) -> Result<(), Error>;
async fn source_hash(&self) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error>; async fn source_hash(
&self,
) -> Result<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>, Error>;
} }

View File

@@ -31,7 +31,7 @@ pub enum ErrorKind {
InvalidOnionAddress = 22, InvalidOnionAddress = 22,
Pack = 23, Pack = 23,
ValidateS9pk = 24, ValidateS9pk = 24,
DiskCorrupted = 25, DiskCorrupted = 25, // Remove
Tor = 26, Tor = 26,
ConfigGen = 27, ConfigGen = 27,
ParseNumber = 28, ParseNumber = 28,
@@ -66,6 +66,7 @@ pub enum ErrorKind {
ProductKeyMismatch = 57, ProductKeyMismatch = 57,
LanPortConflict = 58, LanPortConflict = 58,
Javascript = 59, Javascript = 59,
Pem = 60,
} }
impl ErrorKind { impl ErrorKind {
pub fn as_str(&self) -> &'static str { pub fn as_str(&self) -> &'static str {
@@ -128,8 +129,9 @@ impl ErrorKind {
Incoherent => "Incoherent", Incoherent => "Incoherent",
InvalidBackupTargetId => "Invalid Backup Target ID", InvalidBackupTargetId => "Invalid Backup Target ID",
ProductKeyMismatch => "Incompatible Product Keys", ProductKeyMismatch => "Incompatible Product Keys",
LanPortConflict => "Incompatible LAN port configuration", LanPortConflict => "Incompatible LAN Port Configuration",
Javascript => "Javascript engine error", Javascript => "Javascript Engine Error",
Pem => "PEM Encoding Error",
} }
} }
} }

View File

@@ -1,4 +1,3 @@
pub const CONFIG_PATH: &str = "/etc/embassy/config.yaml";
#[cfg(not(feature = "beta"))] #[cfg(not(feature = "beta"))]
pub const DEFAULT_MARKETPLACE: &str = "https://marketplace.start9.com"; pub const DEFAULT_MARKETPLACE: &str = "https://marketplace.start9.com";
#[cfg(feature = "beta")] #[cfg(feature = "beta")]

View File

@@ -1,5 +1,4 @@
use digest::Digest; use sha2_old::{Digest, Sha512};
use sha2::Sha512;
use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt, SeekFrom}; use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt, SeekFrom};
use tracing::instrument; use tracing::instrument;
use typed_builder::TypedBuilder; use typed_builder::TypedBuilder;

View File

@@ -6,10 +6,10 @@ use std::str::FromStr;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use color_eyre::eyre::eyre; use color_eyre::eyre::eyre;
use digest::Output; use digest_old::Output;
use ed25519_dalek::PublicKey; use ed25519_dalek::PublicKey;
use futures::TryStreamExt; use futures::TryStreamExt;
use sha2::{Digest, Sha512}; use sha2_old::{Digest, Sha512};
use tokio::fs::File; use tokio::fs::File;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, ReadBuf, Take}; use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, ReadBuf, Take};
use tracing::instrument; use tracing::instrument;

View File

@@ -7,6 +7,7 @@ use std::time::Duration;
use color_eyre::eyre::eyre; use color_eyre::eyre::eyre;
use digest::generic_array::GenericArray; use digest::generic_array::GenericArray;
use digest::OutputSizeUser;
use futures::future::BoxFuture; use futures::future::BoxFuture;
use futures::{FutureExt, TryFutureExt, TryStreamExt}; use futures::{FutureExt, TryFutureExt, TryStreamExt};
use nix::unistd::{Gid, Uid}; use nix::unistd::{Gid, Uid};
@@ -477,7 +478,7 @@ async fn recover(
async fn shasum( async fn shasum(
path: impl AsRef<Path>, path: impl AsRef<Path>,
) -> Result<GenericArray<u8, <Sha256 as Digest>::OutputSize>, Error> { ) -> Result<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>, Error> {
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
let mut rdr = tokio::fs::File::open(path).await?; let mut rdr = tokio::fs::File::open(path).await?;

View File

@@ -0,0 +1,56 @@
use std::fs::File;
use std::path::{Path, PathBuf};
use serde::Deserialize;
use serde_json::Value;
use crate::util::serde::IoFormat;
use crate::{Config, Error, ResultExt};
pub const CONFIG_PATH: &str = "/etc/embassy/config.yaml";
pub const CONFIG_PATH_LOCAL: &str = ".embassy/config.yaml";
pub fn local_config_path() -> Option<PathBuf> {
if let Ok(home) = std::env::var("HOME") {
Some(Path::new(&home).join(CONFIG_PATH_LOCAL))
} else {
None
}
}
/// BLOCKING
pub fn load_config_from_paths<'a, T: for<'de> Deserialize<'de>>(
paths: impl IntoIterator<Item = impl AsRef<Path>>,
) -> Result<T, Error> {
let mut config = Default::default();
for path in paths {
if path.as_ref().exists() {
let format: IoFormat = path
.as_ref()
.extension()
.and_then(|s| s.to_str())
.map(|f| f.parse())
.transpose()?
.unwrap_or_default();
let new = format.from_reader(File::open(path)?)?;
config = merge_configs(config, new);
}
}
serde_json::from_value(Value::Object(config)).with_kind(crate::ErrorKind::Deserialization)
}
pub fn merge_configs(mut first: Config, second: Config) -> Config {
for (k, v) in second.into_iter() {
let new = match first.remove(&k) {
None => v,
Some(old) => match (old, v) {
(Value::Object(first), Value::Object(second)) => {
Value::Object(merge_configs(first, second))
}
(first, _) => first,
},
};
first.insert(k, new);
}
first
}

View File

@@ -10,22 +10,21 @@ use std::task::{Context, Poll};
use async_trait::async_trait; use async_trait::async_trait;
use clap::ArgMatches; use clap::ArgMatches;
use color_eyre::eyre::{self, eyre}; use color_eyre::eyre::{self, eyre};
use digest::Digest;
use fd_lock_rs::FdLock; use fd_lock_rs::FdLock;
use futures::future::BoxFuture; use futures::future::BoxFuture;
use futures::FutureExt; use futures::FutureExt;
pub use helpers::NonDetachingJoinHandle;
use lazy_static::lazy_static; use lazy_static::lazy_static;
pub use models::Version;
use pin_project::pin_project; use pin_project::pin_project;
use sha2_old::Digest;
use tokio::fs::File; use tokio::fs::File;
use tokio::sync::{Mutex, OwnedMutexGuard, RwLock}; use tokio::sync::{Mutex, OwnedMutexGuard, RwLock};
use tracing::instrument; use tracing::instrument;
use crate::shutdown::Shutdown; use crate::shutdown::Shutdown;
use crate::{Error, ResultExt as _}; use crate::{Error, ResultExt as _};
pub mod config;
pub use helpers::NonDetachingJoinHandle;
pub use models::Version;
pub mod io; pub mod io;
pub mod logger; pub mod logger;
pub mod serde; pub mod serde;
@@ -251,7 +250,6 @@ where
} }
} }
pub struct GeneralGuard<F: FnOnce() -> T, T = ()>(Option<F>); pub struct GeneralGuard<F: FnOnce() -> T, T = ()>(Option<F>);
impl<F: FnOnce() -> T, T> GeneralGuard<F, T> { impl<F: FnOnce() -> T, T> GeneralGuard<F, T> {
pub fn new(f: F) -> Self { pub fn new(f: F) -> Self {