| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * (c) ZeroTier, Inc.
- * https://www.zerotier.com/
- */
- use std::ffi::{CStr, CString};
- use std::os::raw::c_char;
- #[cfg(feature = "ztcontroller")]
- use tokio::runtime;
- use url::Url;
- #[cfg(feature = "ztcontroller")]
- static mut RT: Option<tokio::runtime::Runtime> = None;
- #[cfg(feature = "ztcontroller")]
- static START: std::sync::Once = std::sync::Once::new();
- #[cfg(feature = "ztcontroller")]
- static SHUTDOWN: std::sync::Once = std::sync::Once::new();
- #[cfg(feature = "ztcontroller")]
- #[no_mangle]
- pub unsafe extern "C" fn init_async_runtime() {
- START.call_once(|| {
- let rt = runtime::Builder::new_multi_thread()
- .worker_threads(4)
- .thread_name("rust-async-worker")
- .enable_all()
- .build()
- .expect("Failed to create tokio runtime");
- unsafe { RT = Some(rt) };
- });
- }
- #[cfg(feature = "ztcontroller")]
- #[no_mangle]
- #[allow(static_mut_refs)]
- pub unsafe extern "C" fn shutdown_async_runtime() {
- SHUTDOWN.call_once(|| {
- // Shutdown the tokio runtime
- unsafe {
- if let Some(rt) = RT.take() {
- rt.shutdown_timeout(std::time::Duration::from_secs(5));
- }
- }
- });
- }
- #[cfg(feature = "zeroidc")]
- use crate::zeroidc::ZeroIDC;
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_new(
- issuer: *const c_char,
- client_id: *const c_char,
- auth_endpoint: *const c_char,
- provider: *const c_char,
- web_listen_port: u16,
- ) -> *mut ZeroIDC {
- if issuer.is_null() {
- println!("issuer is null");
- return std::ptr::null_mut();
- }
- if client_id.is_null() {
- println!("client_id is null");
- return std::ptr::null_mut();
- }
- if provider.is_null() {
- println!("provider is null");
- return std::ptr::null_mut();
- }
- if auth_endpoint.is_null() {
- println!("auth_endpoint is null");
- return std::ptr::null_mut();
- }
- let issuer = unsafe { CStr::from_ptr(issuer) };
- let client_id = unsafe { CStr::from_ptr(client_id) };
- let provider = unsafe { CStr::from_ptr(provider) };
- let auth_endpoint = unsafe { CStr::from_ptr(auth_endpoint) };
- match ZeroIDC::new(
- issuer.to_str().unwrap(),
- client_id.to_str().unwrap(),
- provider.to_str().unwrap(),
- auth_endpoint.to_str().unwrap(),
- web_listen_port,
- ) {
- Ok(idc) => Box::into_raw(Box::new(idc)),
- Err(s) => {
- println!("Error creating ZeroIDC instance: {}", s);
- std::ptr::null_mut()
- }
- }
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_delete(ptr: *mut ZeroIDC) {
- if ptr.is_null() {
- return;
- }
- let idc = unsafe {
- assert!(!ptr.is_null());
- &mut *ptr
- };
- idc.stop();
- unsafe {
- let _ = Box::from_raw(ptr);
- }
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_start(ptr: *mut ZeroIDC) {
- let idc = unsafe {
- assert!(!ptr.is_null());
- &mut *ptr
- };
- idc.start();
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_stop(ptr: *mut ZeroIDC) {
- let idc = unsafe {
- assert!(!ptr.is_null());
- &mut *ptr
- };
- idc.stop();
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_is_running(ptr: *mut ZeroIDC) -> bool {
- let idc = unsafe {
- assert!(!ptr.is_null());
- &mut *ptr
- };
- idc.is_running()
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_get_exp_time(ptr: *mut ZeroIDC) -> u64 {
- let id = unsafe {
- assert!(!ptr.is_null());
- &mut *ptr
- };
- id.get_exp_time()
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_set_nonce_and_csrf(
- ptr: *mut ZeroIDC,
- csrf_token: *const c_char,
- nonce: *const c_char,
- ) {
- let idc = unsafe {
- assert!(!ptr.is_null());
- &mut *ptr
- };
- if csrf_token.is_null() {
- println!("csrf_token is null");
- return;
- }
- if nonce.is_null() {
- println!("nonce is null");
- return;
- }
- let csrf_token = unsafe { CStr::from_ptr(csrf_token) }.to_str().unwrap().to_string();
- let nonce = unsafe { CStr::from_ptr(nonce) }.to_str().unwrap().to_string();
- idc.set_nonce_and_csrf(csrf_token, nonce);
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn free_cstr(s: *mut c_char) {
- if s.is_null() {
- println!("passed a null object");
- return;
- }
- unsafe {
- let _ = CString::from_raw(s);
- }
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_get_auth_url(ptr: *mut ZeroIDC) -> *mut c_char {
- if ptr.is_null() {
- println!("passed a null object");
- return std::ptr::null_mut();
- }
- let idc = unsafe { &mut *ptr };
- let s = CString::new(idc.auth_url()).unwrap();
- s.into_raw()
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_token_exchange(idc: *mut ZeroIDC, code: *const c_char) -> *mut c_char {
- if idc.is_null() {
- println!("idc is null");
- return std::ptr::null_mut();
- }
- if code.is_null() {
- println!("code is null");
- return std::ptr::null_mut();
- }
- let idc = unsafe { &mut *idc };
- let code = unsafe { CStr::from_ptr(code) }.to_str().unwrap();
- let ret = idc.do_token_exchange(code);
- match ret {
- Ok(ret) => {
- #[cfg(debug_assertions)]
- {
- println!("do_token_exchange ret: {}", ret);
- }
- let ret = CString::new(ret).unwrap();
- ret.into_raw()
- }
- Err(e) => {
- #[cfg(debug_assertions)]
- {
- println!("do_token_exchange err: {}", e);
- }
- let errstr = format!("{{\"errorMessage\": \"{}\"}}", e);
- let ret = CString::new(errstr).unwrap();
- ret.into_raw()
- }
- }
- }
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_get_url_param_value(param: *const c_char, path: *const c_char) -> *mut c_char {
- if param.is_null() {
- println!("param is null");
- return std::ptr::null_mut();
- }
- if path.is_null() {
- println!("path is null");
- return std::ptr::null_mut();
- }
- let param = unsafe { CStr::from_ptr(param) }.to_str().unwrap();
- let path = unsafe { CStr::from_ptr(path) }.to_str().unwrap();
- let url = "http://localhost:9993".to_string() + path;
- let url = Url::parse(&url).unwrap();
- let pairs = url.query_pairs();
- for p in pairs {
- if p.0 == param {
- let s = CString::new(p.1.into_owned()).unwrap();
- return s.into_raw();
- }
- }
- std::ptr::null_mut()
- }
- #[no_mangle]
- pub unsafe extern "C" fn zeroidc_network_id_from_state(state: *const c_char) -> *mut c_char {
- if state.is_null() {
- println!("state is null");
- return std::ptr::null_mut();
- }
- let state = unsafe { CStr::from_ptr(state) }.to_str().unwrap();
- let split = state.split('_');
- let split = split.collect::<Vec<&str>>();
- if split.len() != 2 {
- return std::ptr::null_mut();
- }
- let s = CString::new(split[1]).unwrap();
- s.into_raw()
- }
- #[cfg(all(
- feature = "zeroidc",
- any(
- all(target_os = "linux", target_arch = "x86"),
- all(target_os = "linux", target_arch = "x86_64"),
- all(target_os = "linux", target_arch = "aarch64"),
- target_os = "windows",
- target_os = "macos",
- )
- ))]
- #[no_mangle]
- pub unsafe 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();
- }
- #[cfg(feature = "ztcontroller")]
- use crate::smeeclient::NetworkJoinedParams;
- #[cfg(feature = "ztcontroller")]
- use crate::smeeclient::SmeeClient;
- #[cfg(feature = "ztcontroller")]
- #[no_mangle]
- pub unsafe extern "C" fn smee_client_new(
- temporal_url: *const c_char,
- namespace: *const c_char,
- task_queue: *const c_char,
- ) -> *mut SmeeClient {
- let url = unsafe {
- assert!(!temporal_url.is_null());
- CStr::from_ptr(temporal_url).to_str().unwrap()
- };
- let ns = unsafe {
- assert!(!namespace.is_null());
- CStr::from_ptr(namespace).to_str().unwrap()
- };
- let tq = unsafe {
- assert!(!task_queue.is_null());
- CStr::from_ptr(task_queue).to_str().unwrap()
- };
- match SmeeClient::new(url, ns, tq) {
- Ok(c) => Box::into_raw(Box::new(c)),
- Err(e) => {
- println!("error creating smee client instance: {}", e);
- std::ptr::null_mut()
- }
- }
- }
- #[cfg(feature = "ztcontroller")]
- #[no_mangle]
- pub unsafe extern "C" fn smee_client_delete(ptr: *mut SmeeClient) {
- if ptr.is_null() {
- return;
- }
- let smee = unsafe {
- assert!(!ptr.is_null());
- Box::from_raw(&mut *ptr)
- };
- drop(smee);
- }
- #[cfg(feature = "ztcontroller")]
- #[no_mangle]
- pub unsafe extern "C" fn smee_client_notify_network_joined(
- smee_instance: *mut SmeeClient,
- network_id: *const c_char,
- member_id: *const c_char,
- ) -> bool {
- let nwid = unsafe {
- assert!(!network_id.is_null());
- CStr::from_ptr(network_id).to_str().unwrap()
- };
- let mem_id = unsafe {
- assert!(!member_id.is_null());
- CStr::from_ptr(member_id).to_str().unwrap()
- };
- let smee = unsafe {
- assert!(!smee_instance.is_null());
- &mut *smee_instance
- };
- let params = NetworkJoinedParams::new(nwid, mem_id);
- match smee.notify_network_joined(params) {
- Ok(()) => true,
- Err(e) => {
- println!("error notifying network joined: {0}", e);
- false
- }
- }
- }
|