2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // sstransit - SecurityServer client library transition code.
22 // These are the functions that implement CssmClient methods in terms of
23 // MIG IPC client calls, plus their supporting machinery.
25 #include "sstransit.h"
30 using MachPlusPlus::check
;
31 using MachPlusPlus::VMGuard
;
36 // This happens "at the end" of a glue method, via the DataOutput destructor.
38 DataOutput::~DataOutput()
40 VMGuard
_(mData
, mLength
);
41 if (mData
) { // was assigned to; IPC returned OK
42 if (argument
) { // buffer was provided
43 if (argument
.length() < mLength
)
44 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
45 argument
.length(mLength
);
46 } else { // allocate buffer
47 argument
= CssmData(allocator
.malloc(mLength
), mLength
);
49 memcpy(argument
.data(), mData
, mLength
);
54 CssmList
chunkCopy(CssmList
&list
, CssmAllocator
&alloc
)
57 ChunkCopyWalker
w(alloc
);
64 // Create a packaged-up Context for IPC transmission.
65 // In addition to collecting the context into a contiguous blob for transmission,
66 // we also evaluate CssmCryptoData callbacks at this time.
68 SendContext::SendContext(const Context
&ctx
) : context(ctx
)
70 CssmCryptoData cryptoDataValue
; // holding area for CssmCryptoData element
71 IFDEBUG(uint32 cryptoDataUsed
= 0);
72 Context::Builder
builder(CssmAllocator::standard());
73 for (unsigned n
= 0; n
< ctx
.attributesInUse(); n
++) {
74 switch (ctx
[n
].baseType()) {
75 case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA
: {
76 CssmCryptoData
&data
= ctx
[n
]; // extract CssmCryptoData value
77 cryptoDataValue
= data(); // evaluate callback (if any)
78 builder
.setup(&cryptoDataValue
); // use evaluted value
79 IFDEBUG(cryptoDataUsed
++);
83 builder
.setup(ctx
[n
]);
87 attributeSize
= builder
.make();
88 for (unsigned n
= 0; n
< ctx
.attributesInUse(); n
++) {
89 const Context::Attr
&attr
= ctx
[n
];
90 switch (attr
.baseType()) {
91 case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA
:
92 builder
.put(attr
.type(), &cryptoDataValue
);
99 uint32 count
; // not needed
100 builder
.done(attributes
, count
);
101 assert(cryptoDataUsed
<= 1); // no more than one slot converted
105 namespace SecurityServer
111 DbHandle
ClientSession::createDb(const DLDbIdentifier
&dbId
,
112 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
113 const DBParameters
¶ms
)
115 Copier
<AccessCredentials
> creds(cred
, internalAllocator
);
116 Copier
<AclEntryPrototype
> proto(&owner
->proto(), internalAllocator
);
117 DataWalkers::DLDbFlatIdentifier
ident(dbId
);
118 Copier
<DataWalkers::DLDbFlatIdentifier
> id(&ident
, internalAllocator
);
120 IPC(ucsp_client_createDb(UCSP_ARGS
, &db
, COPY(id
), COPY(creds
), COPY(proto
), params
));
124 DbHandle
ClientSession::decodeDb(const DLDbIdentifier
&dbId
,
125 const AccessCredentials
*cred
, const CssmData
&blob
)
127 Copier
<AccessCredentials
> creds(cred
, internalAllocator
);
128 DataWalkers::DLDbFlatIdentifier
ident(dbId
);
129 Copier
<DataWalkers::DLDbFlatIdentifier
> id(&ident
, internalAllocator
);
131 IPC(ucsp_client_decodeDb(UCSP_ARGS
, &db
, COPY(id
), COPY(creds
), DATA(blob
)));
135 void ClientSession::encodeDb(DbHandle db
, CssmData
&blob
, CssmAllocator
&alloc
)
137 DataOutput
outBlob(blob
, alloc
);
138 IPC(ucsp_client_encodeDb(UCSP_ARGS
, db
, DATA(outBlob
)));
141 void ClientSession::releaseDb(DbHandle db
)
143 IPC(ucsp_client_releaseDb(UCSP_ARGS
, db
));
146 void ClientSession::authenticateDb(DbHandle db
, DBAccessType type
,
147 const AccessCredentials
*cred
)
149 Copier
<AccessCredentials
> creds(cred
, internalAllocator
);
150 IPC(ucsp_client_authenticateDb(UCSP_ARGS
, db
, COPY(creds
)));
153 void ClientSession::setDbParameters(DbHandle db
, const DBParameters
¶ms
)
155 IPC(ucsp_client_setDbParameters(UCSP_ARGS
, db
, params
));
158 void ClientSession::getDbParameters(DbHandle db
, DBParameters
¶ms
)
160 IPC(ucsp_client_getDbParameters(UCSP_ARGS
, db
, ¶ms
));
163 void ClientSession::changePassphrase(DbHandle db
, const AccessCredentials
*cred
)
165 Copier
<AccessCredentials
> creds(cred
, internalAllocator
);
166 IPC(ucsp_client_changePassphrase(UCSP_ARGS
, db
, COPY(creds
)));
170 void ClientSession::lock(DbHandle db
)
172 IPC(ucsp_client_lockDb(UCSP_ARGS
, db
));
175 void ClientSession::unlock(DbHandle db
)
177 IPC(ucsp_client_unlockDb(UCSP_ARGS
, db
));
180 void ClientSession::unlock(DbHandle db
, const CssmData
&passphrase
)
182 IPC(ucsp_client_unlockDbWithPassphrase(UCSP_ARGS
, db
, DATA(passphrase
)));
185 bool ClientSession::isLocked(DbHandle db
)
188 IPC(ucsp_client_isLocked(UCSP_ARGS
, db
, &locked
));
196 void ClientSession::encodeKey(KeyHandle key
, CssmData
&blob
,
197 KeyUID
*uid
, CssmAllocator
&alloc
)
199 DataOutput
oBlob(blob
, alloc
);
201 mach_msg_type_number_t uidLength
;
202 IPC(ucsp_client_encodeKey(UCSP_ARGS
, key
, oBlob
.data(), oBlob
.length(),
203 (uid
!= NULL
), &uidp
, &uidLength
));
204 // return key uid if requested
206 assert(uidLength
== sizeof(KeyUID
));
207 memcpy(uid
, uidp
, sizeof(KeyUID
));
212 KeyHandle
ClientSession::decodeKey(DbHandle db
, const CssmData
&blob
, CssmKey::Header
&header
)
215 IPC(ucsp_client_decodeKey(UCSP_ARGS
, &key
, &header
, db
, blob
.data(), blob
.length()));
219 void ClientSession::releaseKey(KeyHandle key
)
221 IPC(ucsp_client_releaseKey(UCSP_ARGS
, key
));
225 CssmKeySize
ClientSession::queryKeySizeInBits(KeyHandle key
)
228 IPC(ucsp_client_queryKeySizeInBits(UCSP_ARGS
, key
, &length
));
233 uint32
ClientSession::getOutputSize(const Context
&context
, KeyHandle key
,
234 uint32 inputSize
, bool encrypt
)
236 SendContext
ctx(context
);
238 IPC(ucsp_client_getOutputSize(UCSP_ARGS
, CONTEXT(ctx
), key
, inputSize
, encrypt
, &outputSize
));
244 // Random number generation.
245 // This interfaces to the secure RNG inside the SecurityServer; it does not access
246 // a PRNG in its CSP. If you need a reproducible PRNG, attach a local CSP and use it.
247 // Note that this function does not allocate a buffer; it always fills the buffer provided.
249 void ClientSession::generateRandom(CssmData
&data
)
252 mach_msg_type_number_t resultLength
;
253 IPC(ucsp_client_generateRandom(UCSP_ARGS
, data
.length(), &result
, &resultLength
));
254 assert(resultLength
== data
.length());
255 memcpy(data
.data(), result
, data
.length());
260 // Signatures and MACs
262 void ClientSession::generateSignature(const Context
&context
, KeyHandle key
,
263 const CssmData
&data
, CssmData
&signature
, CssmAllocator
&alloc
, CSSM_ALGORITHMS signOnlyAlgorithm
)
265 SendContext
ctx(context
);
266 DataOutput
sig(signature
, alloc
);
267 IPC(ucsp_client_generateSignature(UCSP_ARGS
, CONTEXT(ctx
), key
, signOnlyAlgorithm
,
268 DATA(data
), DATA(sig
)));
271 void ClientSession::verifySignature(const Context
&context
, KeyHandle key
,
272 const CssmData
&data
, const CssmData
&signature
, CSSM_ALGORITHMS verifyOnlyAlgorithm
)
274 SendContext
ctx(context
);
275 IPC(ucsp_client_verifySignature(UCSP_ARGS
, CONTEXT(ctx
), key
, verifyOnlyAlgorithm
,
276 DATA(data
), DATA(signature
)));
280 void ClientSession::generateMac(const Context
&context
, KeyHandle key
,
281 const CssmData
&data
, CssmData
&signature
, CssmAllocator
&alloc
)
283 SendContext
ctx(context
);
284 DataOutput
sig(signature
, alloc
);
285 IPC(ucsp_client_generateMac(UCSP_ARGS
, CONTEXT(ctx
), key
,
286 DATA(data
), DATA(sig
)));
289 void ClientSession::verifyMac(const Context
&context
, KeyHandle key
,
290 const CssmData
&data
, const CssmData
&signature
)
292 SendContext
ctx(context
);
293 IPC(ucsp_client_verifyMac(UCSP_ARGS
, CONTEXT(ctx
), key
,
294 DATA(data
), DATA(signature
)));
299 // Encryption/Decryption
302 void ClientSession::encrypt(const Context
&context
, KeyHandle key
,
303 const CssmData
&clear
, CssmData
&cipher
, CssmAllocator
&alloc
)
305 SendContext
ctx(context
);
306 DataOutput
cipherOut(cipher
, alloc
);
307 IPC(ucsp_client_encrypt(UCSP_ARGS
, CONTEXT(ctx
), key
, DATA(clear
), DATA(cipherOut
)));
310 void ClientSession::decrypt(const Context
&context
, KeyHandle key
,
311 const CssmData
&cipher
, CssmData
&clear
, CssmAllocator
&alloc
)
313 SendContext
ctx(context
);
314 DataOutput
clearOut(clear
, alloc
);
315 IPC(ucsp_client_decrypt(UCSP_ARGS
, CONTEXT(ctx
), key
, DATA(cipher
), DATA(clearOut
)));
322 void ClientSession::generateKey(DbHandle db
, const Context
&context
, uint32 keyUsage
, uint32 keyAttr
,
323 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
324 KeyHandle
&newKey
, CssmKey::Header
&newHeader
)
326 SendContext
ctx(context
);
327 Copier
<AccessCredentials
> creds(cred
, internalAllocator
);
328 Copier
<AclEntryPrototype
> proto(&owner
->proto(), internalAllocator
);
329 IPC(ucsp_client_generateKey(UCSP_ARGS
, db
, CONTEXT(ctx
),
330 COPY(creds
), COPY(proto
), keyUsage
, keyAttr
, &newKey
, &newHeader
));
333 void ClientSession::generateKey(DbHandle db
, const Context
&context
,
334 uint32 pubKeyUsage
, uint32 pubKeyAttr
,
335 uint32 privKeyUsage
, uint32 privKeyAttr
,
336 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
337 KeyHandle
&pubKey
, CssmKey::Header
&pubHeader
,
338 KeyHandle
&privKey
, CssmKey::Header
&privHeader
)
340 SendContext
ctx(context
);
341 Copier
<AccessCredentials
> creds(cred
, internalAllocator
);
342 Copier
<AclEntryPrototype
> proto(&owner
->proto(), internalAllocator
);
343 IPC(ucsp_client_generateKeyPair(UCSP_ARGS
, db
, CONTEXT(ctx
),
344 COPY(creds
), COPY(proto
),
345 pubKeyUsage
, pubKeyAttr
, privKeyUsage
, privKeyAttr
,
346 &pubKey
, &pubHeader
, &privKey
, &privHeader
));
352 // This is a bit strained; the incoming 'param' value may have structure
353 // and needs to be handled on a per-algorithm basis, which means we have to
354 // know which key derivation algorithms we support for passing to our CSP(s).
355 // The default behavior is to handle "flat" data blobs, which is as good
356 // a default as we can manage.
357 // NOTE: The param-specific handling must be synchronized with the server
358 // transition layer code (in transition.cpp).
360 void ClientSession::deriveKey(DbHandle db
, const Context
&context
, KeyHandle baseKey
,
361 uint32 keyUsage
, uint32 keyAttr
, CssmData
¶m
,
362 const AccessCredentials
*cred
, const AclEntryInput
*owner
,
363 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, CssmAllocator
&allocator
)
365 SendContext
ctx(context
);
366 Copier
<AccessCredentials
> creds(cred
, internalAllocator
);
367 Copier
<AclEntryPrototype
> proto(&owner
->proto(), internalAllocator
);
368 DataOutput
paramOutput(param
, allocator
);
369 switch (context
.algorithm()) {
370 case CSSM_ALGID_PKCS5_PBKDF2
: {
371 typedef CSSM_PKCS5_PBKDF2_PARAMS Params
;
372 Copier
<Params
> params(param
.interpretedAs
<Params
> (sizeof(Params
)), internalAllocator
);
373 IPC(ucsp_client_deriveKey(UCSP_ARGS
, db
, CONTEXT(ctx
), baseKey
,
374 COPY(creds
), COPY(proto
), COPY(params
), DATA(paramOutput
),
375 keyUsage
, keyAttr
, &newKey
, &newHeader
));
378 IPC(ucsp_client_deriveKey(UCSP_ARGS
, db
, CONTEXT(ctx
), baseKey
,
379 COPY(creds
), COPY(proto
),
380 param
.data(), param
.length(), param
.data(),
382 keyUsage
, keyAttr
, &newKey
, &newHeader
));
389 // Key wrapping and unwrapping
391 void ClientSession::wrapKey(const Context
&context
, KeyHandle wrappingKey
,
392 KeyHandle keyToBeWrapped
, const AccessCredentials
*cred
,
393 const CssmData
*descriptiveData
, CssmWrappedKey
&wrappedKey
, CssmAllocator
&alloc
)
395 SendContext
ctx(context
);
396 Copier
<AccessCredentials
> creds(cred
, internalAllocator
);
397 DataOutput
keyData(wrappedKey
, alloc
);
398 IPC(ucsp_client_wrapKey(UCSP_ARGS
, CONTEXT(ctx
), wrappingKey
, COPY(creds
),
399 keyToBeWrapped
, OPTIONALDATA(descriptiveData
),
400 &wrappedKey
, DATA(keyData
)));
401 wrappedKey
= CssmData(); // null out data section (force allocation for key data)
404 void ClientSession::unwrapKey(DbHandle db
, const Context
&context
, KeyHandle key
,
405 KeyHandle publicKey
, const CssmWrappedKey
&wrappedKey
,
406 uint32 usage
, uint32 attr
,
407 const AccessCredentials
*cred
, const AclEntryInput
*acl
,
408 CssmData
&descriptiveData
,
409 KeyHandle
&newKey
, CssmKey::Header
&newHeader
, CssmAllocator
&alloc
)
411 SendContext
ctx(context
);
412 DataOutput
descriptor(descriptiveData
, alloc
);
413 Copier
<AccessCredentials
> creds(cred
, internalAllocator
);
414 Copier
<AclEntryPrototype
> proto(&acl
->proto(), internalAllocator
);
415 IPC(ucsp_client_unwrapKey(UCSP_ARGS
, db
, CONTEXT(ctx
), key
,
416 COPY(creds
), COPY(proto
),
417 publicKey
, wrappedKey
, DATA(wrappedKey
), usage
, attr
, DATA(descriptor
),
418 &newKey
, &newHeader
));
425 void ClientSession::getAcl(AclKind kind
, KeyHandle key
, const char *tag
,
426 uint32
&infoCount
, AclEntryInfo
* &infoArray
, CssmAllocator
&alloc
)
429 AclEntryInfo
*info
, *infoBase
;
430 mach_msg_type_number_t infoLength
;
431 IPC(ucsp_client_getAcl(UCSP_ARGS
, kind
, key
,
432 (tag
!= NULL
), tag
? tag
: "",
433 &count
, COPY_OUT(info
)));
434 VMGuard
_(info
, infoLength
);
437 // relocate incoming AclEntryInfo array
438 ReconstituteWalker
relocator(info
, infoBase
);
439 for (uint32 n
= 0; n
< count
; n
++)
440 walk(relocator
, info
[n
]);
442 // copy AclEntryInfo array into discrete memory nodes
443 infoArray
= alloc
.alloc
<AclEntryInfo
>(count
);
444 ChunkCopyWalker
chunker(alloc
);
445 for (uint32 n
= 0; n
< count
; n
++) {
446 infoArray
[n
] = info
[n
];
447 walk(chunker
, infoArray
[n
]);
451 void ClientSession::changeAcl(AclKind kind
, KeyHandle key
, const AccessCredentials
&cred
,
454 Copier
<AccessCredentials
> creds(&cred
, internalAllocator
);
455 //@@@ ignoring callback
456 Copier
<AclEntryInput
> newEntry(edit
.newEntry(), internalAllocator
);
457 IPC(ucsp_client_changeAcl(UCSP_ARGS
, kind
, key
, COPY(creds
),
458 edit
.mode(), edit
.handle(), COPY(newEntry
)));
461 void ClientSession::getOwner(AclKind kind
, KeyHandle key
, AclOwnerPrototype
&owner
,
462 CssmAllocator
&alloc
)
464 AclOwnerPrototype
*proto
, *protoBase
;
465 mach_msg_type_number_t protoLength
;
466 IPC(ucsp_client_getOwner(UCSP_ARGS
, kind
, key
, COPY_OUT(proto
)));
467 // turn the returned AclOwnerPrototype into its proper output form
468 relocate(proto
, protoBase
);
469 owner
.TypedSubject
= chunkCopy(proto
->subject(), alloc
);
470 owner
.Delegate
= proto
->delegate();
473 void ClientSession::changeOwner(AclKind kind
, KeyHandle key
,
474 const AccessCredentials
&cred
, const AclOwnerPrototype
&proto
)
476 Copier
<AccessCredentials
> creds(&cred
, internalAllocator
);
477 Copier
<AclOwnerPrototype
> protos(&proto
, internalAllocator
);
478 IPC(ucsp_client_setOwner(UCSP_ARGS
, kind
, key
, COPY(creds
), COPY(protos
)));
482 void ClientSession::getKeyAcl(DbHandle db
, const char *tag
,
483 uint32
&count
, AclEntryInfo
* &info
, CssmAllocator
&alloc
)
484 { getAcl(keyAcl
, db
, tag
, count
, info
, alloc
); }
486 void ClientSession::changeKeyAcl(DbHandle db
, const AccessCredentials
&cred
,
488 { changeAcl(keyAcl
, db
, cred
, edit
); }
490 void ClientSession::getKeyOwner(DbHandle db
, AclOwnerPrototype
&owner
, CssmAllocator
&alloc
)
491 { getOwner(keyAcl
, db
, owner
, alloc
); }
493 void ClientSession::changeKeyOwner(DbHandle db
, const AccessCredentials
&cred
,
494 const AclOwnerPrototype
&edit
)
495 { changeOwner(keyAcl
, db
, cred
, edit
); }
497 void ClientSession::getDbAcl(DbHandle db
, const char *tag
,
498 uint32
&count
, AclEntryInfo
* &info
, CssmAllocator
&alloc
)
499 { getAcl(dbAcl
, db
, tag
, count
, info
, alloc
); }
501 void ClientSession::changeDbAcl(DbHandle db
, const AccessCredentials
&cred
,
503 { changeAcl(dbAcl
, db
, cred
, edit
); }
505 void ClientSession::getDbOwner(DbHandle db
, AclOwnerPrototype
&owner
, CssmAllocator
&alloc
)
506 { getOwner(dbAcl
, db
, owner
, alloc
); }
508 void ClientSession::changeDbOwner(DbHandle db
, const AccessCredentials
&cred
,
509 const AclOwnerPrototype
&edit
)
510 { changeOwner(dbAcl
, db
, cred
, edit
); }
514 // Authorization subsystem entry
516 void ClientSession::authCreate(const AuthorizationItemSet
*rights
,
517 const AuthorizationItemSet
*environment
, AuthorizationFlags flags
,
518 AuthorizationBlob
&result
)
520 Copier
<AuthorizationItemSet
> rightSet(rights
, internalAllocator
);
521 Copier
<AuthorizationItemSet
> environ(environment
, internalAllocator
);
522 IPC(ucsp_client_authorizationCreate(UCSP_ARGS
,
523 COPY(rightSet
), flags
, COPY(environ
), &result
));
526 void ClientSession::authRelease(const AuthorizationBlob
&auth
,
527 AuthorizationFlags flags
)
529 IPC(ucsp_client_authorizationRelease(UCSP_ARGS
, auth
, flags
));
532 void ClientSession::authCopyRights(const AuthorizationBlob
&auth
,
533 const AuthorizationItemSet
*rights
, const AuthorizationItemSet
*environment
,
534 AuthorizationFlags flags
,
535 AuthorizationItemSet
**grantedRights
)
537 Copier
<AuthorizationItemSet
> rightSet(rights
, internalAllocator
);
538 Copier
<AuthorizationItemSet
> environ(environment
, internalAllocator
);
539 COPY_OUT_DECL(AuthorizationItemSet
, result
);
540 IPC(ucsp_client_authorizationCopyRights(UCSP_ARGS
, auth
, COPY(rightSet
),
541 flags
| (grantedRights
? 0 : kAuthorizationFlagNoData
),
542 COPY(environ
), COPY_OUT(result
)));
543 VMGuard
_(result
, resultLength
);
544 // return rights vector (only) if requested
546 relocate(result
, resultBase
);
547 *grantedRights
= copy(result
, returnAllocator
);
551 void ClientSession::authCopyInfo(const AuthorizationBlob
&auth
,
553 AuthorizationItemSet
* &info
)
555 COPY_OUT_DECL(AuthorizationItemSet
, result
);
558 else if (tag
[0] == '\0')
559 MacOSError::throwMe(errAuthorizationInvalidTag
);
560 IPC(ucsp_client_authorizationCopyInfo(UCSP_ARGS
, auth
, tag
, COPY_OUT(result
)));
561 VMGuard
_(result
, resultLength
);
562 relocate(result
, resultBase
);
563 info
= copy(result
, returnAllocator
);
566 void ClientSession::authExternalize(const AuthorizationBlob
&auth
,
567 AuthorizationExternalForm
&extForm
)
569 IPC(ucsp_client_authorizationExternalize(UCSP_ARGS
, auth
, &extForm
));
572 void ClientSession::authInternalize(const AuthorizationExternalForm
&extForm
,
573 AuthorizationBlob
&auth
)
575 IPC(ucsp_client_authorizationInternalize(UCSP_ARGS
, extForm
, &auth
));
580 // Session management API
582 void ClientSession::getSessionInfo(SecuritySessionId
&sessionId
, SessionAttributeBits
&attrs
)
584 IPC(ucsp_client_getSessionInfo(UCSP_ARGS
, &sessionId
, &attrs
));
587 void ClientSession::setupSession(SessionCreationFlags flags
, SessionAttributeBits attrs
)
589 mSetupSession
= true; // global flag to Global constructor
590 mGlobal
.reset(); // kill existing cache, all threads
591 IPC(ucsp_client_setupSession(UCSP_ARGS
, flags
, attrs
));
596 // Notification subsystem
598 void ClientSession::requestNotification(Port receiver
, NotifyDomain domain
, NotifyEvents events
)
600 IPC(ucsp_client_requestNotification(UCSP_ARGS
, receiver
, domain
, events
));
603 void ClientSession::stopNotification(Port port
)
605 IPC(ucsp_client_stopNotification(UCSP_ARGS
, port
.port()));
608 void ClientSession::postNotification(NotifyDomain domain
, NotifyEvent event
, const CssmData
&data
)
610 IPC(ucsp_client_postNotification(UCSP_ARGS
, domain
, event
, DATA(data
)));
613 OSStatus
ClientSession::dispatchNotification(const mach_msg_header_t
*message
,
614 ConsumeNotification
*consumer
, void *context
)
617 mach_msg_header_t Head
;
618 /* start of the kernel processed data */
619 mach_msg_body_t msgh_body
;
620 mach_msg_ool_descriptor_t data
;
621 /* end of the kernel processed data */
625 mach_msg_type_number_t dataCnt
;
627 } *msg
= (Message
*)message
;
629 OSStatus status
= consumer(msg
->domain
, msg
->event
, msg
->data
.address
, msg
->dataCnt
, context
);
631 mig_deallocate((vm_offset_t
) msg
->data
.address
, msg
->dataCnt
);
632 msg
->data
.address
= (vm_offset_t
) 0;
633 msg
->data
.size
= (mach_msg_size_t
) 0;
639 } // end namespace SecurityServer
640 } // end namespace Security