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
25 #include "xdatabase.h"
26 #include "transwalkers.h"
27 #include <mach/mach_error.h>
29 #include <CoreFoundation/CFDictionary.h>
30 #include <CoreFoundation/CFPropertyList.h>
35 #define UCSP_ARGS mach_port_t servicePort, mach_port_t replyPort, security_token_t securityToken, \
37 #define CONTEXT_ARGS Context context, Pointer contextBase, Context::Attr *attributes, mach_msg_type_number_t attrSize
39 #define BEGIN_IPCN *rcode = CSSM_OK; try {
40 #define BEGIN_IPC BEGIN_IPCN Connection &connection __attribute__((unused)) = Server::connection(replyPort);
41 #define END_IPC(base) END_IPCN(base) Server::requestComplete(); return KERN_SUCCESS;
42 #define END_IPCN(base) } \
43 catch (const CssmCommonError &err) { *rcode = err.cssmError(CSSM_ ## base ## _BASE_ERROR); } \
44 catch (const std::bad_alloc &) { *rcode = CssmError::merge(CSSM_ERRCODE_MEMORY_ERROR, CSSM_ ## base ## _BASE_ERROR); } \
45 catch (Connection *conn) { *rcode = 0; } \
46 catch (...) { *rcode = CssmError::merge(CSSM_ERRCODE_INTERNAL_ERROR, CSSM_ ## base ## _BASE_ERROR); }
48 #define DATA_IN(base) void *base, mach_msg_type_number_t base##Length
49 #define DATA_OUT(base) void **base, mach_msg_type_number_t *base##Length
50 #define DATA(base) CssmData(base, base##Length)
52 #define COPY_IN(type,name) type *name, mach_msg_type_number_t name##Length, type *name##Base
53 #define COPY_OUT(type,name) \
54 type **name, mach_msg_type_number_t *name##Length, type **name##Base
57 using LowLevelMemoryUtilities::increment
;
58 using LowLevelMemoryUtilities::difference
;
62 // An OutputData object will take memory allocated within the SecurityServer,
63 // hand it to the MIG return-output parameters, and schedule it to be released
64 // after the MIG reply has been sent. It will also get rid of it in case of
67 class OutputData
: public CssmData
{
69 OutputData(void **outP
, mach_msg_type_number_t
*outLength
)
70 : mData(*outP
), mLength(*outLength
) { }
72 { mData
= data(); mLength
= length(); Server::releaseWhenDone(mData
); }
74 void operator = (const CssmData
&source
)
75 { CssmData::operator = (source
); }
79 mach_msg_type_number_t
&mLength
;
84 // Setup/Teardown functions.
86 kern_return_t
ucsp_server_setup(UCSP_ARGS
, mach_port_t taskPort
, ClientSetupInfo info
, const char *identity
)
89 Server::active().setupConnection(Server::connectNewProcess
, servicePort
, replyPort
,
90 taskPort
, securityToken
, &info
, identity
);
95 kern_return_t
ucsp_server_setupNew(UCSP_ARGS
, mach_port_t taskPort
,
96 ClientSetupInfo info
, const char *identity
,
97 mach_port_t
*newServicePort
)
101 Session
*session
= new DynamicSession(TaskPort(taskPort
).bootstrap());
102 Server::active().setupConnection(Server::connectNewSession
, session
->servicePort(), replyPort
,
103 taskPort
, securityToken
, &info
, identity
);
104 *newServicePort
= session
->servicePort();
105 } catch (const MachPlusPlus::Error
&err
) {
107 case BOOTSTRAP_SERVICE_ACTIVE
:
108 MacOSError::throwMe(errSessionAuthorizationDenied
); // translate
117 kern_return_t
ucsp_server_setupThread(UCSP_ARGS
, mach_port_t taskPort
)
120 Server::active().setupConnection(Server::connectNewThread
, servicePort
, replyPort
,
121 taskPort
, securityToken
);
127 kern_return_t
ucsp_server_teardown(UCSP_ARGS
)
130 Server::active().endConnection(replyPort
);
137 // Database management
139 kern_return_t
ucsp_server_createDb(UCSP_ARGS
, DbHandle
*db
,
140 COPY_IN(DLDbFlatIdentifier
, ident
),
141 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
145 relocate(cred
, credBase
, credLength
);
146 relocate(owner
, ownerBase
, ownerLength
);
147 relocate(ident
, identBase
, identLength
);
148 *db
= (new Database(*ident
, params
, connection
.process
, cred
, owner
))->handle();
152 kern_return_t
ucsp_server_decodeDb(UCSP_ARGS
, DbHandle
*db
,
153 COPY_IN(DLDbFlatIdentifier
, ident
), COPY_IN(AccessCredentials
, cred
), DATA_IN(blob
))
156 relocate(cred
, credBase
, credLength
);
157 relocate(ident
, identBase
, identLength
);
158 *db
= (new Database(*ident
, DATA(blob
).interpretedAs
<DbBlob
>(),
159 connection
.process
, cred
))->handle();
163 kern_return_t
ucsp_server_encodeDb(UCSP_ARGS
, DbHandle db
, DATA_OUT(blob
))
166 DbBlob
*dbBlob
= Server::database(db
).blob(); // memory owned by database
168 *blobLength
= dbBlob
->length();
172 kern_return_t
ucsp_server_releaseDb(UCSP_ARGS
, DbHandle db
)
175 delete &Server::database(db
);
179 kern_return_t
ucsp_server_getDbIndex(UCSP_ARGS
, DbHandle db
, DATA_OUT(index
))
182 OutputData
indexData(index
, indexLength
);
183 Server::database(db
).getDbIndex(indexData
);
187 kern_return_t
ucsp_server_authenticateDb(UCSP_ARGS
, DbHandle db
,
188 COPY_IN(AccessCredentials
, cred
))
191 relocate(cred
, credBase
, credLength
);
192 Server::database(db
).authenticate(cred
);
196 kern_return_t
ucsp_server_setDbParameters(UCSP_ARGS
, DbHandle db
, DBParameters params
)
199 Server::database(db
).setParameters(params
);
203 kern_return_t
ucsp_server_getDbParameters(UCSP_ARGS
, DbHandle db
, DBParameters
*params
)
206 Server::database(db
).getParameters(*params
);
210 kern_return_t
ucsp_server_changePassphrase(UCSP_ARGS
, DbHandle db
,
211 COPY_IN(AccessCredentials
, cred
))
214 relocate(cred
, credBase
, credLength
);
215 Server::database(db
).changePassphrase(cred
);
219 kern_return_t
ucsp_server_lockDb(UCSP_ARGS
, DbHandle db
)
222 Server::database(db
).lock();
226 kern_return_t
ucsp_server_lockAll (UCSP_ARGS
, boolean_t forSleep
)
229 Database::lockAllDatabases(connection
.process
.session
.databases(), forSleep
);
233 kern_return_t
ucsp_server_unlockDb(UCSP_ARGS
, DbHandle db
)
236 Server::database(db
).unlock();
240 kern_return_t
ucsp_server_unlockDbWithPassphrase(UCSP_ARGS
, DbHandle db
, DATA_IN(passphrase
))
243 Server::database(db
).unlock(DATA(passphrase
));
247 kern_return_t
ucsp_server_isLocked(UCSP_ARGS
, DbHandle db
, boolean_t
*locked
)
250 *locked
= Server::database(db
).isLocked();
258 kern_return_t
ucsp_server_encodeKey(UCSP_ARGS
, KeyHandle keyh
, DATA_OUT(blob
),
259 boolean_t wantUid
, DATA_OUT(uid
))
262 Key
&key
= Server::key(keyh
);
263 KeyBlob
*keyBlob
= key
.blob(); // still owned by key
265 *blobLength
= keyBlob
->length();
268 *uidLength
= sizeof(KeyUID
);
270 *uidLength
= 0; // do not return this
275 kern_return_t
ucsp_server_decodeKey(UCSP_ARGS
, KeyHandle
*keyh
, CssmKey::Header
*header
,
276 DbHandle db
, DATA_IN(blob
))
279 Key
&key
= *new Key(Server::database(db
), DATA(blob
).interpretedAs
<KeyBlob
>());
280 key
.returnKey(*keyh
, *header
);
285 kern_return_t
ucsp_server_releaseKey(UCSP_ARGS
, KeyHandle key
)
288 connection
.releaseKey(key
);
292 kern_return_t
ucsp_server_queryKeySizeInBits(UCSP_ARGS
, KeyHandle key
, CSSM_KEY_SIZE
*length
)
295 *length
= connection
.queryKeySize(Server::key(key
));
299 kern_return_t
ucsp_server_getOutputSize(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
300 uint32 inputSize
, boolean_t encrypt
, uint32
*outputSize
)
303 relocate(context
, contextBase
, attributes
, attrSize
);
304 *outputSize
= connection
.getOutputSize(context
, Server::key(key
), inputSize
, encrypt
);
308 kern_return_t
ucsp_server_getKeyDigest(UCSP_ARGS
, KeyHandle key
, DATA_OUT(digest
))
311 CssmData digestData
= Server::key(key
).canonicalDigest();
312 *digest
= digestData
.data();
313 *digestLength
= digestData
.length();
320 kern_return_t
ucsp_server_generateRandom(UCSP_ARGS
, uint32 bytes
, DATA_OUT(data
))
323 CssmAllocator
&allocator
= CssmAllocator::standard(CssmAllocator::sensitive
);
324 void *buffer
= allocator
.malloc(bytes
);
325 Server::active().random(buffer
, bytes
);
328 Server::releaseWhenDone(allocator
, buffer
);
334 // Signatures and MACs
336 kern_return_t
ucsp_server_generateSignature(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
337 CSSM_ALGORITHMS signOnlyAlgorithm
, DATA_IN(data
), DATA_OUT(signature
))
340 relocate(context
, contextBase
, attributes
, attrSize
);
341 OutputData
sigData(signature
, signatureLength
);
342 connection
.generateSignature(context
, Server::key(key
), signOnlyAlgorithm
,
343 DATA(data
), sigData
);
347 kern_return_t
ucsp_server_verifySignature(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
348 CSSM_ALGORITHMS verifyOnlyAlgorithm
, DATA_IN(data
), DATA_IN(signature
))
351 relocate(context
, contextBase
, attributes
, attrSize
);
352 connection
.verifySignature(context
, Server::key(key
), verifyOnlyAlgorithm
,
353 DATA(data
), DATA(signature
));
357 kern_return_t
ucsp_server_generateMac(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
358 DATA_IN(data
), DATA_OUT(mac
))
361 relocate(context
, contextBase
, attributes
, attrSize
);
362 OutputData
macData(mac
, macLength
);
363 connection
.generateMac(context
, Server::key(key
),
364 DATA(data
), macData
);
368 kern_return_t
ucsp_server_verifyMac(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
369 DATA_IN(data
), DATA_IN(mac
))
372 relocate(context
, contextBase
, attributes
, attrSize
);
373 connection
.verifyMac(context
, Server::key(key
), DATA(data
), DATA(mac
));
379 // Encryption/Decryption
381 kern_return_t
ucsp_server_encrypt(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
382 DATA_IN(clear
), DATA_OUT(cipher
))
385 relocate(context
, contextBase
, attributes
, attrSize
);
386 OutputData
cipherOut(cipher
, cipherLength
);
387 connection
.encrypt(context
, Server::key(key
),
388 DATA(clear
), cipherOut
);
392 kern_return_t
ucsp_server_decrypt(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
393 DATA_IN(cipher
), DATA_OUT(clear
))
396 relocate(context
, contextBase
, attributes
, attrSize
);
397 OutputData
clearOut(clear
, clearLength
);
398 connection
.decrypt(context
, Server::key(key
),
399 DATA(cipher
), clearOut
);
407 kern_return_t
ucsp_server_generateKey(UCSP_ARGS
, DbHandle db
, CONTEXT_ARGS
,
408 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
409 uint32 usage
, uint32 attrs
, KeyHandle
*newKey
, CssmKey::Header
*newHeader
)
412 relocate(context
, contextBase
, attributes
, attrSize
);
413 relocate(cred
, credBase
, credLength
);
414 relocate(owner
, ownerBase
, ownerLength
);
416 connection
.generateKey(Server::optionalDatabase(db
),
417 context
, cred
, owner
, usage
, attrs
, key
);
418 key
->returnKey(*newKey
, *newHeader
);
423 kern_return_t
ucsp_server_generateKeyPair(UCSP_ARGS
, DbHandle db
, CONTEXT_ARGS
,
424 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
425 uint32 pubUsage
, uint32 pubAttrs
, uint32 privUsage
, uint32 privAttrs
,
426 KeyHandle
*pubKey
, CssmKey::Header
*pubHeader
, KeyHandle
*privKey
, CssmKey::Header
*privHeader
)
429 relocate(context
, contextBase
, attributes
, attrSize
);
430 relocate(cred
, credBase
, credLength
);
431 relocate(owner
, ownerBase
, ownerLength
);
433 connection
.generateKey(Server::optionalDatabase(db
),
434 context
, cred
, owner
,
435 pubUsage
, pubAttrs
, privUsage
, privAttrs
, pub
, priv
);
436 pub
->returnKey(*pubKey
, *pubHeader
);
438 priv
->returnKey(*privKey
, *privHeader
);
446 // This is a bit strained; the incoming 'param' value may have structure
447 // and needs to be handled on a per-algorithm basis, which means we have to
448 // know which key derivation algorithms we support for passing to our CSP(s).
449 // The default behavior is to handle "flat" data blobs, which is as good
450 // a default as we can manage.
451 // NOTE: The param-specific handling must be synchronized with the client library
452 // code (in sstransit.h).
454 kern_return_t
ucsp_server_deriveKey(UCSP_ARGS
, DbHandle db
, CONTEXT_ARGS
, KeyHandle key
,
455 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
456 COPY_IN(void, paramInputData
), DATA_OUT(paramOutput
),
457 uint32 usage
, uint32 attrs
, KeyHandle
*newKey
, CssmKey::Header
*newHeader
)
460 relocate(context
, contextBase
, attributes
, attrSize
);
461 relocate(cred
, credBase
, credLength
);
462 relocate(owner
, ownerBase
, ownerLength
);
464 // munge together the incoming 'param' value according to algorithm
466 switch (context
.algorithm()) {
467 case CSSM_ALGID_PKCS5_PBKDF2
:
468 relocate((CSSM_PKCS5_PBKDF2_PARAMS
*)paramInputData
,
469 (CSSM_PKCS5_PBKDF2_PARAMS
*)paramInputDataBase
,
470 paramInputDataLength
);
471 param
= CssmData(paramInputData
, sizeof(CSSM_PKCS5_PBKDF2_PARAMS
));
474 param
= CssmData(paramInputData
, paramInputDataLength
);
477 Key
&theKey
= connection
.deriveKey(Server::optionalDatabase(db
),
478 context
, Server::optionalKey(key
), cred
, owner
, ¶m
, usage
, attrs
);
479 theKey
.returnKey(*newKey
, *newHeader
);
481 if (param
.length()) {
482 if (!param
) // CSP screwed up
483 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR
);
484 if (paramInputDataLength
) // using incoming buffer; make a copy
485 param
= CssmAutoData(Server::csp().allocator(), param
).release();
486 OutputData(paramOutput
, paramOutputLength
) = param
; // return the data
493 // Key wrapping and unwrapping
495 kern_return_t
ucsp_server_wrapKey(UCSP_ARGS
, CONTEXT_ARGS
, KeyHandle key
,
496 COPY_IN(AccessCredentials
, cred
), KeyHandle keyToBeWrapped
,
497 DATA_IN(descriptiveData
), CssmKey
*wrappedKey
, DATA_OUT(keyData
))
500 relocate(context
, contextBase
, attributes
, attrSize
);
501 relocate(cred
, credBase
, credLength
);
502 connection
.wrapKey(context
, Server::optionalKey(key
),
503 Server::key(keyToBeWrapped
), cred
, DATA(descriptiveData
), *wrappedKey
);
504 // transmit key data back as a separate blob
505 *keyData
= wrappedKey
->data();
506 *keyDataLength
= wrappedKey
->length();
507 Server::releaseWhenDone(*keyData
);
512 kern_return_t
ucsp_server_unwrapKey(UCSP_ARGS
, DbHandle db
, CONTEXT_ARGS
, KeyHandle key
,
513 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
514 KeyHandle publicKey
, CssmKey wrappedKey
, DATA_IN(wrappedKeyData
),
515 uint32 usage
, uint32 attr
, DATA_OUT(descriptiveData
),
516 KeyHandle
*newKey
, CssmKey::Header
*newHeader
)
519 relocate(context
, contextBase
, attributes
, attrSize
);
521 wrappedKey
.KeyData
= DATA(wrappedKeyData
);
522 relocate(cred
, credBase
, credLength
);
523 relocate(owner
, ownerBase
, ownerLength
);
524 CssmData descriptiveDatas
;
525 Key
&theKey
= connection
.unwrapKey(Server::optionalDatabase(db
),
526 context
, Server::optionalKey(key
), cred
, owner
, usage
, attr
, wrappedKey
,
527 Server::optionalKey(publicKey
), &descriptiveDatas
);
528 theKey
.returnKey(*newKey
, *newHeader
);
530 *descriptiveData
= descriptiveDatas
.data();
531 *descriptiveDataLength
= descriptiveDatas
.length();
532 Server::releaseWhenDone(*descriptiveData
);
539 // Watch out for the memory-management tap-dance.
541 kern_return_t
ucsp_server_getOwner(UCSP_ARGS
, AclKind kind
, KeyHandle key
,
542 COPY_OUT(AclOwnerPrototype
, ownerOut
))
545 AclOwnerPrototype owner
;
546 Server::aclBearer(kind
, key
).cssmGetOwner(owner
); // allocates memory in owner
547 Copier
<AclOwnerPrototype
> owners(&owner
, CssmAllocator::standard()); // make flat copy
548 { ChunkFreeWalker free
; walk(free
, owner
); } // release chunked original
549 *ownerOutLength
= owners
.length();
550 flips(owners
.value(), ownerOut
, ownerOutBase
);
551 Server::releaseWhenDone(owners
.keep()); // throw flat copy out when done
555 kern_return_t
ucsp_server_setOwner(UCSP_ARGS
, AclKind kind
, KeyHandle key
,
556 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclOwnerPrototype
, owner
))
559 relocate(cred
, credBase
, credLength
);
560 relocate(owner
, ownerBase
, ownerLength
);
561 Server::aclBearer(kind
, key
).cssmChangeOwner(*owner
, cred
);
565 kern_return_t
ucsp_server_getAcl(UCSP_ARGS
, AclKind kind
, KeyHandle key
,
566 boolean_t haveTag
, const char *tag
,
567 uint32
*countp
, COPY_OUT(AclEntryInfo
, acls
))
571 AclEntryInfo
*aclList
;
572 Server::aclBearer(kind
, key
).cssmGetAcl(haveTag
? tag
: NULL
, count
, aclList
);
574 Copier
<AclEntryInfo
> aclsOut(AclEntryInfo::overlay(aclList
), count
); // make flat copy
576 { // release the chunked memory originals
577 ChunkFreeWalker free
;
578 for (uint32 n
= 0; n
< count
; n
++)
579 walk(free
, aclList
[n
]);
581 // release the memory allocated for the list itself when we are done
582 CssmAllocator::standard().free (aclList
);
585 // set result (note: this is *almost* flips(), but on an array)
586 *aclsLength
= aclsOut
.length();
587 *acls
= *aclsBase
= aclsOut
;
590 for (uint32 n
= 0; n
< count
; n
++)
593 Flippers::flip(*aclsBase
);
595 Server::releaseWhenDone(aclsOut
.keep());
599 kern_return_t
ucsp_server_changeAcl(UCSP_ARGS
, AclKind kind
, KeyHandle key
,
600 COPY_IN(AccessCredentials
, cred
), CSSM_ACL_EDIT_MODE mode
, CSSM_ACL_HANDLE handle
,
601 COPY_IN(AclEntryInput
, acl
))
604 relocate(cred
, credBase
, credLength
);
605 relocate(acl
, aclBase
, aclLength
);
606 Server::aclBearer(kind
, key
).cssmChangeAcl(AclEdit(mode
, handle
, acl
), cred
);
612 // Database key management.
613 // ExtractMasterKey looks vaguely like a key derivation operation, and is in fact
614 // presented by the CSPDL's CSSM layer as such.
616 kern_return_t
ucsp_server_extractMasterKey(UCSP_ARGS
, DbHandle db
, CONTEXT_ARGS
, DbHandle sourceDb
,
617 COPY_IN(AccessCredentials
, cred
), COPY_IN(AclEntryPrototype
, owner
),
618 uint32 usage
, uint32 attrs
, KeyHandle
*newKey
, CssmKey::Header
*newHeader
)
621 context
.postIPC(contextBase
, attributes
);
622 relocate(cred
, credBase
, credLength
);
623 relocate(owner
, ownerBase
, ownerLength
);
624 Key
*masterKey
= Server::database(sourceDb
).extractMasterKey(Server::optionalDatabase(db
),
625 cred
, owner
, usage
, attrs
);
626 masterKey
->returnKey(*newKey
, *newHeader
);
633 // Authorization subsystem support
635 kern_return_t
ucsp_server_authorizationCreate(UCSP_ARGS
,
636 COPY_IN(AuthorizationItemSet
, inRights
),
638 COPY_IN(AuthorizationItemSet
, inEnvironment
),
639 AuthorizationBlob
*authorization
)
642 relocate(inRights
, inRightsBase
, inRightsLength
);
643 relocate(inEnvironment
, inEnvironmentBase
, inEnvironmentLength
);
644 Authorization::AuthItemSet
rights(inRights
), environment(inEnvironment
);
646 *rcode
= connection
.process
.session
.authCreate(rights
, environment
,
647 flags
, *authorization
, securityToken
);
651 kern_return_t
ucsp_server_authorizationRelease(UCSP_ARGS
,
652 AuthorizationBlob authorization
, uint32 flags
)
655 connection
.process
.session
.authFree(authorization
, flags
);
659 kern_return_t
ucsp_server_authorizationCopyRights(UCSP_ARGS
,
660 AuthorizationBlob authorization
,
661 COPY_IN(AuthorizationItemSet
, inRights
),
663 COPY_IN(AuthorizationItemSet
, inEnvironment
),
664 COPY_OUT(AuthorizationItemSet
, result
))
667 relocate(inRights
, inRightsBase
, inRightsLength
);
668 relocate(inEnvironment
, inEnvironmentBase
, inEnvironmentLength
);
669 Authorization::AuthItemSet
rights(inRights
), environment(inEnvironment
), grantedRights
;
670 *rcode
= connection
.process
.session
.authGetRights(authorization
,
671 rights
, environment
, flags
, grantedRights
);
672 if (result
&& resultLength
)
675 grantedRights
.copy(*result
, resultSize
);
676 *resultLength
= resultSize
;
677 *resultBase
= *result
;
678 flips(*result
, result
, resultBase
);
679 Server::releaseWhenDone(*result
);
684 kern_return_t
ucsp_server_authorizationCopyInfo(UCSP_ARGS
,
685 AuthorizationBlob authorization
,
686 AuthorizationString tag
,
687 COPY_OUT(AuthorizationItemSet
, info
))
690 Authorization::AuthItemSet infoSet
;
691 *info
= *infoBase
= NULL
;
693 *rcode
= connection
.process
.session
.authGetInfo(authorization
,
694 tag
[0] ? tag
: NULL
, infoSet
);
695 if (*rcode
== noErr
) {
697 infoSet
.copy(*info
, infoSize
);
698 *infoLength
= infoSize
;
700 flips(*info
, info
, infoBase
);
701 Server::releaseWhenDone(*info
);
706 kern_return_t
ucsp_server_authorizationExternalize(UCSP_ARGS
,
707 AuthorizationBlob authorization
, AuthorizationExternalForm
*extForm
)
710 *rcode
= connection
.process
.session
.authExternalize(authorization
, *extForm
);
714 kern_return_t
ucsp_server_authorizationInternalize(UCSP_ARGS
,
715 AuthorizationExternalForm extForm
, AuthorizationBlob
*authorization
)
718 *rcode
= connection
.process
.session
.authInternalize(extForm
, *authorization
);
724 // Session management subsystem
726 kern_return_t
ucsp_server_getSessionInfo(UCSP_ARGS
,
727 SecuritySessionId
*sessionId
, SessionAttributeBits
*attrs
)
730 Session
&session
= Session::find(*sessionId
);
731 *sessionId
= session
.handle();
732 *attrs
= session
.attributes();
736 kern_return_t
ucsp_server_setupSession(UCSP_ARGS
,
737 SessionCreationFlags flags
, SessionAttributeBits attrs
)
740 Session::setup(flags
, attrs
);
746 // Notification core subsystem
748 kern_return_t
ucsp_server_requestNotification(UCSP_ARGS
, mach_port_t receiver
, uint32 domain
, uint32 events
)
751 connection
.process
.requestNotifications(receiver
, domain
, events
);
755 kern_return_t
ucsp_server_stopNotification(UCSP_ARGS
, mach_port_t receiver
)
758 connection
.process
.stopNotifications(receiver
);
762 kern_return_t
ucsp_server_postNotification(UCSP_ARGS
, uint32 domain
, uint32 event
, DATA_IN(data
))
765 connection
.process
.postNotification(domain
, event
, DATA(data
));
771 // AuthorizationDB modification
773 kern_return_t
ucsp_server_authorizationdbGet(UCSP_ARGS
, const char *rightname
, DATA_OUT(rightDefinition
))
776 CFDictionaryRef rightDict
;
778 *rcode
= connection
.process
.session
.authorizationdbGet(rightname
, &rightDict
);
780 if (!*rcode
&& rightDict
)
782 CFRef
<CFDataRef
> data(CFPropertyListCreateXMLData (NULL
, rightDict
));
783 CFRelease(rightDict
);
785 return errAuthorizationInternal
;
787 // @@@ copy data to avoid having to do a delayed cfrelease
788 mach_msg_type_number_t length
= CFDataGetLength(data
);
789 void *xmlData
= CssmAllocator::standard().malloc(length
);
790 memcpy(xmlData
, CFDataGetBytePtr(data
), length
);
791 Server::releaseWhenDone(xmlData
);
793 *rightDefinition
= xmlData
;
794 *rightDefinitionLength
= length
;
799 kern_return_t
ucsp_server_authorizationdbSet(UCSP_ARGS
, AuthorizationBlob authorization
, const char *rightname
, DATA_IN(rightDefinition
))
802 CFRef
<CFDataRef
> data(CFDataCreate(NULL
, (UInt8
*)rightDefinition
, rightDefinitionLength
));
805 return errAuthorizationInternal
;
807 CFRef
<CFDictionaryRef
> rightDefinition(static_cast<CFDictionaryRef
>(CFPropertyListCreateFromXMLData(NULL
, data
, kCFPropertyListImmutable
, NULL
)));
809 if (!rightDefinition
|| (CFGetTypeID(rightDefinition
) != CFDictionaryGetTypeID()))
810 return errAuthorizationInternal
;
812 *rcode
= connection
.process
.session
.authorizationdbSet(authorization
, rightname
, rightDefinition
);
817 kern_return_t
ucsp_server_authorizationdbRemove(UCSP_ARGS
, AuthorizationBlob authorization
, const char *rightname
)
820 *rcode
= connection
.process
.session
.authorizationdbRemove(authorization
, rightname
);
826 // Miscellaneous administrative functions
828 kern_return_t
ucsp_server_addCodeEquivalence(UCSP_ARGS
, DATA_IN(oldHash
), DATA_IN(newHash
),
829 const char *name
, boolean_t forSystem
)
832 Server::codeSignatures().addLink(DATA(oldHash
), DATA(newHash
), name
, forSystem
);
836 kern_return_t
ucsp_server_removeCodeEquivalence(UCSP_ARGS
, DATA_IN(hash
),
837 const char *name
, boolean_t forSystem
)
840 Server::codeSignatures().removeLink(DATA(hash
), name
, forSystem
);
844 kern_return_t
ucsp_server_setAlternateSystemRoot(UCSP_ARGS
, const char *root
)
848 if (connection
.process
.uid() != 0)
849 CssmError::throwMe(CSSM_ERRCODE_OS_ACCESS_DENIED
);
851 Server::codeSignatures().open((string(root
) + EQUIVALENCEDBPATH
).c_str());