mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 03:53:44 +02:00
Finally implement network join auth tokens, at least at the protocol level.
This commit is contained in:
parent
168b86fdcd
commit
b72847d504
2 changed files with 54 additions and 2 deletions
|
@ -658,11 +658,39 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
|
||||||
|
|
||||||
// Stop if network is private and member is not authorized
|
// Stop if network is private and member is not authorized
|
||||||
if ( (network.value("private",true)) && (!member.value("authorized",false)) ) {
|
if ( (network.value("private",true)) && (!member.value("authorized",false)) ) {
|
||||||
_writeJson(memberJP,member);
|
bool authenticatedViaToken = false;
|
||||||
return NetworkController::NETCONF_QUERY_ACCESS_DENIED;
|
char atok[256];
|
||||||
|
if (metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH_TOKEN,atok,sizeof(atok)) > 0) {
|
||||||
|
atok[255] = (char)0; // not necessary but YDIFLO
|
||||||
|
if (strlen(atok) > 0) { // extra sanity check
|
||||||
|
auto authTokens = network["authTokens"];
|
||||||
|
if (authTokens.is_array()) {
|
||||||
|
for(unsigned long i=0;i<authTokens.size();++i) {
|
||||||
|
auto at = authTokens[i];
|
||||||
|
if (at.is_object()) {
|
||||||
|
const uint64_t expires = at.value("expires",0ULL);
|
||||||
|
std::string tok = at.value("token","");
|
||||||
|
if ( ((expires == 0ULL)||(expires > now)) && (tok.length() > 0) && (tok == atok) ) {
|
||||||
|
authenticatedViaToken = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!authenticatedViaToken) {
|
||||||
|
_writeJson(memberJP,member);
|
||||||
|
return NetworkController::NETCONF_QUERY_ACCESS_DENIED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Else compose and send network config
|
// Else compose and send network config
|
||||||
|
|
||||||
|
// If we made it here for some reason other than authorized being true, such as this
|
||||||
|
// being a public network or via a bearer token, then we set this in the member config.
|
||||||
|
member["authorized"] = true;
|
||||||
|
|
||||||
nc.networkId = nwid;
|
nc.networkId = nwid;
|
||||||
nc.type = network.value("private",true) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC;
|
nc.type = network.value("private",true) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC;
|
||||||
nc.timestamp = now;
|
nc.timestamp = now;
|
||||||
|
@ -1308,6 +1336,26 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
||||||
network["rules"] = nrules;
|
network["rules"] = nrules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (b.count("authTokens")) {
|
||||||
|
auto authTokens = b["authTokens"];
|
||||||
|
if (authTokens.is_array()) {
|
||||||
|
json nat = json::array();
|
||||||
|
for(unsigned long i=0;i<authTokens.size();++i) {
|
||||||
|
auto token = authTokens[i];
|
||||||
|
if (token.is_object()) {
|
||||||
|
std::string tstr = token["token"];
|
||||||
|
if (tstr.length() > 0) {
|
||||||
|
json t = json::object();
|
||||||
|
t["token"] = tstr;
|
||||||
|
t["expires"] = token.value("expires",0ULL);
|
||||||
|
nat.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
network["authTokens"] = nat;
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch ( ... ) {
|
} catch ( ... ) {
|
||||||
return 400;
|
return 400;
|
||||||
}
|
}
|
||||||
|
@ -1319,6 +1367,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
||||||
if (!network.count("v4AssignMode")) network["v4AssignMode"] = "{\"zt\":false}"_json;
|
if (!network.count("v4AssignMode")) network["v4AssignMode"] = "{\"zt\":false}"_json;
|
||||||
if (!network.count("v6AssignMode")) network["v6AssignMode"] = "{\"rfc4193\":false,\"zt\":false,\"6plane\":false}"_json;
|
if (!network.count("v6AssignMode")) network["v6AssignMode"] = "{\"rfc4193\":false,\"zt\":false,\"6plane\":false}"_json;
|
||||||
if (!network.count("activeBridges")) network["activeBridges"] = json::array();
|
if (!network.count("activeBridges")) network["activeBridges"] = json::array();
|
||||||
|
if (!network.count("authTokens")) network["authTokens"] = json::array();
|
||||||
|
|
||||||
if (!network.count("rules")) {
|
if (!network.count("rules")) {
|
||||||
// If unspecified, rules are set to allow anything and behave like a flat L2 segment
|
// If unspecified, rules are set to allow anything and behave like a flat L2 segment
|
||||||
|
|
|
@ -101,6 +101,9 @@ namespace ZeroTier {
|
||||||
// Maximum number of tags this node can accept
|
// Maximum number of tags this node can accept
|
||||||
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS "mt"
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS "mt"
|
||||||
|
|
||||||
|
// Network join authorization token (if any)
|
||||||
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH_TOKEN "atok"
|
||||||
|
|
||||||
// These dictionary keys are short so they don't take up much room.
|
// These dictionary keys are short so they don't take up much room.
|
||||||
// By convention we use upper case for binary blobs, but it doesn't really matter.
|
// By convention we use upper case for binary blobs, but it doesn't really matter.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue