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

Side by Side Diff: chrome/common/service_process_util_mac.mm

Issue 982883003: Use fixed socket name instead of SecureSocketWithKey (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: tests update Created 5 years, 9 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
« no previous file with comments | « chrome/common/service_process_util.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/service_process_util_posix.h" 5 #include "chrome/common/service_process_util_posix.h"
6 6
7 #import <Foundation/Foundation.h> 7 #import <Foundation/Foundation.h>
8 #include <launch.h> 8 #include <launch.h>
9 9
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/mac/bundle_locations.h" 15 #include "base/mac/bundle_locations.h"
16 #include "base/mac/foundation_util.h" 16 #include "base/mac/foundation_util.h"
17 #include "base/mac/mac_util.h" 17 #include "base/mac/mac_util.h"
18 #include "base/mac/scoped_nsautorelease_pool.h" 18 #include "base/mac/scoped_nsautorelease_pool.h"
19 #include "base/mac/scoped_nsobject.h" 19 #include "base/mac/scoped_nsobject.h"
20 #include "base/path_service.h" 20 #include "base/path_service.h"
21 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
23 #include "base/strings/sys_string_conversions.h" 23 #include "base/strings/sys_string_conversions.h"
24 #include "base/threading/thread_restrictions.h" 24 #include "base/threading/thread_restrictions.h"
25 #include "base/version.h" 25 #include "base/version.h"
26 #include "chrome/common/chrome_paths.h" 26 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/chrome_version_info.h" 28 #include "chrome/common/chrome_version_info.h"
29 #include "chrome/common/mac/launchd.h" 29 #include "chrome/common/mac/launchd.h"
30 #include "ipc/unix_domain_socket_util.h"
30 31
31 using ::base::FilePathWatcher; 32 using ::base::FilePathWatcher;
32 33
33 namespace { 34 namespace {
34 35
35 #define kServiceProcessSessionType "Aqua" 36 #define kServiceProcessSessionType "Aqua"
36 37
37 CFStringRef CopyServiceProcessLaunchDName() { 38 CFStringRef CopyServiceProcessLaunchDName() {
38 base::mac::ScopedNSAutoreleasePool pool; 39 base::mac::ScopedNSAutoreleasePool pool;
39 NSBundle* bundle = base::mac::FrameworkBundle(); 40 NSBundle* bundle = base::mac::FrameworkBundle();
40 return CFStringCreateCopy(kCFAllocatorDefault, 41 return CFStringCreateCopy(kCFAllocatorDefault,
41 base::mac::NSToCFCast([bundle bundleIdentifier])); 42 base::mac::NSToCFCast([bundle bundleIdentifier]));
42 } 43 }
43 44
44 NSString* GetServiceProcessLaunchDLabel() { 45 NSString* GetServiceProcessLaunchDLabel() {
45 base::scoped_nsobject<NSString> name( 46 base::scoped_nsobject<NSString> name(
46 base::mac::CFToNSCast(CopyServiceProcessLaunchDName())); 47 base::mac::CFToNSCast(CopyServiceProcessLaunchDName()));
47 NSString *label = [name stringByAppendingString:@".service_process"]; 48 NSString* label = [name stringByAppendingString:@".service_process"];
48 base::FilePath user_data_dir; 49 base::FilePath user_data_dir;
49 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 50 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
50 std::string user_data_dir_path = user_data_dir.value(); 51 std::string user_data_dir_path = user_data_dir.value();
51 NSString *ns_path = base::SysUTF8ToNSString(user_data_dir_path); 52 NSString* ns_path = base::SysUTF8ToNSString(user_data_dir_path);
52 ns_path = [ns_path stringByReplacingOccurrencesOfString:@" " 53 ns_path = [ns_path stringByReplacingOccurrencesOfString:@" "
53 withString:@"_"]; 54 withString:@"_"];
54 label = [label stringByAppendingString:ns_path]; 55 label = [label stringByAppendingString:ns_path];
55 return label; 56 return label;
56 } 57 }
57 58
58 NSString* GetServiceProcessLaunchDSocketKey() { 59 NSString* GetServiceProcessLaunchDSocketKey() {
59 return @"ServiceProcessSocket"; 60 return @"ServiceProcessSocket";
60 } 61 }
61 62
(...skipping 15 matching lines...) Expand all
77 ExecFilePathWatcherCallback() {} 78 ExecFilePathWatcherCallback() {}
78 ~ExecFilePathWatcherCallback() {} 79 ~ExecFilePathWatcherCallback() {}
79 80
80 bool Init(const base::FilePath& path); 81 bool Init(const base::FilePath& path);
81 void NotifyPathChanged(const base::FilePath& path, bool error); 82 void NotifyPathChanged(const base::FilePath& path, bool error);
82 83
83 private: 84 private:
84 FSRef executable_fsref_; 85 FSRef executable_fsref_;
85 }; 86 };
86 87
88 base::FilePath GetServiceProcessSocketName() {
89 base::FilePath socket_name;
90 PathService::Get(base::DIR_TEMP, &socket_name);
91 std::string pipe_name = GetServiceProcessScopedName("srv");
92 socket_name = socket_name.Append(pipe_name);
93 if (socket_name.value().size() < IPC::kMaxSocketNameLength)
94 return socket_name;
95 // Fallback to /tmp if $TMPDIR is too long.
Robert Sesek 2015/03/11 22:20:29 I'd suggest using an UMA histogram to track how of
96 return base::FilePath("/tmp").Append(pipe_name);
97 }
98
87 } // namespace 99 } // namespace
88 100
89 NSString* GetServiceProcessLaunchDSocketEnvVar() {
90 NSString *label = GetServiceProcessLaunchDLabel();
91 NSString *env_var = [label stringByReplacingOccurrencesOfString:@"."
92 withString:@"_"];
93 env_var = [env_var stringByAppendingString:@"_SOCKET"];
94 env_var = [env_var uppercaseString];
95 return env_var;
96 }
97
98 // Gets the name of the service process IPC channel.
99 IPC::ChannelHandle GetServiceProcessChannel() { 101 IPC::ChannelHandle GetServiceProcessChannel() {
100 base::mac::ScopedNSAutoreleasePool pool; 102 base::FilePath socket_name = GetServiceProcessSocketName();
101 std::string socket_path; 103 VLOG(1) << "ServiceProcessChannel: " << socket_name.value();
102 base::scoped_nsobject<NSDictionary> dictionary( 104 return IPC::ChannelHandle(socket_name.value());
103 base::mac::CFToNSCast(Launchd::GetInstance()->CopyExports()));
104 NSString *ns_socket_path =
105 [dictionary objectForKey:GetServiceProcessLaunchDSocketEnvVar()];
106 if (ns_socket_path) {
107 socket_path = base::SysNSStringToUTF8(ns_socket_path);
108 }
109 return IPC::ChannelHandle(socket_path);
110 } 105 }
111 106
112 bool ForceServiceProcessShutdown(const std::string& /* version */, 107 bool ForceServiceProcessShutdown(const std::string& /* version */,
113 base::ProcessId /* process_id */) { 108 base::ProcessId /* process_id */) {
114 base::mac::ScopedNSAutoreleasePool pool; 109 base::mac::ScopedNSAutoreleasePool pool;
115 CFStringRef label = base::mac::NSToCFCast(GetServiceProcessLaunchDLabel()); 110 CFStringRef label = base::mac::NSToCFCast(GetServiceProcessLaunchDLabel());
116 CFErrorRef err = NULL; 111 CFErrorRef err = NULL;
117 bool ret = Launchd::GetInstance()->RemoveJob(label, &err); 112 bool ret = Launchd::GetInstance()->RemoveJob(label, &err);
118 if (!ret) { 113 if (!ret) {
119 DLOG(ERROR) << "ForceServiceProcessShutdown: " << err << " " 114 DLOG(ERROR) << "ForceServiceProcessShutdown: " << err << " "
120 << base::SysCFStringRefToUTF8(label); 115 << base::SysCFStringRefToUTF8(label);
121 CFRelease(err); 116 CFRelease(err);
122 } 117 }
123 return ret; 118 return ret;
124 } 119 }
125 120
126 bool GetServiceProcessData(std::string* version, base::ProcessId* pid) { 121 bool GetServiceProcessData(std::string* version, base::ProcessId* pid) {
127 base::mac::ScopedNSAutoreleasePool pool; 122 base::mac::ScopedNSAutoreleasePool pool;
128 CFStringRef label = base::mac::NSToCFCast(GetServiceProcessLaunchDLabel()); 123 CFStringRef label = base::mac::NSToCFCast(GetServiceProcessLaunchDLabel());
129 base::scoped_nsobject<NSDictionary> launchd_conf( 124 base::scoped_nsobject<NSDictionary> launchd_conf(
130 base::mac::CFToNSCast(Launchd::GetInstance()->CopyJobDictionary(label))); 125 base::mac::CFToNSCast(Launchd::GetInstance()->CopyJobDictionary(label)));
131 if (!launchd_conf.get()) { 126 if (!launchd_conf.get()) {
132 return false; 127 return false;
133 } 128 }
134 // Anything past here will return true in that there does appear 129 // Anything past here will return true in that there does appear
135 // to be a service process of some sort registered with launchd. 130 // to be a service process of some sort registered with launchd.
136 if (version) { 131 if (version) {
137 *version = "0"; 132 *version = "0";
138 NSString *exe_path = [launchd_conf objectForKey:@ LAUNCH_JOBKEY_PROGRAM]; 133 NSString* exe_path = [launchd_conf objectForKey:@ LAUNCH_JOBKEY_PROGRAM];
139 if (exe_path) { 134 if (exe_path) {
140 NSString *bundle_path = [[[exe_path stringByDeletingLastPathComponent] 135 NSString* bundle_path = [[[exe_path stringByDeletingLastPathComponent]
141 stringByDeletingLastPathComponent] 136 stringByDeletingLastPathComponent]
142 stringByDeletingLastPathComponent]; 137 stringByDeletingLastPathComponent];
143 NSBundle *bundle = [NSBundle bundleWithPath:bundle_path]; 138 NSBundle* bundle = [NSBundle bundleWithPath:bundle_path];
144 if (bundle) { 139 if (bundle) {
145 NSString *ns_version = 140 NSString* ns_version =
146 [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 141 [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
147 if (ns_version) { 142 if (ns_version) {
148 *version = base::SysNSStringToUTF8(ns_version); 143 *version = base::SysNSStringToUTF8(ns_version);
149 } else { 144 } else {
150 DLOG(ERROR) << "Unable to get version at: " 145 DLOG(ERROR) << "Unable to get version at: "
151 << reinterpret_cast<CFStringRef>(bundle_path); 146 << reinterpret_cast<CFStringRef>(bundle_path);
152 } 147 }
153 } else { 148 } else {
154 // The bundle has been deleted out from underneath the registered 149 // The bundle has been deleted out from underneath the registered
155 // job. 150 // job.
(...skipping 23 matching lines...) Expand all
179 << "CopyLaunchdDictionaryByCheckingIn: " << err; 174 << "CopyLaunchdDictionaryByCheckingIn: " << err;
180 CFRelease(err); 175 CFRelease(err);
181 return false; 176 return false;
182 } 177 }
183 state_->launchd_conf.reset(dict); 178 state_->launchd_conf.reset(dict);
184 return true; 179 return true;
185 } 180 }
186 181
187 IPC::ChannelHandle ServiceProcessState::GetServiceProcessChannel() { 182 IPC::ChannelHandle ServiceProcessState::GetServiceProcessChannel() {
188 DCHECK(state_); 183 DCHECK(state_);
189 NSDictionary *ns_launchd_conf = base::mac::CFToNSCast(state_->launchd_conf); 184 NSDictionary* ns_launchd_conf = base::mac::CFToNSCast(state_->launchd_conf);
190 NSDictionary* socket_dict = 185 NSDictionary* socket_dict =
191 [ns_launchd_conf objectForKey:@ LAUNCH_JOBKEY_SOCKETS]; 186 [ns_launchd_conf objectForKey:@ LAUNCH_JOBKEY_SOCKETS];
192 NSArray* sockets = 187 NSArray* sockets =
193 [socket_dict objectForKey:GetServiceProcessLaunchDSocketKey()]; 188 [socket_dict objectForKey:GetServiceProcessLaunchDSocketKey()];
194 DCHECK_EQ([sockets count], 1U); 189 DCHECK_EQ([sockets count], 1U);
195 int socket = [[sockets objectAtIndex:0] intValue]; 190 int socket = [[sockets objectAtIndex:0] intValue];
196 base::FileDescriptor fd(socket, false); 191 base::FileDescriptor fd(socket, false);
197 return IPC::ChannelHandle(std::string(), fd); 192 return IPC::ChannelHandle(std::string(), fd);
198 } 193 }
199 194
(...skipping 24 matching lines...) Expand all
224 if (!ready) { 219 if (!ready) {
225 ForceServiceProcessShutdown(version, pid); 220 ForceServiceProcessShutdown(version, pid);
226 } 221 }
227 return ready; 222 return ready;
228 } 223 }
229 224
230 CFDictionaryRef CreateServiceProcessLaunchdPlist(base::CommandLine* cmd_line, 225 CFDictionaryRef CreateServiceProcessLaunchdPlist(base::CommandLine* cmd_line,
231 bool for_auto_launch) { 226 bool for_auto_launch) {
232 base::mac::ScopedNSAutoreleasePool pool; 227 base::mac::ScopedNSAutoreleasePool pool;
233 228
234 NSString *program = 229 NSString* program =
235 base::SysUTF8ToNSString(cmd_line->GetProgram().value()); 230 base::SysUTF8ToNSString(cmd_line->GetProgram().value());
236 231
237 std::vector<std::string> args = cmd_line->argv(); 232 std::vector<std::string> args = cmd_line->argv();
238 NSMutableArray *ns_args = [NSMutableArray arrayWithCapacity:args.size()]; 233 NSMutableArray* ns_args = [NSMutableArray arrayWithCapacity:args.size()];
239 234
240 for (std::vector<std::string>::iterator iter = args.begin(); 235 for (std::vector<std::string>::iterator iter = args.begin();
241 iter < args.end(); 236 iter < args.end();
242 ++iter) { 237 ++iter) {
243 [ns_args addObject:base::SysUTF8ToNSString(*iter)]; 238 [ns_args addObject:base::SysUTF8ToNSString(*iter)];
244 } 239 }
245 240
246 NSDictionary *socket = 241 NSString* soket_name =
247 [NSDictionary dictionaryWithObject:GetServiceProcessLaunchDSocketEnvVar() 242 base::SysUTF8ToNSString(GetServiceProcessSocketName().value());
248 forKey:@ LAUNCH_JOBSOCKETKEY_SECUREWITHKEY]; 243
249 NSDictionary *sockets = 244 NSDictionary* socket =
245 [NSDictionary dictionaryWithObject:soket_name
246 forKey:@LAUNCH_JOBSOCKETKEY_PATHNAME];
247 NSDictionary* sockets =
250 [NSDictionary dictionaryWithObject:socket 248 [NSDictionary dictionaryWithObject:socket
251 forKey:GetServiceProcessLaunchDSocketKey()]; 249 forKey:GetServiceProcessLaunchDSocketKey()];
252 250
253 // See the man page for launchd.plist. 251 // See the man page for launchd.plist.
254 NSMutableDictionary *launchd_plist = 252 NSMutableDictionary* launchd_plist =
255 [[NSMutableDictionary alloc] initWithObjectsAndKeys: 253 [[NSMutableDictionary alloc] initWithObjectsAndKeys:
256 GetServiceProcessLaunchDLabel(), @ LAUNCH_JOBKEY_LABEL, 254 GetServiceProcessLaunchDLabel(), @LAUNCH_JOBKEY_LABEL,
257 program, @ LAUNCH_JOBKEY_PROGRAM, 255 program, @LAUNCH_JOBKEY_PROGRAM,
258 ns_args, @ LAUNCH_JOBKEY_PROGRAMARGUMENTS, 256 ns_args, @LAUNCH_JOBKEY_PROGRAMARGUMENTS,
259 sockets, @ LAUNCH_JOBKEY_SOCKETS, 257 sockets, @LAUNCH_JOBKEY_SOCKETS,
260 nil]; 258 nil];
261 259
262 if (for_auto_launch) { 260 if (for_auto_launch) {
263 // We want the service process to be able to exit if there are no services 261 // We want the service process to be able to exit if there are no services
264 // enabled. With a value of NO in the SuccessfulExit key, launchd will 262 // enabled. With a value of NO in the SuccessfulExit key, launchd will
265 // relaunch the service automatically in any other case than exiting 263 // relaunch the service automatically in any other case than exiting
266 // cleanly with a 0 return code. 264 // cleanly with a 0 return code.
267 NSDictionary *keep_alive = 265 NSDictionary* keep_alive =
268 [NSDictionary 266 [NSDictionary
269 dictionaryWithObject:[NSNumber numberWithBool:NO] 267 dictionaryWithObject:[NSNumber numberWithBool:NO]
270 forKey:@ LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT]; 268 forKey:@LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT];
271 NSDictionary *auto_launchd_plist = 269 NSDictionary* auto_launchd_plist =
272 [[NSDictionary alloc] initWithObjectsAndKeys: 270 [[NSDictionary alloc] initWithObjectsAndKeys:
273 [NSNumber numberWithBool:YES], @ LAUNCH_JOBKEY_RUNATLOAD, 271 [NSNumber numberWithBool:YES], @LAUNCH_JOBKEY_RUNATLOAD,
274 keep_alive, @ LAUNCH_JOBKEY_KEEPALIVE, 272 keep_alive, @LAUNCH_JOBKEY_KEEPALIVE,
275 @ kServiceProcessSessionType, @ LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE, 273 @kServiceProcessSessionType, @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE,
276 nil]; 274 nil];
277 [launchd_plist addEntriesFromDictionary:auto_launchd_plist]; 275 [launchd_plist addEntriesFromDictionary:auto_launchd_plist];
278 } 276 }
279 return reinterpret_cast<CFDictionaryRef>(launchd_plist); 277 return reinterpret_cast<CFDictionaryRef>(launchd_plist);
280 } 278 }
281 279
282 // Writes the launchd property list into the user's LaunchAgents directory, 280 // Writes the launchd property list into the user's LaunchAgents directory,
283 // creating that directory if needed. This will cause the service process to be 281 // creating that directory if needed. This will cause the service process to be
284 // auto launched on the next user login. 282 // auto launched on the next user login.
285 bool ServiceProcessState::AddToAutoRun() { 283 bool ServiceProcessState::AddToAutoRun() {
286 // We're creating directories and writing a file. 284 // We're creating directories and writing a file.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 CFErrorRef err = NULL; 432 CFErrorRef err = NULL;
435 if (!Launchd::GetInstance()->RemoveJob(label, &err)) { 433 if (!Launchd::GetInstance()->RemoveJob(label, &err)) {
436 base::ScopedCFTypeRef<CFErrorRef> scoped_err(err); 434 base::ScopedCFTypeRef<CFErrorRef> scoped_err(err);
437 DLOG(ERROR) << "RemoveJob " << err; 435 DLOG(ERROR) << "RemoveJob " << err;
438 // Exiting with zero, so launchd doesn't restart the process. 436 // Exiting with zero, so launchd doesn't restart the process.
439 exit(0); 437 exit(0);
440 } 438 }
441 } 439 }
442 } 440 }
443 } 441 }
OLDNEW
« no previous file with comments | « chrome/common/service_process_util.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698