--- /dev/null
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include "securityd_data_saver.h"
+
+/*
+ * Please don't use this as an exemplar for new write...() calls. This was
+ * the first, is messy, and probably should be rewritten. At the very
+ * least, its correctness should be revisited.
+ */
+void
+SecuritydDataSave::writeContext(Context *context, intptr_t attraddr,
+ mach_msg_type_number_t attrSize)
+{
+ // finish the preamble
+ uint32_t dtype = CONTEXT;
+ writeAll(&dtype, sizeof(dtype));
+
+ // save size of a CSSM_CONTEXT (not strictly necessary)
+ uint32_t csize = sizeof(CSSM_CONTEXT);
+ writeAll(&csize, sizeof(csize)); // write the length first!
+ writeAll(context, csize);
+
+ // save the original base address for relocation
+ csize = sizeof(attraddr);
+ writeAll(&csize, sizeof(csize));
+ writeAll(&attraddr, csize);
+
+ // finally, save off the attributes
+ csize = attrSize;
+ writeAll(&csize, sizeof(csize));
+ writeAll(context->ContextAttributes, csize);
+}
+
+void
+SecuritydDataSave::writeAclEntryInfo(AclEntryInfo *acls,
+ mach_msg_type_number_t aclsLength)
+{
+ // finish the preamble
+ uint32_t dtype = ACL_ENTRY_INFO;
+ writeAll(&dtype, sizeof(dtype));
+
+ // write the base pointer, then the ACL itself
+ uint32_t ptrsize = sizeof(acls);
+ writeAll(&ptrsize, sizeof(ptrsize));
+ writeAll(&acls, ptrsize);
+ writeAll(&aclsLength, sizeof(aclsLength));
+ writeAll(acls, aclsLength);
+}
+
+void
+SecuritydDataSave::writeAclEntryInput(AclEntryInput *acl,
+ mach_msg_type_number_t aclLength)
+{
+ // finish the preamble
+ uint32_t dtype = ACL_ENTRY_INPUT;
+ writeAll(&dtype, sizeof(dtype));
+
+ // write the pointer, then the ACL itself
+ uint32_t ptrsize = sizeof(acl);
+ writeAll(&ptrsize, sizeof(ptrsize));
+ writeAll(&acl, ptrsize);
+ writeAll(&aclLength, sizeof(aclLength));
+ writeAll(acl, aclLength);
+}
+
+
+//
+// Excerpts from securityd's transition.cpp showing where SecuritydDataSave
+// is (to be) used
+//
+
+#if 0
+kern_return_t ucsp_server_findFirst(UCSP_ARGS, DbHandle db,
+ COPY_IN(CssmQuery, query),
+ COPY_IN(CssmDbRecordAttributeData, inAttributes),
+ COPY_OUT(CssmDbRecordAttributeData, outAttributes),
+ boolean_t getData,
+ DATA_OUT(data), KeyHandle *hKey, SearchHandle *hSearch, RecordHandle *hRecord)
+{
+ BEGIN_IPC
+ relocate(query, queryBase, queryLength);
+ SecuritydDataSave sds("/var/tmp/Query_findFirst");
+ sds.writeQuery(query, queryLength);
+ relocate(inAttributes, inAttributesBase, inAttributesLength);
+
+ RefPointer<Database::Search> search;
+ RefPointer<Database::Record> record;
+ RefPointer<Key> key;
+ CssmData outData; //OutputData outData(data, dataLength);
+ CssmDbRecordAttributeData *outAttrs; mach_msg_type_number_t outAttrsLength;
+ Server::database(db)->findFirst(*query, inAttributes, inAttributesLength,
+ getData ? &outData : NULL, key, search, record, outAttrs, outAttrsLength);
+
+ // handle nothing-found case without exceptions
+ if (!record) {
+ *hRecord = noRecord;
+ *hSearch = noSearch;
+ *hKey = noKey;
+ } else {
+ // return handles
+ *hRecord = record->handle();
+ *hSearch = search->handle();
+ *hKey = key ? key->handle() : noKey;
+
+ // return attributes (assumes relocated flat blob)
+ flips(outAttrs, outAttributes, outAttributesBase);
+ *outAttributesLength = outAttrsLength;
+
+ // return data (temporary fix)
+ if (getData) {
+ *data = outData.data();
+ *dataLength = outData.length();
+ }
+ }
+ END_IPC(DL)
+}
+
+kern_return_t ucsp_server_decrypt(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
+ DATA_IN(cipher), DATA_OUT(clear))
+{
+ BEGIN_IPC
+ SecuritydDataSave td("/var/tmp/securityd_Context_decrypt"); // XXX/gh get sample Context for XDR testing
+ relocate(context, contextBase, attributes, attrSize);
+ // save attributes base addr for backwards compatibility
+ intptr_t attraddr = reinterpret_cast<intptr_t>(&context->ContextAttributes);
+ td.writeContext(&context, attraddr, attrSize);
+ RefPointer<Key> key = Server::key(keyh);
+ OutputData clearOut(clear, clearLength);
+ key->database().decrypt(context, *key, DATA(cipher), clearOut);
+ END_IPC(CSP)
+}
+
+// ...
+
+kern_return_t ucsp_server_getAcl(UCSP_ARGS, AclKind kind, KeyHandle key,
+ boolean_t haveTag, const char *tag,
+ uint32 *countp, COPY_OUT(AclEntryInfo, acls))
+{
+ BEGIN_IPC
+ uint32 count;
+ AclEntryInfo *aclList;
+ Server::aclBearer(kind, key).getAcl(haveTag ? tag : NULL, count, aclList);
+ *countp = count;
+ Copier<AclEntryInfo> aclsOut(aclList, count); // make flat copy
+
+ { // release the chunked memory originals
+ ChunkFreeWalker free;
+ for (uint32 n = 0; n < count; n++)
+ walk(free, aclList[n]);
+
+ // release the memory allocated for the list itself when we are done
+ Allocator::standard().free (aclList);
+ }
+
+ // set result (note: this is *almost* flips(), but on an array)
+ *aclsLength = aclsOut.length();
+ *acls = *aclsBase = aclsOut;
+ if (flipClient()) {
+ FlipWalker w;
+ for (uint32 n = 0; n < count; n++)
+ walk(w, (*acls)[n]);
+ w.doFlips();
+ Flippers::flip(*aclsBase);
+ }
+ SecuritydDataSave sds("/var/tmp/AclEntryInfo_getAcl");
+ sds.writeAclEntryInfo(*acls, *aclsLength);
+ Server::releaseWhenDone(aclsOut.keep());
+ END_IPC(CSP)
+}
+
+kern_return_t ucsp_server_changeAcl(UCSP_ARGS, AclKind kind, KeyHandle key,
+ COPY_IN(AccessCredentials, cred), CSSM_ACL_EDIT_MODE mode, CSSM_ACL_HANDLE handle,
+ COPY_IN(AclEntryInput, acl))
+{
+ BEGIN_IPC
+ relocate(cred, credBase, credLength);
+ relocate(acl, aclBase, aclLength);
+ SecuritydDataSave sds("/var/tmp/AclEntryInput_changeAcl");
+ sds.writeAclEntryInput(acl, aclLength);
+ Server::aclBearer(kind, key).changeAcl(AclEdit(mode, handle, acl), cred);
+ END_IPC(CSP)
+}
+
+#endif /* 0 -- example code */