native windows http get for premium auth

This commit is contained in:
Nick Bolton 2014-02-04 19:41:29 +00:00
parent b0a02fc94b
commit 7f08036ff3
21 changed files with 606 additions and 43 deletions

View File

@ -276,7 +276,7 @@ if (UNIX)
else (UNIX)
list(APPEND libs Wtsapi32 Userenv)
list(APPEND libs Wtsapi32 Userenv Wininet)
add_definitions(
/DWIN32

View File

@ -18,6 +18,7 @@ add_subdirectory(synergyc)
add_subdirectory(synergys)
add_subdirectory(synergyd)
add_subdirectory(usynergy)
add_subdirectory(syntool)
if (WIN32)
add_subdirectory(synergyp)

View File

@ -0,0 +1,50 @@
# synergy -- mouse and keyboard sharing utility
# Copyright (C) 2014 Bolton Software Ltd.
#
# This package is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# found in the file COPYING that should have accompanied this file.
#
# This package is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(src
syntool.cpp
)
set(inc
../../lib/arch
../../lib/base
../../lib/common
../../lib/io
../../lib/ipc
../../lib/mt
../../lib/net
../../lib/platform
../../lib/synergy
../../lib/synwinhk
../../lib/synwinxt
)
if (UNIX)
list(APPEND inc
../../..
)
endif()
include_directories(${inc})
add_executable(syntool ${src})
target_link_libraries(syntool
arch base client common io mt net ipc platform synergy cryptopp ${libs})
if (CONF_CPACK)
install(TARGETS
syntool
COMPONENT core
DESTINATION bin)
endif()

View File

@ -0,0 +1,34 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CToolApp.h"
#include "CArch.h"
int
main(int argc, char** argv)
{
#if SYSAPI_WIN32
// record window instance for tray icon, etc
CArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
#endif
CArch arch;
arch.init();
CToolApp app;
return app.run(argc, argv);
}

View File

@ -40,7 +40,8 @@ SOURCES += src/main.cpp \
src/IpcReader.cpp \
src/Ipc.cpp \
src/SynergyLocale.cpp \
src/QUtility.cpp
src/QUtility.cpp \
src/PremiumAuth.cpp
HEADERS += src/MainWindow.h \
src/AboutDialog.h \
src/ServerConfig.h \
@ -67,7 +68,8 @@ HEADERS += src/MainWindow.h \
src/IpcReader.h \
src/Ipc.h \
src/SynergyLocale.h \
src/QUtility.h
src/QUtility.h \
src/PremiumAuth.h
RESOURCES += res/Synergy.qrc
RC_FILE = res/win/Synergy.rc
macx {

View File

@ -0,0 +1,48 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "PremiumAuth.h"
#include "QUtility.h"
#include <QProcess>
#include <QCoreApplication>
// we use syntool to authenticate because Qt's http library is very
// unreliable, and since we're writing platform specific code, use the
// synergy code since there we can use integ tests.
QString PremiumAuth::auth(const QString& email, const QString& password)
{
QString program(QCoreApplication::applicationDirPath() + "/syntool");
QStringList args("--premium-auth");
QProcess process;
process.setReadChannel(QProcess::StandardOutput);
process.start(program, args);
if (process.waitForStarted())
{
// hash password in case it contains interesting chars.
QString credentials(email + ":" + hash(password) + "\n");
process.write(credentials.toStdString().c_str());
if (process.waitForFinished()) {
return process.readLine();
}
}
return "";
}

26
src/gui/src/PremiumAuth.h Normal file
View File

@ -0,0 +1,26 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QString>
class PremiumAuth
{
public:
QString auth(const QString& email, const QString& password);
};

View File

@ -19,6 +19,7 @@
#include "MainWindow.h"
#include "QSynergyApplication.h"
#include "QUtility.h"
#include "PremiumAuth.h"
#include <QMessageBox>
#include <QDesktopServices>
@ -26,8 +27,6 @@
#include <QNetworkRequest>
#include <QNetworkReply>
//#define PREMIUM_AUTH_URL "http://localhost/synergy/premium/json/auth/"
#define PREMIUM_AUTH_URL "http://synergy-foss.org/premium/json/auth/"
#define PREMIUM_REGISTER_URL "http://synergy-foss.org/donate/?source=gui-wizard"
SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) :
@ -250,39 +249,11 @@ void SetupWizard::on_m_pRadioButtonPremiumLogin_toggled(bool checked)
bool SetupWizard::isPremiumLoginValid(QMessageBox& message)
{
// hash the email and password and send it over plain-text,
// it would be nice to use SSL, but unfortunately the Qt
// implementation is unreliable.
QString email = hash(m_pLineEditPremiumEmail->text());
QString password = hash(m_pLineEditPremiumPassword->text());
QString email = m_pLineEditPremiumEmail->text();
QString password = m_pLineEditPremiumPassword->text();
QString requestJson = "{\"email\":\"" + email + "\",\"password\":\"" + password + "\"}";
QByteArray requestData(requestJson.toStdString().c_str());
QString version = m_MainWindow.versionChecker().getVersion();
QString userAgent = "Synergy GUI " + version;
QByteArray userAgentData(userAgent.toStdString().c_str());
QNetworkRequest request(QUrl(PREMIUM_AUTH_URL));
request.setRawHeader("User-Agent", userAgentData);
QUrl params;
params.addEncodedQueryItem("json", requestData);
QNetworkReply* reply = m_Network.post(request, params.encodedQuery());
// use loop instead of waitForReadyRead (which doesnt seem to work).
QEventLoop loop;
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
if (reply->error() != QNetworkReply::NoError) {
message.setText(tr("Login failed, an error occurred.\n\nError: %1").arg(reply->errorString()));
message.exec();
return false;
}
QByteArray responseData = reply->readAll();
QString responseJson(responseData);
PremiumAuth auth;
QString responseJson = auth.auth(email, password);
// this feels like a lot of work, but its cheaper than getting a json
// parsing library involved.

View File

@ -46,7 +46,6 @@ private:
MainWindow& m_MainWindow;
bool m_StartMain;
SynergyLocale m_Locale;
QNetworkAccessManager m_Network;
private slots:
void on_m_pCheckBoxEnableCrypto_stateChanged(int );

View File

@ -52,6 +52,7 @@
# include "CArchTaskBarWindows.h"
# include "CArchTimeWindows.h"
# include "CArchPluginWindows.h"
# include "CArchInternetWindows.h"
#elif SYSAPI_UNIX
# include "CArchConsoleUnix.h"
# include "CArchDaemonUnix.h"
@ -67,6 +68,7 @@
# include "CArchTaskBarXWindows.h"
# include "CArchTimeUnix.h"
# include "CArchPluginUnix.h"
# include "CArchInternetUnix.h"
#endif
/*!
@ -119,10 +121,12 @@ public:
static CArch* getInstance();
ARCH_PLUGIN& plugin() const { return (ARCH_PLUGIN&)m_plugin; }
ARCH_INTERNET& internet() const { return (ARCH_INTERNET&)m_internet; }
private:
static CArch* s_instance;
ARCH_PLUGIN m_plugin;
ARCH_INTERNET m_internet;
};
//! Convenience object to lock/unlock an arch mutex

View File

@ -0,0 +1,24 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CArchInternetUnix.h"
CString
CArchInternetUnix::get(const CString& url)
{
return "Not implemented";
}

View File

@ -0,0 +1,27 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define ARCH_INTERNET CArchInternetUnix
#include "CString.h"
class CArchInternetUnix {
public:
CString get(const CString& url);
};

View File

@ -0,0 +1,119 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CArchInternetWindows.h"
#include "CArch.h"
#include "Version.h"
#include "XArchWindows.h"
#include <sstream>
#include <Wininet.h>
CString
CArchInternetWindows::get(const CString& url)
{
std::stringstream userAgent;
userAgent << "Synergy ";
userAgent << kVersion;
HINTERNET session = InternetOpen(
userAgent.str().c_str(),
INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, NULL);
if (session == NULL) {
throw XArch(new XArchEvalWindows());
}
// InternetCrackUrl didn't seem to work too well, this isn't quite
// as robust, but it should do just fine for basic URLs.
size_t schemeEnd = url.find("://");
size_t hostEnd = url.find('/', schemeEnd + 3);
CString scheme = url.substr(0, schemeEnd);
CString host = url.substr(schemeEnd + 3, hostEnd - (schemeEnd + 3));
CString path = url.substr(hostEnd);
INTERNET_PORT port = INTERNET_DEFAULT_HTTP_PORT;
DWORD requestFlags = 0;
if (scheme.find("https") != CString::npos) {
port = INTERNET_DEFAULT_HTTPS_PORT;
requestFlags = INTERNET_FLAG_SECURE;
}
HINTERNET connect = InternetConnect(
session, host.c_str(), port, NULL, NULL,
INTERNET_SERVICE_HTTP, NULL, NULL);
if (connect == NULL) {
throw XArch(new XArchEvalWindows());
}
HINTERNET request = HttpOpenRequest(
connect, "GET", path.c_str(),
HTTP_VERSION, NULL,
NULL, requestFlags, NULL);
if (request == NULL) {
throw XArch(new XArchEvalWindows());
}
CString headers("Content-Type: text/html");
if (!HttpSendRequest(request, headers.c_str(), (DWORD)headers.length(), NULL, NULL)) {
int error = GetLastError();
throw XArch(new XArchEvalWindows());
}
std::stringstream result;
CHAR buffer[1025];
DWORD read = 0;
while (InternetReadFile(request, buffer, sizeof(buffer) - 1, &read) && (read != 0)) {
buffer[read] = 0;
result << buffer;
read = 0;
}
InternetCloseHandle(request);
InternetCloseHandle(connect);
InternetCloseHandle(session);
return result.str();
}
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CArchInternetWindows.h"
CString
CArchInternetWindows::get(const CString& url)
{
return "Hello bob!";
}

View File

@ -0,0 +1,54 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define ARCH_INTERNET CArchInternetWindows
#include "CString.h"
class CArchInternetWindows {
public:
CString get(const CString& url);
};
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define ARCH_INTERNET CArchInternetWindows
#include "CString.h"
class CArchInternetWindows {
public:
CString get(const CString& url);
};

View File

@ -43,6 +43,7 @@ if (WIN32)
XArch.h
IArchPlugin.h
CArchPluginWindows.h
CArchInternetWindows.h
)
list(APPEND src
@ -61,6 +62,7 @@ if (WIN32)
CArchTimeWindows.cpp
XArchWindows.cpp
CArchPluginWindows.cpp
CArchInternetWindows.cpp
)
elseif (UNIX)
@ -80,6 +82,7 @@ elseif (UNIX)
XArchUnix.cpp
CArchDaemonNone.cpp
CArchPluginUnix.cpp
CArchInternetUnix.cpp
)
endif()

View File

@ -49,6 +49,7 @@ set(inc
IAppUtil.h
CFileChunker.h
CDragInformation.h
CToolApp.h
)
set(src
@ -77,6 +78,7 @@ set(src
CArgsBase.cpp
CFileChunker.cpp
CDragInformation.cpp
CToolApp.cpp
)
if (WIN32)

View File

@ -0,0 +1,60 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CToolApp.h"
#include "CString.h"
#include "CArch.h"
#include <iostream>
#include <sstream>
//#define PREMIUM_AUTH_URL "http://localhost/synergy/premium/json/auth/"
#define PREMIUM_AUTH_URL "https://synergy-foss.org/premium/json/auth/"
int
CToolApp::run(int argc, char** argv)
{
if (argc <= 1) {
std::cerr << "no args" << std::endl;
return 1;
}
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--premium-auth") == 0) {
CString credentials;
std::cin >> credentials;
size_t separator = credentials.find(':');
CString email = credentials.substr(0, separator);
CString password = credentials.substr(separator + 1, credentials.length());
std::stringstream ss;
ss << PREMIUM_AUTH_URL;
ss << "?email=" << email;
ss << "&password=" << password;
std::cout << ARCH->internet().get(ss.str()) << std::endl;
return 0;
}
else {
std::cerr << "unknown arg: " << argv[i] << std::endl;
return 1;
}
}
return 0;
}

View File

@ -0,0 +1,23 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
class CToolApp {
public:
int run(int argc, char** argv);
};

View File

@ -30,6 +30,7 @@ if (WIN32)
list(APPEND src
platform/CMSWindowsClipboardTests.cpp
platform/CMSWindowsKeyStateTests.cpp
arch/CArchInternetWindowsTests.cpp
)
elseif (APPLE)
list(APPEND src

View File

@ -0,0 +1,116 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
#include "CArchInternetWindows.h"
#define TEST_URL "https://synergy-foss.org/tests/?testString"
//#define TEST_URL "http://localhost/synergy/tests/?testString"
TEST(CArchInternetWindowsTests, openWebPage)
{
CArchInternetWindows internet;
CString result = internet.get(TEST_URL);
ASSERT_EQ("Hello world!", result);
}
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
#include "CArchInternetWindows.h"
#define TEST_URL "https://synergy-foss.org/tests/?testString"
//#define TEST_URL "http://localhost/synergy/tests/?testString"
TEST(CArchInternetWindowsTests, openWebPage)
{
CArchInternetWindows internet;
CString result = internet.get(TEST_URL);
ASSERT_EQ("Hello world!", result);
}
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
#include "CArchInternetWindows.h"
//#define TEST_URL "https://synergy-foss.org/tests/?testString"
#define TEST_URL "http://localhost/synergy/tests/?testString"
TEST(CArchInternetWindowsTests, openWebPage)
{
CArchInternetWindows internet;
CString result = internet.get(TEST_URL);
ASSERT_EQ("Hello world!", result);
}
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2014 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
#include "CArchInternetWindows.h"
//#define TEST_URL "https://synergy-foss.org/tests/?testString"
#define TEST_URL "http://localhost/synergy/tests/?testString"
TEST(CArchInternetWindowsTests, openWebPage)
{
CArchInternetWindows internet;
CString result = internet.get(TEST_URL);
ASSERT_EQ("Hello world!", result);
}

View File

@ -483,10 +483,9 @@ class InternalCommands:
# copy synergy[cs] binaries into the bundle, since the gui
# now looks for the binaries in the current app dir.
shutil.copy(dir + "/synergyc",
dir + "/Synergy.app/Contents/MacOS/")
shutil.copy(dir + "/synergys",
dir + "/Synergy.app/Contents/MacOS/")
shutil.copy(dir + "/synergyc", dir + "/Synergy.app/Contents/MacOS/")
shutil.copy(dir + "/synergys", dir + "/Synergy.app/Contents/MacOS/")
shutil.copy(dir + "/syntool", dir + "/Synergy.app/Contents/MacOS/")
# use qt to copy libs to bundle so no dependencies are needed. do not create a
# dmg at this point, since we need to sign it first, and then create our own