mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-26 17:03:43 +02:00
Locator creation.
This commit is contained in:
parent
37ef33caa0
commit
a0a79fa1b7
8 changed files with 181 additions and 69 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -39,5 +39,5 @@ node_modules
|
||||||
/*.opendb
|
/*.opendb
|
||||||
/rust-zerotier-core/src/capi.rs
|
/rust-zerotier-core/src/capi.rs
|
||||||
/rust-zerotier-core/target
|
/rust-zerotier-core/target
|
||||||
/rust-zerotier-service/target
|
/service/target
|
||||||
/rust-zerotier-service/src/osdep.rs
|
/service/src/osdep.rs
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub enum EndpointType {
|
||||||
|
|
||||||
pub struct Endpoint {
|
pub struct Endpoint {
|
||||||
pub type_: EndpointType,
|
pub type_: EndpointType,
|
||||||
capi: ztcore::ZT_Endpoint
|
pub(crate) capi: ztcore::ZT_Endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Endpoint {
|
impl Endpoint {
|
||||||
|
|
|
@ -16,6 +16,7 @@ use std::os::raw::{c_char, c_int, c_uint};
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use crate::capi as ztcore;
|
use crate::capi as ztcore;
|
||||||
|
use std::ptr::null;
|
||||||
|
|
||||||
pub struct Locator {
|
pub struct Locator {
|
||||||
pub(crate) capi: *const ztcore::ZT_Locator,
|
pub(crate) capi: *const ztcore::ZT_Locator,
|
||||||
|
@ -23,6 +24,22 @@ pub struct Locator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Locator {
|
impl Locator {
|
||||||
|
/// Create and sign a new locator.
|
||||||
|
/// The signer must include its secret key.
|
||||||
|
pub fn new(signer: &Identity, timestamp: i64, endpoints: &Vec<Endpoint>) -> Result<Locator, ResultCode> {
|
||||||
|
let mut capi_endpoints: Vec<ztcore::ZT_Endpoint> = Vec::new();
|
||||||
|
capi_endpoints.reserve(endpoints.len());
|
||||||
|
for ep in endpoints.iter() {
|
||||||
|
capi_endpoints.push(ep.capi);
|
||||||
|
}
|
||||||
|
let loc = unsafe { ztcore::ZT_Locator_create(timestamp, capi_endpoints.as_ptr(), null(), capi_endpoints.len() as c_uint, signer.capi) };
|
||||||
|
if loc.is_null() {
|
||||||
|
Err(ResultCode::ErrorBadParameter)
|
||||||
|
} else {
|
||||||
|
Ok(Locator::new_from_capi(loc, true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn new_from_capi(l: *const ztcore::ZT_Locator, requires_delete: bool) -> Locator {
|
pub(crate) fn new_from_capi(l: *const ztcore::ZT_Locator, requires_delete: bool) -> Locator {
|
||||||
Locator{
|
Locator{
|
||||||
|
@ -89,7 +106,7 @@ impl Clone for Locator {
|
||||||
|
|
||||||
impl ToString for Locator {
|
impl ToString for Locator {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
let mut buf: [u8; 4096] = [0; 4096];
|
let mut buf = [0_u8; 16384];
|
||||||
unsafe {
|
unsafe {
|
||||||
if ztcore::ZT_Locator_toString(self.capi, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() {
|
if ztcore::ZT_Locator_toString(self.capi, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() {
|
||||||
return String::from("(invalid)");
|
return String::from("(invalid)");
|
||||||
|
|
|
@ -20,89 +20,91 @@ fn make_help() -> String {
|
||||||
(c)2013-2021 ZeroTier, Inc.
|
(c)2013-2021 ZeroTier, Inc.
|
||||||
Licensed under the ZeroTier BSL (see LICENSE.txt)
|
Licensed under the ZeroTier BSL (see LICENSE.txt)
|
||||||
|
|
||||||
Usage: zerotier [-global options] <command> [command args]
|
Usage: zerotier [-...] <command> [command args]
|
||||||
|
|
||||||
Global Options:
|
Global Options:
|
||||||
|
|
||||||
-j Output raw JSON where applicable
|
-j Output raw JSON where applicable
|
||||||
-p <path> Use alternate base path
|
-p <path> Use alternate base path
|
||||||
-t <path> Load secret auth token from a file
|
-t <path> Load secret auth token from a file
|
||||||
-T <token> Set secret auth token on command line
|
-T <token> Set secret token on command line
|
||||||
|
|
||||||
Common Operations:
|
Common Operations:
|
||||||
|
|
||||||
help Show this help
|
help Show this help
|
||||||
version Print version
|
version Print version
|
||||||
|
|
||||||
· status Show node status and configuration
|
· status Show node status and configuration
|
||||||
|
|
||||||
· set [setting] [value] List all settings (with no args)
|
· set [setting] [value] List all settings (with no args)
|
||||||
· port <port> Primary P2P port
|
· port <port> Primary P2P port
|
||||||
· secondaryport <port/0> Secondary P2P port (0 to disable)
|
· secondaryport <port/0> Secondary P2P port (0 to disable)
|
||||||
· blacklist cidr <IP/bits> <boolean> Toggle physical path blacklisting
|
· blacklist cidr <IP/bits> <boolean> Toggle physical path blacklisting
|
||||||
· blacklist if <prefix> <boolean> [Un]blacklist interface prefix
|
· blacklist if <prefix> <boolean> [Un]blacklist interface prefix
|
||||||
· portmap <boolean> Toggle use of uPnP and NAT-PMP
|
· portmap <boolean> Toggle use of uPnP and NAT-PMP
|
||||||
|
|
||||||
· peer <command> [option]
|
· peer <command> [option]
|
||||||
· show <address> Show detailed peer information
|
· show <address> Show detailed peer information
|
||||||
· list List peers
|
· list List peers
|
||||||
· listroots List root peers
|
· listroots List root peers
|
||||||
· try <address> <endpoint> [...] Try peer at explicit endpoint
|
· try <address> <endpoint> [...] Try peer at explicit endpoint
|
||||||
|
|
||||||
· network <command> [option]
|
· network <command> [option]
|
||||||
· show <network ID> Show detailed network information
|
· show <network ID> Show detailed network information
|
||||||
· list List networks
|
· list List networks
|
||||||
· set <network ID> [option] [value] Get or set network options
|
· set <network ID> [option] [value] Get or set network options
|
||||||
· manageips <boolean> Is IP management allowed?
|
· manageips <boolean> Is IP management allowed?
|
||||||
· manageroutes <boolean> Is route management allowed?
|
· manageroutes <boolean> Is route management allowed?
|
||||||
· managedns <boolean> Allow network to push DNS config
|
· managedns <boolean> Allow network to push DNS config
|
||||||
· globalips <boolean> Allow assignment of global IPs?
|
· globalips <boolean> Allow assignment of global IPs?
|
||||||
· globalroutes <boolean> Can global IP space routes be set?
|
· globalroutes <boolean> Can global IP routes be set?
|
||||||
· defaultroute <boolean> Can default route be overridden?
|
· defaultroute <boolean> Can default route be overridden?
|
||||||
|
|
||||||
· join [-options] <network> Join a virtual network
|
· join [-...] <network> Join a virtual network
|
||||||
-c <identity | fingerprint> Controller identity or fingerprint
|
-c <identity | fingerprint> Controller identity / fingerprint
|
||||||
· leave <network> Leave a virtual network
|
· leave <network> Leave a virtual network
|
||||||
|
|
||||||
Advanced Operations:
|
Advanced Operations:
|
||||||
|
|
||||||
service Start this node (runs until stopped)
|
service Start this node
|
||||||
|
(usually not run directly)
|
||||||
|
|
||||||
controller <command> [option]
|
controller <command> [option]
|
||||||
· list List networks on controller
|
· list List networks on controller
|
||||||
· new Create a new network
|
· new Create a new network
|
||||||
· set <network> [setting] [value] Show or modify network settings
|
· set <network> [setting] [value] Show or modify network settings
|
||||||
· show <network> [<address>] Show network or member status
|
· show <network> [<address>] Show network or member status
|
||||||
· auth <address> Authorize a peer
|
· auth <address> Authorize a peer
|
||||||
· deauth <address> Deauthorize a peer
|
· deauth <address> Deauthorize a peer
|
||||||
|
|
||||||
identity <command> [args]
|
identity <command> [args]
|
||||||
new [c25519 | p384] Create identity (default: c25519)
|
new [c25519 | p384] Create identity (default: c25519)
|
||||||
getpublic <identity> Extract only public part of identity
|
getpublic <identity> Extract public part of identity
|
||||||
fingerprint <identity> Get an identity's fingerprint
|
fingerprint <identity> Get an identity's fingerprint
|
||||||
validate <identity> Locally validate an identity
|
validate <identity> Locally validate an identity
|
||||||
sign <identity> <file> Sign a file with an identity's key
|
sign <identity> <file> Sign a file with an identity's key
|
||||||
verify <identity> <file> <sig> Verify a signature
|
verify <identity> <file> <sig> Verify a signature
|
||||||
|
|
||||||
locator <command> [args]
|
locator <command> [args]
|
||||||
new <identity> <endpoint> [...] Create new signed locator
|
new [-...] <identity> <endpoint> [...] Create new signed locator
|
||||||
verify <identity> <locator> Verify locator signature
|
-t <timestamp> Timestamp (default: system time)
|
||||||
show <locator> Show contents of a locator
|
verify <identity> <locator> Verify locator signature
|
||||||
|
show <locator> Show contents of a locator
|
||||||
|
|
||||||
cert <command> [args]
|
cert <command> [args]
|
||||||
· list List certificates at local node
|
· list List certificates at local node
|
||||||
· show <serial> Show certificate details
|
· show <serial> Show certificate details
|
||||||
newsid [sid secret out] Create a new subject unique ID
|
newsid [sid secret out] Create a new subject unique ID
|
||||||
newcsr <csr output path> Create a subject CSR (interactive)
|
newcsr <csr output path> Create a subject CSR (interactive)
|
||||||
sign <csr> <identity> [cert out] Sign a CSR to create a certificate
|
sign <csr> <identity> [cert out] Sign a CSR to create a certificate
|
||||||
verify <cert> Verify certificate (not chain)
|
verify <cert> Verify certificate (not chain)
|
||||||
dump <cert> Verify and print certificate
|
dump <cert> Verify and print certificate
|
||||||
· import <cert> [trust,trust,...] Import certificate into this node
|
· import <cert> [trust,trust,...] Import certificate into this node
|
||||||
trust flag: rootca Certificate is a root CA
|
trust flag: rootca Certificate is a root CA
|
||||||
trust flag: ztrootset ZeroTier root node set
|
trust flag: ztrootset ZeroTier root node set
|
||||||
· factoryreset Re-import compiled-in default certs
|
· factoryreset Re-import compiled-in default certs
|
||||||
· export <serial> [path] Export a certificate from this node
|
· export <serial> [path] Export a certificate from this node
|
||||||
· delete <serial|ALL> Delete certificate from this node
|
· delete <serial|ALL> Delete certificate from this node
|
||||||
|
|
||||||
· Command requires a running node and access to a local API token.
|
· Command requires a running node and access to a local API token.
|
||||||
|
|
||||||
|
@ -144,6 +146,8 @@ fn is_valid_port(v: String) -> Result<(), String> {
|
||||||
|
|
||||||
/// Parses CLI arguments, prints error and exits on failure.
|
/// Parses CLI arguments, prints error and exits on failure.
|
||||||
pub(crate) fn parse_cli_args() -> ArgMatches<'static> {
|
pub(crate) fn parse_cli_args() -> ArgMatches<'static> {
|
||||||
|
// NOTE: the names of these arguments must match the names used to look
|
||||||
|
// them up in the various command demuxers under commands/.
|
||||||
let help = make_help();
|
let help = make_help();
|
||||||
let args = App::new("zerotier")
|
let args = App::new("zerotier")
|
||||||
.arg(Arg::with_name("json").short("j"))
|
.arg(Arg::with_name("json").short("j"))
|
||||||
|
@ -219,6 +223,7 @@ pub(crate) fn parse_cli_args() -> ArgMatches<'static> {
|
||||||
.arg(Arg::with_name("signature").index(3).required(true))))
|
.arg(Arg::with_name("signature").index(3).required(true))))
|
||||||
.subcommand(App::new("locator")
|
.subcommand(App::new("locator")
|
||||||
.subcommand(App::new("new")
|
.subcommand(App::new("new")
|
||||||
|
.arg(Arg::with_name("timestamp").short("t").required(false))
|
||||||
.arg(Arg::with_name("identity").index(1).required(true))
|
.arg(Arg::with_name("identity").index(1).required(true))
|
||||||
.arg(Arg::with_name("endpoint").index(2).multiple(true).required(true)))
|
.arg(Arg::with_name("endpoint").index(2).multiple(true).required(true)))
|
||||||
.subcommand(App::new("verify")
|
.subcommand(App::new("verify")
|
||||||
|
|
|
@ -16,8 +16,6 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use dialoguer::Input;
|
use dialoguer::Input;
|
||||||
use lazy_static::lazy_static;
|
|
||||||
|
|
||||||
use zerotier_core::*;
|
use zerotier_core::*;
|
||||||
|
|
||||||
use crate::store::Store;
|
use crate::store::Store;
|
||||||
|
@ -260,7 +258,7 @@ fn import<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Option<Stri
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore(store: &Store, auth_token: &Option<String>) -> i32 {
|
fn factoryreset(store: &Store, auth_token: &Option<String>) -> i32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +280,7 @@ pub(crate) fn run<'a>(store: &Store, cli_args: &ArgMatches<'a>, auth_token: &Opt
|
||||||
("verify", Some(sub_cli_args)) => verify(store, sub_cli_args, auth_token),
|
("verify", Some(sub_cli_args)) => verify(store, sub_cli_args, auth_token),
|
||||||
("dump", Some(sub_cli_args)) => dump(store, sub_cli_args, auth_token),
|
("dump", Some(sub_cli_args)) => dump(store, sub_cli_args, auth_token),
|
||||||
("import", Some(sub_cli_args)) => import(store, sub_cli_args, auth_token),
|
("import", Some(sub_cli_args)) => import(store, sub_cli_args, auth_token),
|
||||||
("factoryreset", None) => restore(store, auth_token),
|
("factoryreset", None) => factoryreset(store, auth_token),
|
||||||
("export", Some(sub_cli_args)) => export(store, sub_cli_args, auth_token),
|
("export", Some(sub_cli_args)) => export(store, sub_cli_args, auth_token),
|
||||||
("delete", Some(sub_cli_args)) => delete(store, sub_cli_args, auth_token),
|
("delete", Some(sub_cli_args)) => delete(store, sub_cli_args, auth_token),
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file in the project's root directory.
|
||||||
|
*
|
||||||
|
* Change Date: 2026-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2.0 of the Apache License.
|
||||||
|
*/
|
||||||
|
/****/
|
||||||
|
|
||||||
|
use clap::ArgMatches;
|
||||||
|
|
||||||
|
use zerotier_core::*;
|
||||||
|
|
||||||
|
use crate::store::Store;
|
||||||
|
|
||||||
|
fn new_<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 {
|
||||||
|
let timestamp = cli_args.value_of("timestamp").map_or(crate::utils::ms_since_epoch(), |ts| {
|
||||||
|
if ts.is_empty() {
|
||||||
|
0_i64
|
||||||
|
} else {
|
||||||
|
i64::from_str_radix(ts, 10).unwrap_or(0_i64) * 1000_i64 // internally uses ms since epoch
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if timestamp <= 0 {
|
||||||
|
println!("ERROR: invalid or empty timestamp specified.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let identity = crate::utils::read_identity(cli_args.value_of("identity").unwrap(), true);
|
||||||
|
if identity.is_err() {
|
||||||
|
println!("ERROR: identity invalid: {}", identity.err().unwrap());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let identity = identity.unwrap();
|
||||||
|
if !identity.has_private() {
|
||||||
|
println!("ERROR: identity must include secret key to create and sign a locator.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let endpoints_cli = cli_args.values_of("endpoint");
|
||||||
|
if endpoints_cli.is_none() {
|
||||||
|
println!("ERROR: at least one endpoint required.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let mut endpoints: Vec<Endpoint> = Vec::new();
|
||||||
|
let mut endpoint_bad = false;
|
||||||
|
endpoints_cli.unwrap().for_each(|ep_str| {
|
||||||
|
Endpoint::new_from_string(ep_str).map_or_else(|e| {
|
||||||
|
println!("ERROR: endpoint {} invalid: {}", ep_str, e.to_str());
|
||||||
|
endpoint_bad = true;
|
||||||
|
}, |ep| {
|
||||||
|
endpoints.push(ep);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if endpoint_bad {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Locator::new(&identity, timestamp, &endpoints).map_or_else(|e| {
|
||||||
|
println!("ERROR: failure creating locator: {}", e.to_str());
|
||||||
|
1
|
||||||
|
}, |loc| {
|
||||||
|
println!("{}", loc.to_string());
|
||||||
|
0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show<'a>(store: &Store, cli_args: &ArgMatches<'a>) -> i32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run<'a>(store: &Store, cli_args: &ArgMatches<'a>, _: &Option<String>) -> i32 {
|
||||||
|
match cli_args.subcommand() {
|
||||||
|
("new", Some(sub_cli_args)) => new_(store, sub_cli_args),
|
||||||
|
("verify", Some(sub_cli_args)) => verify(store, sub_cli_args),
|
||||||
|
("show", Some(sub_cli_args)) => show(store, sub_cli_args),
|
||||||
|
_ => {
|
||||||
|
crate::cli::print_help();
|
||||||
|
1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -102,7 +102,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
("controller", Some(sub_cli_args)) => {}
|
("controller", Some(sub_cli_args)) => {}
|
||||||
("identity", Some(sub_cli_args)) => {}
|
("identity", Some(sub_cli_args)) => {}
|
||||||
("locator", Some(sub_cli_args)) => {}
|
("locator", Some(sub_cli_args)) => {
|
||||||
|
process_exit_value = crate::commands::locator::run(&store, sub_cli_args, &auth_token);
|
||||||
|
}
|
||||||
("cert", Some(sub_cli_args)) => {
|
("cert", Some(sub_cli_args)) => {
|
||||||
process_exit_value = crate::commands::cert::run(&store, sub_cli_args, &auth_token);
|
process_exit_value = crate::commands::cert::run(&store, sub_cli_args, &auth_token);
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,7 +220,7 @@ async fn run_async(store: &Arc<Store>, auth_token: String, log: &Arc<Log>, local
|
||||||
let service = service; // make immutable after setting node
|
let service = service; // make immutable after setting node
|
||||||
|
|
||||||
let mut local_config = service.local_config();
|
let mut local_config = service.local_config();
|
||||||
store.write_port(local_config.settings.primary_port);
|
let _ = store.write_port(local_config.settings.primary_port);
|
||||||
|
|
||||||
let mut now: i64 = ms_since_epoch();
|
let mut now: i64 = ms_since_epoch();
|
||||||
let mut loop_delay = zerotier_core::NODE_BACKGROUND_TASKS_MAX_INTERVAL;
|
let mut loop_delay = zerotier_core::NODE_BACKGROUND_TASKS_MAX_INTERVAL;
|
||||||
|
|
Loading…
Add table
Reference in a new issue