From ce40a1df8a21326c8c01334b0a28953d787e4d1d Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 1 Jan 2021 17:09:30 -0500 Subject: [PATCH] Remove CRL from Certificate as it really does not belong there, and Rust cleanup. --- core/Certificate.cpp | 31 --- core/Certificate.hpp | 8 - core/zerotier.h | 10 - rust-zerotier-core/src/certificate.rs | 192 +++++++++++------- rust-zerotier-core/src/endpoint.rs | 31 ++- rust-zerotier-core/src/identity.rs | 15 +- rust-zerotier-core/src/lib.rs | 19 +- rust-zerotier-core/src/node.rs | 10 +- rust-zerotier-core/src/path.rs | 11 +- rust-zerotier-core/src/peer.rs | 40 ++-- .../src/virtualnetworkconfig.rs | 20 +- 11 files changed, 205 insertions(+), 182 deletions(-) diff --git a/core/Certificate.cpp b/core/Certificate.cpp index 3dc0cc215..3e244ba24 100644 --- a/core/Certificate.cpp +++ b/core/Certificate.cpp @@ -108,12 +108,6 @@ Certificate &Certificate::operator=(const ZT_Certificate &cert) this->maxPathLength = cert.maxPathLength; - if ((cert.crl) && (cert.crlCount > 0)) { - for (unsigned int i = 0; i < cert.crlCount; ++i) { - if (cert.crl[i]) - addCRLCertificate(cert.crl[i]); - } - } if ((cert.signature) && (cert.signatureSize > 0)) { m_signature.assign(cert.signature, cert.signature + cert.signatureSize); this->signature = m_signature.data(); @@ -223,14 +217,6 @@ bool Certificate::setSubjectUniqueId(const uint8_t uniqueId[ZT_CERTIFICATE_UNIQU return true; } -void Certificate::addCRLCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE]) -{ - m_serials.push_front(SHA384Hash(serialNo)); - m_crl.push_back(m_serials.front().bytes()); - this->crl = m_crl.data(); - this->crlCount = (unsigned int)m_crl.size(); -} - Vector< uint8_t > Certificate::encode(const bool omitSignature) const { char tmp[32]; @@ -285,14 +271,6 @@ Vector< uint8_t > Certificate::encode(const bool omitSignature) const if ((this->extendedAttributes) && (this->extendedAttributesSize > 0)) d["x"].assign(this->extendedAttributes, this->extendedAttributes + this->extendedAttributesSize); - if ((this->crl) && (this->crlCount > 0)) { - d.add("r$", (uint64_t)this->crlCount); - for (unsigned int i = 0; i < this->crlCount; ++i) { - if (this->crl[i]) - d[Dictionary::arraySubscript(tmp, sizeof(tmp), "r$", i)].assign(this->crl[i], this->crl[i] + ZT_SHA384_DIGEST_SIZE); - } - } - if ((!omitSignature) && (this->signature) && (this->signatureSize > 0)) d["S"].assign(this->signature, this->signature + this->signatureSize); @@ -423,14 +401,6 @@ bool Certificate::decode(const void *const data, const unsigned int len) this->extendedAttributesSize = (unsigned int)m_extendedAttributes.size(); } - cnt = (unsigned int)d.getUI("r$"); - for (unsigned int i = 0; i < cnt; ++i) { - const Vector< uint8_t > &cr = d[Dictionary::arraySubscript(tmp, sizeof(tmp), "r$", i)]; - if (cr.size() != ZT_SHA384_DIGEST_SIZE) - return false; - this->addCRLCertificate(cr.data()); - } - m_signature = d["S"]; if (!m_signature.empty()) { this->signature = m_signature.data(); @@ -588,7 +558,6 @@ void Certificate::m_clear() m_extendedAttributes.clear(); m_subjectUniqueId.clear(); m_subjectUniqueIdProofSignature.clear(); - m_crl.clear(); m_signature.clear(); } diff --git a/core/Certificate.hpp b/core/Certificate.hpp index 750aa8767..71093fc54 100644 --- a/core/Certificate.hpp +++ b/core/Certificate.hpp @@ -125,13 +125,6 @@ public: */ bool setSubjectUniqueId(const uint8_t uniqueId[ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE], const uint8_t uniqueIdPrivate[ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE]); - /** - * Add a serial number to the CRL list - * - * @param serialNo Serial number of certificate to revoke - */ - void addCRLCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE]); - /** * Marshal this certificate in binary form * @@ -236,7 +229,6 @@ private: Vector< uint8_t > m_extendedAttributes; Vector< uint8_t > m_subjectUniqueId; Vector< uint8_t > m_subjectUniqueIdProofSignature; - Vector< const uint8_t * > m_crl; Vector< uint8_t > m_signature; std::atomic< int > __refCount; diff --git a/core/zerotier.h b/core/zerotier.h index b6379d6c4..ffe120e30 100644 --- a/core/zerotier.h +++ b/core/zerotier.h @@ -601,16 +601,6 @@ typedef struct */ unsigned int maxPathLength; - /** - * List of certificate serial numbers being revoked. - */ - const uint8_t *const *crl; - - /** - * Number of 48-byte serial numbers in crl list. - */ - unsigned int crlCount; - /** * Signature by issuer (algorithm determined by identity type). */ diff --git a/rust-zerotier-core/src/certificate.rs b/rust-zerotier-core/src/certificate.rs index 53763443c..340236f74 100644 --- a/rust-zerotier-core/src/certificate.rs +++ b/rust-zerotier-core/src/certificate.rs @@ -1,5 +1,6 @@ use std::cell::Cell; use std::ffi::{CStr, CString}; +use std::hash::{Hash, Hasher}; use std::mem::{MaybeUninit, zeroed}; use std::os::raw::{c_char, c_uint, c_void}; use std::ptr::{copy_nonoverlapping, null, null_mut}; @@ -48,6 +49,7 @@ impl CertificateSerialNo { } impl From<&[u8; 48]> for CertificateSerialNo { + #[inline(always)] fn from(a: &[u8; 48]) -> CertificateSerialNo { CertificateSerialNo(*a) } @@ -65,7 +67,15 @@ impl From<&[u8]> for CertificateSerialNo { } } +impl Hash for CertificateSerialNo { + #[inline(always)] + fn hash(&self, state: &mut H) { + self.0.hash(state); + } +} + impl ToString for CertificateSerialNo { + #[inline(always)] fn to_string(&self) -> String { hex::encode(self.0) } @@ -162,7 +172,8 @@ impl<'de> serde::Deserialize<'de> for CertificateUniqueIdType { pub struct CertificateSubjectUniqueIdSecret { pub public: Vec, pub private: Vec, - pub type_: CertificateUniqueIdType, + #[serde(rename = "type")] + pub type_: CertificateUniqueIdType } const CERTIFICATE_UNIQUE_ID_CREATE_BUF_SIZE: usize = 128; @@ -227,36 +238,56 @@ impl ToString for CertificateError { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#[allow(non_snake_case)] #[derive(Serialize, Deserialize)] pub struct CertificateName { - pub serialNo: String, - pub commonName: String, + #[serde(rename = "serialNo")] + pub serial_no: String, + #[serde(rename = "commonName")] + pub common_name: String, pub country: String, pub organization: String, pub unit: String, pub locality: String, pub province: String, - pub streetAddress: String, - pub postalCode: String, + #[serde(rename = "streetAddress")] + pub street_address: String, + #[serde(rename = "postalCode")] + pub postal_code: String, pub email: String, pub url: String, pub host: String, } impl CertificateName { + pub fn new() -> CertificateName { + CertificateName { + serial_no: String::new(), + common_name: String::new(), + country: String::new(), + organization: String::new(), + unit: String::new(), + locality: String::new(), + province: String::new(), + street_address: String::new(), + postal_code: String::new(), + email: String::new(), + url: String::new(), + host: String::new() + } + } + pub(crate) unsafe fn new_from_capi(cn: &ztcore::ZT_Certificate_Name) -> CertificateName { unsafe { return CertificateName { - serialNo: cstr_to_string(cn.serialNo.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), - commonName: cstr_to_string(cn.commonName.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), + serial_no: cstr_to_string(cn.serialNo.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), + common_name: cstr_to_string(cn.commonName.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), country: cstr_to_string(cn.country.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), organization: cstr_to_string(cn.organization.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), unit: cstr_to_string(cn.unit.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), locality: cstr_to_string(cn.locality.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), province: cstr_to_string(cn.province.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), - streetAddress: cstr_to_string(cn.streetAddress.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), - postalCode: cstr_to_string(cn.postalCode.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), + street_address: cstr_to_string(cn.streetAddress.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), + postal_code: cstr_to_string(cn.postalCode.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), email: cstr_to_string(cn.email.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), url: cstr_to_string(cn.url.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1), host: cstr_to_string(cn.host.as_ptr(), CERTIFICATE_MAX_STRING_LENGTH - 1) @@ -282,15 +313,15 @@ impl CertificateName { pub(crate) unsafe fn to_capi(&self) -> ztcore::ZT_Certificate_Name { unsafe { let mut cn: ztcore::ZT_Certificate_Name = zeroed(); - Self::str_to_cert_cstr(&self.serialNo, &mut cn.serialNo); - Self::str_to_cert_cstr(&self.commonName, &mut cn.commonName); + Self::str_to_cert_cstr(&self.serial_no, &mut cn.serialNo); + Self::str_to_cert_cstr(&self.common_name, &mut cn.commonName); Self::str_to_cert_cstr(&self.country, &mut cn.country); Self::str_to_cert_cstr(&self.organization, &mut cn.organization); Self::str_to_cert_cstr(&self.unit, &mut cn.unit); Self::str_to_cert_cstr(&self.locality, &mut cn.locality); Self::str_to_cert_cstr(&self.province, &mut cn.province); - Self::str_to_cert_cstr(&self.streetAddress, &mut cn.streetAddress); - Self::str_to_cert_cstr(&self.postalCode, &mut cn.postalCode); + Self::str_to_cert_cstr(&self.street_address, &mut cn.streetAddress); + Self::str_to_cert_cstr(&self.postal_code, &mut cn.postalCode); Self::str_to_cert_cstr(&self.email, &mut cn.email); Self::str_to_cert_cstr(&self.url, &mut cn.url); Self::str_to_cert_cstr(&self.host, &mut cn.host); @@ -364,17 +395,19 @@ implement_to_from_json!(CertificateIdentity); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#[allow(non_snake_case)] #[derive(Serialize, Deserialize)] pub struct CertificateSubject { pub timestamp: i64, pub identities: Vec, pub networks: Vec, pub certificates: Vec, - pub updateURLs: Vec, + #[serde(rename = "updateURLs")] + pub update_urls: Vec, pub name: CertificateName, - pub uniqueId: Vec, - pub uniqueIdProofSignature: Vec, + #[serde(rename = "uniqueId")] + pub unique_id: Vec, + #[serde(rename = "uniqueIdProofSignature")] + pub unique_id_proof_signature: Vec, } pub(crate) struct CertificateSubjectCAPIContainer { @@ -387,6 +420,19 @@ pub(crate) struct CertificateSubjectCAPIContainer { } impl CertificateSubject { + pub fn new() -> CertificateSubject { + CertificateSubject { + timestamp: 0, + identities: Vec::new(), + networks: Vec::new(), + certificates: Vec::new(), + update_urls: Vec::new(), + name: CertificateName::new(), + unique_id: Vec::new(), + unique_id_proof_signature: Vec::new() + } + } + pub(crate) unsafe fn new_from_capi(cs: &ztcore::ZT_Certificate_Subject) -> CertificateSubject { unsafe { let mut identities: Vec = Vec::new(); @@ -431,10 +477,10 @@ impl CertificateSubject { identities: identities, networks: networks, certificates: certificates, - updateURLs: update_urls, + update_urls: update_urls, name: CertificateName::new_from_capi(&cs.name), - uniqueId: Vec::from(std::slice::from_raw_parts(cs.uniqueId, cs.uniqueIdSize as usize)), - uniqueIdProofSignature: Vec::from(std::slice::from_raw_parts(cs.uniqueIdProofSignature, cs.uniqueIdProofSignatureSize as usize)), + unique_id: Vec::from(std::slice::from_raw_parts(cs.uniqueId, cs.uniqueIdSize as usize)), + unique_id_proof_signature: Vec::from(std::slice::from_raw_parts(cs.uniqueIdProofSignature, cs.uniqueIdProofSignatureSize as usize)), }; } } @@ -464,9 +510,9 @@ impl CertificateSubject { capi_certificates.push((*i).0.as_ptr()); } } - if !self.updateURLs.is_empty() { - capi_urls.reserve(self.updateURLs.len()); - for i in self.updateURLs.iter() { + if !self.update_urls.is_empty() { + capi_urls.reserve(self.update_urls.len()); + for i in self.update_urls.iter() { let cs = CString::new((*i).as_str()); if cs.is_ok() { capi_urls_strs.push(cs.unwrap()); @@ -487,10 +533,10 @@ impl CertificateSubject { certificateCount: capi_certificates.len() as c_uint, updateURLCount: capi_urls.len() as c_uint, name: unsafe { self.name.to_capi() }, - uniqueId: self.uniqueId.as_ptr(), - uniqueIdProofSignature: self.uniqueIdProofSignature.as_ptr(), - uniqueIdSize: self.uniqueId.len() as c_uint, - uniqueIdProofSignatureSize: self.uniqueIdProofSignature.len() as c_uint, + uniqueId: self.unique_id.as_ptr(), + uniqueIdProofSignature: self.unique_id_proof_signature.as_ptr(), + uniqueIdSize: self.unique_id.len() as c_uint, + uniqueIdProofSignatureSize: self.unique_id_proof_signature.len() as c_uint, }, subject_identities: capi_identities, subject_networks: capi_networks, @@ -527,85 +573,79 @@ implement_to_from_json!(CertificateSubject); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#[allow(non_snake_case)] #[derive(Serialize, Deserialize)] pub struct Certificate { - pub serialNo: CertificateSerialNo, + #[serde(rename = "serialNo")] + pub serial_no: CertificateSerialNo, pub flags: u64, pub timestamp: i64, pub validity: [i64; 2], pub subject: CertificateSubject, - pub issuer: Identity, - pub issuerName: CertificateName, - pub extendedAttributes: Vec, - pub maxPathLength: u32, - pub crl: Vec, - pub signature: Vec, + pub issuer: Option, + #[serde(rename = "issuerName")] + pub issuer_name: CertificateName, + #[serde(rename = "extendedAttributes")] + pub extended_attributes: Vec, + #[serde(rename = "maxPathLength")] + pub max_path_length: u32, + pub signature: Vec } pub(crate) struct CertificateCAPIContainer { pub(crate) certificate: ztcore::ZT_Certificate, - certificate_crls: Vec<*const u8>, subject_container: CertificateSubjectCAPIContainer, } impl Certificate { + pub fn new() -> Certificate { + Certificate { + serial_no: CertificateSerialNo::new(), + flags: 0, + timestamp: 0, + validity: [0, i64::max_value()], + subject: CertificateSubject::new(), + issuer: None, + issuer_name: CertificateName::new(), + extended_attributes: Vec::new(), + max_path_length: 0, + signature: Vec::new() + } + } + pub(crate) unsafe fn new_from_capi(c: &ztcore::ZT_Certificate) -> Certificate { unsafe { - let mut crl: Vec = Vec::new(); - if !c.crl.is_null() && c.crlCount > 0 { - let ccrl: &[*const u8] = std::slice::from_raw_parts(c.crl, c.crlCount as usize); - let mut ctmp: [u8; 48] = [0; 48]; - for i in ccrl.iter() { - if !(*i).is_null() { - copy_nonoverlapping(*i, ctmp.as_mut_ptr(), 48); - crl.push(CertificateSerialNo(ctmp)); - } - } - } - return Certificate { - serialNo: CertificateSerialNo(c.serialNo), + serial_no: CertificateSerialNo(c.serialNo), flags: c.flags, timestamp: c.timestamp, validity: c.validity, subject: CertificateSubject::new_from_capi(&c.subject), - issuer: Identity::new_from_capi(c.issuer, false), - issuerName: CertificateName::new_from_capi(&c.issuerName), - extendedAttributes: Vec::from(std::slice::from_raw_parts(c.extendedAttributes, c.extendedAttributesSize as usize)), - maxPathLength: c.maxPathLength as u32, - crl: crl, + issuer: if c.issuer.is_null() { None } else { Some(Identity::new_from_capi(c.issuer, false)) }, + issuer_name: CertificateName::new_from_capi(&c.issuerName), + extended_attributes: Vec::from(std::slice::from_raw_parts(c.extendedAttributes, c.extendedAttributesSize as usize)), + max_path_length: c.maxPathLength as u32, signature: Vec::from(std::slice::from_raw_parts(c.signature, c.signatureSize as usize)), }; } } pub(crate) unsafe fn to_capi(&self) -> CertificateCAPIContainer { - let mut capi_crls: Vec<*const u8> = Vec::new(); - capi_crls.reserve(self.crl.len()); - for i in self.crl.iter() { - capi_crls.push((*i).0.as_ptr()); - } - let subject = unsafe { self.subject.to_capi() }; CertificateCAPIContainer { certificate: ztcore::ZT_Certificate { - serialNo: self.serialNo.0, + serialNo: self.serial_no.0, flags: self.flags, timestamp: self.timestamp, validity: self.validity, subject: subject.subject, - issuer: self.issuer.capi, - issuerName: unsafe { self.issuerName.to_capi() }, - extendedAttributes: self.extendedAttributes.as_ptr(), - extendedAttributesSize: self.extendedAttributes.len() as c_uint, - maxPathLength: self.maxPathLength as c_uint, - crl: capi_crls.as_ptr(), - crlCount: capi_crls.len() as c_uint, + issuer: if self.issuer.is_some() { self.issuer.as_ref().unwrap().capi } else { null() }, + issuerName: unsafe { self.issuer_name.to_capi() }, + extendedAttributes: self.extended_attributes.as_ptr(), + extendedAttributesSize: self.extended_attributes.len() as c_uint, + maxPathLength: self.max_path_length as c_uint, signature: self.signature.as_ptr(), signatureSize: self.signature.len() as c_uint, }, - certificate_crls: capi_crls, subject_container: subject, } } @@ -669,3 +709,15 @@ impl Certificate { implement_to_from_json!(Certificate); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#[cfg(test)] +mod tests { + use crate::*; + + #[test] + fn certificate_serial_no() { + let test: [u8; 48] = [1; 48]; + let sn = CertificateSerialNo::from(&test[0..48]); + assert!(test.eq(&sn.0)); + } +} diff --git a/rust-zerotier-core/src/endpoint.rs b/rust-zerotier-core/src/endpoint.rs index 1b6bc51ec..5d15f3052 100644 --- a/rust-zerotier-core/src/endpoint.rs +++ b/rust-zerotier-core/src/endpoint.rs @@ -1,9 +1,25 @@ -use crate::*; -use crate::bindings::capi as ztcore; -use num_traits::FromPrimitive; -use std::os::raw::{c_char, c_int}; use std::ffi::CStr; use std::mem::MaybeUninit; +use std::os::raw::{c_char, c_int}; + +use num_derive::{FromPrimitive, ToPrimitive}; +use num_traits::FromPrimitive; + +use crate::*; +use crate::bindings::capi as ztcore; + +#[derive(FromPrimitive,ToPrimitive)] +pub enum EndpointType { + Nil = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_NIL as isize, + ZeroTier = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ZEROTIER as isize, + Ethernet = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ETHERNET as isize, + WifiDirect = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_WIFI_DIRECT as isize, + Bluetooth = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_BLUETOOTH as isize, + Ip = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP as isize, + IpUdp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_UDP as isize, + IpTcp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_TCP as isize, + IpHttp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_HTTP as isize, +} pub struct Endpoint { pub type_: EndpointType, @@ -11,7 +27,6 @@ pub struct Endpoint { } impl Endpoint { - #[inline] pub(crate) fn new_from_capi(ep: &ztcore::ZT_Endpoint) -> Endpoint { return Endpoint{ type_: EndpointType::from_u32(ep.type_ as u32).unwrap(), @@ -37,12 +52,12 @@ impl Endpoint { impl ToString for Endpoint { fn to_string(&self) -> String { - let mut buf: [u8; 1024] = [0; 1024]; unsafe { - if ztcore::ZT_Endpoint_toString(&(self.capi) as *const ztcore::ZT_Endpoint, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() { + let mut buf: MaybeUninit<[c_char; 1024]> = MaybeUninit::uninit(); + if ztcore::ZT_Endpoint_toString(&(self.capi) as *const ztcore::ZT_Endpoint, (*buf.as_mut_ptr()).as_mut_ptr(), 1024).is_null() { return String::from("(invalid)"); } - return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap()); + return cstr_to_string((*buf.as_ptr()).as_ptr(), 1024); } } } diff --git a/rust-zerotier-core/src/identity.rs b/rust-zerotier-core/src/identity.rs index a75ef3775..76ec78779 100644 --- a/rust-zerotier-core/src/identity.rs +++ b/rust-zerotier-core/src/identity.rs @@ -1,8 +1,11 @@ +use std::ffi::CStr; +use std::mem::MaybeUninit; +use std::os::raw::*; + +use num_traits::{FromPrimitive, ToPrimitive}; + use crate::*; use crate::bindings::capi as ztcore; -use std::os::raw::*; -use std::ffi::CStr; -use num_traits::{ToPrimitive, FromPrimitive}; #[derive(FromPrimitive,ToPrimitive)] pub enum IdentityType { @@ -55,12 +58,12 @@ impl Identity { } fn intl_to_string(&self, include_private: bool) -> String { - let mut buf: [u8; 2048] = [0; 2048]; unsafe { - if ztcore::ZT_Identity_toString(self.capi, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int, if include_private { 1 } else { 0 }).is_null() { + let mut buf: MaybeUninit<[c_char; 4096]> = MaybeUninit::uninit(); + if ztcore::ZT_Identity_toString(self.capi, (*buf.as_mut_ptr()).as_mut_ptr(), 4096, if include_private { 1 } else { 0 }).is_null() { return String::from("(invalid)"); } - return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap()); + return cstr_to_string((*buf.as_ptr()).as_ptr(), 4096); } } diff --git a/rust-zerotier-core/src/lib.rs b/rust-zerotier-core/src/lib.rs index 02f4bd613..1c0e33f96 100644 --- a/rust-zerotier-core/src/lib.rs +++ b/rust-zerotier-core/src/lib.rs @@ -23,13 +23,13 @@ use bindings::capi as ztcore; pub use identity::*; pub use address::Address; pub use fingerprint::Fingerprint; -pub use endpoint::Endpoint; +pub use endpoint::*; pub use certificate::*; pub use networkid::NetworkId; -pub use locator::Locator; +pub use locator::*; pub use path::Path; pub use peer::Peer; -pub use node::Node; +pub use node::*; pub use mac::MAC; pub use buffer::Buffer; pub use portableatomici64::PortableAtomicI64; @@ -72,19 +72,6 @@ pub enum CredentialType { Revocation = ztcore::ZT_CredentialType_ZT_CREDENTIAL_TYPE_REVOCATION as isize, } -#[derive(FromPrimitive,ToPrimitive)] -pub enum EndpointType { - Nil = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_NIL as isize, - ZeroTier = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ZEROTIER as isize, - Ethernet = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_ETHERNET as isize, - WifiDirect = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_WIFI_DIRECT as isize, - Bluetooth = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_BLUETOOTH as isize, - Ip = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP as isize, - IpUdp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_UDP as isize, - IpTcp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_TCP as isize, - IpHttp = ztcore::ZT_EndpointType_ZT_ENDPOINT_TYPE_IP_HTTP as isize, -} - #[derive(FromPrimitive,ToPrimitive)] pub enum TraceEventType { UnexpectedError = ztcore::ZT_TraceEventType_ZT_TRACE_UNEXPECTED_ERROR as isize, diff --git a/rust-zerotier-core/src/node.rs b/rust-zerotier-core/src/node.rs index 8d9602076..fd154fe7a 100644 --- a/rust-zerotier-core/src/node.rs +++ b/rust-zerotier-core/src/node.rs @@ -20,8 +20,10 @@ const NODE_BACKGROUND_MIN_DELAY: i64 = 250; pub struct NodeStatus { pub address: Address, pub identity: Identity, - pub publicIdentity: String, - pub secretIdentity: String, + #[serde(rename = "publicIdentity")] + pub public_identity: String, + #[serde(rename = "secretIdentity")] + pub secret_identity: String, pub online: bool } @@ -293,8 +295,8 @@ impl Node { return NodeStatus { address: Address(ns.address), identity: Identity::new_from_capi(&*ns.identity, false).clone(), - publicIdentity: String::from(CStr::from_ptr(ns.publicIdentity).to_str().unwrap()), - secretIdentity: String::from(CStr::from_ptr(ns.secretIdentity).to_str().unwrap()), + public_identity: String::from(CStr::from_ptr(ns.publicIdentity).to_str().unwrap()), + secret_identity: String::from(CStr::from_ptr(ns.secretIdentity).to_str().unwrap()), online: ns.online != 0 } } diff --git a/rust-zerotier-core/src/path.rs b/rust-zerotier-core/src/path.rs index e27063516..98185e530 100644 --- a/rust-zerotier-core/src/path.rs +++ b/rust-zerotier-core/src/path.rs @@ -2,12 +2,13 @@ use crate::*; use crate::bindings::capi as ztcore; use serde::{Deserialize, Serialize}; -#[allow(non_snake_case)] #[derive(Serialize, Deserialize)] pub struct Path { pub endpoint: Endpoint, - pub lastSend: i64, - pub lastReceive: i64, + #[serde(rename = "lastSend")] + pub last_send: i64, + #[serde(rename = "lastReceive")] + pub last_receive: i64, pub alive: bool, pub preferred: bool } @@ -17,8 +18,8 @@ impl Path { pub(crate) fn new_from_capi(p: &ztcore::ZT_Path) -> Path { Path{ endpoint: Endpoint::new_from_capi(&p.endpoint), - lastSend: p.lastSend, - lastReceive: p.lastReceive, + last_send: p.lastSend, + last_receive: p.lastReceive, alive: p.alive != 0, preferred: p.preferred != 0 } diff --git a/rust-zerotier-core/src/peer.rs b/rust-zerotier-core/src/peer.rs index 50d73ba52..8db1f67de 100644 --- a/rust-zerotier-core/src/peer.rs +++ b/rust-zerotier-core/src/peer.rs @@ -2,21 +2,24 @@ use crate::*; use crate::bindings::capi as ztcore; use serde::{Deserialize, Serialize}; -#[allow(non_snake_case)] #[derive(Serialize, Deserialize)] pub struct Peer { - address: Address, - identity: Identity, - fingerprint: Fingerprint, - versionMajor: i32, - versionMinor: i32, - versionRev: i32, - versionProto: i32, - latency: i32, - root: bool, - networks: Vec, - paths: Vec, - // locator: Locator + pub address: Address, + pub identity: Identity, + pub fingerprint: Fingerprint, + #[serde(rename = "versionMajor")] + pub version_major: i32, + #[serde(rename = "versionMinor")] + pub version_minor: i32, + #[serde(rename = "versionRev")] + pub version_rev: i32, + #[serde(rename = "versionProto")] + pub version_proto: i32, + pub latency: i32, + pub root: bool, + pub networks: Vec, + pub paths: Vec, + pub locator: Option } impl Peer { @@ -35,14 +38,15 @@ impl Peer { address: Address(p.address), identity: Identity::new_from_capi(p.identity, false).clone(), // clone to get a copy independent of 'p' fingerprint: Fingerprint::new_from_capi(&(*p.fingerprint)), - versionMajor: p.versionMajor as i32, - versionMinor: p.versionMinor as i32, - versionRev: p.versionRev as i32, - versionProto: p.versionProto as i32, + version_major: p.versionMajor as i32, + version_minor: p.versionMinor as i32, + version_rev: p.versionRev as i32, + version_proto: p.versionProto as i32, latency: p.latency as i32, root: p.root != 0, networks: networks, - paths: paths + paths: paths, + locator: if p.locator.is_null() { None } else { Some(Locator::new_from_capi(p.locator, false).clone() )} } } } diff --git a/rust-zerotier-core/src/virtualnetworkconfig.rs b/rust-zerotier-core/src/virtualnetworkconfig.rs index 64c798eab..b1eae7428 100644 --- a/rust-zerotier-core/src/virtualnetworkconfig.rs +++ b/rust-zerotier-core/src/virtualnetworkconfig.rs @@ -83,12 +83,16 @@ pub struct VirtualNetworkConfig { pub mac: MAC, pub name: String, pub status: VirtualNetworkStatus, + #[serde(rename = "type")] pub type_: VirtualNetworkType, pub mtu: u32, pub bridge: bool, - pub broadcastEnabled: bool, - pub netconfRevision: u64, - pub assignedAddresses: Vec, + #[serde(rename = "broadcastEnabled")] + pub broadcast_enabled: bool, + #[serde(rename = "netconfRevision")] + pub netconf_revision: u64, + #[serde(rename = "assignedAddresses")] + pub assigned_addresses: Vec, pub routes: Vec } @@ -97,6 +101,10 @@ const SIZEOF_SOCKADDR_IN6: ztcore::socklen_t = size_of::() /// Obtain a socket2::SockAddr from a C struct sockaddr_storage as used in the ZeroTier core. pub(crate) fn sockaddr_from_capi(ss: &ztcore::sockaddr_storage) -> Option { + // The transmute() calls in here are to work around the fact that socket2 + // uses sockaddr_storage from the libc crate, while ztcore uses it as + // generated from bindgen from the system headers. It's the same thing but + // Rust's type system doesn't know that. match ss.ss_family as u32 { ztcore::AF_INET => { unsafe { Some(SockAddr::from_raw_parts(transmute(ss as *const ztcore::sockaddr_storage), transmute(SIZEOF_SOCKADDR_IN))) } }, ztcore::AF_INET6 => { unsafe { Some(SockAddr::from_raw_parts(transmute(ss as *const ztcore::sockaddr_storage), transmute(SIZEOF_SOCKADDR_IN6))) } }, @@ -136,9 +144,9 @@ impl VirtualNetworkConfig { type_: FromPrimitive::from_u32(vnc.type_ as u32).unwrap(), mtu: vnc.mtu as u32, bridge: vnc.bridge != 0, - broadcastEnabled: vnc.broadcastEnabled != 0, - netconfRevision: vnc.netconfRevision as u64, - assignedAddresses: aa, + broadcast_enabled: vnc.broadcastEnabled != 0, + netconf_revision: vnc.netconfRevision as u64, + assigned_addresses: aa, routes: rts } }