summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2014-01-15 17:00:53 -0800
committerAdam Ierymenko <adam.ierymenko@gmail.com>2014-01-15 17:00:53 -0800
commit99c384e110f34d780ba78a76de95616a6801fcfa (patch)
treeafde6e50a00975c94947f6b48f609ddae461730c
parent49076d406e2941016c8b0ccc1d30abbcd49e486c (diff)
downloadinfinitytier-99c384e110f34d780ba78a76de95616a6801fcfa.tar.gz
infinitytier-99c384e110f34d780ba78a76de95616a6801fcfa.zip
New way of doing authenticate and install. Now with more kittens.
-rw-r--r--ZeroTierUI/ZeroTierUI.pro12
-rw-r--r--ZeroTierUI/installdialog.cpp83
-rw-r--r--ZeroTierUI/mac_doprivileged.h12
-rw-r--r--ZeroTierUI/mac_doprivileged.mm24
-rw-r--r--ZeroTierUI/mainwindow.cpp44
5 files changed, 136 insertions, 39 deletions
diff --git a/ZeroTierUI/ZeroTierUI.pro b/ZeroTierUI/ZeroTierUI.pro
index 6473fdb6..37857b3b 100644
--- a/ZeroTierUI/ZeroTierUI.pro
+++ b/ZeroTierUI/ZeroTierUI.pro
@@ -3,9 +3,11 @@ TARGET = "ZeroTier One"
TEMPLATE = app
win32:RC_FILE = ZeroTierUI.rc
+
mac:ICON = zt1icon.icns
mac:QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
mac:QMAKE_INFO_PLIST = Info.plist
+mac:LIBS += -framework Cocoa
SOURCES += main.cpp\
mainwindow.cpp \
@@ -40,7 +42,7 @@ SOURCES += main.cpp\
../ext/lz4/lz4.c \
../ext/lz4/lz4hc.c \
networkwidget.cpp \
- installdialog.cpp
+ installdialog.cpp
HEADERS += mainwindow.h \
aboutwindow.h \
@@ -90,12 +92,16 @@ HEADERS += mainwindow.h \
../ext/lz4/lz4.h \
../ext/lz4/lz4hc.h \
networkwidget.h \
- installdialog.h
+ installdialog.h \
+ mac_doprivileged.h
FORMS += mainwindow.ui \
aboutwindow.ui \
networkwidget.ui \
- installdialog.ui
+ installdialog.ui
RESOURCES += \
resources.qrc
+
+mac:OBJECTIVE_SOURCES += \
+ mac_doprivileged.mm
diff --git a/ZeroTierUI/installdialog.cpp b/ZeroTierUI/installdialog.cpp
index 66dd53dc..14ad5b6a 100644
--- a/ZeroTierUI/installdialog.cpp
+++ b/ZeroTierUI/installdialog.cpp
@@ -38,9 +38,14 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <fcntl.h>
#endif
+#ifdef __APPLE__
+#include "mac_doprivileged.h"
+#endif
+
#include <QMainWindow>
#include <QMessageBox>
#include <QByteArray>
@@ -103,45 +108,61 @@ void InstallDialog::on_networkReply(QNetworkReply *reply)
} break;
case FETCHING_INSTALLER: {
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);
return;
}
#ifdef __APPLE__
- QString zt1Caches(QDir::homePath() + "/Library/Caches/ZeroTier/One");
- QDir::root().mkpath(zt1Caches);
- QString instPath(zt1Caches+"/ZeroTierOneInstaller");
-
- 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;
- }
- 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);
+ {
+ std::string homePath(QDir::homePath().toStdString());
+ 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());
- 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
} break;
}
diff --git a/ZeroTierUI/mac_doprivileged.h b/ZeroTierUI/mac_doprivileged.h
new file mode 100644
index 00000000..52fba922
--- /dev/null
+++ b/ZeroTierUI/mac_doprivileged.h
@@ -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
diff --git a/ZeroTierUI/mac_doprivileged.mm b/ZeroTierUI/mac_doprivileged.mm
new file mode 100644
index 00000000..5bd6a7a6
--- /dev/null
+++ b/ZeroTierUI/mac_doprivileged.mm
@@ -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);
+}
diff --git a/ZeroTierUI/mainwindow.cpp b/ZeroTierUI/mainwindow.cpp
index 3fd37586..4bbee8c9 100644
--- a/ZeroTierUI/mainwindow.cpp
+++ b/ZeroTierUI/mainwindow.cpp
@@ -51,6 +51,15 @@
#include <QScrollBar>
#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;
// Globally visible
@@ -121,15 +130,39 @@ void MainWindow::timerEvent(QTimerEvent *event)
if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
#ifdef __APPLE__
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);
- QString authHelperPath(QCoreApplication::applicationDirPath() + "/../Resources/helpers/mac/ZeroTier One (Authenticate).app/Contents/MacOS/applet");
- if (!QFile::exists(authHelperPath)) {
- QMessageBox::critical(this,"Unable to Locate Helper","Unable to locate authorization helper, cannot obtain authentication token.",QMessageBox::Ok,QMessageBox::NoButton);
+ // Authorize user by copying auth token into local home directory
+ 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);
+
+ 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);
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 {
+ // Install service and other support files if service isn't there
doInstallDialog();
return;
}
@@ -268,6 +301,7 @@ void MainWindow::customEvent(QEvent *event)
void MainWindow::showEvent(QShowEvent *event)
{
#ifdef __APPLE__
+ // If service isn't installed, download and install it
if (!QFile::exists("/Library/Application Support/ZeroTier/One/zerotier-one"))
doInstallDialog();
#endif