]> git.saurik.com Git - apple/security.git/blob - SecurityTests/xdr_rpc/Reference/transition.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / xdr_rpc / Reference / transition.cpp
1 /*
2 * Copyright (c) 2000-2004,2006 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 //
26 // transition - securityd IPC-to-class-methods transition layer
27 //
28 #include <securityd_client/ucsp.h>
29 #include "server.h"
30 #include "session.h"
31 #include "database.h"
32 #include "kcdatabase.h"
33 #include "tokendatabase.h"
34 #include "kckey.h"
35 #include "transwalkers.h"
36 #include "child.h"
37 #include <mach/mach_error.h>
38 #include "securityd_data_saver.h" // for SecuritydDataSave
39
40 #include <CoreFoundation/CFDictionary.h>
41 #include <CoreFoundation/CFPropertyList.h>
42
43
44 //
45 // Bracket Macros
46 //
47 #define UCSP_ARGS mach_port_t servicePort, mach_port_t replyPort, audit_token_t auditToken, \
48 CSSM_RETURN *rcode
49 #define CONTEXT_ARGS Context context, Pointer contextBase, Context::Attr *attributes, mach_msg_type_number_t attrSize
50
51 #define BEGIN_IPCN *rcode = CSSM_OK; try {
52 #define BEGIN_IPC BEGIN_IPCN RefPointer<Connection> connRef(&Server::connection(replyPort)); \
53 Connection &connection __attribute__((unused)) = *connRef;
54 #define END_IPC(base) END_IPCN(base) Server::requestComplete(); return KERN_SUCCESS;
55 #define END_IPCN(base) } \
56 catch (const CommonError &err) { *rcode = CssmError::cssmError(err, CSSM_ ## base ## _BASE_ERROR); } \
57 catch (const std::bad_alloc &) { *rcode = CssmError::merge(CSSM_ERRCODE_MEMORY_ERROR, CSSM_ ## base ## _BASE_ERROR); } \
58 catch (Connection *conn) { *rcode = 0; } \
59 catch (...) { *rcode = CssmError::merge(CSSM_ERRCODE_INTERNAL_ERROR, CSSM_ ## base ## _BASE_ERROR); }
60
61 #define BEGIN_IPCS try {
62 #define END_IPCS(more) } catch (...) { } \
63 mach_port_deallocate(mach_task_self(), serverPort); more; return KERN_SUCCESS;
64
65 #define DATA_IN(base) void *base, mach_msg_type_number_t base##Length
66 #define DATA_OUT(base) void **base, mach_msg_type_number_t *base##Length
67 #define DATA(base) CssmData(base, base##Length)
68 #define OPTDATA(base) (base ? &CssmData(base, base##Length) : NULL)
69
70 #define SSBLOB(Type, name) makeBlob<Type>(DATA(name))
71
72 #define COPY_IN(type,name) type *name, mach_msg_type_number_t name##Length, type *name##Base
73 #define COPY_OUT(type,name) \
74 type **name, mach_msg_type_number_t *name##Length, type **name##Base
75
76
77 using LowLevelMemoryUtilities::increment;
78 using LowLevelMemoryUtilities::difference;
79
80
81 //
82 // Setup/Teardown functions.
83 //
84 kern_return_t ucsp_server_setup(UCSP_ARGS, mach_port_t taskPort, ClientSetupInfo info, const char *identity)
85 {
86 BEGIN_IPCN
87 Server::active().setupConnection(Server::connectNewProcess, servicePort, replyPort,
88 taskPort, auditToken, &info, identity);
89 END_IPCN(CSSM)
90 return KERN_SUCCESS;
91 }
92
93 kern_return_t ucsp_server_setupNew(UCSP_ARGS, mach_port_t taskPort,
94 ClientSetupInfo info, const char *identity,
95 mach_port_t *newServicePort)
96 {
97 BEGIN_IPCN
98 try {
99 RefPointer<Session> session = new DynamicSession(taskPort);
100 Server::active().setupConnection(Server::connectNewSession, session->servicePort(), replyPort,
101 taskPort, auditToken, &info, identity);
102 *newServicePort = session->servicePort();
103 } catch (const MachPlusPlus::Error &err) {
104 switch (err.error) {
105 case BOOTSTRAP_SERVICE_ACTIVE:
106 MacOSError::throwMe(errSessionAuthorizationDenied); // translate
107 default:
108 throw;
109 }
110 }
111 END_IPCN(CSSM)
112 return KERN_SUCCESS;
113 }
114
115 kern_return_t ucsp_server_setupThread(UCSP_ARGS, mach_port_t taskPort)
116 {
117 BEGIN_IPCN
118 Server::active().setupConnection(Server::connectNewThread, servicePort, replyPort,
119 taskPort, auditToken);
120 END_IPCN(CSSM)
121 return KERN_SUCCESS;
122 }
123
124
125 kern_return_t ucsp_server_teardown(UCSP_ARGS)
126 {
127 BEGIN_IPCN
128 Server::active().endConnection(replyPort);
129 END_IPCN(CSSM)
130 return KERN_SUCCESS;
131 }
132
133
134 //
135 // Common database operations
136 //
137 kern_return_t ucsp_server_authenticateDb(UCSP_ARGS, DbHandle db,
138 CSSM_DB_ACCESS_TYPE accessType, COPY_IN(AccessCredentials, cred))
139 {
140 BEGIN_IPC
141 secdebug("dl", "authenticateDb");
142 relocate(cred, credBase, credLength);
143 // ignoring accessType
144 Server::database(db)->authenticate(accessType, cred);
145 END_IPC(DL)
146 }
147
148 kern_return_t ucsp_server_releaseDb(UCSP_ARGS, DbHandle db)
149 {
150 BEGIN_IPC
151 connection.process().kill(*Server::database(db));
152 END_IPC(DL)
153 }
154
155
156 kern_return_t ucsp_server_getDbName(UCSP_ARGS, DbHandle db, char name[PATH_MAX])
157 {
158 BEGIN_IPC
159 string result = Server::database(db)->dbName();
160 assert(result.length() < PATH_MAX);
161 memcpy(name, result.c_str(), result.length() + 1);
162 END_IPC(DL)
163 }
164
165 kern_return_t ucsp_server_setDbName(UCSP_ARGS, DbHandle db, const char *name)
166 {
167 BEGIN_IPC
168 Server::database(db)->dbName(name);
169 END_IPC(DL)
170 }
171
172
173 //
174 // External database interface
175 //
176 kern_return_t ucsp_server_openToken(UCSP_ARGS, uint32 ssid, FilePath name,
177 COPY_IN(AccessCredentials, accessCredentials), DbHandle *db)
178 {
179 BEGIN_IPC
180 relocate(accessCredentials, accessCredentialsBase, accessCredentialsLength);
181 *db = (new TokenDatabase(ssid, connection.process(), name, accessCredentials))->handle();
182 END_IPC(DL)
183 }
184
185 kern_return_t ucsp_server_findFirst(UCSP_ARGS, DbHandle db,
186 COPY_IN(CssmQuery, query),
187 COPY_IN(CssmDbRecordAttributeData, inAttributes),
188 COPY_OUT(CssmDbRecordAttributeData, outAttributes),
189 boolean_t getData,
190 DATA_OUT(data), KeyHandle *hKey, SearchHandle *hSearch, RecordHandle *hRecord)
191 {
192 BEGIN_IPC
193 relocate(query, queryBase, queryLength);
194 SecuritydDataSave sds("/var/tmp/Query_findFirst");
195 sds.writeQuery(query, queryLength);
196 relocate(inAttributes, inAttributesBase, inAttributesLength);
197
198 RefPointer<Database::Search> search;
199 RefPointer<Database::Record> record;
200 RefPointer<Key> key;
201 CssmData outData; //OutputData outData(data, dataLength);
202 CssmDbRecordAttributeData *outAttrs; mach_msg_type_number_t outAttrsLength;
203 Server::database(db)->findFirst(*query, inAttributes, inAttributesLength,
204 getData ? &outData : NULL, key, search, record, outAttrs, outAttrsLength);
205
206 // handle nothing-found case without exceptions
207 if (!record) {
208 *hRecord = noRecord;
209 *hSearch = noSearch;
210 *hKey = noKey;
211 } else {
212 // return handles
213 *hRecord = record->handle();
214 *hSearch = search->handle();
215 *hKey = key ? key->handle() : noKey;
216
217 // return attributes (assumes relocated flat blob)
218 flips(outAttrs, outAttributes, outAttributesBase);
219 *outAttributesLength = outAttrsLength;
220
221 // return data (temporary fix)
222 if (getData) {
223 *data = outData.data();
224 *dataLength = outData.length();
225 }
226 }
227 END_IPC(DL)
228 }
229
230 kern_return_t ucsp_server_findNext(UCSP_ARGS, SearchHandle hSearch,
231 COPY_IN(CssmDbRecordAttributeData, inAttributes),
232 COPY_OUT(CssmDbRecordAttributeData, outAttributes),
233 boolean_t getData, DATA_OUT(data), KeyHandle *hKey,
234 RecordHandle *hRecord)
235 {
236 BEGIN_IPC
237 relocate(inAttributes, inAttributesBase, inAttributesLength);
238 RefPointer<Database::Search> search =
239 Server::find<Database::Search>(hSearch, CSSMERR_DL_INVALID_RESULTS_HANDLE);
240 RefPointer<Database::Record> record;
241 RefPointer<Key> key;
242 CssmData outData; //OutputData outData(data, dataLength);
243 CssmDbRecordAttributeData *outAttrs; mach_msg_type_number_t outAttrsLength;
244 search->database().findNext(search, inAttributes, inAttributesLength,
245 getData ? &outData : NULL, key, record, outAttrs, outAttrsLength);
246
247 // handle nothing-found case without exceptions
248 if (!record) {
249 *hRecord = noRecord;
250 *hKey = noKey;
251 } else {
252 // return handles
253 *hRecord = record->handle();
254 *hKey = key ? key->handle() : noKey;
255
256 // return attributes (assumes relocated flat blob)
257 flips(outAttrs, outAttributes, outAttributesBase);
258 *outAttributesLength = outAttrsLength;
259
260 // return data (temporary fix)
261 if (getData) {
262 *data = outData.data();
263 *dataLength = outData.length();
264 }
265 }
266 END_IPC(DL)
267 }
268
269 kern_return_t ucsp_server_findRecordHandle(UCSP_ARGS, RecordHandle hRecord,
270 COPY_IN(CssmDbRecordAttributeData, inAttributes),
271 COPY_OUT(CssmDbRecordAttributeData, outAttributes),
272 boolean_t getData, DATA_OUT(data), KeyHandle *hKey)
273 {
274 BEGIN_IPC
275 relocate(inAttributes, inAttributesBase, inAttributesLength);
276 RefPointer<Database::Record> record =
277 Server::find<Database::Record>(hRecord, CSSMERR_DL_INVALID_RECORD_UID);
278 RefPointer<Key> key;
279 CssmData outData; //OutputData outData(data, dataLength);
280 CssmDbRecordAttributeData *outAttrs; mach_msg_type_number_t outAttrsLength;
281 record->database().findRecordHandle(record, inAttributes, inAttributesLength,
282 getData ? &outData : NULL, key, outAttrs, outAttrsLength);
283
284 // return handles
285 *hKey = key ? key->handle() : noKey;
286
287 // return attributes (assumes relocated flat blob)
288 flips(outAttrs, outAttributes, outAttributesBase);
289 *outAttributesLength = outAttrsLength;
290
291 // return data (temporary fix)
292 if (getData) {
293 *data = outData.data();
294 *dataLength = outData.length();
295 }
296 END_IPC(DL)
297 }
298
299 kern_return_t ucsp_server_insertRecord(UCSP_ARGS, DbHandle db, CSSM_DB_RECORDTYPE recordType,
300 COPY_IN(CssmDbRecordAttributeData, attributes), DATA_IN(data), RecordHandle *record)
301 {
302 BEGIN_IPC
303 relocate(attributes, attributesBase, attributesLength);
304 Server::database(db)->insertRecord(recordType, attributes, attributesLength,
305 DATA(data), *record);
306 END_IPC(DL)
307 }
308
309 kern_return_t ucsp_server_modifyRecord(UCSP_ARGS, DbHandle db, RecordHandle *hRecord,
310 CSSM_DB_RECORDTYPE recordType, COPY_IN(CssmDbRecordAttributeData, attributes),
311 boolean_t setData, DATA_IN(data), CSSM_DB_MODIFY_MODE modifyMode)
312 {
313 BEGIN_IPC
314 relocate(attributes, attributesBase, attributesLength);
315 CssmData newData(DATA(data));
316 RefPointer<Database::Record> record =
317 Server::find<Database::Record>(*hRecord, CSSMERR_DL_INVALID_RECORD_UID);
318 Server::database(db)->modifyRecord(recordType, record, attributes, attributesLength,
319 setData ? &newData : NULL, modifyMode);
320 // note that the record handle presented to the client never changes here
321 // (we could, but have no reason to - our record handles are just always up to date)
322 END_IPC(DL)
323 }
324
325 kern_return_t ucsp_server_deleteRecord(UCSP_ARGS, DbHandle db, RecordHandle hRecord)
326 {
327 BEGIN_IPC
328 Server::database(db)->deleteRecord(
329 Server::find<Database::Record>(hRecord, CSSMERR_DL_INVALID_RECORD_UID));
330 END_IPC(DL)
331 }
332
333 kern_return_t ucsp_server_releaseSearch(UCSP_ARGS, SearchHandle hSearch)
334 {
335 BEGIN_IPC
336 RefPointer<Database::Search> search = Server::find<Database::Search>(hSearch, 0);
337 search->database().releaseSearch(*search);
338 END_IPC(DL)
339 }
340
341 kern_return_t ucsp_server_releaseRecord(UCSP_ARGS, RecordHandle hRecord)
342 {
343 BEGIN_IPC
344 RefPointer<Database::Record> record = Server::find<Database::Record>(hRecord, 0);
345 record->database().releaseRecord(*record);
346 END_IPC(DL)
347 }
348
349 kern_return_t ucsp_server_getRecordFromHandle(UCSP_ARGS, RecordHandle record,
350 COPY_IN(CssmDbRecordAttributeData, inAttributes),
351 COPY_OUT(CssmDbRecordAttributeData, outAttributes),
352 boolean_t getData,
353 DATA_OUT(data))
354 {
355 BEGIN_IPC
356 secdebug("dl", "getRecordFromHandle");
357 relocate(inAttributes, inAttributesBase, inAttributesLength);
358 // @@@
359 END_IPC(DL)
360 }
361
362
363 //
364 // Internal database management
365 //
366 kern_return_t ucsp_server_createDb(UCSP_ARGS, DbHandle *db,
367 COPY_IN(DLDbFlatIdentifier, ident),
368 COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
369 DBParameters params)
370 {
371 BEGIN_IPC
372 relocate(cred, credBase, credLength);
373 relocate(owner, ownerBase, ownerLength);
374 relocate(ident, identBase, identLength);
375 *db = (new KeychainDatabase(*ident, params, connection.process(), cred, owner))->handle();
376 END_IPC(DL)
377 }
378
379 // keychain synchronization
380 // @@@ caller should be required to call decodeDb() to get a DbHandle
381 // instead of passing the blob itself
382 kern_return_t ucsp_server_cloneDbForSync(UCSP_ARGS, DATA_IN(blob),
383 DbHandle srcDb, DATA_IN(agentData), DbHandle *newDb)
384 {
385 BEGIN_IPC
386 RefPointer<KeychainDatabase> srcKC = Server::keychain(srcDb);
387 *newDb = (new KeychainDatabase(*srcKC, connection.process(),
388 SSBLOB(DbBlob, blob), DATA(agentData)))->handle();
389 END_IPC(DL)
390 }
391
392 kern_return_t ucsp_server_commitDbForSync(UCSP_ARGS, DbHandle srcDb,
393 DbHandle cloneDb, DATA_OUT(blob))
394 {
395 BEGIN_IPC
396 RefPointer<KeychainDatabase> srcKC = Server::keychain(srcDb);
397 RefPointer<KeychainDatabase> cloneKC = Server::keychain(cloneDb);
398 srcKC->commitSecretsForSync(*cloneKC);
399
400 // re-encode blob for convenience
401 if (blob && blobLength) {
402 DbBlob *dbBlob = srcKC->blob();
403 *blob = dbBlob;
404 *blobLength = dbBlob->length();
405 } else {
406 secdebug("kcrecode", "No blob can be returned to client");
407 }
408 END_IPC(DL)
409 }
410
411 kern_return_t ucsp_server_decodeDb(UCSP_ARGS, DbHandle *db,
412 COPY_IN(DLDbFlatIdentifier, ident), COPY_IN(AccessCredentials, cred), DATA_IN(blob))
413 {
414 BEGIN_IPC
415 relocate(cred, credBase, credLength);
416 relocate(ident, identBase, identLength);
417 *db = (new KeychainDatabase(*ident, SSBLOB(DbBlob, blob),
418 connection.process(), cred))->handle();
419 END_IPC(DL)
420 }
421
422 kern_return_t ucsp_server_encodeDb(UCSP_ARGS, DbHandle db, DATA_OUT(blob))
423 {
424 BEGIN_IPC
425 DbBlob *dbBlob = Server::keychain(db)->blob(); // memory owned by database
426 *blob = dbBlob;
427 *blobLength = dbBlob->length();
428 END_IPC(DL)
429 }
430
431 kern_return_t ucsp_server_setDbParameters(UCSP_ARGS, DbHandle db, DBParameters params)
432 {
433 BEGIN_IPC
434 Server::keychain(db)->setParameters(params);
435 END_IPC(DL)
436 }
437
438 kern_return_t ucsp_server_getDbParameters(UCSP_ARGS, DbHandle db, DBParameters *params)
439 {
440 BEGIN_IPC
441 Server::keychain(db)->getParameters(*params);
442 END_IPC(DL)
443 }
444
445 kern_return_t ucsp_server_changePassphrase(UCSP_ARGS, DbHandle db,
446 COPY_IN(AccessCredentials, cred))
447 {
448 BEGIN_IPC
449 relocate(cred, credBase, credLength);
450 Server::keychain(db)->changePassphrase(cred);
451 END_IPC(DL)
452 }
453
454 kern_return_t ucsp_server_lockAll (UCSP_ARGS, boolean_t)
455 {
456 BEGIN_IPC
457 connection.session().processLockAll();
458 END_IPC(DL)
459 }
460
461 kern_return_t ucsp_server_unlockDb(UCSP_ARGS, DbHandle db)
462 {
463 BEGIN_IPC
464 Server::keychain(db)->unlockDb();
465 END_IPC(DL)
466 }
467
468 kern_return_t ucsp_server_unlockDbWithPassphrase(UCSP_ARGS, DbHandle db, DATA_IN(passphrase))
469 {
470 BEGIN_IPC
471 Server::keychain(db)->unlockDb(DATA(passphrase));
472 END_IPC(DL)
473 }
474
475 kern_return_t ucsp_server_isLocked(UCSP_ARGS, DbHandle db, boolean_t *locked)
476 {
477 BEGIN_IPC
478 *locked = Server::database(db)->isLocked();
479 END_IPC(DL)
480 }
481
482
483 //
484 // Key management
485 //
486 kern_return_t ucsp_server_encodeKey(UCSP_ARGS, KeyHandle keyh, DATA_OUT(blob),
487 boolean_t wantUid, DATA_OUT(uid))
488 {
489 BEGIN_IPC
490 RefPointer<Key> gKey = Server::key(keyh);
491 if (KeychainKey *key = dynamic_cast<KeychainKey *>(gKey.get())) {
492 KeyBlob *keyBlob = key->blob(); // still owned by key
493 *blob = keyBlob;
494 *blobLength = keyBlob->length();
495 if (wantUid) { // uid generation is not implemented
496 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
497 } else {
498 *uidLength = 0; // do not return this
499 }
500 } else { // not a KeychainKey
501 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
502 }
503 END_IPC(CSP)
504 }
505
506 kern_return_t ucsp_server_decodeKey(UCSP_ARGS, KeyHandle *keyh, CssmKey::Header *header,
507 DbHandle db, DATA_IN(blob))
508 {
509 BEGIN_IPC
510 RefPointer<Key> key = new KeychainKey(*Server::keychain(db), SSBLOB(KeyBlob, blob));
511 key->returnKey(*keyh, *header);
512 flip(*header);
513 END_IPC(CSP)
514 }
515
516 // keychain synchronization
517 kern_return_t ucsp_server_recodeKey(UCSP_ARGS, DbHandle oldDb, KeyHandle keyh,
518 DbHandle newDb, DATA_OUT(newBlob))
519 {
520 BEGIN_IPC
521 // If the old key is passed in as DATA_IN(oldBlob):
522 // RefPointer<KeychainKey> key = new KeychainKey(*Server::keychain(oldDb), SSBLOB(KeyBlob, oldBlob));
523 RefPointer<Key> key = Server::key(keyh);
524 if (KeychainKey *kckey = dynamic_cast<KeychainKey *>(key.get())) {
525 KeyBlob *blob = Server::keychain(newDb)->recodeKey(*kckey);
526 *newBlob = blob;
527 *newBlobLength = blob->length();
528 Server::releaseWhenDone(*newBlob);
529 // @@@ stop leaking blob
530 } else { // not a KeychainKey
531 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
532 }
533 END_IPC(CSP)
534 }
535
536 kern_return_t ucsp_server_releaseKey(UCSP_ARGS, KeyHandle keyh)
537 {
538 BEGIN_IPC
539 RefPointer<Key> key = Server::key(keyh);
540 key->database().releaseKey(*key);
541 END_IPC(CSP)
542 }
543
544 kern_return_t ucsp_server_queryKeySizeInBits(UCSP_ARGS, KeyHandle keyh, CSSM_KEY_SIZE *length)
545 {
546 BEGIN_IPC
547 RefPointer<Key> key = Server::key(keyh);
548 key->database().queryKeySizeInBits(*key, CssmKeySize::overlay(*length));
549 END_IPC(CSP)
550 }
551
552 kern_return_t ucsp_server_getOutputSize(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
553 uint32 inputSize, boolean_t encrypt, uint32 *outputSize)
554 {
555 BEGIN_IPC
556 relocate(context, contextBase, attributes, attrSize);
557 RefPointer<Key> key = Server::key(keyh);
558 key->database().getOutputSize(context, *key, inputSize, encrypt, *outputSize);
559 END_IPC(CSP)
560 }
561
562 kern_return_t ucsp_server_getKeyDigest(UCSP_ARGS, KeyHandle key, DATA_OUT(digest))
563 {
564 BEGIN_IPC
565 CssmData digestData = Server::key(key)->canonicalDigest();
566 *digest = digestData.data();
567 *digestLength = digestData.length();
568 END_IPC(CSP)
569 }
570
571
572 //
573 // Signatures and MACs
574 //
575 kern_return_t ucsp_server_generateSignature(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
576 CSSM_ALGORITHMS signOnlyAlgorithm, DATA_IN(data), DATA_OUT(signature))
577 {
578 BEGIN_IPC
579 relocate(context, contextBase, attributes, attrSize);
580 RefPointer<Key> key = Server::key(keyh);
581 OutputData sigData(signature, signatureLength);
582 key->database().generateSignature(context, *key, signOnlyAlgorithm,
583 DATA(data), sigData);
584 END_IPC(CSP)
585 }
586
587 kern_return_t ucsp_server_verifySignature(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
588 CSSM_ALGORITHMS verifyOnlyAlgorithm, DATA_IN(data), DATA_IN(signature))
589 {
590 BEGIN_IPC
591 relocate(context, contextBase, attributes, attrSize);
592 RefPointer<Key> key = Server::key(keyh);
593 key->database().verifySignature(context, *key, verifyOnlyAlgorithm,
594 DATA(data), DATA(signature));
595 END_IPC(CSP)
596 }
597
598 kern_return_t ucsp_server_generateMac(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
599 DATA_IN(data), DATA_OUT(mac))
600 {
601 BEGIN_IPC
602 relocate(context, contextBase, attributes, attrSize);
603 RefPointer<Key> key = Server::key(keyh);
604 OutputData macData(mac, macLength);
605 key->database().generateMac(context, *key, DATA(data), macData);
606 END_IPC(CSP)
607 }
608
609 kern_return_t ucsp_server_verifyMac(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
610 DATA_IN(data), DATA_IN(mac))
611 {
612 BEGIN_IPC
613 relocate(context, contextBase, attributes, attrSize);
614 RefPointer<Key> key = Server::key(keyh);
615 key->database().verifyMac(context, *key, DATA(data), DATA(mac));
616 END_IPC(CSP)
617 }
618
619
620 //
621 // Encryption/Decryption
622 //
623 kern_return_t ucsp_server_encrypt(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
624 DATA_IN(clear), DATA_OUT(cipher))
625 {
626 BEGIN_IPC
627 relocate(context, contextBase, attributes, attrSize);
628 RefPointer<Key> key = Server::key(keyh);
629 OutputData cipherOut(cipher, cipherLength);
630 key->database().encrypt(context, *key, DATA(clear), cipherOut);
631 END_IPC(CSP)
632 }
633
634 kern_return_t ucsp_server_decrypt(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
635 DATA_IN(cipher), DATA_OUT(clear))
636 {
637 BEGIN_IPC
638 SecuritydDataSave sds("/var/tmp/securityd_Context_decrypt"); // XXX/gh get sample Context for XDR testing
639 relocate(context, contextBase, attributes, attrSize);
640 // save attributes base addr for backwards compatibility
641 intptr_t attraddr = reinterpret_cast<intptr_t>(&context->ContextAttributes);
642 sds.writeContext(&context, attraddr, attrSize);
643 RefPointer<Key> key = Server::key(keyh);
644 OutputData clearOut(clear, clearLength);
645 key->database().decrypt(context, *key, DATA(cipher), clearOut);
646 END_IPC(CSP)
647 }
648
649
650 //
651 // Key generation
652 //
653 kern_return_t ucsp_server_generateKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
654 COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
655 uint32 usage, uint32 attrs, KeyHandle *newKey, CssmKey::Header *newHeader)
656 {
657 BEGIN_IPC
658 relocate(context, contextBase, attributes, attrSize);
659 relocate(cred, credBase, credLength);
660 relocate(owner, ownerBase, ownerLength);
661 //@@@ preliminary interpretation - will get "type handle"
662 RefPointer<Database> database =
663 Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT);
664 RefPointer<Key> key;
665 database->generateKey(context, cred, owner, usage, attrs, key);
666 key->returnKey(*newKey, *newHeader);
667 flip(*newHeader);
668 END_IPC(CSP)
669 }
670
671 kern_return_t ucsp_server_generateKeyPair(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
672 COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
673 uint32 pubUsage, uint32 pubAttrs, uint32 privUsage, uint32 privAttrs,
674 KeyHandle *pubKey, CssmKey::Header *pubHeader, KeyHandle *privKey, CssmKey::Header *privHeader)
675 {
676 BEGIN_IPC
677 relocate(context, contextBase, attributes, attrSize);
678 relocate(cred, credBase, credLength);
679 relocate(owner, ownerBase, ownerLength);
680 RefPointer<Database> database =
681 Server::optionalDatabase(db, (privAttrs | pubAttrs) & CSSM_KEYATTR_PERMANENT);
682 RefPointer<Key> pub, priv;
683 database->generateKey(context, cred, owner,
684 pubUsage, pubAttrs, privUsage, privAttrs, pub, priv);
685 pub->returnKey(*pubKey, *pubHeader);
686 flip(*pubHeader);
687 priv->returnKey(*privKey, *privHeader);
688 flip(*privHeader);
689 END_IPC(CSP)
690 }
691
692
693 //
694 // Key wrapping and unwrapping
695 //
696 kern_return_t ucsp_server_wrapKey(UCSP_ARGS, CONTEXT_ARGS, KeyHandle hWrappingKey,
697 COPY_IN(AccessCredentials, cred), KeyHandle hKeyToBeWrapped,
698 DATA_IN(descriptiveData), CssmKey *wrappedKey, DATA_OUT(keyData))
699 {
700 BEGIN_IPC
701 relocate(context, contextBase, attributes, attrSize);
702 relocate(cred, credBase, credLength);
703 RefPointer<Key> subjectKey = Server::key(hKeyToBeWrapped);
704 RefPointer<Key> wrappingKey = Server::optionalKey(hWrappingKey);
705 if ((context.algorithm() == CSSM_ALGID_NONE && subjectKey->attribute(CSSM_KEYATTR_SENSITIVE))
706 || !subjectKey->attribute(CSSM_KEYATTR_EXTRACTABLE))
707 CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
708 pickDb(subjectKey, wrappingKey)->wrapKey(context, cred, wrappingKey, *subjectKey, DATA(descriptiveData), *wrappedKey);
709
710 // transmit key data back as a separate blob
711 OutputData keyDatas(keyData, keyDataLength);
712 keyDatas = wrappedKey->keyData();
713 flip(*wrappedKey);
714 END_IPC(CSP)
715 }
716
717 kern_return_t ucsp_server_unwrapKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
718 KeyHandle hWrappingKey, COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
719 KeyHandle hPublicKey, CssmKey wrappedKey, DATA_IN(wrappedKeyData),
720 CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs, DATA_OUT(descriptiveData),
721 KeyHandle *newKey, CssmKey::Header *newHeader)
722 {
723 BEGIN_IPC
724 relocate(context, contextBase, attributes, attrSize);
725 flip(wrappedKey);
726 wrappedKey.keyData() = DATA(wrappedKeyData);
727 relocate(cred, credBase, credLength);
728 relocate(owner, ownerBase, ownerLength);
729 OutputData descriptiveDatas(descriptiveData, descriptiveDataLength);
730 RefPointer<Key> wrappingKey = Server::optionalKey(hWrappingKey);
731 RefPointer<Key> unwrappedKey;
732 pickDb(Server::optionalDatabase(db), wrappingKey)->unwrapKey(context, cred, owner,
733 wrappingKey, Server::optionalKey(hPublicKey),
734 usage, attrs, wrappedKey, unwrappedKey, descriptiveDatas);
735 unwrappedKey->returnKey(*newKey, *newHeader);
736 flip(*newHeader);
737 END_IPC(CSP)
738 }
739
740
741 //
742 // Key derivation.
743 //
744 // Note that the "param" argument can have structure. The walker for the
745 // (artificial) POD CssmDeriveData handles those that are known; if you add
746 // an algorithm with structured param, you need to add a case there.
747 //
748 kern_return_t ucsp_server_deriveKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS, KeyHandle hKey,
749 COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
750 COPY_IN(CssmDeriveData, paramInput), DATA_OUT(paramOutput),
751 uint32 usage, uint32 attrs, KeyHandle *newKey, CssmKey::Header *newHeader)
752 {
753 BEGIN_IPC
754 relocate(context, contextBase, attributes, attrSize);
755 relocate(cred, credBase, credLength);
756 relocate(owner, ownerBase, ownerLength);
757 relocate(paramInput, paramInputBase, paramInputLength);
758 if (!paramInput || paramInput->algorithm != context.algorithm())
759 CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); // client layer fault
760
761 RefPointer<Database> database =
762 Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT);
763 RefPointer<Key> key = Server::optionalKey(hKey);
764 CssmData *param = paramInput ? &paramInput->baseData : NULL;
765 RefPointer<Key> derivedKey;
766 pickDb(Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT),
767 key)->deriveKey(context, key, cred, owner, param, usage, attrs, derivedKey);
768 derivedKey->returnKey(*newKey, *newHeader);
769 flip(*newHeader);
770 if (param && param->length()) {
771 if (!param->data()) // CSP screwed up
772 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
773 if (paramInputLength) // using incoming buffer; make a copy
774 *param = CssmAutoData(Server::csp().allocator(), *param).release();
775 OutputData(paramOutput, paramOutputLength) = *param; // return the data
776 }
777 END_IPC(CSP)
778 }
779
780
781 //
782 // Random generation
783 //
784 kern_return_t ucsp_server_generateRandom(UCSP_ARGS, uint32 ssid, CONTEXT_ARGS, DATA_OUT(data))
785 {
786 BEGIN_IPC
787 relocate(context, contextBase, attributes, attrSize);
788 if (ssid)
789 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
790
791 // default version (use /dev/random)
792 Allocator &allocator = Allocator::standard(Allocator::sensitive);
793 if (size_t bytes = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE)) {
794 void *buffer = allocator.malloc(bytes);
795 Server::active().random(buffer, bytes);
796 *data = buffer;
797 *dataLength = bytes;
798 Server::releaseWhenDone(allocator, buffer);
799 }
800 END_IPC(CSP)
801 }
802
803
804 //
805 // ACL management.
806 // Watch out for the memory-management tap-dance.
807 //
808 kern_return_t ucsp_server_getOwner(UCSP_ARGS, AclKind kind, KeyHandle key,
809 COPY_OUT(AclOwnerPrototype, ownerOut))
810 {
811 BEGIN_IPC
812 AclOwnerPrototype owner;
813 Server::aclBearer(kind, key).getOwner(owner); // allocates memory in owner
814 Copier<AclOwnerPrototype> owners(&owner, Allocator::standard()); // make flat copy
815 { ChunkFreeWalker free; walk(free, owner); } // release chunked original
816 *ownerOutLength = owners.length();
817 flips(owners.value(), ownerOut, ownerOutBase);
818 Server::releaseWhenDone(owners.keep()); // throw flat copy out when done
819 END_IPC(CSP)
820 }
821
822 kern_return_t ucsp_server_setOwner(UCSP_ARGS, AclKind kind, KeyHandle key,
823 COPY_IN(AccessCredentials, cred), COPY_IN(AclOwnerPrototype, owner))
824 {
825 BEGIN_IPC
826 relocate(cred, credBase, credLength);
827 relocate(owner, ownerBase, ownerLength);
828 Server::aclBearer(kind, key).changeOwner(*owner, cred);
829 END_IPC(CSP)
830 }
831
832 kern_return_t ucsp_server_getAcl(UCSP_ARGS, AclKind kind, KeyHandle key,
833 boolean_t haveTag, const char *tag,
834 uint32 *countp, COPY_OUT(AclEntryInfo, acls))
835 {
836 BEGIN_IPC
837 uint32 count;
838 AclEntryInfo *aclList;
839 Server::aclBearer(kind, key).getAcl(haveTag ? tag : NULL, count, aclList);
840 *countp = count;
841 Copier<AclEntryInfo> aclsOut(aclList, count); // make flat copy
842
843 { // release the chunked memory originals
844 ChunkFreeWalker free;
845 for (uint32 n = 0; n < count; n++)
846 walk(free, aclList[n]);
847
848 // release the memory allocated for the list itself when we are done
849 Allocator::standard().free (aclList);
850 }
851
852 // set result (note: this is *almost* flips(), but on an array)
853 *aclsLength = aclsOut.length();
854 *acls = *aclsBase = aclsOut;
855 if (flipClient()) {
856 FlipWalker w;
857 for (uint32 n = 0; n < count; n++)
858 walk(w, (*acls)[n]);
859 w.doFlips();
860 Flippers::flip(*aclsBase);
861 }
862 SecuritydDataSave sds("/var/tmp/AclEntryInfo_getAcl");
863 sds.writeAclEntryInfo(*acls, *aclsLength);
864 Server::releaseWhenDone(aclsOut.keep());
865 END_IPC(CSP)
866 }
867
868 kern_return_t ucsp_server_changeAcl(UCSP_ARGS, AclKind kind, KeyHandle key,
869 COPY_IN(AccessCredentials, cred), CSSM_ACL_EDIT_MODE mode, CSSM_ACL_HANDLE handle,
870 COPY_IN(AclEntryInput, acl))
871 {
872 BEGIN_IPC
873 relocate(cred, credBase, credLength);
874 relocate(acl, aclBase, aclLength);
875 SecuritydDataSave sds("/var/tmp/AclEntryInput_changeAcl");
876 sds.writeAclEntryInput(acl, aclLength);
877 Server::aclBearer(kind, key).changeAcl(AclEdit(mode, handle, acl), cred);
878 END_IPC(CSP)
879 }
880
881
882 //
883 // Login/Logout
884 //
885 kern_return_t ucsp_server_login(UCSP_ARGS, COPY_IN(AccessCredentials, cred), DATA_IN(name))
886 {
887 BEGIN_IPC
888 relocate(cred, credBase, credLength);
889 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
890 END_IPC(CSP)
891 }
892
893 kern_return_t ucsp_server_logout(UCSP_ARGS)
894 {
895 BEGIN_IPC
896 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
897 END_IPC(CSP)
898 }
899
900
901 //
902 // Miscellaneous CSP-related calls
903 //
904 kern_return_t ucsp_server_getStatistics(UCSP_ARGS, uint32 ssid, CSPOperationalStatistics *statistics)
905 {
906 BEGIN_IPC
907 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
908 END_IPC(CSP)
909 }
910
911 kern_return_t ucsp_server_getTime(UCSP_ARGS, uint32 ssid, CSSM_ALGORITHMS algorithm, DATA_OUT(data))
912 {
913 BEGIN_IPC
914 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
915 END_IPC(CSP)
916 }
917
918 kern_return_t ucsp_server_getCounter(UCSP_ARGS, uint32 ssid, DATA_OUT(data))
919 {
920 BEGIN_IPC
921 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
922 END_IPC(CSP)
923 }
924
925 kern_return_t ucsp_server_selfVerify(UCSP_ARGS, uint32 ssid)
926 {
927 BEGIN_IPC
928 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
929 END_IPC(CSP)
930 }
931
932
933 //
934 // Passthrough calls (separate for CSP and DL passthroughs)
935 //
936 kern_return_t ucsp_server_cspPassThrough(UCSP_ARGS, uint32 ssid, uint32 id, CONTEXT_ARGS,
937 KeyHandle hKey, DATA_IN(inData), DATA_OUT(outData))
938 {
939 BEGIN_IPC
940 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
941 END_IPC(CSP)
942 }
943
944 kern_return_t ucsp_server_dlPassThrough(UCSP_ARGS, uint32 ssid, uint32 id,
945 DATA_IN(inData), DATA_OUT(outData))
946 {
947 BEGIN_IPC
948 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
949 END_IPC(DL)
950 }
951
952
953 //
954 // Database key management.
955 // ExtractMasterKey looks vaguely like a key derivation operation, and is in fact
956 // presented by the CSPDL's CSSM layer as such.
957 //
958 kern_return_t ucsp_server_extractMasterKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS, DbHandle sourceDb,
959 COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
960 uint32 usage, uint32 attrs, KeyHandle *newKey, CssmKey::Header *newHeader)
961 {
962 BEGIN_IPC
963 context.postIPC(contextBase, attributes);
964 relocate(cred, credBase, credLength);
965 relocate(owner, ownerBase, ownerLength);
966 RefPointer<KeychainDatabase> keychain = Server::keychain(sourceDb);
967 RefPointer<Key> masterKey = keychain->extractMasterKey(
968 *Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT),
969 cred, owner, usage, attrs);
970 masterKey->returnKey(*newKey, *newHeader);
971 flip(*newHeader);
972 END_IPC(CSP)
973 }
974
975
976 //
977 // Authorization subsystem support
978 //
979 kern_return_t ucsp_server_authorizationCreate(UCSP_ARGS,
980 COPY_IN(AuthorizationItemSet, inRights),
981 uint32 flags,
982 COPY_IN(AuthorizationItemSet, inEnvironment),
983 AuthorizationBlob *authorization)
984 {
985 BEGIN_IPC
986 relocate(inRights, inRightsBase, inRightsLength);
987 relocate(inEnvironment, inEnvironmentBase, inEnvironmentLength);
988 Authorization::AuthItemSet rights(inRights), environment(inEnvironment);
989
990 *rcode = connection.process().session().authCreate(rights, environment,
991 flags, *authorization, auditToken);
992 END_IPC(CSSM)
993 }
994
995 kern_return_t ucsp_server_authorizationRelease(UCSP_ARGS,
996 AuthorizationBlob authorization, uint32 flags)
997 {
998 BEGIN_IPC
999 connection.process().session().authFree(authorization, flags);
1000 END_IPC(CSSM)
1001 }
1002
1003 kern_return_t ucsp_server_authorizationCopyRights(UCSP_ARGS,
1004 AuthorizationBlob authorization,
1005 COPY_IN(AuthorizationItemSet, inRights),
1006 uint32 flags,
1007 COPY_IN(AuthorizationItemSet, inEnvironment),
1008 COPY_OUT(AuthorizationItemSet, result))
1009 {
1010 BEGIN_IPC
1011 relocate(inRights, inRightsBase, inRightsLength);
1012 relocate(inEnvironment, inEnvironmentBase, inEnvironmentLength);
1013 Authorization::AuthItemSet rights(inRights), environment(inEnvironment), grantedRights;
1014 *rcode = connection.process().session().authGetRights(authorization,
1015 rights, environment, flags, grantedRights);
1016 if (result && resultLength)
1017 {
1018 size_t resultSize;
1019 grantedRights.copy(*result, resultSize);
1020 *resultLength = resultSize;
1021 *resultBase = *result;
1022 flips(*result, result, resultBase);
1023 Server::releaseWhenDone(*result);
1024 }
1025 END_IPC(CSSM)
1026 }
1027
1028 kern_return_t ucsp_server_authorizationCopyInfo(UCSP_ARGS,
1029 AuthorizationBlob authorization,
1030 AuthorizationString tag,
1031 COPY_OUT(AuthorizationItemSet, info))
1032 {
1033 BEGIN_IPC
1034 Authorization::AuthItemSet infoSet;
1035 *info = *infoBase = NULL;
1036 *infoLength = 0;
1037 *rcode = connection.process().session().authGetInfo(authorization,
1038 tag[0] ? tag : NULL, infoSet);
1039 if (*rcode == noErr) {
1040 size_t infoSize;
1041 infoSet.copy(*info, infoSize);
1042 *infoLength = infoSize;
1043 *infoBase = *info;
1044 flips(*info, info, infoBase);
1045 Server::releaseWhenDone(*info);
1046 }
1047 END_IPC(CSSM)
1048 }
1049
1050 kern_return_t ucsp_server_authorizationExternalize(UCSP_ARGS,
1051 AuthorizationBlob authorization, AuthorizationExternalForm *extForm)
1052 {
1053 BEGIN_IPC
1054 *rcode = connection.process().session().authExternalize(authorization, *extForm);
1055 END_IPC(CSSM)
1056 }
1057
1058 kern_return_t ucsp_server_authorizationInternalize(UCSP_ARGS,
1059 AuthorizationExternalForm extForm, AuthorizationBlob *authorization)
1060 {
1061 BEGIN_IPC
1062 *rcode = connection.process().session().authInternalize(extForm, *authorization);
1063 END_IPC(CSSM)
1064 }
1065
1066
1067 //
1068 // Session management subsystem
1069 //
1070 kern_return_t ucsp_server_getSessionInfo(UCSP_ARGS,
1071 SecuritySessionId *sessionId, SessionAttributeBits *attrs)
1072 {
1073 BEGIN_IPC
1074 Session &session = Session::find(*sessionId);
1075 *sessionId = session.handle();
1076 *attrs = session.attributes();
1077 END_IPC(CSSM)
1078 }
1079
1080 kern_return_t ucsp_server_setupSession(UCSP_ARGS,
1081 SessionCreationFlags flags, SessionAttributeBits attrs)
1082 {
1083 BEGIN_IPC
1084 Server::process().session().setupAttributes(flags, attrs);
1085 END_IPC(CSSM)
1086 }
1087
1088 kern_return_t ucsp_server_setSessionDistinguishedUid(UCSP_ARGS,
1089 SecuritySessionId sessionId, uid_t user)
1090 {
1091 BEGIN_IPC
1092 Session::find<DynamicSession>(sessionId).originatorUid(user);
1093 END_IPC(CSSM)
1094 }
1095
1096 kern_return_t ucsp_server_getSessionDistinguishedUid(UCSP_ARGS,
1097 SecuritySessionId sessionId, uid_t *user)
1098 {
1099 BEGIN_IPC
1100 *user = Session::find(sessionId).originatorUid();
1101 END_IPC(CSSM)
1102 }
1103
1104 kern_return_t ucsp_server_setSessionUserPrefs(UCSP_ARGS, SecuritySessionId sessionId, DATA_IN(userPrefs))
1105 {
1106 BEGIN_IPC
1107 CFRef<CFDataRef> data(CFDataCreate(NULL, (UInt8 *)userPrefs, userPrefsLength));
1108
1109 if (!data)
1110 {
1111 *rcode = errSessionValueNotSet;
1112 return 0;
1113 }
1114
1115 Session::find<DynamicSession>(sessionId).setUserPrefs(data);
1116 *rcode = 0;
1117
1118 END_IPC(CSSM)
1119 }
1120
1121
1122
1123 //
1124 // Notification core subsystem
1125 //
1126 kern_return_t ucsp_server_requestNotification(UCSP_ARGS, mach_port_t receiver, uint32 domain, uint32 events)
1127 {
1128 BEGIN_IPC
1129 connection.process().requestNotifications(receiver, domain, events);
1130 END_IPC(CSSM)
1131 }
1132
1133 kern_return_t ucsp_server_stopNotification(UCSP_ARGS, mach_port_t receiver)
1134 {
1135 BEGIN_IPC
1136 connection.process().stopNotifications(receiver);
1137 END_IPC(CSSM)
1138 }
1139
1140 kern_return_t ucsp_server_postNotification(mach_port_t serverPort, uint32 domain, uint32 event, DATA_IN(data))
1141 {
1142 BEGIN_IPCS
1143 Listener::notify(domain, event, DATA(data));
1144 END_IPCS()
1145 }
1146
1147
1148 //
1149 // AuthorizationDB modification
1150 //
1151 kern_return_t ucsp_server_authorizationdbGet(UCSP_ARGS, const char *rightname, DATA_OUT(rightDefinition))
1152 {
1153 BEGIN_IPC
1154 CFDictionaryRef rightDict;
1155
1156 *rcode = connection.process().session().authorizationdbGet(rightname, &rightDict);
1157
1158 if (!*rcode && rightDict)
1159 {
1160 CFRef<CFDataRef> data(CFPropertyListCreateXMLData (NULL, rightDict));
1161 CFRelease(rightDict);
1162 if (!data)
1163 return errAuthorizationInternal;
1164
1165 // @@@ copy data to avoid having to do a delayed cfrelease
1166 mach_msg_type_number_t length = CFDataGetLength(data);
1167 void *xmlData = Allocator::standard().malloc(length);
1168 memcpy(xmlData, CFDataGetBytePtr(data), length);
1169 Server::releaseWhenDone(xmlData);
1170
1171 *rightDefinition = xmlData;
1172 *rightDefinitionLength = length;
1173 }
1174 END_IPC(CSSM)
1175 }
1176
1177 kern_return_t ucsp_server_authorizationdbSet(UCSP_ARGS, AuthorizationBlob authorization, const char *rightname, DATA_IN(rightDefinition))
1178 {
1179 BEGIN_IPC
1180 CFRef<CFDataRef> data(CFDataCreate(NULL, (UInt8 *)rightDefinition, rightDefinitionLength));
1181
1182 if (!data)
1183 return errAuthorizationInternal;
1184
1185 CFRef<CFDictionaryRef> rightDefinition(static_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(NULL, data, kCFPropertyListImmutable, NULL)));
1186
1187 if (!rightDefinition || (CFGetTypeID(rightDefinition) != CFDictionaryGetTypeID()))
1188 return errAuthorizationInternal;
1189
1190 *rcode = connection.process().session().authorizationdbSet(authorization, rightname, rightDefinition);
1191
1192 END_IPC(CSSM)
1193 }
1194
1195 kern_return_t ucsp_server_authorizationdbRemove(UCSP_ARGS, AuthorizationBlob authorization, const char *rightname)
1196 {
1197 BEGIN_IPC
1198 *rcode = connection.process().session().authorizationdbRemove(authorization, rightname);
1199 END_IPC(CSSM)
1200 }
1201
1202
1203 //
1204 // Miscellaneous administrative functions
1205 //
1206 kern_return_t ucsp_server_addCodeEquivalence(UCSP_ARGS, DATA_IN(oldHash), DATA_IN(newHash),
1207 const char *name, boolean_t forSystem)
1208 {
1209 BEGIN_IPC
1210 Server::codeSignatures().addLink(DATA(oldHash), DATA(newHash), name, forSystem);
1211 END_IPC(CSSM)
1212 }
1213
1214 kern_return_t ucsp_server_removeCodeEquivalence(UCSP_ARGS, DATA_IN(hash),
1215 const char *name, boolean_t forSystem)
1216 {
1217 BEGIN_IPC
1218 Server::codeSignatures().removeLink(DATA(hash), name, forSystem);
1219 END_IPC(CSSM)
1220 }
1221
1222 kern_return_t ucsp_server_setAlternateSystemRoot(UCSP_ARGS, const char *root)
1223 {
1224 BEGIN_IPC
1225 #if defined(NDEBUG)
1226 if (connection.process().uid() != 0)
1227 CssmError::throwMe(CSSM_ERRCODE_OS_ACCESS_DENIED);
1228 #endif //NDEBUG
1229 Server::codeSignatures().open((string(root) + EQUIVALENCEDBPATH).c_str());
1230 END_IPC(CSSM)
1231 }
1232
1233
1234 //
1235 // Child check-in service.
1236 // Note that this isn't using the standard argument pattern.
1237 //
1238 kern_return_t ucsp_server_childCheckIn(mach_port_t serverPort,
1239 mach_port_t servicePort, mach_port_t taskPort)
1240 {
1241 BEGIN_IPCS
1242 ServerChild::checkIn(servicePort, TaskPort(taskPort).pid());
1243 END_IPCS(mach_port_deallocate(mach_task_self(), taskPort))
1244 }