From 2293b0703f9e9ace1e7245cab0368756e8a5f1b8 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 16 Dec 2021 11:37:58 -0800 Subject: [PATCH] Can get Central JSON bundle back to zerotier-one window --- service/OneService.cpp | 9 +++-- zeroidc/Cargo.lock | 1 + zeroidc/Cargo.toml | 1 + zeroidc/src/ext.rs | 10 +++-- zeroidc/src/lib.rs | 85 ++++++++++++++++++++++++++++-------------- 5 files changed, 69 insertions(+), 37 deletions(-) diff --git a/service/OneService.cpp b/service/OneService.cpp index 9648c5dd8..4291402bb 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -310,13 +310,13 @@ public: return ""; } - void doTokenExchange(const char *code) { + const char* doTokenExchange(const char *code) { if (_idc == nullptr) { 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( _idc, _config.ssoState, @@ -326,6 +326,7 @@ public: const char* url = zeroidc::zeroidc_get_auth_url(_idc); memcpy(_config.authenticationURL, url, strlen(url)); _config.authenticationURL[strlen(url)] = 0; + return ret; } uint64_t getExpiryTime() { @@ -1674,7 +1675,7 @@ public: if (_nets.find(id) != _nets.end()) { NetworkState& ns = _nets[id]; const char* code = zeroidc::zeroidc_get_url_param_value("code", path.c_str()); - ns.doTokenExchange(code); + res = json::parse(ns.doTokenExchange(code)); scode = 200; } else { scode = 404; diff --git a/zeroidc/Cargo.lock b/zeroidc/Cargo.lock index 2447d8d21..24c126e8c 100644 --- a/zeroidc/Cargo.lock +++ b/zeroidc/Cargo.lock @@ -1494,6 +1494,7 @@ name = "zeroidc" version = "0.1.0" dependencies = [ "base64 0.13.0", + "bytes", "cbindgen", "jsonwebtoken", "openidconnect", diff --git a/zeroidc/Cargo.toml b/zeroidc/Cargo.toml index 058564be5..e74c9efaa 100644 --- a/zeroidc/Cargo.toml +++ b/zeroidc/Cargo.toml @@ -19,6 +19,7 @@ reqwest = "0.11.7" jsonwebtoken = "7.2.0" serde = "1.0.130" time = { version = "0.3.5", features = ["formatting"] } +bytes = "1.1.0" [build-dependencies] cbindgen = "0.20.0" diff --git a/zeroidc/src/ext.rs b/zeroidc/src/ext.rs index 740cced29..d39f82452 100644 --- a/zeroidc/src/ext.rs +++ b/zeroidc/src/ext.rs @@ -166,15 +166,15 @@ pub extern "C" fn zeroidc_get_auth_url(ptr: *mut ZeroIDC) -> *const c_char { } #[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() { println!("idc is null"); - return + return std::ptr::null(); } if code.is_null() { println!("code is null"); - return + return std::ptr::null(); } let idc = unsafe { &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(); - idc.do_token_exchange( code); + let ret = idc.do_token_exchange( code); + let ret = CString::new(ret).unwrap(); + return ret.into_raw(); } #[no_mangle] diff --git a/zeroidc/src/lib.rs b/zeroidc/src/lib.rs index 3e48c11c0..5b4458249 100644 --- a/zeroidc/src/lib.rs +++ b/zeroidc/src/lib.rs @@ -1,21 +1,26 @@ pub mod ext; extern crate base64; +extern crate bytes; extern crate openidconnect; extern crate time; extern crate url; -use std::time::{SystemTime, UNIX_EPOCH, Duration}; -use time::{OffsetDateTime, format_description}; -use std::sync::{Arc, Mutex}; -use std::thread::{sleep, spawn, JoinHandle}; -use serde::{Deserialize, Serialize}; +use bytes::Bytes; use openidconnect::core::{CoreClient, CoreProviderMetadata, CoreResponseType}; use openidconnect::reqwest::http_client; 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 url::Url; +use time::ext::NumericalDuration; pub struct ZeroIDC { inner: Arc>, @@ -277,26 +282,30 @@ impl ZeroIDC { fn set_nonce_and_csrf(&mut self, csrf_token: String, nonce: String) { let local = Arc::clone(&self.inner); (*local.lock().expect("can't lock inner")).as_opt().map(|i| { - let mut csrf_diff = false; - let mut nonce_diff = false; - let mut need_verifier = false; - - match i.pkce_verifier { - None => { - need_verifier = true; - }, - _ => (), - } - if let Some(csrf) = i.csrf_token.clone() { + let need_verifier = match i.pkce_verifier { + None => true, + _ => false, + }; + + let csrf_diff = if let Some(csrf) = i.csrf_token.clone() { if *csrf.secret() != csrf_token { - csrf_diff = true; + true + } else { + false } - } - if let Some(n) = i.nonce.clone() { + } else { + false + }; + + let nonce_diff = if let Some(n) = i.nonce.clone() { if *n.secret() != nonce { - nonce_diff = true; + true + } else { + false } - } + } else { + false + }; if need_verifier || csrf_diff || nonce_diff { 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 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() { let token_response = i.oidc_client.as_ref().map(|c| { 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 { let id_token = tok.id_token().unwrap(); println!("ID token: {}", id_token.to_string()); @@ -399,6 +408,23 @@ impl ZeroIDC { i.refresh_token = Some(t.clone()); 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) => { 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 { println!("invalid split length?!?"); } } } + "".to_string() }); if should_start { self.start(); } + return match res { + Some(res) => res, + _ => "".to_string(), + }; } }