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);
}
/*
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

View File

@ -61,17 +61,12 @@ public:
_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:
DB::ChangeListener *const _listener;
std::atomic_bool _running;
std::thread _syncCheckerThread;
std::vector< std::shared_ptr< DB > > _dbs;
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

View File

@ -1424,10 +1424,12 @@ void EmbeddedNetworkController::_request(
ms.identity = identity;
}
/*
if (authenticationExpiryTime > 0) {
std::lock_guard<std::mutex> l(_expiringSoon_l);
_expiringSoon.insert(std::pair<int64_t, _MemberStatusKey>(authenticationExpiryTime, msk));
}
*/
}
} else {
// If they are not authorized, STOP!
@ -1441,18 +1443,13 @@ void EmbeddedNetworkController::_request(
// If we made it this far, they are authorized (and authenticated).
// -------------------------------------------------------------------------
int64_t credentialtmd = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
if (now > ns.mostRecentDeauthTime) {
// If we recently de-authorized a member, shrink credential TTL/max delta to
// be below the threshold required to exclude it. Cap this to a min/max to
// prevent jitter or absurdly large values.
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;
}
// Default timeout: 15 minutes. Maximum: two hours. Can be specified by an optional field in the network config
// if something longer than 15 minutes is desired. Minimum is 5 minutes since shorter than that would be flaky.
int64_t credentialtmd = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_DFL_MAX_DELTA;
if (network.contains("certificateTimeoutWindowSize")) {
credentialtmd = (int64_t)network["certificateTimeoutWindowSize"];
}
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());
@ -1884,6 +1881,7 @@ void EmbeddedNetworkController::_startThreads()
}
}
/*
expired.clear();
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));
}
_expiringSoon.erase(s++);
} else if ((when - now) > 1000) {
} else if ((when - now) > 500) {
// Don't bother going further into the future than necessary.
break;
} else {
// Skip not yet expired entries.
++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) {
onNetworkMemberDeauthorize(nullptr, e->first, e->second);
}

View File

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

View File

@ -42,19 +42,18 @@
/**
* 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
*
* This is just slightly over three minutes and provides three retries for
* all currently online members to refresh.
* Maximum time delta for COMs, tags, and capabilities
*/
#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