#include "server.h"
#include "session.h"
#include "tempdatabase.h"
-#include "authority.h"
#include "child.h" // ServerChild (really UnixPlusPlus::Child)::find()
+#include <security_utilities/ccaudit.h>
#include <security_utilities/logging.h> //@@@ debug only
#include "agentquery.h"
// Construct a Process object.
//
Process::Process(TaskPort taskPort, const ClientSetupInfo *info, const CommonCriteria::AuditToken &audit)
- : mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid())
+ : mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid()), mAudit(audit)
{
StLock<Mutex> _(*this);
// set parent session
parent(Session::find(audit.sessionId(), true));
-
- // let's take a look at our wannabe client...
+
+ // let's take a look at our wannabe client...
+
+ // Not enough to make sure we will get the right process, as
+ // pids get recycled. But we will later create the actual SecCode using
+ // the audit token, which is unique to the one instance of the process,
+ // so this just catches a pid mismatch early.
if (mTaskPort.pid() != mPid) {
- secdebug("SS", "Task/pid setup mismatch pid=%d task=%d(%d)",
- mPid, mTaskPort.port(), mTaskPort.pid());
+ secnotice("SecServer", "Task/pid setup mismatch pid=%d task=%d(%d)",
+ mPid, mTaskPort.port(), mTaskPort.pid());
CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED); // you lied!
}
-
+
setup(info);
- ClientIdentification::setup(this->pid());
-
+ ClientIdentification::setup(this->audit_token());
+
+ if(!processCode()) {
+ // This can happen if the process died in the meantime.
+ secnotice("SecServer", "no process created in setup, old pid=%d old task=%d(%d)",
+ mPid, mTaskPort.port(), mTaskPort.pid());
+ CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED);
+ }
+
// NB: ServerChild::find() should only be used to determine
// *existence*. Don't use the returned Child object for anything else,
// as it is not protected against its underlying process's destruction.
|| ServerChild::find<ServerChild>(this->pid())) // securityd's child; do not mark this txn dirty
VProc::Transaction::deactivate();
- if (SECURITYD_CLIENT_NEW_ENABLED())
- SECURITYD_CLIENT_NEW(this, this->pid(), &this->session(),
- (char *)codePath(this->processCode()).c_str(), taskPort, mUid, mGid, mByteFlipped);
+ secinfo("SecServer", "%p client new: pid:%d session:%d %s taskPort:%d uid:%d gid:%d", this, this->pid(), this->session().sessionId(),
+ (char *)codePath(this->processCode()).c_str(), taskPort.port(), mUid, mGid);
}
{
StLock<Mutex> _(*this);
if (taskPort != mTaskPort) {
- secdebug("SS", "Process %p(%d) reset mismatch (tp %d-%d)",
+ secnotice("SecServer", "Process %p(%d) reset mismatch (tp %d-%d)",
this, pid(), taskPort.port(), mTaskPort.port());
//@@@ CssmError::throwMe(CSSM_ERRCODE_VERIFICATION_FAILURE); // liar
}
setup(info);
CFCopyRef<SecCodeRef> oldCode = processCode();
- ClientIdentification::setup(this->pid()); // re-constructs processCode()
+ ClientIdentification::setup(this->audit_token()); // re-constructs processCode()
if (CFEqual(oldCode, processCode())) {
- SECURITYD_CLIENT_RESET_AMNESIA(this);
+ secnotice("SecServer", "%p Client reset amnesia", this);
} else {
- SECURITYD_CLIENT_RESET_FULL(this);
+ secnotice("SecServer", "%p Client reset full", this);
CodeSigningHost::reset();
}
}
//
Process::~Process()
{
- SECURITYD_CLIENT_RELEASE(this, this->pid());
+ secinfo("SecServer", "%p client release: %d", this, this->pid());
- // tell all our authorizations that we're gone
- IFDEBUG(if (!mAuthorizations.empty())
- secdebug("SS", "Process %p(%d) clearing %d authorizations",
- this, mPid, int(mAuthorizations.size())));
- for (AuthorizationSet::iterator it = mAuthorizations.begin();
- it != mAuthorizations.end(); ) {
- AuthorizationToken *auth = *it;
- while (++it != mAuthorizations.end() && *it == auth) ; // Skip duplicates
- if (auth->endProcess(*this))
- delete auth;
- }
-
// release our name for the process's task port
- if (mTaskPort)
- mTaskPort.destroy();
+ if (mTaskPort) {
+ mTaskPort.deallocate();
+ }
}
void Process::kill()
void Process::checkSession(const audit_token_t &auditToken)
{
- AuditToken audit(auditToken);
+ Security::CommonCriteria::AuditToken audit(auditToken);
if (audit.sessionId() != this->session().sessionId())
this->changeSession(audit.sessionId());
}
{
// re-parent
parent(Session::find(sessionId, true));
- SECURITYD_CLIENT_CHANGE_SESSION(this, &this->session());
-}
-
-
-//
-// Authorization set maintainance
-//
-void Process::addAuthorization(AuthorizationToken *auth)
-{
- assert(auth);
- StLock<Mutex> _(*this);
- mAuthorizations.insert(auth);
- auth->addProcess(*this);
-}
-
-void Process::checkAuthorization(AuthorizationToken *auth)
-{
- assert(auth);
- StLock<Mutex> _(*this);
- if (mAuthorizations.find(auth) == mAuthorizations.end())
- MacOSError::throwMe(errAuthorizationInvalidRef);
-}
-
-bool Process::removeAuthorization(AuthorizationToken *auth)
-{
- assert(auth);
- StLock<Mutex> _(*this);
- // we do everything with a single set lookup call...
- typedef AuthorizationSet::iterator Iter;
- Iter it = mAuthorizations.lower_bound(auth);
- bool isLast;
- if (it == mAuthorizations.end() || auth != *it) {
- isLast = true;
- } else {
- Iter next = it; ++next; // following element
- isLast = (next == mAuthorizations.end()) || auth != *next;
- mAuthorizations.erase(it); // remove first match
- }
- if (isLast) {
- if (auth->endProcess(*this)) // ... tell it to remove us,
- return true; // ... and tell the caller
- }
- return false; // keep the auth; it's still in use
+ secnotice("SecServer", "%p client change session to %d", this, this->session().sessionId());
}