- Revision
- 286624
- Author
- [email protected]
- Date
- 2021-12-07 14:51:38 -0800 (Tue, 07 Dec 2021)
Log Message
webpushd should run with regular user permissions
https://bugs.webkit.org/show_bug.cgi?id=233844
Reviewed by Brady Eidson.
Currently webpushd runs as root, which is unneessary. This patch makes it so that we run
with regular user permissions. This is done by specifying a UserName in the launchd plist on
iOS and by installing the plist to /System/Library/LaunchAgents on Mac. Since the plists now
differ based on platform, I changed the "Copy Daemon Plists" build phase in the WebKit
target to copy the appropriate plist to either /S/L/LaunchDaemons or /S/L/LaunchAgents.
Additionally, webpushd needs the `aps-connection-initiate` or
`com.apple.private.aps-connection-initiate` to receive pushes from apsd on iOS and Mac
respectively, so I gave the daemon those entitlements.
Finally, webpushd now registers for the `com.apple.aps.webkit.webpushd.incoming-push` Mach
service so that it can be launched on demand in response to a push. Right now we just
`bootstrap_check_in` to the service at launch time, but eventually we'll remove that and
use APSConnection to check in to the service instead. Since the `bootstrap_check_in`
call is temporary, I chose not to make a header file in wtf/spi and declared the prototype
in the implementation file instead.
* Configurations/webpushd.xcconfig:
* Scripts/process-entitlements.sh:
* WebKit.xcodeproj/project.pbxproj:
* webpushd/WebPushDaemonMain.mm:
(WebKit::WebPushDaemonMain):
* webpushd/com.apple.webkit.webpushd.ios.plist: Added.
* webpushd/com.apple.webkit.webpushd.mac.plist: Added.
* webpushd/com.apple.webkit.webpushd.plist: Removed.
Modified Paths
Added Paths
Removed Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (286623 => 286624)
--- trunk/Source/WebKit/ChangeLog 2021-12-07 22:31:12 UTC (rev 286623)
+++ trunk/Source/WebKit/ChangeLog 2021-12-07 22:51:38 UTC (rev 286624)
@@ -1,3 +1,36 @@
+2021-12-07 Ben Nham <[email protected]>
+
+ webpushd should run with regular user permissions
+ https://bugs.webkit.org/show_bug.cgi?id=233844
+
+ Reviewed by Brady Eidson.
+
+ Currently webpushd runs as root, which is unneessary. This patch makes it so that we run
+ with regular user permissions. This is done by specifying a UserName in the launchd plist on
+ iOS and by installing the plist to /System/Library/LaunchAgents on Mac. Since the plists now
+ differ based on platform, I changed the "Copy Daemon Plists" build phase in the WebKit
+ target to copy the appropriate plist to either /S/L/LaunchDaemons or /S/L/LaunchAgents.
+
+ Additionally, webpushd needs the `aps-connection-initiate` or
+ `com.apple.private.aps-connection-initiate` to receive pushes from apsd on iOS and Mac
+ respectively, so I gave the daemon those entitlements.
+
+ Finally, webpushd now registers for the `com.apple.aps.webkit.webpushd.incoming-push` Mach
+ service so that it can be launched on demand in response to a push. Right now we just
+ `bootstrap_check_in` to the service at launch time, but eventually we'll remove that and
+ use APSConnection to check in to the service instead. Since the `bootstrap_check_in`
+ call is temporary, I chose not to make a header file in wtf/spi and declared the prototype
+ in the implementation file instead.
+
+ * Configurations/webpushd.xcconfig:
+ * Scripts/process-entitlements.sh:
+ * WebKit.xcodeproj/project.pbxproj:
+ * webpushd/WebPushDaemonMain.mm:
+ (WebKit::WebPushDaemonMain):
+ * webpushd/com.apple.webkit.webpushd.ios.plist: Added.
+ * webpushd/com.apple.webkit.webpushd.mac.plist: Added.
+ * webpushd/com.apple.webkit.webpushd.plist: Removed.
+
2021-12-07 Chris Dumez <[email protected]>
ASSERTION FAILED: m_messagesBeingDispatched.isEmpty() on http/tests/resourceLoadStatistics/website-data-removal-for-site-with-user-interaction.html
Modified: trunk/Source/WebKit/Configurations/webpushd.xcconfig (286623 => 286624)
--- trunk/Source/WebKit/Configurations/webpushd.xcconfig 2021-12-07 22:31:12 UTC (rev 286623)
+++ trunk/Source/WebKit/Configurations/webpushd.xcconfig 2021-12-07 22:51:38 UTC (rev 286624)
@@ -28,7 +28,16 @@
OTHER_LDFLAGS = -framework WebKit;
LIBRARY_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR);
+// We want this to always be NO for non-simulator builds. If set to YES, Xcode will invoke codesign with an --entitlements parameter that points to the platform's BaseEntitlements.plist. This parameter would override any --entitlements parameter that we establish in WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS, causing our entitlements to be ignored.
+CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO;
+CODE_SIGN_INJECT_BASE_ENTITLEMENTS[sdk=*simulator] = YES;
+
+// For simulator builds, entitlements are added to a special __entitlements section on the binary rather than the signature.
+CODE_SIGN_ENTITLEMENTS[sdk=*simulator] = Resources/ios/XPCService-embedded-simulator.entitlements
+
WK_PROCESSED_XCENT_FILE=$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).entitlements
+OTHER_CODE_SIGN_FLAGS = --entitlements $(WK_PROCESSED_XCENT_FILE);
+
INSTALL_PATH[sdk=iphone*] = $(WEBKIT_FRAMEWORKS_DIR)/WebKit.framework/Daemons;
INSTALL_PATH[sdk=macosx*] = $(WEBKIT_FRAMEWORKS_DIR)/WebKit.framework/Versions/A/Daemons;
Modified: trunk/Source/WebKit/Scripts/process-entitlements.sh (286623 => 286624)
--- trunk/Source/WebKit/Scripts/process-entitlements.sh 2021-12-07 22:31:12 UTC (rev 286623)
+++ trunk/Source/WebKit/Scripts/process-entitlements.sh 2021-12-07 22:51:38 UTC (rev 286624)
@@ -216,6 +216,13 @@
fi
}
+function mac_process_webpushd_entitlements()
+{
+ # FIXME: Add a sandbox profile for webpushd.
+ echo "webpushd sandbox has not been implemented yet"
+ plistbuddy Add :com.apple.private.aps-connection-initiate bool YES
+}
+
# ========================================
# macCatalyst entitlements
# ========================================
@@ -504,6 +511,7 @@
{
# FIXME: Add a sandbox profile for webpushd and add it to the seatbelt-profiles array.
echo "webpushd sandbox has not been implemented yet"
+ plistbuddy Add :aps-connection-initiate bool YES
}
function ios_family_process_network_entitlements()
@@ -559,7 +567,8 @@
elif [[ "${PRODUCT_NAME}" == com.apple.WebKit.Plugin.64 ]]; then mac_process_plugin_entitlements
elif [[ "${PRODUCT_NAME}" == com.apple.WebKit.GPU ]]; then mac_process_gpu_entitlements
elif [[ "${PRODUCT_NAME}" == com.apple.WebKit.WebAuthn ]]; then mac_process_webauthn_entitlements
- elif [[ "${PRODUCT_NAME}" != webpushd && "${PRODUCT_NAME}" != adattributiond ]]; then echo "Unsupported/unknown product: ${PRODUCT_NAME}"
+ elif [[ "${PRODUCT_NAME}" == webpushd ]]; then mac_process_webpushd_entitlements
+ elif [[ "${PRODUCT_NAME}" != adattributiond ]]; then echo "Unsupported/unknown product: ${PRODUCT_NAME}"
fi
elif [[ "${WK_PLATFORM_NAME}" == maccatalyst || "${WK_PLATFORM_NAME}" == iosmac ]]
then
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (286623 => 286624)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2021-12-07 22:31:12 UTC (rev 286623)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2021-12-07 22:51:38 UTC (rev 286624)
@@ -4895,7 +4895,6 @@
5CB9310626E839A90032B1C0 /* PrivateClickMeasurementManagerInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateClickMeasurementManagerInterface.cpp; sourceTree = "<group>"; };
5CB9310726E841CB0032B1C0 /* PrivateClickMeasurementXPCUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurementXPCUtilities.h; sourceTree = "<group>"; };
5CB9310826E841CB0032B1C0 /* PrivateClickMeasurementXPCUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PrivateClickMeasurementXPCUtilities.mm; sourceTree = "<group>"; };
- 5CBB6D4D271F67CC00FD1A5D /* com.apple.webkit.webpushd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.webkit.webpushd.plist; sourceTree = "<group>"; };
5CBC9B891C6524A500A8FDCF /* NetworkDataTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkDataTask.h; sourceTree = "<group>"; };
5CBC9B8B1C65257300A8FDCF /* NetworkDataTaskCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkDataTaskCocoa.mm; sourceTree = "<group>"; };
5CBE908F26D7FB62005A2E95 /* PrivateClickMeasurementDebugInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurementDebugInfo.h; sourceTree = "<group>"; };
@@ -6373,6 +6372,8 @@
E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKFormColorControl.h; path = ios/forms/WKFormColorControl.h; sourceTree = "<group>"; };
E5CB07DB20E1678F0022C183 /* WKFormColorControl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFormColorControl.mm; path = ios/forms/WKFormColorControl.mm; sourceTree = "<group>"; };
E5DEFA6726F8F42600AB68DB /* PhotosUISPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PhotosUISPI.h; sourceTree = "<group>"; };
+ EB0D312D275AE13300863D8F /* com.apple.webkit.webpushd.mac.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.webkit.webpushd.mac.plist; sourceTree = "<group>"; };
+ EB0D312E275AE13300863D8F /* com.apple.webkit.webpushd.ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.webkit.webpushd.ios.plist; sourceTree = "<group>"; };
ECA680D31E6904B500731D20 /* ExtraPrivateSymbolsForTAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtraPrivateSymbolsForTAPI.h; sourceTree = "<group>"; };
ECBFC1DB1E6A4D66000300C7 /* ExtraPublicSymbolsForTAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtraPublicSymbolsForTAPI.h; sourceTree = "<group>"; };
F036978715F4BF0500C3A80E /* WebColorPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebColorPicker.cpp; sourceTree = "<group>"; };
@@ -9952,7 +9953,8 @@
517B5F63275A8D5C002DC22D /* webpushtool */,
5160E954274B887100567388 /* AppBundleRequest.h */,
5160E953274B887100567388 /* AppBundleRequest.mm */,
- 5CBB6D4D271F67CC00FD1A5D /* com.apple.webkit.webpushd.plist */,
+ EB0D312E275AE13300863D8F /* com.apple.webkit.webpushd.ios.plist */,
+ EB0D312D275AE13300863D8F /* com.apple.webkit.webpushd.mac.plist */,
51F7BB75274498BB00C45A72 /* MockAppBundleForTesting.h */,
51F7BB74274498BA00C45A72 /* MockAppBundleForTesting.mm */,
5160E95C274C2A0300567388 /* MockAppBundleRegistry.h */,
@@ -14994,6 +14996,8 @@
);
inputPaths = (
"$(SRCROOT)/Shared/EntryPointUtilities/Cocoa/Daemon/com.apple.webkit.adattributiond.plist",
+ "$(SRCROOT)/webpushd/com.apple.webkit.webpushd.ios.plist",
+ "$(SRCROOT)/webpushd/com.apple.webkit.webpushd.mac.plist",
);
name = "Copy Daemon Plists";
outputFileListPaths = (
@@ -15000,10 +15004,12 @@
);
outputPaths = (
"$(DSTROOT)/System/Library/LaunchDaemons/com.apple.webkit.adattributiond.plist",
+ "$(DSTROOT)/System/Library/LaunchDaemons/com.apple.webkit.webpushd.plist",
+ "$(DSTROOT)/System/Library/LaunchAgents/com.apple.webkit.webpushd.plist",
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
- shellScript = "if [[ \"${WK_PLATFORM_NAME}\" == iphoneos ]]; then\n ADATTRIBUTIOND_PLIST_SOURCE=\"${SRCROOT}/Shared/EntryPointUtilities/Cocoa/Daemon/com.apple.webkit.adattributiond.plist\"\n ADATTRIBUTIOND_PLIST_DESTINATION=\"${DSTROOT}/System/Library/LaunchDaemons/com.apple.webkit.adattributiond.plist\"\n echo \"copying adattributiond plist\"\n echo plutil -convert binary1 -o \"${ADATTRIBUTIOND_PLIST_DESTINATION}\" \"${ADATTRIBUTIOND_PLIST_SOURCE}\"\n plutil -convert binary1 -o \"${ADATTRIBUTIOND_PLIST_DESTINATION}\" \"${ADATTRIBUTIOND_PLIST_SOURCE}\"\nelse\n echo \"not copying adattributiond plist\"\nfi\n\nif [[ \"${WK_PLATFORM_NAME}\" == iphoneos || \"${WK_PLATFORM_NAME}\" == macosx ]]; then\n WEBPUSHD_PLIST_SOURCE=\"${SRCROOT}/webpushd/com.apple.webkit.webpushd.plist\"\n WEBPUSHD_PLIST_DESTINATION=\"${DSTROOT}/Sy
stem/Library/LaunchDaemons/com.apple.webkit.webpushd.plist\"\n echo \"copying webpushd plist\"\n echo plutil -convert binary1 -o \"${WEBPUSHD_PLIST_DESTINATION}\" \"${WEBPUSHD_PLIST_SOURCE}\"\n plutil -convert binary1 -o \"${WEBPUSHD_PLIST_DESTINATION}\" \"${WEBPUSHD_PLIST_SOURCE}\"\nelse\n echo \"not copying webpushd plist\"\nfi\n";
+ shellScript = "if [[ \"${WK_PLATFORM_NAME}\" == iphoneos ]]; then\n ADATTRIBUTIOND_PLIST_SOURCE=\"${SRCROOT}/Shared/EntryPointUtilities/Cocoa/Daemon/com.apple.webkit.adattributiond.plist\"\n ADATTRIBUTIOND_PLIST_DESTINATION=\"${DSTROOT}/System/Library/LaunchDaemons/com.apple.webkit.adattributiond.plist\"\n echo \"copying adattributiond plist\"\n echo plutil -convert binary1 -o \"${ADATTRIBUTIOND_PLIST_DESTINATION}\" \"${ADATTRIBUTIOND_PLIST_SOURCE}\"\n plutil -convert binary1 -o \"${ADATTRIBUTIOND_PLIST_DESTINATION}\" \"${ADATTRIBUTIOND_PLIST_SOURCE}\"\nelse\n echo \"not copying adattributiond plist\"\nfi\n\nif [[ \"${WK_PLATFORM_NAME}\" == iphoneos || \"${WK_PLATFORM_NAME}\" == macosx ]]; then\n if [[ \"${WK_PLATFORM_NAME}\" == iphoneos ]]; then\n WEBPUSHD_PLIST_SOURCE=\"${SRCROOT}/webpushd/com.apple.webkit.webpu
shd.ios.plist\"\n WEBPUSHD_PLIST_DESTINATION=\"${DSTROOT}/System/Library/LaunchDaemons/com.apple.webkit.webpushd.plist\"\n else\n WEBPUSHD_PLIST_SOURCE=\"${SRCROOT}/webpushd/com.apple.webkit.webpushd.mac.plist\"\n WEBPUSHD_PLIST_DESTINATION=\"${DSTROOT}/System/Library/LaunchAgents/com.apple.webkit.webpushd.plist\"\n fi\n\n echo \"copying webpushd plist\"\n echo plutil -convert binary1 -o \"${WEBPUSHD_PLIST_DESTINATION}\" \"${WEBPUSHD_PLIST_SOURCE}\"\n plutil -convert binary1 -o \"${WEBPUSHD_PLIST_DESTINATION}\" \"${WEBPUSHD_PLIST_SOURCE}\"\nelse\n echo \"not copying webpushd plist\"\nfi\n";
};
E1AC2E2C20F7B95800B0897D /* Unlock Keychain */ = {
isa = PBXShellScriptBuildPhase;
Modified: trunk/Source/WebKit/webpushd/WebPushDaemonMain.mm (286623 => 286624)
--- trunk/Source/WebKit/webpushd/WebPushDaemonMain.mm 2021-12-07 22:31:12 UTC (rev 286623)
+++ trunk/Source/WebKit/webpushd/WebPushDaemonMain.mm 2021-12-07 22:51:38 UTC (rev 286624)
@@ -35,9 +35,20 @@
#import <wtf/MainThread.h>
#import <wtf/spi/darwin/XPCSPI.h>
+#if USE(APPLE_INTERNAL_SDK)
+#import <servers/bootstrap.h>
+#else
+#import <mach/std_types.h>
+extern "C" {
+extern kern_return_t bootstrap_check_in(mach_port_t bootstrapPort, const char *serviceName, mach_port_t*);
+}
+#endif
+
using WebKit::Daemon::EncodedMessage;
using WebPushD::Daemon;
+static const char *incomingPushServiceName = "com.apple.aps.webkit.webpushd.incoming-push";
+
namespace WebPushD {
static void connectionEventHandler(xpc_object_t request)
@@ -73,6 +84,12 @@
@autoreleasepool {
WebKit::startListeningForMachServiceConnections(machServiceName, "com.apple.private.webkit.webpush", connectionAdded, connectionRemoved, connectionEventHandler);
+
+ // TODO: remove this once we actually start using APSConnection.
+ mach_port_t incomingMessagePort;
+ if (bootstrap_check_in(bootstrap_port, incomingPushServiceName, &incomingMessagePort) != KERN_SUCCESS)
+ NSLog(@"Couldn't register for incoming push launch port.");
+
WTF::initializeMainThread();
}
CFRunLoopRun();
Added: trunk/Source/WebKit/webpushd/com.apple.webkit.webpushd.ios.plist (0 => 286624)
--- trunk/Source/WebKit/webpushd/com.apple.webkit.webpushd.ios.plist (rev 0)
+++ trunk/Source/WebKit/webpushd/com.apple.webkit.webpushd.ios.plist 2021-12-07 22:51:38 UTC (rev 286624)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>EnablePressuredExit</key>
+ <true/>
+ <key>EnableTransactions</key>
+ <true/>
+ <key>Label</key>
+ <string>com.apple.webkit.webpushd</string>
+ <key>MachServices</key>
+ <dict>
+ <key>com.apple.webkit.webpushd.service</key>
+ <true/>
+ <key>com.apple.aps.webkit.webpushd.incoming-push</key>
+ <true/>
+ </dict>
+ <key>ProcessType</key>
+ <string>Adaptive</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/System/Library/Frameworks/WebKit.framework/Daemons/webpushd</string>
+ <string>--machServiceName</string>
+ <string>com.apple.webkit.webpushd.service</string>
+ </array>
+ <key>StandardErrorPath</key>
+ <string>/dev/null</string>
+ <key>UserName</key>
+ <string>mobile</string>
+</dict>
+</plist>
Added: trunk/Source/WebKit/webpushd/com.apple.webkit.webpushd.mac.plist (0 => 286624)
--- trunk/Source/WebKit/webpushd/com.apple.webkit.webpushd.mac.plist (rev 0)
+++ trunk/Source/WebKit/webpushd/com.apple.webkit.webpushd.mac.plist 2021-12-07 22:51:38 UTC (rev 286624)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>EnablePressuredExit</key>
+ <true/>
+ <key>EnableTransactions</key>
+ <true/>
+ <key>Label</key>
+ <string>com.apple.webkit.webpushd</string>
+ <key>MachServices</key>
+ <dict>
+ <key>com.apple.webkit.webpushd.service</key>
+ <true/>
+ <key>com.apple.aps.webkit.webpushd.incoming-push</key>
+ <true/>
+ </dict>
+ <key>ProcessType</key>
+ <string>Adaptive</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/System/Library/Frameworks/WebKit.framework/Daemons/webpushd</string>
+ <string>--machServiceName</string>
+ <string>com.apple.webkit.webpushd.service</string>
+ </array>
+ <key>StandardErrorPath</key>
+ <string>/dev/null</string>
+</dict>
+</plist>
Deleted: trunk/Source/WebKit/webpushd/com.apple.webkit.webpushd.plist (286623 => 286624)
--- trunk/Source/WebKit/webpushd/com.apple.webkit.webpushd.plist 2021-12-07 22:31:12 UTC (rev 286623)
+++ trunk/Source/WebKit/webpushd/com.apple.webkit.webpushd.plist 2021-12-07 22:51:38 UTC (rev 286624)
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>EnablePressuredExit</key>
- <true/>
- <key>EnableTransactions</key>
- <true/>
- <key>Label</key>
- <string>com.apple.webkit.webpushd</string>
- <key>MachServices</key>
- <dict>
- <key>com.apple.webkit.webpushd.service</key>
- <true/>
- </dict>
- <key>ProcessType</key>
- <string>Adaptive</string>
- <key>ProgramArguments</key>
- <array>
- <string>/System/Library/Frameworks/WebKit.framework/Daemons/webpushd</string>
- <string>--machServiceName</string>
- <string>com.apple.webkit.webpushd.service</string>
- <string>--storageLocation</string>
- <string>/var/mobile/Library/com.apple.webkit.webpushd/Version1</string>
- </array>
- <key>StandardErrorPath</key>
- <string>/dev/null</string>
-</dict>
-</plist>
\ No newline at end of file