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 // transition - SecurityServer IPC-to-class-methods transition layer
22 #include <Security/AuthorizationWalkers.h>
26 #include "xdatabase.h"
27 #include <mach/mach_error.h>
33 #define UCSP_ARGS mach_port_t servicePort, mach_port_t replyPort, security_token_t securityToken, \
35 #define CONTEXT_ARGS Context context, Pointer contextBase, Context::Attr *attributes, mach_msg_type_number_t attrCount
37 #define BEGIN_IPCN *rcode = CSSM_OK; try {
38 #define BEGIN_IPC BEGIN_IPCN Connection &connection = Server::connection(replyPort);
39 #define END_IPC(base) END_IPCN(base) Server::requestComplete(); return KERN_SUCCESS;
40 #define END_IPCN(base) } \
41 catch (const CssmCommonError &err) { *rcode = err.cssmError(CSSM_ ## base ## _BASE_ERROR); } \
42 catch (const std::bad_alloc &) { *rcode = CssmError::merge(CSSM_ERRCODE_MEMORY_ERROR, CSSM_ ## base ## _BASE_ERROR); } \
43 catch (Connection *conn) { *rcode = 0; } \
44 catch (...) { *rcode = CssmError::merge(CSSM_ERRCODE_INTERNAL_ERROR, CSSM_ ## base ## _BASE_ERROR); }
46 #define DATA_IN(base) void *base, mach_msg_type_number_t base##Length
47 #define DATA_OUT(base) void **base, mach_msg_type_number_t *base##Length
48 #define DATA(base) CssmData(base, base##Length)
50 #define COPY_IN(type,name) type *name, mach_msg_type_number_t name##Length, type *name##Base
51 #define COPY_OUT(type,name) \
52 type **name, mach_msg_type_number_t *name##Length, type **name##Base
55 using LowLevelMemoryUtilities::increment
;
56 using LowLevelMemoryUtilities::difference
;
60 // An OutputData object will take memory allocated within the SecurityServer,
61 // hand it to the MIG return-output parameters, and schedule it to be released
62 // after the MIG reply has been sent. It will also get rid of it in case of
65 class OutputData
: public CssmData
{
67 OutputData(void **outP
, mach_msg_type_number_t
*outLength
)
68 : mData(*outP
), mLength(*outLength
) { }
70 { mData
= data(); mLength
= length(); Server::releaseWhenDone(mData
); }
72 void operator = (const CssmData
&source
)
73 { CssmData::operator = (source
); }
77 mach_msg_type_number_t
&mLength
;
82 // A CheckingReconstituteWalker is a variant of an ordinary ReconstituteWalker
83 // that checks object pointers and sizes against the incoming block limits.
84 // It throws an exception if incoming data has pointers outside the incoming block.
85 // This avoids trouble inside of the SecurityServer caused (by bug or malice)
86 // from someone spoofing the client access side.
88 class CheckingReconstituteWalker
{
90 CheckingReconstituteWalker(void *ptr
, void *base
, size_t size
)
91 : mBase(base
), mLimit(increment(base
, size
)), mOffset(difference(ptr
, base
)) { }
94 void operator () (T
* &addr
, size_t size
= sizeof(T
))
97 if (addr
< mBase
|| increment(addr
, size
) > mLimit
)
98 CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER
);
99 addr
= increment
<T
>(addr
, mOffset
);
103 static const bool needsRelinking
= true;
104 static const bool needsSize
= false;
107 void *mBase
; // old base address
108 void *mLimit
; // old last byte address + 1
109 off_t mOffset
; // relocation offset
113 void relocate(T
*obj
, T
*base
, size_t size
)
116 if (base
== NULL
) // invalid, could confuse walkers
117 CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER
);
118 CheckingReconstituteWalker
w(obj
, base
, size
);
125 // Setup/Teardown functions.
127 kern_return_t
ucsp_server_setup(UCSP_ARGS
, mach_port_t taskPort
, const char *identity
)
130 Server::active().setupConnection(servicePort
, replyPort
, taskPort
, securityToken
, identity
);
135 kern_return_t
ucsp_server_setupNew(UCSP_ARGS
, mach_port_t taskPort
, const char *identity
,
136 mach_port_t
*newServicePort
)
139 Session
*session
= new DynamicSession(TaskPort(taskPort
).bootstrap());
140 Server::active().setupConnection(session
->servicePort(), replyPort
,
141 taskPort
, securityToken
, identity
);
142 *newServicePort
= session
->servicePort();
147 kern_return_t
ucsp_server_teardown(UCSP_ARGS
)
150 Server::active().endConnection(replyPort
);
157 // Database management
159 kern_return_t
ucsp_server_createDb(UCSP_ARGS
, DbHandle
*db
,
160 COPY_IN(DLDbFlatIdentifier
, ident
),
161 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
165 relocate(cred
, credBase
, credLength
);
166 relocate(owner
, ownerBase
, ownerLength
);
167 relocate(ident
, identBase
, identLength
);
168 *db
= (new Database(*ident
, params
, connection
.process
, cred
, owner
))->handle();
172 kern_return_t
ucsp_server_decodeDb(UCSP_ARGS
, DbHandle
*db
,
173 COPY_IN(DLDbFlatIdentifier
, ident
), COPY_IN(AccessCredentials
, cred
), DATA_IN(blob
))
176 relocate(cred
, credBase
, credLength
);
177 relocate(ident
, identBase
, identLength
);
178 *db
= (new Database(*ident
, DATA(blob
).interpretedAs
<DbBlob
>(),
179 connection
.process
, cred
))->handle();
183 kern_return_t
ucsp_server_encodeDb(UCSP_ARGS
, DbHandle db
, DATA_OUT(blob
))
186 DbBlob
*dbBlob
= Server::database(db
).encode(); // memory owned by database
188 *blobLength
= dbBlob
->length();
192 kern_return_t
ucsp_server_releaseDb(UCSP_ARGS
, DbHandle db
)
195 delete &Server::database(db
);
199 kern_return_t
ucsp_server_authenticateDb(UCSP_ARGS
, DbHandle db
,
200 COPY_IN(AccessCredentials
, cred
))
203 relocate(cred
, credBase
, credLength
);
204 Server::database(db
).authenticate(cred
);
208 kern_return_t
ucsp_server_setDbParameters(UCSP_ARGS
, DbHandle db
, DBParameters params
)
211 Server::database(db
).setParameters(params
);
215 kern_return_t
ucsp_server_getDbParameters(UCSP_ARGS
, DbHandle db
, DBParameters
*params
)
218 Server::database(db
).getParameters(*params
);
222 kern_return_t
ucsp_server_changePassphrase(UCSP_ARGS
, DbHandle db
,
223 COPY_IN(AccessCredentials
, cred
))
226 relocate(cred
, credBase
, credLength
);
227 Server::database(db
).changePassphrase(cred
);
231 kern_return_t
ucsp_server_lockDb(UCSP_ARGS
, DbHandle db
)
234 Server::database(db
).lock();
238 kern_return_t
ucsp_server_unlockDb(UCSP_ARGS
, DbHandle db
)
241 Server::database(db
).unlock();
245 kern_return_t
ucsp_server_unlockDbWithPassphrase(UCSP_ARGS
, DbHandle db
, DATA_IN(passphrase
))
248 Server::database(db
).unlock(DATA(passphrase
));
252 kern_return_t
ucsp_server_isLocked(UCSP_ARGS
, DbHandle db
, boolean_t
*locked
)
255 *locked
= Server::database(db
).isLocked();
263 kern_return_t
ucsp_server_encodeKey(UCSP_ARGS
, KeyHandle keyh
, DATA_OUT(blob
),
264 boolean_t wantUid
, DATA_OUT(uid
))
267 Key
&key
= Server::key(keyh
);
268 KeyBlob
*keyBlob
= key
.blob(); // still owned by key
270 *blobLength
= keyBlob
->length();
273 *uidLength
= sizeof(KeyUID
);
275 *uidLength
= 0; // do not return this
280 kern_return_t
ucsp_server_decodeKey(UCSP_ARGS
, KeyHandle
*keyh
, CssmKey::Header
*header
,
281 DbHandle db
, DATA_IN(blob
))
284 Key
&key
= *new Key(Server::database(db
), DATA(blob
).interpretedAs
<KeyBlob
>());
285 key
.returnKey(*keyh
, *header
);
289 kern_return_t
ucsp_server_releaseKey(UCSP_ARGS
, KeyHandle key
)
292 connection
.releaseKey(key
);
296 kern_return_t
ucsp_server_queryKeySizeInBits(UCSP_ARGS
, KeyHandle key
, CSSM_KEY_SIZE
*length
)
299 *length
= connection
.queryKeySize(findHandle
<Key
>(key
));
303 kern_return_t
ucsp_server_getOutputSize(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
304 uint32 inputSize
, boolean_t encrypt
, uint32
*outputSize
)
307 context
.postIPC(contextBase
, attributes
);
308 *outputSize
= connection
.getOutputSize(context
, findHandle
<Key
>(key
), inputSize
, encrypt
);
316 kern_return_t
ucsp_server_generateRandom(UCSP_ARGS
, uint32 bytes
, DATA_OUT(data
))
319 CssmAllocator
&allocator
= CssmAllocator::standard(CssmAllocator::sensitive
);
320 void *buffer
= allocator
.malloc(bytes
);
321 Server::active().random(buffer
, bytes
);
324 Server::releaseWhenDone(allocator
, buffer
);
330 // Signatures and MACs
332 kern_return_t
ucsp_server_generateSignature(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
333 CSSM_ALGORITHMS signOnlyAlgorithm
, DATA_IN(data
), DATA_OUT(signature
))
336 context
.postIPC(contextBase
, attributes
);
337 OutputData
sigData(signature
, signatureLength
);
338 connection
.generateSignature(context
, findHandle
<Key
>(key
), signOnlyAlgorithm
,
339 DATA(data
), sigData
);
343 kern_return_t
ucsp_server_verifySignature(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
344 CSSM_ALGORITHMS verifyOnlyAlgorithm
, DATA_IN(data
), DATA_IN(signature
))
347 context
.postIPC(contextBase
, attributes
);
348 connection
.verifySignature(context
, findHandle
<Key
>(key
), verifyOnlyAlgorithm
,
349 DATA(data
), DATA(signature
));
353 kern_return_t
ucsp_server_generateMac(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
354 DATA_IN(data
), DATA_OUT(mac
))
357 context
.postIPC(contextBase
, attributes
);
358 OutputData
macData(mac
, macLength
);
359 connection
.generateMac(context
, findHandle
<Key
>(key
),
360 DATA(data
), macData
);
364 kern_return_t
ucsp_server_verifyMac(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
365 DATA_IN(data
), DATA_IN(mac
))
368 context
.postIPC(contextBase
, attributes
);
369 connection
.verifyMac(context
, findHandle
<Key
>(key
),
370 DATA(data
), DATA(mac
));
376 // Encryption/Decryption
378 kern_return_t
ucsp_server_encrypt(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
379 DATA_IN(clear
), DATA_OUT(cipher
))
382 context
.postIPC(contextBase
, attributes
);
383 OutputData
cipherOut(cipher
, cipherLength
);
384 connection
.encrypt(context
, findHandle
<Key
>(key
),
385 DATA(clear
), cipherOut
);
389 kern_return_t
ucsp_server_decrypt(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
390 DATA_IN(cipher
), DATA_OUT(clear
))
393 context
.postIPC(contextBase
, attributes
);
394 OutputData
clearOut(clear
, clearLength
);
395 connection
.decrypt(context
, findHandle
<Key
>(key
),
396 DATA(cipher
), clearOut
);
404 kern_return_t
ucsp_server_generateKey(UCSP_ARGS
, DbHandle db
, CONTEXT_ARGS
,
405 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
406 uint32 usage
, uint32 attrs
, KeyHandle
*newKey
, CssmKey::Header
*newHeader
)
409 context
.postIPC(contextBase
, attributes
);
410 relocate(cred
, credBase
, credLength
);
411 relocate(owner
, ownerBase
, ownerLength
);
413 connection
.generateKey(Server::optionalDatabase(db
),
414 context
, cred
, owner
, usage
, attrs
, key
);
415 key
->returnKey(*newKey
, *newHeader
);
419 kern_return_t
ucsp_server_generateKeyPair(UCSP_ARGS
, DbHandle db
, CONTEXT_ARGS
,
420 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
421 uint32 pubUsage
, uint32 pubAttrs
, uint32 privUsage
, uint32 privAttrs
,
422 KeyHandle
*pubKey
, CssmKey::Header
*pubHeader
, KeyHandle
*privKey
, CssmKey::Header
*privHeader
)
425 context
.postIPC(contextBase
, attributes
);
426 relocate(cred
, credBase
, credLength
);
427 relocate(owner
, ownerBase
, ownerLength
);
429 connection
.generateKey(Server::optionalDatabase(db
),
430 context
, cred
, owner
,
431 pubUsage
, pubAttrs
, privUsage
, privAttrs
, pub
, priv
);
432 pub
->returnKey(*pubKey
, *pubHeader
);
433 priv
->returnKey(*privKey
, *privHeader
);
440 // This is a bit strained; the incoming 'param' value may have structure
441 // and needs to be handled on a per-algorithm basis, which means we have to
442 // know which key derivation algorithms we support for passing to our CSP(s).
443 // The default behavior is to handle "flat" data blobs, which is as good
444 // a default as we can manage.
445 // NOTE: The param-specific handling must be synchronized with the client library
446 // code (in sstransit.h).
448 kern_return_t
ucsp_server_deriveKey(UCSP_ARGS
, DbHandle db
, CONTEXT_ARGS
, KeyHandle key
,
449 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
450 COPY_IN(void, paramInputData
), DATA_OUT(paramOutput
),
451 uint32 usage
, uint32 attrs
, KeyHandle
*newKey
, CssmKey::Header
*newHeader
)
454 context
.postIPC(contextBase
, attributes
);
455 relocate(cred
, credBase
, credLength
);
456 relocate(owner
, ownerBase
, ownerLength
);
458 // munge together the incoming 'param' value according to algorithm
460 switch (context
.algorithm()) {
461 case CSSM_ALGID_PKCS5_PBKDF2
:
462 relocate((CSSM_PKCS5_PBKDF2_PARAMS
*)paramInputData
,
463 (CSSM_PKCS5_PBKDF2_PARAMS
*)paramInputDataBase
,
464 paramInputDataLength
);
465 param
= CssmData(paramInputData
, sizeof(CSSM_PKCS5_PBKDF2_PARAMS
));
468 param
= CssmData(paramInputData
, paramInputDataLength
);
471 Key
&theKey
= connection
.deriveKey(Server::optionalDatabase(db
),
472 context
, Server::optionalKey(key
), cred
, owner
, ¶m
, usage
, attrs
);
473 theKey
.returnKey(*newKey
, *newHeader
);
474 if (param
.length()) {
475 if (!param
) // CSP screwed up
476 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR
);
477 if (paramInputDataLength
) // using incoming buffer; make a copy
478 param
= CssmAutoData(Server::csp().allocator(), param
).release();
479 OutputData(paramOutput
, paramOutputLength
) = param
; // return the data
486 // Key wrapping and unwrapping
488 kern_return_t
ucsp_server_wrapKey(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
489 COPY_IN(AccessCredentials
, cred
), KeyHandle keyToBeWrapped
,
490 DATA_IN(descriptiveData
), CssmKey
*wrappedKey
, DATA_OUT(keyData
))
493 context
.postIPC(contextBase
, attributes
);
494 relocate(cred
, credBase
, credLength
);
495 connection
.wrapKey(context
, Server::optionalKey(key
),
496 Server::key(keyToBeWrapped
), cred
, DATA(descriptiveData
), *wrappedKey
);
497 // transmit key data back as a separate blob
498 *keyData
= wrappedKey
->data();
499 *keyDataLength
= wrappedKey
->length();
500 Server::releaseWhenDone(*keyData
);
504 kern_return_t
ucsp_server_unwrapKey(UCSP_ARGS
, DbHandle db
, CONTEXT_ARGS
, KeyHandle key
,
505 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
506 KeyHandle publicKey
, CssmKey wrappedKey
, DATA_IN(wrappedKeyData
),
507 uint32 usage
, uint32 attr
, DATA_OUT(descriptiveData
),
508 KeyHandle
*newKey
, CssmKey::Header
*newHeader
)
511 context
.postIPC(contextBase
, attributes
);
512 wrappedKey
.KeyData
= DATA(wrappedKeyData
);
513 relocate(cred
, credBase
, credLength
);
514 relocate(owner
, ownerBase
, ownerLength
);
515 CssmData descriptiveDatas
;
516 Key
&theKey
= connection
.unwrapKey(Server::optionalDatabase(db
),
517 context
, Server::optionalKey(key
), cred
, owner
, usage
, attr
, wrappedKey
,
518 Server::optionalKey(publicKey
), &descriptiveDatas
);
519 theKey
.returnKey(*newKey
, *newHeader
);
520 *descriptiveData
= descriptiveDatas
.data();
521 *descriptiveDataLength
= descriptiveDatas
.length();
522 Server::releaseWhenDone(*descriptiveData
);
529 // Watch out for the memory-management tap-dance.
531 kern_return_t
ucsp_server_getOwner(UCSP_ARGS
, AclKind kind
, KeyHandle key
,
532 COPY_OUT(AclOwnerPrototype
, ownerOut
))
535 AclOwnerPrototype owner
;
536 Server::aclBearer(kind
, key
).cssmGetOwner(owner
); // allocates memory in owner
537 Copier
<AclOwnerPrototype
> owners(&owner
, CssmAllocator::standard()); // make flat copy
538 { ChunkFreeWalker free
; walk(free
, owner
); } // release chunked original
539 *ownerOut
= *ownerOutBase
= owners
;
540 *ownerOutLength
= owners
.length();
541 Server::releaseWhenDone(owners
.keep()); // throw flat copy out when done
545 kern_return_t
ucsp_server_setOwner(UCSP_ARGS
, AclKind kind
, KeyHandle key
,
546 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclOwnerPrototype
, owner
))
549 relocate(cred
, credBase
, credLength
);
550 relocate(owner
, ownerBase
, ownerLength
);
551 Server::aclBearer(kind
, key
).cssmChangeOwner(*owner
, cred
);
555 kern_return_t
ucsp_server_getAcl(UCSP_ARGS
, AclKind kind
, KeyHandle key
,
556 boolean_t haveTag
, const char *tag
,
557 uint32
*countp
, COPY_OUT(AclEntryInfo
, acls
))
561 AclEntryInfo
*aclList
;
562 Server::aclBearer(kind
, key
).cssmGetAcl(haveTag
? tag
: NULL
, count
, aclList
);
564 Copier
<AclEntryInfo
> aclsOut(AclEntryInfo::overlay(aclList
), count
); // make flat copy
566 { // release the chunked memory originals
567 ChunkFreeWalker free
;
568 for (uint32 n
= 0; n
< count
; n
++)
569 walk(free
, aclList
[n
]);
573 *acls
= *aclsBase
= aclsOut
;
574 *aclsLength
= aclsOut
.length();
575 Server::releaseWhenDone(aclsOut
.keep());
579 kern_return_t
ucsp_server_changeAcl(UCSP_ARGS
, AclKind kind
, KeyHandle key
,
580 COPY_IN(AccessCredentials
, cred
), CSSM_ACL_EDIT_MODE mode
, CSSM_ACL_HANDLE handle
,
581 COPY_IN(AclEntryInput
, acl
))
584 relocate(cred
, credBase
, credLength
);
585 relocate(acl
, aclBase
, aclLength
);
586 Server::aclBearer(kind
, key
).cssmChangeAcl(AclEdit(mode
, handle
, acl
), cred
);
592 // Authorization subsystem support
594 kern_return_t
ucsp_server_authorizationCreate(UCSP_ARGS
,
595 COPY_IN(AuthorizationItemSet
, rights
),
597 COPY_IN(AuthorizationItemSet
, environment
),
598 AuthorizationBlob
*authorization
)
601 relocate(rights
, rightsBase
, rightsLength
);
602 relocate(environment
, environmentBase
, environmentLength
);
603 *rcode
= connection
.process
.session
.authCreate(rights
, environment
,
604 flags
, *authorization
);
608 kern_return_t
ucsp_server_authorizationRelease(UCSP_ARGS
,
609 AuthorizationBlob authorization
, uint32 flags
)
612 connection
.process
.session
.authFree(authorization
, flags
);
616 kern_return_t
ucsp_server_authorizationCopyRights(UCSP_ARGS
,
617 AuthorizationBlob authorization
,
618 COPY_IN(AuthorizationItemSet
, rights
),
620 COPY_IN(AuthorizationItemSet
, environment
),
621 COPY_OUT(AuthorizationItemSet
, result
))
624 relocate(rights
, rightsBase
, rightsLength
);
625 relocate(environment
, environmentBase
, environmentLength
);
626 Authorization::MutableRightSet grantedRights
;
627 *rcode
= connection
.process
.session
.authGetRights(authorization
,
628 rights
, environment
, flags
, grantedRights
);
629 Copier
<AuthorizationRights
> returnedRights(grantedRights
, CssmAllocator::standard());
630 *result
= *resultBase
= returnedRights
;
631 *resultLength
= returnedRights
.length();
632 Server::releaseWhenDone(returnedRights
.keep());
636 kern_return_t
ucsp_server_authorizationCopyInfo(UCSP_ARGS
,
637 AuthorizationBlob authorization
,
638 AuthorizationString tag
,
639 COPY_OUT(AuthorizationItemSet
, info
))
642 AuthorizationItemSet
*result
;
643 *info
= *infoBase
= NULL
;
645 *rcode
= connection
.process
.session
.authGetInfo(authorization
,
646 tag
[0] ? tag
: NULL
, result
); // result is a deep copy
649 *info
= *infoBase
= result
;
650 *infoLength
= size(result
);
651 Server::releaseWhenDone(result
);
656 kern_return_t
ucsp_server_authorizationExternalize(UCSP_ARGS
,
657 AuthorizationBlob authorization
, AuthorizationExternalForm
*extForm
)
660 *rcode
= connection
.process
.session
.authExternalize(authorization
, *extForm
);
664 kern_return_t
ucsp_server_authorizationInternalize(UCSP_ARGS
,
665 AuthorizationExternalForm extForm
, AuthorizationBlob
*authorization
)
668 *rcode
= connection
.process
.session
.authInternalize(extForm
, *authorization
);
674 // Session management subsystem
676 kern_return_t
ucsp_server_getSessionInfo(UCSP_ARGS
,
677 SecuritySessionId
*sessionId
, SessionAttributeBits
*attrs
)
680 Session
&session
= Session::find(*sessionId
);
681 *sessionId
= session
.handle();
682 *attrs
= session
.attributes();
686 kern_return_t
ucsp_server_setupSession(UCSP_ARGS
,
687 SessionCreationFlags flags
, SessionAttributeBits attrs
)
690 Session::setup(flags
, attrs
);
696 // Notification core subsystem
698 kern_return_t
ucsp_server_requestNotification(UCSP_ARGS
, mach_port_t receiver
, uint32 domain
, uint32 events
)
701 connection
.process
.requestNotifications(receiver
, domain
, events
);
705 kern_return_t
ucsp_server_stopNotification(UCSP_ARGS
, mach_port_t receiver
)
708 connection
.process
.stopNotifications(receiver
);
712 kern_return_t
ucsp_server_postNotification(UCSP_ARGS
, uint32 domain
, uint32 event
, DATA_IN(data
))
715 connection
.process
.postNotification(domain
, event
, DATA(data
));