mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-05-29 08:33:44 +02:00
MOAR rust.
This commit is contained in:
parent
7fa7f6f07a
commit
ab2870cbb7
11 changed files with 297 additions and 53 deletions
|
@ -445,10 +445,10 @@ int ZT_Locator_verify(const ZT_Locator *loc, const ZT_Identity *signer)
|
|||
return reinterpret_cast<const ZeroTier::Locator *>(loc)->verify(*reinterpret_cast<const ZeroTier::Identity *>(signer)) ? 1 : 0;
|
||||
}
|
||||
|
||||
void ZT_Locator_delete(ZT_Locator *loc)
|
||||
void ZT_Locator_delete(const ZT_Locator *loc)
|
||||
{
|
||||
if (loc)
|
||||
delete reinterpret_cast<ZeroTier::Locator *>(loc);
|
||||
delete reinterpret_cast<const ZeroTier::Locator *>(loc);
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
@ -466,6 +466,18 @@ ZT_Identity *ZT_Identity_new(enum ZT_IdentityType type)
|
|||
}
|
||||
}
|
||||
|
||||
ZT_Identity *ZT_Identity_clone(const ZT_Identity *id)
|
||||
{
|
||||
if (id) {
|
||||
try {
|
||||
return reinterpret_cast<ZT_Identity *>(new ZeroTier::Identity(*reinterpret_cast<const ZeroTier::Identity *>(id)));
|
||||
} catch ( ... ) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ZT_Identity *ZT_Identity_fromString(const char *idStr)
|
||||
{
|
||||
if (!idStr)
|
||||
|
@ -541,10 +553,10 @@ const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id)
|
|||
return &(reinterpret_cast<const ZeroTier::Identity *>(id)->fingerprint());
|
||||
}
|
||||
|
||||
void ZT_Identity_delete(ZT_Identity *id)
|
||||
void ZT_Identity_delete(const ZT_Identity *id)
|
||||
{
|
||||
if (id)
|
||||
delete reinterpret_cast<ZeroTier::Identity *>(id);
|
||||
delete reinterpret_cast<const ZeroTier::Identity *>(id);
|
||||
}
|
||||
|
||||
/********************************************************************************************************************/
|
||||
|
|
|
@ -2452,6 +2452,14 @@ ZT_SDK_API void ZT_Node_setController(
|
|||
*/
|
||||
ZT_SDK_API ZT_Identity *ZT_Identity_new(enum ZT_IdentityType type);
|
||||
|
||||
/**
|
||||
* Make a copy of an identity
|
||||
*
|
||||
* @param id Identity to copy
|
||||
* @return Copy, must be freed with ZT_Identity_delete.
|
||||
*/
|
||||
ZT_SDK_API ZT_Identity *ZT_Identity_clone(const ZT_Identity *id);
|
||||
|
||||
/**
|
||||
* Create a new identity object from a string-serialized identity
|
||||
*
|
||||
|
@ -2560,7 +2568,7 @@ ZT_SDK_API const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id);
|
|||
*
|
||||
* @param id Identity to delete
|
||||
*/
|
||||
ZT_SDK_API void ZT_Identity_delete(ZT_Identity *id);
|
||||
ZT_SDK_API void ZT_Identity_delete(const ZT_Identity *id);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -2712,7 +2720,7 @@ ZT_SDK_API int ZT_Locator_verify(
|
|||
*
|
||||
* @param loc Locator to delete
|
||||
*/
|
||||
ZT_SDK_API void ZT_Locator_delete(ZT_Locator *loc);
|
||||
ZT_SDK_API void ZT_Locator_delete(const ZT_Locator *loc);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
|
|
|
@ -1,23 +1,9 @@
|
|||
pub struct Address(pub u64);
|
||||
pub type Address = u64;
|
||||
|
||||
impl Address {
|
||||
pub fn new_from_string(s: &str) -> Self {
|
||||
Address(u64::from_str_radix(s, 16).unwrap_or(0))
|
||||
}
|
||||
|
||||
pub fn to_u64(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
pub fn address_to_string(a: Address) -> String {
|
||||
format!("{:0>10x}", a as u64)
|
||||
}
|
||||
|
||||
impl ToString for Address {
|
||||
fn to_string(&self) -> String {
|
||||
format!("{:0>10x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Address {
|
||||
fn from(s: String) -> Self {
|
||||
Address::new_from_string(s.as_str())
|
||||
}
|
||||
pub fn address_from_string(s: &str) -> Address {
|
||||
return u64::from_str_radix(s, 16).unwrap_or(0) as Address;
|
||||
}
|
||||
|
|
143
rust-zerotier-core/src/certificate.rs
Normal file
143
rust-zerotier-core/src/certificate.rs
Normal file
|
@ -0,0 +1,143 @@
|
|||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
use std::ffi::CStr;
|
||||
use std::ptr::copy_nonoverlapping;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
pub struct CertificateName {
|
||||
pub serial_no: String,
|
||||
pub common_name: String,
|
||||
pub country: String,
|
||||
pub organization: String,
|
||||
pub unit: String,
|
||||
pub locality: String,
|
||||
pub province: String,
|
||||
pub street_address: String,
|
||||
pub postal_code: String,
|
||||
pub email: String,
|
||||
pub url: String,
|
||||
pub host: String
|
||||
}
|
||||
|
||||
pub struct CertificateNetwork {
|
||||
pub id: NetworkId,
|
||||
pub controller: Fingerprint
|
||||
}
|
||||
|
||||
pub struct CertificateIdentity {
|
||||
pub identity: Identity,
|
||||
pub locator: Locator
|
||||
}
|
||||
|
||||
pub struct CertificateSubject {
|
||||
pub timestamp: i64,
|
||||
pub identities: Box<[CertificateIdentity]>,
|
||||
pub networks: Box<[CertificateNetwork]>,
|
||||
pub certificates: Box<[[u8; 48]]>,
|
||||
pub update_urls: Box<[String]>,
|
||||
pub name: CertificateName,
|
||||
pub unique_id: Box<[u8]>,
|
||||
pub unique_id_proof_signature: Box<[u8]>
|
||||
}
|
||||
|
||||
pub struct Certificate {
|
||||
pub serial_no: [u8; 48],
|
||||
pub flags: u64,
|
||||
pub timestamp: i64,
|
||||
pub validity: [i64; 2],
|
||||
pub subject: CertificateSubject,
|
||||
pub issuer: Identity,
|
||||
pub issuer_name: CertificateName,
|
||||
pub extended_attributes: Box<[u8]>,
|
||||
pub max_path_length: u32,
|
||||
pub crl: Box<[u8; 48]>,
|
||||
pub signature: Box<[u8]>
|
||||
}
|
||||
|
||||
impl CertificateName {
|
||||
pub(crate) fn new_from_capi(cn: &ztcore::ZT_Certificate_Name) -> CertificateName {
|
||||
unsafe {
|
||||
return CertificateName {
|
||||
serial_no: String::from(CStr::from_ptr(cn.serialNo.as_ptr()).to_str().unwrap()),
|
||||
common_name: String::from(CStr::from_ptr(cn.commonName.as_ptr()).to_str().unwrap()),
|
||||
country: String::from(CStr::from_ptr(cn.country.as_ptr()).to_str().unwrap()),
|
||||
organization: String::from(CStr::from_ptr(cn.organization.as_ptr()).to_str().unwrap()),
|
||||
unit: String::from(CStr::from_ptr(cn.unit.as_ptr()).to_str().unwrap()),
|
||||
locality: String::from(CStr::from_ptr(cn.locality.as_ptr()).to_str().unwrap()),
|
||||
province: String::from(CStr::from_ptr(cn.province.as_ptr()).to_str().unwrap()),
|
||||
street_address: String::from(CStr::from_ptr(cn.streetAddress.as_ptr()).to_str().unwrap()),
|
||||
postal_code: String::from(CStr::from_ptr(cn.postalCode.as_ptr()).to_str().unwrap()),
|
||||
email: String::from(CStr::from_ptr(cn.email.as_ptr()).to_str().unwrap()),
|
||||
url: String::from(CStr::from_ptr(cn.url.as_ptr()).to_str().unwrap()),
|
||||
host: String::from(CStr::from_ptr(cn.host.as_ptr()).to_str().unwrap())
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CertificateNetwork {
|
||||
pub(crate) fn new_from_capi(cn: &ztcore::ZT_Certificate_Network) -> CertificateNetwork {
|
||||
CertificateNetwork{
|
||||
id: cn.id as NetworkId,
|
||||
controller: Fingerprint{
|
||||
address: cn.controller.address as Address,
|
||||
hash: cn.controller.hash
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CertificateIdentity {
|
||||
pub(crate) fn new_from_capi(ci: &ztcore::ZT_Certificate_Identity) -> CertificateIdentity {
|
||||
CertificateIdentity{
|
||||
identity: Identity::new_from_capi(ci.identity, false),
|
||||
locator: Locator::new_from_capi(ci.locator, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CertificateSubject {
|
||||
pub(crate) fn new_from_capi(cs: &ztcore::ZT_Certificate_Subject) -> CertificateSubject {
|
||||
unsafe {
|
||||
let cidentities: &[ztcore::ZT_Certificate_Identity] = std::slice::from_raw_parts(cs.identities, cs.identityCount as usize);
|
||||
let mut identities: Vec<CertificateIdentity> = Vec::new();
|
||||
for i in cidentities.iter() {
|
||||
identities.push(CertificateIdentity::new_from_capi(i));
|
||||
}
|
||||
|
||||
let cnetworks: &[ztcore::ZT_Certificate_Network] = std::slice::from_raw_parts(cs.networks, cs.networkCount as usize);
|
||||
let mut networks: Vec<CertificateNetwork> = Vec::new();
|
||||
for i in cnetworks.iter() {
|
||||
networks.push(CertificateNetwork::new_from_capi(i));
|
||||
}
|
||||
|
||||
let ccertificates: &[*const u8] = std::slice::from_raw_parts(cs.certificates, cs.certificateCount as usize);
|
||||
let mut certificates: Vec<[u8; 48]> = Vec::new();
|
||||
let mut ctmp: [u8; 48] = [0; 48];
|
||||
for i in ccertificates.iter() {
|
||||
copy_nonoverlapping(*i, ctmp.as_mut_ptr(), 48);
|
||||
certificates.push(ctmp.clone());
|
||||
}
|
||||
|
||||
let cupdate_urls: &[*const c_char] = std::slice::from_raw_parts(cs.updateURLs, cs.updateURLCount as usize);
|
||||
let mut update_urls: Vec<String> = Vec::new();
|
||||
for i in cupdate_urls.iter() {
|
||||
update_urls.push(CStr::from_ptr(*i).to_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
return CertificateSubject{
|
||||
timestamp: cs.timestamp,
|
||||
identities: identities.into_boxed_slice(),
|
||||
networks: networks.into_boxed_slice(),
|
||||
certificates: certificates.into_boxed_slice(),
|
||||
update_urls: update_urls.into_boxed_slice(),
|
||||
name: CertificateName::new_from_capi(&cs.name),
|
||||
unique_id: Box::from(std::slice::from_raw_parts(cs.uniqueId, cs.uniqueIdSize as usize).clone()),
|
||||
unique_id_proof_signature: Box::from(std::slice::from_raw_parts(cs.uniqueIdProofSignature, cs.uniqueIdProofSignatureSize as usize).clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Certificate {
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
use num_traits::FromPrimitive;
|
||||
use std::os::raw::c_char;
|
||||
use std::os::raw::{c_char, c_int};
|
||||
use std::ffi::CStr;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
|
@ -25,16 +25,25 @@ impl Endpoint {
|
|||
return Err(ResultCode::from_i32(ec).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn new_from_capi(ep: *const ztcore::ZT_Endpoint) -> Endpoint {
|
||||
unsafe {
|
||||
return Endpoint{
|
||||
ep_type: EndpointType::from_u32((*ep).type_ as u32).unwrap(),
|
||||
intl: *ep
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Endpoint {
|
||||
fn to_string(&self) -> String {
|
||||
let mut buf: [u8; 256] = [0; 256];
|
||||
let mut buf: [u8; 1024] = [0; 1024];
|
||||
unsafe {
|
||||
if ztcore::ZT_Endpoint_toString(&(self.intl) as *const ztcore::ZT_Endpoint,buf.as_mut_ptr() as *mut c_char, 1024).is_null() {
|
||||
if ztcore::ZT_Endpoint_toString(&(self.intl) as *const ztcore::ZT_Endpoint,buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() {
|
||||
return String::from("(invalid)");
|
||||
}
|
||||
return String::from(CStr::from_bytes_with_nul(&buf).unwrap().to_str().unwrap());
|
||||
return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ impl Fingerprint {
|
|||
if ztcore::ZT_Fingerprint_fromString(cfp.as_mut_ptr(), s.as_ptr() as *const c_char) != 0 {
|
||||
let fp = cfp.assume_init();
|
||||
return Ok(Fingerprint{
|
||||
address: Address(fp.address),
|
||||
address: fp.address as Address,
|
||||
hash: fp.hash
|
||||
});
|
||||
}
|
||||
|
@ -30,12 +30,12 @@ impl ToString for Fingerprint {
|
|||
let mut buf: [u8; 256] = [0; 256];
|
||||
unsafe {
|
||||
if ztcore::ZT_Fingerprint_toString(&ztcore::ZT_Fingerprint {
|
||||
address: self.address.to_u64(),
|
||||
address: self.address,
|
||||
hash: self.hash
|
||||
}, buf.as_mut_ptr() as *mut c_char, buf.len() as c_int).is_null() {
|
||||
return String::from("(invalid)");
|
||||
}
|
||||
return String::from(CStr::from_bytes_with_nul(&buf).unwrap().to_str().unwrap());
|
||||
return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,27 +2,36 @@ use crate::*;
|
|||
use crate::bindings::capi as ztcore;
|
||||
use std::os::raw::*;
|
||||
use std::ffi::CStr;
|
||||
use num_traits::ToPrimitive;
|
||||
use num_traits::{ToPrimitive, FromPrimitive};
|
||||
|
||||
pub struct Identity {
|
||||
pub id_type: IdentityType,
|
||||
pub address: Address,
|
||||
capi: *mut ztcore::ZT_Identity,
|
||||
capi: *const ztcore::ZT_Identity,
|
||||
requires_delete: bool
|
||||
}
|
||||
|
||||
impl Identity {
|
||||
pub(crate) fn new_from_capi(id: *const ztcore::ZT_Identity, requires_delete: bool) -> Identity {
|
||||
unsafe {
|
||||
let idt = ztcore::ZT_Identity_type(id);
|
||||
let a = ztcore::ZT_Identity_address(id);
|
||||
return Identity{
|
||||
id_type: FromPrimitive::from_u32(idt as u32).unwrap(),
|
||||
address: a as Address,
|
||||
capi: id,
|
||||
requires_delete: requires_delete
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate(id_type: IdentityType) -> Result<Identity, ResultCode> {
|
||||
unsafe {
|
||||
let id = ztcore::ZT_Identity_new(id_type.to_u32().unwrap());
|
||||
if id.is_null() {
|
||||
return Err(ResultCode::ErrorBadParameter); // this only really happens if type is invalid
|
||||
}
|
||||
let a = ztcore::ZT_Identity_address(id);
|
||||
return Ok(Identity {
|
||||
id_type: id_type,
|
||||
address: Address(a as u64),
|
||||
capi: id,
|
||||
});
|
||||
return Ok(Identity::new_from_capi(id, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,13 +41,7 @@ impl Identity {
|
|||
if id.is_null() {
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
let idt = ztcore::ZT_Identity_type(id);
|
||||
let a = ztcore::ZT_Identity_address(id);
|
||||
return Ok(Identity {
|
||||
id_type: num_traits::FromPrimitive::from_u32(idt).unwrap(),
|
||||
address: Address(a as u64),
|
||||
capi: id
|
||||
});
|
||||
return Ok(Identity::new_from_capi(id, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +51,7 @@ impl Identity {
|
|||
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() {
|
||||
return String::from("(invalid)");
|
||||
}
|
||||
return String::from(CStr::from_bytes_with_nul(&buf).unwrap().to_str().unwrap());
|
||||
return String::from(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +77,7 @@ impl Identity {
|
|||
unsafe {
|
||||
let cfp = ztcore::ZT_Identity_fingerprint(self.capi);
|
||||
return Fingerprint {
|
||||
address: Address((*cfp).address),
|
||||
address: (*cfp).address,
|
||||
hash: (*cfp).hash
|
||||
}
|
||||
}
|
||||
|
@ -107,8 +110,10 @@ impl Identity {
|
|||
|
||||
impl Drop for Identity {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ztcore::ZT_Identity_delete(self.capi);
|
||||
if self.requires_delete && !self.capi.is_null() {
|
||||
unsafe {
|
||||
ztcore::ZT_Identity_delete(self.capi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,16 @@ mod identity;
|
|||
mod address;
|
||||
mod fingerprint;
|
||||
mod endpoint;
|
||||
mod inetaddress;
|
||||
mod certificate;
|
||||
mod networkid;
|
||||
mod locator;
|
||||
|
||||
pub use identity::Identity;
|
||||
pub use address::Address;
|
||||
pub use address::*;
|
||||
pub use fingerprint::Fingerprint;
|
||||
pub use endpoint::Endpoint;
|
||||
pub use networkid::*;
|
||||
pub use locator::Locator;
|
||||
|
||||
use bindings::capi as ztcore;
|
||||
use num_derive::FromPrimitive;
|
||||
|
|
68
rust-zerotier-core/src/locator.rs
Normal file
68
rust-zerotier-core/src/locator.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
use std::os::raw::{c_char, c_int, c_uint};
|
||||
use std::ffi::CStr;
|
||||
|
||||
pub struct Locator {
|
||||
capi: *const ztcore::ZT_Locator,
|
||||
requires_delete: bool
|
||||
}
|
||||
|
||||
impl Locator {
|
||||
pub(crate) fn new_from_capi(l: *const ztcore::ZT_Locator, requires_delete: bool) -> Locator {
|
||||
Locator{
|
||||
capi: l,
|
||||
requires_delete: requires_delete
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_string(s: &str) -> Result<Locator, ResultCode> {
|
||||
unsafe {
|
||||
let l = ztcore::ZT_Locator_fromString(s.as_ptr() as *const c_char);
|
||||
if l.is_null() {
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
return Ok(Locator::new_from_capi(l, true));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn timestamp(&self) -> i64 {
|
||||
unsafe {
|
||||
return ztcore::ZT_Locator_timestamp(self.capi) as i64;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn endpoints(&self) -> Box<[Endpoint]> {
|
||||
let mut eps: Vec<Endpoint> = Vec::new();
|
||||
unsafe {
|
||||
let ep_count = ztcore::ZT_Locator_endpointCount(self.capi) as usize;
|
||||
eps.reserve(ep_count as usize);
|
||||
for i in 0..ep_count {
|
||||
eps.push(Endpoint::new_from_capi(ztcore::ZT_Locator_endpoint(self.capi, i as c_uint)));
|
||||
}
|
||||
}
|
||||
eps.into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Locator {
|
||||
fn drop(&mut self) {
|
||||
if self.requires_delete && !self.capi.is_null() {
|
||||
unsafe {
|
||||
ztcore::ZT_Locator_delete(self.capi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Locator {
|
||||
fn to_string(&self) -> String {
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
unsafe {
|
||||
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(CStr::from_bytes_with_nul(buf.as_ref()).unwrap().to_str().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
9
rust-zerotier-core/src/networkid.rs
Normal file
9
rust-zerotier-core/src/networkid.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
pub type NetworkId = u64;
|
||||
|
||||
pub fn network_id_to_string(n: NetworkId) -> String {
|
||||
format!("{:0>16x}", n as u64)
|
||||
}
|
||||
|
||||
pub fn network_id_from_string(s: &str) -> NetworkId {
|
||||
return u64::from_str_radix(s, 16).unwrap_or(0) as NetworkId;
|
||||
}
|
Loading…
Add table
Reference in a new issue