temp workaround for oidc auth dropping issue

Add a method to "kick" the refresh thread and re-post the tokens in the case where the thread is somehow still running & controller pushes out an AUTH_REQUIRED.  This situation happens in a corner case still under investigation where the controller pushes out many copies of the network config repeatedly
This commit is contained in:
Grant Limberg 2022-01-20 09:44:56 -08:00
parent cdd25c389e
commit d719137565
No known key found for this signature in database
GPG Key ID: 2BA62CCABBB4095A
5 changed files with 47 additions and 4 deletions

View File

@ -1058,9 +1058,11 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,c
{
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PACKET_IDX_PAYLOAD)));
if (network) {
fprintf(stderr, "IncomingPacket::_doNETWORK_CONFIG %.16llx\n", network->id());
const uint64_t configUpdateId = network->handleConfigChunk(tPtr,packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD);
if (configUpdateId) {
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
fprintf(stderr, "Have config update ID: %llu\n", configUpdateId);
Packet outp(peer->address(), RR->identity.address(), Packet::VERB_OK);
outp.append((uint8_t)Packet::VERB_ECHO);
outp.append((uint64_t)packetId());
outp.append((uint64_t)network->id());
@ -1068,7 +1070,9 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,c
const int64_t now = RR->node->now();
outp.armor(peer->key(),true,peer->aesKeysIfSupported());
peer->recordOutgoingPacket(_path,outp.packetId(),outp.payloadLength(),outp.verb(),ZT_QOS_NO_FLOW,now);
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
if (!_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now())) {
fprintf(stderr, "Error sending VERB_OK after NETWORK_CONFIG packet for %.16llx\n", network->id());
}
}
}

View File

@ -984,7 +984,8 @@ uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Add
}
if (nc) {
this->setConfiguration(tPtr,*nc,true);
fprintf(stderr, "Network::handleConfigChucnk->setConfiguration %.16llx\n", this->_id);
this->setConfiguration(tPtr, *nc, true);
delete nc;
return configUpdateId;
} else {

View File

@ -285,6 +285,11 @@ public:
const char* url = zeroidc::zeroidc_get_auth_url(_idc);
memcpy(_config.authenticationURL, url, strlen(url));
_config.authenticationURL[strlen(url)] = 0;
if (zeroidc::zeroidc_is_running(_idc) && nwc->status == ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED) {
// TODO: kick the refresh thread
zeroidc::zeroidc_kick_refresh_thread(_idc);
}
}
}

View File

@ -218,3 +218,16 @@ pub extern "C" fn zeroidc_network_id_from_state(state: *const c_char) -> *const
let s = CString::new(split[1]).unwrap();
return s.into_raw();
}
#[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();
}

View File

@ -48,6 +48,7 @@ struct Inner {
access_token: Option<AccessToken>,
refresh_token: Option<RefreshToken>,
exp_time: u64,
kick: bool,
url: Option<Url>,
csrf_token: Option<CsrfToken>,
@ -109,6 +110,7 @@ impl ZeroIDC {
access_token: None,
refresh_token: None,
exp_time: 0,
kick: false,
url: None,
csrf_token: None,
@ -138,6 +140,11 @@ impl ZeroIDC {
Ok(idc)
}
fn kick_refresh_thread(&mut self) {
let local = Arc::clone(&self.inner);
(*local.lock().unwrap()).kick = true;
}
fn start(&mut self) {
let local = Arc::clone(&self.inner);
@ -160,7 +167,15 @@ impl ZeroIDC {
}
let refresh_token = (*inner_local.lock().unwrap()).refresh_token.clone();
if let Some(refresh_token) = refresh_token {
if now >= (exp - Duration::from_secs(30)) {
let should_kick = (*inner_local.lock().unwrap()).kick;
if now >= (exp - Duration::from_secs(30)) || should_kick {
if should_kick {
#[cfg(debug_assertions)] {
println!("refresh thread kicked");
}
(*inner_local.lock().unwrap()).kick = false;
}
let token_response = (*inner_local.lock().unwrap()).oidc_client.as_ref().map(|c| {
let res = c.exchange_refresh_token(&refresh_token)
.request(http_client);
@ -356,6 +371,11 @@ impl ZeroIDC {
pub 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| {
if i.running {
println!("refresh thread running. not setting new nonce or csrf");
return
}
let need_verifier = match i.pkce_verifier {
None => true,
_ => false,