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 28namespace Security 29{ 30 31namespace CommonCriteria 32{ 33 34namespace 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// 56class AuditLogger 57{ 58public: 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 92protected: 93 void logInternalError(const char *fmt, ...); 94 95private: 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// 120class KeychainAuthLogger : public AuditLogger 121{ 122 static const char *sysKCAuthStr; 123 static const char *unknownKCStr; 124 static const char *unknownItemStr; 125 126public: 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 136private: 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// 145class RightLogger 146{ 147protected: 148 static const char *unknownRightStr; 149 150public: 151 RightLogger() : mRight(unknownRightStr) { } 152 virtual ~RightLogger() { } 153 154 void setRight(const string &rightName); 155 void setRight(const char *rightName); 156 157protected: 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// 172class AuthMechLogger : public AuditLogger, public RightLogger 173{ 174 static const char *unknownMechStr; 175 static const char *mechStr; 176 177public: 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 192private: 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// 220class 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 231public: 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 logFailure(uid_t authenticator, const char *targetName); 246}; 247 248 249} // namespace Securityd 250 251} // namespace CommonCriteria 252 253} // namespace Security 254