X-Git-Url: https://git.saurik.com/apple/securityd.git/blobdiff_plain/9b7150daea46853b31f80dffbfc3f6f64cd7a635..4cd1cad0dea00daa03e1b54fdf2797a02373ad5b:/src/AuthorizationMechEval.cpp?ds=inline diff --git a/src/AuthorizationMechEval.cpp b/src/AuthorizationMechEval.cpp index 571cff7..0080eb3 100644 --- a/src/AuthorizationMechEval.cpp +++ b/src/AuthorizationMechEval.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved. + * Copyright (c) 2003-2004,2008-2009 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -27,10 +27,12 @@ #include "AuthorizationMechEval.h" #include #include -#include +#include "ccaudit_extensions.h" namespace Authorization { +using namespace CommonCriteria::Securityd; + AgentMechanismRef::AgentMechanismRef(const AuthHostType type, Session &session) : RefPointer(new QueryInvokeMechanism(type, session)) {} @@ -44,6 +46,21 @@ AgentMechanismEvaluator::AgentMechanismEvaluator(uid_t uid, Session& session, co OSStatus AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemSet &inHints, const AuthorizationToken &auth) { + AuthMechLogger logger(auth.creatorAuditToken(), AUE_ssauthmech); + string rightName = ""; // for syslog + + // as of 10.6, the first item in inArguments should be the name of the + // requested right, for auditing + try + { + AuthorizationValue val = inArguments.at(0)->value(); + string tmpstr(static_cast(val.data), val.length); + logger.setRight(tmpstr); + rightName.clear(); + rightName = tmpstr; + } + catch (...) { } + const AuthItemSet &inContext = const_cast(auth).infoSet(); // add process specifics to context? @@ -54,10 +71,18 @@ AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemS AuthItemSet hints = inHints; AuthItemSet context = inContext; - + // add saved-off sticky context values to context for evaluation + context.insert(mStickyContext.begin(), mStickyContext.end()); + while ( (result == kAuthorizationResultAllow) && (currentMechanism != mMechanisms.end()) ) // iterate mechanisms { + SECURITYD_AUTH_MECH(&auth, (char *)(*currentMechanism).c_str()); + + // set up the audit message + logger.setCurrentMechanism(*currentMechanism); + + // do the real work ClientMap::iterator iter = mClients.find(*currentMechanism); if (iter == mClients.end()) { @@ -74,7 +99,12 @@ AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemS if (extMechanism != string::npos) { if (extMechanism < extPlugin) + { + string auditMsg = "badly formed mechanism name; ending rule evaluation"; + Syslog::alert("Right '%s', mech '%s': %s", rightName.c_str(), (*currentMechanism).c_str(), auditMsg.c_str()); + logger.logFailure(auditMsg); return errAuthorizationInternal; + } mechanismIn = currentMechanism->substr(extPlugin + 1, extMechanism - extPlugin - 1); authhostIn = currentMechanism->substr(extMechanism + 1); @@ -95,23 +125,30 @@ AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemS secdebug("AuthEvalMech", "performing authentication"); result = authinternal(context); - AuthItem *rightItem = hints.find(AGENT_HINT_AUTHORIZE_RIGHT); - string right = (rightItem == NULL) ? string("") : rightItem->stringValue(); - CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken()); if (kAuthorizationResultAllow == result) - auditrec.submit(AUE_ssauthint, CommonCriteria::errNone, right.c_str()); + { + logger.logSuccess(); + } else // kAuthorizationResultDeny - auditrec.submit(AUE_ssauthint, CommonCriteria::errInvalidCredential, right.c_str()); + { + logger.logFailure(); + } } else if (*currentMechanism == "push_hints_to_context") { secdebug("AuthEvalMech", "evaluate push_hints_to_context"); + logger.logSuccess(); // doesn't block evaluation, ever result = kAuthorizationResultAllow; context = hints; } else + { + string auditMsg = "unknown mechanism; ending rule evaluation"; + Syslog::alert("Right '%s', mech '%s': %s", rightName.c_str(), (*currentMechanism).c_str(), auditMsg.c_str()); + logger.logFailure(auditMsg); return errAuthorizationInternal; + } } iter = mClients.find(*currentMechanism); @@ -136,7 +173,11 @@ AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemS while (client->state() == client->deactivating) client->receive(); - secdebug("AuthEvalMech", "evaluate(%s) interrupted by %s.", (iter->first).c_str(), (iter2->first).c_str()); + string auditMsg = "evaluation interrupted by "; + auditMsg += (iter2->first).c_str(); + auditMsg += "; restarting evaluation there"; + secdebug("AuthEvalMech", "%s", auditMsg.c_str()); + logger.logInterrupt(auditMsg); interrupted = true; hints = iter2->second->inHints(); @@ -162,23 +203,50 @@ AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemS continue; } else - secdebug("AuthEvalMech", "evaluate(%s) with result: %lu.", (iter->first).c_str(), result); + secdebug("AuthEvalMech", "evaluate(%s) with result: %u.", (iter->first).c_str(), (uint32_t)result); } catch (...) { - secdebug("AuthEvalMech", "exception during evaluate(%s).", (iter->first).c_str()); + string auditMsg = "exception during evaluation of "; + auditMsg += (iter->first).c_str(); + secdebug("AuthEvalMech", "%s", auditMsg.c_str()); + logger.logFailure(auditMsg); result = kAuthorizationResultUndefined; } } if (result == kAuthorizationResultAllow) + { + logger.logSuccess(); currentMechanism++; + } } - + if ((result == kAuthorizationResultUserCanceled) || (result == kAuthorizationResultAllow)) { mHints = hints; - mContext = context; + mContext.clear(); + // only make non-sticky context values available externally + AuthItemSet::const_iterator end = context.end(); + for (AuthItemSet::const_iterator it = context.begin(); it != end; ++it) { + const AuthItemRef &item = *it; + if (item->flags() != kAuthorizationContextFlagSticky) + mContext.insert(item); + } + if (result == kAuthorizationResultUserCanceled) + logger.logFailure(NULL, errAuthorizationCanceled); + } + else if (result == kAuthorizationResultDeny) + { + // save off sticky values in context + mStickyContext.clear(); + AuthItemSet::const_iterator end = context.end(); + for (AuthItemSet::const_iterator it = context.begin(); it != end; ++it) { + const AuthItemRef &item = *it; + if (item->flags() == kAuthorizationContextFlagSticky) + mStickyContext.insert(item); + } + logger.logFailure(); } // convert AuthorizationResult to OSStatus @@ -190,8 +258,14 @@ AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemS return errAuthorizationCanceled; case kAuthorizationResultAllow: return errAuthorizationSuccess; + case kAuthorizationResultUndefined: + return errAuthorizationInternal; default: + { + Syslog::alert("Right '%s': unexpected error result (%u)", rightName.c_str(), result); + logger.logFailure("unexpected error result", result); return errAuthorizationInternal; + } } } @@ -210,17 +284,9 @@ AuthorizationResult AgentMechanismEvaluator::authinternal(AuthItemSet &context) string password(static_cast((*found)->value().data), (*found)->value().length); secdebug("AuthEvalMech", "found password"); - // Call to checkpw in DS - Server::active().longTermActivity(); Credential newCredential(username, password, true); // create a new shared credential - if (newCredential->isValid()) - { - Syslog::info("authinternal authenticated user %s (uid %lu).", newCredential->username().c_str(), newCredential->uid()); return kAuthorizationResultAllow; - } - - Syslog::error("authinternal failed to authenticate user %s.", newCredential->username().c_str()); } while (0);