Merge branch 'adamierymenko-dev' into android-jni
3
.gitignore
vendored
@ -49,3 +49,6 @@ java/build_win64/
|
||||
java/build_win32/
|
||||
/java/mac32_64/
|
||||
/ext/mac-ui-macgap1-wrapper/MacGap.xcodeproj/project.xcworkspace/xcuserdata/*
|
||||
/ui/.module-cache
|
||||
/windows/WebUIWrapper/bin
|
||||
/windows/WebUIWrapper/obj
|
||||
|
BIN
artwork/ZeroTierIcon.ico
Normal file
After Width: | Height: | Size: 361 KiB |
BIN
artwork/ZeroTierIcon.png
Normal file
After Width: | Height: | Size: 26 KiB |
37
artwork/logo.html
Normal file
@ -0,0 +1,37 @@
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
html,body {
|
||||
background: #aaaaaa;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Helvetica";
|
||||
font-weight: bold;
|
||||
font-size: 12pt;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
div.icon {
|
||||
background: #ffb354;
|
||||
color: #000000;
|
||||
font-size: 150pt;
|
||||
border-radius: 2.5rem;
|
||||
display: inline-block;
|
||||
width: 1.3em;
|
||||
height: 1.3em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
line-height: 1.4em;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<br><br><br><br><br><br>
|
||||
<!-- Yes, our logo is a Unicode character. It sort of just turned out that way. -->
|
||||
<center>
|
||||
<div class="icon">⏁</div>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 715 B After Width: | Height: | Size: 715 B |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
BIN
ext/win-ui-wrapper/ZeroTier One.exe
Normal file
@ -334,29 +334,6 @@ bool Network::peerNeedsOurMembershipCertificate(const Address &to,uint64_t now)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Network::isAllowed(const Address &peer) const
|
||||
{
|
||||
try {
|
||||
Mutex::Lock _l(_lock);
|
||||
|
||||
if (!_config)
|
||||
return false;
|
||||
if (_config->isPublic())
|
||||
return true;
|
||||
|
||||
std::map<Address,CertificateOfMembership>::const_iterator pc(_membershipCertificates.find(peer));
|
||||
if (pc == _membershipCertificates.end())
|
||||
return false; // no certificate on file
|
||||
|
||||
return _config->com().agreesWith(pc->second); // is other cert valid against ours?
|
||||
} catch (std::exception &exc) {
|
||||
TRACE("isAllowed() check failed for peer %s: unexpected exception: %s",peer.toString().c_str(),exc.what());
|
||||
} catch ( ... ) {
|
||||
TRACE("isAllowed() check failed for peer %s: unexpected exception: unknown exception",peer.toString().c_str());
|
||||
}
|
||||
return false; // default position on any failure
|
||||
}
|
||||
|
||||
void Network::clean()
|
||||
{
|
||||
const uint64_t now = RR->node->now();
|
||||
@ -511,6 +488,28 @@ void Network::_externalConfig(ZT1_VirtualNetworkConfig *ec) const
|
||||
} else ec->assignedAddressCount = 0;
|
||||
}
|
||||
|
||||
bool Network::_isAllowed(const Address &peer) const
|
||||
{
|
||||
// Assumes _lock is locked
|
||||
try {
|
||||
if (!_config)
|
||||
return false;
|
||||
if (_config->isPublic())
|
||||
return true;
|
||||
|
||||
std::map<Address,CertificateOfMembership>::const_iterator pc(_membershipCertificates.find(peer));
|
||||
if (pc == _membershipCertificates.end())
|
||||
return false; // no certificate on file
|
||||
|
||||
return _config->com().agreesWith(pc->second); // is other cert valid against ours?
|
||||
} catch (std::exception &exc) {
|
||||
TRACE("isAllowed() check failed for peer %s: unexpected exception: %s",peer.toString().c_str(),exc.what());
|
||||
} catch ( ... ) {
|
||||
TRACE("isAllowed() check failed for peer %s: unexpected exception: unknown exception",peer.toString().c_str());
|
||||
}
|
||||
return false; // default position on any failure
|
||||
}
|
||||
|
||||
// Used in Network::_announceMulticastGroups()
|
||||
class _AnnounceMulticastGroupsToPeersWithActiveDirectPaths
|
||||
{
|
||||
@ -524,7 +523,7 @@ public:
|
||||
|
||||
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
|
||||
{
|
||||
if ( ( (p->hasActiveDirectPath(_now)) && (_network->isAllowed(p->address())) ) || (std::find(_supernodeAddresses.begin(),_supernodeAddresses.end(),p->address()) != _supernodeAddresses.end()) ) {
|
||||
if ( ( (p->hasActiveDirectPath(_now)) && (_network->_isAllowed(p->address())) ) || (std::find(_supernodeAddresses.begin(),_supernodeAddresses.end(),p->address()) != _supernodeAddresses.end()) ) {
|
||||
Packet outp(p->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
|
||||
|
||||
std::vector<MulticastGroup> mgs(_network->allMulticastGroups());
|
||||
@ -557,6 +556,7 @@ private:
|
||||
|
||||
void Network::_announceMulticastGroups()
|
||||
{
|
||||
// Assumes _lock is locked
|
||||
_AnnounceMulticastGroupsToPeersWithActiveDirectPaths afunc(RR,this);
|
||||
RR->topology->eachPeer<_AnnounceMulticastGroupsToPeersWithActiveDirectPaths &>(afunc);
|
||||
}
|
||||
|
@ -55,6 +55,7 @@
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
class _AnnounceMulticastGroupsToPeersWithActiveDirectPaths;
|
||||
|
||||
/**
|
||||
* A virtual LAN
|
||||
@ -62,6 +63,7 @@ class RuntimeEnvironment;
|
||||
class Network : NonCopyable
|
||||
{
|
||||
friend class SharedPtr<Network>;
|
||||
friend class _AnnounceMulticastGroupsToPeersWithActiveDirectPaths;
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -197,7 +199,11 @@ public:
|
||||
* @param peer Peer address to check
|
||||
* @return True if peer is allowed to communicate on this network
|
||||
*/
|
||||
bool isAllowed(const Address &peer) const;
|
||||
inline bool isAllowed(const Address &peer) const
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
return _isAllowed(peer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform cleanup and possibly save state
|
||||
@ -348,6 +354,7 @@ public:
|
||||
private:
|
||||
ZT1_VirtualNetworkStatus _status() const;
|
||||
void _externalConfig(ZT1_VirtualNetworkConfig *ec) const; // assumes _lock is locked
|
||||
bool _isAllowed(const Address &peer) const;
|
||||
void _announceMulticastGroups();
|
||||
|
||||
const RuntimeEnvironment *RR;
|
||||
|
@ -118,8 +118,6 @@ bool Packet::dearmor(const void *key)
|
||||
s20.decrypt(payload,payload,payloadLen);
|
||||
|
||||
return true;
|
||||
} else if (cs == ZT_PROTO_CIPHER_SUITE__C25519_AES256_GCM) {
|
||||
return false; // not implemented yet
|
||||
} else return false; // unrecognized cipher suite
|
||||
}
|
||||
|
||||
|
@ -99,14 +99,12 @@
|
||||
#define ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 1
|
||||
|
||||
/**
|
||||
* Cipher suite: Curve25519/AES256-GCM
|
||||
* DEPRECATED payload encrypted flag, will be removed for re-use soon.
|
||||
*
|
||||
* This specifies AES256 in GCM mode using GCM's built-in authentication
|
||||
* with Curve25519 elliptic curve Diffie-Hellman.
|
||||
*
|
||||
* (Not implemented yet in client but reserved for future use.)
|
||||
* This has been replaced by the two-bit cipher suite selection field where
|
||||
* a value of 0 indicated unencrypted (but authenticated) messages.
|
||||
*/
|
||||
#define ZT_PROTO_CIPHER_SUITE__C25519_AES256_GCM 2
|
||||
#define ZT_PROTO_FLAG_ENCRYPTED 0x80
|
||||
|
||||
/**
|
||||
* Header flag indicating that a packet is fragmented
|
||||
@ -116,6 +114,13 @@
|
||||
*/
|
||||
#define ZT_PROTO_FLAG_FRAGMENTED 0x40
|
||||
|
||||
/**
|
||||
* Flag indicating encryption with a PFS session key
|
||||
*
|
||||
* Not used yet -- for future PFS session re-keying support.
|
||||
*/
|
||||
#define ZT_PROTO_FLAG_PFS_SESSION 0x20
|
||||
|
||||
/**
|
||||
* Verb flag indicating payload is compressed with LZ4
|
||||
*/
|
||||
@ -293,9 +298,9 @@ namespace ZeroTier {
|
||||
*
|
||||
* Packets smaller than 28 bytes are invalid and silently discarded.
|
||||
*
|
||||
* The flags/cipher/hops bit field is: FFCCCHHH where C is a 3-bit cipher
|
||||
* selection allowing up to 8 cipher suites, F is flags (reserved, currently
|
||||
* all zero), and H is hop count.
|
||||
* The flags/cipher/hops bit field is: FFFCCHHH where C is a 2-bit cipher
|
||||
* selection allowing up to 4 cipher suites, F is outside-envelope flags,
|
||||
* and H is hop count.
|
||||
*
|
||||
* The three-bit hop count is the only part of a packet that is mutable in
|
||||
* transit without invalidating the MAC. All other bits in the packet are
|
||||
@ -968,25 +973,21 @@ public:
|
||||
*/
|
||||
inline unsigned int cipher() const
|
||||
{
|
||||
//return (((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x38) >> 3);
|
||||
// Use DEPRECATED 0x80 "encrypted" flag -- this will go away once there are no more <1.0.0 peers on the net
|
||||
return (((*this)[ZT_PACKET_IDX_FLAGS] & 0x80) == 0) ? ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE : ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012;
|
||||
// Note: this uses the new cipher spec field, which is incompatible with <1.0.0 peers
|
||||
return (((unsigned int)(*this)[ZT_PACKET_IDX_FLAGS] & 0x18) >> 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this packet's cipher suite
|
||||
*
|
||||
* This normally shouldn't be called directly as armor() will set it after
|
||||
* encrypting and MACing the packet.
|
||||
*/
|
||||
inline void setCipher(unsigned int c)
|
||||
{
|
||||
unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS];
|
||||
b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38);
|
||||
// Set both the new cipher suite spec field and the old DEPRECATED "encrypted" flag as long as there's <1.0.0 peers online
|
||||
b = (b & 0xe7) | (unsigned char)((c << 3) & 0x18); // bits: FFFCCHHH
|
||||
// DEPRECATED "encrypted" flag -- used by pre-1.0.3 peers
|
||||
if (c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)
|
||||
b |= 0x80;
|
||||
else b &= 0x7f;
|
||||
b |= ZT_PROTO_FLAG_ENCRYPTED;
|
||||
else b &= (~ZT_PROTO_FLAG_ENCRYPTED);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,7 +53,7 @@
|
||||
#include "WindowsEthernetTap.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
#include "..\windows\TapDriver\tap-windows.h"
|
||||
#include "..\windows\TapDriver6\tap-windows.h"
|
||||
|
||||
// ff:ff:ff:ff:ff:ff with no ADI
|
||||
//static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0);
|
||||
@ -89,11 +89,14 @@ public:
|
||||
};
|
||||
static const WindowsEthernetTapEnv WINENV;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// Only create or delete devices one at a time
|
||||
static Mutex _systemTapInitLock;
|
||||
|
||||
// Incrementing this causes everyone currently open to close and reopen
|
||||
static volatile int _systemTapResetStatus = 0;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
WindowsEthernetTap::WindowsEthernetTap(
|
||||
const char *hp,
|
||||
const MAC &mac,
|
||||
@ -124,11 +127,14 @@ WindowsEthernetTap::WindowsEthernetTap(
|
||||
|
||||
Mutex::Lock _l(_systemTapInitLock);
|
||||
|
||||
std::string tapDriverPath(_pathToHelpers + WINENV.tapDriverNdis6);
|
||||
const char *tapDriverName = "zttap300";
|
||||
// Use NDIS5 if it's installed, since we don't want to switch out the driver on
|
||||
// pre-existing installs (yet). We won't ship NDIS5 anymore so new installs will
|
||||
// use NDIS6.
|
||||
std::string tapDriverPath(_pathToHelpers + WINENV.tapDriverNdis5);
|
||||
const char *tapDriverName = "zttap200";
|
||||
if (::PathFileExistsA(tapDriverPath.c_str()) == FALSE) {
|
||||
tapDriverPath = _pathToHelpers + WINENV.tapDriverNdis5;
|
||||
tapDriverName = "zttap200";
|
||||
tapDriverPath = _pathToHelpers + WINENV.tapDriverNdis6;
|
||||
tapDriverName = "zttap300";
|
||||
if (::PathFileExistsA(tapDriverPath.c_str()) == FALSE) {
|
||||
throw std::runtime_error("no tap driver available: cannot find zttap300.inf (NDIS6) or zttap200.inf (NDIS5) under home path");
|
||||
}
|
||||
@ -198,7 +204,7 @@ WindowsEthernetTap::WindowsEthernetTap(
|
||||
if (devconLog != INVALID_HANDLE_VALUE)
|
||||
SetFilePointer(devconLog,0,0,FILE_END);
|
||||
|
||||
// Execute devcon to install an instance of the Microsoft Loopback Adapter
|
||||
// Execute devcon to create a new tap device
|
||||
STARTUPINFOA startupInfo;
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
if (devconLog != INVALID_HANDLE_VALUE) {
|
||||
@ -262,6 +268,12 @@ WindowsEthernetTap::WindowsEthernetTap(
|
||||
}
|
||||
} else break; // no more keys or error occurred
|
||||
}
|
||||
|
||||
// When we create a new tap device from scratch, existing taps for
|
||||
// some reason go into 'unplugged' state. This can be fixed by
|
||||
// closing and re-opening them. Incrementing this causes all
|
||||
// existing tap threads to do this.
|
||||
++_systemTapResetStatus;
|
||||
}
|
||||
|
||||
if (_netCfgInstanceId.length() > 0) {
|
||||
@ -306,15 +318,15 @@ WindowsEthernetTap::WindowsEthernetTap(
|
||||
if (ConvertInterfaceGuidToLuid(&_deviceGuid,&_deviceLuid) != NO_ERROR)
|
||||
throw std::runtime_error("unable to convert device interface GUID to LUID");
|
||||
|
||||
// Certain functions can now work (e.g. ips())
|
||||
_initialized = true;
|
||||
|
||||
if (friendlyName)
|
||||
setFriendlyName(friendlyName);
|
||||
|
||||
// Start background thread that actually performs I/O
|
||||
_injectSemaphore = CreateSemaphore(NULL,0,1,NULL);
|
||||
_thread = Thread::start(this);
|
||||
|
||||
// Certain functions can now work (e.g. ips())
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
WindowsEthernetTap::~WindowsEthernetTap()
|
||||
@ -566,38 +578,26 @@ void WindowsEthernetTap::threadMain()
|
||||
HANDLE wait4[3];
|
||||
char *tapReadBuf = (char *)0;
|
||||
|
||||
// Shouldn't be needed, but Windows does not overcommit. This Windows
|
||||
// tap code is defensive to schizoid paranoia degrees.
|
||||
if (!_enableTapDevice()) {
|
||||
_enabled = false;
|
||||
return; // only happens if devcon is missing or totally fails
|
||||
}
|
||||
|
||||
/* No idea why I did this. I did it a long time ago and there was only a
|
||||
* a snarky comment. But I'd never do crap like this without a reason, so
|
||||
* I am leaving it alone with a more descriptive snarky comment. */
|
||||
while (!tapReadBuf) {
|
||||
tapReadBuf = (char *)::malloc(ZT_IF_MTU + 32);
|
||||
if (!tapReadBuf)
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
// Tap is in this weird Windows global pseudo file space
|
||||
Utils::snprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_netCfgInstanceId.c_str());
|
||||
|
||||
/* More insanity: repetatively try to enable/disable tap device. The first
|
||||
* time we succeed, close it and do it again. This is to fix a driver init
|
||||
* bug that seems to be extremely non-deterministic and to only occur after
|
||||
* headless MSI upgrade. It cannot be reproduced in any other circumstance.
|
||||
*
|
||||
* Eventually when ZeroTier has actual money we will have someone create an
|
||||
* NDIS6 tap driver. Yes, we'll likely be cool and open source it. */
|
||||
bool throwOneAway = true;
|
||||
int prevTapResetStatus = _systemTapResetStatus;
|
||||
while (_run) {
|
||||
_disableTapDevice();
|
||||
Sleep(250);
|
||||
if (!_enableTapDevice()) {
|
||||
::free(tapReadBuf);
|
||||
_enabled = false;
|
||||
return; // only happens if devcon is missing or totally fails
|
||||
}
|
||||
Sleep(250);
|
||||
|
||||
_tap = CreateFileA(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL);
|
||||
if (_tap == INVALID_HANDLE_VALUE) {
|
||||
Sleep(500);
|
||||
fprintf(stderr,"Error opening %s -- retrying.\r\n",tapPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -605,8 +605,6 @@ void WindowsEthernetTap::threadMain()
|
||||
uint32_t tmpi = 1;
|
||||
DWORD bytesReturned = 0;
|
||||
DeviceIoControl(_tap,TAP_WIN_IOCTL_SET_MEDIA_STATUS,&tmpi,sizeof(tmpi),&tmpi,sizeof(tmpi),&bytesReturned,NULL);
|
||||
bytesReturned = 0;
|
||||
DeviceIoControl(_tap,TAP_WIN_IOCTL_SET_MEDIA_STATUS,&tmpi,sizeof(tmpi),&tmpi,sizeof(tmpi),&bytesReturned,NULL);
|
||||
}
|
||||
|
||||
{
|
||||
@ -688,75 +686,70 @@ void WindowsEthernetTap::threadMain()
|
||||
#endif
|
||||
}
|
||||
|
||||
if (throwOneAway) {
|
||||
throwOneAway = false;
|
||||
CloseHandle(_tap);
|
||||
_tap = INVALID_HANDLE_VALUE;
|
||||
Sleep(1000);
|
||||
continue;
|
||||
} else break;
|
||||
}
|
||||
memset(&tapOvlRead,0,sizeof(tapOvlRead));
|
||||
tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
memset(&tapOvlWrite,0,sizeof(tapOvlWrite));
|
||||
tapOvlWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
memset(&tapOvlRead,0,sizeof(tapOvlRead));
|
||||
tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
memset(&tapOvlWrite,0,sizeof(tapOvlWrite));
|
||||
tapOvlWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
wait4[0] = _injectSemaphore;
|
||||
wait4[1] = tapOvlRead.hEvent;
|
||||
wait4[2] = tapOvlWrite.hEvent; // only included if writeInProgress is true
|
||||
|
||||
wait4[0] = _injectSemaphore;
|
||||
wait4[1] = tapOvlRead.hEvent;
|
||||
wait4[2] = tapOvlWrite.hEvent; // only included if writeInProgress is true
|
||||
|
||||
// Start overlapped read, which is always active
|
||||
ReadFile(_tap,tapReadBuf,sizeof(tapReadBuf),NULL,&tapOvlRead);
|
||||
bool writeInProgress = false;
|
||||
|
||||
for(;;) {
|
||||
if (!_run) break;
|
||||
DWORD r = WaitForMultipleObjectsEx(writeInProgress ? 3 : 2,wait4,FALSE,5000,TRUE);
|
||||
if (!_run) break;
|
||||
|
||||
if ((r == WAIT_TIMEOUT)||(r == WAIT_FAILED))
|
||||
continue;
|
||||
|
||||
if (HasOverlappedIoCompleted(&tapOvlRead)) {
|
||||
DWORD bytesRead = 0;
|
||||
if (GetOverlappedResult(_tap,&tapOvlRead,&bytesRead,FALSE)) {
|
||||
if ((bytesRead > 14)&&(_enabled)) {
|
||||
MAC to(tapReadBuf,6);
|
||||
MAC from(tapReadBuf + 6,6);
|
||||
unsigned int etherType = ((((unsigned int)tapReadBuf[12]) & 0xff) << 8) | (((unsigned int)tapReadBuf[13]) & 0xff);
|
||||
try {
|
||||
// TODO: decode vlans
|
||||
_handler(_arg,_nwid,from,to,etherType,0,tapReadBuf + 14,bytesRead - 14);
|
||||
} catch ( ... ) {} // handlers should not throw
|
||||
}
|
||||
ReadFile(_tap,tapReadBuf,sizeof(tapReadBuf),NULL,&tapOvlRead);
|
||||
bool writeInProgress = false;
|
||||
while (_run) {
|
||||
if (prevTapResetStatus != _systemTapResetStatus) {
|
||||
prevTapResetStatus = _systemTapResetStatus;
|
||||
break; // this will cause us to close and reopen the tap
|
||||
}
|
||||
ReadFile(_tap,tapReadBuf,ZT_IF_MTU + 32,NULL,&tapOvlRead);
|
||||
DWORD r = WaitForMultipleObjectsEx(writeInProgress ? 3 : 2,wait4,FALSE,2500,TRUE);
|
||||
if (!_run) break; // will also break outer while(_run)
|
||||
|
||||
if ((r == WAIT_TIMEOUT)||(r == WAIT_FAILED))
|
||||
continue;
|
||||
|
||||
if (HasOverlappedIoCompleted(&tapOvlRead)) {
|
||||
DWORD bytesRead = 0;
|
||||
if (GetOverlappedResult(_tap,&tapOvlRead,&bytesRead,FALSE)) {
|
||||
if ((bytesRead > 14)&&(_enabled)) {
|
||||
MAC to(tapReadBuf,6);
|
||||
MAC from(tapReadBuf + 6,6);
|
||||
unsigned int etherType = ((((unsigned int)tapReadBuf[12]) & 0xff) << 8) | (((unsigned int)tapReadBuf[13]) & 0xff);
|
||||
try {
|
||||
// TODO: decode vlans
|
||||
_handler(_arg,_nwid,from,to,etherType,0,tapReadBuf + 14,bytesRead - 14);
|
||||
} catch ( ... ) {} // handlers should not throw
|
||||
}
|
||||
}
|
||||
ReadFile(_tap,tapReadBuf,ZT_IF_MTU + 32,NULL,&tapOvlRead);
|
||||
}
|
||||
|
||||
if (writeInProgress) {
|
||||
if (HasOverlappedIoCompleted(&tapOvlWrite)) {
|
||||
writeInProgress = false;
|
||||
_injectPending_m.lock();
|
||||
_injectPending.pop();
|
||||
} else continue; // still writing, so skip code below and wait
|
||||
} else _injectPending_m.lock();
|
||||
|
||||
if (!_injectPending.empty()) {
|
||||
WriteFile(_tap,_injectPending.front().first.data,_injectPending.front().second,NULL,&tapOvlWrite);
|
||||
writeInProgress = true;
|
||||
}
|
||||
|
||||
_injectPending_m.unlock();
|
||||
}
|
||||
|
||||
if (writeInProgress) {
|
||||
if (HasOverlappedIoCompleted(&tapOvlWrite)) {
|
||||
writeInProgress = false;
|
||||
_injectPending_m.lock();
|
||||
_injectPending.pop();
|
||||
} else continue; // still writing, so skip code below and wait
|
||||
} else _injectPending_m.lock();
|
||||
CancelIo(_tap);
|
||||
|
||||
if (!_injectPending.empty()) {
|
||||
WriteFile(_tap,_injectPending.front().first.data,_injectPending.front().second,NULL,&tapOvlWrite);
|
||||
writeInProgress = true;
|
||||
}
|
||||
CloseHandle(tapOvlRead.hEvent);
|
||||
CloseHandle(tapOvlWrite.hEvent);
|
||||
CloseHandle(_tap);
|
||||
_tap = INVALID_HANDLE_VALUE;
|
||||
|
||||
_injectPending_m.unlock();
|
||||
// We will restart and re-open the tap unless _run == false
|
||||
}
|
||||
|
||||
CancelIo(_tap);
|
||||
|
||||
CloseHandle(tapOvlRead.hEvent);
|
||||
CloseHandle(tapOvlWrite.hEvent);
|
||||
CloseHandle(_tap);
|
||||
_tap = INVALID_HANDLE_VALUE;
|
||||
|
||||
::free(tapReadBuf);
|
||||
}
|
||||
|
||||
|
1820
ui/JSXTransformer.min.js
vendored
6
ui/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
all:
|
||||
mkdir -p build
|
||||
jsx --target es3 -x jsx . ./build
|
||||
rm -f ztui.min.js
|
||||
minify build/*.js >>ztui.min.js
|
||||
rm -rf build
|
10
ui/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
ZeroTier HTML5 UI
|
||||
======
|
||||
|
||||
This is the new (as of 1.0.3) ZeroTier One UI. It's implemented in HTML5 and React.
|
||||
|
||||
If you make changes to the .jsx files, type 'make'. You will need NodeJS, react-tools, and minify installed and available in your path.
|
||||
|
||||
For this to work, these files must be installed in the 'ui' subfolder of the ZeroTier home path. For development it's nice to symlink this to the 'ui' folder in your working directory. If the 'ui' subfolder is not present, the UI static files will not be served by the embedded web server.
|
||||
|
||||
Packaging for Mac and Windows is accomplished by way of the wrappers in ext/. For Mac this is done with a modified version of MacGap. Windows uses a custom project that embeds a web view.
|
@ -1,8 +1,6 @@
|
||||
var ZeroTierNetwork = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
deleted: false
|
||||
};
|
||||
return {};
|
||||
},
|
||||
|
||||
leaveNetwork: function(event) {
|
||||
@ -11,7 +9,8 @@ var ZeroTierNetwork = React.createClass({
|
||||
cache: false,
|
||||
type: 'DELETE',
|
||||
success: function(data) {
|
||||
this.setState({deleted: true});
|
||||
if (this.props.onNetworkDeleted)
|
||||
this.props.onNetworkDeleted(this.props.nwid);
|
||||
}.bind(this),
|
||||
error: function(error) {
|
||||
}.bind(this)
|
||||
@ -22,13 +21,8 @@ var ZeroTierNetwork = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<div className="zeroTierNetwork">
|
||||
{
|
||||
(this.state.deleted) ? (
|
||||
<div className="deletedOverlay"> </div>
|
||||
) : (null)
|
||||
}
|
||||
<div className="networkInfo">
|
||||
<span className="networkId">{this.props.nwid}</span>
|
||||
<span className="networkId">{this.props.nwid}</span>
|
||||
<span className="networkName">{this.props.name}</span>
|
||||
</div>
|
||||
<div className="networkProps">
|
||||
@ -66,14 +60,14 @@ var ZeroTierNetwork = React.createClass({
|
||||
{
|
||||
this.props['assignedAddresses'].map(function(ipAssignment) {
|
||||
return (
|
||||
<div className="ipAddress">{ipAssignment}</div>
|
||||
<div key={ipAssignment} className="ipAddress">{ipAssignment}</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button className="leaveNetworkButton" onClick={this.leaveNetwork}>Leave Network</button>
|
||||
<button type="button" className="leaveNetworkButton" onClick={this.leaveNetwork}>Leave Network</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ var ZeroTierNode = React.createClass({
|
||||
cache: false,
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
this.alertedToFailure = false;
|
||||
if (data) {
|
||||
var status = JSON.parse(data);
|
||||
this.setState(status);
|
||||
@ -65,7 +66,11 @@ var ZeroTierNode = React.createClass({
|
||||
this.updatePeers();
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
this.setState({online: false});
|
||||
this.setState(this.getInitialState());
|
||||
if (!this.alertedToFailure) {
|
||||
this.alertedToFailure = true;
|
||||
alert('Authorization token invalid or ZeroTier One service not running.');
|
||||
}
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
@ -77,14 +82,21 @@ var ZeroTierNode = React.createClass({
|
||||
cache: false,
|
||||
type: 'POST',
|
||||
success: function(data) {
|
||||
this.networkToJoin = '';
|
||||
if (this.networkInputElement)
|
||||
this.networkInputElement.value = '';
|
||||
this.updateNetworks();
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
}.bind(this)
|
||||
});
|
||||
} else {
|
||||
alert('To join a network, enter its 16-digit network ID.');
|
||||
}
|
||||
},
|
||||
handleNetworkIdEntry: function(event) {
|
||||
var nid = event.target.value;
|
||||
this.networkInputElement = event.target;
|
||||
var nid = this.networkInputElement.value;
|
||||
if (nid) {
|
||||
nid = nid.toLowerCase();
|
||||
var nnid = '';
|
||||
@ -93,13 +105,22 @@ var ZeroTierNode = React.createClass({
|
||||
nnid += nid.charAt(i);
|
||||
}
|
||||
this.networkToJoin = nnid;
|
||||
event.target.value = nnid;
|
||||
this.networkInputElement.value = nnid;
|
||||
} else {
|
||||
this.networkToJoin = '';
|
||||
event.target.value = '';
|
||||
this.networkInputElement.value = '';
|
||||
}
|
||||
},
|
||||
|
||||
handleNetworkDelete: function(nwid) {
|
||||
var networks = [];
|
||||
for(var i=0;i<this.state._networks.length;++i) {
|
||||
if (this.state._networks[i].nwid !== nwid)
|
||||
networks.push(this.state._networks[i]);
|
||||
}
|
||||
this.setState({_networks: networks});
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.tabIndex = 0;
|
||||
this.updateAll();
|
||||
@ -109,54 +130,56 @@ var ZeroTierNode = React.createClass({
|
||||
clearInterval(this.updateIntervalId);
|
||||
},
|
||||
render: function() {
|
||||
/* We implement tabs in a very simple way here with a React JSX conditional. The tabIndex
|
||||
* local variable indicates the tab, and switching it determines which set of things we
|
||||
* render in the main middle portion. On tab switch calls forceUpdate(). */
|
||||
return (
|
||||
<div className="zeroTierNode">
|
||||
<div className="top">
|
||||
<button disabled={this.tabIndex === 0} onClick={function() {this.tabIndex = 0; this.forceUpdate();}.bind(this)}>Networks</button>
|
||||
<button disabled={this.tabIndex === 1} onClick={function() {this.tabIndex = 1; this.forceUpdate();}.bind(this)}>Peers</button>
|
||||
</div>
|
||||
<div className="middle">
|
||||
<div className="middle"><div className="middleCell">
|
||||
<div className="middleScroll">
|
||||
{
|
||||
(this.tabIndex === 1) ? (
|
||||
<div className="peers">
|
||||
<div className="peerHeader">
|
||||
<div className="peers" key="_peers">
|
||||
<div className="peerHeader" key="_peersHeader">
|
||||
<div className="f">Address</div>
|
||||
<div className="f">Version</div>
|
||||
<div className="f">Latency</div>
|
||||
<div className="f">Direct Paths</div>
|
||||
<div className="f">Data Paths</div>
|
||||
<div className="f">Last Unicast</div>
|
||||
<div className="f">Last Multicast</div>
|
||||
<div className="f">Role</div>
|
||||
</div>
|
||||
{
|
||||
this.state._peers.map(function(peer) {
|
||||
return (
|
||||
<div className="peer">
|
||||
<div className="peer" key={peer['address']}>
|
||||
<div className="f zeroTierAddress">{peer['address']}</div>
|
||||
<div className="f">{(peer['version'] === '-1.-1.-1') ? '-' : peer['version']}</div>
|
||||
<div className="f">{peer['latency']}</div>
|
||||
<div className="f">
|
||||
{
|
||||
(peer['paths'].length === 0) ? (
|
||||
<div className="peerPath"><i>(none)</i></div>
|
||||
<div className="peerPath"></div>
|
||||
) : (
|
||||
<div>
|
||||
{
|
||||
peer['paths'].map(function(path) {
|
||||
if ((path.active)||(path.fixed)) {
|
||||
return (
|
||||
<div className="peerPath">{path.address} {this.ago(path.lastSend)} {this.ago(path.lastReceive)}{path.preferred ? ' *' : ''}</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="peerPathInactive">{path.address} {this.ago(path.lastSend)} {this.ago(path.lastReceive)}</div>
|
||||
);
|
||||
}
|
||||
var cn = ((path.active)||(path.fixed)) ? (path.preferred ? 'peerPathPreferred' : 'peerPathActive') : 'peerPathInactive';
|
||||
return (
|
||||
<div className={cn}>{path.address} {this.ago(path.lastSend)}/{this.ago(path.lastReceive)}</div>
|
||||
);
|
||||
}.bind(this))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className="f">{this.ago(peer['lastUnicastFrame'])}</div>
|
||||
<div className="f">{this.ago(peer['lastMulticastFrame'])}</div>
|
||||
<div className="f">{peer['role']}</div>
|
||||
</div>
|
||||
);
|
||||
@ -164,24 +187,25 @@ var ZeroTierNode = React.createClass({
|
||||
}
|
||||
</div>
|
||||
) : (
|
||||
<div className="networks">
|
||||
<div className="networks" key="_networks">
|
||||
{
|
||||
this.state._networks.map(function(network) {
|
||||
network['authToken'] = this.props.authToken;
|
||||
return React.createElement('div',{className: 'network'},React.createElement(ZeroTierNetwork,network));
|
||||
network['onNetworkDeleted'] = this.handleNetworkDelete;
|
||||
return React.createElement('div',{className: 'network',key: network.nwid},React.createElement(ZeroTierNetwork,network));
|
||||
}.bind(this))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div className="bottom">
|
||||
<div className="left">
|
||||
<span className="statusLine"><span className="zeroTierAddress">{this.state.address}</span> {this.state.online ? 'ONLINE' : 'OFFLINE'} {this.state.version}</span>
|
||||
</div>
|
||||
<div className="right">
|
||||
<form onSubmit={this.joinNetwork}><input type="text" placeholder="################" onChange={this.handleNetworkIdEntry} size="16"/><button type="submit">Join</button></form>
|
||||
<form onSubmit={this.joinNetwork}><input type="text" maxlength="16" placeholder="[ Network ID ]" onChange={this.handleNetworkIdEntry} size="16"/><button type="button" onClick={this.joinNetwork}>Join</button></form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,25 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>ZeroTier One</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!--
|
||||
<link rel="stylesheet" href="bootstrap.min.css">
|
||||
<link rel="stylesheet" href="bootstrap-theme.min.css">
|
||||
-->
|
||||
<link rel="stylesheet" href="zerotier.css">
|
||||
|
||||
<script src="simpleajax.min.js"></script>
|
||||
<script src="react.min.js"></script>
|
||||
<script src="JSXTransformer.min.js"></script>
|
||||
|
||||
<script type="text/jsx" src="ZeroTierNetwork.jsx"></script>
|
||||
<script type="text/jsx" src="ZeroTierNode.jsx"></script>
|
||||
|
||||
<script type="text/jsx" src="main.jsx"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width: 100%; height: 100%;" id="main"></div>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>ZeroTier One</title>
|
||||
<link rel="stylesheet" href="zerotier.css">
|
||||
<script src="simpleajax.min.js"></script>
|
||||
<!-- <script src="https://fb.me/react-0.13.2.js"></script> -->
|
||||
<script src="react.min.js"></script>
|
||||
<script src="ztui.min.js"></script>
|
||||
</head>
|
||||
<body><div style="width: 100%; height: 100%;" id="main"></div></body>
|
||||
<script src="main.js"></script>
|
||||
<script>
|
||||
function isIE() {
|
||||
var myNav = navigator.userAgent.toLowerCase();
|
||||
return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
|
||||
}
|
||||
var ieVersion = isIE();
|
||||
function resizeMiddleScrollClasses() {
|
||||
var elems = document.getElementsByTagName('*'), i;
|
||||
for (i in elems) {
|
||||
if ((' ' + elems[i].className + ' ').indexOf(' middleScroll ') > -1) {
|
||||
elems[i].style.height = (document.body.clientHeight - (elems[i].parentNode.parentNode.previousElementSibling.clientHeight + elems[i].parentNode.parentNode.nextElementSibling.clientHeight)) + "px";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ieVersion !== false) {
|
||||
if (ieVersion < 7) {
|
||||
alert("Upgrade Internet Explorer on your system to use this interface. (detected version: " + ieVersion + ")");
|
||||
} else {
|
||||
resizeMiddleScrollClasses();
|
||||
window.onresize = resizeMiddleScrollClasses;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
|
@ -46,6 +46,6 @@ if ((!ztAuthToken)||(ztAuthToken.length <= 0)) {
|
||||
}
|
||||
|
||||
React.render(
|
||||
<ZeroTierNode authToken={ztAuthToken} />,
|
||||
React.createElement(ZeroTierNode, {authToken: ztAuthToken}),
|
||||
document.getElementById('main')
|
||||
);
|
111
ui/zerotier.css
@ -20,7 +20,6 @@ html,body {
|
||||
.zeroTierNode {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: table;
|
||||
@ -55,80 +54,105 @@ html,body {
|
||||
}
|
||||
|
||||
.zeroTierNode > .middle {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
display: table-row;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll {
|
||||
.zeroTierNode > .middle > .middleCell {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: table-cell;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: scroll;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
background: #eeeeee;
|
||||
background: #dddddd;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .networks {
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .networks {
|
||||
display: block;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
padding: 0 0 0.25rem 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
text-align: left;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .networks > .network {
|
||||
padding: 0.5rem;
|
||||
margin: 0.25rem;
|
||||
float: left;
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .networks > .network {
|
||||
display: inline-block;
|
||||
padding: 0.25rem;
|
||||
margin: 0.25rem 0 0 1%;
|
||||
min-width: 31%;
|
||||
max-width: 98%;
|
||||
border: 1px solid #234447;
|
||||
background: #ffffff;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers {
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers {
|
||||
display: table;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peer {
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers > .peer {
|
||||
width: 100%;
|
||||
display: table-row;
|
||||
background: #ffffff;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peer .peerPath {
|
||||
font-size: 10pt;
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers > .peer:nth-child(odd) {
|
||||
background: #f3f3f3;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers > .peer:nth-child(even) {
|
||||
}
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers > .peer .peerPathActive {
|
||||
font-size: 8pt;
|
||||
color: #555555;
|
||||
font-style: italic;
|
||||
font-family: monospace;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peer .peerPathInactive {
|
||||
font-size: 10pt;
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers > .peer .peerPathPreferred {
|
||||
font-size: 8pt;
|
||||
color: #000000;
|
||||
font-family: monospace;
|
||||
color: #bbbbbb;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers > .peer .peerPathInactive {
|
||||
font-size: 8pt;
|
||||
font-family: monospace;
|
||||
color: #aaaaaa;
|
||||
font-style: italic;
|
||||
text-decoration: line-through;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peer > .f {
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers > .peer > .f {
|
||||
display: table-cell;
|
||||
font-size: 10pt;
|
||||
padding: 0.05rem 0.15rem 0.05rem 0.15rem;
|
||||
font-size: 8pt;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peerHeader {
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers > .peerHeader {
|
||||
width: 100%;
|
||||
font-size: 8pt;
|
||||
display: table-row;
|
||||
background: #ffffff;
|
||||
border-bottom: 1px solid #000000;
|
||||
}
|
||||
.zeroTierNode > .middle > .middleScroll > .peers > .peerHeader > .f {
|
||||
.zeroTierNode > .middle > .middleCell > .middleScroll > .peers > .peerHeader > .f {
|
||||
display: table-cell;
|
||||
font-size: 10pt;
|
||||
font-size: 8pt;
|
||||
padding: 0.05rem 0.15rem 0.05rem 0.15rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.zeroTierNode > .bottom {
|
||||
font-size: 12pt;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: table-row;
|
||||
@ -140,29 +164,38 @@ html,body {
|
||||
white-space: nowrap;
|
||||
float: left;
|
||||
padding: 0 0 0 0.5rem;
|
||||
font-size: 12pt;
|
||||
height: 100%;
|
||||
}
|
||||
.zeroTierNode > .bottom > .left > .statusLine {
|
||||
font-family: monospace;
|
||||
white-space: nowrap;
|
||||
font-size: 12pt;
|
||||
height: 100%;
|
||||
}
|
||||
.zeroTierNode > .bottom > .right {
|
||||
background: #91a2a3;
|
||||
text-align: right;
|
||||
height: 100%;
|
||||
white-space: nowrap;
|
||||
float: right;
|
||||
font-size: 12pt;
|
||||
}
|
||||
.zeroTierNode > .bottom > .right form {
|
||||
height: 100%;
|
||||
}
|
||||
.zeroTierNode > .bottom > .right input {
|
||||
font-family: monospace;
|
||||
font-size: 12pt;
|
||||
background: #91a2a3;
|
||||
color: #ffffff;
|
||||
background: #ffffff;
|
||||
color: #000000;
|
||||
outline: none;
|
||||
outline-style: none;
|
||||
box-shadow: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0.05rem 0.25rem 0.05rem 0.25rem;
|
||||
padding: 0 0.25rem 0 0.25rem;
|
||||
display: inline;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.zeroTierNode > .bottom > .right button {
|
||||
display: inline-block;
|
||||
@ -172,10 +205,14 @@ html,body {
|
||||
color: #000000;
|
||||
margin: 0;
|
||||
padding: 0.05rem 0.75rem 0.05rem 0.75rem;
|
||||
outline: none;
|
||||
outline-style: none;
|
||||
height: 100%;
|
||||
}
|
||||
.zeroTierNode > .bottom > .right button:hover {
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
outline-style: none;
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
||||
@ -187,23 +224,13 @@ html,body {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.zeroTierNetwork .deletedOverlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background: rgba(255,255,255,0.8);
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
.zeroTierNetwork .networkInfo {
|
||||
padding: 0 0 0.5rem 0;
|
||||
padding: 0 0 0.25rem 0;
|
||||
text-align: left;
|
||||
font-size: 12pt;
|
||||
}
|
||||
.zeroTierNetwork .networkInfo .networkId {
|
||||
font-size: 10pt;
|
||||
font-size: 11pt;
|
||||
font-family: monospace;
|
||||
color: #91a2a3;
|
||||
}
|
||||
@ -242,7 +269,7 @@ html,body {
|
||||
}
|
||||
.zeroTierNetwork .leaveNetworkButton {
|
||||
padding: 0.25rem 0.5rem 0.25rem 0.5rem;
|
||||
margin: 0.5rem 0 0 0;
|
||||
margin: 0.25rem 0 0 0;
|
||||
font-size: 10pt;
|
||||
background: #ffffff;
|
||||
outline: none;
|
||||
|
1
ui/ztui.min.js
vendored
Normal file
6
windows/WebUIWrapper/App.config
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
</configuration>
|
65
windows/WebUIWrapper/Form1.Designer.cs
generated
Normal file
@ -0,0 +1,65 @@
|
||||
namespace WebUIWrapper
|
||||
{
|
||||
partial class Form1
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
|
||||
this.webContainer = new System.Windows.Forms.WebBrowser();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// webContainer
|
||||
//
|
||||
this.webContainer.AllowNavigation = false;
|
||||
this.webContainer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.webContainer.IsWebBrowserContextMenuEnabled = false;
|
||||
this.webContainer.Location = new System.Drawing.Point(0, 0);
|
||||
this.webContainer.MinimumSize = new System.Drawing.Size(20, 20);
|
||||
this.webContainer.Name = "webContainer";
|
||||
this.webContainer.Size = new System.Drawing.Size(1012, 556);
|
||||
this.webContainer.TabIndex = 0;
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1012, 556);
|
||||
this.Controls.Add(this.webContainer);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "Form1";
|
||||
this.Text = "ZeroTier One";
|
||||
this.Load += new System.EventHandler(this.Form1_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.WebBrowser webContainer;
|
||||
}
|
||||
}
|
||||
|
74
windows/WebUIWrapper/Form1.cs
Normal file
@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace WebUIWrapper
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Form1_Load(object sender, EventArgs e)
|
||||
{
|
||||
String ztDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\ZeroTier\\One";
|
||||
String authToken = "";
|
||||
Int32 port = 9993;
|
||||
try
|
||||
{
|
||||
byte[] tmp = File.ReadAllBytes(ztDir + "\\authtoken.secret");
|
||||
authToken = System.Text.Encoding.ASCII.GetString(tmp).Trim();
|
||||
} catch {
|
||||
MessageBox.Show("Unable to read ZeroTier One authtoken.secret from:\r\n" + ztDir,"ZeroTier One");
|
||||
this.Close();
|
||||
}
|
||||
if ((authToken == null)||(authToken.Length <= 0))
|
||||
{
|
||||
MessageBox.Show("Unable to read ZeroTier One authtoken.secret from:\r\n" + ztDir, "ZeroTier One");
|
||||
this.Close();
|
||||
}
|
||||
try
|
||||
{
|
||||
byte[] tmp = File.ReadAllBytes(ztDir + "\\zerotier-one.port");
|
||||
port = Int32.Parse(System.Text.Encoding.ASCII.GetString(tmp).Trim());
|
||||
if ((port <= 0) || (port > 65535))
|
||||
port = 9993;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
TcpClient tc = new TcpClient();
|
||||
try
|
||||
{
|
||||
tc.Connect("127.0.0.1", port);
|
||||
tc.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBox.Show("ZeroTier One service does not appear to be running at local port " + port.ToString(),"ZeroTier One");
|
||||
this.Close();
|
||||
return;
|
||||
}
|
||||
webContainer.Navigate("http://127.0.0.1:" + port.ToString() + "/index.html?authToken=" + authToken);
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBox.Show("Unable to open service control panel.", "ZeroTier One");
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
6293
windows/WebUIWrapper/Form1.resx
Normal file
22
windows/WebUIWrapper/Program.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace WebUIWrapper
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new Form1());
|
||||
}
|
||||
}
|
||||
}
|
36
windows/WebUIWrapper/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ZeroTier One")]
|
||||
[assembly: AssemblyDescription("UI Wrapper")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("ZeroTier, Inc.")]
|
||||
[assembly: AssemblyProduct("ZeroTier One")]
|
||||
[assembly: AssemblyCopyright("Copyright ©2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("98eb6dae-d218-4a8c-9935-a0ccdca3e936")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
63
windows/WebUIWrapper/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.34209
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace WebUIWrapper.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WebUIWrapper.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
windows/WebUIWrapper/Properties/Resources.resx
Normal file
@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
26
windows/WebUIWrapper/Properties/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.34209
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace WebUIWrapper.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
windows/WebUIWrapper/Properties/Settings.settings
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
52
windows/WebUIWrapper/Properties/app.manifest
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
Specifying requestedExecutionLevel node will disable file and registry virtualization.
|
||||
If you want to utilize File and Registry Virtualization for backward
|
||||
compatibility then delete the requestedExecutionLevel node.
|
||||
-->
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
<applicationRequestMinimum>
|
||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
||||
<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
|
||||
</applicationRequestMinimum>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of all Windows versions that this application is designed to work with.
|
||||
Windows will automatically select the most compatible environment.-->
|
||||
<!-- If your application is designed to work with Windows Vista, uncomment the following supportedOS node-->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>-->
|
||||
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
|
||||
<!-- If your application is designed to work with Windows 8, uncomment the following supportedOS node-->
|
||||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>-->
|
||||
</application>
|
||||
</compatibility>
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
<!-- <dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>-->
|
||||
</asmv1:assembly>
|
144
windows/WebUIWrapper/WebUIWrapper.csproj
Normal file
@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{04832129-0F0C-438B-ACDF-8BB7F99AE241}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>WebUIWrapper</RootNamespace>
|
||||
<AssemblyName>ZeroTier One</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>
|
||||
</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>WebUIWrapper.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetZone>LocalIntranet</TargetZone>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateManifests>false</GenerateManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>ZeroTierIcon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Form1.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Form1.Designer.cs">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Form1.resx">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="Properties\app.manifest" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.5 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="ZeroTierIcon.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
BIN
windows/WebUIWrapper/ZeroTierIcon.ico
Normal file
After Width: | Height: | Size: 361 KiB |
@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZeroTierOne", "ZeroTierOne\
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TapDriver6", "TapDriver6\TapDriver6.vcxproj", "{43BA7584-D4DB-4F7C-90FC-E2B18A68A213}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebUIWrapper", "WebUIWrapper\WebUIWrapper.csproj", "{04832129-0F0C-438B-ACDF-8BB7F99AE241}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
CD_ROM|Any CPU = CD_ROM|Any CPU
|
||||
@ -440,6 +442,83 @@ Global
|
||||
{43BA7584-D4DB-4F7C-90FC-E2B18A68A213}.Win8 Release|x86.ActiveCfg = Win8 Release|Win32
|
||||
{43BA7584-D4DB-4F7C-90FC-E2B18A68A213}.Win8 Release|x86.Build.0 = Win8 Release|Win32
|
||||
{43BA7584-D4DB-4F7C-90FC-E2B18A68A213}.Win8 Release|x86.Deploy.0 = Win8 Release|Win32
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.CD_ROM|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.CD_ROM|Any CPU.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.CD_ROM|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.CD_ROM|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.CD_ROM|Win32.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.CD_ROM|x64.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.CD_ROM|x86.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.DVD-5|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.DVD-5|Any CPU.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.DVD-5|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.DVD-5|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.DVD-5|Win32.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.DVD-5|x64.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.DVD-5|x86.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.SingleImage|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.SingleImage|Any CPU.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.SingleImage|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.SingleImage|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.SingleImage|Win32.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.SingleImage|x64.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.SingleImage|x86.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Release|x64.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Vista Release|x86.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Release|x64.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win7 Release|x86.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Release|x64.ActiveCfg = Release|Any CPU
|
||||
{04832129-0F0C-438B-ACDF-8BB7F99AE241}.Win8 Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|