ccaudit_extensions.h
1 /* 2 * ccaudit_extensions.h 3 * securityd 4 * 5 * Created by G H on 3/24/09. 6 * Copyright (c) 2009 Apple Inc. All Rights Reserved. 7 * 8 * Extensions to utility classes in Security::CommonCriteria 9 * (libsecurity_utilities). Not clear that these are useful enough to be 10 * added there, so for now, they're here. 11 */ 12 13 #include <string> 14 #include <stdint.h> 15 #include <Security/Authorization.h> 16 #include <bsm/audit_kevents.h> // AUE_NULL 17 #include <bsm/libbsm.h> 18 19 // 20 // Regarding message formats in comments, below: 21 // 22 // <> denotes a string with the indicated information 23 // '' denotes a literal string 24 // 25 // Message info is in text tokens unless otherwise indicated. 26 // 27 28 namespace Security 29 { 30 31 namespace CommonCriteria 32 { 33 34 namespace Securityd 35 { 36 37 // 38 // Pure virtual class from which audit log writers should be derived. 39 // The assumption about logging is that a "success" case logs certain 40 // data about what succeeded, while a "failure" case logs that same data 41 // plus some indication as to why the failure occurred. 42 // 43 // Subclasses minimally need to provide a writeCommon() method. They may 44 // override logSuccess(); q.v. 45 // 46 // An AuditLogger is intended to live no longer than the audit trailer of a 47 // securityd IPC. 48 // 49 // setClientInfo() must be called before logging, or at best, gibberish 50 // will be logged. 51 // 52 // Nomenclature: 53 // "write" methods only au_write() 54 // "log" methods open, write, and close the log 55 // 56 class AuditLogger 57 { 58 public: 59 AuditLogger() : mAuditFd(-1), mEvent(AUE_NULL), mClientInfoSet(false) { } 60 AuditLogger(const audit_token_t *srcToken, short auEvent = AUE_NULL); 61 AuditLogger(const AuditToken &srcToken, short auEvent = AUE_NULL); 62 virtual ~AuditLogger(); 63 64 bool open(); // false if auditing disabled; throws on real errors 65 void close(bool writeLog = true); // throws if writeLog true but au_close() failed 66 67 void setClientInfo(const audit_token_t *srcToken); 68 void setClientInfo(const AuditToken &srcToken); 69 void setEvent(short auEvent) { mEvent = auEvent; } 70 short event() const { return mEvent; } 71 72 // common log-writing activities 73 void writeToken(token_t *token, const char *name); 74 void writeSubject(); 75 void writeReturn(char status, int reterr); 76 virtual void writeCommon() = 0; // should not open or close log 77 78 // logSuccess() assumes that all the ancillary information you need is 79 // written by writeCommon(). If that's not true, you can either 80 // override logSuccess() in your subclass, or use a different method 81 // altogether. Do not call AuditLogger::logSuccess() from the subclass 82 // in eiher case. 83 virtual void logSuccess(); 84 85 virtual void logFailure(const char *errMsg = NULL, int errcode = errAuthorizationDenied); 86 virtual void logFailure(string &errMsg, int errcode = errAuthorizationDenied) { logFailure(errMsg.c_str(), errcode); } 87 88 // @@@ Extra credit: let callers add arbitrary tokens. Tokens added 89 // before a log*() call would be appended to the end of writeCommon()'s 90 // standard set. 91 92 protected: 93 void logInternalError(const char *fmt, ...); 94 95 private: 96 int mAuditFd; 97 short mEvent; 98 bool mClientInfoSet; // disallow resetting client info 99 100 uid_t mAuditId; 101 uid_t mEuid; 102 gid_t mEgid; 103 uid_t mRuid; 104 gid_t mRgid; 105 pid_t mPid; 106 au_asid_t mAuditSessionId; 107 au_tid_t mOldTerminalId; // to cache audit_token_to_au32() result 108 au_tid_addr_t mTerminalId; // @@@ AuditInfo still uses ai_tid_t 109 }; 110 111 // 112 // KeychainAuthLogger format: 113 // 'System keychain authorization' 114 // <keychain name> 115 // <keychain item name> 116 // [optional] <more failure info> 117 // 118 // For QueryKeychainAuth audit logging 119 // 120 class KeychainAuthLogger : public AuditLogger 121 { 122 static const char *sysKCAuthStr; 123 static const char *unknownKCStr; 124 static const char *unknownItemStr; 125 126 public: 127 KeychainAuthLogger() : AuditLogger(), mDatabase(unknownKCStr), mItem(unknownItemStr) { } 128 KeychainAuthLogger(const audit_token_t *srcToken, short auEvent); 129 KeychainAuthLogger(const audit_token_t *srcToken, short auEvent, const char *database, const char *item); 130 KeychainAuthLogger(const AuditToken &srcToken, short auEvent); 131 KeychainAuthLogger(const AuditToken &srcToken, short auEvent, const char *database, const char *item); 132 void setDbName(const char *database); 133 void setItemName(const char *item); 134 virtual void writeCommon(); 135 136 private: 137 string mDatabase; 138 string mItem; 139 }; 140 141 // 142 // RightLogger provides basic common data and behavior for rights-based 143 // logging classes. @@@ "RightLogger" is a lousy name 144 // 145 class RightLogger 146 { 147 protected: 148 static const char *unknownRightStr; 149 150 public: 151 RightLogger() : mRight(unknownRightStr) { } 152 virtual ~RightLogger() { } 153 154 void setRight(const string &rightName); 155 void setRight(const char *rightName); 156 157 protected: 158 string mRight; 159 }; 160 161 // 162 // Basic (per-mechanism) AuthMechLogger format: 163 // <right name> 164 // [optional] 'mechanism' <mechanism name> 165 // [optional] <more info> 166 // 167 // e.g.: 168 // com.foo.bar 169 // mechanism FooPlugin:SomeMechanism 170 // unknown mechanism; ending rule evaluation 171 // 172 class AuthMechLogger : public AuditLogger, public RightLogger 173 { 174 static const char *unknownMechStr; 175 static const char *mechStr; 176 177 public: 178 AuthMechLogger() : AuditLogger(), RightLogger(), mEvaluatingMechanism(false), mCurrentMechanism(unknownMechStr) { } 179 AuthMechLogger(const AuditToken &srcToken, short auEvent); 180 AuthMechLogger(const audit_token_t *srcToken, short auEvent); 181 182 void setCurrentMechanism(const char *mech); // pass NULL if not running mechs. 183 void setCurrentMechanism(const string &mech) { setCurrentMechanism(mech.c_str()); } 184 virtual void writeCommon(); 185 186 // Authorization mechanism-evaluation interrupts need to be logged since 187 // they cause evaluation to restart, possibly at a different point in the 188 // mechanism chain. 189 void logInterrupt(const char *msg); // NULL msg okay 190 void logInterrupt(string &msg) { logInterrupt(msg.c_str()); } 191 192 private: 193 bool mEvaluatingMechanism; 194 string mCurrentMechanism; 195 }; 196 197 // 198 // Basic RightAuthenticationLogger formats: 199 // 200 // Per-credential (newly granted during an evaluation): 201 // <right name> 202 // UID of user performing the authentication [arg32 token] 203 // UID and username of the successfully authenticated user [arg32 token] 204 // or: 205 // <right name> 206 // UID of user performing the authentication [arg32 token] 207 // Name of the user as whom the first UID was attempting to authenticate 208 // 209 // Final (i.e., after all mechanisms) right-granting decision format: 210 // <right name> 211 // name of process requesting authorization 212 // name of process that created the Authorization handle 213 // 214 // Least-privilege credential-generating event format: 215 // <right name> 216 // 'least-privilege' 217 // 218 // @@@ each format should be its own class 219 // 220 class RightAuthenticationLogger : public AuditLogger, public RightLogger 221 { 222 static const char *unknownUserStr; 223 static const char *unknownClientStr; 224 static const char *unknownAuthCreatorStr; 225 static const char *authenticatorStr; 226 static const char *clientStr; 227 static const char *authCreatorStr; 228 static const char *authenticatedAsStr; 229 static const char *leastPrivStr; 230 231 public: 232 RightAuthenticationLogger() : AuditLogger(), RightLogger() { } 233 RightAuthenticationLogger(const AuditToken &srcToken, short auEvent); 234 RightAuthenticationLogger(const audit_token_t *srcToken, short auEvent); 235 virtual ~RightAuthenticationLogger() { } 236 237 virtual void writeCommon(); 238 239 virtual void logSuccess() { } // throw? in any case, don't allow the usual logSuccess() to work 240 // @@@ clean up, consolidate Success and AuthorizationResult 241 void logSuccess(uid_t authenticator, uid_t target, const char *targetName); 242 void logAuthorizationResult(const char *client, const char *authCreator, int errcode); 243 void logLeastPrivilege(uid_t userId, bool isAuthorizingUser); 244 virtual void logFailure(const char *errMsg, int errcode) { AuditLogger::logFailure(errMsg, errcode); } 245 void logAuthenticatorFailure(uid_t authenticator, const char *targetName); 246 }; 247 248 249 } // namespace Securityd 250 251 } // namespace CommonCriteria 252 253 } // namespace Security