Exit if loading an invalid identity from disk

Previously, if an invalid identity was loaded from disk, ZeroTier would
generate a new identity & chug along and generate a brand new identity
as if nothing happened.  When running in containers, this introduces the
possibility for key matter loss; especially when running in containers
where the identity files are mounted in the container read only.  In
this case, ZT will continue chugging along with a brand new identity
with no possibility of recovering the private key.

ZeroTier should exit upon loading of invalid identity.public/identity.secret #2056
This commit is contained in:
Grant Limberg 2023-07-17 11:29:22 -07:00
parent fdc2e0f692
commit 6a872af009
No known key found for this signature in database
GPG key ID: 8F2F97D3BE8D7735
3 changed files with 58 additions and 4 deletions

View file

@ -687,6 +687,7 @@
#define ZT_EXCEPTION_OUT_OF_MEMORY 101
#define ZT_EXCEPTION_PRIVATE_KEY_REQUIRED 102
#define ZT_EXCEPTION_INVALID_ARGUMENT 103
#define ZT_EXCEPTION_INVALID_IDENTITY 104
#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE 200
#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW 201
#define ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN 202

View file

@ -80,7 +80,11 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64
RR->identity.toString(false,RR->publicIdentityStr);
RR->identity.toString(true,RR->secretIdentityStr);
} else {
n = -1;
throw ZT_EXCEPTION_INVALID_IDENTITY;
}
if (!RR->identity.locallyValidate()) {
throw ZT_EXCEPTION_INVALID_IDENTITY;
}
}

View file

@ -786,6 +786,7 @@ public:
httplib::Server _controlPlane;
std::thread _serverThread;
bool _serverThreadRunning;
bool _allowTcpFallbackRelay;
bool _forceTcpRelay;
@ -887,6 +888,7 @@ public:
,_updateAutoApply(false)
,_controlPlane()
,_serverThread()
,_serverThreadRunning(false)
,_forceTcpRelay(false)
,_primaryPort(port)
,_udpPortPickerCounter(0)
@ -938,8 +940,9 @@ public:
#endif
_controlPlane.stop();
_serverThread.join();
if (_serverThreadRunning) {
_serverThread.join();
}
#ifdef ZT_USE_MINIUPNPC
delete _portMapper;
@ -1005,7 +1008,6 @@ public:
_node = new Node(this,(void *)0,&cb,OSUtils::now());
}
// local.conf
readLocalSettings();
applyLocalConfig();
@ -1260,6 +1262,51 @@ public:
Mutex::Lock _l(_termReason_m);
_termReason = ONE_UNRECOVERABLE_ERROR;
_fatalErrorMessage = std::string("unexpected exception in main thread: ")+e.what();
} catch (int e) {
Mutex::Lock _l(_termReason_m);
_termReason = ONE_UNRECOVERABLE_ERROR;
switch (e) {
case ZT_EXCEPTION_OUT_OF_BOUNDS: {
_fatalErrorMessage = "out of bounds exception";
break;
}
case ZT_EXCEPTION_OUT_OF_MEMORY: {
_fatalErrorMessage = "out of memory";
break;
}
case ZT_EXCEPTION_PRIVATE_KEY_REQUIRED: {
_fatalErrorMessage = "private key required";
break;
}
case ZT_EXCEPTION_INVALID_ARGUMENT: {
_fatalErrorMessage = "invalid argument";
break;
}
case ZT_EXCEPTION_INVALID_IDENTITY: {
_fatalErrorMessage = "invalid identity loaded from disk. Please remove identity.public and identity.secret from " + _homePath + " and try again";
break;
}
case ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE: {
_fatalErrorMessage = "invalid serialized data: invalid type";
break;
}
case ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW: {
_fatalErrorMessage = "invalid serialized data: overflow";
break;
}
case ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN: {
_fatalErrorMessage = "invalid serialized data: invalid cryptographic token";
break;
}
case ZT_EXCEPTION_INVALID_SERIALIZED_DATA_BAD_ENCODING: {
_fatalErrorMessage = "invalid serialized data: bad encoding";
break;
}
default: {
_fatalErrorMessage = "unexpected exception code: " + std::to_string(e);
break;
}
}
} catch ( ... ) {
Mutex::Lock _l(_termReason_m);
_termReason = ONE_UNRECOVERABLE_ERROR;
@ -2077,11 +2124,13 @@ public:
}
_serverThread = std::thread([&] {
_serverThreadRunning = true;
fprintf(stderr, "Starting Control Plane...\n");
if(!_controlPlane.listen_after_bind()) {
fprintf(stderr, "Error on listen_after_bind()\n");
}
fprintf(stderr, "Control Plane Stopped\n");
_serverThreadRunning = false;
});
}