Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2558)

Unified Diff: chrome/installer/mac/app/AuthorizedInstall.m

Issue 2243863003: Added authorized install with a script to do the copy. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleaned up code and made the script waiting not awkward Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/installer/mac/app/AuthorizedInstall.m
diff --git a/chrome/installer/mac/app/AuthorizedInstall.m b/chrome/installer/mac/app/AuthorizedInstall.m
new file mode 100644
index 0000000000000000000000000000000000000000..b67815afd71c5d641b791fb7e91609f59da3661f
--- /dev/null
+++ b/chrome/installer/mac/app/AuthorizedInstall.m
@@ -0,0 +1,132 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "AuthorizedInstall.h"
+
+@interface AuthorizedInstall () {
+ NSFileHandle* communicationFile_;
+ NSString* destinationAppBundlePath_;
+}
+@end
+
+@implementation AuthorizedInstall
+// Does the setup needed to authorize a tool to run as admin.
+- (OSStatus)setUpAuthorization:(AuthorizationRef*)authRef {
+ OSStatus status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
+ kAuthorizationFlagDefaults, authRef);
+
+ AuthorizationItem items = {kAuthorizationRightExecute, 0, NULL, 0};
+ AuthorizationRights rights = {1, &items};
+ AuthorizationFlags flags =
+ kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
+ kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
+
+ status = AuthorizationCopyRights(*authRef, &rights, NULL, flags, NULL);
+ return status;
+}
+
+// Starts up the proccess with privileged permissions.
+- (void)startPrivilegedTool:(const char*)toolPath
+ withArguments:(const char**)args
+ authorization:(AuthorizationRef)authRef
+ status:(OSStatus)status {
+ if (status != errAuthorizationSuccess)
+ return;
+
+ FILE* file;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ status = AuthorizationExecuteWithPrivileges(
+ authRef, toolPath, kAuthorizationFlagDefaults, (char* const*)args, &file);
+#pragma clang diagnostic pop
+ communicationFile_ = [[NSFileHandle alloc] initWithFileDescriptor:fileno(file)
+ closeOnDealloc:YES];
+}
+
+// Starts up same proccess as above without privileged permissions.
+- (void)startUnprivilegedTool:(NSString*)toolPath withArguments:(NSArray*)args {
+ NSPipe* pipe = [NSPipe pipe];
+ NSTask* task = [[NSTask alloc] init];
+ [task setArguments:args];
+ [task setLaunchPath:toolPath];
+ [task setStandardInput:pipe];
+ [task launch];
+ communicationFile_ = [pipe fileHandleForWriting];
+}
+
+// Determines which "Applications" folder to use based on authorization.
+// There are three possible scenarios and two possible return values.
+// 1) /Applications is returned if:
+// a) The user authenticates the app.
+// b) The user doesn't authenticate but is an admin.
+// 2) /Users/username/Applications is returned if:
+// c) The user doesn't authenticate and is not an admin.
Elly Fong-Jones 2016/08/24 16:39:22 This comment is so good. You can refer to /Users/u
ivanhernandez 2016/08/24 18:23:17 Done.
+- (NSString*)getApplicationsFolder:(BOOL)isAuthorized {
+ NSFileManager* manager = [NSFileManager defaultManager];
+ NSArray* applicationDirectories = NSSearchPathForDirectoriesInDomains(
+ NSApplicationDirectory, NSLocalDomainMask, YES);
+ if (isAuthorized ||
+ [manager isWritableFileAtPath:applicationDirectories.firstObject]) {
+ return applicationDirectories.firstObject;
+ } else {
+ NSString* usersApplicationsDirectory =
+ [NSString pathWithComponents:@[ NSHomeDirectory(), @"Applications" ]];
+ if (![manager fileExistsAtPath:usersApplicationsDirectory]) {
+ [manager createDirectoryAtPath:usersApplicationsDirectory
+ withIntermediateDirectories:NO
+ attributes:nil
+ error:nil];
+ }
+ return usersApplicationsDirectory;
+ }
+}
+
+// Attempts to gain authorization to run installation tool with elevated
+// permissions.
+// Then starts the tool with the appropiate paths for the tools elevation
+// status.
+- (BOOL)loadInstallationTool {
+ AuthorizationRef authRef = NULL;
+ OSStatus status = [self setUpAuthorization:&authRef];
+ BOOL isAuthorized = (status == errAuthorizationSuccess);
+
+ NSString* toolPath =
+ [[NSBundle mainBundle] pathForResource:@"copy_to_disk" ofType:@"sh"];
+ NSFileManager* manager = [NSFileManager defaultManager];
+ if (![manager fileExistsAtPath:toolPath]) {
+ return false;
+ }
+
+ NSString* applicationsDirectory = [self getApplicationsFolder:isAuthorized];
+ destinationAppBundlePath_ = [NSString pathWithComponents: @[
+ applicationsDirectory, @"Google Chrome.app"]];
Elly Fong-Jones 2016/08/24 16:39:22 no more Chromo? :)
ivanhernandez 2016/08/24 18:23:17 This app is moving up in the world.
+
+ if (isAuthorized) {
+ const char* args[] = {[applicationsDirectory UTF8String], NULL};
+ [self startPrivilegedTool:[toolPath UTF8String]
+ withArguments:args
+ authorization:authRef
+ status:status];
+ } else {
+ NSArray* args = @[ applicationsDirectory ];
+ [self startUnprivilegedTool:toolPath withArguments:args];
+ }
+
+ AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
+ return true;
+}
+
+- (NSString*)startInstall:(NSString*)appBundlePath {
+ [self sendMessageToTool:appBundlePath];
+ [self sendMessageToTool:@"\n"];
Elly Fong-Jones 2016/08/24 16:39:22 that's odd - why is the newline necessary? is the
ivanhernandez 2016/08/24 18:23:16 Good point, having sendMessageToTool append the ne
+ return destinationAppBundlePath_;
+}
+
+// Sends a message to the tool's stdin.
+- (void)sendMessageToTool:(NSString*)message {
+ [communicationFile_
+ writeData:[message dataUsingEncoding:NSUTF8StringEncoding]];
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698