Can get Central JSON bundle back to zerotier-one window

This commit is contained in:
Grant Limberg 2021-12-16 11:37:58 -08:00
parent 1375e3e2f5
commit 2293b0703f
No known key found for this signature in database
GPG Key ID: 2BA62CCABBB4095A
5 changed files with 69 additions and 37 deletions

View File

@ -310,13 +310,13 @@ public:
return ""; return "";
} }
void doTokenExchange(const char *code) { const char* doTokenExchange(const char *code) {
if (_idc == nullptr) { if (_idc == nullptr) {
fprintf(stderr, "ainfo or idc null\n"); fprintf(stderr, "ainfo or idc null\n");
return; return "";
} }
zeroidc::zeroidc_token_exchange(_idc, code); const char *ret = zeroidc::zeroidc_token_exchange(_idc, code);
zeroidc::zeroidc_set_nonce_and_csrf( zeroidc::zeroidc_set_nonce_and_csrf(
_idc, _idc,
_config.ssoState, _config.ssoState,
@ -326,6 +326,7 @@ public:
const char* url = zeroidc::zeroidc_get_auth_url(_idc); const char* url = zeroidc::zeroidc_get_auth_url(_idc);
memcpy(_config.authenticationURL, url, strlen(url)); memcpy(_config.authenticationURL, url, strlen(url));
_config.authenticationURL[strlen(url)] = 0; _config.authenticationURL[strlen(url)] = 0;
return ret;
} }
uint64_t getExpiryTime() { uint64_t getExpiryTime() {
@ -1674,7 +1675,7 @@ public:
if (_nets.find(id) != _nets.end()) { if (_nets.find(id) != _nets.end()) {
NetworkState& ns = _nets[id]; NetworkState& ns = _nets[id];
const char* code = zeroidc::zeroidc_get_url_param_value("code", path.c_str()); const char* code = zeroidc::zeroidc_get_url_param_value("code", path.c_str());
ns.doTokenExchange(code); res = json::parse(ns.doTokenExchange(code));
scode = 200; scode = 200;
} else { } else {
scode = 404; scode = 404;

1
zeroidc/Cargo.lock generated
View File

@ -1494,6 +1494,7 @@ name = "zeroidc"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64 0.13.0", "base64 0.13.0",
"bytes",
"cbindgen", "cbindgen",
"jsonwebtoken", "jsonwebtoken",
"openidconnect", "openidconnect",

View File

@ -19,6 +19,7 @@ reqwest = "0.11.7"
jsonwebtoken = "7.2.0" jsonwebtoken = "7.2.0"
serde = "1.0.130" serde = "1.0.130"
time = { version = "0.3.5", features = ["formatting"] } time = { version = "0.3.5", features = ["formatting"] }
bytes = "1.1.0"
[build-dependencies] [build-dependencies]
cbindgen = "0.20.0" cbindgen = "0.20.0"

View File

@ -166,15 +166,15 @@ pub extern "C" fn zeroidc_get_auth_url(ptr: *mut ZeroIDC) -> *const c_char {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn zeroidc_token_exchange(idc: *mut ZeroIDC, code: *const c_char ) { pub extern "C" fn zeroidc_token_exchange(idc: *mut ZeroIDC, code: *const c_char ) -> *const c_char {
if idc.is_null() { if idc.is_null() {
println!("idc is null"); println!("idc is null");
return return std::ptr::null();
} }
if code.is_null() { if code.is_null() {
println!("code is null"); println!("code is null");
return return std::ptr::null();
} }
let idc = unsafe { let idc = unsafe {
&mut *idc &mut *idc
@ -182,7 +182,9 @@ pub extern "C" fn zeroidc_token_exchange(idc: *mut ZeroIDC, code: *const c_char
let code = unsafe{CStr::from_ptr(code)}.to_str().unwrap(); let code = unsafe{CStr::from_ptr(code)}.to_str().unwrap();
idc.do_token_exchange( code); let ret = idc.do_token_exchange( code);
let ret = CString::new(ret).unwrap();
return ret.into_raw();
} }
#[no_mangle] #[no_mangle]

View File

@ -1,21 +1,26 @@
pub mod ext; pub mod ext;
extern crate base64; extern crate base64;
extern crate bytes;
extern crate openidconnect; extern crate openidconnect;
extern crate time; extern crate time;
extern crate url; extern crate url;
use std::time::{SystemTime, UNIX_EPOCH, Duration}; use bytes::Bytes;
use time::{OffsetDateTime, format_description};
use std::sync::{Arc, Mutex};
use std::thread::{sleep, spawn, JoinHandle};
use serde::{Deserialize, Serialize};
use openidconnect::core::{CoreClient, CoreProviderMetadata, CoreResponseType}; use openidconnect::core::{CoreClient, CoreProviderMetadata, CoreResponseType};
use openidconnect::reqwest::http_client; use openidconnect::reqwest::http_client;
use openidconnect::{AccessToken, AuthorizationCode, AuthenticationFlow, ClientId, CsrfToken, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, RefreshToken, Scope, TokenResponse}; use openidconnect::{AccessToken, AuthorizationCode, AuthenticationFlow, ClientId, CsrfToken, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, RefreshToken, Scope, TokenResponse};
use serde::{Deserialize, Serialize};
use std::str::from_utf8;
use std::sync::{Arc, Mutex};
use std::thread::{sleep, spawn, JoinHandle};
use std::time::{SystemTime, UNIX_EPOCH, Duration};
use time::{OffsetDateTime, format_description};
use jsonwebtoken::{dangerous_insecure_decode}; use jsonwebtoken::{dangerous_insecure_decode};
use url::Url; use url::Url;
use time::ext::NumericalDuration;
pub struct ZeroIDC { pub struct ZeroIDC {
inner: Arc<Mutex<Inner>>, inner: Arc<Mutex<Inner>>,
@ -277,26 +282,30 @@ impl ZeroIDC {
fn set_nonce_and_csrf(&mut self, csrf_token: String, nonce: String) { fn set_nonce_and_csrf(&mut self, csrf_token: String, nonce: String) {
let local = Arc::clone(&self.inner); let local = Arc::clone(&self.inner);
(*local.lock().expect("can't lock inner")).as_opt().map(|i| { (*local.lock().expect("can't lock inner")).as_opt().map(|i| {
let mut csrf_diff = false; let need_verifier = match i.pkce_verifier {
let mut nonce_diff = false; None => true,
let mut need_verifier = false; _ => false,
};
match i.pkce_verifier {
None => { let csrf_diff = if let Some(csrf) = i.csrf_token.clone() {
need_verifier = true;
},
_ => (),
}
if let Some(csrf) = i.csrf_token.clone() {
if *csrf.secret() != csrf_token { if *csrf.secret() != csrf_token {
csrf_diff = true; true
} else {
false
} }
} } else {
if let Some(n) = i.nonce.clone() { false
};
let nonce_diff = if let Some(n) = i.nonce.clone() {
if *n.secret() != nonce { if *n.secret() != nonce {
nonce_diff = true; true
} else {
false
} }
} } else {
false
};
if need_verifier || csrf_diff || nonce_diff { if need_verifier || csrf_diff || nonce_diff {
let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256(); let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256();
@ -341,10 +350,10 @@ impl ZeroIDC {
} }
} }
fn do_token_exchange(&mut self, code: &str) { fn do_token_exchange(&mut self, code: &str) -> String {
let local = Arc::clone(&self.inner); let local = Arc::clone(&self.inner);
let mut should_start = false; let mut should_start = false;
(*local.lock().unwrap()).as_opt().map(|i| { let res = (*local.lock().unwrap()).as_opt().map(|i| {
if let Some(verifier) = i.pkce_verifier.take() { if let Some(verifier) = i.pkce_verifier.take() {
let token_response = i.oidc_client.as_ref().map(|c| { let token_response = i.oidc_client.as_ref().map(|c| {
let r = c.exchange_code(AuthorizationCode::new(code.to_string())) let r = c.exchange_code(AuthorizationCode::new(code.to_string()))
@ -361,7 +370,7 @@ impl ZeroIDC {
}, },
} }
}); });
// TODO: do stuff with token response
if let Some(Some(tok)) = token_response { if let Some(Some(tok)) = token_response {
let id_token = tok.id_token().unwrap(); let id_token = tok.id_token().unwrap();
println!("ID token: {}", id_token.to_string()); println!("ID token: {}", id_token.to_string());
@ -399,6 +408,23 @@ impl ZeroIDC {
i.refresh_token = Some(t.clone()); i.refresh_token = Some(t.clone());
should_start = true; should_start = true;
} }
let access_token = tok.access_token();
println!("Access Token: {}", access_token.secret());
let refresh_token = tok.refresh_token();
println!("Refresh Token: {}", refresh_token.unwrap().secret());
let bytes = match res.bytes() {
Ok(bytes) => bytes,
Err(_) => Bytes::from(""),
};
let bytes = match from_utf8(bytes.as_ref()) {
Ok(bytes) => bytes.to_string(),
Err(_) => "".to_string(),
};
return bytes;
}, },
Err(res) => { Err(res) => {
println!("hit url: {}", res.url().unwrap().as_str()); println!("hit url: {}", res.url().unwrap().as_str());
@ -408,20 +434,21 @@ impl ZeroIDC {
} }
} }
let access_token = tok.access_token();
println!("Access Token: {}", access_token.secret());
let refresh_token = tok.refresh_token();
println!("Refresh Token: {}", refresh_token.unwrap().secret());
} else { } else {
println!("invalid split length?!?"); println!("invalid split length?!?");
} }
} }
} }
"".to_string()
}); });
if should_start { if should_start {
self.start(); self.start();
} }
return match res {
Some(res) => res,
_ => "".to_string(),
};
} }
} }