]>
git.saurik.com Git - apple/security.git/blob - securityd/src/ccaudit_extensions.cpp
2 * ccaudit_extensions.cpp
5 * Created by G H on 3/24/09.
6 * Copyright (c) 2009 Apple Inc. All Rights Reserved.
12 #include <stdio.h> // vsnprintf()
13 #include <stdarg.h> // va_start(), et al.
15 #include <string.h> // memcpy()
16 #include <bsm/audit_uevents.h> // AUE_ssauth*
17 #include <bsm/libbsm.h>
18 #include <security_utilities/errors.h>
19 #include <security_utilities/ccaudit.h>
20 #include "ccaudit_extensions.h"
25 namespace CommonCriteria
34 AuditLogger::AuditLogger(const audit_token_t
*srcToken
, short auEvent
)
35 : mAuditFd(-1), mEvent(auEvent
), mClientInfoSet(false)
37 setClientInfo(srcToken
);
40 AuditLogger::AuditLogger(const AuditToken
&srcToken
, short auEvent
)
41 : mAuditFd(-1), mEvent(auEvent
), mClientInfoSet(false)
43 setClientInfo(srcToken
);
46 AuditLogger::~AuditLogger()
57 // @@@ use audit_get_cond() when it's available
58 int acond
= au_get_state();
66 logInternalError("error checking auditing status (%d)", acond
);
67 UnixError::throwMe(acond
); // assume it's a Unix error
69 if ((mAuditFd
= au_open()) < 0)
71 logInternalError("au_open() failed (%s)", strerror(errno
));
72 UnixError::throwMe(errno
);
78 AuditLogger::close(bool writeLog
/* = true*/)
82 int keep
= writeLog
== true ? AU_TO_WRITE
: AU_TO_NO_WRITE
;
83 int error
= au_close(mAuditFd
, keep
, mEvent
);
85 if (writeLog
== true && error
< 0)
87 logInternalError("au_close() failed; record not committed");
88 UnixError::throwMe(error
);
94 AuditLogger::setClientInfo(const audit_token_t
*srcToken
)
97 audit_token_to_au32(*srcToken
, &mAuditId
, &mEuid
, &mEgid
, &mRuid
, &mRgid
, &mPid
, &mAuditSessionId
, &mOldTerminalId
);
99 mTerminalId
.at_type
= AU_IPv4
;
100 mTerminalId
.at_addr
[0] = mOldTerminalId
.machine
;
101 mTerminalId
.at_port
= mOldTerminalId
.port
;
103 mClientInfoSet
= true;
107 AuditLogger::setClientInfo(const AuditToken
&srcToken
)
109 mAuditId
= srcToken
.auditId();
110 mEuid
= srcToken
.euid();
111 mEgid
= srcToken
.egid();
112 mRuid
= srcToken
.ruid();
113 mRgid
= srcToken
.rgid();
114 mPid
= srcToken
.pid();
115 mAuditSessionId
= srcToken
.sessionId();
116 memcpy(&mOldTerminalId
, &(srcToken
.terminalId()), sizeof(mOldTerminalId
));
118 mTerminalId
.at_type
= AU_IPv4
;
119 mTerminalId
.at_addr
[0] = mOldTerminalId
.machine
;
120 mTerminalId
.at_port
= mOldTerminalId
.port
;
122 mClientInfoSet
= true;
126 AuditLogger::writeToken(token_t
*token
, const char *name
)
128 const char *tokenName
= name
? name
: "<unidentified>";
131 logInternalError("Invalid '%s' token", tokenName
);
133 UnixError::throwMe(EPERM
); // per audit_submit()
135 if (au_write(mAuditFd
, token
) < 0)
137 logInternalError("Error writing '%s' token (%s)", tokenName
, strerror(errno
));
139 UnixError::throwMe(errno
);
144 AuditLogger::writeSubject()
146 assert(mClientInfoSet
);
150 // @@@ terminal ID is not carried in the audit trailer nowadays, but
151 // this code should be harmless: it replicates the current logic in
153 if (AU_IPv4
== mTerminalId
.at_type
)
154 token
= au_to_subject32(mAuditId
, mEuid
, mEgid
, mRuid
, mRgid
, mPid
, mAuditSessionId
, &mOldTerminalId
);
156 token
= au_to_subject_ex(mAuditId
, mEuid
, mEgid
, mRuid
, mRgid
, mPid
, mAuditSessionId
, &mTerminalId
);
157 writeToken(token
, "subject");
161 AuditLogger::writeReturn(char status
, int reterr
)
163 writeToken(au_to_return32(status
, reterr
), "return");
167 AuditLogger::logSuccess()
177 AuditLogger::logFailure(const char *errMsg
, int errcode
)
183 writeToken(au_to_text(errMsg
), "evaluation error");
184 writeReturn(EPERM
, errcode
);
188 // cribbed from audit_submit()
190 AuditLogger::logInternalError(const char *fmt
, ...)
193 char text
[MAX_AUDITSTRING_LEN
];
199 (void)vsnprintf(text
, MAX_AUDITSTRING_LEN
, fmt
, ap
);
201 syslog(LOG_AUTH
| LOG_ERR
, "%s", text
);
207 // KeychainAuthLogger
209 const char *KeychainAuthLogger::sysKCAuthStr
= "System keychain authorization";
210 const char *KeychainAuthLogger::unknownKCStr
= "<unknown keychain>";
211 const char *KeychainAuthLogger::unknownItemStr
= "<unknown item>";
213 KeychainAuthLogger::KeychainAuthLogger(const audit_token_t
*srcToken
, short auEvent
)
214 : AuditLogger(srcToken
, auEvent
), mDatabase(unknownKCStr
),
215 mItem(unknownItemStr
)
219 KeychainAuthLogger::KeychainAuthLogger(const AuditToken
&srcToken
, short auEvent
)
220 : AuditLogger(srcToken
, auEvent
), mDatabase(unknownKCStr
),
221 mItem(unknownItemStr
)
225 KeychainAuthLogger::KeychainAuthLogger(const audit_token_t
*srcToken
, short auEvent
, const char *database
, const char *item
)
226 : AuditLogger(srcToken
, auEvent
)
232 KeychainAuthLogger::KeychainAuthLogger(const AuditToken
&srcToken
, short auEvent
, const char *database
, const char *item
)
233 : AuditLogger(srcToken
, auEvent
)
240 KeychainAuthLogger::setDbName(const char *database
)
242 mDatabase
= database
? database
: unknownKCStr
;
246 KeychainAuthLogger::setItemName(const char *item
)
248 mItem
= item
? item
: unknownItemStr
;
252 KeychainAuthLogger::writeCommon()
255 writeToken(au_to_text(sysKCAuthStr
), sysKCAuthStr
);
256 writeToken(au_to_text(mDatabase
.c_str()), "keychain");
257 writeToken(au_to_text(mItem
.c_str()), "keychain item");
264 const char *RightLogger::unknownRightStr
= "<unknown right>";
267 RightLogger::setRight(const string
&rightName
)
274 RightLogger::setRight(const char *rightName
)
276 if (rightName
) // NULL bad for string class and au_to_text()
278 string
tmpStr(rightName
); // setRight() takes a string&
287 const char *AuthMechLogger::unknownMechStr
= "<unknown mechanism>";
288 const char *AuthMechLogger::mechStr
= "mechanism ";
290 AuthMechLogger::AuthMechLogger(const AuditToken
&srcToken
, short auEvent
)
291 : AuditLogger(srcToken
, auEvent
), RightLogger(),
292 mEvaluatingMechanism(false), mCurrentMechanism(unknownMechStr
)
296 AuthMechLogger::AuthMechLogger(const audit_token_t
*srcToken
, short auEvent
)
297 : AuditLogger(srcToken
, auEvent
), RightLogger(),
298 mEvaluatingMechanism(false), mCurrentMechanism(unknownMechStr
)
303 AuthMechLogger::setCurrentMechanism(const char *mech
)
305 mCurrentMechanism
.clear();
308 mEvaluatingMechanism
= false;
312 mCurrentMechanism
= mech
;
313 mEvaluatingMechanism
= true;
318 AuthMechLogger::writeCommon()
321 writeToken(au_to_text(mRight
.c_str()), "right");
322 if (true == mEvaluatingMechanism
)
324 string tmpStr
= mechStr
; // mechStr includes a trailing space
325 tmpStr
+= mCurrentMechanism
;
326 writeToken(au_to_text(tmpStr
.c_str()), "mechanism");
331 AuthMechLogger::logInterrupt(const char *msg
)
337 writeToken(au_to_text(msg
), "interrupt");
343 // RightAuthenticationLogger
345 const char *RightAuthenticationLogger::unknownUserStr
= "<unknown user>";
346 const char *RightAuthenticationLogger::unknownClientStr
= "<unknown client>";
347 const char *RightAuthenticationLogger::unknownAuthCreatorStr
= "<unknown creator>";
348 const char *RightAuthenticationLogger::authenticatorStr
= "known UID ";
349 const char *RightAuthenticationLogger::clientStr
= "client ";
350 const char *RightAuthenticationLogger::authCreatorStr
= "creator ";
351 const char *RightAuthenticationLogger::authenticatedAsStr
= "authenticated as ";
352 const char *RightAuthenticationLogger::leastPrivStr
= "least-privilege";
354 RightAuthenticationLogger::RightAuthenticationLogger(const AuditToken
&srcToken
, short auEvent
)
355 : AuditLogger(srcToken
, auEvent
), RightLogger()
359 RightAuthenticationLogger::RightAuthenticationLogger(const audit_token_t
*srcToken
, short auEvent
)
360 : AuditLogger(srcToken
, auEvent
), RightLogger()
365 RightAuthenticationLogger::writeCommon()
368 writeToken(au_to_text(mRight
.c_str()), "right");
372 RightAuthenticationLogger::logSuccess(uid_t authenticator
, uid_t target
, const char *targetName
)
378 // au_to_arg32() is really meant for auditing syscall arguments;
379 // we're slightly abusing it to get descriptive strings for free.
380 writeToken(au_to_arg32(1, authenticatorStr
, authenticator
), "authenticator");
381 string
tmpStr(authenticatedAsStr
);
382 // targetName shouldn't be NULL on a successful authentication, but allow
383 // for programmer screwups
384 tmpStr
+= targetName
? targetName
: unknownUserStr
;
385 writeToken(au_to_arg32(2, tmpStr
.c_str(), target
), "target");
391 RightAuthenticationLogger::logAuthorizationResult(const char *client
, const char *authCreator
, int errcode
)
396 string
tmpStr(clientStr
);
397 tmpStr
+= client
? client
: unknownClientStr
;
398 writeToken(au_to_text(tmpStr
.c_str()), "Authorization client");
400 tmpStr
= authCreatorStr
;
401 tmpStr
+= authCreator
? authCreator
: unknownAuthCreatorStr
;
402 writeToken(au_to_text(tmpStr
.c_str()), "Authorization creator");
403 if (errAuthorizationSuccess
== errcode
)
406 writeReturn(EPERM
, errcode
);
411 RightAuthenticationLogger::logLeastPrivilege(uid_t userId
, bool isAuthorizingUser
)
416 writeToken(au_to_text(leastPrivStr
), leastPrivStr
);
422 RightAuthenticationLogger::logFailure(uid_t authenticator
, const char *targetName
)
427 writeToken(au_to_arg32(1, authenticatorStr
, authenticator
), "authenticator");
428 if (NULL
== targetName
)
429 writeToken(au_to_text(unknownUserStr
), "target username");
431 writeToken(au_to_text(targetName
), "target username");
432 // @@@ EAUTH more appropriate, but !defined for _POSIX_C_SOURCE
433 writeReturn(EPERM
, errAuthorizationDenied
);
437 } // namespace Securityd
439 } // namespace CommonCriteria
441 } // namespace Security