1/* 2 * Copyright (c) 2007-2009,2013-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25 26#include <stdio.h> 27#include <CoreFoundation/CoreFoundation.h> 28#include <Security/SecTask.h> 29#include <Security/SecEntitlements.h> 30#include <AssertMacros.h> 31#include <TargetConditionals.h> 32#include <sys/sysctl.h> 33 34#include "utilities/SecCFRelease.h" 35 36#include "sectask_regressions.h" 37 38/* IPC stuff: 39 40 This is a hack to get our own audittoken: 41 We send a simple request with no argument to our mach port. 42 The mach port callback copy the audittoken to a global. 43 */ 44 45#include <mach/mach.h> 46#include <mach/message.h> 47#include "sectask_ipc.h" 48 49static audit_token_t g_self_audittoken = {{0}}; 50 51kern_return_t sectask_server_request(mach_port_t receiver, 52 audit_token_t auditToken); 53kern_return_t sectask_server_request(mach_port_t receiver, 54 audit_token_t auditToken) 55{ 56 memcpy(&g_self_audittoken, &auditToken, sizeof(g_self_audittoken)); 57 58 CFRunLoopStop(CFRunLoopGetCurrent()); 59 60 return 0; 61} 62 63extern boolean_t sectask_ipc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); 64 65union max_msg_size_union { 66 union __RequestUnion__sectask_client_sectask_ipc_subsystem reply; 67}; 68 69static uint8_t reply_buffer[sizeof(union max_msg_size_union) + MAX_TRAILER_SIZE]; 70 71static void server_callback(CFMachPortRef port, void *msg, CFIndex size, void *info) 72{ 73 mach_msg_header_t *message = (mach_msg_header_t *)msg; 74 mach_msg_header_t *reply = (mach_msg_header_t *)reply_buffer; 75 76 sectask_ipc_server(message, reply); 77 78} 79 80static 81void init_self_audittoken(void) 82{ 83 /* create a mach port and an event source */ 84 CFMachPortRef server_port = CFMachPortCreate (NULL, server_callback, NULL, false); 85 CFRunLoopSourceRef server_source = CFMachPortCreateRunLoopSource(NULL, server_port, 0/*order*/); 86 87 /* add the source to the current run loop */ 88 CFRunLoopAddSource(CFRunLoopGetCurrent(), server_source, kCFRunLoopDefaultMode); 89 CFRelease(server_source); 90 91 /* Send the request */ 92 sectask_client_request(CFMachPortGetPort(server_port)); 93 94 /* Run the loop to process the message */ 95 CFRunLoopRun(); 96 97 /* done */ 98 CFRelease(server_port); 99 100} 101 102static 103CFStringRef copyProcName(pid_t pid) { 104 const char *task_name; 105 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; 106 struct kinfo_proc kp; 107 size_t len = sizeof(kp); 108 if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1 || len == 0) 109 task_name = strerror(errno); 110 else 111 task_name = kp.kp_proc.p_comm; 112 return CFStringCreateWithCString(kCFAllocatorDefault, task_name, kCFStringEncodingASCII); 113} 114 115/* Actual test code */ 116 117int sectask_10_sectask_self(int argc, char *const *argv) 118{ 119 SecTaskRef task=NULL; 120 CFStringRef appId=NULL; 121 CFStringRef signingIdentifier=NULL; 122 plan_tests(6); 123 124 ok(task=SecTaskCreateFromSelf(kCFAllocatorDefault), "SecTaskCreateFromSelf"); 125 require(task, out); 126 127 /* TODO: remove the todo once xcode signs simulator binaries */ 128SKIP: { 129#if TARGET_IPHONE_SIMULATOR 130 todo("no entitlements in the simulator binaries yet, until <rdar://problem/12194625>"); 131#endif 132 ok(appId=SecTaskCopyValueForEntitlement(task, kSecEntitlementApplicationIdentifier, NULL), "SecTaskCopyValueForEntitlement"); 133 skip("appId is NULL", 1, appId); 134 ok(CFEqual(appId, CFSTR("com.apple.security.regressions")), "Application Identifier match"); 135 136 ok(signingIdentifier=SecTaskCopySigningIdentifier(task, NULL), "SecTaskCopySigningIdentifier"); 137 ok(CFEqual(signingIdentifier, CFBundleGetIdentifier(CFBundleGetMainBundle())), "CodeSigning Identifier match"); 138 } 139 140 pid_t pid = getpid(); 141 CFStringRef name = copyProcName(pid); 142 CFStringRef expected = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@[%d]"), name, pid); 143 CFStringRef desc = CFCopyDescription(task); 144 ok(CFEqual(desc, expected), "task-description expected: %@ got: %@", expected, desc); 145 CFReleaseSafe(name); 146 CFReleaseSafe(desc); 147 CFReleaseSafe(expected); 148 149out: 150 CFReleaseSafe(task); 151 CFReleaseSafe(appId); 152 CFReleaseSafe(signingIdentifier); 153 154 return 0; 155} 156 157int sectask_11_sectask_audittoken(int argc, char *const *argv) 158{ 159 SecTaskRef task=NULL; 160 CFStringRef appId=NULL; 161 CFStringRef signingIdentifier=NULL; 162 163 plan_tests(6); 164 165 init_self_audittoken(); 166 167 ok(task=SecTaskCreateWithAuditToken(kCFAllocatorDefault, g_self_audittoken), "SecTaskCreateFromAuditToken"); 168 require(task, out); 169 170 /* TODO: remove the todo once xcode signs simulator binaries */ 171SKIP: { 172#if TARGET_IPHONE_SIMULATOR 173 todo("no entitlements in the simulator binaries yet, until <rdar://problem/12194625>"); 174#endif 175 ok(appId=SecTaskCopyValueForEntitlement(task, kSecEntitlementApplicationIdentifier, NULL), "SecTaskCopyValueForEntitlement"); 176 skip("appId is NULL", 1, appId); 177 ok(CFEqual(appId, CFSTR("com.apple.security.regressions")), "Application Identifier match"); 178 ok(signingIdentifier=SecTaskCopySigningIdentifier(task, NULL), "SecTaskCopySigningIdentifier"); 179 ok(CFEqual(signingIdentifier, CFBundleGetIdentifier(CFBundleGetMainBundle())), "CodeSigning Identifier match"); 180} 181 182 pid_t pid = getpid(); 183 CFStringRef name = copyProcName(pid); 184 CFStringRef expected = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@[%d]"), name, pid); 185 CFStringRef desc = CFCopyDescription(task); 186 ok(CFEqual(desc, expected), "task-description expected: %@ got: %@", expected, desc); 187 188 CFReleaseSafe(name); 189 CFReleaseSafe(desc); 190 CFReleaseSafe(expected); 191 192out: 193 CFReleaseSafe(task); 194 CFReleaseSafe(appId); 195 CFReleaseSafe(signingIdentifier); 196 197 return 0; 198} 199