1/* 2 * Copyright (c) 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#ifndef _UTILITIES_SECMETA_H_ 26#define _UTILITIES_SECMETA_H_ 27 28#include <CoreFoundation/CoreFoundation.h> 29 30// 31// MARK - SecMeta 32// MARK - Logging, Trace, Error reporting, action log capture, and more. 33// 34 35#define SecInline static inline 36 37// Disable all logging. 38#define SecDisableLogging() do { _secOptions = _SecClearMask(_secOptions, mask); } while(0) 39 40// For people who don't like flag1|flag2|flag3 syntax use SecFlags(flag1,flag2,flag3) 41#define SecFlags(...) _SecFlags(0, __VA_ARGS__) 42 43// Set the current scopes log level. 44#define SecSetLogLevel(level) _SecSetLogLevel(&secOptions, (level)); 45 46// Mark that we performed an action for the log and for an generated errors. 47#define SecAction(flags, key, action,...) \ 48 if (_SecLogLevel(flags)) { _SecSetLogLevel(&_secFlags, _SecLogLevel(flags)); } \ 49 if (_SecSetFlags(flags) \ 50 if ((_secFlags | flags) & kSecTraceAction) {} \ 51 if ((_secFlags | flags) & kSecLogEveryActionFlag) { \ 52 if (flags & kSecLogLevelMask) { \ 53 54 55 } \ 56 } \ 57// _SecAction(&_secResult, &_secFlags, &_secName, &_secError, &_secChain, &_secActions, flags, key, action, __VA_ARGS__) 58 59// Usage: declare a variable that represents the result of your function 60#define SecTry(result,flags,humanReadableFunctionNameForLogs) switch (0) case 0: { \ 61 __typeof__(result) _secResult = result; \ 62 __typeof__(flags) _secFlags = flags; \ 63 __typeof__(format) _secName = humanReadableFunctionNameForLogs; \ 64 CFErrorRef _secError = NULL; \ 65 CFMutableArrayRef _secChain = NULL; \ 66 CFMutableStringRef _secActions = NULL; \ 67 CFMutableDictionaryRef _secFormatOptions = NULL; \ 68 SecAction(_secFlags, CFSTR("entered")); 69 70 71 72#define SecEnableFlags(&_secFlags, flags) _secFlags = (flags); 73#define SecDisableFlags(&_secFlags, flags) _secFlags = (flags); 74 75#define SecSetFlags(flags) _SecSetFlags(&_secFlags, flags) 76 77#define SecCatch(result, flags, error, ...) } _SecCatch(&_secResult, &_secFlags, &_secName, &_secError, &_secChain, &_secActions, result, flags, error,__VA_ARGS__) 78 79// Add pending errors to *error Clears any pending errors, and will log anything that was marked as needing to be logged. 80#define SecFinally(result, flags, error, ...) _SecFinally(&_secResult, &_secFlags, &_secName, &_secError, &_secChain, &_secActions, result, flags, error, __VA_ARGS__) 81 82// Boolean function result 83#define SecOk(result, flags, format, ...) _SecOK() 84 85// Log action and it's arguments into the action log. 86#if DEBUG 87#define SecDebugAction(flags, action...) SecAction(flags, action...) 88#else 89#define SecDebugAction(flags, action,...) 90#endif 91 92#define SecThrow(result, domain, flags, body, format...) { rtype _r = body(); __security_trace_return_api(__FUNCTION__, format, _r); return _r; } 93 94 95#define SecEnd(rtype, body, error, format...) { rtype _r = body(); __security_trace_return_api(__FUNCTION__, format, _r); return _r; } 96 97// Internal USE only DO NOT USE directly 98#define _SecClearMask(flags, mask) (((flags) | (mask)) ^ (mask)) 99#define _SecLogLevel(level) (((level) << 0) & kSecLogLevelMask) 100#define _SecLogStyle(style) (((style) << 4) & kSecLogStyleMask) 101 102__BEGIN_DECLS 103 104enum SecFlagEnum { 105 kSecNoFlag = 0, // No flags, no logging nada 106 kSecLogLevelMask = (15 << 0), // Bits 0-3 contain the log levels 1-15 (since 0 is no flags). 107 108 kSecFirstLogLevel = _SecLogLevel(1), // Lowest log level 109 kSecDebugLogLevel = _SecLogLevel(1), // log secdebug 110 kSecInfoLogLevel = _SecLogLevel(2), // log info 111 kSecNoticeLogLevel = _SecLogLevel(3), // log notice 112 kSecWarningLogLevel = _SecLogLevel(4), // log warning 113 kSecErrorLogLevel = _SecLogLevel(5), // log error 114 kSecCriticalLogLevel = _SecLogLevel(6), // log critical 115 kSecAlertLogLevel = _SecLogLevel(7), // log alert 116 kSecLastLogLevel = _SecLogLevel(15),// Max available log level. 117 118 kSecLogStyleMask = ( 0x30), // Bits 4-5 are used to store log style chhoices. The choice is yours. 119 kSecLogPlainStyle = _SecLogStyle(0), // Log plain message in code only no built in function names. 120 kSecLogFunctionStyle = _SecLogStyle(1), // Log full __FUNCTION_NAME__ 121 kSecLogPrettyFuncStyle=_SecLogStyle(2), // Log full ___PRETTY_FUNCTION__ 122 kSecLogNameStyle = _SecLogStyle(3), // Log name argument to SecWith() 123 124 kSecFlagMask = ( 0xFFC0), // Bits 4-16 are option flags and can be ored together with | 125 kSecFirstFlag = ( 1 << 6), // First flag defined 126 127 kSecTraceFlag = ( 1 << 6), // trace this api call 128 kSecChainFlag = ( 1 << 7), // chain multiple errors together in a array with the last error Enclosing all the others. 129 kSecFlagAssert = ( 1 << 8), // assert that result is not fail without an error having been thrown 130 kSecSafeModeFlag = ( 1 << 9), // Do not evaluate format arguments to avoid infinite recursion. 131 kSecClearPendingFlag = ( 1 << 10), // Clear any pending errors. 132 kSecLogDisabledFlag = ( 1 << 11), // Logging is disabled. 133 kSecLogAlwaysFlag = ( 1 << 12), // always log regardless of success or failure 134 kSecLogEveryActionFlag = ( 1 << 13), // log every action 135 kSecReservedFlag = ( 1 << 14), // Reserved for future use. 136 kSecLastFlag = ( 1 << 15), // Reserved for future use. 137 138 139 kSecActionsMask = (15 << 16), // Bits 4-16 are option flags and can be ored together with | 140 kSecLowerLogLevelAction = ( 1 << 16), // Allow the log level to be lowered 141 kSecTraceAction = ( 1 << 17), // Trace this action. 142 kSecReserved3Action = ( 1 << 18), // Reserved for future use. 143 kSecReserved4Action = ( 1 << 19), // Reserved for future use. 144 kSecReserved5Action = ( 1 << 20), // Reserved for future use. 145 kSecReserved6Action = ( 1 << 21), // Reserved for future use. 146 kSecReserved7Action = ( 1 << 22), // Reserved for future use. 147 kSecReserved8Action = ( 1 << 23), // Reserved for future use. 148 kSecReserved9Action = ( 1 << 24), // Reserved for future use. 149 kSecReserved10Action = ( 1 << 25), // Reserved for future use. 150 kSecReserved11Action = ( 1 << 26), // Reserved for future use. 151 kSecReserved12Action = ( 1 << 27), // Reserved for future use. 152 kSecReserved13Action = ( 1 << 28), // Reserved for future use. 153 kSecReserved14Action = ( 1 << 29), // Reserved for future use. 154 kSecReserved14Action = ( 1 << 30), // Reserved for future use. 155 kSecLastAction = ( 1 << 31), // The last action defined. 156 157}; 158typedef uint32_t SecFlagType; 159 160SecInline SecFlagType _SecFlags(flag, ...) { 161 SecFlagType _flag = flag; 162 va_list ap; 163 va_start(ap, flag); 164 SecFlagType nextFlag; 165 while ((nextFlag = va_arg(ap, SecFlagType))) _flag |= nextFlag; 166 va_end(ap); 167 return _flag; 168} 169 170SecInline void _SecSetLogLevel(SecFlagType flags[1], SecFlagType newFlags) { 171 SecFlagType newLevel = _SecLogLevel(newFlags); 172 if (!newLevel || newFlags & kSecLowerLogLevelAction) 173 *oldFlags = newLevel & _SecClearMask(newFlags, kSecActionsMask); 174 else if (newLevel > _SecLogLevel(*oldFlags)) 175 *oldFlags = _SecClearMask(*oldFlags, kSecLogLevelMask) | newLevel; 176 // Canot lower log level 177} 178 179SecInline void _SecAction(void *_secResult, void *flags, void *name, CFErrorRef *error, CFMutableArrayRef *chain, CFMutableStringRef *actions, SecFlagType flags, key, CFStringRef action, __VA_ARGS__) { 180} 181 182SecInline void _SecSetFlags(SecFlagType oldFlags[1], SecFlagType newFlags) { 183 // Log level can't be lowered unless kSecLowerLogLevelAction is present in newFlags. 184 newLevel = newFlags & kSecLogLevelMask 185 if (!newLevel || newFlags & kSecLowerLogLevelAction) 186 *oldFlags = newFlags & (kSecLogLevelMask | kSecFlagMask); 187 else if (newLevel > _SecLogLevel(*oldFlags)) 188 *oldFlags = _SecClearMask(*oldFlags, kSecLogLevelMask) 189 (_SecLogLevel(newFlags)) ? _SecClearMask(*oldFlags); 190 *oldFlags |= newFlags; 191} 192 193SecInline void _SecEnableFlags(SecFlagType oldFlags[1], SecFlagType newFlags) { 194 (_SecLogLevel(newFlags)) ? _SecClearMask(*oldFlags); 195 *oldFlags |= newFlags; 196} 197 198SecInline void _SecDisableFlags(SecFlagType oldFlags[1], SecFlagType newFlags) { 199} 200 201__END_DECLS 202 203#endif /* _UTILITIES_SECMETA_H_ */ 204