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

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: Changed BUILD.gn so that only the app would compile AuthorizedInstall.m and not the tests. 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
« no previous file with comments | « chrome/installer/mac/app/AuthorizedInstall.h ('k') | chrome/installer/mac/app/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..07dde8a3ed86185d0311e1d93f2c2b257555a67e
--- /dev/null
+++ b/chrome/installer/mac/app/AuthorizedInstall.m
@@ -0,0 +1,133 @@
+// 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) $HOME/Applications is returned if:
+// c) The user doesn't authenticate and is not an admin.
+- (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"]];
+
+ 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];
+ return destinationAppBundlePath_;
+}
+
+// Sends a message to the tool's stdin. The tool is using 'read' to wait for
+// input. 'read' adds to its buffer until it receives a newline to continue so
+// append '\n' to the message to end the read.
+- (void)sendMessageToTool:(NSString*)message {
+ [communicationFile_ writeData:[[message stringByAppendingString:@"\n"]
+ dataUsingEncoding:NSUTF8StringEncoding]];
+}
+
+@end
« no previous file with comments | « chrome/installer/mac/app/AuthorizedInstall.h ('k') | chrome/installer/mac/app/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698