More build fixes.

This commit is contained in:
Adam Ierymenko 2023-03-27 17:00:24 -04:00
parent c7ba67c717
commit 65854aea5f
4 changed files with 72 additions and 29 deletions

View file

@ -26,17 +26,13 @@ pub fn cmd(_: Flags, cmd_args: &ArgMatches) -> i32 {
if path.is_some() && secret_arg.is_some() {
let path = path.unwrap();
let secret_arg = secret_arg.unwrap();
let secret = crate::utils::parse_cli_identity(secret_arg, true);
let secret = crate::utils::parse_cli_identity_secret(secret_arg);
let json_data = read_limit(path, DEFAULT_FILE_IO_READ_LIMIT);
if secret.is_err() {
eprintln!("ERROR: unable to parse '{}' or read as a file.", secret_arg);
return exitcode::ERR_IOERR;
}
let secret = secret.unwrap();
if !secret.secret.is_some() {
eprintln!("ERROR: identity does not include secret key, which is required for signing.");
return exitcode::ERR_IOERR;
}
if json_data.is_err() {
eprintln!("ERROR: unable to read '{}'.", path);
return exitcode::ERR_IOERR;
@ -102,7 +98,7 @@ pub fn cmd(_: Flags, cmd_args: &ArgMatches) -> i32 {
eprintln!("ERROR: root set JSON parsing failed: {}", root_set.err().unwrap().to_string());
return exitcode::ERR_IOERR;
}
let _ = std::io::stdout().write_all(root_set.unwrap().to_bytes().as_slice());
let _ = std::io::stdout().write_all(root_set.unwrap().to_buffer::<16384>().unwrap().as_ref());
} else {
eprintln!("ERROR: 'rootset marshal' requires a path to a root set in JSON format.");
return exitcode::ERR_IOERR;

View file

@ -207,28 +207,34 @@ fn main() {
if let Ok(_tokio_runtime) = zerotier_utils::tokio::runtime::Builder::new_multi_thread().enable_all().build() {
let test_inner = Arc::new(DummyInnerLayer);
let datadir = open_datadir(&flags);
let svc = VL1Service::new(datadir, test_inner, zerotier_vl1_service::VL1Settings::default());
if svc.is_ok() {
let svc = svc.unwrap();
svc.node().init_default_roots();
// Wait for kill signal on Unix-like platforms.
#[cfg(unix)]
{
let term = Arc::new(AtomicBool::new(false));
let _ = signal_hook::flag::register(libc::SIGINT, term.clone());
let _ = signal_hook::flag::register(libc::SIGTERM, term.clone());
let _ = signal_hook::flag::register(libc::SIGQUIT, term.clone());
while !term.load(Ordering::Relaxed) {
std::thread::sleep(Duration::from_secs(1));
}
}
println!("Terminate signal received, shutting down...");
exitcode::OK
} else {
eprintln!("FATAL: error launching service: {}", svc.err().unwrap().to_string());
let id = datadir.read_identity(true, true);
if let Err(e) = id {
eprintln!("FATAL: error generator or writing identity: {}", e.to_string());
exitcode::ERR_IOERR
} else {
let svc = VL1Service::new(id.unwrap(), test_inner, zerotier_vl1_service::VL1Settings::default());
if svc.is_ok() {
let svc = svc.unwrap();
svc.node.init_default_roots();
// Wait for kill signal on Unix-like platforms.
#[cfg(unix)]
{
let term = Arc::new(AtomicBool::new(false));
let _ = signal_hook::flag::register(libc::SIGINT, term.clone());
let _ = signal_hook::flag::register(libc::SIGTERM, term.clone());
let _ = signal_hook::flag::register(libc::SIGQUIT, term.clone());
while !term.load(Ordering::Relaxed) {
std::thread::sleep(Duration::from_secs(1));
}
}
println!("Terminate signal received, shutting down...");
exitcode::OK
} else {
eprintln!("FATAL: error launching service: {}", svc.err().unwrap().to_string());
exitcode::ERR_IOERR
}
}
} else {
eprintln!("FATAL: error launching service: can't start async runtime");

View file

@ -3,7 +3,7 @@
use std::path::Path;
use std::str::FromStr;
use zerotier_network_hypervisor::vl1::identity::Identity;
use zerotier_network_hypervisor::vl1::identity::{Identity, IdentitySecret};
use zerotier_utils::io::read_limit;
/// Returns true if the string starts with [yY1tT] or false for [nN0fF].
@ -36,7 +36,6 @@ pub fn is_valid_port(v: &str) -> Result<(), String> {
Err(format!("invalid TCP/IP port number: {}", v))
}
/// Read an identity as either a literal or from a file.
pub fn parse_cli_identity(input: &str, validate: bool) -> Result<Identity, String> {
let parse_func = |s: &str| {
Identity::from_str(s).map_or_else(
@ -64,6 +63,20 @@ pub fn parse_cli_identity(input: &str, validate: bool) -> Result<Identity, Strin
}
}
pub fn parse_cli_identity_secret(input: &str) -> Result<IdentitySecret, String> {
let parse_func = |s: &str| IdentitySecret::from_str(s).map_err(|e| format!("invalid identity: {}", e.to_string()));
let input_p = Path::new(input);
if input_p.is_file() {
read_limit(input_p, 16384).map_or_else(
|e| Err(e.to_string()),
|v| String::from_utf8(v).map_or_else(|e| Err(e.to_string()), |s| parse_func(s.as_str())),
)
} else {
parse_func(input)
}
}
//#[cfg(unix)]
//pub fn c_strerror() -> String {
// unsafe { std::ffi::CStr::from_ptr(libc::strerror(*libc::__error()).cast()).to_string_lossy().to_string() }

View file

@ -1,12 +1,15 @@
// (c) 2020-2022 ZeroTier, Inc. -- currently proprietary pending actual release and licensing. See LICENSE.md.
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::sync::{Arc, Mutex, RwLock};
use serde::de::DeserializeOwned;
use serde::Serialize;
use zerotier_crypto::random::next_u32_secure;
use zerotier_network_hypervisor::vl1::identity::{Identity, IdentitySecret};
use zerotier_utils::io::{fs_restrict_permissions, read_limit, DEFAULT_FILE_IO_READ_LIMIT};
use zerotier_utils::json::to_json_pretty;
@ -56,6 +59,31 @@ impl<Config: PartialEq + Eq + Clone + Send + Sync + Default + Serialize + Deseri
return Ok(Self { base_path, config, authtoken: Mutex::new(String::new()) });
}
/// Read (and possibly generate) the identity.
pub fn read_identity(&self, auto_generate: bool, generate_x25519_only: bool) -> std::io::Result<IdentitySecret> {
let identity_path = self.base_path.join(IDENTITY_SECRET_FILENAME);
match read_limit(&identity_path, 4096) {
Ok(id_bytes) => {
return IdentitySecret::from_str(String::from_utf8_lossy(id_bytes.as_slice()).as_ref())
.map_err(|_| std::io::Error::new(ErrorKind::InvalidData, "invalid identity"));
}
Err(e) => match e.kind() {
ErrorKind::NotFound => {
if auto_generate {
let id = Identity::generate(generate_x25519_only);
let ids = id.to_string();
std::fs::write(&identity_path, ids.as_bytes())?;
std::fs::write(self.base_path.join(IDENTITY_PUBLIC_FILENAME), id.public.to_string().as_bytes())?;
return Ok(id);
} else {
return Err(e);
}
}
_ => return Err(e),
},
}
}
/// Get authorization token for local API, creating and saving if it does not exist.
pub fn authtoken(&self) -> std::io::Result<String> {
let authtoken = self.authtoken.lock().unwrap().clone();