diff --git a/node/C25519.hpp b/node/C25519.hpp index 2a594f725..1015ecc38 100644 --- a/node/C25519.hpp +++ b/node/C25519.hpp @@ -73,7 +73,7 @@ public: throw() { Pair kp; - Utils::getSecureRandom(kp.priv.data,kp.priv.size()); + Utils::getSecureRandom(kp.priv.data,(unsigned int)kp.priv.size()); _calcPubDH(kp); _calcPubED(kp); return kp; @@ -98,7 +98,7 @@ public: { Pair kp; void *const priv = (void *)kp.priv.data; - Utils::getSecureRandom(priv,kp.priv.size()); + Utils::getSecureRandom(priv,(unsigned int)kp.priv.size()); _calcPubED(kp); // do Ed25519 key -- bytes 32-63 of pub and priv do { ++(((uint64_t *)priv)[1]); diff --git a/node/CertificateOfMembership.cpp b/node/CertificateOfMembership.cpp index dd92455eb..cba613dad 100644 --- a/node/CertificateOfMembership.cpp +++ b/node/CertificateOfMembership.cpp @@ -74,7 +74,7 @@ std::string CertificateOfMembership::toString() const if (_signedBy) { s.push_back(':'); - s.append(Utils::hex(_signature.data,_signature.size())); + s.append(Utils::hex(_signature.data,(unsigned int)_signature.size())); } return s; @@ -132,7 +132,7 @@ void CertificateOfMembership::fromString(const char *s) while ((s[colonAt])&&(s[colonAt] != ':')) ++colonAt; if (colonAt) { - if (Utils::unhex(s,colonAt,_signature.data,_signature.size()) != _signature.size()) + if (Utils::unhex(s,colonAt,_signature.data,(unsigned int)_signature.size()) != _signature.size()) _signedBy.zero(); } else _signedBy.zero(); } else _signedBy.zero(); diff --git a/node/CertificateOfMembership.hpp b/node/CertificateOfMembership.hpp index 6f78734eb..5514c47a8 100644 --- a/node/CertificateOfMembership.hpp +++ b/node/CertificateOfMembership.hpp @@ -327,7 +327,7 @@ public: } _signedBy.appendTo(b); if (_signedBy) - b.append(_signature.data,_signature.size()); + b.append(_signature.data,(unsigned int)_signature.size()); } template @@ -361,8 +361,8 @@ public: p += ZT_ADDRESS_LENGTH; if (_signedBy) { - memcpy(_signature.data,b.field(p,_signature.size()),_signature.size()); - p += _signature.size(); + memcpy(_signature.data,b.field(p,(unsigned int)_signature.size()),_signature.size()); + p += (unsigned int)_signature.size(); } return (p - startAt); diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp index 458f1eed0..231fde066 100644 --- a/node/EthernetTap.cpp +++ b/node/EthernetTap.cpp @@ -268,8 +268,6 @@ EthernetTap::EthernetTap( _r(renv), _handler(handler), _arg(arg), - _dhcp(false), - _dhcp6(false), _fd(0) { char devpath[64],ethaddr[64],mtustr[16],tmp[4096]; @@ -389,7 +387,7 @@ void EthernetTap::whack() if (cpid == 0) { execl(ipconfig,ipconfig,"set",_dev,"AUTOMATIC-V6",(const char *)0); _exit(-1); - } else { + } else if (cpid > 0) { int exitcode = -1; waitpid(cpid,&exitcode,0); } @@ -399,17 +397,6 @@ void EthernetTap::whack() void EthernetTap::whack() {} #endif // __APPLE__ / !__APPLE__ -bool EthernetTap::setDhcpEnabled(bool dhcp) -{ - // TODO - return _dhcp; -} - -bool EthernetTap::setDhcp6Enabled(bool dhcp) -{ - return _dhcp6; -} - void EthernetTap::setDisplayName(const char *dn) { } @@ -810,7 +797,6 @@ static inline void _intl_freeifmaddrs(struct ifmaddrs *ifmp) free(ifmp); } - // -------------------------------------------------------------------------- bool EthernetTap::updateMulticastGroups(std::set &groups) @@ -981,8 +967,6 @@ EthernetTap::EthernetTap( _r(renv), _handler(handler), _arg(arg), - _dhcp(false), - _dhcp6(false), _tap(INVALID_HANDLE_VALUE), _injectSemaphore(INVALID_HANDLE_VALUE), _run(true) @@ -995,10 +979,14 @@ EthernetTap::EthernetTap( throw std::runtime_error("MTU too large for Windows tap"); #ifdef _WIN64 - const char *devcon = "\\devcon64.exe"; + BOOL is64Bit = TRUE; + const char *devcon = "\\devcon_x64.exe"; + const char *tapDriver = "\\tap-windows\\x64\\ztTap100.inf"; #else - BOOL f64 = FALSE; - const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe"); + BOOL is64Bit = FALSE; + IsWow64Process(GetCurrentProcess(),&is64Bit); + const char *devcon = ((is64Bit == TRUE) ? "\\devcon_x64.exe" : "\\devcon_x86.exe"); + const char *tapDriver = ((is64Bit == TRUE) ? "\\tap-windows\\x64\\ztTap100.inf" : "\\tap-windows\\x86\\ztTap100.inf"); #endif Mutex::Lock _l(_systemTapInitLock); // only init one tap at a time, process-wide @@ -1066,7 +1054,7 @@ EthernetTap::EthernetTap( PROCESS_INFORMATION processInfo; memset(&startupInfo,0,sizeof(STARTUPINFOA)); memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); - if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" install \"" + _r->homePath + "\\ztTap100.inf\" ztTap100").c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { + if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" install \"" + _r->homePath + tapDriver + "\" ztTap100").c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { RegCloseKey(nwAdapters); throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon); } @@ -1145,9 +1133,6 @@ EthernetTap::EthernetTap( throw std::runtime_error("unable to convert instance ID GUID to native GUID (invalid NetCfgInstanceId in registry?)"); } - setDhcpEnabled(false); - setDhcp6Enabled(false); - // Disable and enable interface to ensure registry settings take effect { STARTUPINFOA startupInfo; @@ -1211,24 +1196,25 @@ EthernetTap::~EthernetTap() CloseHandle(_tapOvlWrite.hEvent); CloseHandle(_injectSemaphore); - // Disable network device on shutdown #ifdef _WIN64 - const char *devcon = "\\devcon64.exe"; + BOOL is64Bit = TRUE; + const char *devcon = "\\devcon_x64.exe"; #else - BOOL f64 = FALSE; - const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe"); + BOOL is64Bit = FALSE; + IsWow64Process(GetCurrentProcess(),&is64Bit); + const char *devcon = ((is64Bit == TRUE) ? "\\devcon_x64.exe" : "\\devcon_x86.exe"); #endif - { - STARTUPINFOA startupInfo; - startupInfo.cb = sizeof(startupInfo); - PROCESS_INFORMATION processInfo; - memset(&startupInfo,0,sizeof(STARTUPINFOA)); - memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); - if (CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" disable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { - WaitForSingleObject(processInfo.hProcess,INFINITE); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); - } + + // Disable network device on shutdown + STARTUPINFOA startupInfo; + startupInfo.cb = sizeof(startupInfo); + PROCESS_INFORMATION processInfo; + memset(&startupInfo,0,sizeof(STARTUPINFOA)); + memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); + if (CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" disable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { + WaitForSingleObject(processInfo.hProcess,INFINITE); + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); } } @@ -1236,25 +1222,6 @@ void EthernetTap::whack() { } -bool EthernetTap::setDhcpEnabled(bool dhcp) -{ - HKEY tcpIpInterfaces; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) { - _dhcp = dhcp; - DWORD enable = (dhcp ? 1 : 0); - RegSetKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"EnableDHCP",REG_DWORD,&enable,sizeof(enable)); - RegCloseKey(tcpIpInterfaces); - } else _dhcp = false; - - return _dhcp; -} - -bool EthernetTap::setDhcp6Enabled(bool dhcp) -{ - // TODO - return _dhcp6; -} - void EthernetTap::setDisplayName(const char *dn) { HKEY ifp; @@ -1394,14 +1361,43 @@ bool EthernetTap::updateMulticastGroups(std::set &groups) { std::set newGroups; + // Ensure that groups are added for each IP... this handles the MAC:ADI + // groups that are created from IPv4 addresses. Some of these may end + // up being duplicates of what the IOCTL returns but that's okay since + // the set will filter these. std::set ipaddrs(allIps()); for(std::set::const_iterator i(ipaddrs.begin());i!=ipaddrs.end();++i) newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i)); - bool changed = false; + // The ZT1 tap driver supports an IOCTL to get multicast memberships at the L2 + // level... something Windows does not seem to expose ordinarily. This lets + // pretty much anything work... IPv4, IPv6, IPX, oldskool Netbios, who knows... + unsigned char mcastbuf[TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE]; + DWORD bytesReturned = 0; + if (DeviceIoControl(_tap,TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS,(LPVOID)0,0,(LPVOID)mcastbuf,sizeof(mcastbuf),&bytesReturned,NULL)) { + printf("TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS: got %d bytes\n",(int)bytesReturned); + MAC mac; + DWORD i = 0; + while ((i + 6) <= bytesReturned) { + mac.data[0] = mcastbuf[i++]; + mac.data[1] = mcastbuf[i++]; + mac.data[2] = mcastbuf[i++]; + mac.data[3] = mcastbuf[i++]; + mac.data[4] = mcastbuf[i++]; + mac.data[5] = mcastbuf[i++]; + if (mac.isMulticast()) { // exclude the nulls that may be returned or any other junk Windows puts in there + newGroups.insert(MulticastGroup(mac,0)); + printf("TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS: %s\n",mac.toString().c_str()); + } + } + } else { + printf("TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS: failed\n"); + } newGroups.insert(_blindWildcardMulticastGroup); // always join this + bool changed = false; + for(std::set::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) { if (!groups.count(*mg)) { groups.insert(*mg); diff --git a/node/EthernetTap.hpp b/node/EthernetTap.hpp index 68a365bf0..3d91261bb 100644 --- a/node/EthernetTap.hpp +++ b/node/EthernetTap.hpp @@ -99,22 +99,6 @@ public: */ void whack(); - /** - * Set whether or not DHCP is enabled (disabled by default) - * - * @param dhcp DHCP status - * @return New state of DHCP (may be false even on 'true' if DHCP enable failed) - */ - bool setDhcpEnabled(bool dhcp); - - /** - * Set whether or not DHCP6 is enabled (disabled by default) - * - * @param dhcp DHCP6 status - * @return New state of DHCP6 (may be false even on 'true' if DHCP enable failed) - */ - bool setDhcp6Enabled(bool dhcp); - /** * Set the user display name for this connection * @@ -230,9 +214,6 @@ private: void (*_handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &); void *_arg; - bool _dhcp; - bool _dhcp6; - Thread _thread; #ifdef __UNIX_LIKE__ diff --git a/node/HttpClient.cpp b/node/HttpClient.cpp index ca2324378..a648d690d 100644 --- a/node/HttpClient.cpp +++ b/node/HttpClient.cpp @@ -361,7 +361,7 @@ public: uc.dwHostNameLength = -1; uc.dwUrlPathLength = -1; uc.dwExtraInfoLength = -1; - if (!WinHttpCrackUrl(wurl.c_str(),wurl.length(),0,&uc)) { + if (!WinHttpCrackUrl(wurl.c_str(),(DWORD)wurl.length(),0,&uc)) { _handler(_arg,-1,_url,false,"unable to parse URL: WinHttpCrackUrl() failed"); goto closeAndReturnFromHttp; } diff --git a/node/Identity.cpp b/node/Identity.cpp index 859a129fa..15eae2458 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -90,7 +90,7 @@ struct _Identity_generate_cond inline bool operator()(const C25519::Pair &kp) const throw() { - _computeMemoryHardHash(kp.pub.data,kp.pub.size(),digest,genmem); + _computeMemoryHardHash(kp.pub.data,(unsigned int)kp.pub.size(),digest,genmem); return (digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN); } unsigned char *digest; @@ -123,7 +123,7 @@ bool Identity::locallyValidate() const unsigned char digest[64]; char *genmem = new char[ZT_IDENTITY_GEN_MEMORY]; - _computeMemoryHardHash(_publicKey.data,_publicKey.size(),digest,genmem); + _computeMemoryHardHash(_publicKey.data,(unsigned int)_publicKey.size(),digest,genmem); delete [] genmem; unsigned char addrb[5]; @@ -144,10 +144,10 @@ std::string Identity::toString(bool includePrivate) const r.append(_address.toString()); r.append(":0:"); // 0 == IDENTITY_TYPE_C25519 - r.append(Utils::hex(_publicKey.data,_publicKey.size())); + r.append(Utils::hex(_publicKey.data,(unsigned int)_publicKey.size())); if ((_privateKey)&&(includePrivate)) { r.push_back(':'); - r.append(Utils::hex(_privateKey->data,_privateKey->size())); + r.append(Utils::hex(_privateKey->data,(unsigned int)_privateKey->size())); } return r; @@ -176,12 +176,12 @@ bool Identity::fromString(const char *str) return false; break; case 2: - if (Utils::unhex(f,_publicKey.data,_publicKey.size()) != _publicKey.size()) + if (Utils::unhex(f,_publicKey.data,(unsigned int)_publicKey.size()) != _publicKey.size()) return false; break; case 3: _privateKey = new C25519::Private(); - if (Utils::unhex(f,_privateKey->data,_privateKey->size()) != _privateKey->size()) + if (Utils::unhex(f,_privateKey->data,(unsigned int)_privateKey->size()) != _privateKey->size()) return false; break; default: diff --git a/node/Identity.hpp b/node/Identity.hpp index f6b1f8766..e23a808e7 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -224,10 +224,10 @@ public: { _address.appendTo(b); b.append((unsigned char)IDENTITY_TYPE_C25519); - b.append(_publicKey.data,_publicKey.size()); + b.append(_publicKey.data,(unsigned int)_publicKey.size()); if ((_privateKey)&&(includePrivate)) { b.append((unsigned char)_privateKey->size()); - b.append(_privateKey->data,_privateKey->size()); + b.append(_privateKey->data,(unsigned int)_privateKey->size()); } else b.append((unsigned char)0); } @@ -258,8 +258,8 @@ public: if (b[p++] != IDENTITY_TYPE_C25519) throw std::invalid_argument("unsupported identity type"); - memcpy(_publicKey.data,b.field(p,_publicKey.size()),_publicKey.size()); - p += _publicKey.size(); + memcpy(_publicKey.data,b.field(p,(unsigned int)_publicKey.size()),(unsigned int)_publicKey.size()); + p += (unsigned int)_publicKey.size(); unsigned int privateKeyLength = (unsigned int)b[p++]; if (privateKeyLength) { diff --git a/node/Network.cpp b/node/Network.cpp index ad85cd775..37f006256 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -59,6 +59,9 @@ Network::~Network() if (_destroyOnDelete) { Utils::rm(std::string(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".conf")); Utils::rm(std::string(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".mcerts")); + + // TODO: on Windows we need to also remove the tap interface since they're + // sticky on that platform. } else { // Causes flush of membership certs to disk clean(); diff --git a/node/Node.cpp b/node/Node.cpp index 9bfa7ad66..d195b9f18 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -134,7 +134,7 @@ Node::LocalClient::LocalClient(const char *authToken,unsigned int controlPort,vo if (sock) { { unsigned int csk[64]; - SHA512::hash(csk,authToken,strlen(authToken)); + SHA512::hash(csk,authToken,(unsigned int)strlen(authToken)); memcpy(impl->key,csk,32); } diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index 374e99164..eb0802a4a 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -66,7 +66,7 @@ NodeConfig::NodeConfig(const RuntimeEnvironment *renv,const char *authToken,unsi { { unsigned int csk[64]; - SHA512::hash(csk,authToken,strlen(authToken)); + SHA512::hash(csk,authToken,(unsigned int)strlen(authToken)); memcpy(_controlSocketKey,csk,32); } diff --git a/node/SoftwareUpdater.cpp b/node/SoftwareUpdater.cpp index db884d803..0ce946ad2 100644 --- a/node/SoftwareUpdater.cpp +++ b/node/SoftwareUpdater.cpp @@ -113,7 +113,7 @@ bool SoftwareUpdater::validateUpdate( 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(),signature.length()); + return updateAuthority->second.verify(data,len,signature.data(),(unsigned int)signature.length()); } void SoftwareUpdater::_cbHandleGetLatestVersionInfo(void *arg,int code,const std::string &url,bool onDisk,const std::string &body) @@ -176,7 +176,7 @@ void SoftwareUpdater::_cbHandleGetLatestVersionBinary(void *arg,int code,const s const RuntimeEnvironment *_r = (const RuntimeEnvironment *)upd->_r; Mutex::Lock _l(upd->_lock); - if (!validateUpdate(body.data(),body.length(),upd->_signedBy,upd->_signature)) { + if (!validateUpdate(body.data(),(unsigned int)body.length(),upd->_signedBy,upd->_signature)) { LOG("software update aborted: update fetched from '%s' failed signature check (got %u bytes)",url.c_str(),(unsigned int)body.length()); upd->_status = UPDATE_STATUS_IDLE; return; diff --git a/node/Switch.cpp b/node/Switch.cpp index 585b87168..5473402d3 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -155,7 +155,7 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c C25519::Signature sig(_r->identity.sign(outp.field(ZT_PROTO_VERB_MULTICAST_FRAME_IDX__START_OF_SIGNED_PORTION,signedPartLen),signedPartLen)); outp.append((uint16_t)sig.size()); - outp.append(sig.data,sig.size()); + outp.append(sig.data,(unsigned int)sig.size()); if (nconf->com()) nconf->com().serialize(outp); diff --git a/selftest.cpp b/selftest.cpp index 66e1b75ed..5c96277fa 100644 --- a/selftest.cpp +++ b/selftest.cpp @@ -53,6 +53,8 @@ #include "node/Poly1305.hpp" #include "node/CertificateOfMembership.hpp" #include "node/HttpClient.hpp" +#include "node/Defaults.hpp" +#include "node/Node.hpp" #ifdef __WINDOWS__ #include @@ -70,7 +72,7 @@ static void testHttpHandler(void *arg,int code,const std::string &url,bool onDis { unsigned char sha[64]; if (code == 200) { - SHA512::hash(sha,body.data(),body.length()); + SHA512::hash(sha,body.data(),(unsigned int)body.length()); if (webSha512ShouldBe == Utils::hex(sha,64)) std::cout << "got " << body.length() << " bytes, response code " << code << ", SHA-512 OK" << std::endl; else std::cout << "got " << body.length() << " bytes, response code " << code << ", SHA-512 FAILED!" << std::endl; @@ -129,7 +131,7 @@ static int testCrypto() } std::cout << "[crypto] Testing SHA-512... "; std::cout.flush(); - SHA512::hash(buf1,sha512TV0Input,strlen(sha512TV0Input)); + SHA512::hash(buf1,sha512TV0Input,(unsigned int)strlen(sha512TV0Input)); if (memcmp(buf1,sha512TV0Digest,64)) { std::cout << "FAIL" << std::endl; return -1; @@ -465,7 +467,7 @@ static int testPacket() a.reset(Address(),Address(),Packet::VERB_HELLO); for(int i=0;i<32;++i) - a.append("supercalifragilisticexpealidocious",strlen("supercalifragilisticexpealidocious")); + a.append("supercalifragilisticexpealidocious",(unsigned int)strlen("supercalifragilisticexpealidocious")); b = a; if (a != b) { @@ -504,7 +506,7 @@ static int testOther() if ((dec.length() != flen)||(memcmp(dec.data(),fuzzbuf,dec.length()))) { std::cout << "FAILED!" << std::endl; std::cout << Utils::hex(fuzzbuf,flen) << std::endl; - std::cout << Utils::hex(dec.data(),dec.length()) << std::endl; + std::cout << Utils::hex(dec.data(),(unsigned int)dec.length()) << std::endl; return -1; } } @@ -614,6 +616,9 @@ int main(int argc,char **argv) */ std::cout << "[info] sizeof(void *) == " << sizeof(void *) << std::endl; + std::cout << "[info] default home: " << ZT_DEFAULTS.defaultHomePath << std::endl; + std::cout << "[info] system authtoken.secret: " << Node::LocalClient::authTokenDefaultSystemPath() << std::endl; + std::cout << "[info] user authtoken.secret: " << Node::LocalClient::authTokenDefaultUserPath() << std::endl; srand((unsigned int)time(0));