]> git.saurik.com Git - apple/security.git/blob - SecurityServer/sstransit.cpp
Security-54.tar.gz
[apple/security.git] / SecurityServer / sstransit.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 //
20 // sstransit - SecurityServer client library transition code.
21 //
22 // These are the functions that implement CssmClient methods in terms of
23 // MIG IPC client calls, plus their supporting machinery.
24 //
25 #include "sstransit.h"
26
27 namespace Security
28 {
29
30 using MachPlusPlus::check;
31 using MachPlusPlus::VMGuard;
32
33
34 //
35 // DataOutput helper.
36 // This happens "at the end" of a glue method, via the DataOutput destructor.
37 //
38 DataOutput::~DataOutput()
39 {
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);
48 }
49 memcpy(argument.data(), mData, mLength);
50 }
51 }
52
53
54 CssmList chunkCopy(CssmList &list, CssmAllocator &alloc)
55 {
56 CssmList copy = list;
57 ChunkCopyWalker w(alloc);
58 walk(w, copy);
59 return copy;
60 }
61
62
63 //
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.
67 //
68 SendContext::SendContext(const Context &ctx) : context(ctx)
69 {
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++);
80 break;
81 }
82 default:
83 builder.setup(ctx[n]);
84 break;
85 }
86 }
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);
93 break;
94 default:
95 builder.put(attr);
96 break;
97 }
98 }
99 uint32 count; // not needed
100 builder.done(attributes, count);
101 assert(cryptoDataUsed <= 1); // no more than one slot converted
102 }
103
104
105 namespace SecurityServer
106 {
107
108 //
109 // Database control
110 //
111 DbHandle ClientSession::createDb(const DLDbIdentifier &dbId,
112 const AccessCredentials *cred, const AclEntryInput *owner,
113 const DBParameters &params)
114 {
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);
119 DbHandle db;
120 IPC(ucsp_client_createDb(UCSP_ARGS, &db, COPY(id), COPY(creds), COPY(proto), params));
121 return db;
122 }
123
124 DbHandle ClientSession::decodeDb(const DLDbIdentifier &dbId,
125 const AccessCredentials *cred, const CssmData &blob)
126 {
127 Copier<AccessCredentials> creds(cred, internalAllocator);
128 DataWalkers::DLDbFlatIdentifier ident(dbId);
129 Copier<DataWalkers::DLDbFlatIdentifier> id(&ident, internalAllocator);
130 DbHandle db;
131 IPC(ucsp_client_decodeDb(UCSP_ARGS, &db, COPY(id), COPY(creds), DATA(blob)));
132 return db;
133 }
134
135 void ClientSession::encodeDb(DbHandle db, CssmData &blob, CssmAllocator &alloc)
136 {
137 DataOutput outBlob(blob, alloc);
138 IPC(ucsp_client_encodeDb(UCSP_ARGS, db, DATA(outBlob)));
139 }
140
141 void ClientSession::releaseDb(DbHandle db)
142 {
143 IPC(ucsp_client_releaseDb(UCSP_ARGS, db));
144 }
145
146 void ClientSession::authenticateDb(DbHandle db, DBAccessType type,
147 const AccessCredentials *cred)
148 {
149 Copier<AccessCredentials> creds(cred, internalAllocator);
150 IPC(ucsp_client_authenticateDb(UCSP_ARGS, db, COPY(creds)));
151 }
152
153 void ClientSession::setDbParameters(DbHandle db, const DBParameters &params)
154 {
155 IPC(ucsp_client_setDbParameters(UCSP_ARGS, db, params));
156 }
157
158 void ClientSession::getDbParameters(DbHandle db, DBParameters &params)
159 {
160 IPC(ucsp_client_getDbParameters(UCSP_ARGS, db, &params));
161 }
162
163 void ClientSession::changePassphrase(DbHandle db, const AccessCredentials *cred)
164 {
165 Copier<AccessCredentials> creds(cred, internalAllocator);
166 IPC(ucsp_client_changePassphrase(UCSP_ARGS, db, COPY(creds)));
167 }
168
169
170 void ClientSession::lock(DbHandle db)
171 {
172 IPC(ucsp_client_lockDb(UCSP_ARGS, db));
173 }
174
175 void ClientSession::unlock(DbHandle db)
176 {
177 IPC(ucsp_client_unlockDb(UCSP_ARGS, db));
178 }
179
180 void ClientSession::unlock(DbHandle db, const CssmData &passphrase)
181 {
182 IPC(ucsp_client_unlockDbWithPassphrase(UCSP_ARGS, db, DATA(passphrase)));
183 }
184
185 bool ClientSession::isLocked(DbHandle db)
186 {
187 boolean_t locked;
188 IPC(ucsp_client_isLocked(UCSP_ARGS, db, &locked));
189 return locked;
190 }
191
192
193 //
194 // Key control
195 //
196 void ClientSession::encodeKey(KeyHandle key, CssmData &blob,
197 KeyUID *uid, CssmAllocator &alloc)
198 {
199 DataOutput oBlob(blob, alloc);
200 void *uidp;
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
205 if (uid) {
206 assert(uidLength == sizeof(KeyUID));
207 memcpy(uid, uidp, sizeof(KeyUID));
208 }
209 }
210
211
212 KeyHandle ClientSession::decodeKey(DbHandle db, const CssmData &blob, CssmKey::Header &header)
213 {
214 KeyHandle key;
215 IPC(ucsp_client_decodeKey(UCSP_ARGS, &key, &header, db, blob.data(), blob.length()));
216 return key;
217 }
218
219 void ClientSession::releaseKey(KeyHandle key)
220 {
221 IPC(ucsp_client_releaseKey(UCSP_ARGS, key));
222 }
223
224
225 CssmKeySize ClientSession::queryKeySizeInBits(KeyHandle key)
226 {
227 CssmKeySize length;
228 IPC(ucsp_client_queryKeySizeInBits(UCSP_ARGS, key, &length));
229 return length;
230 }
231
232
233 uint32 ClientSession::getOutputSize(const Context &context, KeyHandle key,
234 uint32 inputSize, bool encrypt)
235 {
236 SendContext ctx(context);
237 uint32 outputSize;
238 IPC(ucsp_client_getOutputSize(UCSP_ARGS, CONTEXT(ctx), key, inputSize, encrypt, &outputSize));
239 return outputSize;
240 }
241
242
243 //
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.
248 //
249 void ClientSession::generateRandom(CssmData &data)
250 {
251 void *result;
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());
256 }
257
258
259 //
260 // Signatures and MACs
261 //
262 void ClientSession::generateSignature(const Context &context, KeyHandle key,
263 const CssmData &data, CssmData &signature, CssmAllocator &alloc, CSSM_ALGORITHMS signOnlyAlgorithm)
264 {
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)));
269 }
270
271 void ClientSession::verifySignature(const Context &context, KeyHandle key,
272 const CssmData &data, const CssmData &signature, CSSM_ALGORITHMS verifyOnlyAlgorithm)
273 {
274 SendContext ctx(context);
275 IPC(ucsp_client_verifySignature(UCSP_ARGS, CONTEXT(ctx), key, verifyOnlyAlgorithm,
276 DATA(data), DATA(signature)));
277 }
278
279
280 void ClientSession::generateMac(const Context &context, KeyHandle key,
281 const CssmData &data, CssmData &signature, CssmAllocator &alloc)
282 {
283 SendContext ctx(context);
284 DataOutput sig(signature, alloc);
285 IPC(ucsp_client_generateMac(UCSP_ARGS, CONTEXT(ctx), key,
286 DATA(data), DATA(sig)));
287 }
288
289 void ClientSession::verifyMac(const Context &context, KeyHandle key,
290 const CssmData &data, const CssmData &signature)
291 {
292 SendContext ctx(context);
293 IPC(ucsp_client_verifyMac(UCSP_ARGS, CONTEXT(ctx), key,
294 DATA(data), DATA(signature)));
295 }
296
297
298 //
299 // Encryption/Decryption
300 //
301
302 void ClientSession::encrypt(const Context &context, KeyHandle key,
303 const CssmData &clear, CssmData &cipher, CssmAllocator &alloc)
304 {
305 SendContext ctx(context);
306 DataOutput cipherOut(cipher, alloc);
307 IPC(ucsp_client_encrypt(UCSP_ARGS, CONTEXT(ctx), key, DATA(clear), DATA(cipherOut)));
308 }
309
310 void ClientSession::decrypt(const Context &context, KeyHandle key,
311 const CssmData &cipher, CssmData &clear, CssmAllocator &alloc)
312 {
313 SendContext ctx(context);
314 DataOutput clearOut(clear, alloc);
315 IPC(ucsp_client_decrypt(UCSP_ARGS, CONTEXT(ctx), key, DATA(cipher), DATA(clearOut)));
316 }
317
318
319 //
320 // Key generation
321 //
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)
325 {
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));
331 }
332
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)
339 {
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));
347 }
348
349
350 //
351 // Key derivation
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).
359 //
360 void ClientSession::deriveKey(DbHandle db, const Context &context, KeyHandle baseKey,
361 uint32 keyUsage, uint32 keyAttr, CssmData &param,
362 const AccessCredentials *cred, const AclEntryInput *owner,
363 KeyHandle &newKey, CssmKey::Header &newHeader, CssmAllocator &allocator)
364 {
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));
376 break; }
377 default: {
378 IPC(ucsp_client_deriveKey(UCSP_ARGS, db, CONTEXT(ctx), baseKey,
379 COPY(creds), COPY(proto),
380 param.data(), param.length(), param.data(),
381 DATA(paramOutput),
382 keyUsage, keyAttr, &newKey, &newHeader));
383 break; }
384 }
385 }
386
387
388 //
389 // Key wrapping and unwrapping
390 //
391 void ClientSession::wrapKey(const Context &context, KeyHandle wrappingKey,
392 KeyHandle keyToBeWrapped, const AccessCredentials *cred,
393 const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, CssmAllocator &alloc)
394 {
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)
402 }
403
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)
410 {
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));
419 }
420
421
422 //
423 // ACL management
424 //
425 void ClientSession::getAcl(AclKind kind, KeyHandle key, const char *tag,
426 uint32 &infoCount, AclEntryInfo * &infoArray, CssmAllocator &alloc)
427 {
428 uint32 count;
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);
435 infoCount = count;
436
437 // relocate incoming AclEntryInfo array
438 ReconstituteWalker relocator(info, infoBase);
439 for (uint32 n = 0; n < count; n++)
440 walk(relocator, info[n]);
441
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]);
448 }
449 }
450
451 void ClientSession::changeAcl(AclKind kind, KeyHandle key, const AccessCredentials &cred,
452 const AclEdit &edit)
453 {
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)));
459 }
460
461 void ClientSession::getOwner(AclKind kind, KeyHandle key, AclOwnerPrototype &owner,
462 CssmAllocator &alloc)
463 {
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();
471 }
472
473 void ClientSession::changeOwner(AclKind kind, KeyHandle key,
474 const AccessCredentials &cred, const AclOwnerPrototype &proto)
475 {
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)));
479 }
480
481
482 void ClientSession::getKeyAcl(DbHandle db, const char *tag,
483 uint32 &count, AclEntryInfo * &info, CssmAllocator &alloc)
484 { getAcl(keyAcl, db, tag, count, info, alloc); }
485
486 void ClientSession::changeKeyAcl(DbHandle db, const AccessCredentials &cred,
487 const AclEdit &edit)
488 { changeAcl(keyAcl, db, cred, edit); }
489
490 void ClientSession::getKeyOwner(DbHandle db, AclOwnerPrototype &owner, CssmAllocator &alloc)
491 { getOwner(keyAcl, db, owner, alloc); }
492
493 void ClientSession::changeKeyOwner(DbHandle db, const AccessCredentials &cred,
494 const AclOwnerPrototype &edit)
495 { changeOwner(keyAcl, db, cred, edit); }
496
497 void ClientSession::getDbAcl(DbHandle db, const char *tag,
498 uint32 &count, AclEntryInfo * &info, CssmAllocator &alloc)
499 { getAcl(dbAcl, db, tag, count, info, alloc); }
500
501 void ClientSession::changeDbAcl(DbHandle db, const AccessCredentials &cred,
502 const AclEdit &edit)
503 { changeAcl(dbAcl, db, cred, edit); }
504
505 void ClientSession::getDbOwner(DbHandle db, AclOwnerPrototype &owner, CssmAllocator &alloc)
506 { getOwner(dbAcl, db, owner, alloc); }
507
508 void ClientSession::changeDbOwner(DbHandle db, const AccessCredentials &cred,
509 const AclOwnerPrototype &edit)
510 { changeOwner(dbAcl, db, cred, edit); }
511
512
513 //
514 // Authorization subsystem entry
515 //
516 void ClientSession::authCreate(const AuthorizationItemSet *rights,
517 const AuthorizationItemSet *environment, AuthorizationFlags flags,
518 AuthorizationBlob &result)
519 {
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));
524 }
525
526 void ClientSession::authRelease(const AuthorizationBlob &auth,
527 AuthorizationFlags flags)
528 {
529 IPC(ucsp_client_authorizationRelease(UCSP_ARGS, auth, flags));
530 }
531
532 void ClientSession::authCopyRights(const AuthorizationBlob &auth,
533 const AuthorizationItemSet *rights, const AuthorizationItemSet *environment,
534 AuthorizationFlags flags,
535 AuthorizationItemSet **grantedRights)
536 {
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
545 if (grantedRights) {
546 relocate(result, resultBase);
547 *grantedRights = copy(result, returnAllocator);
548 }
549 }
550
551 void ClientSession::authCopyInfo(const AuthorizationBlob &auth,
552 const char *tag,
553 AuthorizationItemSet * &info)
554 {
555 COPY_OUT_DECL(AuthorizationItemSet, result);
556 if (tag == NULL)
557 tag = "";
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);
564 }
565
566 void ClientSession::authExternalize(const AuthorizationBlob &auth,
567 AuthorizationExternalForm &extForm)
568 {
569 IPC(ucsp_client_authorizationExternalize(UCSP_ARGS, auth, &extForm));
570 }
571
572 void ClientSession::authInternalize(const AuthorizationExternalForm &extForm,
573 AuthorizationBlob &auth)
574 {
575 IPC(ucsp_client_authorizationInternalize(UCSP_ARGS, extForm, &auth));
576 }
577
578
579 //
580 // Session management API
581 //
582 void ClientSession::getSessionInfo(SecuritySessionId &sessionId, SessionAttributeBits &attrs)
583 {
584 IPC(ucsp_client_getSessionInfo(UCSP_ARGS, &sessionId, &attrs));
585 }
586
587 void ClientSession::setupSession(SessionCreationFlags flags, SessionAttributeBits attrs)
588 {
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));
592 }
593
594
595 //
596 // Notification subsystem
597 //
598 void ClientSession::requestNotification(Port receiver, NotifyDomain domain, NotifyEvents events)
599 {
600 IPC(ucsp_client_requestNotification(UCSP_ARGS, receiver, domain, events));
601 }
602
603 void ClientSession::stopNotification(Port port)
604 {
605 IPC(ucsp_client_stopNotification(UCSP_ARGS, port.port()));
606 }
607
608 void ClientSession::postNotification(NotifyDomain domain, NotifyEvent event, const CssmData &data)
609 {
610 IPC(ucsp_client_postNotification(UCSP_ARGS, domain, event, DATA(data)));
611 }
612
613 OSStatus ClientSession::dispatchNotification(const mach_msg_header_t *message,
614 ConsumeNotification *consumer, void *context)
615 {
616 struct Message {
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 */
622 NDR_record_t NDR;
623 uint32 domain;
624 uint32 event;
625 mach_msg_type_number_t dataCnt;
626 uint32 sender;
627 } *msg = (Message *)message;
628
629 OSStatus status = consumer(msg->domain, msg->event, msg->data.address, msg->dataCnt, context);
630
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;
634
635 return status;
636 }
637
638
639 } // end namespace SecurityServer
640 } // end namespace Security