mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-21 05:53:09 +00:00
Revise bearer token code in controller, and add relay policy as a meta-data item presented to controller by nodes (to facilitate future meshiness).
This commit is contained in:
parent
24fce0be86
commit
68e549233d
@ -566,42 +566,69 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
|
|||||||
|
|
||||||
// Determine whether and how member is authorized
|
// Determine whether and how member is authorized
|
||||||
const char *authorizedBy = (const char *)0;
|
const char *authorizedBy = (const char *)0;
|
||||||
if (!_jB(network["private"],true)) {
|
if (_jB(member["authorized"],false)) {
|
||||||
|
authorizedBy = "memberIsAuthorized";
|
||||||
|
} else if (!_jB(network["private"],true)) {
|
||||||
authorizedBy = "networkIsPublic";
|
authorizedBy = "networkIsPublic";
|
||||||
// If member already has an authorized field, leave it alone. That way its state is
|
|
||||||
// preserved if the user toggles the network back to private. Otherwise set it to
|
|
||||||
// true by default for new members of public nets.
|
|
||||||
if (!member.count("authorized")) {
|
if (!member.count("authorized")) {
|
||||||
member["authorized"] = true;
|
member["authorized"] = true;
|
||||||
member["lastAuthorizedTime"] = now;
|
json ah;
|
||||||
member["lastAuthorizedBy"] = authorizedBy;
|
ah["a"] = true;
|
||||||
|
ah["by"] = authorizedBy;
|
||||||
|
ah["ts"] = now;
|
||||||
|
ah["ct"] = json();
|
||||||
|
ah["c"] = json();
|
||||||
|
member["authHistory"].push_back(ah);
|
||||||
member["lastModified"] = now;
|
member["lastModified"] = now;
|
||||||
auto revj = member["revision"];
|
json &revj = member["revision"];
|
||||||
member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
||||||
}
|
}
|
||||||
} else if (_jB(member["authorized"],false)) {
|
|
||||||
authorizedBy = "memberIsAuthorized";
|
|
||||||
} else {
|
} else {
|
||||||
char atok[256];
|
char presentedAuth[512];
|
||||||
if (metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH_TOKEN,atok,sizeof(atok)) > 0) {
|
if (metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH,presentedAuth,sizeof(presentedAuth)) > 0) {
|
||||||
atok[255] = (char)0; // not necessary but YDIFLO
|
presentedAuth[511] = (char)0; // sanity check
|
||||||
if (strlen(atok) > 0) { // extra sanity check since we never want to compare a null token on either side
|
|
||||||
auto authTokens = network["authTokens"];
|
// Check for bearer token presented by member
|
||||||
|
if ((strlen(presentedAuth) > 6)&&(!strncmp(presentedAuth,"token:",6))) {
|
||||||
|
const char *const presentedToken = presentedAuth + 6;
|
||||||
|
|
||||||
|
json &authTokens = network["authTokens"];
|
||||||
if (authTokens.is_array()) {
|
if (authTokens.is_array()) {
|
||||||
for(unsigned long i=0;i<authTokens.size();++i) {
|
for(unsigned long i=0;i<authTokens.size();++i) {
|
||||||
auto at = authTokens[i];
|
json &token = authTokens[i];
|
||||||
if (at.is_object()) {
|
if (token.is_object()) {
|
||||||
const uint64_t expires = _jI(at["expires"],0ULL);
|
const uint64_t expires = _jI(token["expires"],0ULL);
|
||||||
std::string tok = _jS(at["token"],"");
|
const uint64_t maxUses = _jI(token["maxUsesPerMember"],0ULL);
|
||||||
if ( ((expires == 0ULL)||(expires > now)) && (tok.length() > 0) && (tok == atok) ) {
|
std::string tstr = _jS(token["token"],"");
|
||||||
|
|
||||||
|
if (((expires == 0ULL)||(expires > now))&&(tstr == presentedToken)) {
|
||||||
|
bool usable = (maxUses == 0);
|
||||||
|
if (!usable) {
|
||||||
|
uint64_t useCount = 0;
|
||||||
|
json &ahist = member["authHistory"];
|
||||||
|
if (ahist.is_array()) {
|
||||||
|
for(unsigned long j=0;j<ahist.size();++j) {
|
||||||
|
json &ah = ahist[j];
|
||||||
|
if ((_jS(ah["ct"],"") == "token")&&(_jS(ah["c"],"") == tstr)&&(_jB(ah["a"],false)))
|
||||||
|
++useCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usable = (useCount < maxUses);
|
||||||
|
}
|
||||||
|
if (usable) {
|
||||||
authorizedBy = "token";
|
authorizedBy = "token";
|
||||||
member["authorized"] = true; // tokens actually change member authorization state
|
member["authorized"] = true;
|
||||||
member["lastAuthorizedTime"] = now;
|
json ah;
|
||||||
member["lastAuthorizedBy"] = authorizedBy;
|
ah["a"] = true;
|
||||||
|
ah["by"] = authorizedBy;
|
||||||
|
ah["ts"] = now;
|
||||||
|
ah["ct"] = "token";
|
||||||
|
ah["c"] = tstr;
|
||||||
|
member["authHistory"].push_back(ah);
|
||||||
member["lastModified"] = now;
|
member["lastModified"] = now;
|
||||||
auto revj = member["revision"];
|
json &revj = member["revision"];
|
||||||
member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
member["revision"] = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1137,16 +1164,15 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
|||||||
|
|
||||||
if (b.count("authorized")) {
|
if (b.count("authorized")) {
|
||||||
const bool newAuth = _jB(b["authorized"],false);
|
const bool newAuth = _jB(b["authorized"],false);
|
||||||
const bool oldAuth = _jB(member["authorized"],false);
|
if (newAuth != _jB(member["authorized"],false)) {
|
||||||
if (newAuth != oldAuth) {
|
member["authorized"] = newAuth;
|
||||||
if (newAuth) {
|
json ah;
|
||||||
member["authorized"] = true;
|
ah["a"] = newAuth;
|
||||||
member["lastAuthorizedTime"] = now;
|
ah["by"] = "api";
|
||||||
member["lastAuthorizedBy"] = "user";
|
ah["ts"] = now;
|
||||||
} else {
|
ah["ct"] = json();
|
||||||
member["authorized"] = false;
|
ah["c"] = json();
|
||||||
member["lastDeauthorizedTime"] = now;
|
member["authHistory"].push_back(ah);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1427,13 +1453,14 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
|||||||
if (authTokens.is_array()) {
|
if (authTokens.is_array()) {
|
||||||
json nat = json::array();
|
json nat = json::array();
|
||||||
for(unsigned long i=0;i<authTokens.size();++i) {
|
for(unsigned long i=0;i<authTokens.size();++i) {
|
||||||
auto token = authTokens[i];
|
json &token = authTokens[i];
|
||||||
if (token.is_object()) {
|
if (token.is_object()) {
|
||||||
std::string tstr = token["token"];
|
std::string tstr = token["token"];
|
||||||
if (tstr.length() > 0) {
|
if (tstr.length() > 0) {
|
||||||
json t = json::object();
|
json t = json::object();
|
||||||
t["token"] = tstr;
|
t["token"] = tstr;
|
||||||
t["expires"] = _jI(token["expires"],0ULL);
|
t["expires"] = _jI(token["expires"],0ULL);
|
||||||
|
t["maxUsesPerMember"] = _jI(token["maxUsesPerMember"],0ULL);
|
||||||
nat.push_back(t);
|
nat.push_back(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,9 +143,7 @@ private:
|
|||||||
inline void _initMember(nlohmann::json &member)
|
inline void _initMember(nlohmann::json &member)
|
||||||
{
|
{
|
||||||
if (!member.count("authorized")) member["authorized"] = false;
|
if (!member.count("authorized")) member["authorized"] = false;
|
||||||
if (!member.count("lastAuthorizedTime")) member["lastAuthorizedTime"] = 0ULL;
|
if (!member.count("authHistory")) member["authHistory"] = nlohmann::json::array();
|
||||||
if (!member.count("lastAuthorizedBy")) member["lastAuthorizedBy"] = "";
|
|
||||||
if (!member.count("lastDeauthorizedTime")) member["lastDeauthorizedTime"] = 0ULL;
|
|
||||||
if (!member.count("ipAssignments")) member["ipAssignments"] = nlohmann::json::array();
|
if (!member.count("ipAssignments")) member["ipAssignments"] = nlohmann::json::array();
|
||||||
if (!member.count("recentLog")) member["recentLog"] = nlohmann::json::array();
|
if (!member.count("recentLog")) member["recentLog"] = nlohmann::json::array();
|
||||||
if (!member.count("activeBridge")) member["activeBridge"] = false;
|
if (!member.count("activeBridge")) member["activeBridge"] = false;
|
||||||
|
@ -229,9 +229,7 @@ This returns an object containing all currently online members and the most rece
|
|||||||
| nwid | string | 16-digit network ID | no |
|
| nwid | string | 16-digit network ID | no |
|
||||||
| clock | integer | Current clock, ms since epoch | no |
|
| clock | integer | Current clock, ms since epoch | no |
|
||||||
| authorized | boolean | Is member authorized? (for private networks) | YES |
|
| authorized | boolean | Is member authorized? (for private networks) | YES |
|
||||||
| lastAuthorizedTime | integer | Time 'authorized' was last set to 'true' | no |
|
| authHistory | array[object] | History of auth changes, latest at end | no |
|
||||||
| lastAuthorizedBy | string | What last set 'authorized' to 'true'? | no |
|
|
||||||
| lastDeauthorizedTime | integer | Time 'authorized' was last set to 'false' | no |
|
|
||||||
| activeBridge | boolean | Member is able to bridge to other Ethernet nets | YES |
|
| activeBridge | boolean | Member is able to bridge to other Ethernet nets | YES |
|
||||||
| identity | string | Member's public ZeroTier identity (if known) | no |
|
| identity | string | Member's public ZeroTier identity (if known) | no |
|
||||||
| ipAssignments | array[string] | Managed IP address assignments | YES |
|
| ipAssignments | array[string] | Managed IP address assignments | YES |
|
||||||
|
@ -1001,6 +1001,7 @@ void Network::requestConfiguration()
|
|||||||
|
|
||||||
Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> rmd;
|
Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> rmd;
|
||||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION);
|
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,(uint64_t)ZT_NETWORKCONFIG_VERSION);
|
||||||
|
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR,(uint64_t)ZT_VENDOR_ZEROTIER);
|
||||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION);
|
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION,(uint64_t)ZT_PROTO_VERSION);
|
||||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MAJOR);
|
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MAJOR);
|
||||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MINOR);
|
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,(uint64_t)ZEROTIER_ONE_VERSION_MINOR);
|
||||||
@ -1011,6 +1012,7 @@ void Network::requestConfiguration()
|
|||||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS);
|
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_MAX_NETWORK_TAGS,(uint64_t)ZT_MAX_NETWORK_TAGS);
|
||||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0);
|
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS,(uint64_t)0);
|
||||||
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION);
|
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,(uint64_t)ZT_RULES_ENGINE_REVISION);
|
||||||
|
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_RELAY_POLICY,(uint64_t)RR->node->relayPolicy());
|
||||||
|
|
||||||
if (ctrl == RR->identity.address()) {
|
if (ctrl == RR->identity.address()) {
|
||||||
if (RR->localNetworkController) {
|
if (RR->localNetworkController) {
|
||||||
|
@ -108,9 +108,13 @@ namespace ZeroTier {
|
|||||||
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION "v"
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION "v"
|
||||||
// Protocol version (see Packet.hpp)
|
// Protocol version (see Packet.hpp)
|
||||||
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION "pv"
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_PROTOCOL_VERSION "pv"
|
||||||
// Software major, minor, revision
|
// Software vendor
|
||||||
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_VENDOR "vend"
|
||||||
|
// Software major version
|
||||||
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION "majv"
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION "majv"
|
||||||
|
// Software minor version
|
||||||
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION "minv"
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION "minv"
|
||||||
|
// Software revision
|
||||||
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION "revv"
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION "revv"
|
||||||
// Rules engine revision
|
// Rules engine revision
|
||||||
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV "revr"
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV "revr"
|
||||||
@ -123,9 +127,11 @@ 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)
|
// Network join authorization token (if any)
|
||||||
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH_TOKEN "atok"
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_AUTH "a"
|
||||||
// Network configuration meta-data flags
|
// Network configuration meta-data flags
|
||||||
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS "f"
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS "f"
|
||||||
|
// Relay policy for this node
|
||||||
|
#define ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_RELAY_POLICY "rp"
|
||||||
|
|
||||||
// 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…
Reference in New Issue
Block a user