From af79be50021fb1710023688223d09bb5163ea16f Mon Sep 17 00:00:00 2001 From: channelbeta <88544994+channelbeta@users.noreply.github.com> Date: Mon, 20 Sep 2021 13:51:41 -0300 Subject: [PATCH 1/7] Update PGP keyserver URL --- ext/installfiles/linux/zerotier-containerized/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/installfiles/linux/zerotier-containerized/Dockerfile b/ext/installfiles/linux/zerotier-containerized/Dockerfile index ab286e34c..4db6bf915 100644 --- a/ext/installfiles/linux/zerotier-containerized/Dockerfile +++ b/ext/installfiles/linux/zerotier-containerized/Dockerfile @@ -5,7 +5,7 @@ FROM debian:buster-slim as builder ## Supports x86_64, x86, arm, and arm64 RUN apt-get update && apt-get install -y curl gnupg -RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys 0x1657198823e52a61 && \ +RUN apt-key adv --keyserver pgp.mit.edu --recv-keys 0x1657198823e52a61 && \ echo "deb http://download.zerotier.com/debian/buster buster main" > /etc/apt/sources.list.d/zerotier.list RUN apt-get update && apt-get install -y zerotier-one=1.6.2 COPY ext/installfiles/linux/zerotier-containerized/main.sh /var/lib/zerotier-one/main.sh From fa25b451983f7371bbfa4a95d47d340dcc813473 Mon Sep 17 00:00:00 2001 From: Travis LaDuke Date: Fri, 7 Jan 2022 07:59:48 -0800 Subject: [PATCH 2/7] Keep interface name on via routes on linux See issue #1498 --- osdep/ManagedRoute.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp index 746808112..325f4c803 100644 --- a/osdep/ManagedRoute.cpp +++ b/osdep/ManagedRoute.cpp @@ -526,14 +526,13 @@ bool ManagedRoute::sync() #ifdef __LINUX__ // ---------------------------------------------------------- - const char *const devptr = (_via) ? (const char *)0 : _device; - if ((leftt)&&(!LinuxNetLink::getInstance().routeIsSet(leftt,_via,_src,devptr))) { + if ((leftt)&&(!LinuxNetLink::getInstance().routeIsSet(leftt,_via,_src,_device))) { _applied[leftt] = false; // boolean unused - LinuxNetLink::getInstance().addRoute(leftt, _via, _src, devptr); + LinuxNetLink::getInstance().addRoute(leftt, _via, _src, _device); } - if ((rightt)&&(!LinuxNetLink::getInstance().routeIsSet(rightt,_via,_src,devptr))) { + if ((rightt)&&(!LinuxNetLink::getInstance().routeIsSet(rightt,_via,_src,_device))) { _applied[rightt] = false; // boolean unused - LinuxNetLink::getInstance().addRoute(rightt, _via, _src, devptr); + LinuxNetLink::getInstance().addRoute(rightt, _via, _src, _device); } #endif // __LINUX__ ---------------------------------------------------------- From 692a0e7ac22e43745b45185e5d105e9ccda7c6ef Mon Sep 17 00:00:00 2001 From: Travis LaDuke Date: Tue, 7 Dec 2021 12:12:16 -0800 Subject: [PATCH 3/7] Set a high metric on linux routes that have a via. See issue #750. zerotier doesn't currently set a metric on routes. Linux takes this to mean "0", the highest priority. Every comment in the issue is about routing between zerotier and lan and how they conflict. This quick change could fix this problem for most people. The subnet route for the zerotier network, the one with no via, is still 0 in this patch. Just the "via" routes get higher metrics. If for some reason, you needed your via routes to have higher priority, you could use a prefix work-around: 192.168.1.0/25 via 10.147.17.1 192.168.1.128/25 via 10.147.17.1 --- osdep/LinuxNetLink.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/osdep/LinuxNetLink.cpp b/osdep/LinuxNetLink.cpp index 421da1f63..6f07963eb 100644 --- a/osdep/LinuxNetLink.cpp +++ b/osdep/LinuxNetLink.cpp @@ -25,6 +25,7 @@ #ifndef IFNAMSIZ #define IFNAMSIZ 16 #endif +const int ZT_RTE_METRIC = 5000; namespace ZeroTier { @@ -731,6 +732,23 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c rtl += rtap->rta_len; if(via) { + /* + * Setting a metric keeps zerotier routes from taking priority over physical + * At best the computer would use zerotier through the router instead of the LAN. + * At worst it stops working at all. + * + * default via 192.168.82.1 dev eth0 proto dhcp src 192.168.82.169 metric 202 + * 10.147.17.0/24 dev zt5u4uptmb proto kernel scope link src 10.147.17.94 + * 192.168.82.0/24 dev eth0 proto dhcp scope link src 192.168.82.169 metric 202 + * 192.168.82.0/24 via 10.147.17.1 dev zt5u4uptmb proto static metric 5000 + * + */ + rtap = (struct rtattr*)(((char*)rtap) + rtap->rta_len); + rtap->rta_type = RTA_PRIORITY; + rtap->rta_len = RTA_LENGTH(sizeof(ZT_RTE_METRIC)); + memcpy(RTA_DATA(rtap), &ZT_RTE_METRIC, sizeof(ZT_RTE_METRIC)); + rtl += rtap->rta_len; + rtap = (struct rtattr *)(((char*)rtap)+rtap->rta_len); rtap->rta_type = RTA_GATEWAY; if(via.isV4()) { From 511c77aa994cd7e94844b717fb8ae97bebf66889 Mon Sep 17 00:00:00 2001 From: Ka Ho Ng Date: Mon, 10 Jan 2022 20:19:37 -0500 Subject: [PATCH 4/7] ext/libnatpmp: Set sa_len properly in getdefaultgateway() In USE_SOCKET_ROUTE's implementation, sa_len of the sockaddrs need to be set as well. Sponsored by: The FreeBSD Foundation --- ext/libnatpmp/getgateway.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/libnatpmp/getgateway.c b/ext/libnatpmp/getgateway.c index f743a0894..0f06e1dc2 100644 --- a/ext/libnatpmp/getgateway.c +++ b/ext/libnatpmp/getgateway.c @@ -271,7 +271,9 @@ int getdefaultgateway(in_addr_t *addr) rtm.rtm_addrs = rtm_addrs; so_dst.sa_family = AF_INET; + so_dst.sa_len = sizeof(struct sockaddr); so_mask.sa_family = AF_INET; + so_mask.sa_len = sizeof(struct sockaddr); NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_NETMASK, so_mask); From 7bb8703bf9eb7e858ba25a914d8a49c14df9b6df Mon Sep 17 00:00:00 2001 From: Ka Ho Ng Date: Wed, 12 Jan 2022 13:50:39 -0500 Subject: [PATCH 5/7] Build osdep/PortMapper on FreeBSD This enables NAT-PMP and UPnP supports on FreeBSD. --- make-bsd.mk | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/make-bsd.mk b/make-bsd.mk index 06c188090..637f80d68 100644 --- a/make-bsd.mk +++ b/make-bsd.mk @@ -7,6 +7,29 @@ LIBS= include objects.mk ONE_OBJS+=osdep/BSDEthernetTap.o ext/http-parser/http_parser.o +ifeq ($(OSTYPE),FreeBSD) + # Auto-detect miniupnpc and nat-pmp as well and use ports libs if present, + # otherwise build into binary as done on Mac and Windows. + INCLUDES+=-I/usr/local/include + LIBS+=-L/usr/local/lib + ONE_OBJS+=osdep/PortMapper.o + override DEFS+=-DZT_USE_MINIUPNPC + MINIUPNPC_IS_NEW_ENOUGH=$(shell grep -sqr '.*define.*MINIUPNPC_VERSION.*"2..*"' /usr/local/include/miniupnpc/miniupnpc.h && echo 1) + ifeq ($(MINIUPNPC_IS_NEW_ENOUGH),1) + LIBS+=-lminiupnpc + override DEFS+=-DZT_USE_SYSTEM_MINIUPNPC + else + override DEFS+=-DMINIUPNP_STATICLIB -DMINIUPNPC_SET_SOCKET_TIMEOUT -DMINIUPNPC_GET_SRC_ADDR -D_BSD_SOURCE -D_DEFAULT_SOURCE -DOS_STRING=\"FreeBSD/$(shell uname -r)\" -DMINIUPNPC_VERSION_STRING=\"2.0\" -DUPNP_VERSION_STRING=\"UPnP/1.1\" -DENABLE_STRNATPMPERR + ONE_OBJS+=ext/miniupnpc/connecthostport.o ext/miniupnpc/igd_desc_parse.o ext/miniupnpc/minisoap.o ext/miniupnpc/minissdpc.o ext/miniupnpc/miniupnpc.o ext/miniupnpc/miniwget.o ext/miniupnpc/minixml.o ext/miniupnpc/portlistingparse.o ext/miniupnpc/receivedata.o ext/miniupnpc/upnpcommands.o ext/miniupnpc/upnpdev.o ext/miniupnpc/upnperrors.o ext/miniupnpc/upnpreplyparse.o + endif + ifeq ($(wildcard /usr/local/include/natpmp.h),) + ONE_OBJS+=ext/libnatpmp/natpmp.o ext/libnatpmp/getgateway.o + else + LIBS+=-lnatpmp + override DEFS+=-DZT_USE_SYSTEM_NATPMP + endif +endif + # Build with address sanitization library for advanced debugging (clang) ifeq ($(ZT_SANITIZE),1) SANFLAGS+=-fsanitize=address -DASAN_OPTIONS=symbolize=1 From 58aba9649488f03116708d65adcace77d45466e6 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 20 Jan 2022 11:16:26 -0500 Subject: [PATCH 6/7] Mac Rust build fix. --- make-mac.mk | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/make-mac.mk b/make-mac.mk index 4655c8618..ca1fed6aa 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -75,7 +75,6 @@ ifeq ($(ZT_DEBUG),1) ARCH_FLAGS= CFLAGS+=-Wall -g $(INCLUDES) $(DEFS) $(ARCH_FLAGS) STRIP=echo - RUSTFLAGS= RUST_VARIANT=debug # The following line enables optimization for the crypto code, since # C25519 in particular is almost UNUSABLE in heavy testing without it. @@ -84,7 +83,6 @@ else CFLAGS?=-Ofast -fstack-protector-strong CFLAGS+=$(ARCH_FLAGS) -Wall -flto -fPIE -mmacosx-version-min=$(MACOS_VERSION_MIN) -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS) STRIP=strip - RUSTFLAGS=--release RUST_VARIANT=release endif @@ -121,8 +119,8 @@ zerotier-one: one zeroidc: zeroidc/target/libzeroidc.a zeroidc/target/libzeroidc.a: FORCE - cd zeroidc && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build --target=x86_64-apple-darwin $(RUSTFLAGS) - cd zeroidc && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build --target=aarch64-apple-darwin $(RUSTFLAGS) + cd zeroidc && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build --target=x86_64-apple-darwin --$(RUST_VARIANT) + cd zeroidc && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build --target=aarch64-apple-darwin --$(RUST_VARIANT) cd zeroidc && lipo -create target/x86_64-apple-darwin/$(RUST_VARIANT)/libzeroidc.a target/aarch64-apple-darwin/$(RUST_VARIANT)/libzeroidc.a -output target/libzeroidc.a central-controller: From d719137565e0234b41bc487ac90e9cbdb88f3abc Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 20 Jan 2022 09:44:56 -0800 Subject: [PATCH 7/7] temp workaround for oidc auth dropping issue Add a method to "kick" the refresh thread and re-post the tokens in the case where the thread is somehow still running & controller pushes out an AUTH_REQUIRED. This situation happens in a corner case still under investigation where the controller pushes out many copies of the network config repeatedly --- node/IncomingPacket.cpp | 8 ++++++-- node/Network.cpp | 3 ++- service/OneService.cpp | 5 +++++ zeroidc/src/ext.rs | 13 +++++++++++++ zeroidc/src/lib.rs | 22 +++++++++++++++++++++- 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 5fc38be02..e4e184241 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -1058,9 +1058,11 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,c { const SharedPtr network(RR->node->network(at(ZT_PACKET_IDX_PAYLOAD))); if (network) { + fprintf(stderr, "IncomingPacket::_doNETWORK_CONFIG %.16llx\n", network->id()); const uint64_t configUpdateId = network->handleConfigChunk(tPtr,packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD); if (configUpdateId) { - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK); + fprintf(stderr, "Have config update ID: %llu\n", configUpdateId); + Packet outp(peer->address(), RR->identity.address(), Packet::VERB_OK); outp.append((uint8_t)Packet::VERB_ECHO); outp.append((uint64_t)packetId()); outp.append((uint64_t)network->id()); @@ -1068,7 +1070,9 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,c const int64_t now = RR->node->now(); outp.armor(peer->key(),true,peer->aesKeysIfSupported()); peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now); - _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); + if (!_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now())) { + fprintf(stderr, "Error sending VERB_OK after NETWORK_CONFIG packet for %.16llx\n", network->id()); + } } } diff --git a/node/Network.cpp b/node/Network.cpp index c77f94a6d..8a6d40686 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -984,7 +984,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add } if (nc) { - this->setConfiguration(tPtr,*nc,true); + fprintf(stderr, "Network::handleConfigChucnk->setConfiguration %.16llx\n", this->_id); + this->setConfiguration(tPtr, *nc, true); delete nc; return configUpdateId; } else { diff --git a/service/OneService.cpp b/service/OneService.cpp index 6c4be6b54..191103209 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -285,6 +285,11 @@ public: const char* url = zeroidc::zeroidc_get_auth_url(_idc); memcpy(_config.authenticationURL, url, strlen(url)); _config.authenticationURL[strlen(url)] = 0; + + if (zeroidc::zeroidc_is_running(_idc) && nwc->status == ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED) { + // TODO: kick the refresh thread + zeroidc::zeroidc_kick_refresh_thread(_idc); + } } } diff --git a/zeroidc/src/ext.rs b/zeroidc/src/ext.rs index 9bf0181bc..361e7ab6e 100644 --- a/zeroidc/src/ext.rs +++ b/zeroidc/src/ext.rs @@ -218,3 +218,16 @@ pub extern "C" fn zeroidc_network_id_from_state(state: *const c_char) -> *const let s = CString::new(split[1]).unwrap(); return s.into_raw(); } + +#[no_mangle] +pub extern "C" fn zeroidc_kick_refresh_thread(idc: *mut ZeroIDC) { + if idc.is_null() { + println!("idc is null"); + return; + } + let idc = unsafe { + &mut *idc + }; + + idc.kick_refresh_thread(); +} \ No newline at end of file diff --git a/zeroidc/src/lib.rs b/zeroidc/src/lib.rs index 0bca86890..579dad7d9 100644 --- a/zeroidc/src/lib.rs +++ b/zeroidc/src/lib.rs @@ -48,6 +48,7 @@ struct Inner { access_token: Option, refresh_token: Option, exp_time: u64, + kick: bool, url: Option, csrf_token: Option, @@ -109,6 +110,7 @@ impl ZeroIDC { access_token: None, refresh_token: None, exp_time: 0, + kick: false, url: None, csrf_token: None, @@ -138,6 +140,11 @@ impl ZeroIDC { Ok(idc) } + fn kick_refresh_thread(&mut self) { + let local = Arc::clone(&self.inner); + (*local.lock().unwrap()).kick = true; + } + fn start(&mut self) { let local = Arc::clone(&self.inner); @@ -160,7 +167,15 @@ impl ZeroIDC { } let refresh_token = (*inner_local.lock().unwrap()).refresh_token.clone(); if let Some(refresh_token) = refresh_token { - if now >= (exp - Duration::from_secs(30)) { + let should_kick = (*inner_local.lock().unwrap()).kick; + if now >= (exp - Duration::from_secs(30)) || should_kick { + if should_kick { + #[cfg(debug_assertions)] { + println!("refresh thread kicked"); + } + (*inner_local.lock().unwrap()).kick = false; + } + let token_response = (*inner_local.lock().unwrap()).oidc_client.as_ref().map(|c| { let res = c.exchange_refresh_token(&refresh_token) .request(http_client); @@ -356,6 +371,11 @@ impl ZeroIDC { pub fn set_nonce_and_csrf(&mut self, csrf_token: String, nonce: String) { let local = Arc::clone(&self.inner); (*local.lock().expect("can't lock inner")).as_opt().map(|i| { + if i.running { + println!("refresh thread running. not setting new nonce or csrf"); + return + } + let need_verifier = match i.pkce_verifier { None => true, _ => false,