]> git.saurik.com Git - apple/security.git/blame - securityd/src/process.cpp
Security-58286.51.6.tar.gz
[apple/security.git] / securityd / src / process.cpp
CommitLineData
d8f41ccd
A
1/*
2 * Copyright (c) 2000-2009,2012 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25//
26// process - track a single client process and its belongings
27//
28#include "process.h"
29#include "server.h"
30#include "session.h"
31#include "tempdatabase.h"
d8f41ccd
A
32#include "child.h" // ServerChild (really UnixPlusPlus::Child)::find()
33
fa7225c8 34#include <security_utilities/ccaudit.h>
d8f41ccd
A
35#include <security_utilities/logging.h> //@@@ debug only
36#include "agentquery.h"
37
38
39//
40// Construct a Process object.
41//
42Process::Process(TaskPort taskPort, const ClientSetupInfo *info, const CommonCriteria::AuditToken &audit)
43 : mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid())
44{
45 StLock<Mutex> _(*this);
46
47 // set parent session
48 parent(Session::find(audit.sessionId(), true));
49
50 // let's take a look at our wannabe client...
51 if (mTaskPort.pid() != mPid) {
fa7225c8 52 secnotice("SS", "Task/pid setup mismatch pid=%d task=%d(%d)",
d8f41ccd
A
53 mPid, mTaskPort.port(), mTaskPort.pid());
54 CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED); // you lied!
55 }
56
57 setup(info);
58 ClientIdentification::setup(this->pid());
59
60 // NB: ServerChild::find() should only be used to determine
61 // *existence*. Don't use the returned Child object for anything else,
62 // as it is not protected against its underlying process's destruction.
63 if (this->pid() == getpid() // called ourselves (through some API). Do NOT record this as a "dirty" transaction
64 || ServerChild::find<ServerChild>(this->pid())) // securityd's child; do not mark this txn dirty
65 VProc::Transaction::deactivate();
66
b04fe171 67 secinfo("SS", "%p client new: pid:%d session:%d %s taskPort:%d uid:%d gid:%d", this, this->pid(), this->session().sessionId(),
fa7225c8 68 (char *)codePath(this->processCode()).c_str(), taskPort.port(), mUid, mGid);
d8f41ccd
A
69}
70
71
72//
73// Screen a process setup request for an existing process.
74// This means the client has requested intialization even though we remember having
75// talked to it in the past. This could either be an exec(2), or the client could just
76// have forgotten all about its securityd client state. Or it could be an attack...
77//
78void Process::reset(TaskPort taskPort, const ClientSetupInfo *info, const CommonCriteria::AuditToken &audit)
79{
80 StLock<Mutex> _(*this);
81 if (taskPort != mTaskPort) {
fa7225c8 82 secnotice("SS", "Process %p(%d) reset mismatch (tp %d-%d)",
d8f41ccd
A
83 this, pid(), taskPort.port(), mTaskPort.port());
84 //@@@ CssmError::throwMe(CSSM_ERRCODE_VERIFICATION_FAILURE); // liar
85 }
86 setup(info);
87 CFCopyRef<SecCodeRef> oldCode = processCode();
88
89 ClientIdentification::setup(this->pid()); // re-constructs processCode()
90 if (CFEqual(oldCode, processCode())) {
fa7225c8 91 secnotice("SS", "%p Client reset amnesia", this);
d8f41ccd 92 } else {
fa7225c8 93 secnotice("SS", "%p Client reset full", this);
d8f41ccd
A
94 CodeSigningHost::reset();
95 }
96}
97
98
99//
100// Common set processing
101//
102void Process::setup(const ClientSetupInfo *info)
103{
104 // process setup info
105 assert(info);
106 uint32 pversion;
107 if (info->order == 0x1234) { // right side up
108 pversion = info->version;
109 mByteFlipped = false;
110 } else if (info->order == 0x34120000) { // flip side up
111 pversion = flip(info->version);
112 mByteFlipped = true;
113 } else // non comprende
114 CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION);
115
116 // check wire protocol version
117 if (pversion != SSPROTOVERSION)
118 CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION);
119}
120
121
122//
123// Clean up a Process object
124//
125Process::~Process()
126{
b04fe171 127 secinfo("SS", "%p client release: %d", this, this->pid());
fa7225c8 128
d8f41ccd
A
129 // release our name for the process's task port
130 if (mTaskPort)
131 mTaskPort.destroy();
132}
133
134void Process::kill()
135{
136 StLock<Mutex> _(*this);
137
138 // release local temp store
139 mLocalStore = NULL;
140
141 // standard kill processing
142 PerProcess::kill();
143}
144
145
146Session& Process::session() const
147{
148 return parent<Session>();
149}
150
151
152void Process::checkSession(const audit_token_t &auditToken)
153{
fa7225c8 154 Security::CommonCriteria::AuditToken audit(auditToken);
d8f41ccd
A
155 if (audit.sessionId() != this->session().sessionId())
156 this->changeSession(audit.sessionId());
157}
158
159
160LocalDatabase &Process::localStore()
161{
162 StLock<Mutex> _(*this);
163 if (!mLocalStore)
164 mLocalStore = new TempDatabase(*this);
165 return *mLocalStore;
166}
167
168Key *Process::makeTemporaryKey(const CssmKey &key, CSSM_KEYATTR_FLAGS moreAttributes,
169 const AclEntryPrototype *owner)
170{
171 return safer_cast<TempDatabase&>(localStore()).makeKey(key, moreAttributes, owner);
172}
173
174
175//
176// Change the session of a process.
177// This is the result of SessionCreate from a known process client.
178//
179void Process::changeSession(Session::SessionId sessionId)
180{
181 // re-parent
182 parent(Session::find(sessionId, true));
fa7225c8 183 secnotice("SS", "%p client change session to %d", this, this->session().sessionId());
d8f41ccd
A
184}
185
186
187//
188// Debug dump support
189//
190#if defined(DEBUGDUMP)
191
192void Process::dumpNode()
193{
194 PerProcess::dumpNode();
195 if (mByteFlipped)
196 Debug::dump(" FLIPPED");
197 Debug::dump(" task=%d pid=%d uid/gid=%d/%d",
198 mTaskPort.port(), mPid, mUid, mGid);
199 CodeSigningHost::dump();
200 ClientIdentification::dump();
201}
202
203#endif //DEBUGDUMP