Tighten certificate window and deprecate sending of revocations for ordinary SSO timeouts. Revocations should only be for deliberate deauth to kick people off networks. Cert window should now stay within refresh window for SSO so normal cert expiration should handle it just fine.

This commit is contained in:
Adam Ierymenko 2022-04-15 14:23:26 -04:00
parent d0c68096df
commit 55a99f34d0
No known key found for this signature in database
GPG Key ID: C8877CF2D7A5D7F3
5 changed files with 21 additions and 98 deletions

View File

@ -248,51 +248,4 @@ void DBMirrorSet::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,u
_listener->onNetworkMemberDeauthorize(this,networkId,memberId); _listener->onNetworkMemberDeauthorize(this,networkId,memberId);
} }
/*
void DBMirrorSet::membersExpiring(std::set< std::pair<uint64_t, uint64_t> > &soon, std::set< std::pair<uint64_t, uint64_t> > &expired)
{
std::unique_lock<std::mutex> l(_membersExpiringSoon_l);
int64_t now = OSUtils::now();
for(auto next=_membersExpiringSoon.begin();next!=_membersExpiringSoon.end();) {
if (next->first > now) {
const uint64_t nwid = next->second.first;
const uint64_t memberId = next->second.second;
nlohmann::json network, member;
if (this->get(nwid, network, memberId, member)) {
try {
const bool authorized = member["authorized"];
const bool ssoExempt = member["ssoExempt"];
const int64_t authenticationExpiryTime = member["authenticationExpiryTime"];
if ((authenticationExpiryTime == next->first)&&(authorized)&&(!ssoExempt)) {
if ((authenticationExpiryTime - now) > ZT_MEMBER_AUTH_TIMEOUT_NOTIFY_BEFORE) {
// Stop when we get to entries too far in the future.
break;
} else {
const bool ssoEnabled = network["ssoEnabled"];
if (ssoEnabled)
soon.insert(std::pair<uint64_t, uint64_t>(nwid, memberId));
}
} else {
// Obsolete entry, no longer authorized, or SSO exempt.
}
} catch ( ... ) {
// Invalid member object, erase.
}
} else {
// Not found.
}
}
_membersExpiringSoon.erase(next++);
}
}
*/
/*
void DBMirrorSet::memberWillExpire(int64_t expTime, uint64_t nwid, uint64_t memberId)
{
std::unique_lock<std::mutex> l(_membersExpiringSoon_l);
_membersExpiringSoon.insert(std::pair< int64_t, std::pair< uint64_t, uint64_t > >(expTime, std::pair< uint64_t, uint64_t >(nwid, memberId)));
}
*/
} // namespace ZeroTier } // namespace ZeroTier

View File

@ -61,17 +61,12 @@ public:
_dbs.push_back(db); _dbs.push_back(db);
} }
//void membersExpiring(std::set< std::pair<uint64_t, uint64_t> > &soon, std::set< std::pair<uint64_t, uint64_t> > &expired);
//void memberWillExpire(int64_t expTime, uint64_t nwid, uint64_t memberId);
private: private:
DB::ChangeListener *const _listener; DB::ChangeListener *const _listener;
std::atomic_bool _running; std::atomic_bool _running;
std::thread _syncCheckerThread; std::thread _syncCheckerThread;
std::vector< std::shared_ptr< DB > > _dbs; std::vector< std::shared_ptr< DB > > _dbs;
mutable std::mutex _dbs_l; mutable std::mutex _dbs_l;
//std::set< std::pair< int64_t, std::pair<uint64_t, uint64_t> > > _membersExpiringSoon;
//mutable std::mutex _membersExpiringSoon_l;
}; };
} // namespace ZeroTier } // namespace ZeroTier

View File

@ -1424,10 +1424,12 @@ void EmbeddedNetworkController::_request(
ms.identity = identity; ms.identity = identity;
} }
/*
if (authenticationExpiryTime > 0) { if (authenticationExpiryTime > 0) {
std::lock_guard<std::mutex> l(_expiringSoon_l); std::lock_guard<std::mutex> l(_expiringSoon_l);
_expiringSoon.insert(std::pair<int64_t, _MemberStatusKey>(authenticationExpiryTime, msk)); _expiringSoon.insert(std::pair<int64_t, _MemberStatusKey>(authenticationExpiryTime, msk));
} }
*/
} }
} else { } else {
// If they are not authorized, STOP! // If they are not authorized, STOP!
@ -1441,18 +1443,13 @@ void EmbeddedNetworkController::_request(
// If we made it this far, they are authorized (and authenticated). // If we made it this far, they are authorized (and authenticated).
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
int64_t credentialtmd = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA; // Default timeout: 15 minutes. Maximum: two hours. Can be specified by an optional field in the network config
if (now > ns.mostRecentDeauthTime) { // if something longer than 15 minutes is desired. Minimum is 5 minutes since shorter than that would be flaky.
// If we recently de-authorized a member, shrink credential TTL/max delta to int64_t credentialtmd = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_DFL_MAX_DELTA;
// be below the threshold required to exclude it. Cap this to a min/max to if (network.contains("certificateTimeoutWindowSize")) {
// prevent jitter or absurdly large values. credentialtmd = (int64_t)network["certificateTimeoutWindowSize"];
const uint64_t deauthWindow = now - ns.mostRecentDeauthTime;
if (deauthWindow < ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MIN_MAX_DELTA) {
credentialtmd = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MIN_MAX_DELTA;
} else if (deauthWindow < (ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA + 5000ULL)) {
credentialtmd = deauthWindow - 5000ULL;
}
} }
credentialtmd = std::max(std::min(credentialtmd, ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA), ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MIN_MAX_DELTA);
std::unique_ptr<NetworkConfig> nc(new NetworkConfig()); std::unique_ptr<NetworkConfig> nc(new NetworkConfig());
@ -1884,6 +1881,7 @@ void EmbeddedNetworkController::_startThreads()
} }
} }
/*
expired.clear(); expired.clear();
int64_t now = OSUtils::now(); int64_t now = OSUtils::now();
{ {
@ -1898,38 +1896,16 @@ void EmbeddedNetworkController::_startThreads()
expired.push_back(std::pair<uint64_t, uint64_t>(s->second.networkId, s->second.nodeId)); expired.push_back(std::pair<uint64_t, uint64_t>(s->second.networkId, s->second.nodeId));
} }
_expiringSoon.erase(s++); _expiringSoon.erase(s++);
} else if ((when - now) > 1000) { } else if ((when - now) > 500) {
// Don't bother going further into the future than necessary. // Don't bother going further into the future than necessary.
break; break;
} else { } else {
// Skip not yet expired entries.
++s; ++s;
} }
} }
} }
/*
std::set< std::pair<uint64_t, uint64_t> > soon;
std::set< std::pair<uint64_t, uint64_t> > expired;
_db.membersExpiring(soon, expired);
for(auto s=soon.begin();s!=soon.end();++s) {
Identity identity;
Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> lastMetaData;
{
std::unique_lock<std::mutex> ll(_memberStatus_l);
auto ms = _memberStatus.find(_MemberStatusKey(s->first, s->second));
if (ms != _memberStatus.end()) {
lastMetaData = ms->second.lastRequestMetaData;
identity = ms->second.identity;
}
}
if (identity) {
request(s->first,InetAddress(),0,identity,lastMetaData);
}
}
*/
/*
for(auto e=expired.begin();e!=expired.end();++e) { for(auto e=expired.begin();e!=expired.end();++e) {
onNetworkMemberDeauthorize(nullptr, e->first, e->second); onNetworkMemberDeauthorize(nullptr, e->first, e->second);
} }

View File

@ -154,8 +154,8 @@ private:
std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus; std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus;
std::mutex _memberStatus_l; std::mutex _memberStatus_l;
std::multimap< int64_t, _MemberStatusKey > _expiringSoon; //std::multimap< int64_t, _MemberStatusKey > _expiringSoon;
std::mutex _expiringSoon_l; //std::mutex _expiringSoon_l;
RedisConfig *_rc; RedisConfig *_rc;
std::string _ssoRedirectURL; std::string _ssoRedirectURL;

View File

@ -42,19 +42,18 @@
/** /**
* Default maximum time delta for COMs, tags, and capabilities * Default maximum time delta for COMs, tags, and capabilities
*
* The current value is two hours, providing ample time for a controller to
* experience fail-over, etc.
*/ */
#define ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA 7200000ULL #define ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_DFL_MAX_DELTA ((int64_t)(1000 * 60 * 15))
/** /**
* Default minimum credential TTL and maxDelta for COM timestamps * Maximum time delta for COMs, tags, and capabilities
*
* This is just slightly over three minutes and provides three retries for
* all currently online members to refresh.
*/ */
#define ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MIN_MAX_DELTA 185000ULL #define ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA ((int64_t)(1000 * 60 * 60 * 2))
/**
* Minimum credential TTL and maxDelta for COM timestamps
*/
#define ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MIN_MAX_DELTA ((int64_t)(1000 * 60 * 5))
/** /**
* Flag: enable broadcast * Flag: enable broadcast