mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1728167: Add ability for standard users to install from a DMG through elevation. r=mstange,application-update-reviewers,bytesized
Differential Revision: https://phabricator.services.mozilla.com/D123899
This commit is contained in:
parent
86fc7a1397
commit
c494ddeedd
@ -450,3 +450,59 @@ void SetGroupOwnershipAndPermissions(const char* aAppBundle) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_13) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_13
|
||||
@interface NSTask (NSTask10_13)
|
||||
@property(copy) NSURL* executableURL NS_AVAILABLE_MAC(10_13);
|
||||
@property(copy) NSArray<NSString*>* arguments;
|
||||
- (BOOL)launchAndReturnError:(NSError**)error NS_AVAILABLE_MAC(10_13);
|
||||
@end
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Helper to launch macOS tasks via NSTask.
|
||||
*/
|
||||
static void LaunchTask(NSString* aPath, NSArray* aArguments) {
|
||||
if (@available(macOS 10.13, *)) {
|
||||
NSTask* task = [[NSTask alloc] init];
|
||||
[task setExecutableURL:[NSURL fileURLWithPath:aPath]];
|
||||
if (aArguments) {
|
||||
[task setArguments:aArguments];
|
||||
}
|
||||
[task launchAndReturnError:nil];
|
||||
[task release];
|
||||
} else {
|
||||
NSArray* arguments = aArguments;
|
||||
if (!arguments) {
|
||||
arguments = @[];
|
||||
}
|
||||
[NSTask launchedTaskWithLaunchPath:aPath arguments:arguments];
|
||||
}
|
||||
}
|
||||
|
||||
static void RegisterAppWithLaunchServices(NSString* aBundlePath) {
|
||||
NSArray* arguments = @[ @"-f", aBundlePath ];
|
||||
LaunchTask(@"/System/Library/Frameworks/CoreServices.framework/Frameworks/"
|
||||
@"LaunchServices.framework/Support/lsregister",
|
||||
arguments);
|
||||
}
|
||||
|
||||
static void StripQuarantineBit(NSString* aBundlePath) {
|
||||
NSArray* arguments = @[ @"-d", @"com.apple.quarantine", aBundlePath ];
|
||||
LaunchTask(@"/usr/bin/xattr", arguments);
|
||||
}
|
||||
|
||||
bool PerformInstallationFromDMG(int argc, char** argv) {
|
||||
MacAutoreleasePool pool;
|
||||
if (argc < 4) {
|
||||
return false;
|
||||
}
|
||||
NSString* bundlePath = [NSString stringWithUTF8String:argv[2]];
|
||||
NSString* destPath = [NSString stringWithUTF8String:argv[3]];
|
||||
if ([[NSFileManager defaultManager] copyItemAtPath:bundlePath toPath:destPath error:nil]) {
|
||||
RegisterAppWithLaunchServices(destPath);
|
||||
StripQuarantineBit(destPath);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,7 @@
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "MacRunFromDmgUtils.h"
|
||||
#include "MacLaunchHelper.h"
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/intl/Localization.h"
|
||||
@ -25,19 +26,13 @@
|
||||
#include "nsIMacDockSupport.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsString.h"
|
||||
#include "nsUpdateDriver.h"
|
||||
#include "SDKDeclarations.h"
|
||||
|
||||
// For IOKit docs, see:
|
||||
// https://developer.apple.com/documentation/iokit
|
||||
// https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_13) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_13
|
||||
@interface NSTask (NSTask10_13)
|
||||
@property(copy) NSURL* executableURL NS_AVAILABLE_MAC(10_13);
|
||||
@property(copy) NSArray<NSString*>* arguments;
|
||||
- (BOOL)launchAndReturnError:(NSError**)error NS_AVAILABLE_MAC(10_13);
|
||||
@end
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace MacRunFromDmgUtils {
|
||||
|
||||
@ -178,11 +173,41 @@ static void StripQuarantineBit(NSString* aBundlePath) {
|
||||
LaunchTask(@"/usr/bin/xattr", arguments);
|
||||
}
|
||||
|
||||
bool LaunchElevatedDmgInstall(NSString* aBundlePath, NSArray* aArguments) {
|
||||
NSTask* task;
|
||||
if (@available(macOS 10.13, *)) {
|
||||
task = [[NSTask alloc] init];
|
||||
[task setExecutableURL:[NSURL fileURLWithPath:aBundlePath]];
|
||||
if (aArguments) {
|
||||
[task setArguments:aArguments];
|
||||
}
|
||||
[task launchAndReturnError:nil];
|
||||
} else {
|
||||
NSArray* arguments = aArguments;
|
||||
if (!arguments) {
|
||||
arguments = @[];
|
||||
}
|
||||
task = [NSTask launchedTaskWithLaunchPath:aBundlePath arguments:arguments];
|
||||
}
|
||||
|
||||
bool didSucceed = InstallPrivilegedHelper();
|
||||
[task waitUntilExit];
|
||||
if (@available(macOS 10.13, *)) {
|
||||
[task release];
|
||||
}
|
||||
if (!didSucceed) {
|
||||
AbortElevatedUpdate();
|
||||
}
|
||||
|
||||
return didSucceed;
|
||||
}
|
||||
|
||||
// Note: both arguments are expected to contain the app name (to end with
|
||||
// '.app').
|
||||
static bool InstallFromDmg(NSString* aBundlePath, NSString* aDestPath) {
|
||||
bool installSuccessful = false;
|
||||
if ([[NSFileManager defaultManager] copyItemAtPath:aBundlePath toPath:aDestPath error:nil]) {
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
if ([fileManager copyItemAtPath:aBundlePath toPath:aDestPath error:nil]) {
|
||||
RegisterAppWithLaunchServices(aDestPath);
|
||||
StripQuarantineBit(aDestPath);
|
||||
installSuccessful = true;
|
||||
@ -190,10 +215,22 @@ static bool InstallFromDmg(NSString* aBundlePath, NSString* aDestPath) {
|
||||
|
||||
// The installation may have been unsuccessful if the user did not have the
|
||||
// rights to write to the Applications directory. Check for this situation and
|
||||
// launch an elevated installation if necessary.
|
||||
// launch an elevated installation if necessary. Rather than creating a new,
|
||||
// dedicated executable for this installation and incurring the
|
||||
// added maintenance burden of yet another executable, we are using the
|
||||
// updater binary. Since bug 394984 landed, the updater has the ability to
|
||||
// install and launch itself as a Privileged Helper tool, which is what is
|
||||
// necessary here.
|
||||
NSString* destDir = [aDestPath stringByDeletingLastPathComponent];
|
||||
if (!installSuccessful && ![[NSFileManager defaultManager] isWritableFileAtPath:destDir]) {
|
||||
// TODO: launch elevated installation.
|
||||
if (!installSuccessful && ![fileManager isWritableFileAtPath:destDir]) {
|
||||
NSString* updaterBinPath = [NSString pathWithComponents:@[
|
||||
aBundlePath, @"Contents", @"MacOS", [NSString stringWithUTF8String:UPDATER_APP], @"Contents",
|
||||
@"MacOS", [NSString stringWithUTF8String:UPDATER_BIN]
|
||||
]];
|
||||
|
||||
NSArray* arguments = @[ @"-dmgInstall", aBundlePath, aDestPath ];
|
||||
LaunchElevatedDmgInstall(updaterBinPath, arguments);
|
||||
installSuccessful = [fileManager fileExistsAtPath:aDestPath];
|
||||
}
|
||||
|
||||
if (!installSuccessful) {
|
||||
|
@ -64,16 +64,6 @@ static LazyLogModule sUpdateLog("updatedriver");
|
||||
#endif
|
||||
#define LOG(args) MOZ_LOG(sUpdateLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
#ifdef XP_WIN
|
||||
# define UPDATER_BIN "updater.exe"
|
||||
# define MAINTENANCE_SVC_NAME L"MozillaMaintenance"
|
||||
#elif XP_MACOSX
|
||||
# define UPDATER_APP "updater.app"
|
||||
# define UPDATER_BIN "org.mozilla.updater"
|
||||
#else
|
||||
# define UPDATER_BIN "updater"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
static void UpdateDriverSetupMacCommandLine(int& argc, char**& argv,
|
||||
bool restart) {
|
||||
|
@ -26,6 +26,16 @@ typedef pid_t ProcessType;
|
||||
typedef PRProcess* ProcessType;
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
# define UPDATER_BIN "updater.exe"
|
||||
# define MAINTENANCE_SVC_NAME L"MozillaMaintenance"
|
||||
#elif XP_MACOSX
|
||||
# define UPDATER_APP "updater.app"
|
||||
# define UPDATER_BIN "org.mozilla.updater"
|
||||
#else
|
||||
# define UPDATER_BIN "updater"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function processes any available updates. As part of that process, it
|
||||
* may exit the current process and relaunch it at a later time.
|
||||
|
@ -30,6 +30,12 @@ using NSAppearanceName = NSString*;
|
||||
@property(class, strong, readonly) NSColor* systemPurpleColor NS_AVAILABLE_MAC(10_10);
|
||||
@end
|
||||
|
||||
@interface NSTask (NSTask10_13)
|
||||
@property(copy) NSURL* executableURL NS_AVAILABLE_MAC(10_13);
|
||||
@property(copy) NSArray<NSString*>* arguments;
|
||||
- (BOOL)launchAndReturnError:(NSError**)error NS_AVAILABLE_MAC(10_13);
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_14) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_14
|
||||
|
Loading…
Reference in New Issue
Block a user