소스 검색

Wire API auth token stuff.

Adam Ierymenko 10 년 전
부모
커밋
21a7e774bb
4개의 변경된 파일46개의 추가작업 그리고 21개의 파일을 삭제
  1. 0 18
      one.cpp
  2. 12 1
      service/ControlPlane.cpp
  3. 14 2
      service/ControlPlane.hpp
  4. 20 0
      service/OneService.cpp

+ 0 - 18
one.cpp

@@ -68,7 +68,6 @@
 #include "controller/SqliteNetworkController.hpp"
 #endif
 
-#define ZT1_AUTHTOKEN_SECRET_PATH "authtoken.secret"
 #define ZT1_PID_PATH "zerotier-one.pid"
 #define ZT1_CONTROLLER_DB_PATH "controller.db"
 
@@ -643,23 +642,6 @@ int main(int argc,char **argv)
 		}
 	}
 
-	std::string authToken;
-	{
-		std::string authTokenPath(homeDir + ZT_PATH_SEPARATOR_S + ZT1_AUTHTOKEN_SECRET_PATH);
-		if (!OSUtils::readFile(authTokenPath.c_str(),authToken)) {
-			unsigned char foo[24];
-			Utils::getSecureRandom(foo,sizeof(foo));
-			authToken = "";
-			for(unsigned int i=0;i<sizeof(foo);++i)
-				authToken.push_back("abcdefghijklmnopqrstuvwxyz0123456789"[(unsigned long)foo[i] % 36]);
-			if (!OSUtils::writeFile(authTokenPath.c_str(),authToken)) {
-				fprintf(stderr,"%s: cannot create authtoken.secret"ZT_EOL_S,argv[0]);
-				return 1;
-			} else OSUtils::lockDownFile(authTokenPath.c_str(),false);
-		}
-	}
-	authToken = Utils::trim(authToken);
-
 #ifdef __UNIX_LIKE__
 	if (getuid() != 0) {
 		fprintf(stderr,"%s: must be run as root (uid 0)"ZT_EOL_S,argv[0]);

+ 12 - 1
service/ControlPlane.cpp

@@ -248,7 +248,18 @@ unsigned int ControlPlane::handleRequest(
 		ps.push_back(std::string("index.html"));
 	}
 
-	bool isAuth = true; // TODO: auth tokens
+	bool isAuth = false;
+	{
+		Mutex::Lock _l(_authTokens_m);
+		std::map<std::string,std::string>::const_iterator ah(headers.find("x-zt1-auth"));
+		if ((ah != headers.end())&&(_authTokens.count(ah->second) > 0))
+			isAuth = true;
+		else {
+			ah = urlArgs.find("auth");
+			if ((ah != urlArgs.end())&&(_authTokens.count(ah->second) > 0))
+				isAuth = true;
+		}
+	}
 
 	if (httpMethod == HTTP_GET) {
 

+ 14 - 2
service/ControlPlane.hpp

@@ -28,12 +28,14 @@
 #ifndef ZT_ONE_CONTROLPLANE_HPP
 #define ZT_ONE_CONTROLPLANE_HPP
 
-#include "../include/ZeroTierOne.h"
-
 #include <string>
 #include <map>
 #include <set>
 
+#include "../include/ZeroTierOne.h"
+
+#include "../node/Mutex.hpp"
+
 namespace ZeroTier {
 
 class OneService;
@@ -49,6 +51,15 @@ public:
 	ControlPlane(OneService *svc,Node *n);
 	~ControlPlane();
 
+	/**
+	 * Add an authentication token for API access
+	 */
+	inline void addAuthToken(const char *tok)
+	{
+		Mutex::Lock _l(_authTokens_m);
+		_authTokens.insert(std::string(tok));
+	}
+
 	/**
 	 * Handle HTTP request
 	 *
@@ -74,6 +85,7 @@ private:
 	OneService *const _svc;
 	Node *const _node;
 	std::set<std::string> _authTokens;
+	Mutex _authTokens_m;
 };
 
 } // namespace ZeroTier

+ 20 - 0
service/OneService.cpp

@@ -173,6 +173,25 @@ public:
 	virtual ReasonForTermination run()
 	{
 		try {
+			std::string authToken;
+			{
+				std::string authTokenPath(_homePath + ZT_PATH_SEPARATOR_S + "authtoken.secret");
+				if (!OSUtils::readFile(authTokenPath.c_str(),authToken)) {
+					unsigned char foo[24];
+					Utils::getSecureRandom(foo,sizeof(foo));
+					authToken = "";
+					for(unsigned int i=0;i<sizeof(foo);++i)
+						authToken.push_back("abcdefghijklmnopqrstuvwxyz0123456789"[(unsigned long)foo[i] % 36]);
+					if (!OSUtils::writeFile(authTokenPath.c_str(),authToken)) {
+						Mutex::Lock _l(_termReason_m);
+						_termReason = ONE_UNRECOVERABLE_ERROR;
+						_fatalErrorMessage = "authtoken.secret could not be written";
+						return _termReason;
+					} else OSUtils::lockDownFile(authTokenPath.c_str(),false);
+				}
+			}
+			authToken = Utils::trim(authToken);
+
 			_node = new Node(
 				OSUtils::now(),
 				this,
@@ -188,6 +207,7 @@ public:
 				_node->setNetconfMaster((void *)_master);
 
 			_controlPlane = new ControlPlane(this,_node);
+			_controlPlane->addAuthToken(authToken.c_str());
 
 			{	// Remember networks from previous session
 				std::vector<std::string> networksDotD(OSUtils::listDirectory((_homePath + ZT_PATH_SEPARATOR_S + "networks.d").c_str()));