- iter->second->run(inArguments, hints, context, &result);
- secdebug("AuthEvalMech", "evaluate(%s) succeeded with result: %lu.", (iter->first).c_str(), result);
+ 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);