diff --git a/controller/src/handler.rs b/controller/src/handler.rs index 944cd3cde..506af62ac 100644 --- a/controller/src/handler.rs +++ b/controller/src/handler.rs @@ -247,7 +247,7 @@ impl Inner { let deauthed_members_still_in_window = self.database.list_members_deauthorized_after(network.id, now - max_delta).await; // Check and if necessary auto-assign static IPs for this member. - member_changed |= network.check_zt_ip_assignments(self.database.as_ref(), &mut member).await; + member_changed |= network.check_zt_ip_assignments(self.database.as_ref(), &mut member).await?; let mut nc = NetworkConfig::new(network_id, source.identity.address); diff --git a/controller/src/model/network.rs b/controller/src/model/network.rs index 40a00e730..96e94a283 100644 --- a/controller/src/model/network.rs +++ b/controller/src/model/network.rs @@ -1,6 +1,7 @@ // (c) 2020-2022 ZeroTier, Inc. -- currently propritery pending actual release and licensing. See LICENSE.md. use std::collections::{HashMap, HashSet}; +use std::error::Error; use std::hash::Hash; use serde::{Deserialize, Serialize}; @@ -124,7 +125,11 @@ fn troo() -> bool { impl Network { /// Check member IP assignments and return 'true' if IP assignments were created or modified. - pub async fn check_zt_ip_assignments(&self, database: &DatabaseImpl, member: &mut Member) -> bool { + pub async fn check_zt_ip_assignments( + &self, + database: &DatabaseImpl, + member: &mut Member, + ) -> Result> { let mut modified = false; if self.v4_assign_mode.zt { @@ -137,7 +142,7 @@ impl Network { for route in self.ip_routes.iter() { let ip = InetAddress::from_ip_port(&ip_ptr.to_be_bytes(), route.target.port()); // IP/bits if ip.is_within(&route.target) { - if !database.is_ip_assigned(self.id, &ip).await.unwrap_or(true) { + if !database.is_ip_assigned(self.id, &ip).await? { modified = true; let _ = member.ip_assignments.insert(ip); break 'ip_search; @@ -161,7 +166,7 @@ impl Network { for route in self.ip_routes.iter() { let ip = InetAddress::from_ip_port(&ip_ptr.to_be_bytes(), route.target.port()); // IP/bits if ip.is_within(&route.target) { - if !database.is_ip_assigned(self.id, &ip).await.unwrap_or(true) { + if !database.is_ip_assigned(self.id, &ip).await? { modified = true; let _ = member.ip_assignments.insert(ip); break 'ip_search; @@ -175,6 +180,6 @@ impl Network { } } - modified + Ok(modified) } } diff --git a/network-hypervisor/src/vl1/identity.rs b/network-hypervisor/src/vl1/identity.rs index 2b5aeb9d1..5a516645c 100644 --- a/network-hypervisor/src/vl1/identity.rs +++ b/network-hypervisor/src/vl1/identity.rs @@ -415,21 +415,21 @@ impl Identity { pub fn write_secret(&self, w: &mut W, legacy_v0: bool) -> std::io::Result<()> { if let Some(s) = self.secret.as_ref() { - w.write_all(&self.address.to_bytes()); + w.write_all(&self.address.to_bytes())?; if !legacy_v0 && self.p384.is_some() && s.p384.is_some() { let p384 = self.p384.as_ref().unwrap(); let p384s = s.p384.as_ref().unwrap(); - w.write_all(&[Self::ALGORITHM_X25519 | Self::ALGORITHM_EC_NIST_P384 | Self::FLAG_INCLUDES_SECRETS]); - w.write_all(&self.x25519); - w.write_all(&self.ed25519); - w.write_all(s.x25519.secret_bytes().as_bytes()); - w.write_all(s.ed25519.secret_bytes().as_bytes()); - w.write_all(p384.ecdh.as_bytes()); - w.write_all(p384.ecdsa.as_bytes()); - w.write_all(p384s.ecdh.secret_key_bytes().as_bytes()); - w.write_all(p384s.ecdsa.secret_key_bytes().as_bytes()); - w.write_all(&p384.ecdsa_self_signature); - w.write_all(&p384.ed25519_self_signature); + w.write_all(&[Self::ALGORITHM_X25519 | Self::ALGORITHM_EC_NIST_P384 | Self::FLAG_INCLUDES_SECRETS])?; + w.write_all(&self.x25519)?; + w.write_all(&self.ed25519)?; + w.write_all(s.x25519.secret_bytes().as_bytes())?; + w.write_all(s.ed25519.secret_bytes().as_bytes())?; + w.write_all(p384.ecdh.as_bytes())?; + w.write_all(p384.ecdsa.as_bytes())?; + w.write_all(p384s.ecdh.secret_key_bytes().as_bytes())?; + w.write_all(p384s.ecdsa.secret_key_bytes().as_bytes())?; + w.write_all(&p384.ecdsa_self_signature)?; + w.write_all(&p384.ed25519_self_signature)?; } else { w.write_all(&[0])?; w.write_all(&self.x25519)?; @@ -444,13 +444,13 @@ impl Identity { } } - pub fn to_public_bytes(&self, legacy_v8: bool) -> std::io::Result> { + pub fn to_public_bytes(&self) -> std::io::Result> { let mut buf = Buffer::<{ Self::BYTE_LENGTH_MAX }>::new(); self.write_public(&mut buf, false)?; Ok(buf) } - pub fn to_secret_bytes(&self, legacy_v8: bool) -> std::io::Result> { + pub fn to_secret_bytes(&self) -> std::io::Result> { let mut buf = Buffer::<{ Self::BYTE_LENGTH_MAX }>::new(); self.write_secret(&mut buf, false)?; Ok(buf) @@ -502,7 +502,7 @@ impl Identity { fn fill_in_fingerprint(&mut self) { let mut h = SHA384::new(); - self.write_public(&mut h, false); + assert!(self.write_public(&mut h, false).is_ok()); self.fingerprint = h.finish(); } @@ -904,7 +904,7 @@ mod tests { let gen = Identity::generate(); assert!(gen.agree(&gen).is_some()); assert!(gen.validate_identity()); - let bytes = gen.to_secret_bytes(false).unwrap(); + let bytes = gen.to_secret_bytes().unwrap(); let string = gen.to_secret_string(); assert!(Identity::from_str(string.as_str()).unwrap().eq(&gen)); @@ -931,7 +931,7 @@ mod tests { assert!(id.validate_identity()); assert!(id.p384.is_none()); - let idb = id.to_secret_bytes(false).unwrap(); + let idb = id.to_secret_bytes().unwrap(); let id_unmarshal = Identity::from_bytes(idb.as_bytes()).unwrap(); assert!(id == id_unmarshal); assert!(id_unmarshal.secret.is_some()); @@ -961,7 +961,7 @@ mod tests { assert!(id.p384.is_some()); assert!(id.secret.as_ref().unwrap().p384.is_some()); - let idb = id.to_secret_bytes(false).unwrap(); + let idb = id.to_secret_bytes().unwrap(); let id_unmarshal = Identity::from_bytes(idb.as_bytes()).unwrap(); assert!(id == id_unmarshal); diff --git a/network-hypervisor/src/vl1/peer.rs b/network-hypervisor/src/vl1/peer.rs index d956290c3..e46668ad1 100644 --- a/network-hypervisor/src/vl1/peer.rs +++ b/network-hypervisor/src/vl1/peer.rs @@ -778,13 +778,13 @@ impl Peer { if addresses.len() >= ADDRESS_SIZE { if let Some(zt_address) = Address::from_bytes(&addresses[..ADDRESS_SIZE]) { if let Some(peer) = node.peer(zt_address) { - if let Ok(id_bytes) = peer.identity.to_public_bytes(self.identity.p384.is_none()) { - if (packet.capacity() - packet.len()) < id_bytes.len() { - self.send(host_system, None, node, time_ticks, packet); - packet = host_system.get_buffer(); - init_packet(&mut packet); - } - let _ = packet.append_bytes(id_bytes.as_bytes()); + if (packet.capacity() - packet.len()) < Identity::MAX_MARSHAL_SIZE { + self.send(host_system, None, node, time_ticks, packet); + packet = host_system.get_buffer(); + init_packet(&mut packet); + } + if !peer.identity.write_public(packet.as_mut(), self.identity.p384.is_none()).is_ok() { + break; } } } diff --git a/network-hypervisor/src/vl2/networkconfig.rs b/network-hypervisor/src/vl2/networkconfig.rs index 90b6b493f..5237c21dd 100644 --- a/network-hypervisor/src/vl2/networkconfig.rs +++ b/network-hypervisor/src/vl2/networkconfig.rs @@ -43,7 +43,8 @@ pub struct NetworkConfig { pub certificates_of_ownership: Vec, pub tags: HashMap, - pub node_info: HashMap, + pub banned: HashSet
, // v2 only + pub node_info: HashMap, // v2 only pub central_url: String, pub sso: Option, @@ -69,6 +70,7 @@ impl NetworkConfig { certificate_of_membership: None, certificates_of_ownership: Vec::new(), tags: HashMap::new(), + banned: HashSet::new(), node_info: HashMap::new(), central_url: String::new(), sso: None, diff --git a/network-hypervisor/src/vl2/tag.rs b/network-hypervisor/src/vl2/tag.rs index 13664d228..b0c975495 100644 --- a/network-hypervisor/src/vl2/tag.rs +++ b/network-hypervisor/src/vl2/tag.rs @@ -8,7 +8,6 @@ use crate::vl2::NetworkId; use serde::{Deserialize, Serialize}; use zerotier_utils::arrayvec::ArrayVec; -use zerotier_utils::blob::Blob; use zerotier_utils::error::InvalidParameterError; #[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] @@ -18,7 +17,6 @@ pub struct Tag { pub network_id: NetworkId, pub timestamp: i64, pub issued_to: Address, - pub issued_to_fingerprint: Blob<{ Identity::FINGERPRINT_SIZE }>, pub signature: ArrayVec, pub version: u8, } @@ -39,7 +37,6 @@ impl Tag { network_id, timestamp, issued_to: issued_to.address, - issued_to_fingerprint: Blob::from(issued_to.fingerprint), signature: ArrayVec::new(), version: if legacy_v1 { 1 @@ -115,7 +112,6 @@ impl Tag { network_id: NetworkId::from_bytes(&b[0..8]).ok_or(InvalidParameterError("invalid network ID"))?, timestamp: i64::from_be_bytes(b[8..16].try_into().unwrap()), issued_to: Address::from_bytes(&b[24..29]).ok_or(InvalidParameterError("invalid address"))?, - issued_to_fingerprint: Blob::default(), signature: { let mut s = ArrayVec::new(); s.push_slice(&b[37..133]);