From 2e42e535206ff9ff9fecc9af9cf51ccb2bb6edae Mon Sep 17 00:00:00 2001 From: Katja Marttila Date: Fri, 6 Jul 2018 11:55:46 +0300 Subject: Allow maintenancetool signing in Windows Maintenancetool signing was broke as installer modified the maintenancetool binary. Fixed so that maintenancetool is not modified, instead the needed data is written to a separate installer.dat file. Installer.dat is written and needed only after install so we can continue using and deploying only one executable. Task-number: QTIFW-667 Change-Id: I30bf2ebe81d7c7146a78840d234c5c813f8e1da5 Reviewed-by: Jani Heikkinen --- src/libs/installer/packagemanagercore_p.cpp | 34 ++++++++++------------------- src/sdk/sdkapp.h | 31 +++++++++++++++++--------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index 1e271a0d5..7f0d2f722 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -1011,12 +1011,14 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q QInstaller::appendData(&out, input, size); if (writeBinaryLayout) { -#ifdef Q_OS_OSX + QDir resourcePath(QFileInfo(maintenanceToolRenamedName).dir()); +#ifdef Q_OS_OSX if (!resourcePath.path().endsWith(QLatin1String("Contents/MacOS"))) throw Error(tr("Maintenance tool is not a bundle")); resourcePath.cdUp(); resourcePath.cd(QLatin1String("Resources")); +#endif // It's a bit odd to have only the magic in the data file, but this simplifies // other code a lot (since installers don't have any appended data either) QTemporaryFile dataOut; @@ -1043,14 +1045,6 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q dataOut.setAutoRemove(false); dataOut.setPermissions(dataOut.permissions() | QFile::WriteUser | QFile::ReadGroup | QFile::ReadOther); -#else - QInstaller::appendInt64(&out, 0); // operations start - QInstaller::appendInt64(&out, 0); // operations end - QInstaller::appendInt64(&out, 0); // resource count - QInstaller::appendInt64(&out, 4 * sizeof(qint64)); // data block size - QInstaller::appendInt64(&out, BinaryContent::MagicUninstallerMarker); - QInstaller::appendInt64(&out, BinaryContent::MagicCookie); -#endif } { @@ -1312,14 +1306,19 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper QInstaller::openForRead(&input); layout = BinaryContent::binaryLayout(&input, BinaryContent::MagicCookieDat); } catch (const Error &/*error*/) { + // We are only here when using installer + QString binaryName = installerBinaryPath(); + // On Mac data is always in a separate file so that the binary can be signed. + // On other platforms data is in separate file only after install so that the + // maintenancetool sign does not break. #ifdef Q_OS_OSX - // On Mac, data is always in a separate file so that the binary can be signed - QString binaryName = isInstaller() ? installerBinaryPath() : maintenanceToolName(); QDir dataPath(QFileInfo(binaryName).dir()); dataPath.cdUp(); dataPath.cd(QLatin1String("Resources")); input.setFileName(dataPath.filePath(QLatin1String("installer.dat"))); - +#else + input.setFileName(binaryName); +#endif QInstaller::openForRead(&input); layout = BinaryContent::binaryLayout(&input, BinaryContent::MagicCookie); @@ -1329,16 +1328,6 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper QInstaller::openForRead(&tmp); writeMaintenanceToolBinary(&tmp, tmp.size(), true); } -#else - input.setFileName(isInstaller() ? installerBinaryPath() : maintenanceToolName()); - QInstaller::openForRead(&input); - layout = BinaryContent::binaryLayout(&input, BinaryContent::MagicCookie); - if (!newBinaryWritten) { - newBinaryWritten = true; - writeMaintenanceToolBinary(&input, layout.endOfBinaryContent - - layout.binaryContentSize, true); - } -#endif } performedOperations = sortOperationsBasedOnComponentDependencies(performedOperations); @@ -1347,7 +1336,6 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper try { QTemporaryFile file; QInstaller::openForWrite(&file); - writeMaintenanceToolBinaryData(&file, &input, performedOperations, layout); QInstaller::appendInt64(&file, BinaryContent::MagicCookieDat); diff --git a/src/sdk/sdkapp.h b/src/sdk/sdkapp.h index e8932d4f4..17d0ac5e3 100644 --- a/src/sdk/sdkapp.h +++ b/src/sdk/sdkapp.h @@ -67,26 +67,33 @@ public: } /*! - Returns the installer / maintenance tool binary. In case of an installer this will be the + Returns the installer binary or installer.dat. In case of an installer this will be the installer binary itself, which contains the binary layout and the binary content. In case - of an maintenance tool, it will return a binary that has just a binary layout append. + of an maintenance tool, it will return a .dat file that has just a binary layout + as the binary layout cannot be appended to the actual maintenance tool binary + itself because of signing. - Note on OS X: For compatibility reason this function will return the a .dat file located - inside the resource folder in the application bundle, as on OS X the binary layout cannot - be appended to the actual installer / maintenance tool binary itself because of signing. + On OS X: This function will return always the .dat file + .dat file is located inside the resource folder in the application + bundle in OS X. */ QString binaryFile() const { QString binaryFile = QCoreApplication::applicationFilePath(); -#ifdef Q_OS_OSX - // The installer binary on OSX does not contain the binary content, it's put into - // the resources folder as separate file. Adjust the actual binary path. No error - // checking here since we will fail later while reading the binary content. + + // The installer binary on OSX and Windows does not contain the binary + // content, it's put into the resources folder as separate file. + // Adjust the actual binary path. No error checking here since we + // will fail later while reading the binary content. QDir resourcePath(QFileInfo(binaryFile).dir()); + +#ifdef Q_OS_OSX resourcePath.cdUp(); resourcePath.cd(QLatin1String("Resources")); - return resourcePath.filePath(QLatin1String("installer.dat")); #endif + QString datFilePath = resourcePath.filePath(QLatin1String("installer.dat")); + if (QFileInfo::exists(datFilePath)) + return datFilePath; return binaryFile; } @@ -109,7 +116,11 @@ public: QString bundlePath; if (QInstaller::isInBundle(fi.absoluteFilePath(), &bundlePath)) fi.setFile(bundlePath); +#ifdef Q_OS_OSX return fi.absoluteDir().filePath(fi.baseName() + QLatin1String(".dat")); +#else + return fi.absoluteDir().filePath(qApp->applicationName() + QLatin1String(".dat")); +#endif } return QString(); } -- cgit v1.2.3