using namespace CommonCriteria::Securityd;
-AgentMechanismRef::AgentMechanismRef(const AuthHostType type, Session &session) :
- RefPointer<QueryInvokeMechanism>(new QueryInvokeMechanism(type, session)) {}
+AgentMechanismRef::AgentMechanismRef(const AuthHostType type, Session &session) {}
// we need the vector<string> of mechanisms
AgentMechanismEvaluator::AgentMechanismEvaluator(uid_t uid, Session& session, const vector<string>& inMechanisms) :
OSStatus
AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemSet &inHints, const AuthorizationToken &auth)
{
- AuthMechLogger logger(auth.creatorAuditToken(), AUE_ssauthmech);
- string rightName = "<unknown right>"; // 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<const char *>(val.data), val.length);
- logger.setRight(tmpstr);
- rightName.clear();
- rightName = tmpstr;
- }
- catch (...) { }
-
- const AuthItemSet &inContext = const_cast<AuthorizationToken &>(auth).infoSet();
-
- // add process specifics to context?
-
- vector<std::string>::const_iterator currentMechanism = mMechanisms.begin();
-
- AuthorizationResult result = kAuthorizationResultAllow;
-
- 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())
- {
- string::size_type extPlugin = currentMechanism->find(':');
- if (extPlugin != string::npos)
- {
- // no whitespace removal
- string pluginIn(currentMechanism->substr(0, extPlugin));
- string mechanismIn, authhostIn;
-
- string::size_type extMechanism = currentMechanism->rfind(',');
- AuthHostType hostType = securityAgent;
-
- 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);
- if (authhostIn == "privileged")
- hostType = privilegedAuthHost;
- }
- else
- mechanismIn = currentMechanism->substr(extPlugin + 1);
-
- secdebug("AuthEvalMech", "external mechanism %s:%s", pluginIn.c_str(), mechanismIn.c_str());
-
- AgentMechanismRef client(hostType, mSession);
- client->initialize(pluginIn, mechanismIn, inArguments);
- mClients.insert(ClientMap::value_type(*currentMechanism, client));
- }
- else if (*currentMechanism == "authinternal")
- {
- secdebug("AuthEvalMech", "performing authentication");
- result = authinternal(context);
-
- if (kAuthorizationResultAllow == result)
- {
- logger.logSuccess();
- }
- else // kAuthorizationResultDeny
- {
- 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);
- if (iter != mClients.end())
- {
- try
- {
- AgentMechanismRef &client = iter->second;
- client->run(inArguments, hints, context, &result);
-
- bool interrupted = false;
- while (client->state() == client->current)
- {
- // check for interruption
- vector<std::string>::const_iterator checkMechanism = mMechanisms.begin();
- while (*checkMechanism != *currentMechanism) {
- ClientMap::iterator iter2 = mClients.find(*checkMechanism);
- if (iter2->second->state() == iter2->second->interrupting)
- {
- client->deactivate();
- // nothing can happen until the client mechanism returns control to us
- while (client->state() == client->deactivating)
- client->receive();
-
- 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();
- context = iter2->second->inContext();
- currentMechanism = checkMechanism;
- break;
- }
- else
- checkMechanism++;
- }
- if (client->state() == client->current)
- client->receive();
- }
-
- if (interrupted)
- {
- // clear reason for restart from interrupt
- uint32_t reason = SecurityAgent::worldChanged;
- AuthItemRef retryHint(AGENT_HINT_RETRY_REASON, AuthValueOverlay(sizeof(reason), &reason));
- hints.erase(retryHint); hints.insert(retryHint); // replace
-
- result = kAuthorizationResultAllow;
- continue;
- }
- else
- secdebug("AuthEvalMech", "evaluate(%s) with result: %u.", (iter->first).c_str(), (uint32_t)result);
- }
- catch (...) {
- 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.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
- switch(result)
- {
- case kAuthorizationResultDeny:
- return errAuthorizationDenied;
- case kAuthorizationResultUserCanceled:
- 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;
- }
- }
+ return errAuthorizationDenied;
}
AuthorizationResult AgentMechanismEvaluator::authinternal(AuthItemSet &context)
{
- secdebug("AuthEvalMech", "evaluate authinternal");
- do {
- AuthItemSet::iterator found = find_if(context.begin(), context.end(), FindAuthItemByRightName(kAuthorizationEnvironmentUsername) );
- if (found == context.end())
- break;
- string username(static_cast<const char *>((*found)->value().data), (*found)->value().length);
- secdebug("AuthEvalMech", "found username");
- found = find_if(context.begin(), context.end(), FindAuthItemByRightName(kAuthorizationEnvironmentPassword) );
- if (found == context.end())
- break;
- string password(static_cast<const char *>((*found)->value().data), (*found)->value().length);
- secdebug("AuthEvalMech", "found password");
-
- Credential newCredential(username, password, true); // create a new shared credential
- if (newCredential->isValid())
- return kAuthorizationResultAllow;
-
- } while (0);
-
return kAuthorizationResultDeny;
}
-/*
-AuthItemSet &
-AgentMechanismEvaluator::commonHints(const AuthorizationToken &auth)
-{
-
-}
-*/
-
} /* namespace Authorization */