2 * Copyright (c) 2000-2009 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // connection - manage connections to clients.
28 // Note that Connection objects correspond to client process threads, and are
29 // thus inherently single-threaded. It is physically impossible for multiple
30 // requests to come in for the same Connection, unless the client side is
31 // illegally messing with the IPC protocol (for which we check below).
32 // It is still necessary to take the object lock for a Connection because there
33 // are times when we want to manipulate a busy Connection from another securityd
34 // thread (say, in response to a DPN).
36 #include "connection.h"
40 #include <security_cdsa_client/keyclient.h>
41 #include <security_cdsa_client/genkey.h>
42 #include <security_cdsa_client/wrapkey.h>
43 #include <security_cdsa_client/signclient.h>
44 #include <security_cdsa_client/macclient.h>
45 #include <security_cdsa_client/cryptoclient.h>
49 // Construct a Connection object.
51 Connection::Connection(Process
&proc
, Port rPort
)
52 : mClientPort(rPort
), mGuestRef(kSecNoGuest
), state(idle
), agentWait(NULL
)
56 // bump the send-rights count on the reply port so we keep the right after replying
57 mClientPort
.modRefs(MACH_PORT_RIGHT_SEND
, +1);
59 secinfo("SecServer", "New client connection %p: %d %d", this, rPort
.port(), proc
.uid());
64 // When a Connection's destructor executes, the connection must already have been
65 // terminated. All we have to do here is clean up a bit.
67 Connection::~Connection() try
69 mClientPort
.deallocate();
70 secinfo("SecServer", "releasing client connection %p", this);
73 secerror("SecServer: Error deallocating connection port");
78 // Set the (last known) guest handle for this connection.
80 void Connection::guestRef(SecGuestRef newGuest
, SecCSFlags flags
)
82 secinfo("SecServer", "Connection %p switches to guest 0x%x", this, newGuest
);
87 // Service request framing.
88 // These are here so "hanging" connection service threads don't fall
89 // into the Big Bad Void as Connections and processes drop out from
92 void Connection::beginWork(audit_token_t
&auditToken
)
94 // assume the audit token will be valid for the Connection's lifetime
96 mAuditToken
= &auditToken
;
100 mOverrideReturn
= CSSM_OK
; // clear override
103 secinfo("SecServer", "Attempt to re-enter connection %p(port %d)", this, mClientPort
.port());
104 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR
); //@@@ some state-error code instead?
110 void Connection::checkWork()
112 StLock
<Mutex
> _(*this);
117 agentWait
= NULL
; // obviously we're not waiting on this
124 void Connection::endWork(CSSM_RETURN
&rcode
)
130 if (mOverrideReturn
&& rcode
== CSSM_OK
)
131 rcode
= mOverrideReturn
;
135 secinfo("SecServer", "Connection %p abort resuming", this);