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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "AuthorizedInstall.h"
6
7 @interface AuthorizedInstall () {
8 NSFileHandle* communicationFile_;
9 NSString* destinationAppBundlePath_;
10 }
11 @end
12
13 @implementation AuthorizedInstall
14 // Does the setup needed to authorize a tool to run as admin.
15 - (OSStatus)setUpAuthorization:(AuthorizationRef*)authRef {
16 OSStatus status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
17 kAuthorizationFlagDefaults, authRef);
18
19 AuthorizationItem items = {kAuthorizationRightExecute, 0, NULL, 0};
20 AuthorizationRights rights = {1, &items};
21 AuthorizationFlags flags =
22 kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
23 kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
24
25 status = AuthorizationCopyRights(*authRef, &rights, NULL, flags, NULL);
26 return status;
27 }
28
29 // Starts up the proccess with privileged permissions.
30 - (void)startPrivilegedTool:(const char*)toolPath
31 withArguments:(const char**)args
32 authorization:(AuthorizationRef)authRef
33 status:(OSStatus)status {
34 if (status != errAuthorizationSuccess)
35 return;
36
37 FILE* file;
38 #pragma clang diagnostic push
39 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
40 status = AuthorizationExecuteWithPrivileges(
41 authRef, toolPath, kAuthorizationFlagDefaults, (char* const*)args, &file);
42 #pragma clang diagnostic pop
43 communicationFile_ = [[NSFileHandle alloc] initWithFileDescriptor:fileno(file)
44 closeOnDealloc:YES];
45 }
46
47 // Starts up same proccess as above without privileged permissions.
48 - (void)startUnprivilegedTool:(NSString*)toolPath withArguments:(NSArray*)args {
49 NSPipe* pipe = [NSPipe pipe];
50 NSTask* task = [[NSTask alloc] init];
51 [task setArguments:args];
52 [task setLaunchPath:toolPath];
53 [task setStandardInput:pipe];
54 [task launch];
55 communicationFile_ = [pipe fileHandleForWriting];
56 }
57
58 // Determines which "Applications" folder to use based on authorization.
59 // There are three possible scenarios and two possible return values.
60 // 1) /Applications is returned if:
61 // a) The user authenticates the app.
62 // b) The user doesn't authenticate but is an admin.
63 // 2) /Users/username/Applications is returned if:
64 // 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.
65 - (NSString*)getApplicationsFolder:(BOOL)isAuthorized {
66 NSFileManager* manager = [NSFileManager defaultManager];
67 NSArray* applicationDirectories = NSSearchPathForDirectoriesInDomains(
68 NSApplicationDirectory, NSLocalDomainMask, YES);
69 if (isAuthorized ||
70 [manager isWritableFileAtPath:applicationDirectories.firstObject]) {
71 return applicationDirectories.firstObject;
72 } else {
73 NSString* usersApplicationsDirectory =
74 [NSString pathWithComponents:@[ NSHomeDirectory(), @"Applications" ]];
75 if (![manager fileExistsAtPath:usersApplicationsDirectory]) {
76 [manager createDirectoryAtPath:usersApplicationsDirectory
77 withIntermediateDirectories:NO
78 attributes:nil
79 error:nil];
80 }
81 return usersApplicationsDirectory;
82 }
83 }
84
85 // Attempts to gain authorization to run installation tool with elevated
86 // permissions.
87 // Then starts the tool with the appropiate paths for the tools elevation
88 // status.
89 - (BOOL)loadInstallationTool {
90 AuthorizationRef authRef = NULL;
91 OSStatus status = [self setUpAuthorization:&authRef];
92 BOOL isAuthorized = (status == errAuthorizationSuccess);
93
94 NSString* toolPath =
95 [[NSBundle mainBundle] pathForResource:@"copy_to_disk" ofType:@"sh"];
96 NSFileManager* manager = [NSFileManager defaultManager];
97 if (![manager fileExistsAtPath:toolPath]) {
98 return false;
99 }
100
101 NSString* applicationsDirectory = [self getApplicationsFolder:isAuthorized];
102 destinationAppBundlePath_ = [NSString pathWithComponents: @[
103 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.
104
105 if (isAuthorized) {
106 const char* args[] = {[applicationsDirectory UTF8String], NULL};
107 [self startPrivilegedTool:[toolPath UTF8String]
108 withArguments:args
109 authorization:authRef
110 status:status];
111 } else {
112 NSArray* args = @[ applicationsDirectory ];
113 [self startUnprivilegedTool:toolPath withArguments:args];
114 }
115
116 AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
117 return true;
118 }
119
120 - (NSString*)startInstall:(NSString*)appBundlePath {
121 [self sendMessageToTool:appBundlePath];
122 [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
123 return destinationAppBundlePath_;
124 }
125
126 // Sends a message to the tool's stdin.
127 - (void)sendMessageToTool:(NSString*)message {
128 [communicationFile_
129 writeData:[message dataUsingEncoding:NSUTF8StringEncoding]];
130 }
131
132 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698