mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 03:53:44 +02:00
New way of doing authenticate and install. Now with more kittens.
This commit is contained in:
parent
49076d406e
commit
99c384e110
5 changed files with 136 additions and 39 deletions
|
@ -3,9 +3,11 @@ TARGET = "ZeroTier One"
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|
||||||
win32:RC_FILE = ZeroTierUI.rc
|
win32:RC_FILE = ZeroTierUI.rc
|
||||||
|
|
||||||
mac:ICON = zt1icon.icns
|
mac:ICON = zt1icon.icns
|
||||||
mac:QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
|
mac:QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
|
||||||
mac:QMAKE_INFO_PLIST = Info.plist
|
mac:QMAKE_INFO_PLIST = Info.plist
|
||||||
|
mac:LIBS += -framework Cocoa
|
||||||
|
|
||||||
SOURCES += main.cpp\
|
SOURCES += main.cpp\
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
|
@ -40,7 +42,7 @@ SOURCES += main.cpp\
|
||||||
../ext/lz4/lz4.c \
|
../ext/lz4/lz4.c \
|
||||||
../ext/lz4/lz4hc.c \
|
../ext/lz4/lz4hc.c \
|
||||||
networkwidget.cpp \
|
networkwidget.cpp \
|
||||||
installdialog.cpp
|
installdialog.cpp
|
||||||
|
|
||||||
HEADERS += mainwindow.h \
|
HEADERS += mainwindow.h \
|
||||||
aboutwindow.h \
|
aboutwindow.h \
|
||||||
|
@ -90,12 +92,16 @@ HEADERS += mainwindow.h \
|
||||||
../ext/lz4/lz4.h \
|
../ext/lz4/lz4.h \
|
||||||
../ext/lz4/lz4hc.h \
|
../ext/lz4/lz4hc.h \
|
||||||
networkwidget.h \
|
networkwidget.h \
|
||||||
installdialog.h
|
installdialog.h \
|
||||||
|
mac_doprivileged.h
|
||||||
|
|
||||||
FORMS += mainwindow.ui \
|
FORMS += mainwindow.ui \
|
||||||
aboutwindow.ui \
|
aboutwindow.ui \
|
||||||
networkwidget.ui \
|
networkwidget.ui \
|
||||||
installdialog.ui
|
installdialog.ui
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources.qrc
|
resources.qrc
|
||||||
|
|
||||||
|
mac:OBJECTIVE_SOURCES += \
|
||||||
|
mac_doprivileged.mm
|
||||||
|
|
|
@ -38,9 +38,14 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include "mac_doprivileged.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
@ -103,45 +108,61 @@ void InstallDialog::on_networkReply(QNetworkReply *reply)
|
||||||
} break;
|
} break;
|
||||||
case FETCHING_INSTALLER: {
|
case FETCHING_INSTALLER: {
|
||||||
if (!ZeroTier::SoftwareUpdater::validateUpdate(installerData.data(),installerData.length(),signedBy,signature)) {
|
if (!ZeroTier::SoftwareUpdater::validateUpdate(installerData.data(),installerData.length(),signedBy,signature)) {
|
||||||
QMessageBox::critical(this,"Download Failed","Download failed: there is a problem with the software update web site.\nTry agian later. (failed signature check)",QMessageBox::Ok,QMessageBox::NoButton);
|
QMessageBox::critical(this,"Download Failed","Download failed: there is a problem with the software update web site. Try agian later. (downloaded data failed signature check)",QMessageBox::Ok,QMessageBox::NoButton);
|
||||||
QApplication::exit(1);
|
QApplication::exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
QString zt1Caches(QDir::homePath() + "/Library/Caches/ZeroTier/One");
|
{
|
||||||
QDir::root().mkpath(zt1Caches);
|
std::string homePath(QDir::homePath().toStdString());
|
||||||
QString instPath(zt1Caches+"/ZeroTierOneInstaller");
|
QString zt1Caches(QDir::homePath() + "/Library/Caches/ZeroTier/One");
|
||||||
|
QDir::root().mkpath(zt1Caches);
|
||||||
|
std::string instPath((zt1Caches + "/ZeroTierOneInstaller").toStdString());
|
||||||
|
std::string tmpPath((zt1Caches + "/inst.sh").toStdString());
|
||||||
|
|
||||||
|
int outfd = ::open(instPath.c_str(),O_CREAT|O_TRUNC|O_WRONLY,0755);
|
||||||
|
if (outfd <= 0) {
|
||||||
|
QMessageBox::critical(this,"Download Failed",QString("Installation failed: unable to write to ")+instPath.c_str(),QMessageBox::Ok,QMessageBox::NoButton);
|
||||||
|
QApplication::exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (::write(outfd,installerData.data(),installerData.length()) != installerData.length()) {
|
||||||
|
QMessageBox::critical(this,"Installation Failed",QString("Installation failed: unable to write to ")+instPath.c_str(),QMessageBox::Ok,QMessageBox::NoButton);
|
||||||
|
QApplication::exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
::close(outfd);
|
||||||
|
chmod(instPath.c_str(),0755);
|
||||||
|
|
||||||
|
FILE *scr = fopen(tmpPath.c_str(),"w");
|
||||||
|
if (!scr) {
|
||||||
|
QMessageBox::critical(this,"Installation Failed","Cannot write script to temporary Library/Caches/ZeroTier/One folder.",QMessageBox::Ok,QMessageBox::NoButton);
|
||||||
|
QApplication::exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(scr,"#!/bin/bash\n");
|
||||||
|
fprintf(scr,"export PATH=\"/bin:/usr/bin:/sbin:/usr/sbin\"\n");
|
||||||
|
fprintf(scr,"'%s'\n",instPath.c_str());
|
||||||
|
fprintf(scr,"if [ -f '/Library/Application Support/ZeroTier/One/authtoken.secret' ]; then\n");
|
||||||
|
fprintf(scr," cp -f '/Library/Application Support/ZeroTier/One/authtoken.secret' '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
|
||||||
|
fprintf(scr," chown %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getuid(),homePath.c_str());
|
||||||
|
fprintf(scr," chgrp %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getgid(),homePath.c_str());
|
||||||
|
fprintf(scr," chmod 0600 '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
|
||||||
|
fprintf(scr,"fi\n");
|
||||||
|
fprintf(scr,"exit 0\n");
|
||||||
|
|
||||||
|
fclose(scr);
|
||||||
|
chmod(tmpPath.c_str(),0755);
|
||||||
|
|
||||||
|
macExecutePrivilegedShellCommand((std::string("'")+tmpPath+"' >>/dev/null 2>&1").c_str());
|
||||||
|
|
||||||
|
unlink(tmpPath.c_str());
|
||||||
|
unlink(instPath.c_str());
|
||||||
|
|
||||||
int outfd = ::open(instPath.toStdString().c_str(),O_CREAT|O_TRUNC|O_WRONLY,0755);
|
|
||||||
if (outfd <= 0) {
|
|
||||||
QMessageBox::critical(this,"Download Failed",QString("Installation failed: unable to write to ")+instPath,QMessageBox::Ok,QMessageBox::NoButton);
|
|
||||||
QApplication::exit(1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (::write(outfd,installerData.data(),installerData.length()) != installerData.length()) {
|
|
||||||
QMessageBox::critical(this,"Installation Failed",QString("Installation failed: unable to write to ")+instPath,QMessageBox::Ok,QMessageBox::NoButton);
|
|
||||||
QApplication::exit(1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
::close(outfd);
|
|
||||||
::chmod(instPath.toStdString().c_str(),0755);
|
|
||||||
|
|
||||||
QString installHelperPath(QCoreApplication::applicationDirPath() + "/../Resources/helpers/mac/ZeroTier One (Install).app/Contents/MacOS/applet");
|
|
||||||
if (!QFile::exists(installHelperPath)) {
|
|
||||||
QMessageBox::critical(this,"Unable to Locate Helper","Unable to locate install helper, cannot install service.",QMessageBox::Ok,QMessageBox::NoButton);
|
|
||||||
QApplication::exit(1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terminate the GUI and execute the install helper instead
|
|
||||||
::execl(installHelperPath.toStdString().c_str(),installHelperPath.toStdString().c_str(),(const char *)0);
|
|
||||||
|
|
||||||
// We only make it here if execl() failed
|
|
||||||
QMessageBox::critical(this,"Unable to Locate Helper","Unable to locate install helper, cannot install service.",QMessageBox::Ok,QMessageBox::NoButton);
|
|
||||||
QApplication::exit(1);
|
|
||||||
|
|
||||||
return;
|
|
||||||
#endif
|
#endif
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
12
ZeroTierUI/mac_doprivileged.h
Normal file
12
ZeroTierUI/mac_doprivileged.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef mac_doprivileged_h
|
||||||
|
#define mac_doprivileged_h
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
// commandAndArgs can contain only single-tic quotes and should redirect its
|
||||||
|
// stdout and stderr somewhere...
|
||||||
|
bool macExecutePrivilegedShellCommand(const char *commandAndArgs);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
24
ZeroTierUI/mac_doprivileged.mm
Normal file
24
ZeroTierUI/mac_doprivileged.mm
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "mac_doprivileged.h"
|
||||||
|
|
||||||
|
#undef slots
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
bool macExecutePrivilegedShellCommand(const char *commandAndArgs)
|
||||||
|
{
|
||||||
|
char tmp[32768];
|
||||||
|
|
||||||
|
snprintf(tmp,sizeof(tmp),"do shell script \"%s\" with administrator privileges\n",commandAndArgs);
|
||||||
|
tmp[32767] = (char)0;
|
||||||
|
|
||||||
|
NSString *scriptApple = [[NSString alloc] initWithUTF8String:tmp];
|
||||||
|
NSAppleScript *as = [[NSAppleScript alloc] initWithSource:scriptApple];
|
||||||
|
NSDictionary *err = nil;
|
||||||
|
[as executeAndReturnError:&err];
|
||||||
|
[as release];
|
||||||
|
[scriptApple release];
|
||||||
|
|
||||||
|
return (err == nil);
|
||||||
|
}
|
|
@ -51,6 +51,15 @@
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "mac_doprivileged.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
QNetworkAccessManager *nam;
|
QNetworkAccessManager *nam;
|
||||||
|
|
||||||
// Globally visible
|
// Globally visible
|
||||||
|
@ -121,15 +130,39 @@ void MainWindow::timerEvent(QTimerEvent *event)
|
||||||
if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
|
if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (QFile::exists("/Library/Application Support/ZeroTier/One/zerotier-one")) {
|
if (QFile::exists("/Library/Application Support/ZeroTier/One/zerotier-one")) {
|
||||||
QMessageBox::information(this,"Authorization Required","You must authenticate to authorize this user to administrate ZeroTier One on this computer.\n\n(This only needs to be done once.)",QMessageBox::Ok,QMessageBox::NoButton);
|
// Authorize user by copying auth token into local home directory
|
||||||
QString authHelperPath(QCoreApplication::applicationDirPath() + "/../Resources/helpers/mac/ZeroTier One (Authenticate).app/Contents/MacOS/applet");
|
QMessageBox::information(this,"Authorization Needed","Administrator privileges are required to allow the current user to control ZeroTier One on this computer. (You only have to do this once.)",QMessageBox::Ok,QMessageBox::NoButton);
|
||||||
if (!QFile::exists(authHelperPath)) {
|
|
||||||
QMessageBox::critical(this,"Unable to Locate Helper","Unable to locate authorization helper, cannot obtain authentication token.",QMessageBox::Ok,QMessageBox::NoButton);
|
std::string homePath(QDir::homePath().toStdString());
|
||||||
|
QString zt1Caches(QDir::homePath() + "/Library/Caches/ZeroTier/One");
|
||||||
|
QDir::root().mkpath(zt1Caches);
|
||||||
|
std::string tmpPath((zt1Caches + "/auth.sh").toStdString());
|
||||||
|
|
||||||
|
FILE *scr = fopen(tmpPath.c_str(),"w");
|
||||||
|
if (!scr) {
|
||||||
|
QMessageBox::critical(this,"Cannot Authorize","Unable to authorize this user to administrate ZeroTier One. (Cannot write to temporary Library/Caches/ZeroTier/One folder.)",QMessageBox::Ok,QMessageBox::NoButton);
|
||||||
QApplication::exit(1);
|
QApplication::exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QProcess::execute(authHelperPath,QStringList());
|
|
||||||
|
fprintf(scr,"#!/bin/bash\n");
|
||||||
|
fprintf(scr,"export PATH=\"/bin:/usr/bin:/sbin:/usr/sbin\"\n");
|
||||||
|
fprintf(scr,"if [ -f '/Library/Application Support/ZeroTier/One/authtoken.secret' ]; then\n");
|
||||||
|
fprintf(scr," cp -f '/Library/Application Support/ZeroTier/One/authtoken.secret' '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
|
||||||
|
fprintf(scr," chown %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getuid(),homePath.c_str());
|
||||||
|
fprintf(scr," chgrp %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getgid(),homePath.c_str());
|
||||||
|
fprintf(scr," chmod 0600 '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
|
||||||
|
fprintf(scr,"fi\n");
|
||||||
|
fprintf(scr,"exit 0\n");
|
||||||
|
|
||||||
|
fclose(scr);
|
||||||
|
chmod(tmpPath.c_str(),0755);
|
||||||
|
|
||||||
|
macExecutePrivilegedShellCommand((std::string("'")+tmpPath+"' >>/dev/null 2>&1").c_str());
|
||||||
|
|
||||||
|
unlink(tmpPath.c_str());
|
||||||
} else {
|
} else {
|
||||||
|
// Install service and other support files if service isn't there
|
||||||
doInstallDialog();
|
doInstallDialog();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -268,6 +301,7 @@ void MainWindow::customEvent(QEvent *event)
|
||||||
void MainWindow::showEvent(QShowEvent *event)
|
void MainWindow::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
// If service isn't installed, download and install it
|
||||||
if (!QFile::exists("/Library/Application Support/ZeroTier/One/zerotier-one"))
|
if (!QFile::exists("/Library/Application Support/ZeroTier/One/zerotier-one"))
|
||||||
doInstallDialog();
|
doInstallDialog();
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue