1/*
2 * Copyright (c) 2011,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#include "Utilities.h"
25#include "SecTransform.h"
26#include <sys/sysctl.h>
27#include <syslog.h>
28#include <dispatch/dispatch.h>
29
30void MyDispatchAsync(dispatch_queue_t queue, void(^block)(void))
31{
32	fprintf(stderr, "Running job on queue %p\n", queue);
33	dispatch_async(queue, block);
34}
35
36
37
38dispatch_queue_t MyDispatchQueueCreate(const char* name, dispatch_queue_attr_t attr)
39{
40	dispatch_queue_t result = dispatch_queue_create(name, attr);
41	// fprintf(stderr, "Created queue %s as %p\n", name, result);
42	return result;
43}
44
45
46
47static CFErrorRef CreateErrorRefCore(CFStringRef domain, int errorCode, const char* format, va_list ap)
48{
49	CFStringRef fmt = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
50	CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, ap);
51	va_end(ap);
52	CFRelease(fmt);
53
54	CFStringRef keys[] = {kCFErrorDescriptionKey};
55	CFStringRef values[] = {str};
56
57	CFErrorRef result = CFErrorCreateWithUserInfoKeysAndValues(NULL, domain, errorCode, (const void**) keys, (const void**) values, 1);
58	CFRelease(str);
59
60	return result;
61}
62
63
64
65CFErrorRef CreateGenericErrorRef(CFStringRef domain, int errorCode, const char* format, ...)
66{
67	va_list ap;
68	va_start(ap, format);
69	return CreateErrorRefCore(domain, errorCode, format, ap);
70}
71
72
73
74CFErrorRef CreateSecTransformErrorRef(int errorCode, const char* format, ...)
75{
76	// create a CFError in the SecTransform error domain.  You can add an explanation, which is cool.
77	va_list ap;
78	va_start(ap, format);
79
80	return CreateErrorRefCore(kSecTransformErrorDomain, errorCode, format, ap);
81}
82
83
84
85CFErrorRef CreateSecTransformErrorRefWithCFType(int errorCode, CFTypeRef message)
86{
87	CFStringRef keys[] = {kCFErrorLocalizedDescriptionKey};
88	CFTypeRef values[] = {message};
89	return CFErrorCreateWithUserInfoKeysAndValues(NULL, kSecTransformErrorDomain, errorCode, (const void**) keys, (const void**) values, 1);
90}
91
92
93
94CFTypeRef gAnnotatedRef = NULL;
95
96CFTypeRef DebugRetain(const void* owner, CFTypeRef type)
97{
98	CFTypeRef result = CFRetain(type);
99	if (type == gAnnotatedRef)
100	{
101		fprintf(stderr, "Object %p was retained by object %p, count = %ld\n", type, owner, CFGetRetainCount(type));
102	}
103
104	return result;
105}
106
107
108
109void DebugRelease(const void* owner, CFTypeRef type)
110{
111	if (type == gAnnotatedRef)
112	{
113		fprintf(stderr, "Object %p was released by object %p, count = %ld\n", type, owner, CFGetRetainCount(type) - 1);
114	}
115
116	CFRelease(type);
117}
118
119// Cribbed from _dispatch_bug and altered a bit
120void transforms_bug(size_t line, long val)
121{
122    static dispatch_once_t pred;
123    static char os_build[16];
124    static void *last_seen;
125    void *ra = __builtin_return_address(0);
126    dispatch_once(&pred, ^{
127#ifdef __APPLE__
128        int mib[] = { CTL_KERN, KERN_OSVERSION };
129        size_t bufsz = sizeof(os_build);
130        sysctl(mib, 2, os_build, &bufsz, NULL, 0);
131#else
132        os_build[0] = '\0';
133#endif
134    });
135    if (last_seen != ra) {
136        last_seen = ra;
137        syslog(LOG_NOTICE, "BUG in SecTransforms: %s - %p - %lu - %lu", os_build, last_seen, (unsigned long)line, val);
138    }
139}
140