10 changed files with 227 additions and 730 deletions
@ -1,328 +0,0 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere |
||||
* Copyright (C) 2011-2015 ZeroTier, Inc. |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* |
||||
* -- |
||||
* |
||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which |
||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
* |
||||
* If you would like to embed ZeroTier into a commercial application or |
||||
* redistribute it in a modified binary form, please contact ZeroTier Networks |
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include <stdexcept> |
||||
|
||||
#include "../version.h" |
||||
|
||||
#include "Constants.hpp" |
||||
#include "SoftwareUpdater.hpp" |
||||
#include "Dictionary.hpp" |
||||
#include "C25519.hpp" |
||||
#include "Identity.hpp" |
||||
#include "Logger.hpp" |
||||
#include "RuntimeEnvironment.hpp" |
||||
#include "Thread.hpp" |
||||
#include "Node.hpp" |
||||
#include "Utils.hpp" |
||||
#include "HttpClient.hpp" |
||||
|
||||
#ifdef __UNIX_LIKE__ |
||||
#include <unistd.h> |
||||
#include <fcntl.h> |
||||
#include <sys/types.h> |
||||
#include <sys/stat.h> |
||||
#endif |
||||
|
||||
namespace ZeroTier { |
||||
|
||||
static inline std::map< Address,Identity > _mkUpdateAuth() |
||||
{ |
||||
std::map< Address,Identity > ua; |
||||
|
||||
{ // 0001
|
||||
Identity id("e9bc3707b5:0:c4cef17bde99eadf9748c4fd11b9b06dc5cd8eb429227811d2c336e6b96a8d329e8abd0a4f45e47fe1bcebf878c004c822d952ff77fc2833af4c74e65985c435"); |
||||
ua[id.address()] = id; |
||||
} |
||||
{ // 0002
|
||||
Identity id("56520eaf93:0:7d858b47988b34399a9a31136de07b46104d7edb4a98fa1d6da3e583d3a33e48be531532b886f0b12cd16794a66ab9220749ec5112cbe96296b18fe0cc79ca05"); |
||||
ua[id.address()] = id; |
||||
} |
||||
{ // 0003
|
||||
Identity id("7c195de2e0:0:9f659071c960f9b0f0b96f9f9ecdaa27c7295feed9c79b7db6eedcc11feb705e6dd85c70fa21655204d24c897865b99eb946b753a2bbcf2be5f5e006ae618c54"); |
||||
ua[id.address()] = id; |
||||
} |
||||
{ // 0004
|
||||
Identity id("415f4cfde7:0:54118e87777b0ea5d922c10b337c4f4bd1db7141845bd54004b3255551a6e356ba6b9e1e85357dbfafc45630b8faa2ebf992f31479e9005f0472685f2d8cbd6e"); |
||||
ua[id.address()] = id; |
||||
} |
||||
|
||||
return ua; |
||||
} |
||||
|
||||
static inline const char *_mkUpdateUrl() |
||||
{ |
||||
#if defined(__LINUX__) && ( defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__i386) ) |
||||
if (sizeof(void *) == 8) |
||||
return "http://download.zerotier.com/ZeroTierOneInstaller-linux-x64-LATEST.nfo"; |
||||
else return "http://download.zerotier.com/ZeroTierOneInstaller-linux-x86-LATEST.nfo"; |
||||
#define GOT_UPDATE_URL |
||||
#endif |
||||
|
||||
#ifdef __APPLE__ |
||||
return "http://download.zerotier.com/ZeroTierOneInstaller-mac-combined-LATEST.nfo"; |
||||
#define GOT_UPDATE_URL |
||||
#endif |
||||
|
||||
#ifdef __WINDOWS__ |
||||
return "http://download.zerotier.com/ZeroTierOneInstaller-windows-intel-LATEST.nfo"; |
||||
#define GOT_UPDATE_URL |
||||
#endif |
||||
|
||||
#ifndef GOT_UPDATE_URL |
||||
return ""; |
||||
#endif |
||||
} |
||||
|
||||
SoftwareUpdater::SoftwareUpdater(const RuntimeEnvironment *renv) : |
||||
RR(renv), |
||||
_myVersion(packVersion(ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION)), |
||||
_lastUpdateAttempt(0), |
||||
_status(UPDATE_STATUS_IDLE), |
||||
_die(false), |
||||
_lock() |
||||
{ |
||||
} |
||||
|
||||
SoftwareUpdater::~SoftwareUpdater() |
||||
{ |
||||
_die = true; |
||||
for(;;) { |
||||
_lock.lock(); |
||||
bool ip = (_status != UPDATE_STATUS_IDLE); |
||||
_lock.unlock(); |
||||
if (ip) |
||||
Thread::sleep(500); |
||||
else break; |
||||
} |
||||
} |
||||
|
||||
void SoftwareUpdater::cleanOldUpdates() |
||||
{ |
||||
std::string updatesDir(RR->homePath + ZT_PATH_SEPARATOR_S + "updates.d"); |
||||
std::map<std::string,bool> dl(Utils::listDirectory(updatesDir.c_str())); |
||||
for(std::map<std::string,bool>::iterator i(dl.begin());i!=dl.end();++i) { |
||||
if (!i->second) |
||||
Utils::rm((updatesDir + ZT_PATH_SEPARATOR_S + i->first).c_str()); |
||||
} |
||||
} |
||||
|
||||
void SoftwareUpdater::sawRemoteVersion(unsigned int vmaj,unsigned int vmin,unsigned int rev) |
||||
{ |
||||
const uint64_t tmp = packVersion(vmaj,vmin,rev); |
||||
if (tmp > _myVersion) { |
||||
Mutex::Lock _l(_lock); |
||||
if ((_status == UPDATE_STATUS_IDLE)&&(!_die)&&(ZT_DEFAULTS.updateLatestNfoURL.length())) { |
||||
const uint64_t now = Utils::now(); |
||||
if ((now - _lastUpdateAttempt) >= ZT_UPDATE_MIN_INTERVAL) { |
||||
_lastUpdateAttempt = now; |
||||
_status = UPDATE_STATUS_GETTING_NFO; |
||||
RR->http->GET(ZT_DEFAULTS.updateLatestNfoURL,HttpClient::NO_HEADERS,ZT_UPDATE_HTTP_TIMEOUT,&_cbHandleGetLatestVersionInfo,this); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
void SoftwareUpdater::checkNow() |
||||
{ |
||||
Mutex::Lock _l(_lock); |
||||
if (_status == UPDATE_STATUS_IDLE) { |
||||
_lastUpdateAttempt = Utils::now(); |
||||
_status = UPDATE_STATUS_GETTING_NFO; |
||||
RR->http->GET(ZT_DEFAULTS.updateLatestNfoURL,HttpClient::NO_HEADERS,ZT_UPDATE_HTTP_TIMEOUT,&_cbHandleGetLatestVersionInfo,this); |
||||
} |
||||
} |
||||
|
||||
const char *SoftwareUpdater::parseNfo( |
||||
const char *nfoText, |
||||
unsigned int &vMajor, |
||||
unsigned int &vMinor, |
||||
unsigned int &vRevision, |
||||
Address &signedBy, |
||||
std::string &signature, |
||||
std::string &url) |
||||
{ |
||||
try { |
||||
Dictionary nfo(nfoText); |
||||
|
||||
vMajor = Utils::strToUInt(nfo.get("vMajor").c_str()); |
||||
vMinor = Utils::strToUInt(nfo.get("vMinor").c_str()); |
||||
vRevision = Utils::strToUInt(nfo.get("vRevision").c_str()); |
||||
signedBy = nfo.get("signedBy"); |
||||
signature = Utils::unhex(nfo.get("ed25519")); |
||||
url = nfo.get("url"); |
||||
|
||||
if (signature.length() != ZT_C25519_SIGNATURE_LEN) |
||||
return "bad ed25519 signature, invalid length"; |
||||
if ((url.length() <= 7)||(url.substr(0,7) != "http://")) |
||||
return "invalid URL, must begin with http://"; |
||||
|
||||
return (const char *)0; |
||||
} catch ( ... ) { |
||||
return "invalid NFO file format or one or more required fields missing"; |
||||
} |
||||
} |
||||
|
||||
bool SoftwareUpdater::validateUpdate( |
||||
const void *data, |
||||
unsigned int len, |
||||
const Address &signedBy, |
||||
const std::string &signature) |
||||
{ |
||||
std::map< Address,Identity >::const_iterator updateAuthority = ZT_DEFAULTS.updateAuthorities.find(signedBy); |
||||
if (updateAuthority == ZT_DEFAULTS.updateAuthorities.end()) |
||||
return false; |
||||
return updateAuthority->second.verify(data,len,signature.data(),(unsigned int)signature.length()); |
||||
} |
||||
|
||||
void SoftwareUpdater::_cbHandleGetLatestVersionInfo(void *arg,int code,const std::string &url,const std::string &body) |
||||
{ |
||||
SoftwareUpdater *upd = (SoftwareUpdater *)arg; |
||||
const RuntimeEnvironment *RR = (const RuntimeEnvironment *)upd->RR; |
||||
Mutex::Lock _l(upd->_lock); |
||||
|
||||
if ((upd->_die)||(upd->_status != UPDATE_STATUS_GETTING_NFO)) { |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
|
||||
if (code != 200) { |
||||
LOG("software update check failed: server responded with code %d",code); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
|
||||
try { |
||||
unsigned int vMajor = 0,vMinor = 0,vRevision = 0; |
||||
Address signedBy; |
||||
std::string signature,url; |
||||
|
||||
const char *err = parseNfo(body.c_str(),vMajor,vMinor,vRevision,signedBy,signature,url); |
||||
|
||||
if (err) { |
||||
LOG("software update check aborted: .nfo file parse error: %s",err); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
|
||||
if (!ZT_DEFAULTS.updateAuthorities.count(signedBy)) { |
||||
LOG("software update check aborted: .nfo file specifies unknown signing authority"); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
|
||||
#ifndef ZT_ALWAYS_UPDATE /* for testing */ |
||||
if (packVersion(vMajor,vMinor,vRevision) <= upd->_myVersion) { |
||||
TRACE("software update check complete: version on update site is not newer than my version, no update necessary"); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
#endif |
||||
|
||||
upd->_status = UPDATE_STATUS_GETTING_FILE; |
||||
upd->_signedBy = signedBy; |
||||
upd->_signature = signature; |
||||
|
||||
RR->http->GET(url,HttpClient::NO_HEADERS,ZT_UPDATE_HTTP_TIMEOUT,&_cbHandleGetLatestVersionBinary,arg); |
||||
} catch ( ... ) { |
||||
LOG("software update check failed: .nfo file invalid or missing field(s)"); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
} |
||||
} |
||||
|
||||
void SoftwareUpdater::_cbHandleGetLatestVersionBinary(void *arg,int code,const std::string &url,const std::string &body) |
||||
{ |
||||
SoftwareUpdater *upd = (SoftwareUpdater *)arg; |
||||
const RuntimeEnvironment *RR = (const RuntimeEnvironment *)upd->RR; |
||||
Mutex::Lock _l(upd->_lock); |
||||
|
||||
if (!validateUpdate(body.data(),(unsigned int)body.length(),upd->_signedBy,upd->_signature)) { |
||||
LOG("software update failed: update fetched from '%s' failed signature check (image size: %u)",url.c_str(),(unsigned int)body.length()); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
|
||||
size_t lastSlash = url.rfind('/'); |
||||
if (lastSlash == std::string::npos) { // sanity check, shouldn't happen
|
||||
LOG("software update failed: invalid URL"); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
std::string updatesDir(RR->homePath + ZT_PATH_SEPARATOR_S + "updates.d"); |
||||
std::string updateFilename(url.substr(lastSlash + 1)); |
||||
if ((updateFilename.length() < 3)||(updateFilename.find("..") != std::string::npos)) { |
||||
LOG("software update failed: invalid URL: filename contains invalid characters"); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
for(std::string::iterator c(updateFilename.begin());c!=updateFilename.end();++c) { |
||||
// Only allow a list of whitelisted characters to make up the filename to prevent any
|
||||
// path shenanigans, esp on Windows where / is not the path separator.
|
||||
if (!strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.0123456789",*c)) { |
||||
LOG("software update failed: invalid URL: filename contains invalid characters"); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
} |
||||
std::string updatePath(updatesDir + ZT_PATH_SEPARATOR_S + updateFilename); |
||||
#ifdef __WINDOWS__ |
||||
CreateDirectoryA(updatesDir.c_str(),NULL); |
||||
#else |
||||
mkdir(updatesDir.c_str(),0755); |
||||
#endif |
||||
|
||||
FILE *upf = fopen(updatePath.c_str(),"wb"); |
||||
if (!upf) { |
||||
LOG("software update failed: unable to open %s for writing",updatePath.c_str()); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
return; |
||||
} |
||||
if (fwrite(body.data(),body.length(),1,upf) != 1) { |
||||
LOG("software update failed: unable to write to %s",updatePath.c_str()); |
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
fclose(upf); |
||||
Utils::rm(updatePath); |
||||
return; |
||||
} |
||||
fclose(upf); |
||||
|
||||
#ifdef __UNIX_LIKE__ |
||||
::chmod(updatePath.c_str(),0755); |
||||
#endif |
||||
|
||||
// We exit with this reason code and the path as the text. It is the
|
||||
// caller's responsibility (main.c) to pick this up and do the right
|
||||
// thing.
|
||||
upd->_status = UPDATE_STATUS_IDLE; |
||||
RR->node->terminate(Node::NODE_RESTART_FOR_UPGRADE,updatePath.c_str()); |
||||
} |
||||
|
||||
} // namespace ZeroTier
|
||||
@ -1,186 +0,0 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere |
||||
* Copyright (C) 2011-2015 ZeroTier, Inc. |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* |
||||
* -- |
||||
* |
||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which |
||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
* |
||||
* If you would like to embed ZeroTier into a commercial application or |
||||
* redistribute it in a modified binary form, please contact ZeroTier Networks |
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/ |
||||
|
||||
#ifndef ZT_SOFTWAREUPDATER_HPP |
||||
#define ZT_SOFTWAREUPDATER_HPP |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include <string> |
||||
|
||||
#include "../node/Constants.hpp" |
||||
#include "../node/Mutex.hpp" |
||||
#include "../node/Address.hpp" |
||||
|
||||
#include "HttpClient.hpp" |
||||
|
||||
/**
|
||||
* Delay between fetches of the root topology update URL |
||||
* |
||||
* 86400000 = check once every 24 hours (this doesn't change often) |
||||
*/ |
||||
#define ZT_UPDATE_ROOT_TOPOLOGY_CHECK_INTERVAL 86400000 |
||||
|
||||
/**
|
||||
* Minimum interval between attempts to do a software update |
||||
*/ |
||||
#define ZT_UPDATE_MIN_INTERVAL 120000 |
||||
|
||||
/**
|
||||
* Maximum interval between checks for new versions |
||||
*/ |
||||
#define ZT_UPDATE_MAX_INTERVAL 7200000 |
||||
|
||||
/**
|
||||
* Software update HTTP timeout in seconds |
||||
*/ |
||||
#define ZT_UPDATE_HTTP_TIMEOUT 120 |
||||
|
||||
namespace ZeroTier { |
||||
|
||||
/**
|
||||
* Software updater |
||||
*/ |
||||
class SoftwareUpdater |
||||
{ |
||||
public: |
||||
SoftwareUpdater(); |
||||
~SoftwareUpdater(); |
||||
|
||||
/**
|
||||
* Remove old updates in updates.d |
||||
*/ |
||||
void cleanOldUpdates(); |
||||
|
||||
/**
|
||||
* Called on each version message from a peer |
||||
* |
||||
* If a peer has a newer version, that causes an update to be started. |
||||
* |
||||
* @param vmaj Peer's major version |
||||
* @param vmin Peer's minor version |
||||
* @param rev Peer's revision |
||||
*/ |
||||
void sawRemoteVersion(unsigned int vmaj,unsigned int vmin,unsigned int rev); |
||||
|
||||
/**
|
||||
* Check for updates now regardless of last check time or version |
||||
* |
||||
* This only starts a check if one is not in progress. Otherwise it does |
||||
* nothing. |
||||
*/ |
||||
void checkNow(); |
||||
|
||||
/**
|
||||
* Check for updates now if it's been longer than ZT_UPDATE_MAX_INTERVAL |
||||
* |
||||
* This is called periodically from the main loop. |
||||
*/ |
||||
inline void checkIfMaxIntervalExceeded(uint64_t now) |
||||
{ |
||||
if ((now - _lastUpdateAttempt) >= ZT_UPDATE_MAX_INTERVAL) |
||||
checkNow(); |
||||
} |
||||
|
||||
/**
|
||||
* Pack three-component version into a 64-bit integer |
||||
* |
||||
* @param vmaj Major version (0..65535) |
||||
* @param vmin Minor version (0..65535) |
||||
* @param rev Revision (0..65535) |
||||
* @return Version packed into an easily comparable 64-bit integer |
||||
*/ |
||||
static inline uint64_t packVersion(unsigned int vmaj,unsigned int vmin,unsigned int rev) |
||||
throw() |
||||
{ |
||||
return ( ((uint64_t)(vmaj & 0xffff) << 32) | ((uint64_t)(vmin & 0xffff) << 16) | (uint64_t)(rev & 0xffff) ); |
||||
} |
||||
|
||||
/**
|
||||
* Parse NFO data from .nfo file on software update site |
||||
* |
||||
* The first argument is the NFO data, and all the remaining arguments are |
||||
* result parameters to be filled with results. If an error is returned the |
||||
* results in the parameters should be considered undefined. |
||||
* |
||||
* @param nfo NFO data |
||||
* @param vMajor Result: major version |
||||
* @param vMinor Result: minor version |
||||
* @param vRevision Result: revision number |
||||
* @param signedBy Result: signing identity |
||||
* @param signature Result: Ed25519 signature data |
||||
* @param url Result: URL of update binary |
||||
* @return NULL on success or error message on failure |
||||
*/ |
||||
static const char *parseNfo( |
||||
const char *nfoText, |
||||
unsigned int &vMajor, |
||||
unsigned int &vMinor, |
||||
unsigned int &vRevision, |
||||
Address &signedBy, |
||||
std::string &signature, |
||||
std::string &url); |
||||
|
||||
/**
|
||||
* Validate an update once downloaded |
||||
* |
||||
* This obtains the identity corresponding to the address from the compiled-in |
||||
* list of valid signing identities. |
||||
* |
||||
* @param data Update data |
||||
* @param len Length of update data |
||||
* @param signedBy Signing authority address |
||||
* @param signature Signing authority signature |
||||
* @return True on validation success, false if rejected |
||||
*/ |
||||
static bool validateUpdate( |
||||
const void *data, |
||||
unsigned int len, |
||||
const Address &signedBy, |
||||
const std::string &signature); |
||||
|
||||
private: |
||||
static void _cbHandleGetLatestVersionInfo(void *arg,int code,const std::string &url,const std::string &body); |
||||
static void _cbHandleGetLatestVersionBinary(void *arg,int code,const std::string &url,const std::string &body); |
||||
|
||||
HttpClient httpClient; |
||||
const uint64_t _myVersion; |
||||
volatile uint64_t _lastUpdateAttempt; |
||||
volatile enum { |
||||
UPDATE_STATUS_IDLE, |
||||
UPDATE_STATUS_GETTING_NFO, |
||||
UPDATE_STATUS_GETTING_FILE |
||||
} _status; |
||||
volatile bool _die; |
||||
Address _signedBy; |
||||
std::string _signature; |
||||
Mutex _lock; |
||||
}; |
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif |
||||
@ -1,177 +0,0 @@
|
||||
/*
|
||||
* ZeroTier One - Network Virtualization Everywhere |
||||
* Copyright (C) 2011-2015 ZeroTier, Inc. |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* |
||||
* -- |
||||
* |
||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which |
||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
* |
||||
* If you would like to embed ZeroTier into a commercial application or |
||||
* redistribute it in a modified binary form, please contact ZeroTier Networks |
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <stdint.h> |
||||
#include <time.h> |
||||
|
||||
#include <string> |
||||
#include <vector> |
||||
#include <map> |
||||
#include <algorithm> |
||||
#include <stdexcept> |
||||
|
||||
#include "version.h" |
||||
#include "include/ZeroTierOne.h" |
||||
#include "node/Constants.hpp" |
||||
|
||||
#ifdef __WINDOWS__ |
||||
#include <WinSock2.h> |
||||
#include <Windows.h> |
||||
#include <tchar.h> |
||||
#include <wchar.h> |
||||
#include <lmcons.h> |
||||
#include <newdev.h> |
||||
#include <atlbase.h> |
||||
#else |
||||
#include <unistd.h> |
||||
#include <pwd.h> |
||||
#include <fcntl.h> |
||||
#include <sys/types.h> |
||||
#include <sys/stat.h> |
||||
#include <signal.h> |
||||
#endif |
||||
|
||||
#include "node/Utils.hpp" |
||||
#include "node/Address.hpp" |
||||
#include "node/Dictionary.hpp" |
||||
#include "node/Identity.hpp" |
||||
#include "osdep/OSUtils.hpp" |
||||
#include "osdep/Http.hpp" |
||||
|
||||
using namespace ZeroTier; |
||||
|
||||
namespace { |
||||
|
||||
static std::map< Address,Identity > updateAuthorities() |
||||
{ |
||||
std::map< Address,Identity > ua; |
||||
{ // 0001
|
||||
Identity id("e9bc3707b5:0:c4cef17bde99eadf9748c4fd11b9b06dc5cd8eb429227811d2c336e6b96a8d329e8abd0a4f45e47fe1bcebf878c004c822d952ff77fc2833af4c74e65985c435"); |
||||
ua[id.address()] = id; |
||||
} |
||||
{ // 0002
|
||||
Identity id("56520eaf93:0:7d858b47988b34399a9a31136de07b46104d7edb4a98fa1d6da3e583d3a33e48be531532b886f0b12cd16794a66ab9220749ec5112cbe96296b18fe0cc79ca05"); |
||||
ua[id.address()] = id; |
||||
} |
||||
{ // 0003
|
||||
Identity id("7c195de2e0:0:9f659071c960f9b0f0b96f9f9ecdaa27c7295feed9c79b7db6eedcc11feb705e6dd85c70fa21655204d24c897865b99eb946b753a2bbcf2be5f5e006ae618c54"); |
||||
ua[id.address()] = id; |
||||
} |
||||
{ // 0004
|
||||
Identity id("415f4cfde7:0:54118e87777b0ea5d922c10b337c4f4bd1db7141845bd54004b3255551a6e356ba6b9e1e85357dbfafc45630b8faa2ebf992f31479e9005f0472685f2d8cbd6e"); |
||||
ua[id.address()] = id; |
||||
} |
||||
return ua; |
||||
} |
||||
|
||||
static bool validateUpdate( |
||||
const void *data, |
||||
unsigned int len, |
||||
const Address &signedBy, |
||||
const std::string &signature) |
||||
{ |
||||
std::map< Address,Identity > ua(updateAuthorities()); |
||||
std::map< Address,Identity >::const_iterator updateAuthority = ua.find(signedBy); |
||||
if (updateAuthority == ua.end()) |
||||
return false; |
||||
return updateAuthority->second.verify(data,len,signature.data(),(unsigned int)signature.length()); |
||||
} |
||||
|
||||
/*
|
||||
static inline const char *updateUrl() |
||||
{ |
||||
#if defined(__LINUX__) && ( defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__i386) ) |
||||
if (sizeof(void *) == 8) |
||||
return "http://download.zerotier.com/ZeroTierOneInstaller-linux-x64-LATEST.nfo"; |
||||
else return "http://download.zerotier.com/ZeroTierOneInstaller-linux-x86-LATEST.nfo"; |
||||
#define GOT_UPDATE_URL |
||||
#endif |
||||
|
||||
#ifdef __APPLE__ |
||||
return "http://download.zerotier.com/ZeroTierOneInstaller-mac-combined-LATEST.nfo"; |
||||
#define GOT_UPDATE_URL |
||||
#endif |
||||
|
||||
#ifdef __WINDOWS__ |
||||
return "http://download.zerotier.com/ZeroTierOneInstaller-windows-intel-LATEST.nfo"; |
||||
#define GOT_UPDATE_URL |
||||
#endif |
||||
|
||||
#ifndef GOT_UPDATE_URL |
||||
return ""; |
||||
#endif |
||||
} |
||||
*/ |
||||
|
||||
static const char *parseUpdateNfo( |
||||
const char *nfoText, |
||||
unsigned int &vMajor, |
||||
unsigned int &vMinor, |
||||
unsigned int &vRevision, |
||||
Address &signedBy, |
||||
std::string &signature, |
||||
std::string &url) |
||||
{ |
||||
try { |
||||
Dictionary nfo(nfoText); |
||||
|
||||
vMajor = Utils::strToUInt(nfo.get("vMajor").c_str()); |
||||
vMinor = Utils::strToUInt(nfo.get("vMinor").c_str()); |
||||
vRevision = Utils::strToUInt(nfo.get("vRevision").c_str()); |
||||
signedBy = nfo.get("signedBy"); |
||||
signature = Utils::unhex(nfo.get("ed25519")); |
||||
url = nfo.get("url"); |
||||
|
||||
if (signature.length() != ZT_C25519_SIGNATURE_LEN) |
||||
return "bad ed25519 signature, invalid length"; |
||||
if ((url.length() <= 7)||(url.substr(0,7) != "http://")) |
||||
return "invalid URL, must begin with http://"; |
||||
|
||||
return (const char *)0; |
||||
} catch ( ... ) { |
||||
return "invalid NFO file format or one or more required fields missing"; |
||||
} |
||||
} |
||||
|
||||
} // anonymous namespace
|
||||
|
||||
#ifdef __WINDOWS__ |
||||
int _tmain(int argc, _TCHAR* argv[]) |
||||
#else |
||||
int main(int argc,char **argv) |
||||
#endif |
||||
{ |
||||
#ifdef __WINDOWS__ |
||||
WSADATA wsaData; |
||||
WSAStartup(MAKEWORD(2,2),&wsaData); |
||||
#endif |
||||
|
||||
return 0; |
||||
} |
||||
Loading…
Reference in new issue