X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/72a12576750f52947eb043106ba5c12c0d07decf..b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195:/libsecurity_transform/lib/misc.c diff --git a/libsecurity_transform/lib/misc.c b/libsecurity_transform/lib/misc.c new file mode 100644 index 00000000..a82293a7 --- /dev/null +++ b/libsecurity_transform/lib/misc.c @@ -0,0 +1,145 @@ +/* + * misc.c + * libsecurity_transform + * + * Created by JOsborne on 3/14/10. + * Copyright 2010 Apple. All rights reserved. + * + */ + +#include "misc.h" + + +// NOTE: the return may or allocate a fair bit more space then it needs. +// Use it for short lived conversions (or strdup the result). +char *utf8(CFStringRef s) { + CFIndex sz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(s), kCFStringEncodingUTF8) + 1; + CFIndex used = 0; + UInt8 *buf = (UInt8 *)malloc(sz); + if (!buf) { + return NULL; + } + CFStringGetBytes(s, CFRangeMake(0, CFStringGetLength(s)), kCFStringEncodingUTF8, '?', FALSE, buf, sz, &used); + buf[used] = 0; + + return (char*)buf; +} + +void CFfprintf(FILE *f, const char *format, ...) { + va_list ap; + va_start(ap, format); + + CFStringRef fmt = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8); + CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, ap); + va_end(ap); + CFRelease(fmt); + + CFIndex sz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8); + sz += 1; + CFIndex used = 0; + unsigned char *buf; + bool needs_free = false; + if (sz < 1024) { + buf = alloca(sz); + } else { + buf = malloc(sz); + needs_free = true; + } + if (buf) { + CFStringGetBytes(str, CFRangeMake(0, CFStringGetLength(str)), kCFStringEncodingUTF8, '?', FALSE, buf, sz, &used); + } else { + buf = (unsigned char *)"malloc failue during CFfprintf\n"; + } + + fwrite(buf, 1, used, f); + if (needs_free) { + free(buf); + } + + CFRelease(str); +} + +CFErrorRef fancy_error(CFStringRef domain, CFIndex code, CFStringRef description) { + const void *v_ekey = kCFErrorDescriptionKey; + const void *v_description = description; + CFErrorRef err = CFErrorCreateWithUserInfoKeysAndValues(NULL, domain, code, &v_ekey, &v_description, 1); + + return err; +} + +void add_t2ca(CFMutableDictionaryRef t2ca, CFStringRef t, CFStringRef a) { + CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, t); + if (!ca) { + ca = CFSetCreateMutable(NULL, 0, &kCFCopyStringSetCallBacks); + CFDictionarySetValue(t2ca, t, ca); + } + CFSetAddValue(ca, a); +} + +void CFSafeRelease(CFTypeRef object) { + if (object) { + CFRelease(object); + } +} + +void graphviz(FILE *f, SecTransformRef tr) { + CFDictionaryRef d = SecTransformCopyExternalRepresentation(tr); + + CFfprintf(f, "digraph TR {\n\tnode [shape=plaintext];\n\n"); + CFIndex i, j; + CFArrayRef transforms = CFDictionaryGetValue(d, CFSTR("TRANSFORMS")); + CFArrayRef connections = CFDictionaryGetValue(d, CFSTR("ARRAY")); + + + // map transforms to connected attributes + CFMutableDictionaryRef t2ca = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + for(i = 0; i < CFArrayGetCount(connections); i++) { + CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i); + + CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME")); + CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME")); + CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE")); + CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE")); + + add_t2ca(t2ca, t_from, a_from); + add_t2ca(t2ca, t_to, a_to); + } + + + for(i = 0; i < CFArrayGetCount(transforms); i++) { + CFDictionaryRef t = CFArrayGetValueAtIndex(transforms, i); + // NAME STATE(dict) TYPE + CFStringRef name = CFDictionaryGetValue(t, CFSTR("NAME")); + + CFfprintf(f, "\tsubgraph \"cluster_%@\"{\n", name); + + CFMutableSetRef ca = (CFMutableSetRef)CFDictionaryGetValue(t2ca, name); + if (ca) { + CFIndex cnt = CFSetGetCount(ca); + CFStringRef *attrs = malloc(cnt * sizeof(CFStringRef)); + CFSetGetValues(ca, (const void **)attrs); + + for(j = 0; j < cnt; j++) { + CFfprintf(f, "\t\t\"%@#%@\" [label=\"%@\"];\n", name, attrs[j], attrs[j]); + } + CFfprintf(f, "\t\t\"%@\" [fontcolor=blue, fontsize=20];\n\t}\n"); + } + } + + CFfprintf(f, "\n"); + + for(i = 0; i < CFArrayGetCount(connections); i++) { + CFDictionaryRef c = CFArrayGetValueAtIndex(connections, i); + + CFStringRef t_from = CFDictionaryGetValue(c, CFSTR("FROM_NAME")); + CFStringRef t_to = CFDictionaryGetValue(c, CFSTR("TO_NAME")); + CFStringRef a_from = CFDictionaryGetValue(c, CFSTR("FROM_ATTRIBUTE")); + CFStringRef a_to = CFDictionaryGetValue(c, CFSTR("TO_ATTRIBUTE")); + + CFfprintf(f, "\t\"%@#%@\" -> \"%@#%@\";\n", t_from, a_from, t_to, a_to); + } + + CFfprintf(f, "}\n"); + + CFfprintf(f, "\n/*\n%@\n/*\n", d); +} \ No newline at end of file