瀏覽代碼

add "ssoRedirectURL" to local.conf

plumbed it through to the central controller code
Grant Limberg 4 年之前
父節點
當前提交
e6b4fb5af7

+ 1 - 1
controller/DB.hpp

@@ -104,7 +104,7 @@ public:
 	virtual void eraseNetwork(const uint64_t networkId) = 0;
 	virtual void eraseMember(const uint64_t networkId,const uint64_t memberId) = 0;
 	virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) = 0;
-	virtual std::string getSSOAuthURL(const nlohmann::json &member) { return ""; }
+	virtual std::string getSSOAuthURL(const nlohmann::json &member, const std::string &redirectURL) { return ""; }
 
 	inline void addListener(DB::ChangeListener *const listener)
 	{

+ 2 - 2
controller/DBMirrorSet.cpp

@@ -125,11 +125,11 @@ bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,std::vect
 	return false;
 }
 
-std::string DBMirrorSet::getSSOAuthURL(const nlohmann::json &member) 
+std::string DBMirrorSet::getSSOAuthURL(const nlohmann::json &member, const std::string &redirectURL) 
 {
 	std::lock_guard<std::mutex> l(_dbs_l);
 	for(auto d=_dbs.begin();d!=_dbs.end();++d) { 
-		std::string url = (*d)->getSSOAuthURL(member);
+		std::string url = (*d)->getSSOAuthURL(member, redirectURL);
 		if (!url.empty()) {
 			return url;
 		}

+ 1 - 1
controller/DBMirrorSet.hpp

@@ -51,7 +51,7 @@ public:
 	virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member);
 	virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId);
 
-	std::string getSSOAuthURL(const nlohmann::json &member);
+	std::string getSSOAuthURL(const nlohmann::json &member, const std::string &redirectURL);
 
 	inline void addDB(const std::shared_ptr<DB> &db)
 	{

+ 31 - 1
controller/EmbeddedNetworkController.cpp

@@ -28,6 +28,9 @@
 #include <map>
 #include <thread>
 #include <memory>
+#include <iomanip>
+#include <sstream>
+#include <cctype>
 
 #include "../include/ZeroTierOne.h"
 #include "../version.h"
@@ -60,6 +63,29 @@ namespace ZeroTier {
 
 namespace {
 
+std::string url_encode(const std::string &value) {
+    std::ostringstream escaped;
+    escaped.fill('0');
+    escaped << std::hex;
+
+    for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
+        std::string::value_type c = (*i);
+
+        // Keep alphanumeric and other accepted characters intact
+        if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
+            escaped << c;
+            continue;
+        }
+
+        // Any other characters are percent-encoded
+        escaped << std::uppercase;
+        escaped << '%' << std::setw(2) << int((unsigned char) c);
+        escaped << std::nouppercase;
+    }
+
+    return escaped.str();
+}
+
 static json _renderRule(ZT_VirtualNetworkRule &rule)
 {
 	char tmp[128];
@@ -476,6 +502,10 @@ EmbeddedNetworkController::~EmbeddedNetworkController()
 		t->join();
 }
 
+void EmbeddedNetworkController::setSSORedirectURL(const std::string &url) {
+	_ssoRedirectURL = url_encode(url);
+}
+
 void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender)
 {
 	char tmp[64];
@@ -1338,7 +1368,7 @@ void EmbeddedNetworkController::_request(
 		int64_t authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0);
 		fprintf(stderr, "authExpiryTime: %lld\n", authenticationExpiryTime);
 		if ((authenticationExpiryTime == 0) || (authenticationExpiryTime < now)) {
-			std::string authenticationURL = _db.getSSOAuthURL(member);
+			std::string authenticationURL = _db.getSSOAuthURL(member, _ssoRedirectURL);
 			if (!authenticationURL.empty()) {
 				Dictionary<3072> authInfo;
 				authInfo.add("aU", authenticationURL.c_str());

+ 3 - 0
controller/EmbeddedNetworkController.hpp

@@ -57,6 +57,8 @@ public:
 
 	virtual void init(const Identity &signingId,Sender *sender);
 
+	void setSSORedirectURL(const std::string &url);
+
 	virtual void request(
 		uint64_t nwid,
 		const InetAddress &fromAddr,
@@ -151,6 +153,7 @@ private:
 	std::mutex _memberStatus_l;
 
 	RedisConfig *_rc;
+	std::string _ssoRedirectURL;
 };
 
 } // namespace ZeroTier

+ 2 - 3
controller/PostgreSQL.cpp

@@ -309,7 +309,7 @@ void PostgreSQL::nodeIsOnline(const uint64_t networkId, const uint64_t memberId,
 	}
 }
 
-std::string PostgreSQL::getSSOAuthURL(const nlohmann::json &member)
+std::string PostgreSQL::getSSOAuthURL(const nlohmann::json &member, const std::string &redirectURL)
 {
 	// NONCE is just a random character string.  no semantic meaning
 	// state = HMAC SHA384 of Nonce based on shared sso key
@@ -387,11 +387,10 @@ std::string PostgreSQL::getSSOAuthURL(const nlohmann::json &member)
 				char state_hex[256];
 				Utils::hex(state, 48, state_hex);
 				
-				const char *redirect_url = "https%3A%2F%2Fmy.zerotier.com%2Fapi%2Fnetwork%2Fsso-auth"; // TODO: this should be configurable
 				OSUtils::ztsnprintf(authenticationURL, sizeof(authenticationURL),
 					"%s?response_type=id_token&response_mode=form_post&scope=openid+email+profile&redriect_uri=%s&nonce=%s&state=%s&client_id=%s",
 					authorization_endpoint.c_str(),
-					redirect_url,
+					redirectURL.c_str(),
 					nonce.c_str(),
 					state_hex,
 					client_id.c_str());

+ 1 - 1
controller/PostgreSQL.hpp

@@ -107,7 +107,7 @@ public:
 	virtual void eraseNetwork(const uint64_t networkId);
 	virtual void eraseMember(const uint64_t networkId, const uint64_t memberId);
 	virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress &physicalAddress);
-	virtual std::string getSSOAuthURL(const nlohmann::json &member);
+	virtual std::string getSSOAuthURL(const nlohmann::json &member, const std::string &redirectURL);
 
 protected:
 	struct _PairHasher

+ 7 - 0
service/OneService.cpp

@@ -575,6 +575,7 @@ public:
 	Mutex _run_m;
 
 	RedisConfig *_rc;
+	std::string _ssoRedirectURL;
 
 	// end member variables ----------------------------------------------------
 
@@ -612,6 +613,7 @@ public:
 #endif
 		,_run(true)
 		,_rc(NULL)
+		,_ssoRedirectURL()
 	{
 		_ports[0] = 0;
 		_ports[1] = 0;
@@ -790,6 +792,9 @@ public:
 
 			// Network controller is now enabled by default for desktop and server
 			_controller = new EmbeddedNetworkController(_node,_homePath.c_str(),_controllerDbPath.c_str(),_ports[0], _rc);
+			if (!_ssoRedirectURL.empty()) {
+				_controller->setSSORedirectURL(_ssoRedirectURL);
+			}
 			_node->setNetconfMaster((void *)_controller);
 
 			// Join existing networks in networks.d
@@ -1048,6 +1053,8 @@ public:
 			if (cdbp.length() > 0)
 				_controllerDbPath = cdbp;
 
+			_ssoRedirectURL = OSUtils::jsonString(settings["ssoRedirectURL"], "");
+
 #ifdef ZT_CONTROLLER_USE_LIBPQ
 			// TODO:  Redis config
 			json &redis = settings["redis"];