2 * Copyright (c) 2006-2008,2010 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 // csproxy - Code Signing Hosting Proxy
31 #include <security_utilities/casts.h>
32 #include <security_utilities/cfutilities.h>
33 #include <security_utilities/debugging_internal.h>
34 #include <security_cdsa_utilities/handleobject.h>
35 #include <security_utilities/mach++.h>
36 #include <security_utilities/machserver.h>
37 #include <security_cdsa_utilities/cssmdata.h>
38 #include <securityd_client/cshosting.h>
39 #include <Security/SecCodeHost.h>
43 using MachPlusPlus::Port
;
44 using MachPlusPlus::MachServer
;
48 // CodeSigningHost is a mix-in for an object representing a primary
49 // Code Signing host object. It performs two notionally separate functions:
50 // (1) Register a hosting port.
51 // (2) Optionally, maintain a guest registry to offload the host's work.
53 class CodeSigningHost
: private MachServer::Handler
{
60 noHosting
, // is not a host (yet), could go either way
61 dynamicHosting
, // gave us its own hosting port to keep
62 proxyHosting
// we act as a proxy for it
66 strict
, // direct guest relationship required
67 loose
// indirect or identity is okay (prefix check)
70 struct Guest
: public RefCount
, public HandleObject
{
74 std::vector
<SecGuestRef
> guestPath
; // guest chain to this guest
75 uint32_t status
; // dynamic status
76 std::string path
; // canonical code path
77 CFRef
<CFDictionaryRef
> attributes
; // matching attributes set
78 CFRef
<CFDataRef
> cdhash
; // hash of CodeDirectory as specified by host
79 bool dedicated
; // host is dedicated (and this is the only guest)
81 operator bool() const { return attributes
; } // exists
82 SecGuestRef
guestRef() const { return int_cast
<long, SecGuestRef
>(handle()); }
83 void setAttributes(const CssmData
&attrData
);
84 uint8_t const *attrData() const { createAttrData(); return mAttrData
; };
85 CFIndex
attrDataLength() const { createAttrData(); return mAttrDataLength
; };
86 void setHash(const CssmData
&given
, bool generate
);
88 bool isGuestOf(Guest
*host
, GuestCheck check
) const;
89 bool matches(CFIndex count
, CFTypeRef keys
[], CFTypeRef values
[]) const;
91 IFDUMP(void dump() const);
94 void createAttrData() const;
96 mutable uint8_t *mAttrData
; // XML form of attributes (vm_allocate'd, must live until guest destruction)
97 mutable CFIndex mAttrDataLength
;
100 void registerCodeSigning(mach_port_t hostingPort
, SecCSFlags flags
);
101 Port
hostingPort() const { return mHostingPort
; }
103 SecGuestRef
createGuest(SecGuestRef guest
,
104 uint32_t status
, const char *path
,
105 const CssmData
&cdhash
, const CssmData
&attributes
, SecCSFlags flags
);
106 void setGuestStatus(SecGuestRef guest
, uint32_t status
, const CssmData
&attributes
);
107 void removeGuest(SecGuestRef host
, SecGuestRef guest
);
110 IFDUMP(void dump() const);
113 // internal use only (public for use by MIG handlers)
114 Guest
*findHost(SecGuestRef hostRef
); // find most dedicated guest of this host
115 Guest
*findGuest(Guest
*host
, const CssmData
&attrData
); // by host and attributes
116 Guest
*findGuest(SecGuestRef guestRef
, bool hostOk
= false); // by guest reference
117 Guest
*findGuest(Guest
*host
); // any guest of this host
123 boolean_t
handle(mach_msg_header_t
*in
, mach_msg_header_t
*out
);
124 void eraseGuest(Guest
*guest
);
127 mutable Mutex mLock
; // protects everything below
129 // host port registry
130 HostingState mHostingState
; // status of hosting support
131 Port mHostingPort
; // his or ours or NULL
133 // guest map (only used if mHostingState == proxyHosting)
134 typedef std::map
<SecGuestRef
, RefPointer
<Guest
> > GuestMap
;
140 // Proxy implementation of Code Signing Hosting protocol
142 #define CSH_ARGS mach_port_t servicePort, mach_port_t replyPort, OSStatus *rcode
144 #define DATA_IN(base) void *base, mach_msg_type_number_t base##Length
145 #define DATA_OUT(base) void **base, mach_msg_type_number_t *base##Length
146 #define DATA(base) CssmData(base, base##Length)
149 // Find a guest by arbitrary attribute set.
151 // This returns an array of canonical guest references describing the path
152 // from the host given to the guest found. If the host itself is returned
153 // as a guest, this will be an empty array (zero length).
155 // The subhost return argument may in the future return the hosting port for
156 // a guest who dynamically manages its hosting (thus breaking out of proxy mode),
157 // but this is not yet implemented.
159 kern_return_t
cshosting_server_findGuest(CSH_ARGS
, SecGuestRef hostRef
,
161 GuestChain
*foundGuest
, mach_msg_type_number_t
*depth
, mach_port_t
*subhost
);
164 // Retrieve the path to a guest specified by canonical reference.
166 kern_return_t
cshosting_server_identifyGuest(CSH_ARGS
, SecGuestRef guestRef
,
167 char *path
, char *hash
, uint32_t *hashLength
, DATA_OUT(attributes
));
170 // Retrieve the status word for a guest specified by canonical reference.
172 kern_return_t
cshosting_server_guestStatus(CSH_ARGS
, SecGuestRef guestRef
, uint32_t *status
);