123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- /*
- * Copyright (c)2021 ZeroTier, Inc.
- *
- * Use of this software is governed by the Business Source License included
- * in the LICENSE.TXT file in the project's root directory.
- *
- * Change Date: 2026-01-01
- *
- * On the date above, in accordance with the Business Source License, use
- * of this software will be governed by version 2.0 of the Apache License.
- */
- use std::ffi::{CStr, CString};
- use std::os::raw::c_char;
- use url::Url;
- use crate::ZeroIDC;
- #[cfg(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 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(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 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(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 extern "C" fn zeroidc_start(ptr: *mut ZeroIDC) {
- let idc = unsafe {
- assert!(!ptr.is_null());
- &mut *ptr
- };
- idc.start();
- }
- #[cfg(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 extern "C" fn zeroidc_stop(ptr: *mut ZeroIDC) {
- let idc = unsafe {
- assert!(!ptr.is_null());
- &mut *ptr
- };
- idc.stop();
- }
- #[cfg(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 extern "C" fn zeroidc_is_running(ptr: *mut ZeroIDC) -> bool {
- let idc = unsafe {
- assert!(!ptr.is_null());
- &mut *ptr
- };
- idc.is_running()
- }
- #[no_mangle]
- pub 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(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 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(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 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(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 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(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 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 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 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(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 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();
- }
|