mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-25 08:27:39 +02:00
It makes web requests, and fix some warnings.
This commit is contained in:
parent
f5331b5bb9
commit
6df6a955ba
15 changed files with 358 additions and 42 deletions
|
@ -24,6 +24,7 @@ struct prf_ra {
|
|||
#include "../core/Mutex.hpp"
|
||||
#include "../core/Containers.hpp"
|
||||
#include "../core/SHA512.hpp"
|
||||
#include "../core/AES.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include "rust-osdep.h"
|
||||
|
@ -139,4 +140,18 @@ void sha384(const void *in, unsigned int len, void *out)
|
|||
void sha512(const void *in, unsigned int len, void *out)
|
||||
{ ZeroTier::SHA512(out, in, len); }
|
||||
|
||||
static ZT_INLINE ZeroTier::AES _makeHttpAuthCipher() noexcept
|
||||
{
|
||||
uint8_t key[32];
|
||||
ZeroTier::Utils::getSecureRandom(key, 32);
|
||||
return ZeroTier::AES(key);
|
||||
}
|
||||
static const ZeroTier::AES HTTP_AUTH_CIPHER = _makeHttpAuthCipher();
|
||||
|
||||
void encryptHttpAuthNonce(void *block)
|
||||
{ HTTP_AUTH_CIPHER.encrypt(block, block); }
|
||||
|
||||
void decryptHttpAuthNonce(void *block)
|
||||
{ HTTP_AUTH_CIPHER.decrypt(block, block); }
|
||||
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -108,6 +108,8 @@ extern void lockDownFile(const char *path, int isDir);
|
|||
extern void getSecureRandom(void *buf, unsigned int len);
|
||||
extern void sha384(const void *in, unsigned int len, void *out);
|
||||
extern void sha512(const void *in, unsigned int len, void *out);
|
||||
extern void encryptHttpAuthNonce(void *block);
|
||||
extern void decryptHttpAuthNonce(void *block);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
/****/
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::{c_char, c_int, c_uint};
|
||||
use std::os::raw::{c_int, c_uint};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr::null;
|
||||
|
||||
|
|
198
service/Cargo.lock
generated
198
service/Cargo.lock
generated
|
@ -26,6 +26,15 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.0"
|
||||
|
@ -38,7 +47,7 @@ version = "0.6.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e964e3e0a930303c7c0bdb28ebf691dd98d9eee4b8b68019d2c995710b58a18"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.13.0",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
@ -48,6 +57,22 @@ version = "1.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"iovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.0.1"
|
||||
|
@ -256,13 +281,24 @@ version = "0.4.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0"
|
||||
dependencies = [
|
||||
"bytes 0.4.12",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytes 1.0.1",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
@ -273,8 +309,8 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"bytes 1.0.1",
|
||||
"http 0.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -295,11 +331,11 @@ version = "0.14.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12219dc884514cb4a6a03737f4413c0e01c23a1b059b0156004b23f1e19dccbe"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytes 1.0.1",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 0.2.3",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
|
@ -312,12 +348,56 @@ dependencies = [
|
|||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyperx"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a94cbc2c6f63028e5736ca4e811ae36d3990059c384cbe68298c66728a9776"
|
||||
dependencies = [
|
||||
"base64 0.10.1",
|
||||
"bytes 0.4.12",
|
||||
"http 0.1.21",
|
||||
"httparse",
|
||||
"language-tags",
|
||||
"log",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"time",
|
||||
"unicase 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "language-tags"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
@ -339,12 +419,24 @@ dependencies = [
|
|||
"cfg-if 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.7.7"
|
||||
|
@ -423,6 +515,12 @@ version = "1.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.4"
|
||||
|
@ -698,6 +796,21 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.0.2"
|
||||
|
@ -757,6 +870,42 @@ version = "0.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
|
||||
dependencies = [
|
||||
"version_check 0.1.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||
dependencies = [
|
||||
"matches",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
|
@ -769,12 +918,35 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
|
||||
dependencies = [
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.0"
|
||||
|
@ -822,6 +994,17 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "www-authenticate"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c62efb8259cda4e4c732287397701237b78daa4c43edcf3e613c8503a6c07dd"
|
||||
dependencies = [
|
||||
"hyperx",
|
||||
"unicase 1.4.2",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "0.9.3"
|
||||
|
@ -832,7 +1015,7 @@ checksum = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86"
|
|||
name = "zerotier-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.13.0",
|
||||
"base64-serde",
|
||||
"hex",
|
||||
"num-derive",
|
||||
|
@ -860,5 +1043,6 @@ dependencies = [
|
|||
"socket2",
|
||||
"tokio",
|
||||
"winapi",
|
||||
"www-authenticate",
|
||||
"zerotier-core",
|
||||
]
|
||||
|
|
|
@ -23,6 +23,7 @@ num-derive = "0"
|
|||
hyper = { version = "0", features = ["http1", "runtime", "server", "client", "tcp", "stream"] }
|
||||
socket2 = { version = "0", features = ["reuseport", "unix", "pair"] }
|
||||
dialoguer = "0"
|
||||
www-authenticate = "0"
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
winapi = { version = "0.3.9", features = ["handleapi", "ws2ipdef", "ws2tcpip"] }
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use hyper::Uri;
|
||||
use crate::store::Store;
|
||||
|
||||
pub(crate) fn run(store: Arc<Store>) -> i32 {
|
||||
crate::webclient::command(store.clone(), move |client, uri| {
|
||||
async move {
|
||||
let mut res = client.get(uri).await?;
|
||||
println!("status: {}", res.status().as_str());
|
||||
let body = hyper::body::to_bytes(res.body_mut()).await?;
|
||||
String::from_utf8(body.to_vec()).map(|body| {
|
||||
println!("body: {}", body.as_str());
|
||||
});
|
||||
Ok(0)
|
||||
}
|
||||
})
|
||||
}
|
|
@ -233,7 +233,7 @@ impl FastUDPSocket {
|
|||
let mut buf = Buffer::new();
|
||||
let read_length = fast_udp_socket_recvfrom(&thread_socket, &mut buf, &mut from_address);
|
||||
if read_length > 0 {
|
||||
unsafe { buf.set_len(read_length as usize); }
|
||||
buf.set_len(read_length as usize);
|
||||
handler_copy(&thread_socket, &from_address, buf);
|
||||
} else if read_length < 0 {
|
||||
break;
|
||||
|
|
|
@ -48,12 +48,12 @@ pub(crate) fn for_each_address<F: FnMut(&InetAddress, &str)>(mut f: F) {
|
|||
let mut netmask_bits: u16 = 0;
|
||||
if !(*i).ifa_netmask.is_null() {
|
||||
if sa_family == osdep::AF_INET as u8 {
|
||||
let mut a = (*(*i).ifa_netmask.cast::<osdep::sockaddr_in>()).sin_addr.s_addr as u32;
|
||||
let a = (*(*i).ifa_netmask.cast::<osdep::sockaddr_in>()).sin_addr.s_addr as u32;
|
||||
netmask_bits = a.leading_ones() as u16;
|
||||
} else if sa_family == osdep::AF_INET6 as u8 {
|
||||
let a = s6_addr_as_ptr(&((*(*i).ifa_netmask.cast::<osdep::sockaddr_in6>()).sin6_addr)).cast::<u8>();
|
||||
for i in 0..16 as isize {
|
||||
let mut b = *a.offset(i);
|
||||
let b = *a.offset(i);
|
||||
if b == 0xff {
|
||||
netmask_bits += 8;
|
||||
} else {
|
||||
|
|
|
@ -71,7 +71,7 @@ impl Log {
|
|||
let log_line = format!("{}[{}] {}{}\n", l.prefix.as_str(), chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(), pfx, s);
|
||||
if !l.path.is_empty() {
|
||||
if l.file.is_none() {
|
||||
let mut f = OpenOptions::new().read(true).write(true).create(true).open(l.path.as_str());
|
||||
let f = OpenOptions::new().read(true).write(true).create(true).open(l.path.as_str());
|
||||
if f.is_err() {
|
||||
return;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ impl Log {
|
|||
let _ = std::fs::rename(l.path.as_str(), old_path.as_str());
|
||||
let _ = std::fs::remove_file(l.path.as_str()); // should fail
|
||||
|
||||
let mut f = OpenOptions::new().read(true).write(true).create(true).open(l.path.as_str());
|
||||
let f = OpenOptions::new().read(true).write(true).create(true).open(l.path.as_str());
|
||||
if f.is_err() {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ mod network;
|
|||
mod vnic;
|
||||
mod service;
|
||||
mod utils;
|
||||
mod webclient;
|
||||
mod weblistener;
|
||||
|
||||
#[allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, improper_ctypes)]
|
||||
|
@ -291,9 +292,8 @@ fn main() {
|
|||
.get_matches_from_safe(std::env::args());
|
||||
if args.is_err() {
|
||||
let e = args.err().unwrap();
|
||||
match e.kind {
|
||||
ErrorKind::HelpDisplayed => {}
|
||||
_ => { print_help(); }
|
||||
if e.kind != ErrorKind::HelpDisplayed {
|
||||
print_help();
|
||||
}
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
@ -306,22 +306,22 @@ fn main() {
|
|||
};
|
||||
|
||||
std::process::exit(match cli_args.subcommand() {
|
||||
("help", None) => {
|
||||
("help", _) => {
|
||||
print_help();
|
||||
0
|
||||
}
|
||||
("version", None) => {
|
||||
("version", _) => {
|
||||
let ver = zerotier_core::version();
|
||||
println!("{}.{}.{}", ver.0, ver.1, ver.2);
|
||||
0
|
||||
}
|
||||
("status", None) => { 0 }
|
||||
("status", _) => crate::commands::status::run(make_store(&cli_args)),
|
||||
("set", Some(sub_cli_args)) => { 0 }
|
||||
("peer", Some(sub_cli_args)) => { 0 }
|
||||
("network", Some(sub_cli_args)) => { 0 }
|
||||
("join", Some(sub_cli_args)) => { 0 }
|
||||
("leave", Some(sub_cli_args)) => { 0 }
|
||||
("service", None) => {
|
||||
("service", _) => {
|
||||
let store = make_store(&cli_args);
|
||||
drop(cli_args); // free memory
|
||||
service::run(store)
|
||||
|
|
|
@ -221,7 +221,6 @@ async fn run_async(store: Arc<Store>, log: Arc<Log>, local_config: Arc<LocalConf
|
|||
let service = service; // make immutable after setting node
|
||||
|
||||
let mut local_config = service.local_config();
|
||||
let _ = store.write_port(local_config.settings.primary_port);
|
||||
|
||||
let mut now: i64 = ms_since_epoch();
|
||||
let mut loop_delay = zerotier_core::NODE_BACKGROUND_TASKS_MAX_INTERVAL;
|
||||
|
@ -265,7 +264,6 @@ async fn run_async(store: Arc<Store>, log: Arc<Log>, local_config: Arc<LocalConf
|
|||
if local_config.settings.primary_port != next_local_config.settings.primary_port {
|
||||
local_web_listeners.0 = None;
|
||||
local_web_listeners.1 = None;
|
||||
store.write_port(next_local_config.settings.primary_port);
|
||||
}
|
||||
if local_config.settings.log.max_size != next_local_config.settings.log.max_size {
|
||||
log.set_max_size(next_local_config.settings.log.max_size);
|
||||
|
@ -373,7 +371,7 @@ async fn run_async(store: Arc<Store>, log: Arc<Log>, local_config: Arc<LocalConf
|
|||
if addr.0.port() == local_config.settings.primary_port && !web_listeners.contains_key(addr.0) {
|
||||
let sa = addr.0.to_socketaddr();
|
||||
if sa.is_some() {
|
||||
let wl = WebListener::new(addr.1.as_str(), sa.unwrap(), &service).map_or_else(|e| {
|
||||
let wl = WebListener::new(addr.1.as_str(), sa.unwrap(), &service).await.map_or_else(|e| {
|
||||
l!(log, "error creating HTTP listener at {}: {}", addr.0.to_string(), e.to_string());
|
||||
}, |l| {
|
||||
l!(log, "created HTTP listener at {}", addr.0.to_string());
|
||||
|
@ -384,13 +382,17 @@ async fn run_async(store: Arc<Store>, log: Arc<Log>, local_config: Arc<LocalConf
|
|||
}
|
||||
|
||||
if local_web_listeners.0.is_none() {
|
||||
let _ = WebListener::new(loopback_dev_name.as_str(), SocketAddr::new(IpAddr::from(Ipv4Addr::LOCALHOST), local_config.settings.primary_port), &service).map(|wl| {
|
||||
let _ = WebListener::new(loopback_dev_name.as_str(), SocketAddr::new(IpAddr::from(Ipv4Addr::LOCALHOST), local_config.settings.primary_port), &service).await.map(|wl| {
|
||||
local_web_listeners.0 = Some(wl);
|
||||
let _ = store.write_uri(format!("http://127.0.0.1:{}/", local_config.settings.primary_port).as_str());
|
||||
});
|
||||
}
|
||||
if local_web_listeners.1.is_none() {
|
||||
let _ = WebListener::new(loopback_dev_name.as_str(), SocketAddr::new(IpAddr::from(Ipv6Addr::LOCALHOST), local_config.settings.primary_port), &service).map(|wl| {
|
||||
let _ = WebListener::new(loopback_dev_name.as_str(), SocketAddr::new(IpAddr::from(Ipv6Addr::LOCALHOST), local_config.settings.primary_port), &service).await.map(|wl| {
|
||||
local_web_listeners.1 = Some(wl);
|
||||
if local_web_listeners.0.is_none() {
|
||||
let _ = store.write_uri(format!("http://[::1]:{}/", local_config.settings.primary_port).as_str());
|
||||
}
|
||||
});
|
||||
}
|
||||
if local_web_listeners.0.is_none() && local_web_listeners.1.is_none() {
|
||||
|
|
|
@ -249,26 +249,11 @@ impl Store {
|
|||
self.write_file("local.conf", json.as_bytes())
|
||||
}
|
||||
|
||||
/// Writes the primary port number bound to zerotier.port.
|
||||
pub fn write_port(&self, port: u16) -> std::io::Result<()> {
|
||||
let ps = port.to_string();
|
||||
self.write_file("zerotier.port", ps.as_bytes())
|
||||
}
|
||||
|
||||
/// Read zerotier.port and return port or 0 if not found or not readable.
|
||||
pub fn read_port(&self) -> u16 {
|
||||
self.read_file_str("zerotier.port").map_or_else(|_| {
|
||||
0_u16
|
||||
},|s| {
|
||||
u16::from_str(s.trim()).unwrap_or(0_u16)
|
||||
})
|
||||
}
|
||||
|
||||
/// Write zerotier.pid file with current process's PID.
|
||||
#[cfg(unix)]
|
||||
pub fn write_pid(&self) -> std::io::Result<()> {
|
||||
let pid = unsafe { crate::osdep::getpid() }.to_string();
|
||||
self.write_file(self.base_path.join("zerotier.pid").to_str().unwrap(), pid.as_bytes())
|
||||
self.write_file("zerotier.pid", pid.as_bytes())
|
||||
}
|
||||
|
||||
/// Erase zerotier.pid if present.
|
||||
|
@ -276,6 +261,26 @@ impl Store {
|
|||
let _ = std::fs::remove_file(self.base_path.join("zerotier.pid"));
|
||||
}
|
||||
|
||||
/// Write a string to zerotier.uri
|
||||
pub fn write_uri(&self, uri: &str) -> std::io::Result<()> {
|
||||
self.write_file("zerotier.uri", uri.as_bytes())
|
||||
}
|
||||
|
||||
/// Load zerotier.uri if present
|
||||
pub fn load_uri(&self) -> std::io::Result<hyper::Uri> {
|
||||
let uri = String::from_utf8(self.read_file("zerotier.uri")?);
|
||||
uri.map_or_else(|e| {
|
||||
Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))
|
||||
}, |uri| {
|
||||
let uri = hyper::Uri::from_str(uri.trim());
|
||||
uri.map_or_else(|e| {
|
||||
Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))
|
||||
}, |uri| {
|
||||
Ok(uri)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Load a ZeroTier core object.
|
||||
pub fn load_object(&self, obj_type: &StateObjectType, obj_id: &[u64]) -> std::io::Result<Vec<u8>> {
|
||||
let obj_path = self.make_obj_path_internal(&obj_type, obj_id);
|
||||
|
|
|
@ -21,6 +21,7 @@ use std::path::Path;
|
|||
use zerotier_core::{Identity, Locator};
|
||||
|
||||
use crate::osdep;
|
||||
use crate::osdep::time;
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn sha512<T: AsRef<[u8]>>(data: T) -> [u8; 64] {
|
||||
|
@ -107,3 +108,33 @@ pub(crate) fn read_locator(input: &str) -> Result<Locator, String> {
|
|||
parse_func(input)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new HTTP authorization nonce by encrypting the current time.
|
||||
/// The key used to encrypt the current time is random and is re-created for
|
||||
/// each execution of the process. By decrypting this nonce when it is returned,
|
||||
/// the client and server may check the age of a digest auth exchange.
|
||||
pub(crate) fn create_http_auth_nonce(timestamp: u64) -> String {
|
||||
let mut nonce_plaintext: [u64; 2] = [timestamp, 12345]; // the second u64 is arbitrary and unused
|
||||
unsafe {
|
||||
osdep::encryptHttpAuthNonce(nonce_plaintext.as_mut_ptr().cast());
|
||||
hex::encode(*nonce_plaintext.as_ptr().cast::<[u8; 16]>())
|
||||
}
|
||||
}
|
||||
|
||||
/// Decrypt HTTP auth nonce encrypted by this process and return the timestamp.
|
||||
/// This returns zero if the input was not valid.
|
||||
pub(crate) fn decrypt_http_auth_nonce(nonce: &str) -> u64 {
|
||||
let nonce = hex::decode(nonce.trim());
|
||||
if nonce.is_err() {
|
||||
return 0;
|
||||
}
|
||||
let mut nonce = nonce.unwrap();
|
||||
if nonce.len() != 16 {
|
||||
return 0;
|
||||
}
|
||||
unsafe {
|
||||
osdep::decryptHttpAuthNonce(nonce.as_mut_ptr().cast());
|
||||
let nonce = *nonce.as_ptr().cast::<[u64; 2]>();
|
||||
nonce[0]
|
||||
}
|
||||
}
|
||||
|
|
44
service/src/webclient.rs
Normal file
44
service/src/webclient.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use hyper::Uri;
|
||||
use std::sync::Arc;
|
||||
use crate::store::Store;
|
||||
use std::future::Future;
|
||||
|
||||
/// Launch the supplied function inside the tokio runtime.
|
||||
/// The return value of this function should be the process exit code.
|
||||
/// This is for implementation of commands that query the HTTP API, not HTTP
|
||||
/// requests from a running server.
|
||||
pub(crate) fn command<'a, R: Future<Output = hyper::Result<i32>>, F: FnOnce(Arc<hyper::Client<hyper::client::HttpConnector, hyper::Body>>, hyper::Uri) -> R>(store: Arc<Store>, func: F) -> i32 {
|
||||
let rt = tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap();
|
||||
let code = rt.block_on(async move {
|
||||
let uri = store.load_uri();
|
||||
if uri.is_err() {
|
||||
println!("ERROR: unable to read 'zerotier.uri' to get local HTTP API address.");
|
||||
1
|
||||
} else {
|
||||
let f = func(Arc::new(hyper::Client::new()), uri.unwrap());
|
||||
f.await.map_or_else(|e| {
|
||||
println!("ERROR: HTTP request failed: {}", e.to_string());
|
||||
1
|
||||
}, |code| {
|
||||
code
|
||||
})
|
||||
}
|
||||
});
|
||||
rt.shutdown_timeout(Duration::from_millis(10));
|
||||
code
|
||||
}
|
|
@ -42,7 +42,7 @@ pub(crate) struct WebListener {
|
|||
|
||||
impl WebListener {
|
||||
/// Create a new "background" TCP WebListener using the current tokio reactor async runtime.
|
||||
pub fn new(_device_name: &str, addr: SocketAddr, service: &Service) -> Result<WebListener, Box<dyn std::error::Error>> {
|
||||
pub async fn new(_device_name: &str, addr: SocketAddr, service: &Service) -> Result<WebListener, Box<dyn std::error::Error>> {
|
||||
let listener = if addr.is_ipv4() {
|
||||
let listener = socket2::Socket::new(socket2::Domain::ipv4(), socket2::Type::stream(), Some(socket2::Protocol::tcp()));
|
||||
if listener.is_err() {
|
||||
|
|
Loading…
Add table
Reference in a new issue