├── SMJobBlessHelper
├── SMJobBlessHelper-Launchd.plist
├── SMJobBlessHelper-Info.plist
└── SMJobBlessHelper.c
├── SMJobBlessApp
├── SMJobBlessApp-Info.plist
├── main.m
├── SMJobBlessAppController.h
├── SMJobBlessAppController.m
└── MainMenu.xib
├── README.md
├── ReadMe-Original.txt
└── SMJobBless.xcodeproj
└── project.pbxproj
/SMJobBlessHelper/SMJobBlessHelper-Launchd.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Label
6 | com.apple.bsd.SMJobBlessHelper
7 | MachServices
8 |
9 | com.apple.bsd.SMJobBlessHelper
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/SMJobBlessHelper/SMJobBlessHelper-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | com.apple.bsd.SMJobBlessHelper
7 | CFBundleInfoDictionaryVersion
8 | 6.0
9 | CFBundleName
10 | SMJobBlessHelper
11 | CFBundleVersion
12 | 1.0
13 | SMAuthorizedClients
14 |
15 | identifier com.apple.bsd.SMJobBlessApp and certificate leaf[subject.CN] = "Mac Developer: Nathan de Vries (T3RB9JQ8KZ)"
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/SMJobBlessApp/SMJobBlessApp-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.apple.bsd.SMJobBlessApp
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | APPL
15 | CFBundleSignature
16 | ????
17 | CFBundleVersion
18 | 1.0
19 | NSMainNibFile
20 | MainMenu
21 | NSPrincipalClass
22 | NSApplication
23 | SMPrivilegedExecutables
24 |
25 | com.apple.bsd.SMJobBlessHelper
26 | identifier com.apple.bsd.SMJobBlessHelper and certificate leaf[subject.CN] = "Mac Developer: Nathan de Vries (T3RB9JQ8KZ)"
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # `SMJobBless` + XPC #
2 |
3 | `SMJobBlessXPC` is based off Apple's `SMJobBless` sample code, but uses XPC over Mach ports for communication between the app and privileged helper tool.
4 |
5 | ## Original README ##
6 |
7 | For the original `README` that ships with Apple's `SMJobBless` sample code, see `ReadMe-Original.txt`.
8 |
9 | ## Outline of changes to the original sample code ##
10 |
11 | The following changes have been made to Apple's sample code:
12 |
13 | * Project files and build configuration have been updated to more modern settings.
14 | * Issues that were causing compile warnings have been corrected.
15 | * Code signing identity has been changed from "Joe Developer" to "Mac Developer". You will need to edit `SMJobBlessApp/SMJobBlessApp-Info.plist` and `SMJobBlessHelper/SMJobBlessHelper-Info.plist` to reflect the Common Name (CN) of the certificate you're using to sign your app & helper tool.
16 | * The helper tool registers a Mach service named `com.apple.bsd.SMJobBlessHelper` with `launchd`.
17 | * The host application connects to the helper tool using XPC via the registered Mach service, sends a message and receives a response.
18 | * A status log is displayed in a text field in the host application to show what's going on.
--------------------------------------------------------------------------------
/SMJobBlessApp/main.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | File: main.m
4 | Abstract: Main function for SMJobBlessApp.
5 | Version: 1.2
6 |
7 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
8 | Inc. ("Apple") in consideration of your agreement to the following
9 | terms, and your use, installation, modification or redistribution of
10 | this Apple software constitutes acceptance of these terms. If you do
11 | not agree with these terms, please do not use, install, modify or
12 | redistribute this Apple software.
13 |
14 | In consideration of your agreement to abide by the following terms, and
15 | subject to these terms, Apple grants you a personal, non-exclusive
16 | license, under Apple's copyrights in this original Apple software (the
17 | "Apple Software"), to use, reproduce, modify and redistribute the Apple
18 | Software, with or without modifications, in source and/or binary forms;
19 | provided that if you redistribute the Apple Software in its entirety and
20 | without modifications, you must retain this notice and the following
21 | text and disclaimers in all such redistributions of the Apple Software.
22 | Neither the name, trademarks, service marks or logos of Apple Inc. may
23 | be used to endorse or promote products derived from the Apple Software
24 | without specific prior written permission from Apple. Except as
25 | expressly stated in this notice, no other rights or licenses, express or
26 | implied, are granted by Apple herein, including but not limited to any
27 | patent rights that may be infringed by your derivative works or by other
28 | works in which the Apple Software may be incorporated.
29 |
30 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE
31 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
32 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
33 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
34 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
35 |
36 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
37 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
40 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
41 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
42 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
43 | POSSIBILITY OF SUCH DAMAGE.
44 |
45 | Copyright (C) 2011 Apple Inc. All Rights Reserved.
46 |
47 |
48 | */
49 |
50 | #import
51 |
52 | int main(int argc, char *argv[])
53 | {
54 | return NSApplicationMain(argc, (const char **) argv);
55 | }
56 |
--------------------------------------------------------------------------------
/SMJobBlessApp/SMJobBlessAppController.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | File: SMJobBlessAppController.h
4 | Abstract: The main application controller header.
5 | Version: 1.2
6 |
7 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
8 | Inc. ("Apple") in consideration of your agreement to the following
9 | terms, and your use, installation, modification or redistribution of
10 | this Apple software constitutes acceptance of these terms. If you do
11 | not agree with these terms, please do not use, install, modify or
12 | redistribute this Apple software.
13 |
14 | In consideration of your agreement to abide by the following terms, and
15 | subject to these terms, Apple grants you a personal, non-exclusive
16 | license, under Apple's copyrights in this original Apple software (the
17 | "Apple Software"), to use, reproduce, modify and redistribute the Apple
18 | Software, with or without modifications, in source and/or binary forms;
19 | provided that if you redistribute the Apple Software in its entirety and
20 | without modifications, you must retain this notice and the following
21 | text and disclaimers in all such redistributions of the Apple Software.
22 | Neither the name, trademarks, service marks or logos of Apple Inc. may
23 | be used to endorse or promote products derived from the Apple Software
24 | without specific prior written permission from Apple. Except as
25 | expressly stated in this notice, no other rights or licenses, express or
26 | implied, are granted by Apple herein, including but not limited to any
27 | patent rights that may be infringed by your derivative works or by other
28 | works in which the Apple Software may be incorporated.
29 |
30 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE
31 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
32 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
33 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
34 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
35 |
36 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
37 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
40 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
41 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
42 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
43 | POSSIBILITY OF SUCH DAMAGE.
44 |
45 | Copyright (C) 2011 Apple Inc. All Rights Reserved.
46 |
47 |
48 | */
49 |
50 | #import
51 |
52 | @interface SMJobBlessAppController : NSObject {
53 | NSTextField* _textField;
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/SMJobBlessHelper/SMJobBlessHelper.c:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | File: SMJobBlessHelper.c
4 | Abstract: A helper tool that doesn't do anything event remotely interesting.
5 | See the ssd sample for how to use GCD and launchd to set up an on-demand
6 | server via sockets.
7 | Version: 1.2
8 |
9 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
10 | Inc. ("Apple") in consideration of your agreement to the following
11 | terms, and your use, installation, modification or redistribution of
12 | this Apple software constitutes acceptance of these terms. If you do
13 | not agree with these terms, please do not use, install, modify or
14 | redistribute this Apple software.
15 |
16 | In consideration of your agreement to abide by the following terms, and
17 | subject to these terms, Apple grants you a personal, non-exclusive
18 | license, under Apple's copyrights in this original Apple software (the
19 | "Apple Software"), to use, reproduce, modify and redistribute the Apple
20 | Software, with or without modifications, in source and/or binary forms;
21 | provided that if you redistribute the Apple Software in its entirety and
22 | without modifications, you must retain this notice and the following
23 | text and disclaimers in all such redistributions of the Apple Software.
24 | Neither the name, trademarks, service marks or logos of Apple Inc. may
25 | be used to endorse or promote products derived from the Apple Software
26 | without specific prior written permission from Apple. Except as
27 | expressly stated in this notice, no other rights or licenses, express or
28 | implied, are granted by Apple herein, including but not limited to any
29 | patent rights that may be infringed by your derivative works or by other
30 | works in which the Apple Software may be incorporated.
31 |
32 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE
33 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
34 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
35 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
36 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
37 |
38 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
39 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
40 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
42 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
43 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
44 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
45 | POSSIBILITY OF SUCH DAMAGE.
46 |
47 | Copyright (C) 2011 Apple Inc. All Rights Reserved.
48 |
49 |
50 | */
51 |
52 | #include
53 | #include
54 |
55 | static void __XPC_Peer_Event_Handler(xpc_connection_t connection, xpc_object_t event) {
56 | syslog(LOG_NOTICE, "Received event in helper.");
57 |
58 | xpc_type_t type = xpc_get_type(event);
59 |
60 | if (type == XPC_TYPE_ERROR) {
61 | if (event == XPC_ERROR_CONNECTION_INVALID) {
62 | // The client process on the other end of the connection has either
63 | // crashed or cancelled the connection. After receiving this error,
64 | // the connection is in an invalid state, and you do not need to
65 | // call xpc_connection_cancel(). Just tear down any associated state
66 | // here.
67 |
68 | } else if (event == XPC_ERROR_TERMINATION_IMMINENT) {
69 | // Handle per-connection termination cleanup.
70 | }
71 |
72 | } else {
73 | xpc_connection_t remote = xpc_dictionary_get_remote_connection(event);
74 |
75 | xpc_object_t reply = xpc_dictionary_create_reply(event);
76 | xpc_dictionary_set_string(reply, "reply", "Hi there, host application!");
77 | xpc_connection_send_message(remote, reply);
78 | xpc_release(reply);
79 | }
80 | }
81 |
82 | static void __XPC_Connection_Handler(xpc_connection_t connection) {
83 | syslog(LOG_NOTICE, "Configuring message event handler for helper.");
84 |
85 | xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
86 | __XPC_Peer_Event_Handler(connection, event);
87 | });
88 |
89 | xpc_connection_resume(connection);
90 | }
91 |
92 | int main(int argc, const char *argv[]) {
93 | xpc_connection_t service = xpc_connection_create_mach_service("com.apple.bsd.SMJobBlessHelper",
94 | dispatch_get_main_queue(),
95 | XPC_CONNECTION_MACH_SERVICE_LISTENER);
96 |
97 | if (!service) {
98 | syslog(LOG_NOTICE, "Failed to create service.");
99 | exit(EXIT_FAILURE);
100 | }
101 |
102 | syslog(LOG_NOTICE, "Configuring connection event handler for helper");
103 | xpc_connection_set_event_handler(service, ^(xpc_object_t connection) {
104 | __XPC_Connection_Handler(connection);
105 | });
106 |
107 | xpc_connection_resume(service);
108 |
109 | dispatch_main();
110 |
111 | xpc_release(service);
112 |
113 | return EXIT_SUCCESS;
114 | }
115 |
116 |
--------------------------------------------------------------------------------
/SMJobBlessApp/SMJobBlessAppController.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | File: SMJobBlessAppController.m
4 | Abstract: The main application controller. When the application has finished
5 | launching, the helper tool will be installed.
6 | Version: 1.2
7 |
8 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
9 | Inc. ("Apple") in consideration of your agreement to the following
10 | terms, and your use, installation, modification or redistribution of
11 | this Apple software constitutes acceptance of these terms. If you do
12 | not agree with these terms, please do not use, install, modify or
13 | redistribute this Apple software.
14 |
15 | In consideration of your agreement to abide by the following terms, and
16 | subject to these terms, Apple grants you a personal, non-exclusive
17 | license, under Apple's copyrights in this original Apple software (the
18 | "Apple Software"), to use, reproduce, modify and redistribute the Apple
19 | Software, with or without modifications, in source and/or binary forms;
20 | provided that if you redistribute the Apple Software in its entirety and
21 | without modifications, you must retain this notice and the following
22 | text and disclaimers in all such redistributions of the Apple Software.
23 | Neither the name, trademarks, service marks or logos of Apple Inc. may
24 | be used to endorse or promote products derived from the Apple Software
25 | without specific prior written permission from Apple. Except as
26 | expressly stated in this notice, no other rights or licenses, express or
27 | implied, are granted by Apple herein, including but not limited to any
28 | patent rights that may be infringed by your derivative works or by other
29 | works in which the Apple Software may be incorporated.
30 |
31 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE
32 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
33 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
34 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
35 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
36 |
37 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
38 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
41 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
42 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
43 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
44 | POSSIBILITY OF SUCH DAMAGE.
45 |
46 | Copyright (C) 2011 Apple Inc. All Rights Reserved.
47 |
48 |
49 | */
50 |
51 | #import
52 | #import
53 | #import "SMJobBlessAppController.h"
54 |
55 |
56 | @interface SMJobBlessAppController ()
57 |
58 | @property (nonatomic, assign) IBOutlet NSTextField* textField;
59 |
60 | - (BOOL)blessHelperWithLabel:(NSString *)label error:(NSError **)error;
61 |
62 | @end
63 |
64 |
65 | @implementation SMJobBlessAppController
66 |
67 | @synthesize textField=_textField;
68 |
69 | - (void)appendLog:(NSString *)log {
70 | self.textField.stringValue = [self.textField.stringValue stringByAppendingFormat:@"\n%@", log];
71 | }
72 |
73 | - (void)applicationDidFinishLaunching:(NSNotification *)notification {
74 | NSError *error = nil;
75 | if (![self blessHelperWithLabel:@"com.apple.bsd.SMJobBlessHelper" error:&error]) {
76 | [self appendLog:[NSString stringWithFormat:@"Failed to bless helper. Error: %@", error]];
77 | return;
78 | }
79 |
80 | self.textField.stringValue = @"Helper available.";
81 |
82 | xpc_connection_t connection = xpc_connection_create_mach_service("com.apple.bsd.SMJobBlessHelper", NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
83 |
84 | if (!connection) {
85 | [self appendLog:@"Failed to create XPC connection."];
86 | return;
87 | }
88 |
89 | xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
90 | xpc_type_t type = xpc_get_type(event);
91 |
92 | if (type == XPC_TYPE_ERROR) {
93 |
94 | if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
95 | [self appendLog:@"XPC connection interupted."];
96 |
97 | } else if (event == XPC_ERROR_CONNECTION_INVALID) {
98 | [self appendLog:@"XPC connection invalid, releasing."];
99 | xpc_release(connection);
100 |
101 | } else {
102 | [self appendLog:@"Unexpected XPC connection error."];
103 | }
104 |
105 | } else {
106 | [self appendLog:@"Unexpected XPC connection event."];
107 | }
108 | });
109 |
110 | xpc_connection_resume(connection);
111 |
112 | xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
113 | const char* request = "Hi there, helper service.";
114 | xpc_dictionary_set_string(message, "request", request);
115 |
116 | [self appendLog:[NSString stringWithFormat:@"Sending request: %s", request]];
117 |
118 | xpc_connection_send_message_with_reply(connection, message, dispatch_get_main_queue(), ^(xpc_object_t event) {
119 | const char* response = xpc_dictionary_get_string(event, "reply");
120 | [self appendLog:[NSString stringWithFormat:@"Received response: %s.", response]];
121 | });
122 | }
123 |
124 | - (BOOL)blessHelperWithLabel:(NSString *)label
125 | error:(NSError **)error {
126 |
127 | BOOL result = NO;
128 |
129 | AuthorizationItem authItem = { kSMRightBlessPrivilegedHelper, 0, NULL, 0 };
130 | AuthorizationRights authRights = { 1, &authItem };
131 | AuthorizationFlags flags = kAuthorizationFlagDefaults |
132 | kAuthorizationFlagInteractionAllowed |
133 | kAuthorizationFlagPreAuthorize |
134 | kAuthorizationFlagExtendRights;
135 |
136 | AuthorizationRef authRef = NULL;
137 |
138 | /* Obtain the right to install privileged helper tools (kSMRightBlessPrivilegedHelper). */
139 | OSStatus status = AuthorizationCreate(&authRights, kAuthorizationEmptyEnvironment, flags, &authRef);
140 | if (status != errAuthorizationSuccess) {
141 | [self appendLog:[NSString stringWithFormat:@"Failed to create AuthorizationRef. Error code: %ld", status]];
142 |
143 | } else {
144 | /* This does all the work of verifying the helper tool against the application
145 | * and vice-versa. Once verification has passed, the embedded launchd.plist
146 | * is extracted and placed in /Library/LaunchDaemons and then loaded. The
147 | * executable is placed in /Library/PrivilegedHelperTools.
148 | */
149 | result = SMJobBless(kSMDomainSystemLaunchd, (CFStringRef)label, authRef, (CFErrorRef *)error);
150 | }
151 |
152 | return result;
153 | }
154 |
155 | @end
156 |
--------------------------------------------------------------------------------
/ReadMe-Original.txt:
--------------------------------------------------------------------------------
1 | Read Me About SMJobBless
2 | ====================================
3 | 1.1
4 |
5 | SMJobBless demonstrates how to embed a privileged helper tool in an application, how to securely install that tool, and how to associate the tool with the application that invokes it.
6 |
7 | SMJobBless uses ServiceManagement.framework that was introduced in Mac OS X v10.6 Snow Leopard.
8 |
9 | As of Snow Leopard, this is the preferred method of managing privilege escalation on Mac OS X and should be used instead of earlier approaches such as BetterAuthorizationSample or directly calling AuthorizationExecuteWithPrivileges.
10 |
11 |
12 | Packing List
13 | ------------
14 | The sample contains the following items:
15 |
16 | o Read Me About SMJobBless.txt -- This file.
17 | o SMJobBless.xcodeproj -- An Xcode project for the sample.
18 | o Resources -- The project nib.
19 | o MainWindowController.[h,m] -- The sources for SMJobBlessApp. Gets an authorization right to install the privileged helper tool, then calls the ServiceManagement function SMJobBless to do the actual installation.
20 | o SMJobBlessHelper.c -- The source for the minimal helper tool SMJobBlessHelper.
21 | o SMJobBlessHelper-Info.plist -- the property list for the helper tool.
22 | o SMJobBlessHelper-Launchd.plist -- the launchd property list for the helper tool.
23 | o SMJobBlessApp-Info.plist -- the application's property list.
24 |
25 | Using the Sample
26 | ----------------
27 |
28 | 1. Run the program.
29 |
30 | 2. Look in the system log to see the message "SMJobBlessApp[]: Job is available!". This confirms that the
31 | sample ran correctly.
32 |
33 |
34 | Building the Sample
35 | -------------------
36 | The sample was built using Xcode 3.2.2 on Mac OS X 10.6.3.
37 |
38 | ServiceManagement.framework uses code signatures to insure that the helper tool is the one expected to be run by
39 | the main application. Therefore, you will need a code signing identity to test this sample. This sample ships with the Code Signing Identity build setting set to "Joe Developer".
40 |
41 | You can get a self-signed code signing identity using these steps:
42 | 1. Launch Keychain Access.
43 | 2. Select Keychain Access > Certificate Assistant > Create a Certificate...
44 | 3. In the Name field, enter "Joe Developer".
45 | 4. Change Certificate Type to "Code Signing".
46 | 5. Press Continue.
47 | 6. You're done!
48 |
49 | If you use a signing identity with a different Common Name (CN), you will need to change the CN in four places:
50 |
51 | o The Code Signing Identity build setting in the target SMJobBlessApp
52 | o The Code Signing Identity build setting in the target com.apple.bsd.SMJobBlessHelper
53 | o The SMPrivilegedExecutables property in SMJobBlessApp-Info.plist
54 | o The SMAuthorizedClients property in SMJobBlessHelper-Info.plist
55 |
56 | Once you have your code signing identity set up and the project configured to refer to the desired code signing identity, you should be able to just choose Build from the Build menu.
57 |
58 |
59 | How It Works
60 | ------------
61 |
62 | This sample covers how to install a privileged helper tool that belongs to an application while addressing these challenges:
63 |
64 | 1. Preserving the ability to drag-install the application.
65 | 2. Operating under the principle of least privilege by isolating privlieged code in a separate process instead
66 | of having the entire application running with elevated privileges.
67 | 3. Avoiding the use of setuid binaries.
68 | 4. Requiring the user to authorize the privileged helper tool only once the first time it's used.
69 | 5. Ensuring that the tool hasn't been replaced by another potentially malicious tool.
70 | 6. Ensuring that the tool hasn't been co-opted by a different potentially malicious application.
71 |
72 | Items 1 and 2 are addressed by shipping the helper tool inside the application bundle without requiring any special ownership or permissions.
73 |
74 | Items 3 and 4 are addressed by using launchd to run the helper tool as a daemon with root privileges.
75 |
76 | Items 4, 5 and 6 are handled by the SMJobBless function. See the comments in -awakeFromNib and ServiceManagement/ServiceManagement.h for details.
77 |
78 | BASIC PROJECT LAYOUT
79 | There are two targets: SMJobBlessApp and com.apple.bsd.SMJobBlessHelper. The application target depends on the helper target. Once the helper is built, it is copied into the application's Contents/Library/LaunchServices directory. Both targets are signed by the "Joe Developer" identity.
80 |
81 | PROPERTY LISTS
82 | The application target has a standard Info.plist associated with it. This plist has an additional key, SMPrivilegedExecutables, whose value is a dictionary. Each key in this dictionary is the name of a privileged helper tool contained in the application. The example has one key, "com.apple.bsd.SMJobBlessHelper". This key maps to a code signing identity, specified as a set of code signing requirements. This is the identity of the tool. This is so that the application can be assured that it is installing the correct tool and not a malicious one that has been put in of it. The example requirement is
83 |
84 | identifier com.apple.bsd.SMJobBlessHelper and certificate leaf[subject.CN] = "Joe Developer"
85 |
86 | This states that the helper tool's bundle identifier is "com.apple.bsd.SMJobBlessHelper", and it was signed by a certificate whose "Subject Common Name" field is "Joe Developer". If a certificate is obtained through a certificate authority, that authority will not issue more than one certificate for "Joe Developer", so this is a reliable check provided there is also a requirement that the root certificate which signed the leaf certificate is part of the trusted system roots. If this check is not present, any certificate (even a self-signed one) can be made to pass this check.
87 |
88 | More information about the code signing requirements language is available at
89 |
90 | http://developer.apple.com/mac/library/documentation/Security/Conceptual/CodeSigningGuide/RequirementLang/RequirementLang.html
91 |
92 | The helper tool, symmetrically, also specifies a code signing requirement for the applications that are allowed to install it in its Info.plist with an array whose key is SMAuthorizedClients. The example has two entries in the array:
93 |
94 | identifier com.apple.bsd.SMJobBlessApp and certificate leaf[subject.CN] = "Joe Developer"
95 | identifier com.apple.bsd.SMJobBlessApp and certificate leaf[subject.CN] = "Joe Developer Development"
96 |
97 | These requirements state that tool allows itself to be manipulated by an application that is signed with either Joe Developer's production or development certificates.
98 |
99 | The helper tool also has a launchd.plist associated with it. For these helper tools, Program and ProgramArguments are not specified. The system will fill these properties into the plist when it installs the helper, since the tools are placed in a predetermined location -- currently /Library/PrivilegedHelperTools. So this example has only the Label property. Other launchd.plist keys are valid to include; see launchd.plist(5).
100 |
101 | The application's Info.plist is distributed in the usual way, by being placed in the bundle. The helper tool's plists must be embedded in the executable itself. This is accomplished by setting special linker flags that create two new sections in the binary: __TEXT,__info_plist and __TEXT,__launchd_plist, for the Info.plist and launchd.plist, respectively. These sections are filled in with the bytes contained in the plist files at link-time. See the helper tool's build settings, under "Other Linker Flags" for the specific arguments used.
102 |
103 | The name of the executable produced by the helper target is "com.apple.bsd.SMJobBlessHelper". This name must be the same as the Label attribute in the launchd.plist, which in turn must be the same as the key in the application's SMPrivilegedExecutables dictionary.
104 |
105 | This sample as it stands does not actually run the helper tool. The following samples show how to a launchd job and
106 | set up interprocess communication:
107 |
108 | o ssd
109 | o BetterAuthorizationSample
110 |
111 |
112 | Version History
113 | ---------------------------
114 | If you find any problems with this sample, please file a bug against it.
115 |
116 |
117 |
118 | 1.1 (Jun 2010) Minor stylistic revisions.
119 | 1.0 (Jun 2010) New sample.
120 |
121 | Apple Developer Technical Support
122 | Core OS/Hardware
123 |
124 | 9 Jun 2010
125 |
--------------------------------------------------------------------------------
/SMJobBless.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4BE4905110445D49006BE471 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4904D10445D49006BE471 /* main.m */; };
11 | 4BE4906110445E13006BE471 /* SMJobBlessHelper.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4905510445DDD006BE471 /* SMJobBlessHelper.c */; };
12 | 4BE4906410445F2F006BE471 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BE4906310445F2F006BE471 /* Security.framework */; };
13 | 4BE4906810445F36006BE471 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BE4906710445F36006BE471 /* ServiceManagement.framework */; };
14 | 4BE49092104463A0006BE471 /* com.apple.bsd.SMJobBlessHelper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4BE4905D10445E0A006BE471 /* com.apple.bsd.SMJobBlessHelper */; };
15 | 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
16 | BF04235611C0531400431286 /* SMJobBlessAppController.m in Sources */ = {isa = PBXBuildFile; fileRef = BF04235511C0531400431286 /* SMJobBlessAppController.m */; };
17 | BF65C19111B985C0007C20AB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF65C19011B985C0007C20AB /* MainMenu.xib */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXContainerItemProxy section */
21 | 4BE4907E1044624F006BE471 /* PBXContainerItemProxy */ = {
22 | isa = PBXContainerItemProxy;
23 | containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
24 | proxyType = 1;
25 | remoteGlobalIDString = 4BE4905C10445E0A006BE471;
26 | remoteInfo = SMJobBlessHelper;
27 | };
28 | /* End PBXContainerItemProxy section */
29 |
30 | /* Begin PBXCopyFilesBuildPhase section */
31 | 4BE49098104463C5006BE471 /* CopyFiles */ = {
32 | isa = PBXCopyFilesBuildPhase;
33 | buildActionMask = 2147483647;
34 | dstPath = Contents/Library/LaunchServices;
35 | dstSubfolderSpec = 1;
36 | files = (
37 | 4BE49092104463A0006BE471 /* com.apple.bsd.SMJobBlessHelper in CopyFiles */,
38 | );
39 | runOnlyForDeploymentPostprocessing = 0;
40 | };
41 | /* End PBXCopyFilesBuildPhase section */
42 |
43 | /* Begin PBXFileReference section */
44 | 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; };
45 | 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; };
46 | 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; };
47 | 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; };
48 | 4BE4904C10445D49006BE471 /* SMJobBlessApp-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SMJobBlessApp-Info.plist"; sourceTree = ""; };
49 | 4BE4904D10445D49006BE471 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
50 | 4BE4905310445DDD006BE471 /* SMJobBlessHelper-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SMJobBlessHelper-Info.plist"; sourceTree = ""; };
51 | 4BE4905410445DDD006BE471 /* SMJobBlessHelper-Launchd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SMJobBlessHelper-Launchd.plist"; sourceTree = ""; };
52 | 4BE4905510445DDD006BE471 /* SMJobBlessHelper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SMJobBlessHelper.c; sourceTree = ""; };
53 | 4BE4905D10445E0A006BE471 /* com.apple.bsd.SMJobBlessHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = com.apple.bsd.SMJobBlessHelper; sourceTree = BUILT_PRODUCTS_DIR; };
54 | 4BE4906310445F2F006BE471 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
55 | 4BE4906710445F36006BE471 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
56 | 8D1107320486CEB800E47090 /* SMJobBlessApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SMJobBlessApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
57 | BF04235411C0531400431286 /* SMJobBlessAppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMJobBlessAppController.h; sourceTree = ""; };
58 | BF04235511C0531400431286 /* SMJobBlessAppController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMJobBlessAppController.m; sourceTree = ""; };
59 | BF65C19011B985C0007C20AB /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = SMJobBlessApp/MainMenu.xib; sourceTree = ""; };
60 | /* End PBXFileReference section */
61 |
62 | /* Begin PBXFrameworksBuildPhase section */
63 | 4BE4905B10445E0A006BE471 /* Frameworks */ = {
64 | isa = PBXFrameworksBuildPhase;
65 | buildActionMask = 2147483647;
66 | files = (
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | 8D11072E0486CEB800E47090 /* Frameworks */ = {
71 | isa = PBXFrameworksBuildPhase;
72 | buildActionMask = 2147483647;
73 | files = (
74 | 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
75 | 4BE4906410445F2F006BE471 /* Security.framework in Frameworks */,
76 | 4BE4906810445F36006BE471 /* ServiceManagement.framework in Frameworks */,
77 | );
78 | runOnlyForDeploymentPostprocessing = 0;
79 | };
80 | /* End PBXFrameworksBuildPhase section */
81 |
82 | /* Begin PBXGroup section */
83 | 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
84 | isa = PBXGroup;
85 | children = (
86 | 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
87 | 4BE4906310445F2F006BE471 /* Security.framework */,
88 | 4BE4906710445F36006BE471 /* ServiceManagement.framework */,
89 | );
90 | name = "Linked Frameworks";
91 | sourceTree = "";
92 | };
93 | 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
94 | isa = PBXGroup;
95 | children = (
96 | 29B97324FDCFA39411CA2CEA /* AppKit.framework */,
97 | 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
98 | 29B97325FDCFA39411CA2CEA /* Foundation.framework */,
99 | );
100 | name = "Other Frameworks";
101 | sourceTree = "";
102 | };
103 | 19C28FACFE9D520D11CA2CBB /* Products */ = {
104 | isa = PBXGroup;
105 | children = (
106 | 8D1107320486CEB800E47090 /* SMJobBlessApp.app */,
107 | 4BE4905D10445E0A006BE471 /* com.apple.bsd.SMJobBlessHelper */,
108 | );
109 | name = Products;
110 | sourceTree = "";
111 | };
112 | 29B97314FDCFA39411CA2CEA /* SMJobBless */ = {
113 | isa = PBXGroup;
114 | children = (
115 | 4BE4905210445DDD006BE471 /* SMJobBlessHelper */,
116 | 4BE4904710445D49006BE471 /* SMJobBlessApp */,
117 | 29B97317FDCFA39411CA2CEA /* Resources */,
118 | 29B97323FDCFA39411CA2CEA /* Frameworks */,
119 | 19C28FACFE9D520D11CA2CBB /* Products */,
120 | );
121 | name = SMJobBless;
122 | sourceTree = "";
123 | };
124 | 29B97317FDCFA39411CA2CEA /* Resources */ = {
125 | isa = PBXGroup;
126 | children = (
127 | BF65C19011B985C0007C20AB /* MainMenu.xib */,
128 | );
129 | name = Resources;
130 | sourceTree = "";
131 | };
132 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
133 | isa = PBXGroup;
134 | children = (
135 | 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
136 | 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
137 | );
138 | name = Frameworks;
139 | sourceTree = "";
140 | };
141 | 4BE4904710445D49006BE471 /* SMJobBlessApp */ = {
142 | isa = PBXGroup;
143 | children = (
144 | BF04235411C0531400431286 /* SMJobBlessAppController.h */,
145 | BF04235511C0531400431286 /* SMJobBlessAppController.m */,
146 | 4BE4904C10445D49006BE471 /* SMJobBlessApp-Info.plist */,
147 | 4BE4904D10445D49006BE471 /* main.m */,
148 | );
149 | path = SMJobBlessApp;
150 | sourceTree = "";
151 | };
152 | 4BE4905210445DDD006BE471 /* SMJobBlessHelper */ = {
153 | isa = PBXGroup;
154 | children = (
155 | 4BE4905310445DDD006BE471 /* SMJobBlessHelper-Info.plist */,
156 | 4BE4905410445DDD006BE471 /* SMJobBlessHelper-Launchd.plist */,
157 | 4BE4905510445DDD006BE471 /* SMJobBlessHelper.c */,
158 | );
159 | path = SMJobBlessHelper;
160 | sourceTree = "";
161 | };
162 | /* End PBXGroup section */
163 |
164 | /* Begin PBXNativeTarget section */
165 | 4BE4905C10445E0A006BE471 /* com.apple.bsd.SMJobBlessHelper */ = {
166 | isa = PBXNativeTarget;
167 | buildConfigurationList = 4BE4906210445E31006BE471 /* Build configuration list for PBXNativeTarget "com.apple.bsd.SMJobBlessHelper" */;
168 | buildPhases = (
169 | 4BE4905A10445E0A006BE471 /* Sources */,
170 | 4BE4905B10445E0A006BE471 /* Frameworks */,
171 | );
172 | buildRules = (
173 | );
174 | dependencies = (
175 | );
176 | name = com.apple.bsd.SMJobBlessHelper;
177 | productName = SMJobBlessHelper;
178 | productReference = 4BE4905D10445E0A006BE471 /* com.apple.bsd.SMJobBlessHelper */;
179 | productType = "com.apple.product-type.tool";
180 | };
181 | 8D1107260486CEB800E47090 /* SMJobBlessApp */ = {
182 | isa = PBXNativeTarget;
183 | buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "SMJobBlessApp" */;
184 | buildPhases = (
185 | 8D1107290486CEB800E47090 /* Resources */,
186 | 8D11072C0486CEB800E47090 /* Sources */,
187 | 8D11072E0486CEB800E47090 /* Frameworks */,
188 | 4BE49098104463C5006BE471 /* CopyFiles */,
189 | );
190 | buildRules = (
191 | );
192 | dependencies = (
193 | 4BE4907F1044624F006BE471 /* PBXTargetDependency */,
194 | );
195 | name = SMJobBlessApp;
196 | productInstallPath = "$(HOME)/Applications";
197 | productName = SMJobBless;
198 | productReference = 8D1107320486CEB800E47090 /* SMJobBlessApp.app */;
199 | productType = "com.apple.product-type.application";
200 | };
201 | /* End PBXNativeTarget section */
202 |
203 | /* Begin PBXProject section */
204 | 29B97313FDCFA39411CA2CEA /* Project object */ = {
205 | isa = PBXProject;
206 | attributes = {
207 | LastUpgradeCheck = 0430;
208 | };
209 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SMJobBless" */;
210 | compatibilityVersion = "Xcode 3.2";
211 | developmentRegion = English;
212 | hasScannedForEncodings = 1;
213 | knownRegions = (
214 | en,
215 | );
216 | mainGroup = 29B97314FDCFA39411CA2CEA /* SMJobBless */;
217 | projectDirPath = "";
218 | projectRoot = "";
219 | targets = (
220 | 8D1107260486CEB800E47090 /* SMJobBlessApp */,
221 | 4BE4905C10445E0A006BE471 /* com.apple.bsd.SMJobBlessHelper */,
222 | );
223 | };
224 | /* End PBXProject section */
225 |
226 | /* Begin PBXResourcesBuildPhase section */
227 | 8D1107290486CEB800E47090 /* Resources */ = {
228 | isa = PBXResourcesBuildPhase;
229 | buildActionMask = 2147483647;
230 | files = (
231 | BF65C19111B985C0007C20AB /* MainMenu.xib in Resources */,
232 | );
233 | runOnlyForDeploymentPostprocessing = 0;
234 | };
235 | /* End PBXResourcesBuildPhase section */
236 |
237 | /* Begin PBXSourcesBuildPhase section */
238 | 4BE4905A10445E0A006BE471 /* Sources */ = {
239 | isa = PBXSourcesBuildPhase;
240 | buildActionMask = 2147483647;
241 | files = (
242 | 4BE4906110445E13006BE471 /* SMJobBlessHelper.c in Sources */,
243 | );
244 | runOnlyForDeploymentPostprocessing = 0;
245 | };
246 | 8D11072C0486CEB800E47090 /* Sources */ = {
247 | isa = PBXSourcesBuildPhase;
248 | buildActionMask = 2147483647;
249 | files = (
250 | 4BE4905110445D49006BE471 /* main.m in Sources */,
251 | BF04235611C0531400431286 /* SMJobBlessAppController.m in Sources */,
252 | );
253 | runOnlyForDeploymentPostprocessing = 0;
254 | };
255 | /* End PBXSourcesBuildPhase section */
256 |
257 | /* Begin PBXTargetDependency section */
258 | 4BE4907F1044624F006BE471 /* PBXTargetDependency */ = {
259 | isa = PBXTargetDependency;
260 | target = 4BE4905C10445E0A006BE471 /* com.apple.bsd.SMJobBlessHelper */;
261 | targetProxy = 4BE4907E1044624F006BE471 /* PBXContainerItemProxy */;
262 | };
263 | /* End PBXTargetDependency section */
264 |
265 | /* Begin XCBuildConfiguration section */
266 | 4BE4905F10445E0B006BE471 /* Debug */ = {
267 | isa = XCBuildConfiguration;
268 | buildSettings = {
269 | ALWAYS_SEARCH_USER_PATHS = NO;
270 | COPY_PHASE_STRIP = NO;
271 | GCC_DYNAMIC_NO_PIC = NO;
272 | GCC_MODEL_TUNING = G5;
273 | GCC_OPTIMIZATION_LEVEL = 0;
274 | INFOPLIST_FILE = "SMJobBlessHelper/SMJobBlessHelper-Info.plist";
275 | INFOPLIST_PREPROCESS = YES;
276 | INSTALL_PATH = /usr/local/bin;
277 | OTHER_LDFLAGS = (
278 | "-sectcreate",
279 | __TEXT,
280 | __info_plist,
281 | "SMJobBlessHelper/SMJobBlessHelper-Info.plist",
282 | "-sectcreate",
283 | __TEXT,
284 | __launchd_plist,
285 | "SMJobBlessHelper/SMJobBlessHelper-Launchd.plist",
286 | );
287 | PRODUCT_NAME = com.apple.bsd.SMJobBlessHelper;
288 | };
289 | name = Debug;
290 | };
291 | 4BE4906010445E0B006BE471 /* Release */ = {
292 | isa = XCBuildConfiguration;
293 | buildSettings = {
294 | ALWAYS_SEARCH_USER_PATHS = NO;
295 | COPY_PHASE_STRIP = YES;
296 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
297 | GCC_MODEL_TUNING = G5;
298 | INFOPLIST_FILE = "SMJobBlessHelper/SMJobBlessHelper-Info.plist";
299 | INFOPLIST_PREPROCESS = YES;
300 | INFOPLIST_PREPROCESSOR_DEFINITIONS = SMJOBBLESS_RELEASE;
301 | INSTALL_PATH = /usr/local/bin;
302 | OTHER_LDFLAGS = (
303 | "-sectcreate",
304 | __TEXT,
305 | __info_plist,
306 | "SMJobBlessHelper/SMJobBlessHelper-Info.plist",
307 | "-sectcreate",
308 | __TEXT,
309 | __launchd_plist,
310 | "SMJobBlessHelper/SMJobBlessHelper-Launchd.plist",
311 | );
312 | PRODUCT_NAME = com.apple.bsd.SMJobBlessHelper;
313 | ZERO_LINK = NO;
314 | };
315 | name = Release;
316 | };
317 | C01FCF4B08A954540054247B /* Debug */ = {
318 | isa = XCBuildConfiguration;
319 | buildSettings = {
320 | ALWAYS_SEARCH_USER_PATHS = NO;
321 | COPY_PHASE_STRIP = NO;
322 | GCC_DYNAMIC_NO_PIC = NO;
323 | GCC_MODEL_TUNING = G5;
324 | GCC_OPTIMIZATION_LEVEL = 0;
325 | INFOPLIST_FILE = "SMJobBlessApp/SMJobBlessApp-Info.plist";
326 | INSTALL_PATH = "$(HOME)/Applications";
327 | PRODUCT_NAME = SMJobBlessApp;
328 | };
329 | name = Debug;
330 | };
331 | C01FCF4C08A954540054247B /* Release */ = {
332 | isa = XCBuildConfiguration;
333 | buildSettings = {
334 | ALWAYS_SEARCH_USER_PATHS = NO;
335 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
336 | GCC_MODEL_TUNING = G5;
337 | INFOPLIST_FILE = "SMJobBlessApp/SMJobBlessApp-Info.plist";
338 | INSTALL_PATH = "$(HOME)/Applications";
339 | PRODUCT_NAME = SMJobBlessApp;
340 | };
341 | name = Release;
342 | };
343 | C01FCF4F08A954540054247B /* Debug */ = {
344 | isa = XCBuildConfiguration;
345 | buildSettings = {
346 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
347 | CODE_SIGN_IDENTITY = "Mac Developer";
348 | GCC_C_LANGUAGE_STANDARD = gnu99;
349 | GCC_OPTIMIZATION_LEVEL = 0;
350 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
351 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
352 | GCC_WARN_UNUSED_VARIABLE = YES;
353 | ONLY_ACTIVE_ARCH = YES;
354 | PROVISIONING_PROFILE = "";
355 | };
356 | name = Debug;
357 | };
358 | C01FCF5008A954540054247B /* Release */ = {
359 | isa = XCBuildConfiguration;
360 | buildSettings = {
361 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
362 | CODE_SIGN_IDENTITY = "Mac Developer";
363 | GCC_C_LANGUAGE_STANDARD = gnu99;
364 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
365 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
366 | GCC_WARN_UNUSED_VARIABLE = YES;
367 | PROVISIONING_PROFILE = "";
368 | };
369 | name = Release;
370 | };
371 | /* End XCBuildConfiguration section */
372 |
373 | /* Begin XCConfigurationList section */
374 | 4BE4906210445E31006BE471 /* Build configuration list for PBXNativeTarget "com.apple.bsd.SMJobBlessHelper" */ = {
375 | isa = XCConfigurationList;
376 | buildConfigurations = (
377 | 4BE4905F10445E0B006BE471 /* Debug */,
378 | 4BE4906010445E0B006BE471 /* Release */,
379 | );
380 | defaultConfigurationIsVisible = 0;
381 | defaultConfigurationName = Release;
382 | };
383 | C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "SMJobBlessApp" */ = {
384 | isa = XCConfigurationList;
385 | buildConfigurations = (
386 | C01FCF4B08A954540054247B /* Debug */,
387 | C01FCF4C08A954540054247B /* Release */,
388 | );
389 | defaultConfigurationIsVisible = 0;
390 | defaultConfigurationName = Release;
391 | };
392 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SMJobBless" */ = {
393 | isa = XCConfigurationList;
394 | buildConfigurations = (
395 | C01FCF4F08A954540054247B /* Debug */,
396 | C01FCF5008A954540054247B /* Release */,
397 | );
398 | defaultConfigurationIsVisible = 0;
399 | defaultConfigurationName = Release;
400 | };
401 | /* End XCConfigurationList section */
402 | };
403 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
404 | }
405 |
--------------------------------------------------------------------------------
/SMJobBlessApp/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1050
5 | 11D50b
6 | 2177
7 | 1138.32
8 | 568.00
9 |
13 |
23 |
27 |
31 |
1154 |
1155 |
1156 | YES
1157 |
1158 |
1159 | delegate
1160 |
1161 |
1162 |
1163 | 455
1164 |
1165 |
1166 |
1167 | orderFrontStandardAboutPanel:
1168 |
1169 |
1170 |
1171 | 142
1172 |
1173 |
1174 |
1175 | terminate:
1176 |
1177 |
1178 |
1179 | 448
1180 |
1181 |
1182 |
1183 | performMiniaturize:
1184 |
1185 |
1186 |
1187 | 37
1188 |
1189 |
1190 |
1191 | arrangeInFront:
1192 |
1193 |
1194 |
1195 | 39
1196 |
1197 |
1198 |
1199 | print:
1200 |
1201 |
1202 |
1203 | 86
1204 |
1205 |
1206 |
1207 | runPageLayout:
1208 |
1209 |
1210 |
1211 | 87
1212 |
1213 |
1214 |
1215 | clearRecentDocuments:
1216 |
1217 |
1218 |
1219 | 127
1220 |
1221 |
1222 |
1223 | performClose:
1224 |
1225 |
1226 |
1227 | 193
1228 |
1229 |
1230 |
1231 | toggleContinuousSpellChecking:
1232 |
1233 |
1234 |
1235 | 222
1236 |
1237 |
1238 |
1239 | undo:
1240 |
1241 |
1242 |
1243 | 223
1244 |
1245 |
1246 |
1247 | copy:
1248 |
1249 |
1250 |
1251 | 224
1252 |
1253 |
1254 |
1255 | checkSpelling:
1256 |
1257 |
1258 |
1259 | 225
1260 |
1261 |
1262 |
1263 | paste:
1264 |
1265 |
1266 |
1267 | 226
1268 |
1269 |
1270 |
1271 | stopSpeaking:
1272 |
1273 |
1274 |
1275 | 227
1276 |
1277 |
1278 |
1279 | cut:
1280 |
1281 |
1282 |
1283 | 228
1284 |
1285 |
1286 |
1287 | showGuessPanel:
1288 |
1289 |
1290 |
1291 | 230
1292 |
1293 |
1294 |
1295 | redo:
1296 |
1297 |
1298 |
1299 | 231
1300 |
1301 |
1302 |
1303 | selectAll:
1304 |
1305 |
1306 |
1307 | 232
1308 |
1309 |
1310 |
1311 | startSpeaking:
1312 |
1313 |
1314 |
1315 | 233
1316 |
1317 |
1318 |
1319 | delete:
1320 |
1321 |
1322 |
1323 | 235
1324 |
1325 |
1326 |
1327 | performZoom:
1328 |
1329 |
1330 |
1331 | 240
1332 |
1333 |
1334 |
1335 | performFindPanelAction:
1336 |
1337 |
1338 |
1339 | 241
1340 |
1341 |
1342 |
1343 | centerSelectionInVisibleArea:
1344 |
1345 |
1346 |
1347 | 245
1348 |
1349 |
1350 |
1351 | toggleGrammarChecking:
1352 |
1353 |
1354 |
1355 | 347
1356 |
1357 |
1358 |
1359 | toggleSmartInsertDelete:
1360 |
1361 |
1362 |
1363 | 355
1364 |
1365 |
1366 |
1367 | toggleAutomaticQuoteSubstitution:
1368 |
1369 |
1370 |
1371 | 356
1372 |
1373 |
1374 |
1375 | toggleAutomaticLinkDetection:
1376 |
1377 |
1378 |
1379 | 357
1380 |
1381 |
1382 |
1383 | showHelp:
1384 |
1385 |
1386 |
1387 | 360
1388 |
1389 |
1390 |
1391 | saveDocument:
1392 |
1393 |
1394 |
1395 | 362
1396 |
1397 |
1398 |
1399 | saveDocumentAs:
1400 |
1401 |
1402 |
1403 | 363
1404 |
1405 |
1406 |
1407 | revertDocumentToSaved:
1408 |
1409 |
1410 |
1411 | 364
1412 |
1413 |
1414 |
1415 | runToolbarCustomizationPalette:
1416 |
1417 |
1418 |
1419 | 365
1420 |
1421 |
1422 |
1423 | toggleToolbarShown:
1424 |
1425 |
1426 |
1427 | 366
1428 |
1429 |
1430 |
1431 | hide:
1432 |
1433 |
1434 |
1435 | 369
1436 |
1437 |
1438 |
1439 | hideOtherApplications:
1440 |
1441 |
1442 |
1443 | 370
1444 |
1445 |
1446 |
1447 | unhideAllApplications:
1448 |
1449 |
1450 |
1451 | 372
1452 |
1453 |
1454 |
1455 | raiseBaseline:
1456 |
1457 |
1458 |
1459 | 425
1460 |
1461 |
1462 |
1463 | lowerBaseline:
1464 |
1465 |
1466 |
1467 | 426
1468 |
1469 |
1470 |
1471 | copyFont:
1472 |
1473 |
1474 |
1475 | 427
1476 |
1477 |
1478 |
1479 | subscript:
1480 |
1481 |
1482 |
1483 | 428
1484 |
1485 |
1486 |
1487 | superscript:
1488 |
1489 |
1490 |
1491 | 429
1492 |
1493 |
1494 |
1495 | tightenKerning:
1496 |
1497 |
1498 |
1499 | 430
1500 |
1501 |
1502 |
1503 | underline:
1504 |
1505 |
1506 |
1507 | 431
1508 |
1509 |
1510 |
1511 | orderFrontColorPanel:
1512 |
1513 |
1514 |
1515 | 432
1516 |
1517 |
1518 |
1519 | useAllLigatures:
1520 |
1521 |
1522 |
1523 | 433
1524 |
1525 |
1526 |
1527 | loosenKerning:
1528 |
1529 |
1530 |
1531 | 434
1532 |
1533 |
1534 |
1535 | pasteFont:
1536 |
1537 |
1538 |
1539 | 435
1540 |
1541 |
1542 |
1543 | unscript:
1544 |
1545 |
1546 |
1547 | 436
1548 |
1549 |
1550 |
1551 | useStandardKerning:
1552 |
1553 |
1554 |
1555 | 437
1556 |
1557 |
1558 |
1559 | useStandardLigatures:
1560 |
1561 |
1562 |
1563 | 438
1564 |
1565 |
1566 |
1567 | turnOffLigatures:
1568 |
1569 |
1570 |
1571 | 439
1572 |
1573 |
1574 |
1575 | turnOffKerning:
1576 |
1577 |
1578 |
1579 | 440
1580 |
1581 |
1582 |
1583 | alignLeft:
1584 |
1585 |
1586 |
1587 | 441
1588 |
1589 |
1590 |
1591 | alignJustified:
1592 |
1593 |
1594 |
1595 | 442
1596 |
1597 |
1598 |
1599 | copyRuler:
1600 |
1601 |
1602 |
1603 | 443
1604 |
1605 |
1606 |
1607 | alignCenter:
1608 |
1609 |
1610 |
1611 | 444
1612 |
1613 |
1614 |
1615 | toggleRuler:
1616 |
1617 |
1618 |
1619 | 445
1620 |
1621 |
1622 |
1623 | alignRight:
1624 |
1625 |
1626 |
1627 | 446
1628 |
1629 |
1630 |
1631 | pasteRuler:
1632 |
1633 |
1634 |
1635 | 447
1636 |
1637 |
1638 |
1639 | addFontTrait:
1640 |
1641 |
1642 |
1643 | 420
1644 |
1645 |
1646 |
1647 | addFontTrait:
1648 |
1649 |
1650 |
1651 | 421
1652 |
1653 |
1654 |
1655 | modifyFont:
1656 |
1657 |
1658 |
1659 | 422
1660 |
1661 |
1662 |
1663 | orderFrontFontPanel:
1664 |
1665 |
1666 |
1667 | 423
1668 |
1669 |
1670 |
1671 | modifyFont:
1672 |
1673 |
1674 |
1675 | 424
1676 |
1677 |
1678 |
1679 | textField
1680 |
1681 |
1682 |
1683 | 461
1684 |
1685 |
1686 |
1687 |
1688 | YES
1689 |
1690 | 0
1691 |
1692 | YES
1693 |
1694 |
1695 |
1696 |
1697 |
1698 | -2
1699 |
1700 |
1701 | File's Owner
1702 |
1703 |
1704 | -1
1705 |
1706 |
1707 | First Responder
1708 |
1709 |
1710 | -3
1711 |
1712 |
1713 | Application
1714 |
1715 |
1716 | 29
1717 |
1718 |
1719 | YES
1720 |
1721 |
1722 |
1723 |
1724 |
1725 |
1726 |
1727 |
1728 |
1729 | Main Menu
1730 |
1731 |
1732 | 19
1733 |
1734 |
1735 | YES
1736 |
1737 |
1738 |
1739 |
1740 |
1741 | 56
1742 |
1743 |
1744 | YES
1745 |
1746 |
1747 |
1748 |
1749 |
1750 | 103
1751 |
1752 |
1753 | YES
1754 |
1755 |
1756 |
1757 |
1758 |
1759 | 217
1760 |
1761 |
1762 | YES
1763 |
1764 |
1765 |
1766 |
1767 |
1768 | 83
1769 |
1770 |
1771 | YES
1772 |
1773 |
1774 |
1775 |
1776 |
1777 | 81
1778 |
1779 |
1780 | YES
1781 |
1782 |
1783 |
1784 |
1785 |
1786 |
1787 |
1788 |
1789 |
1790 |
1791 |
1792 |
1793 |
1794 |
1795 |
1796 | 75
1797 |
1798 |
1799 |
1800 |
1801 | 80
1802 |
1803 |
1804 |
1805 |
1806 | 78
1807 |
1808 |
1809 |
1810 |
1811 | 72
1812 |
1813 |
1814 |
1815 |
1816 | 82
1817 |
1818 |
1819 |
1820 |
1821 | 124
1822 |
1823 |
1824 | YES
1825 |
1826 |
1827 |
1828 |
1829 |
1830 | 77
1831 |
1832 |
1833 |
1834 |
1835 | 73
1836 |
1837 |
1838 |
1839 |
1840 | 79
1841 |
1842 |
1843 |
1844 |
1845 | 112
1846 |
1847 |
1848 |
1849 |
1850 | 74
1851 |
1852 |
1853 |
1854 |
1855 | 125
1856 |
1857 |
1858 | YES
1859 |
1860 |
1861 |
1862 |
1863 |
1864 | 126
1865 |
1866 |
1867 |
1868 |
1869 | 205
1870 |
1871 |
1872 | YES
1873 |
1874 |
1875 |
1876 |
1877 |
1878 |
1879 |
1880 |
1881 |
1882 |
1883 |
1884 |
1885 |
1886 |
1887 |
1888 |
1889 |
1890 | 202
1891 |
1892 |
1893 |
1894 |
1895 | 198
1896 |
1897 |
1898 |
1899 |
1900 | 207
1901 |
1902 |
1903 |
1904 |
1905 | 214
1906 |
1907 |
1908 |
1909 |
1910 | 199
1911 |
1912 |
1913 |
1914 |
1915 | 203
1916 |
1917 |
1918 |
1919 |
1920 | 197
1921 |
1922 |
1923 |
1924 |
1925 | 206
1926 |
1927 |
1928 |
1929 |
1930 | 215
1931 |
1932 |
1933 |
1934 |
1935 | 218
1936 |
1937 |
1938 | YES
1939 |
1940 |
1941 |
1942 |
1943 |
1944 | 216
1945 |
1946 |
1947 | YES
1948 |
1949 |
1950 |
1951 |
1952 |
1953 | 200
1954 |
1955 |
1956 | YES
1957 |
1958 |
1959 |
1960 |
1961 |
1962 |
1963 |
1964 |
1965 | 219
1966 |
1967 |
1968 |
1969 |
1970 | 201
1971 |
1972 |
1973 |
1974 |
1975 | 204
1976 |
1977 |
1978 |
1979 |
1980 | 220
1981 |
1982 |
1983 | YES
1984 |
1985 |
1986 |
1987 |
1988 |
1989 |
1990 |
1991 |
1992 |
1993 | 213
1994 |
1995 |
1996 |
1997 |
1998 | 210
1999 |
2000 |
2001 |
2002 |
2003 | 221
2004 |
2005 |
2006 |
2007 |
2008 | 208
2009 |
2010 |
2011 |
2012 |
2013 | 209
2014 |
2015 |
2016 |
2017 |
2018 | 106
2019 |
2020 |
2021 | YES
2022 |
2023 |
2024 |
2025 |
2026 |
2027 | 111
2028 |
2029 |
2030 |
2031 |
2032 | 57
2033 |
2034 |
2035 | YES
2036 |
2037 |
2038 |
2039 |
2040 |
2041 |
2042 |
2043 |
2044 |
2045 |
2046 |
2047 |
2048 |
2049 |
2050 |
2051 | 58
2052 |
2053 |
2054 |
2055 |
2056 | 134
2057 |
2058 |
2059 |
2060 |
2061 | 150
2062 |
2063 |
2064 |
2065 |
2066 | 136
2067 |
2068 |
2069 |
2070 |
2071 | 144
2072 |
2073 |
2074 |
2075 |
2076 | 129
2077 |
2078 |
2079 |
2080 |
2081 | 143
2082 |
2083 |
2084 |
2085 |
2086 | 236
2087 |
2088 |
2089 |
2090 |
2091 | 131
2092 |
2093 |
2094 | YES
2095 |
2096 |
2097 |
2098 |
2099 |
2100 | 149
2101 |
2102 |
2103 |
2104 |
2105 | 145
2106 |
2107 |
2108 |
2109 |
2110 | 130
2111 |
2112 |
2113 |
2114 |
2115 | 24
2116 |
2117 |
2118 | YES
2119 |
2120 |
2121 |
2122 |
2123 |
2124 |
2125 |
2126 |
2127 | 92
2128 |
2129 |
2130 |
2131 |
2132 | 5
2133 |
2134 |
2135 |
2136 |
2137 | 239
2138 |
2139 |
2140 |
2141 |
2142 | 23
2143 |
2144 |
2145 |
2146 |
2147 | 295
2148 |
2149 |
2150 | YES
2151 |
2152 |
2153 |
2154 |
2155 |
2156 | 296
2157 |
2158 |
2159 | YES
2160 |
2161 |
2162 |
2163 |
2164 |
2165 |
2166 | 297
2167 |
2168 |
2169 |
2170 |
2171 | 298
2172 |
2173 |
2174 |
2175 |
2176 | 211
2177 |
2178 |
2179 | YES
2180 |
2181 |
2182 |
2183 |
2184 |
2185 | 212
2186 |
2187 |
2188 | YES
2189 |
2190 |
2191 |
2192 |
2193 |
2194 |
2195 | 195
2196 |
2197 |
2198 |
2199 |
2200 | 196
2201 |
2202 |
2203 |
2204 |
2205 | 346
2206 |
2207 |
2208 |
2209 |
2210 | 348
2211 |
2212 |
2213 | YES
2214 |
2215 |
2216 |
2217 |
2218 |
2219 | 349
2220 |
2221 |
2222 | YES
2223 |
2224 |
2225 |
2226 |
2227 |
2228 |
2229 |
2230 | 350
2231 |
2232 |
2233 |
2234 |
2235 | 351
2236 |
2237 |
2238 |
2239 |
2240 | 354
2241 |
2242 |
2243 |
2244 |
2245 | 367
2246 |
2247 |
2248 | YES
2249 |
2250 |
2251 |
2252 |
2253 |
2254 | 368
2255 |
2256 |
2257 | YES
2258 |
2259 |
2260 |
2261 |
2262 |
2263 | 373
2264 |
2265 |
2266 |
2267 |
2268 | 375
2269 |
2270 |
2271 | YES
2272 |
2273 |
2274 |
2275 |
2276 |
2277 | 376
2278 |
2279 |
2280 | YES
2281 |
2282 |
2283 |
2284 |
2285 |
2286 |
2287 | 377
2288 |
2289 |
2290 | YES
2291 |
2292 |
2293 |
2294 |
2295 |
2296 | 378
2297 |
2298 |
2299 | YES
2300 |
2301 |
2302 |
2303 |
2304 |
2305 | 379
2306 |
2307 |
2308 | YES
2309 |
2310 |
2311 |
2312 |
2313 |
2314 |
2315 |
2316 |
2317 |
2318 |
2319 |
2320 |
2321 | 380
2322 |
2323 |
2324 |
2325 |
2326 | 381
2327 |
2328 |
2329 |
2330 |
2331 | 382
2332 |
2333 |
2334 |
2335 |
2336 | 383
2337 |
2338 |
2339 |
2340 |
2341 | 384
2342 |
2343 |
2344 |
2345 |
2346 | 385
2347 |
2348 |
2349 |
2350 |
2351 | 386
2352 |
2353 |
2354 |
2355 |
2356 | 387
2357 |
2358 |
2359 |
2360 |
2361 | 388
2362 |
2363 |
2364 | YES
2365 |
2366 |
2367 |
2368 |
2369 |
2370 |
2371 |
2372 |
2373 |
2374 |
2375 |
2376 |
2377 |
2378 |
2379 |
2380 |
2381 |
2382 |
2383 |
2384 |
2385 | 389
2386 |
2387 |
2388 |
2389 |
2390 | 390
2391 |
2392 |
2393 |
2394 |
2395 | 391
2396 |
2397 |
2398 |
2399 |
2400 | 392
2401 |
2402 |
2403 |
2404 |
2405 | 393
2406 |
2407 |
2408 |
2409 |
2410 | 394
2411 |
2412 |
2413 |
2414 |
2415 | 395
2416 |
2417 |
2418 |
2419 |
2420 | 396
2421 |
2422 |
2423 |
2424 |
2425 | 397
2426 |
2427 |
2428 | YES
2429 |
2430 |
2431 |
2432 |
2433 |
2434 | 398
2435 |
2436 |
2437 | YES
2438 |
2439 |
2440 |
2441 |
2442 |
2443 | 399
2444 |
2445 |
2446 | YES
2447 |
2448 |
2449 |
2450 |
2451 |
2452 | 400
2453 |
2454 |
2455 |
2456 |
2457 | 401
2458 |
2459 |
2460 |
2461 |
2462 | 402
2463 |
2464 |
2465 |
2466 |
2467 | 403
2468 |
2469 |
2470 |
2471 |
2472 | 404
2473 |
2474 |
2475 |
2476 |
2477 | 405
2478 |
2479 |
2480 | YES
2481 |
2482 |
2483 |
2484 |
2485 |
2486 |
2487 |
2488 |
2489 |
2490 | 406
2491 |
2492 |
2493 |
2494 |
2495 | 407
2496 |
2497 |
2498 |
2499 |
2500 | 408
2501 |
2502 |
2503 |
2504 |
2505 | 409
2506 |
2507 |
2508 |
2509 |
2510 | 410
2511 |
2512 |
2513 |
2514 |
2515 | 411
2516 |
2517 |
2518 | YES
2519 |
2520 |
2521 |
2522 |
2523 |
2524 |
2525 |
2526 | 412
2527 |
2528 |
2529 |
2530 |
2531 | 413
2532 |
2533 |
2534 |
2535 |
2536 | 414
2537 |
2538 |
2539 |
2540 |
2541 | 415
2542 |
2543 |
2544 | YES
2545 |
2546 |
2547 |
2548 |
2549 |
2550 |
2551 |
2552 |
2553 | 416
2554 |
2555 |
2556 |
2557 |
2558 | 417
2559 |
2560 |
2561 |
2562 |
2563 | 418
2564 |
2565 |
2566 |
2567 |
2568 | 419
2569 |
2570 |
2571 |
2572 |
2573 | 449
2574 |
2575 |
2576 |
2577 |
2578 | 458
2579 |
2580 |
2581 | YES
2582 |
2583 |
2584 |
2585 |
2586 |
2587 | 459
2588 |
2589 |
2590 |
2591 |
2592 |
2593 |
2594 | YES
2595 |
2596 | YES
2597 | -1.IBPluginDependency
2598 | -2.IBPluginDependency
2599 | -3.IBPluginDependency
2600 | 103.IBPluginDependency
2601 | 106.IBPluginDependency
2602 | 111.IBPluginDependency
2603 | 112.IBPluginDependency
2604 | 124.IBPluginDependency
2605 | 125.IBPluginDependency
2606 | 126.IBPluginDependency
2607 | 129.IBPluginDependency
2608 | 130.IBPluginDependency
2609 | 131.IBPluginDependency
2610 | 134.IBPluginDependency
2611 | 136.IBPluginDependency
2612 | 143.IBPluginDependency
2613 | 144.IBPluginDependency
2614 | 145.IBPluginDependency
2615 | 149.IBPluginDependency
2616 | 150.IBPluginDependency
2617 | 19.IBPluginDependency
2618 | 195.IBPluginDependency
2619 | 196.IBPluginDependency
2620 | 197.IBPluginDependency
2621 | 198.IBPluginDependency
2622 | 199.IBPluginDependency
2623 | 200.IBPluginDependency
2624 | 201.IBPluginDependency
2625 | 202.IBPluginDependency
2626 | 203.IBPluginDependency
2627 | 204.IBPluginDependency
2628 | 205.IBPluginDependency
2629 | 206.IBPluginDependency
2630 | 207.IBPluginDependency
2631 | 208.IBPluginDependency
2632 | 209.IBPluginDependency
2633 | 210.IBPluginDependency
2634 | 211.IBPluginDependency
2635 | 212.IBPluginDependency
2636 | 213.IBPluginDependency
2637 | 214.IBPluginDependency
2638 | 215.IBPluginDependency
2639 | 216.IBPluginDependency
2640 | 217.IBPluginDependency
2641 | 218.IBPluginDependency
2642 | 219.IBPluginDependency
2643 | 220.IBPluginDependency
2644 | 221.IBPluginDependency
2645 | 23.IBPluginDependency
2646 | 236.IBPluginDependency
2647 | 239.IBPluginDependency
2648 | 24.IBPluginDependency
2649 | 29.IBPluginDependency
2650 | 295.IBPluginDependency
2651 | 296.IBPluginDependency
2652 | 297.IBPluginDependency
2653 | 298.IBPluginDependency
2654 | 346.IBPluginDependency
2655 | 348.IBPluginDependency
2656 | 349.IBPluginDependency
2657 | 350.IBPluginDependency
2658 | 351.IBPluginDependency
2659 | 354.IBPluginDependency
2660 | 367.IBPluginDependency
2661 | 367.IBWindowTemplateEditedContentRect
2662 | 367.NSWindowTemplate.visibleAtLaunch
2663 | 368.IBPluginDependency
2664 | 373.IBPluginDependency
2665 | 375.IBPluginDependency
2666 | 376.IBPluginDependency
2667 | 377.IBPluginDependency
2668 | 378.IBPluginDependency
2669 | 379.IBPluginDependency
2670 | 380.IBPluginDependency
2671 | 381.IBPluginDependency
2672 | 382.IBPluginDependency
2673 | 383.IBPluginDependency
2674 | 384.IBPluginDependency
2675 | 385.IBPluginDependency
2676 | 386.IBPluginDependency
2677 | 387.IBPluginDependency
2678 | 388.IBPluginDependency
2679 | 389.IBPluginDependency
2680 | 390.IBPluginDependency
2681 | 391.IBPluginDependency
2682 | 392.IBPluginDependency
2683 | 393.IBPluginDependency
2684 | 394.IBPluginDependency
2685 | 395.IBPluginDependency
2686 | 396.IBPluginDependency
2687 | 397.IBPluginDependency
2688 | 398.IBPluginDependency
2689 | 399.IBPluginDependency
2690 | 400.IBPluginDependency
2691 | 401.IBPluginDependency
2692 | 402.IBPluginDependency
2693 | 403.IBPluginDependency
2694 | 404.IBPluginDependency
2695 | 405.IBPluginDependency
2696 | 406.IBPluginDependency
2697 | 407.IBPluginDependency
2698 | 408.IBPluginDependency
2699 | 409.IBPluginDependency
2700 | 410.IBPluginDependency
2701 | 411.IBPluginDependency
2702 | 412.IBPluginDependency
2703 | 413.IBPluginDependency
2704 | 414.IBPluginDependency
2705 | 415.IBPluginDependency
2706 | 416.IBPluginDependency
2707 | 417.IBPluginDependency
2708 | 418.IBPluginDependency
2709 | 419.IBPluginDependency
2710 | 449.IBPluginDependency
2711 | 458.IBPluginDependency
2712 | 459.IBPluginDependency
2713 | 5.IBPluginDependency
2714 | 56.IBPluginDependency
2715 | 57.IBPluginDependency
2716 | 58.IBPluginDependency
2717 | 72.IBPluginDependency
2718 | 73.IBPluginDependency
2719 | 74.IBPluginDependency
2720 | 75.IBPluginDependency
2721 | 77.IBPluginDependency
2722 | 78.IBPluginDependency
2723 | 79.IBPluginDependency
2724 | 80.IBPluginDependency
2725 | 81.IBPluginDependency
2726 | 82.IBPluginDependency
2727 | 83.IBPluginDependency
2728 | 92.IBPluginDependency
2729 |
2730 |
2731 | YES
2732 | com.apple.InterfaceBuilder.CocoaPlugin
2733 | com.apple.InterfaceBuilder.CocoaPlugin
2734 | com.apple.InterfaceBuilder.CocoaPlugin
2735 | com.apple.InterfaceBuilder.CocoaPlugin
2736 | com.apple.InterfaceBuilder.CocoaPlugin
2737 | com.apple.InterfaceBuilder.CocoaPlugin
2738 | com.apple.InterfaceBuilder.CocoaPlugin
2739 | com.apple.InterfaceBuilder.CocoaPlugin
2740 | com.apple.InterfaceBuilder.CocoaPlugin
2741 | com.apple.InterfaceBuilder.CocoaPlugin
2742 | com.apple.InterfaceBuilder.CocoaPlugin
2743 | com.apple.InterfaceBuilder.CocoaPlugin
2744 | com.apple.InterfaceBuilder.CocoaPlugin
2745 | com.apple.InterfaceBuilder.CocoaPlugin
2746 | com.apple.InterfaceBuilder.CocoaPlugin
2747 | com.apple.InterfaceBuilder.CocoaPlugin
2748 | com.apple.InterfaceBuilder.CocoaPlugin
2749 | com.apple.InterfaceBuilder.CocoaPlugin
2750 | com.apple.InterfaceBuilder.CocoaPlugin
2751 | com.apple.InterfaceBuilder.CocoaPlugin
2752 | com.apple.InterfaceBuilder.CocoaPlugin
2753 | com.apple.InterfaceBuilder.CocoaPlugin
2754 | com.apple.InterfaceBuilder.CocoaPlugin
2755 | com.apple.InterfaceBuilder.CocoaPlugin
2756 | com.apple.InterfaceBuilder.CocoaPlugin
2757 | com.apple.InterfaceBuilder.CocoaPlugin
2758 | com.apple.InterfaceBuilder.CocoaPlugin
2759 | com.apple.InterfaceBuilder.CocoaPlugin
2760 | com.apple.InterfaceBuilder.CocoaPlugin
2761 | com.apple.InterfaceBuilder.CocoaPlugin
2762 | com.apple.InterfaceBuilder.CocoaPlugin
2763 | com.apple.InterfaceBuilder.CocoaPlugin
2764 | com.apple.InterfaceBuilder.CocoaPlugin
2765 | com.apple.InterfaceBuilder.CocoaPlugin
2766 | com.apple.InterfaceBuilder.CocoaPlugin
2767 | com.apple.InterfaceBuilder.CocoaPlugin
2768 | com.apple.InterfaceBuilder.CocoaPlugin
2769 | com.apple.InterfaceBuilder.CocoaPlugin
2770 | com.apple.InterfaceBuilder.CocoaPlugin
2771 | com.apple.InterfaceBuilder.CocoaPlugin
2772 | com.apple.InterfaceBuilder.CocoaPlugin
2773 | com.apple.InterfaceBuilder.CocoaPlugin
2774 | com.apple.InterfaceBuilder.CocoaPlugin
2775 | com.apple.InterfaceBuilder.CocoaPlugin
2776 | com.apple.InterfaceBuilder.CocoaPlugin
2777 | com.apple.InterfaceBuilder.CocoaPlugin
2778 | com.apple.InterfaceBuilder.CocoaPlugin
2779 | com.apple.InterfaceBuilder.CocoaPlugin
2780 | com.apple.InterfaceBuilder.CocoaPlugin
2781 | com.apple.InterfaceBuilder.CocoaPlugin
2782 | com.apple.InterfaceBuilder.CocoaPlugin
2783 | com.apple.InterfaceBuilder.CocoaPlugin
2784 | com.apple.InterfaceBuilder.CocoaPlugin
2785 | com.apple.InterfaceBuilder.CocoaPlugin
2786 | com.apple.InterfaceBuilder.CocoaPlugin
2787 | com.apple.InterfaceBuilder.CocoaPlugin
2788 | com.apple.InterfaceBuilder.CocoaPlugin
2789 | com.apple.InterfaceBuilder.CocoaPlugin
2790 | com.apple.InterfaceBuilder.CocoaPlugin
2791 | com.apple.InterfaceBuilder.CocoaPlugin
2792 | com.apple.InterfaceBuilder.CocoaPlugin
2793 | com.apple.InterfaceBuilder.CocoaPlugin
2794 | com.apple.InterfaceBuilder.CocoaPlugin
2795 | com.apple.InterfaceBuilder.CocoaPlugin
2796 | {{478, 446}, {480, 270}}
2797 |
2798 | com.apple.InterfaceBuilder.CocoaPlugin
2799 | com.apple.InterfaceBuilder.CocoaPlugin
2800 | com.apple.InterfaceBuilder.CocoaPlugin
2801 | com.apple.InterfaceBuilder.CocoaPlugin
2802 | com.apple.InterfaceBuilder.CocoaPlugin
2803 | com.apple.InterfaceBuilder.CocoaPlugin
2804 | com.apple.InterfaceBuilder.CocoaPlugin
2805 | com.apple.InterfaceBuilder.CocoaPlugin
2806 | com.apple.InterfaceBuilder.CocoaPlugin
2807 | com.apple.InterfaceBuilder.CocoaPlugin
2808 | com.apple.InterfaceBuilder.CocoaPlugin
2809 | com.apple.InterfaceBuilder.CocoaPlugin
2810 | com.apple.InterfaceBuilder.CocoaPlugin
2811 | com.apple.InterfaceBuilder.CocoaPlugin
2812 | com.apple.InterfaceBuilder.CocoaPlugin
2813 | com.apple.InterfaceBuilder.CocoaPlugin
2814 | com.apple.InterfaceBuilder.CocoaPlugin
2815 | com.apple.InterfaceBuilder.CocoaPlugin
2816 | com.apple.InterfaceBuilder.CocoaPlugin
2817 | com.apple.InterfaceBuilder.CocoaPlugin
2818 | com.apple.InterfaceBuilder.CocoaPlugin
2819 | com.apple.InterfaceBuilder.CocoaPlugin
2820 | com.apple.InterfaceBuilder.CocoaPlugin
2821 | com.apple.InterfaceBuilder.CocoaPlugin
2822 | com.apple.InterfaceBuilder.CocoaPlugin
2823 | com.apple.InterfaceBuilder.CocoaPlugin
2824 | com.apple.InterfaceBuilder.CocoaPlugin
2825 | com.apple.InterfaceBuilder.CocoaPlugin
2826 | com.apple.InterfaceBuilder.CocoaPlugin
2827 | com.apple.InterfaceBuilder.CocoaPlugin
2828 | com.apple.InterfaceBuilder.CocoaPlugin
2829 | com.apple.InterfaceBuilder.CocoaPlugin
2830 | com.apple.InterfaceBuilder.CocoaPlugin
2831 | com.apple.InterfaceBuilder.CocoaPlugin
2832 | com.apple.InterfaceBuilder.CocoaPlugin
2833 | com.apple.InterfaceBuilder.CocoaPlugin
2834 | com.apple.InterfaceBuilder.CocoaPlugin
2835 | com.apple.InterfaceBuilder.CocoaPlugin
2836 | com.apple.InterfaceBuilder.CocoaPlugin
2837 | com.apple.InterfaceBuilder.CocoaPlugin
2838 | com.apple.InterfaceBuilder.CocoaPlugin
2839 | com.apple.InterfaceBuilder.CocoaPlugin
2840 | com.apple.InterfaceBuilder.CocoaPlugin
2841 | com.apple.InterfaceBuilder.CocoaPlugin
2842 | com.apple.InterfaceBuilder.CocoaPlugin
2843 | com.apple.InterfaceBuilder.CocoaPlugin
2844 | com.apple.InterfaceBuilder.CocoaPlugin
2845 | com.apple.InterfaceBuilder.CocoaPlugin
2846 | com.apple.InterfaceBuilder.CocoaPlugin
2847 | com.apple.InterfaceBuilder.CocoaPlugin
2848 | com.apple.InterfaceBuilder.CocoaPlugin
2849 | com.apple.InterfaceBuilder.CocoaPlugin
2850 | com.apple.InterfaceBuilder.CocoaPlugin
2851 | com.apple.InterfaceBuilder.CocoaPlugin
2852 | com.apple.InterfaceBuilder.CocoaPlugin
2853 | com.apple.InterfaceBuilder.CocoaPlugin
2854 | com.apple.InterfaceBuilder.CocoaPlugin
2855 | com.apple.InterfaceBuilder.CocoaPlugin
2856 | com.apple.InterfaceBuilder.CocoaPlugin
2857 | com.apple.InterfaceBuilder.CocoaPlugin
2858 | com.apple.InterfaceBuilder.CocoaPlugin
2859 | com.apple.InterfaceBuilder.CocoaPlugin
2860 | com.apple.InterfaceBuilder.CocoaPlugin
2861 | com.apple.InterfaceBuilder.CocoaPlugin
2862 | com.apple.InterfaceBuilder.CocoaPlugin
2863 | com.apple.InterfaceBuilder.CocoaPlugin
2864 |
2865 |
2866 |
2867 | YES
2868 |
2869 |
2870 |
2871 |
2872 |
2873 | YES
2874 |
2875 |
2876 |
2877 |
2878 | 461
2879 |
2880 |
2881 |
2882 | YES
2883 |
2884 | SMJobBlessAppController
2885 | NSObject
2886 |
2887 | textField
2888 | NSTextField
2889 |
2890 |
2891 | textField
2892 |
2893 | textField
2894 | NSTextField
2895 |
2896 |
2897 |
2898 | IBProjectSource
2899 | ./Classes/SMJobBlessAppController.h
2900 |
2901 |
2902 |
2903 |
2904 | 0
2905 | IBCocoaFramework
2906 |
2907 | com.apple.InterfaceBuilder.CocoaPlugin.macosx
2908 |
2909 |
2910 |
2911 | com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3
2912 |
2913 |
2914 | YES
2915 | 3
2916 |
2917 | YES
2918 |
2919 | YES
2920 | NSMenuCheckmark
2921 | NSMenuMixedState
2922 |
2923 |
2924 | YES
2925 | {11, 11}
2926 | {10, 3}
2927 |
2928 |
2929 |
2930 |
2931 |
--------------------------------------------------------------------------------