diff options
author | Mikkel Krautz <mikkel@krautz.dk> | 2010-07-28 01:15:14 +0400 |
---|---|---|
committer | Mikkel Krautz <mikkel@krautz.dk> | 2010-07-28 01:15:14 +0400 |
commit | 8f63e4d79e0f6d069a9bc2929d9cf303340db810 (patch) | |
tree | a8ecdafbeca75769a0ca9405c9b3bdb1d39616b4 /src | |
parent | b8f14d8b9b25c719ca2cd8db0ad33cb62d4848bf (diff) |
Check overlay installer for version info instead of the Mumble app bundle.
Diffstat (limited to 'src')
-rw-r--r-- | src/mumble/Overlay.cpp | 2 | ||||
-rw-r--r-- | src/mumble/Overlay_macx.mm | 117 | ||||
-rw-r--r-- | src/mumble/mumble.plist | 6 |
3 files changed, 94 insertions, 31 deletions
diff --git a/src/mumble/Overlay.cpp b/src/mumble/Overlay.cpp index 5b05ebe7c..3bb6f22e4 100644 --- a/src/mumble/Overlay.cpp +++ b/src/mumble/Overlay.cpp @@ -340,7 +340,7 @@ void OverlayConfig::on_qswOverlayPage_currentChanged(int) { QLatin1String qsStyleSheetInvalid("QLabel { color: red; }"); QLatin1String qsStyleSheetValid("QLabel { color: green; }"); QString qsValidInstaller = tr("Mumble has deemed the installer valid."); - QString qsInvalidInstaller = tr("Mumble was unable to validate authenticity of the installer."); + QString qsInvalidInstaller = tr("Mumble was unable to verify the authenticity of the installer."); if (qswOverlayPage->currentWidget() == qwOverlayInstall) { qpbShowCerts->setVisible(supportsCertificates()); diff --git a/src/mumble/Overlay_macx.mm b/src/mumble/Overlay_macx.mm index ef68bf722..a26db427c 100644 --- a/src/mumble/Overlay_macx.mm +++ b/src/mumble/Overlay_macx.mm @@ -39,6 +39,9 @@ extern "C" { #include <xar/xar.h> } +static const NSString *MumbleOverlayLoaderBundle = @"/Library/ScriptingAdditions/MumbleOverlay.osax"; +static const NSString *MumbleOverlayLoaderBundleIdentifier = @"net.sourceforge.mumble.OverlayScriptingAddition"; + @interface OverlayInjectorMac : NSObject { BOOL active; } @@ -153,21 +156,13 @@ bool OverlayConfig::supportsCertificates() { bool OverlayConfig::isInstalled() { bool ret = false; - // Get the path where we expect the overlay loader to be installed. - NSString *path = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderBundle"]; - if (! path) { - qWarning("Overlay_macx: Unable to find path of overlay loader in Mumble plist."); - return ret; - } - // Determine if the installed bundle is correctly installed (i.e. it's loadable) - NSBundle *bundle = [NSBundle bundleWithPath:path]; + NSBundle *bundle = [NSBundle bundleWithPath:MumbleOverlayLoaderBundle]; ret = [bundle preflightAndReturnError:NULL]; // Do the bundle identifiers match? if (ret) { - NSString *bundleId = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderBundleIdentifier"]; - ret = [[bundle bundleIdentifier] isEqualToString:bundleId]; + ret = [[bundle bundleIdentifier] isEqualToString:MumbleOverlayLoaderBundleIdentifier]; } [bundle unload]; @@ -175,22 +170,100 @@ bool OverlayConfig::isInstalled() { return ret; } -bool OverlayConfig::needsUpgrade() { - // Get required version from our own Info.plist - NSUInteger reqVersion = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderRequiredVersion"] unsignedIntegerValue]; +// Check whether this installer installs something 'newer' than what we already have. +// Also checks whether the new installer is compatiable with the current version of +// Mumble. +static bool isInstallerNewer(const char *path, NSUInteger curVer) { + xar_t pkg = NULL; + xar_iter_t iter = NULL; + xar_file_t file = NULL; + char *data = NULL; + size_t size = 0; + bool ret = false; + QString qsMinVer, qsOverlayVer; + + pkg = xar_open(path, READ); + if (pkg == NULL) { + qWarning("isInstallerNewer: Unable to open pkg."); + goto out; + } + + iter = xar_iter_new(); + if (iter == NULL) { + qWarning("isInstallerNewer: Unable to allocate iter"); + goto out; + } + + file = xar_file_first(pkg, iter); + while (file != NULL) { + if (!strcmp(xar_get_path(file), "mumbleoverlay.pkg/PackageInfo")) + break; + file = xar_file_next(iter); + } + + if (file != NULL) { + if (xar_extract_tobuffersz(pkg, file, &data, &size) == -1) { + goto out; + } + + QXmlStreamReader reader(QByteArray::fromRawData(data, size)); + while (! reader.atEnd()) { + QXmlStreamReader::TokenType tok = reader.readNext(); + if (tok == QXmlStreamReader::StartElement) { + if (reader.name() == QLatin1String("pkg-info")) { + qsOverlayVer = reader.attributes().value(QLatin1String("version")).toString(); + } else if (reader.name() == QLatin1String("mumble")) { + qsMinVer = reader.attributes().value(QLatin1String("minclient")).toString(); + } + } + } + + if (reader.hasError() || qsMinVer.isNull() || qsOverlayVer.isNull()) { + qWarning("isInstallerNewer: Error while parsing XML version info."); + goto out; + } + NSUInteger newVer = qsOverlayVer.toUInt(); + + QRegExp rx(QLatin1String("(\\d+)\\.(\\d+)\\.(\\d+)")); + int major, minor, patch; + int minmajor, minminor, minpatch; + if (! rx.exactMatch(QLatin1String(MUMTEXT(MUMBLE_VERSION_STRING)))) + goto out; + major = rx.cap(1).toInt(); + minor = rx.cap(2).toInt(); + patch = rx.cap(3).toInt(); + if (! rx.exactMatch(qsMinVer)) + goto out; + minmajor = rx.cap(1).toInt(); + minminor = rx.cap(2).toInt(); + minpatch = rx.cap(3).toInt(); + + ret = (major >= minmajor) && (minor >= minminor) && (patch >= minpatch) && (newVer > curVer); + } + +out: + xar_close(pkg); + xar_iter_free(iter); + free(data); + return ret; +} + +bool OverlayConfig::needsUpgrade() { // Load the overlay loader bundle. - NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderBundle"]]; + NSBundle *bundle = [NSBundle bundleWithPath:MumbleOverlayLoaderBundle]; if (! bundle) { qWarning("Overlay_macx: Unable to load the installed OSAX bundle. This shouldn't happen."); return false; } // Get its version. - NSUInteger curVersion = [[bundle objectForInfoDictionaryKey:@"MumbleOverlayLoaderVersion"] unsignedIntegerValue]; + NSUInteger curVersion = [[bundle objectForInfoDictionaryKey:@"MumbleOverlayVersion"] unsignedIntegerValue]; + NSString *installerPath = [[NSBundle mainBundle] pathForResource:@"MumbleOverlay" ofType:@"pkg"]; + if (! installerPath) + return false; - // If the two versions do not match up, we need to upgrade. - return curVersion != reqVersion; + return isInstallerNewer([installerPath UTF8String], curVersion); } static bool authExec(AuthorizationRef ref, const char **argv) { @@ -270,7 +343,6 @@ static bool validateInstallerSignature(const char *path) { uint32_t len = 0; uint8_t *plaindata = NULL, *signdata = NULL; uint32_t plainlen = 0, signlen = 0; - off_t signoff = 0; bool ret = false; int success = 0; RSA *rsa = NULL; @@ -495,23 +567,20 @@ bool OverlayConfig::installFiles() { bool OverlayConfig::uninstallFiles() { AuthorizationRef auth; - NSString *path, *bundleId; NSBundle *loaderBundle; bool ret = false, bundleOk = false; OSStatus err; // Load the installed loader bundle and check if it's something we're willing to uninstall. - path = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderBundle"]; - bundleId = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderBundleIdentifier"]; - loaderBundle = [NSBundle bundleWithPath:path]; - bundleOk = [[loaderBundle bundleIdentifier] isEqualToString:bundleId]; + loaderBundle = [NSBundle bundleWithPath:MumbleOverlayLoaderBundle]; + bundleOk = [[loaderBundle bundleIdentifier] isEqualToString:MumbleOverlayLoaderBundleIdentifier]; [loaderBundle unload]; // Perform uninstallation using Authorization Services. (Pops up a dialog asking for admin privileges) if (bundleOk) { err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth); if (err == errAuthorizationSuccess) { - const char *remove[] = { "/bin/rm", "-rf", [path UTF8String], NULL }; + const char *remove[] = { "/bin/rm", "-rf", [MumbleOverlayLoaderBundle UTF8String], NULL }; ret = authExec(auth, remove); } AuthorizationFree(auth, kAuthorizationFlagDefaults); diff --git a/src/mumble/mumble.plist b/src/mumble/mumble.plist index 5207a7f73..31df91513 100644 --- a/src/mumble/mumble.plist +++ b/src/mumble/mumble.plist @@ -29,11 +29,5 @@ <string>1.2.3</string> <key>NSHumanReadableCopyright</key> <string>Copyright (c) 2005-2010 Thorvald Natvig <slicer@users.sourceforge.net></string> - <key>MumbleOverlayLoaderBundle</key> - <string>/Library/ScriptingAdditions/MumbleOverlay.osax</string> - <key>MumbleOverlayLoaderBundleIdentifier</key> - <string>net.sourceforge.mumble.OverlayScriptingAddition</string> - <key>MumbleOverlayLoaderRequiredVersion</key> - <integer>6</integer> </dict> </plist> |