You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
329 lines
8.4 KiB
329 lines
8.4 KiB
/* 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; |
|
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 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(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(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(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(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() |
|
} |
|
|
|
#[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(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(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(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(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(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(); |
|
}
|
|
|