]>
git.saurik.com Git - apple/security.git/blob - OSX/utilities/src/SecMeta.h
b7c05d49a877d89f8dcb9bc2af7aee54e03179a3
   2  * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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 
  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. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25 #ifndef _UTILITIES_SECMETA_H_ 
  26 #define _UTILITIES_SECMETA_H_ 
  28 #include <CoreFoundation/CoreFoundation.h> 
  32 // MARK - Logging, Trace, Error reporting, action log capture, and more. 
  35 #define SecInline static inline 
  37 // Disable all logging. 
  38 #define SecDisableLogging() do { _secOptions = _SecClearMask(_secOptions, mask); } while(0) 
  40 // For people who don't like flag1|flag2|flag3 syntax use SecFlags(flag1,flag2,flag3) 
  41 #define SecFlags(...)  _SecFlags(0, __VA_ARGS__) 
  43 // Set the current scopes log level. 
  44 #define SecSetLogLevel(level)  _SecSetLogLevel(&secOptions, (level)); 
  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) { \ 
  57 //    _SecAction(&_secResult, &_secFlags, &_secName, &_secError, &_secChain, &_secActions, flags, key, action, __VA_ARGS__) 
  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")); 
  72 #define SecEnableFlags(&_secFlags, flags) _secFlags = (flags); 
  73 #define SecDisableFlags(&_secFlags, flags) _secFlags = (flags); 
  75 #define SecSetFlags(flags) _SecSetFlags(&_secFlags, flags) 
  77 #define SecCatch(result, flags, error, ...) } _SecCatch(&_secResult, &_secFlags, &_secName, &_secError, &_secChain, &_secActions, result, flags, error,__VA_ARGS__) 
  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__) 
  82 // Boolean function result 
  83 #define SecOk(result, flags, format, ...) _SecOK() 
  85 // Log action and it's arguments into the action log. 
  87 #define SecDebugAction(flags, action...)  SecAction(flags, action...) 
  89 #define SecDebugAction(flags, action,...) 
  92 #define SecThrow(result, domain, flags, body, format...) { rtype _r = body(); __security_trace_return_api(__FUNCTION__, format, _r); return _r; } 
  95 #define SecEnd(rtype, body, error, format...) { rtype _r = body(); __security_trace_return_api(__FUNCTION__, format, _r); return _r; } 
  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) 
 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). 
 108     kSecFirstLogLevel    
= _SecLogLevel(1), // Lowest log level 
 109     kSecDebugLogLevel    
= _SecLogLevel(1), // log secinfo 
 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. 
 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() 
 124     kSecFlagMask            
= ( 0xFFC0), // Bits 4-16 are option flags and can be ored together with | 
 125     kSecFirstFlag           
= ( 1 << 6), // First flag defined 
 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. 
 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. 
 158 typedef uint32_t SecFlagType
; 
 160 SecInline SecFlagType 
_SecFlags(flag
, ...) { 
 161     SecFlagType _flag 
= flag
; 
 164     SecFlagType nextFlag
; 
 165     while ((nextFlag 
= va_arg(ap
, SecFlagType
))) _flag 
|= nextFlag
; 
 170 SecInline 
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 
 179 SecInline 
void _SecAction(void *_secResult
, void *flags
, void *name
, CFErrorRef 
*error
, CFMutableArrayRef 
*chain
, CFMutableStringRef 
*actions
, SecFlagType flags
, key
, CFStringRef action
, __VA_ARGS__
) { 
 182 SecInline 
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
; 
 193 SecInline 
void _SecEnableFlags(SecFlagType oldFlags
[1], SecFlagType newFlags
) { 
 194     (_SecLogLevel(newFlags
)) ? _SecClearMask(*oldFlags
); 
 195     *oldFlags 
|= newFlags
; 
 198 SecInline 
void _SecDisableFlags(SecFlagType oldFlags
[1], SecFlagType newFlags
) { 
 203 #endif /* _UTILITIES_SECMETA_H_ */