]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_transform/lib/misc.c
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_transform / lib / misc.c
1 /*
2 * Copyright (c) 2010-2012,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 #include "misc.h"
26 #include "SecCFRelease.h"
27
28 // NOTE: the return may or allocate a fair bit more space then it needs.
29 // Use it for short lived conversions (or strdup the result).
30 char *utf8(CFStringRef s) {
31 CFIndex sz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(s), kCFStringEncodingUTF8) + 1;
32 CFIndex used = 0;
33 UInt8 *buf = (UInt8 *)malloc(sz);
34 if (!buf) {
35 return NULL;
36 }
37 CFStringGetBytes(s, CFRangeMake(0, CFStringGetLength(s)), kCFStringEncodingUTF8, '?', FALSE, buf, sz, &used);
38 buf[used] = 0;
39
40 return (char*)buf;
41 }
42
43 void CFfprintf(FILE *f, const char *format, ...) {
44 va_list ap;
45 va_start(ap, format);
46
47 CFStringRef fmt = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
48 CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, ap);
49 va_end(ap);
50 CFReleaseNull(fmt);
51
52 CFIndex sz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
53 sz += 1;
54 CFIndex used = 0;
55 unsigned char *buf;
56 bool needs_free = false;
57 if (sz < 1024) {
58 buf = alloca(sz);
59 } else {
60 buf = malloc(sz);
61 needs_free = true;
62 }
63 if (buf) {
64 CFStringGetBytes(str, CFRangeMake(0, CFStringGetLength(str)), kCFStringEncodingUTF8, '?', FALSE, buf, sz, &used);
65 } else {
66 buf = (unsigned char *)"malloc failue during CFfprintf\n";
67 needs_free = false;
68 }
69
70 fwrite(buf, 1, used, f);
71 if (needs_free) {
72 free(buf);
73 }
74
75 CFReleaseNull(str);
76 }
77
78 CFErrorRef fancy_error(CFStringRef domain, CFIndex code, CFStringRef description) {
79 const void *v_ekey = kCFErrorDescriptionKey;
80 const void *v_description = description;
81 CFErrorRef err = CFErrorCreateWithUserInfoKeysAndValues(NULL, domain, code, &v_ekey, &v_description, 1);
82 CFAutorelease(err);
83
84 return err;
85 }
86
87 static
88 void add_t2ca(CFMutableDictionaryRef t2ca, CFStringRef t, CFStringRef a) {
89 CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, t);
90 if (!ca) {
91 ca = CFSetCreateMutable(NULL, 0, &kCFCopyStringSetCallBacks);
92 CFDictionarySetValue(t2ca, t, ca);
93 }
94 CFSetAddValue(ca, a);
95 }
96
97 void CFSafeRelease(CFTypeRef object) {
98 if (object) {
99 CFReleaseNull(object);
100 }
101 }
102
103 void graphviz(FILE *f, SecTransformRef tr) {
104 CFDictionaryRef d = SecTransformCopyExternalRepresentation(tr);
105
106 CFfprintf(f, "digraph TR {\n\tnode [shape=plaintext];\n\n");
107 CFIndex i, j;
108 CFArrayRef transforms = CFDictionaryGetValue(d, CFSTR("TRANSFORMS"));
109 CFArrayRef connections = CFDictionaryGetValue(d, CFSTR("ARRAY"));
110
111
112 // map transforms to connected attributes
113 CFMutableDictionaryRef t2ca = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
114 for(i = 0; i < CFArrayGetCount(connections); i++) {
115 CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i);
116
117 CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME"));
118 CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME"));
119 CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE"));
120 CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE"));
121
122 add_t2ca(t2ca, t_from, a_from);
123 add_t2ca(t2ca, t_to, a_to);
124 }
125
126
127 for(i = 0; i < CFArrayGetCount(transforms); i++) {
128 CFDictionaryRef t = CFArrayGetValueAtIndex(transforms, i);
129 // NAME STATE(dict) TYPE
130 CFStringRef name = CFDictionaryGetValue(t, CFSTR("NAME"));
131
132 CFfprintf(f, "\tsubgraph \"cluster_%@\"{\n", name);
133
134 CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, name);
135 if (ca) {
136 CFIndex cnt = CFSetGetCount(ca);
137 CFStringRef *attrs = malloc(cnt * sizeof(CFStringRef));
138 CFSetGetValues(ca, (const void **)attrs);
139
140 for(j = 0; j < cnt; j++) {
141 CFfprintf(f, "\t\t\"%@#%@\" [label=\"%@\"];\n", name, attrs[j], attrs[j]);
142 }
143 CFfprintf(f, "\t\t\"%@\" [fontcolor=blue, fontsize=20];\n\t}\n");
144 free(attrs);
145 }
146 }
147
148 CFfprintf(f, "\n");
149
150 for(i = 0; i < CFArrayGetCount(connections); i++) {
151 CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i);
152
153 CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME"));
154 CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME"));
155 CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE"));
156 CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE"));
157
158 CFfprintf(f, "\t\"%@#%@\" -> \"%@#%@\";\n", t_from, a_from, t_to, a_to);
159 }
160
161 CFfprintf(f, "}\n");
162
163 CFfprintf(f, "\n/*\n%@\n/*\n", d);
164 }