mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2026-09-22 15:29:03 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c17082a4f8 | ||
|
|
9acfd3eb73 | ||
|
|
0ad84b8723 | ||
|
|
3f912eb4ad | ||
|
|
f1b45f7df0 | ||
|
|
29c18d4bde | ||
|
|
33728840ec | ||
|
|
cd339486b7 | ||
|
|
e54a34d8dd | ||
|
|
d24b192f8c | ||
|
|
0442d7e2d6 | ||
|
|
5b97bb247e | ||
|
|
8a7486577a | ||
|
|
6d17993eb6 | ||
|
|
d0e5da2884 | ||
|
|
d5b50ee466 | ||
|
|
8031fe00c7 | ||
|
|
3f6152806f | ||
|
|
7fdca150a9 | ||
|
|
165de71754 | ||
|
|
6b1a4b6e64 | ||
|
|
aaf0ef6b19 | ||
|
|
fb2745ba3b | ||
|
|
d452ed7db8 |
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Binary file not shown.
@@ -45,7 +45,8 @@ SOURCES += main.cpp \
|
||||
../ext/lz4/lz4hc.c \
|
||||
networkwidget.cpp \
|
||||
installdialog.cpp \
|
||||
licensedialog.cpp
|
||||
licensedialog.cpp \
|
||||
onetimedialog.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
aboutwindow.h \
|
||||
@@ -98,14 +99,16 @@ HEADERS += mainwindow.h \
|
||||
installdialog.h \
|
||||
mac_doprivileged.h \
|
||||
licensedialog.h \
|
||||
main.h
|
||||
main.h \
|
||||
onetimedialog.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
aboutwindow.ui \
|
||||
networkwidget.ui \
|
||||
installdialog.ui \
|
||||
licensedialog.ui \
|
||||
quickstartdialog.ui
|
||||
quickstartdialog.ui \
|
||||
onetimedialog.ui
|
||||
|
||||
RESOURCES += \
|
||||
resources.qrc
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define MAIN_H
|
||||
|
||||
#include <QSettings>
|
||||
#include <QMainWindow>
|
||||
|
||||
extern QSettings *settings;
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
ZeroTier::Node::LocalClient *zeroTierClient = (ZeroTier::Node::LocalClient *)0;
|
||||
|
||||
// Main window instance for app
|
||||
static MainWindow *mainWindow = (MainWindow *)0;
|
||||
QMainWindow *mainWindow = (MainWindow *)0;
|
||||
|
||||
// Handles message from ZeroTier One service
|
||||
static void handleZTMessage(void *arg,unsigned long id,const char *line)
|
||||
|
||||
@@ -51,6 +51,9 @@ class MainWindow;
|
||||
// Can be null if not connected, or will point to current
|
||||
extern ZeroTier::Node::LocalClient *zeroTierClient;
|
||||
|
||||
// Globally visible pointer to main app window
|
||||
extern QMainWindow *mainWindow;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "networkwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "ui_networkwidget.h"
|
||||
#include "onetimedialog.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QString>
|
||||
@@ -43,7 +45,8 @@
|
||||
NetworkWidget::NetworkWidget(QWidget *parent,const std::string &nwid) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::NetworkWidget),
|
||||
networkIdStr(nwid)
|
||||
networkIdStr(nwid),
|
||||
publicWarningShown(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->networkIdButton->setText(QString(nwid.c_str()));
|
||||
@@ -98,9 +101,15 @@ void NetworkWidget::setNetworkType(const std::string &type)
|
||||
ui->networkTypeLabel->setText(QString(type.c_str()));
|
||||
if (type == "?")
|
||||
ui->networkTypeLabel->setStatusTip("Waiting for configuration...");
|
||||
else if (type == "public")
|
||||
else if (type == "public") {
|
||||
if ((!publicWarningShown)&&(!settings->value("shown_publicWarning",false).toBool())) {
|
||||
publicWarningShown = true;
|
||||
OneTimeDialog *d = new OneTimeDialog(mainWindow,"shown_publicWarning","Security Notice","Security Notice:"ZT_EOL_S""ZT_EOL_S"You have joined a public network. Anyone can join these. We recommend making sure that your system's automatic software updates are enabled and turning off any shared network services that you do not want people to access.");
|
||||
d->setModal(false);
|
||||
d->show();
|
||||
}
|
||||
ui->networkTypeLabel->setStatusTip("This network can be joined by anyone in the world.");
|
||||
else if (type == "private")
|
||||
} else if (type == "private")
|
||||
ui->networkTypeLabel->setStatusTip("This network is private; only authorized peers can join.");
|
||||
else ui->networkTypeLabel->setStatusTip("Unknown network type.");
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ private slots:
|
||||
private:
|
||||
Ui::NetworkWidget *ui;
|
||||
std::string networkIdStr;
|
||||
bool publicWarningShown;
|
||||
};
|
||||
|
||||
#endif // NETWORK_H
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "onetimedialog.h"
|
||||
#include "ui_onetimedialog.h"
|
||||
#include "main.h"
|
||||
|
||||
OneTimeDialog::OneTimeDialog(QWidget *parent,const char *propName,const QString &title,const QString &message) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::OneTimeDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->label->setText(message);
|
||||
this->setWindowTitle(title);
|
||||
_propName = propName;
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
QWidgetList widgets = this->findChildren<QWidget*>();
|
||||
foreach(QWidget *widget, widgets) {
|
||||
QFont font(widget->font());
|
||||
font.setPointSizeF(font.pointSizeF() * 0.75);
|
||||
widget->setFont(font);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
OneTimeDialog::~OneTimeDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void OneTimeDialog::on_pushButton_clicked()
|
||||
{
|
||||
if (_propName) {
|
||||
settings->setValue(_propName,ui->checkBox->isChecked());
|
||||
settings->sync();
|
||||
}
|
||||
this->close();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef ONETIMEDIALOG_H
|
||||
#define ONETIMEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class OneTimeDialog;
|
||||
}
|
||||
|
||||
class OneTimeDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OneTimeDialog(QWidget *parent = 0,const char *propName = (const char *)0,const QString &title = QString(),const QString &message = QString());
|
||||
~OneTimeDialog();
|
||||
|
||||
private slots:
|
||||
void on_pushButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::OneTimeDialog *ui;
|
||||
const char *_propName;
|
||||
};
|
||||
|
||||
#endif // ONETIMEDIALOG_H
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OneTimeDialog</class>
|
||||
<widget class="QDialog" name="OneTimeDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>496</width>
|
||||
<height>197</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Don't Show This Message Again</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,51 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# This script signs an installer, creates its .NFO file, and
|
||||
# copies it to a destination directory. This in turn can be
|
||||
# uploaded to the official ZeroTier Networks update site for
|
||||
# auto-updating binary distribution users.
|
||||
#
|
||||
# It's in attic/ because end-users won't find it particularly
|
||||
# useful. You must have the ZeroTier One official signing
|
||||
# identity secret keys to sign binary releases for auto-update,
|
||||
# and of course you'd also have to upload it to our servers.
|
||||
#
|
||||
|
||||
# Build the app and the installer, then run this from the root
|
||||
# of the source tree. It'll need the zerotier-idtool symlink
|
||||
# that will be placed there after a build, too.
|
||||
|
||||
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <path to secret signing identity>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e zerotier-idtool ]; then
|
||||
echo "Unable to find zerotier-idtool in current directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
secret="$1"
|
||||
|
||||
if [ ! -e "$secret" ]; then
|
||||
echo "Can't find $secret"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -f *.nfo
|
||||
|
||||
for inst in `ls ZeroTierOneInstaller-*-*-*_*_*`; do
|
||||
echo "Found installer: $inst"
|
||||
nfo="$inst.nfo"
|
||||
rm -f "$nfo"
|
||||
echo "tss=`date`" >>"$nfo"
|
||||
echo "vMajor=`echo $inst | cut -d - -f 4 | cut -d _ -f 1`" >>"$nfo"
|
||||
echo "vMinor=`echo $inst | cut -d - -f 4 | cut -d _ -f 2`" >>"$nfo"
|
||||
echo "vRevision=`echo $inst | cut -d - -f 4 | cut -d _ -f 3`" >>"$nfo"
|
||||
echo "signedBy=`cat $secret | cut -d : -f 1`" >>"$nfo"
|
||||
echo "ed25519=`./zerotier-idtool sign $secret $inst`" >>"$nfo"
|
||||
echo "url=http://download.zerotier.com/$inst" >>"$nfo"
|
||||
done
|
||||
@@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<DOCUMENT Type="Advanced Installer" CreateVersion="10.9" version="10.9" Modules="simple" RootPath="." Language="en" Id="{DC564647-6BF0-4550-87F4-89C938D0159C}">
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
|
||||
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
|
||||
<ROW Property="ALLUSERS" Value="1"/>
|
||||
<ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]." ValueLocId="*"/>
|
||||
<ROW Property="ARPCONTACT" Value="contact@zerotier.com"/>
|
||||
<ROW Property="ARPNOMODIFY" MultiBuildValue="DefaultBuild:1"/>
|
||||
<ROW Property="ARPNOREPAIR" Value="1"/>
|
||||
<ROW Property="ARPPRODUCTICON" Value="zt1icon.exe" Type="8"/>
|
||||
<ROW Property="ARPURLINFOABOUT" Value="https://www.zerotier.com/"/>
|
||||
<ROW Property="LIMITUI" MultiBuildValue="DefaultBuild:1"/>
|
||||
<ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
|
||||
<ROW Property="Manufacturer" Value="ZeroTier Networks LLC"/>
|
||||
<ROW Property="ProductCode" Value="1033:{24DFCEE7-3AC9-4D39-BD53-974220C12043} " Type="16"/>
|
||||
<ROW Property="ProductLanguage" Value="1033"/>
|
||||
<ROW Property="ProductName" Value="ZeroTier One"/>
|
||||
<ROW Property="ProductVersion" Value="0.7.0" Type="32"/>
|
||||
<ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
|
||||
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
|
||||
<ROW Property="UpgradeCode" Value="{B0E2A5F3-88B6-4E77-B922-CB4739B4C4C8}"/>
|
||||
<ROW Property="WindowsType9X" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
|
||||
<ROW Property="WindowsType9XDisplay" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT" MultiBuildValue="DefaultBuild:Windows 2000, Windows 2000 Service Pack 1, Windows 2000 Service Pack 2, Windows 2000 Service Pack 3, Windows 2000 Service Pack 4, Windows XP x86, Windows XP x86 Service Pack 1, Windows XP x86 Service Pack 2, Windows XP x86 Service Pack 3" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT40" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT40Display" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT64" MultiBuildValue="DefaultBuild:Windows XP x64, Windows XP x64 Service Pack 1, Windows XP x64 Service Pack 2" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT64Display" MultiBuildValue="DefaultBuild:Windows XP x64" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNTDisplay" MultiBuildValue="DefaultBuild:Windows 2000, Windows XP x86" ValueLocId="-"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent">
|
||||
<ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/>
|
||||
<ROW Directory="TARGETDIR" DefaultDir="SourceDir"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
||||
<ROW Component="ProductInformation" ComponentId="{DB078D04-EA8E-4A7C-9001-89BAD932F9D9}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="ProductInformation"/>
|
||||
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
|
||||
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" Languages="en" InstallationType="4" UseLargeSchema="true"/>
|
||||
<ATTRIBUTE name="CurrentBuild" value="DefaultBuild"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.CacheComponent">
|
||||
<ATTRIBUTE name="Enable" value="false"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent">
|
||||
<ROW Path="<AI_DICTS>ui.ail"/>
|
||||
<ROW Path="<AI_DICTS>ui_en.ail"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent">
|
||||
<ROW Fragment="CommonUI.aip" Path="<AI_FRAGS>CommonUI.aip"/>
|
||||
<ROW Fragment="MaintenanceTypeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceTypeDlg.aip"/>
|
||||
<ROW Fragment="MaintenanceWelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceWelcomeDlg.aip"/>
|
||||
<ROW Fragment="SequenceDialogs.aip" Path="<AI_THEMES>classic\fragments\SequenceDialogs.aip"/>
|
||||
<ROW Fragment="Sequences.aip" Path="<AI_FRAGS>Sequences.aip"/>
|
||||
<ROW Fragment="StaticUIStrings.aip" Path="<AI_FRAGS>StaticUIStrings.aip"/>
|
||||
<ROW Fragment="UI.aip" Path="<AI_THEMES>classic\fragments\UI.aip"/>
|
||||
<ROW Fragment="Validation.aip" Path="<AI_FRAGS>Validation.aip"/>
|
||||
<ROW Fragment="VerifyRemoveDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRemoveDlg.aip"/>
|
||||
<ROW Fragment="VerifyRepairDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRepairDlg.aip"/>
|
||||
<ROW Fragment="WelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\WelcomeDlg.aip"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
|
||||
<ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlComponent">
|
||||
<ROW Dialog_="WelcomeDlg" Control="WelcomeDlgDialogInitializer" Type="DialogInitializer" X="0" Y="0" Width="0" Height="0" Attributes="0" Order="-1" TextLocId="-" HelpLocId="-" ExtDataLocId="-"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent">
|
||||
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="EndDialog" Argument="Return" Condition="AI_INSTALL" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceWelcomeDlg" Control_="Next" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="99"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_MAINT" Ordering="198"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="202"/>
|
||||
<ROW Dialog_="CustomizeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_MAINT" Ordering="101"/>
|
||||
<ROW Dialog_="CustomizeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="ChangeButton" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="501"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceWelcomeDlg" Condition="AI_MAINT" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="RemoveButton" Event="NewDialog" Argument="VerifyRemoveDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="601"/>
|
||||
<ROW Dialog_="VerifyRemoveDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="RepairButton" Event="NewDialog" Argument="VerifyRepairDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="601"/>
|
||||
<ROW Dialog_="VerifyRepairDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="1"/>
|
||||
<ROW Dialog_="VerifyRepairDlg" Control_="Repair" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="399" Options="1"/>
|
||||
<ROW Dialog_="VerifyRemoveDlg" Control_="Remove" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="299" Options="1"/>
|
||||
<ROW Dialog_="PatchWelcomeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_PATCH" Ordering="201"/>
|
||||
<ROW Dialog_="ResumeDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_RESUME" Ordering="299"/>
|
||||
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfRbDiskDlg" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)" Ordering="2" Options="2"/>
|
||||
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="EnableRollback" Argument="False" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"" Ordering="3" Options="2"/>
|
||||
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfDiskDlg" Condition="AI_INSTALL AND ( (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F") )" Ordering="4" Options="2"/>
|
||||
<ROW Dialog_="WelcomeDlg" Control_="WelcomeDlgDialogInitializer" Event="[AI_ButtonText_Next_Orig]" Argument="[ButtonText_Next]" Condition="AI_INSTALL" Ordering="0" Options="2"/>
|
||||
<ROW Dialog_="WelcomeDlg" Control_="WelcomeDlgDialogInitializer" Event="[ButtonText_Next]" Argument="[[AI_CommitButton]]" Condition="AI_INSTALL" Ordering="1" Options="2"/>
|
||||
<ROW Dialog_="WelcomeDlg" Control_="WelcomeDlgDialogInitializer" Event="[AI_Text_Next_Orig]" Argument="[Text_Next]" Condition="AI_INSTALL" Ordering="2" Options="2"/>
|
||||
<ROW Dialog_="WelcomeDlg" Control_="WelcomeDlgDialogInitializer" Event="[Text_Next]" Argument="[Text_Install]" Condition="AI_INSTALL" Ordering="3" Options="2"/>
|
||||
<ROW Dialog_="WelcomeDlg" Control_="Back" Event="[ButtonText_Next]" Argument="[AI_ButtonText_Next_Orig]" Condition="AI_INSTALL" Ordering="0" Options="2"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/>
|
||||
<ROW Dialog_="WelcomeDlg" Control_="Back" Event="[Text_Next]" Argument="[AI_Text_Next_Orig]" Condition="AI_INSTALL" Ordering="1" Options="2"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
|
||||
<ROW Action="AI_DOWNGRADE" Type="19" Target="4010"/>
|
||||
<ROW Action="AI_DpiContentScale" Type="1" Source="aicustact.dll" Target="DpiContentScale"/>
|
||||
<ROW Action="AI_InstallModeCheck" Type="1" Source="aicustact.dll" Target="UpdateInstallMode" WithoutSeq="true"/>
|
||||
<ROW Action="AI_PREPARE_UPGRADE" Type="65" Source="aicustact.dll" Target="PrepareUpgrade"/>
|
||||
<ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/>
|
||||
<ROW Action="AI_ResolveLocalizedCredentials" Type="1" Source="aicustact.dll" Target="GetLocalizedCredentials"/>
|
||||
<ROW Action="AI_SHOW_LOG" Type="65" Source="aicustact.dll" Target="LaunchLogFile" WithoutSeq="true"/>
|
||||
<ROW Action="AI_STORE_LOCATION" Type="51" Source="ARPINSTALLLOCATION" Target="[APPDIR]"/>
|
||||
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]"/>
|
||||
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
|
||||
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
||||
<ROW Name="zt1icon.exe" SourcePath="..\..\..\ZeroTierUI\zt1icon.ico" Index="0"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
|
||||
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/>
|
||||
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
||||
<ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1501"/>
|
||||
<ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE="No" AND (Not Installed)" Sequence="1399"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
|
||||
<ROW Action="AI_ResolveLocalizedCredentials" Sequence="51"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
||||
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Sequence="53"/>
|
||||
<ROW Action="AI_ResolveLocalizedCredentials" Sequence="52"/>
|
||||
<ROW Action="AI_DpiContentScale" Sequence="51"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent">
|
||||
<ROW Condition="( Version9X OR ( NOT VersionNT64 ) OR ( VersionNT64 AND ((VersionNT64 <> 502) OR (((VersionNT64 = 502) AND (ServicePackLevel >= 1)) OR (MsiNTProductType <> 1))) AND ((VersionNT64 <> 502) OR (((VersionNT64 = 502) AND (ServicePackLevel <> 1)) OR (MsiNTProductType <> 1))) AND ((VersionNT64 <> 502) OR (((VersionNT64 = 502) AND (ServicePackLevel <> 2)) OR (MsiNTProductType <> 1))) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT64Display]" DescriptionLocId="AI.LaunchCondition.NoSpecificNT64" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="( Version9X OR VersionNT64 OR ( VersionNT AND ((VersionNT <> 500) OR ((VersionNT = 500) AND (ServicePackLevel >= 1))) AND ((VersionNT <> 500) OR ((VersionNT = 500) AND (ServicePackLevel <> 1))) AND ((VersionNT <> 500) OR ((VersionNT = 500) AND (ServicePackLevel <> 2))) AND ((VersionNT <> 500) OR ((VersionNT = 500) AND (ServicePackLevel <> 3))) AND ((VersionNT <> 500) OR ((VersionNT = 500) AND (ServicePackLevel <> 4))) AND (((VersionNT <> 501) OR ((VersionNT = 501) AND (ServicePackLevel >= 1))) OR VersionNT64) AND (((VersionNT <> 501) OR ((VersionNT = 501) AND (ServicePackLevel <> 1))) OR VersionNT64) AND (((VersionNT <> 501) OR ((VersionNT = 501) AND (ServicePackLevel <> 2))) OR VersionNT64) AND (((VersionNT <> 501) OR ((VersionNT = 501) AND (ServicePackLevel <> 3))) OR VersionNT64) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNTDisplay]" DescriptionLocId="AI.LaunchCondition.NoSpecificNT" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 400)" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT40Display]" DescriptionLocId="AI.LaunchCondition.NoNT40" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="VersionNT" Description="[ProductName] cannot be installed on [WindowsType9XDisplay]" DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegsComponent">
|
||||
<ROW Registry="Path" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
|
||||
<ROW Registry="Version" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent">
|
||||
<ATTRIBUTE name="UsedTheme" value="classic"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiUpgradeComponent">
|
||||
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="0.0.1" VersionMax="[|ProductVersion]" Attributes="257" ActionProperty="OLDPRODUCTS"/>
|
||||
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="[|ProductVersion]" Attributes="2" ActionProperty="AI_NEWERPRODUCTFOUND"/>
|
||||
</COMPONENT>
|
||||
</DOCUMENT>
|
||||
@@ -42,6 +42,9 @@
|
||||
#include <tchar.h>
|
||||
#include <wchar.h>
|
||||
#include <lmcons.h>
|
||||
#include "windows/ZeroTierOne/ServiceInstaller.h"
|
||||
#include "windows/ZeroTierOne/ServiceBase.h"
|
||||
#include "windows/ZeroTierOne/ZeroTierOneService.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
@@ -93,6 +96,11 @@ static void printHelp(const char *cn,FILE *out)
|
||||
fprintf(out," -c<port> - Bind to this port for local control packets"ZT_EOL_S);
|
||||
fprintf(out," -q - Send a query to a running service (zerotier-cli)"ZT_EOL_S);
|
||||
fprintf(out," -i - Run idtool command (zerotier-idtool)"ZT_EOL_S);
|
||||
#ifdef __WINDOWS__
|
||||
fprintf(out," -C - Run from command line instead of as service (Windows)"ZT_EOL_S);
|
||||
fprintf(out," -I - Install Windows service (Windows)"ZT_EOL_S);
|
||||
fprintf(out," -R - Uninstall Windows service (Windows)"ZT_EOL_S);
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace ZeroTierCLI { // ---------------------------------------------------
|
||||
@@ -373,6 +381,7 @@ static void sighandlerQuit(int sig)
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
// Console signal handler routine to allow CTRL+C to work, mostly for testing
|
||||
static BOOL WINAPI _handlerRoutine(DWORD dwCtrlType)
|
||||
{
|
||||
switch(dwCtrlType) {
|
||||
@@ -388,183 +397,94 @@ static BOOL WINAPI _handlerRoutine(DWORD dwCtrlType)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Returns true if this is running as the local administrator
|
||||
static BOOL IsCurrentUserLocalAdministrator(void)
|
||||
{
|
||||
BOOL fReturn = FALSE;
|
||||
DWORD dwStatus;
|
||||
DWORD dwAccessMask;
|
||||
DWORD dwAccessDesired;
|
||||
DWORD dwACLSize;
|
||||
DWORD dwStructureSize = sizeof(PRIVILEGE_SET);
|
||||
PACL pACL = NULL;
|
||||
PSID psidAdmin = NULL;
|
||||
BOOL fReturn = FALSE;
|
||||
DWORD dwStatus;
|
||||
DWORD dwAccessMask;
|
||||
DWORD dwAccessDesired;
|
||||
DWORD dwACLSize;
|
||||
DWORD dwStructureSize = sizeof(PRIVILEGE_SET);
|
||||
PACL pACL = NULL;
|
||||
PSID psidAdmin = NULL;
|
||||
|
||||
HANDLE hToken = NULL;
|
||||
HANDLE hImpersonationToken = NULL;
|
||||
HANDLE hToken = NULL;
|
||||
HANDLE hImpersonationToken = NULL;
|
||||
|
||||
PRIVILEGE_SET ps;
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
PRIVILEGE_SET ps;
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
|
||||
PSECURITY_DESCRIPTOR psdAdmin = NULL;
|
||||
SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
|
||||
PSECURITY_DESCRIPTOR psdAdmin = NULL;
|
||||
SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
|
||||
|
||||
const DWORD ACCESS_READ = 1;
|
||||
const DWORD ACCESS_WRITE = 2;
|
||||
|
||||
/*
|
||||
Determine if the current thread is running as a user that is a member
|
||||
__try
|
||||
{
|
||||
if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY,TRUE,&hToken))
|
||||
{
|
||||
if (GetLastError() != ERROR_NO_TOKEN)
|
||||
__leave;
|
||||
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
|
||||
__leave;
|
||||
}
|
||||
if (!DuplicateToken (hToken, SecurityImpersonation,&hImpersonationToken))
|
||||
__leave;
|
||||
if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS,
|
||||
0, 0, 0, 0, 0, 0, &psidAdmin))
|
||||
__leave;
|
||||
psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
if (psdAdmin == NULL)
|
||||
__leave;
|
||||
if (!InitializeSecurityDescriptor(psdAdmin,SECURITY_DESCRIPTOR_REVISION))
|
||||
__leave;
|
||||
dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD);
|
||||
pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
|
||||
if (pACL == NULL)
|
||||
__leave;
|
||||
if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
|
||||
__leave;
|
||||
dwAccessMask= ACCESS_READ | ACCESS_WRITE;
|
||||
if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin))
|
||||
__leave;
|
||||
if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
|
||||
__leave;
|
||||
|
||||
of
|
||||
the local admins group. To do this, create a security descriptor
|
||||
SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
|
||||
SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);
|
||||
|
||||
that
|
||||
has a DACL which has an ACE that allows only local aministrators
|
||||
if (!IsValidSecurityDescriptor(psdAdmin))
|
||||
__leave;
|
||||
dwAccessDesired = ACCESS_READ;
|
||||
|
||||
access.
|
||||
Then, call AccessCheck with the current thread's token and the
|
||||
GenericMapping.GenericRead = ACCESS_READ;
|
||||
GenericMapping.GenericWrite = ACCESS_WRITE;
|
||||
GenericMapping.GenericExecute = 0;
|
||||
GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;
|
||||
|
||||
security
|
||||
descriptor. It will say whether the user could access an object if
|
||||
if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,
|
||||
&GenericMapping, &ps, &dwStructureSize, &dwStatus,
|
||||
&fReturn))
|
||||
{
|
||||
fReturn = FALSE;
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
__finally
|
||||
{
|
||||
// Clean up.
|
||||
if (pACL) LocalFree(pACL);
|
||||
if (psdAdmin) LocalFree(psdAdmin);
|
||||
if (psidAdmin) FreeSid(psidAdmin);
|
||||
if (hImpersonationToken) CloseHandle (hImpersonationToken);
|
||||
if (hToken) CloseHandle (hToken);
|
||||
}
|
||||
|
||||
it
|
||||
had that security descriptor. Note: you do not need to actually
|
||||
|
||||
create
|
||||
the object. Just checking access against the security descriptor
|
||||
|
||||
alone
|
||||
will be sufficient.
|
||||
*/
|
||||
const DWORD ACCESS_READ = 1;
|
||||
const DWORD ACCESS_WRITE = 2;
|
||||
|
||||
|
||||
__try
|
||||
{
|
||||
|
||||
/*
|
||||
AccessCheck() requires an impersonation token. We first get a
|
||||
|
||||
primary
|
||||
token and then create a duplicate impersonation token. The
|
||||
impersonation token is not actually assigned to the thread, but is
|
||||
used in the call to AccessCheck. Thus, this function itself never
|
||||
impersonates, but does use the identity of the thread. If the
|
||||
|
||||
thread
|
||||
was impersonating already, this function uses that impersonation
|
||||
|
||||
context.
|
||||
*/
|
||||
if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY,
|
||||
|
||||
TRUE, &hToken))
|
||||
{
|
||||
if (GetLastError() != ERROR_NO_TOKEN)
|
||||
__leave;
|
||||
|
||||
if (!OpenProcessToken(GetCurrentProcess(),
|
||||
|
||||
TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
|
||||
__leave;
|
||||
}
|
||||
|
||||
if (!DuplicateToken (hToken, SecurityImpersonation,
|
||||
|
||||
&hImpersonationToken))
|
||||
__leave;
|
||||
|
||||
|
||||
/*
|
||||
Create the binary representation of the well-known SID that
|
||||
represents the local administrators group. Then create the
|
||||
|
||||
security
|
||||
descriptor and DACL with an ACE that allows only local admins
|
||||
|
||||
access.
|
||||
After that, perform the access check. This will determine whether
|
||||
the current user is a local admin.
|
||||
*/
|
||||
if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS,
|
||||
0, 0, 0, 0, 0, 0, &psidAdmin))
|
||||
__leave;
|
||||
|
||||
psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
if (psdAdmin == NULL)
|
||||
__leave;
|
||||
|
||||
if (!InitializeSecurityDescriptor(psdAdmin,
|
||||
|
||||
SECURITY_DESCRIPTOR_REVISION))
|
||||
__leave;
|
||||
|
||||
// Compute size needed for the ACL.
|
||||
dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
|
||||
GetLengthSid(psidAdmin) - sizeof(DWORD);
|
||||
|
||||
pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
|
||||
if (pACL == NULL)
|
||||
__leave;
|
||||
|
||||
if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
|
||||
__leave;
|
||||
|
||||
dwAccessMask= ACCESS_READ | ACCESS_WRITE;
|
||||
|
||||
if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask,
|
||||
|
||||
psidAdmin))
|
||||
__leave;
|
||||
|
||||
if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
|
||||
__leave;
|
||||
|
||||
/*
|
||||
AccessCheck validates a security descriptor somewhat; set the
|
||||
|
||||
group
|
||||
and owner so that enough of the security descriptor is filled out
|
||||
|
||||
to
|
||||
make AccessCheck happy.
|
||||
*/
|
||||
SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
|
||||
SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);
|
||||
|
||||
if (!IsValidSecurityDescriptor(psdAdmin))
|
||||
__leave;
|
||||
|
||||
dwAccessDesired = ACCESS_READ;
|
||||
|
||||
/*
|
||||
Initialize GenericMapping structure even though you
|
||||
do not use generic rights.
|
||||
*/
|
||||
GenericMapping.GenericRead = ACCESS_READ;
|
||||
GenericMapping.GenericWrite = ACCESS_WRITE;
|
||||
GenericMapping.GenericExecute = 0;
|
||||
GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;
|
||||
|
||||
if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,
|
||||
&GenericMapping, &ps, &dwStructureSize, &dwStatus,
|
||||
&fReturn))
|
||||
{
|
||||
fReturn = FALSE;
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
__finally
|
||||
{
|
||||
// Clean up.
|
||||
if (pACL) LocalFree(pACL);
|
||||
if (psdAdmin) LocalFree(psdAdmin);
|
||||
if (psidAdmin) FreeSid(psidAdmin);
|
||||
if (hImpersonationToken) CloseHandle (hImpersonationToken);
|
||||
if (hToken) CloseHandle (hToken);
|
||||
}
|
||||
|
||||
return fReturn;
|
||||
return fReturn;
|
||||
}
|
||||
#endif // __WINDOWS__
|
||||
|
||||
@@ -599,6 +519,9 @@ int main(int argc,char **argv)
|
||||
const char *homeDir = (const char *)0;
|
||||
unsigned int port = 0;
|
||||
unsigned int controlPort = 0;
|
||||
#ifdef __WINDOWS__
|
||||
bool winRunFromCommandLine = false;
|
||||
#endif
|
||||
for(int i=1;i<argc;++i) {
|
||||
if (argv[i][0] == '-') {
|
||||
switch(argv[i][1]) {
|
||||
@@ -629,6 +552,35 @@ int main(int argc,char **argv)
|
||||
printHelp(argv[0],stderr);
|
||||
return 0;
|
||||
} else return ZeroTierIdTool::main(argc,argv);
|
||||
#ifdef __WINDOWS__
|
||||
case 'C':
|
||||
winRunFromCommandLine = true;
|
||||
break;
|
||||
case 'I': { // install self as service
|
||||
if (IsCurrentUserLocalAdministrator() != TRUE) {
|
||||
fprintf(stderr,"%s: must be run as a local administrator."ZT_EOL_S,argv[0]);
|
||||
return 1;
|
||||
}
|
||||
std::string ret(InstallService(ZT_SERVICE_NAME,ZT_SERVICE_DISPLAY_NAME,ZT_SERVICE_START_TYPE,ZT_SERVICE_DEPENDENCIES,ZT_SERVICE_ACCOUNT,ZT_SERVICE_PASSWORD));
|
||||
if (ret.length()) {
|
||||
fprintf(stderr,"%s: unable to install service: %s"ZT_EOL_S,argv[0],ret.c_str());
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
} break;
|
||||
case 'R': { // uninstall self as service
|
||||
if (IsCurrentUserLocalAdministrator() != TRUE) {
|
||||
fprintf(stderr,"%s: must be run as a local administrator."ZT_EOL_S,argv[0]);
|
||||
return 1;
|
||||
}
|
||||
std::string ret(UninstallService(ZT_SERVICE_NAME));
|
||||
if (ret.length()) {
|
||||
fprintf(stderr,"%s: unable to uninstall service: %s"ZT_EOL_S,argv[0],ret.c_str());
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
} break;
|
||||
#endif
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
@@ -672,52 +624,54 @@ int main(int argc,char **argv)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int exitCode = 0;
|
||||
|
||||
try {
|
||||
node = new Node(homeDir,port,controlPort);
|
||||
switch(node->run()) {
|
||||
case Node::NODE_RESTART_FOR_UPGRADE: {
|
||||
const char *upgPath = node->reasonForTermination();
|
||||
#ifdef __UNIX_LIKE__
|
||||
// On Unix-type OSes we exec() right into the upgrade. This in turn will
|
||||
// end with us being re-launched either via the upgrade itself or something
|
||||
// like OSX's launchd.
|
||||
if (upgPath) {
|
||||
Utils::rm((std::string(homeDir)+"/zerotier-one.pid").c_str());
|
||||
::execl(upgPath,upgPath,(char *)0);
|
||||
}
|
||||
exitCode = 2;
|
||||
fprintf(stderr,"%s: abnormal termination: unable to execute update at %s\n",argv[0],(upgPath) ? upgPath : "(unknown path)");
|
||||
#else // not __UNIX_LIKE
|
||||
#ifdef __WINDOWS__
|
||||
// On Windows the service checks updates.d and invokes updates if they are
|
||||
// found there. This only happens after exit code 4. The Windows service
|
||||
// will listen to stdout as well to catch the filename.
|
||||
if (upgPath) {
|
||||
printf("[[[ UPDATE AVAILABLE: \"%s\" ]]]\r\n",upgPath);
|
||||
exitCode = 4;
|
||||
} else {
|
||||
exitCode = 2;
|
||||
}
|
||||
#endif // __WINDOWS__
|
||||
#endif // not __UNIX_LIKE__
|
||||
} break;
|
||||
case Node::NODE_UNRECOVERABLE_ERROR: {
|
||||
exitCode = 3;
|
||||
const char *termReason = node->reasonForTermination();
|
||||
fprintf(stderr,"%s: abnormal termination: %s\n",argv[0],(termReason) ? termReason : "(unknown reason)");
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
if (!winRunFromCommandLine) {
|
||||
ZeroTierOneService zt1Service;
|
||||
if (CServiceBase::Run(zt1Service) == TRUE) {
|
||||
// Normal termination of service process
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr,"%s: unable to start service (try -h for help)"ZT_EOL_S,argv[0]);
|
||||
return 1;
|
||||
}
|
||||
delete node;
|
||||
node = (Node *)0;
|
||||
} catch ( ... ) {}
|
||||
|
||||
#ifdef __UNIX_LIKE__
|
||||
Utils::rm((std::string(homeDir)+"/zerotier-one.pid").c_str());
|
||||
} else
|
||||
#endif
|
||||
|
||||
return exitCode;
|
||||
{
|
||||
int exitCode = 0;
|
||||
try {
|
||||
node = new Node(homeDir,port,controlPort);
|
||||
switch(node->run()) {
|
||||
#ifndef __WINDOWS__
|
||||
case Node::NODE_RESTART_FOR_UPGRADE: {
|
||||
const char *upgPath = node->reasonForTermination();
|
||||
// On Unix-type OSes we exec() right into the upgrade. This in turn will
|
||||
// end with us being re-launched either via the upgrade itself or something
|
||||
// like OSX's launchd.
|
||||
if (upgPath) {
|
||||
Utils::rm((std::string(homeDir)+"/zerotier-one.pid").c_str());
|
||||
::execl(upgPath,upgPath,(char *)0);
|
||||
}
|
||||
exitCode = 3;
|
||||
fprintf(stderr,"%s: abnormal termination: unable to execute update at %s\n",argv[0],(upgPath) ? upgPath : "(unknown path)");
|
||||
} break;
|
||||
#endif
|
||||
case Node::NODE_UNRECOVERABLE_ERROR: {
|
||||
exitCode = 3;
|
||||
const char *termReason = node->reasonForTermination();
|
||||
fprintf(stderr,"%s: abnormal termination: %s\n",argv[0],(termReason) ? termReason : "(unknown reason)");
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
delete node;
|
||||
node = (Node *)0;
|
||||
} catch ( ... ) {
|
||||
fprintf(stderr,"%s: unexpected exception!"ZT_EOL_S,argv[0]);
|
||||
exitCode = 3;
|
||||
}
|
||||
#ifdef __UNIX_LIKE__
|
||||
Utils::rm((std::string(homeDir)+"/zerotier-one.pid").c_str());
|
||||
#endif
|
||||
return exitCode;
|
||||
}
|
||||
}
|
||||
+30
-28
@@ -277,7 +277,7 @@ int main(int argc,char **argv)
|
||||
std::string desc;
|
||||
{
|
||||
Query q = dbCon->query();
|
||||
q << "SELECT name,`desc`,isOpen,multicastPrefixBits,multicastDepth,emulateArp,emulateNdp,arpCacheTtl,ndpCacheTtl FROM Network WHERE id = " << nwid;
|
||||
q << "SELECT * FROM Network WHERE id = " << nwid;
|
||||
StoreQueryResult rs = q.store();
|
||||
if (rs.num_rows() > 0) {
|
||||
name = rs[0]["name"].c_str();
|
||||
@@ -411,36 +411,38 @@ int main(int argc,char **argv)
|
||||
uint32_t ipNet = (uint32_t)((unsigned long)rs[aaRow]["ipNet"]);
|
||||
unsigned int netmaskBits = (unsigned int)rs[aaRow]["netmaskBits"];
|
||||
|
||||
uint32_t tryIp = (((uint32_t)addressBytes[1]) << 24) |
|
||||
(((uint32_t)addressBytes[2]) << 16) |
|
||||
(((uint32_t)addressBytes[3]) << 8) |
|
||||
((((uint32_t)addressBytes[4]) % 254) + 1);
|
||||
tryIp &= (0xffffffff >> netmaskBits);
|
||||
tryIp |= ipNet;
|
||||
if ((netmaskBits > 0)&&(ipNet)) {
|
||||
uint32_t tryIp = (((uint32_t)addressBytes[1]) << 24) |
|
||||
(((uint32_t)addressBytes[2]) << 16) |
|
||||
(((uint32_t)addressBytes[3]) << 8) |
|
||||
((((uint32_t)addressBytes[4]) % 254) + 1);
|
||||
tryIp &= (0xffffffff >> netmaskBits);
|
||||
tryIp |= ipNet;
|
||||
|
||||
for(int k=0;k<100000;++k) {
|
||||
Query q2 = dbCon->query();
|
||||
q2 << "INSERT INTO IPv4Static (Network_id,Node_id,ip,netmaskBits) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << tryIp << "," << netmaskBits << ")";
|
||||
if (q2.exec()) {
|
||||
sprintf(buf,"%u.%u.%u.%u",(unsigned int)((tryIp >> 24) & 0xff),(unsigned int)((tryIp >> 16) & 0xff),(unsigned int)((tryIp >> 8) & 0xff),(unsigned int)(tryIp & 0xff));
|
||||
if (ipv4Static.length())
|
||||
ipv4Static.push_back(',');
|
||||
ipv4Static.append(buf);
|
||||
ipv4Static.push_back('/');
|
||||
sprintf(buf,"%u",netmaskBits);
|
||||
ipv4Static.append(buf);
|
||||
break;
|
||||
} else { // insert will fail if IP is in use due to uniqueness constraints in DB
|
||||
++tryIp;
|
||||
if ((tryIp & 0xff) == 0)
|
||||
tryIp |= 1;
|
||||
tryIp &= (0xffffffff >> netmaskBits);
|
||||
tryIp |= ipNet;
|
||||
for(int k=0;k<100000;++k) {
|
||||
Query q2 = dbCon->query();
|
||||
q2 << "INSERT INTO IPv4Static (Network_id,Node_id,ip,netmaskBits) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << tryIp << "," << netmaskBits << ")";
|
||||
if (q2.exec()) {
|
||||
sprintf(buf,"%u.%u.%u.%u",(unsigned int)((tryIp >> 24) & 0xff),(unsigned int)((tryIp >> 16) & 0xff),(unsigned int)((tryIp >> 8) & 0xff),(unsigned int)(tryIp & 0xff));
|
||||
if (ipv4Static.length())
|
||||
ipv4Static.push_back(',');
|
||||
ipv4Static.append(buf);
|
||||
ipv4Static.push_back('/');
|
||||
sprintf(buf,"%u",netmaskBits);
|
||||
ipv4Static.append(buf);
|
||||
break;
|
||||
} else { // insert will fail if IP is in use due to uniqueness constraints in DB
|
||||
++tryIp;
|
||||
if ((tryIp & 0xff) == 0)
|
||||
tryIp |= 1;
|
||||
tryIp &= (0xffffffff >> netmaskBits);
|
||||
tryIp |= ipNet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ipv4Static.length())
|
||||
break;
|
||||
if (ipv4Static.length())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,13 @@ static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap()
|
||||
addrs.push_back(InetAddress("198.211.127.172",ZT_DEFAULT_UDP_PORT));
|
||||
sn[id] = addrs;
|
||||
|
||||
// mi-go.zerotier.com - Singapore
|
||||
addrs.clear();
|
||||
if (!id.fromString("abbb7f4622:0:89d2c6b2062b10f4ce314dfcb914c082566247090a6f74c8ba1c15c63b205f540758f0abae85287397152c9d8cf463cfe51e7a480946cd6a31495b24ca13253c"))
|
||||
throw std::runtime_error("invalid identity in Defaults");
|
||||
addrs.push_back(InetAddress("128.199.254.204",ZT_DEFAULT_UDP_PORT));
|
||||
sn[id] = addrs;
|
||||
|
||||
return sn;
|
||||
}
|
||||
|
||||
|
||||
+35
-12
@@ -234,6 +234,7 @@ EthernetTap::EthernetTap(
|
||||
_fd(0)
|
||||
{
|
||||
char procpath[128];
|
||||
struct stat sbuf;
|
||||
Mutex::Lock _l(__tapCreateLock); // create only one tap at a time, globally
|
||||
|
||||
if (mtu > 4096)
|
||||
@@ -246,13 +247,19 @@ EthernetTap::EthernetTap(
|
||||
struct ifreq ifr;
|
||||
memset(&ifr,0,sizeof(ifr));
|
||||
|
||||
{ // pick an unused device name
|
||||
// Try to recall our last device name, or pick an unused one if that fails.
|
||||
bool recalledDevice = false;
|
||||
if ((tag)&&(tag[0])) {
|
||||
Utils::scopy(ifr.ifr_name,sizeof(ifr.ifr_name),tag);
|
||||
Utils::snprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
|
||||
recalledDevice = (stat(procpath,&sbuf) != 0);
|
||||
}
|
||||
if (!recalledDevice) {
|
||||
int devno = 0;
|
||||
struct stat sbuf;
|
||||
do {
|
||||
Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"zt%d",devno++);
|
||||
Utils::snprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
|
||||
} while (stat(procpath,&sbuf) == 0);
|
||||
} while (stat(procpath,&sbuf) == 0); // try zt#++ until we find one that does not exist
|
||||
}
|
||||
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
@@ -359,17 +366,33 @@ EthernetTap::EthernetTap(
|
||||
if (stat("/dev/zt0",&stattmp))
|
||||
throw std::runtime_error("/dev/zt# tap devices do not exist and unable to load kernel extension");
|
||||
|
||||
// Open the first available device (ones in use will fail with resource busy)
|
||||
for(int i=0;i<256;++i) {
|
||||
Utils::snprintf(devpath,sizeof(devpath),"/dev/zt%d",i);
|
||||
if (stat(devpath,&stattmp))
|
||||
throw std::runtime_error("no more TAP devices available");
|
||||
_fd = ::open(devpath,O_RDWR);
|
||||
if (_fd > 0) {
|
||||
Utils::snprintf(_dev,sizeof(_dev),"zt%d",i);
|
||||
break;
|
||||
// Try to reopen the last device we had, if we had one and it's still unused.
|
||||
bool recalledDevice = false;
|
||||
if ((tag)&&(tag[0])) {
|
||||
Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",tag);
|
||||
if (stat(devpath,&stattmp) == 0) {
|
||||
_fd = ::open(devpath,O_RDWR);
|
||||
if (_fd > 0) {
|
||||
Utils::scopy(_dev,sizeof(_dev),tag);
|
||||
recalledDevice = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Open the first unused tap device if we didn't recall a previous one.
|
||||
if (!recalledDevice) {
|
||||
for(int i=0;i<256;++i) {
|
||||
Utils::snprintf(devpath,sizeof(devpath),"/dev/zt%d",i);
|
||||
if (stat(devpath,&stattmp))
|
||||
throw std::runtime_error("no more TAP devices available");
|
||||
_fd = ::open(devpath,O_RDWR);
|
||||
if (_fd > 0) {
|
||||
Utils::snprintf(_dev,sizeof(_dev),"zt%d",i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_fd <= 0)
|
||||
throw std::runtime_error("unable to open TAP device or no more devices available");
|
||||
|
||||
|
||||
+24
-4
@@ -75,7 +75,7 @@ Network::~Network()
|
||||
}
|
||||
}
|
||||
|
||||
SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t id)
|
||||
SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,NodeConfig *nc,uint64_t id)
|
||||
{
|
||||
/* We construct Network via a static method to ensure that it is immediately
|
||||
* wrapped in a SharedPtr<>. Otherwise if there is traffic on the Ethernet
|
||||
@@ -85,6 +85,7 @@ SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t
|
||||
|
||||
SharedPtr<Network> nw(new Network());
|
||||
nw->_id = id;
|
||||
nw->_nc = nc;
|
||||
nw->_mac = renv->identity.address().toMAC();
|
||||
nw->_r = renv;
|
||||
nw->_tap = (EthernetTap *)0;
|
||||
@@ -269,12 +270,31 @@ void Network::_pushMembershipCertificate(const Address &peer,bool force,uint64_t
|
||||
void Network::threadMain()
|
||||
throw()
|
||||
{
|
||||
// Setup thread -- this exits when tap is constructed. It's here
|
||||
// because opening the tap can take some time on some platforms.
|
||||
|
||||
try {
|
||||
// Setup thread -- this exits when tap is constructed. It's here
|
||||
// because opening the tap can take some time on some platforms.
|
||||
char tag[32];
|
||||
#ifdef __WINDOWS__
|
||||
// Windows tags interfaces by their network IDs, which are shoved into the
|
||||
// registry to mark persistent instance of the tap device.
|
||||
char tag[24];
|
||||
Utils::snprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)_id);
|
||||
#else
|
||||
// Unix tries to get the same device name next time, if possible.
|
||||
std::string tagstr;
|
||||
char lcentry[128];
|
||||
Utils::snprintf(lcentry,sizeof(lcentry),"_dev_for_%.16llx",(unsigned long long)_id);
|
||||
tagstr = _nc->getLocalConfig(lcentry);
|
||||
const char *tag = (tagstr.length() > 0) ? tagstr.c_str() : (const char *)0;
|
||||
#endif
|
||||
|
||||
_tap = new EthernetTap(_r,tag,_mac,ZT_IF_MTU,&_CBhandleTapData,this);
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
std::string dn(_tap->deviceName());
|
||||
if ((!tag)||(dn != tag))
|
||||
_nc->putLocalConfig(lcentry,dn);
|
||||
#endif
|
||||
} catch (std::exception &exc) {
|
||||
LOG("network %.16llx failed to initialize: %s",_id,exc.what());
|
||||
_netconfFailure = NETCONF_FAILURE_INIT_FAILED;
|
||||
|
||||
+4
-3
@@ -82,8 +82,7 @@ private:
|
||||
// Only NodeConfig can create, only SharedPtr can delete
|
||||
|
||||
// Actual construction happens in newInstance()
|
||||
Network() throw() : _tap((EthernetTap *)0) {}
|
||||
|
||||
Network() throw() {}
|
||||
~Network();
|
||||
|
||||
/**
|
||||
@@ -96,11 +95,12 @@ private:
|
||||
* cough).
|
||||
*
|
||||
* @param renv Runtime environment
|
||||
* @param nc Parent NodeConfig
|
||||
* @param id Network ID
|
||||
* @return Reference counted pointer to new network
|
||||
* @throws std::runtime_error Unable to create tap device or other fatal error
|
||||
*/
|
||||
static SharedPtr<Network> newInstance(const RuntimeEnvironment *renv,uint64_t id);
|
||||
static SharedPtr<Network> newInstance(const RuntimeEnvironment *renv,NodeConfig *nc,uint64_t id);
|
||||
|
||||
/**
|
||||
* Causes all persistent disk presence to be erased on delete
|
||||
@@ -406,6 +406,7 @@ private:
|
||||
void _dumpMulticastCerts();
|
||||
|
||||
uint64_t _id;
|
||||
NodeConfig *_nc;
|
||||
MAC _mac;
|
||||
const RuntimeEnvironment *_r;
|
||||
EthernetTap *volatile _tap;
|
||||
|
||||
@@ -461,6 +461,7 @@ Node::ReasonForTermination Node::run()
|
||||
#ifdef ZT_AUTO_UPDATE
|
||||
if (ZT_DEFAULTS.updateLatestNfoURL.length()) {
|
||||
_r->updater = new SoftwareUpdater(_r);
|
||||
_r->updater->cleanOldUpdates(); // clean out updates.d on startup
|
||||
} else {
|
||||
LOG("WARNING: unable to enable software updates: latest .nfo URL from ZT_DEFAULTS is empty (does this platform actually support software updates?)");
|
||||
}
|
||||
|
||||
Loaded 20 of 45 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user