diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index ad2d55281..a3fc4a6e5 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -696,8 +696,10 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST( DB::initMember(member); try { - if (b.count("activeBridge")) member["activeBridge"] = OSUtils::jsonBool(b["activeBridge"],false); - if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"],false); + if (b.count("activeBridge")) member["activeBridge"] = OSUtils::jsonBool(b["activeBridge"], false); + if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"], false); + if (b.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = (int64_t)OSUtils::jsonInt(b["authenticationExpiryTime"], -1LL); + if (b.count("authenticationURL")) member["authenticationURL"] = OSUtils::jsonString(b["authenticationURL"], ""); if (b.count("remoteTraceTarget")) { const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],"")); @@ -1404,7 +1406,7 @@ void EmbeddedNetworkController::_request( Utils::scopy(nc->name,sizeof(nc->name),OSUtils::jsonString(network["name"],"").c_str()); nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU); nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"],32ULL); - Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationExpiryTime), authenticationURL.c_str()); + Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationURL), authenticationURL.c_str()); nc->authenticationExpiryTime = authenticationExpiryTime; std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"],"")); diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index d1f0f51dc..6f5a49f0b 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -191,6 +191,27 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar } } break; + case Packet::ERROR_NETWORK_AUTHENTICATION_REQUIRED: { + const SharedPtr network(RR->node->network(at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); + if ((network)&&(network->controller() == peer->address())) { + int s = (int)size() - (ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8); + if (s > 2) { + const uint16_t errorDataSize = at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8); + s -= 2; + if (s >= (int)errorDataSize) { + Dictionary<1024> authInfo(((const char *)this->data()) + (ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 10), errorDataSize); + char authenticationURL[256]; + if (authInfo.get("aU", authenticationURL, sizeof(authenticationURL)) > 0) { + authenticationURL[sizeof(authenticationURL) - 1] = 0; // ensure always zero terminated + network->setAuthenticationRequired(authenticationURL); + } else { + network->setAuthenticationRequired(""); + } + } + } + } + } break; + default: break; } diff --git a/node/Node.cpp b/node/Node.cpp index 3e4c65c0f..0c443f828 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -770,8 +770,10 @@ void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &des outp.append(nwid); - if ((errorData)&&(errorDataSize > 0)) + if ((errorData)&&(errorDataSize > 0)&&(errorDataSize <= 0xffff)) { + outp.append((uint16_t)errorDataSize); outp.append(errorData, errorDataSize); + } RR->sw->send((void *)0,outp,true); } // else we can't send an ERROR() in response to nothing, so discard diff --git a/one.cpp b/one.cpp index d83ef5bea..eb3198e7e 100644 --- a/one.cpp +++ b/one.cpp @@ -786,20 +786,21 @@ static int cli(int argc,char **argv) } } if (aa.length() == 0) aa = "-"; + const std::string status = OSUtils::jsonString(n["status"],"-"); printf("200 listnetworks %s %s %s %s %s %s %s" ZT_EOL_S, OSUtils::jsonString(n["nwid"],"-").c_str(), OSUtils::jsonString(n["name"],"-").c_str(), OSUtils::jsonString(n["mac"],"-").c_str(), - OSUtils::jsonString(n["status"],"-").c_str(), + status.c_str(), OSUtils::jsonString(n["type"],"-").c_str(), OSUtils::jsonString(n["portDeviceName"],"-").c_str(), aa.c_str()); int64_t authenticationExpiryTime = n["authenticationExpiryTime"]; if (authenticationExpiryTime >= 0) { - if (n["status"] == "AUTHENTICATION_REQUIRED") { - printf(" SSO authentication required, URL: %s" ZT_EOL_S, OSUtils::jsonString(n["authenticationURL"], "(null)").c_str()); - } else { - printf(" SSO authentication expires in %lld" ZT_EOL_S, (authenticationExpiryTime - OSUtils::now()) / 1000LL); + if (status == "AUTHENTICATION_REQUIRED") { + printf(" AUTH EXPIRED, URL: %s" ZT_EOL_S, OSUtils::jsonString(n["authenticationURL"], "(null)").c_str()); + } else if (status == "OK") { + printf(" AUTH OK, expires in: %lld seconds" ZT_EOL_S, (authenticationExpiryTime - OSUtils::now()) / 1000LL); } } }