]> git.saurik.com Git - apple/securityd.git/commitdiff
securityd-32661.tar.gz v32661
authorApple <opensource@apple.com>
Mon, 1 Oct 2007 21:50:55 +0000 (21:50 +0000)
committerApple <opensource@apple.com>
Mon, 1 Oct 2007 21:50:55 +0000 (21:50 +0000)
81 files changed:
APPLE_LICENSE [new file with mode: 0644]
doc/BLOBFORMAT
doc/securityd.1
etc/CodeEquivalenceCandidates
etc/authorization.plist
etc/com.apple.securityd.plist [new file with mode: 0644]
etc/securityd-installCD.plist [deleted file]
etc/securityd.plist [deleted file]
etc/startup.mk
securityd.xcode/project.pbxproj [deleted file]
securityd.xcodeproj/project.pbxproj [new file with mode: 0644]
src/AuthorizationDBPlist.cpp
src/AuthorizationDBPlist.h
src/AuthorizationEngine.cpp
src/AuthorizationMechEval.cpp
src/AuthorizationMechEval.h
src/AuthorizationRule.cpp
src/AuthorizationRule.h
src/SharedMemoryServer.cpp [new file with mode: 0644]
src/SharedMemoryServer.h [new file with mode: 0644]
src/acl_keychain.cpp
src/acl_keychain.h
src/acls.cpp
src/acls.h
src/agentquery.cpp
src/agentquery.h
src/authhost.cpp
src/authority.cpp
src/authority.h
src/child.cpp
src/clientid.cpp [new file with mode: 0644]
src/clientid.h [new file with mode: 0644]
src/codesigdb.cpp
src/codesigdb.h
src/connection.cpp
src/connection.h
src/credential.cpp [new file with mode: 0644]
src/credential.h [new file with mode: 0644]
src/csproxy.cpp [new file with mode: 0644]
src/csproxy.h [new file with mode: 0644]
src/database.cpp
src/database.h
src/dbcrypto.cpp
src/dbcrypto.h
src/flippers.cpp [deleted file]
src/flippers.h [deleted file]
src/generate.cf [deleted file]
src/generate.mk [deleted file]
src/generate.pl [deleted file]
src/kcdatabase.cpp
src/kcdatabase.h
src/kckey.cpp
src/kckey.h
src/localdatabase.cpp
src/localkey.cpp
src/main.cpp
src/notifications.cpp
src/notifications.h
src/osxcodewrap.cpp [new file with mode: 0644]
src/osxcodewrap.h [new file with mode: 0644]
src/pcscmonitor.cpp
src/pcscmonitor.h
src/process.cpp
src/process.h
src/securityd.exp [new file with mode: 0644]
src/securityd.order
src/server.cpp
src/server.h
src/session.cpp
src/session.h
src/token.cpp
src/token.h
src/tokenacl.cpp
src/tokencache.cpp
src/tokend.cpp
src/tokend.h
src/tokendatabase.cpp
src/tokendatabase.h
src/transition.cpp
src/transwalkers.cpp [deleted file]
src/transwalkers.h [deleted file]

diff --git a/APPLE_LICENSE b/APPLE_LICENSE
new file mode 100644 (file)
index 0000000..fe81a60
--- /dev/null
@@ -0,0 +1,367 @@
+APPLE PUBLIC SOURCE LICENSE
+Version 2.0 - August 6, 2003
+
+Please read this License carefully before downloading this software.
+By downloading or using this software, you are agreeing to be bound by
+the terms of this License. If you do not or cannot agree to the terms
+of this License, please do not download or use the software.
+
+1. General; Definitions. This License applies to any program or other
+work which Apple Computer, Inc. ("Apple") makes publicly available and
+which contains a notice placed by Apple identifying such program or
+work as "Original Code" and stating that it is subject to the terms of
+this Apple Public Source License version 2.0 ("License"). As used in
+this License:
+
+1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is
+the grantor of rights, (i) claims of patents that are now or hereafter
+acquired, owned by or assigned to Apple and (ii) that cover subject
+matter contained in the Original Code, but only to the extent
+necessary to use, reproduce and/or distribute the Original Code
+without infringement; and (b) in the case where You are the grantor of
+rights, (i) claims of patents that are now or hereafter acquired,
+owned by or assigned to You and (ii) that cover subject matter in Your
+Modifications, taken alone or in combination with Original Code.
+
+1.2 "Contributor" means any person or entity that creates or
+contributes to the creation of Modifications.
+
+1.3 "Covered Code" means the Original Code, Modifications, the
+combination of Original Code and any Modifications, and/or any
+respective portions thereof.
+
+1.4 "Externally Deploy" means: (a) to sublicense, distribute or
+otherwise make Covered Code available, directly or indirectly, to
+anyone other than You; and/or (b) to use Covered Code, alone or as
+part of a Larger Work, in any way to provide a service, including but
+not limited to delivery of content, through electronic communication
+with a client other than You.
+
+1.5 "Larger Work" means a work which combines Covered Code or portions
+thereof with code not governed by the terms of this License.
+
+1.6 "Modifications" mean any addition to, deletion from, and/or change
+to, the substance and/or structure of the Original Code, any previous
+Modifications, the combination of Original Code and any previous
+Modifications, and/or any respective portions thereof. When code is
+released as a series of files, a Modification is: (a) any addition to
+or deletion from the contents of a file containing Covered Code;
+and/or (b) any new file or other representation of computer program
+statements that contains any part of Covered Code.
+
+1.7 "Original Code" means (a) the Source Code of a program or other
+work as originally made available by Apple under this License,
+including the Source Code of any updates or upgrades to such programs
+or works made available by Apple under this License, and that has been
+expressly identified by Apple as such in the header file(s) of such
+work; and (b) the object code compiled from such Source Code and
+originally made available by Apple under this License.
+
+1.8 "Source Code" means the human readable form of a program or other
+work that is suitable for making modifications to it, including all
+modules it contains, plus any associated interface definition files,
+scripts used to control compilation and installation of an executable
+(object code).
+
+1.9 "You" or "Your" means an individual or a legal entity exercising
+rights under this License. For legal entities, "You" or "Your"
+includes any entity which controls, is controlled by, or is under
+common control with, You, where "control" means (a) the power, direct
+or indirect, to cause the direction or management of such entity,
+whether by contract or otherwise, or (b) ownership of fifty percent
+(50%) or more of the outstanding shares or beneficial ownership of
+such entity.
+
+2. Permitted Uses; Conditions & Restrictions. Subject to the terms
+and conditions of this License, Apple hereby grants You, effective on
+the date You accept this License and download the Original Code, a
+world-wide, royalty-free, non-exclusive license, to the extent of
+Apple's Applicable Patent Rights and copyrights covering the Original
+Code, to do the following:
+
+2.1 Unmodified Code. You may use, reproduce, display, perform,
+internally distribute within Your organization, and Externally Deploy
+verbatim, unmodified copies of the Original Code, for commercial or
+non-commercial purposes, provided that in each instance:
+
+(a) You must retain and reproduce in all copies of Original Code the
+copyright and other proprietary notices and disclaimers of Apple as
+they appear in the Original Code, and keep intact all notices in the
+Original Code that refer to this License; and
+
+(b) You must include a copy of this License with every copy of Source
+Code of Covered Code and documentation You distribute or Externally
+Deploy, and You may not offer or impose any terms on such Source Code
+that alter or restrict this License or the recipients' rights
+hereunder, except as permitted under Section 6.
+
+2.2 Modified Code. You may modify Covered Code and use, reproduce,
+display, perform, internally distribute within Your organization, and
+Externally Deploy Your Modifications and Covered Code, for commercial
+or non-commercial purposes, provided that in each instance You also
+meet all of these conditions:
+
+(a) You must satisfy all the conditions of Section 2.1 with respect to
+the Source Code of the Covered Code;
+
+(b) You must duplicate, to the extent it does not already exist, the
+notice in Exhibit A in each file of the Source Code of all Your
+Modifications, and cause the modified files to carry prominent notices
+stating that You changed the files and the date of any change; and
+
+(c) If You Externally Deploy Your Modifications, You must make
+Source Code of all Your Externally Deployed Modifications either
+available to those to whom You have Externally Deployed Your
+Modifications, or publicly available. Source Code of Your Externally
+Deployed Modifications must be released under the terms set forth in
+this License, including the license grants set forth in Section 3
+below, for as long as you Externally Deploy the Covered Code or twelve
+(12) months from the date of initial External Deployment, whichever is
+longer. You should preferably distribute the Source Code of Your
+Externally Deployed Modifications electronically (e.g. download from a
+web site).
+
+2.3 Distribution of Executable Versions. In addition, if You
+Externally Deploy Covered Code (Original Code and/or Modifications) in
+object code, executable form only, You must include a prominent
+notice, in the code itself as well as in related documentation,
+stating that Source Code of the Covered Code is available under the
+terms of this License with information on how and where to obtain such
+Source Code.
+
+2.4 Third Party Rights. You expressly acknowledge and agree that
+although Apple and each Contributor grants the licenses to their
+respective portions of the Covered Code set forth herein, no
+assurances are provided by Apple or any Contributor that the Covered
+Code does not infringe the patent or other intellectual property
+rights of any other entity. Apple and each Contributor disclaim any
+liability to You for claims brought by any other entity based on
+infringement of intellectual property rights or otherwise. As a
+condition to exercising the rights and licenses granted hereunder, You
+hereby assume sole responsibility to secure any other intellectual
+property rights needed, if any. For example, if a third party patent
+license is required to allow You to distribute the Covered Code, it is
+Your responsibility to acquire that license before distributing the
+Covered Code.
+
+3. Your Grants. In consideration of, and as a condition to, the
+licenses granted to You under this License, You hereby grant to any
+person or entity receiving or distributing Covered Code under this
+License a non-exclusive, royalty-free, perpetual, irrevocable license,
+under Your Applicable Patent Rights and other intellectual property
+rights (other than patent) owned or controlled by You, to use,
+reproduce, display, perform, modify, sublicense, distribute and
+Externally Deploy Your Modifications of the same scope and extent as
+Apple's licenses under Sections 2.1 and 2.2 above.
+
+4. Larger Works. You may create a Larger Work by combining Covered
+Code with other code not governed by the terms of this License and
+distribute the Larger Work as a single product. In each such instance,
+You must make sure the requirements of this License are fulfilled for
+the Covered Code or any portion thereof.
+
+5. Limitations on Patent License. Except as expressly stated in
+Section 2, no other patent rights, express or implied, are granted by
+Apple herein. Modifications and/or Larger Works may require additional
+patent licenses from Apple which Apple may grant in its sole
+discretion.
+
+6. Additional Terms. You may choose to offer, and to charge a fee for,
+warranty, support, indemnity or liability obligations and/or other
+rights consistent with the scope of the license granted herein
+("Additional Terms") to one or more recipients of Covered Code.
+However, You may do so only on Your own behalf and as Your sole
+responsibility, and not on behalf of Apple or any Contributor. You
+must obtain the recipient's agreement that any such Additional Terms
+are offered by You alone, and You hereby agree to indemnify, defend
+and hold Apple and every Contributor harmless for any liability
+incurred by or claims asserted against Apple or such Contributor by
+reason of any such Additional Terms.
+
+7. Versions of the License. Apple may publish revised and/or new
+versions of this License from time to time. Each version will be given
+a distinguishing version number. Once Original Code has been published
+under a particular version of this License, You may continue to use it
+under the terms of that version. You may also choose to use such
+Original Code under the terms of any subsequent version of this
+License published by Apple. No one other than Apple has the right to
+modify the terms applicable to Covered Code created under this
+License.
+
+8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in
+part pre-release, untested, or not fully tested works. The Covered
+Code may contain errors that could cause failures or loss of data, and
+may be incomplete or contain inaccuracies. You expressly acknowledge
+and agree that use of the Covered Code, or any portion thereof, is at
+Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND
+WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND
+APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE
+PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM
+ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF
+MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR
+PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD
+PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST
+INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE
+FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS,
+THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR
+ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO
+ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE
+AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY.
+You acknowledge that the Covered Code is not intended for use in the
+operation of nuclear facilities, aircraft navigation, communication
+systems, or air traffic control machines in which case the failure of
+the Covered Code could lead to death, personal injury, or severe
+physical or environmental damage.
+
+9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
+EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL,
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING
+TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR
+ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY,
+TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF
+APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY
+REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY
+TO YOU. In no event shall Apple's total liability to You for all
+damages (other than as may be required by applicable law) under this
+License exceed the amount of fifty dollars ($50.00).
+
+10. Trademarks. This License does not grant any rights to use the
+trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS",
+"QuickTime", "QuickTime Streaming Server" or any other trademarks,
+service marks, logos or trade names belonging to Apple (collectively
+"Apple Marks") or to any trademark, service mark, logo or trade name
+belonging to any Contributor. You agree not to use any Apple Marks in
+or as part of the name of products derived from the Original Code or
+to endorse or promote products derived from the Original Code other
+than as expressly permitted by and in strict compliance at all times
+with Apple's third party trademark usage guidelines which are posted
+at http://www.apple.com/legal/guidelinesfor3rdparties.html.
+
+11. Ownership. Subject to the licenses granted under this License,
+each Contributor retains all rights, title and interest in and to any
+Modifications made by such Contributor. Apple retains all rights,
+title and interest in and to the Original Code and any Modifications
+made by or on behalf of Apple ("Apple Modifications"), and such Apple
+Modifications will not be automatically subject to this License. Apple
+may, at its sole discretion, choose to license such Apple
+Modifications under this License, or on different terms from those
+contained in this License or may choose not to license them at all.
+
+12. Termination.
+
+12.1 Termination. This License and the rights granted hereunder will
+terminate:
+
+(a) automatically without notice from Apple if You fail to comply with
+any term(s) of this License and fail to cure such breach within 30
+days of becoming aware of such breach;
+
+(b) immediately in the event of the circumstances described in Section
+13.5(b); or
+
+(c) automatically without notice from Apple if You, at any time during
+the term of this License, commence an action for patent infringement
+against Apple; provided that Apple did not first commence
+an action for patent infringement against You in that instance.
+
+12.2 Effect of Termination. Upon termination, You agree to immediately
+stop any further use, reproduction, modification, sublicensing and
+distribution of the Covered Code. All sublicenses to the Covered Code
+which have been properly granted prior to termination shall survive
+any termination of this License. Provisions which, by their nature,
+should remain in effect beyond the termination of this License shall
+survive, including but not limited to Sections 3, 5, 8, 9, 10, 11,
+12.2 and 13. No party will be liable to any other for compensation,
+indemnity or damages of any sort solely as a result of terminating
+this License in accordance with its terms, and termination of this
+License will be without prejudice to any other right or remedy of
+any party.
+
+13. Miscellaneous.
+
+13.1 Government End Users. The Covered Code is a "commercial item" as
+defined in FAR 2.101. Government software and technical data rights in
+the Covered Code include only those rights customarily provided to the
+public as defined in this License. This customary commercial license
+in technical data and software is provided in accordance with FAR
+12.211 (Technical Data) and 12.212 (Computer Software) and, for
+Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
+Commercial Items) and 227.7202-3 (Rights in Commercial Computer
+Software or Computer Software Documentation). Accordingly, all U.S.
+Government End Users acquire Covered Code with only those rights set
+forth herein.
+
+13.2 Relationship of Parties. This License will not be construed as
+creating an agency, partnership, joint venture or any other form of
+legal association between or among You, Apple or any Contributor, and
+You will not represent to the contrary, whether expressly, by
+implication, appearance or otherwise.
+
+13.3 Independent Development. Nothing in this License will impair
+Apple's right to acquire, license, develop, have others develop for
+it, market and/or distribute technology or products that perform the
+same or similar functions as, or otherwise compete with,
+Modifications, Larger Works, technology or products that You may
+develop, produce, market or distribute.
+
+13.4 Waiver; Construction. Failure by Apple or any Contributor to
+enforce any provision of this License will not be deemed a waiver of
+future enforcement of that or any other provision. Any law or
+regulation which provides that the language of a contract shall be
+construed against the drafter will not apply to this License.
+
+13.5 Severability. (a) If for any reason a court of competent
+jurisdiction finds any provision of this License, or portion thereof,
+to be unenforceable, that provision of the License will be enforced to
+the maximum extent permissible so as to effect the economic benefits
+and intent of the parties, and the remainder of this License will
+continue in full force and effect. (b) Notwithstanding the foregoing,
+if applicable law prohibits or restricts You from fully and/or
+specifically complying with Sections 2 and/or 3 or prevents the
+enforceability of either of those Sections, this License will
+immediately terminate and You must immediately discontinue any use of
+the Covered Code and destroy all copies of it that are in your
+possession or control.
+
+13.6 Dispute Resolution. Any litigation or other dispute resolution
+between You and Apple relating to this License shall take place in the
+Northern District of California, and You and Apple hereby consent to
+the personal jurisdiction of, and venue in, the state and federal
+courts within that District with respect to this License. The
+application of the United Nations Convention on Contracts for the
+International Sale of Goods is expressly excluded.
+
+13.7 Entire Agreement; Governing Law. This License constitutes the
+entire agreement between the parties with respect to the subject
+matter hereof. This License shall be governed by the laws of the
+United States and the State of California, except that body of
+California law concerning conflicts of law.
+
+Where You are located in the province of Quebec, Canada, the following
+clause applies: The parties hereby confirm that they have requested
+that this License and all related documents be drafted in English. Les
+parties ont exige que le present contrat et tous les documents
+connexes soient rediges en anglais.
+
+EXHIBIT A.
+
+"Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+Reserved.
+
+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."
index 22528f706b8926a4523398b0b5a52625ecf9cbba..6e426695c194d4ae7cc01c05b3358d28ba0e4293 100644 (file)
@@ -61,4 +61,3 @@ Decode (input DSK, DEK, KB output PRIVATE_KEY_BYTES, PUBLIC_KEY_BYTES)
 5. Reverse the order of the octects in TEMP3 and call the result TEMP2.
 6. Split TEMP2 in IV (first 8 bytes) and TEMP1 (rest).
 7. Decrypt TEMP1 using DEK (3DES) and IV in CBC mode with PKCS1 padding.  Call the plaintext PRIVATE_KEY_BYTES.
 5. Reverse the order of the octects in TEMP3 and call the result TEMP2.
 6. Split TEMP2 in IV (first 8 bytes) and TEMP1 (rest).
 7. Decrypt TEMP1 using DEK (3DES) and IV in CBC mode with PKCS1 padding.  Call the plaintext PRIVATE_KEY_BYTES.
-
index e9ded6968d16e04d0591cb0b0a3b00260b9236ae..b23cae7d431859ad25ade5be6ecc812ed283e7b2 100644 (file)
@@ -31,6 +31,6 @@ is mediated through the
 This command is not intended to be invoked directly.
 .Sh HISTORY
 .Nm
 This command is not intended to be invoked directly.
 .Sh HISTORY
 .Nm
-was first introduced in Mac OS X version 10.0 (Cheetah) as the "Security Server" and was renamed in 10.4 (Panther).
+was first introduced in Mac OS X version 10.0 (Cheetah) as the "Security Server" and was renamed in 10.4 (Tiger).
 .Sh AUTHORS
 .Sh AUTHORS
-.An "Perry Kiehtreiber"
+.An "Perry The Cynic"
index 5404062d0d0b36f3db0ea72d01955b9a77350e65..41674bced628814b112b5d783e9e618e7e0deb8e 100644 (file)
@@ -21,6 +21,7 @@
 /System/Library/CoreServices/loginwindow.app
 /System/Library/CoreServices/MirrorAgent.app
 /System/Library/CoreServices/SecurityAgent.app
 /System/Library/CoreServices/loginwindow.app
 /System/Library/CoreServices/MirrorAgent.app
 /System/Library/CoreServices/SecurityAgent.app
+/System/Library/CoreServices/SecurityAgent.app/Contents/Resources/authorizationhost
 /System/Library/CoreServices/SyncServer.app
 /System/Library/CoreServices/SyncServer.app/Contents/Resources/safaritool
 /System/Library/CoreServices/SystemUIServer.app
 /System/Library/CoreServices/SyncServer.app
 /System/Library/CoreServices/SyncServer.app/Contents/Resources/safaritool
 /System/Library/CoreServices/SystemUIServer.app
 /System/Library/Frameworks/SecurityFoundation.framework/Resources/dotmacfx.app
 /System/Library/Frameworks/SecurityFoundation.framework/Resources/kcSync.app
 /System/Library/PreferencePanes/Mac.prefPane
 /System/Library/Frameworks/SecurityFoundation.framework/Resources/dotmacfx.app
 /System/Library/Frameworks/SecurityFoundation.framework/Resources/kcSync.app
 /System/Library/PreferencePanes/Mac.prefPane
-/System/Library/PreferencePanes/Mac.prefPane/Contents/Resources/dotMacPrefTool
+/System/Library/PreferencePanes/Mac.prefPane/Contents/Resources/dotMacPrefTool 
+/System/Library/PreferencePanes/Mac.prefPane/Contents/Versions/A/Resources/dotMacPrefTool 
+/System/Library/PreferencePanes/Mac.prefPane/Contents/Versions/Current/Resources/dotMacPrefTool 
 /System/Library/PrivateFrameworks/Admin.framework/Resources/writeconfig
 /System/Library/PrivateFrameworks/Admin.framework/Versions/A/Resources/writeconfig
 /System/Library/PrivateFrameworks/Admin.framework/Resources/writeconfig
 /System/Library/PrivateFrameworks/Admin.framework/Versions/A/Resources/writeconfig
+/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport
 /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport
 /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport
+/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
+/System/Library/PrivateFrameworks/Apple80211.framework/Resources/AirPortNetworkPrefs.bundle/Contents/Resources/AirPortCfgTool
 /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/AirPortNetworkPrefs.bundle/Contents/Resources/AirPortCfgTool
 /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/AirPortNetworkPrefs.bundle/Contents/Resources/AirPortCfgTool
+/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/AirPortNetworkPrefs.bundle/Contents/Resources/AirPortCfgTool
 /System/Library/PrivateFrameworks/DotmacLegacy.framework/Resources/dotMacTranslator
 /System/Library/PrivateFrameworks/DotmacLegacy.framework/Versions/A/Resources/dotMacTranslator
 /System/Library/PrivateFrameworks/DotmacLegacy.framework/Versions/Current/Resources/dotMacTranslator
 /System/Library/PrivateFrameworks/DotmacLegacy.framework/Resources/dotMacTranslator
 /System/Library/PrivateFrameworks/DotmacLegacy.framework/Versions/A/Resources/dotMacTranslator
 /System/Library/PrivateFrameworks/DotmacLegacy.framework/Versions/Current/Resources/dotMacTranslator
index 0dc7382e8ea665a2a53d947b6d3b5309d6c6b7fb..c5d137040f092e7984172c6db5d3eef25f287556 100644 (file)
@@ -15,7 +15,7 @@ deny rule: this is always denied
 
 user rule: successful authentication as a user in the specified group(5) allows the associated right.
 
 
 user rule: successful authentication as a user in the specified group(5) allows the associated right.
 
-The shared property specifies whether a credential generated on success is shared with other apps (same "session"). This property defaults to false if not specified.
+The shared property specifies whether a credential generated on success is shared with other apps (i.e., those in the same "session"). This property defaults to false if not specified.
 
 The timeout property specifies the maximum age of a (cached/shared) credential accepted for this rule.
 
 
 The timeout property specifies the maximum age of a (cached/shared) credential accepted for this rule.
 
@@ -30,7 +30,7 @@ See remaining rules for examples.
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
-                       <string>All other rights will be matched by this rule.</string>
+                       <string>Matches otherwise unmatched rights (i.e., is a default).</string>
                        <key>rule</key>
                        <string>default</string>
                </dict>
                        <key>rule</key>
                        <string>default</string>
                </dict>
@@ -39,21 +39,21 @@ See remaining rules for examples.
                        <key>class</key>
                        <string>allow</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>allow</string>
                        <key>comment</key>
-                       <string>wildcard right for adding rights.  Anyone is allowed to add any (non-wildcard) rights</string>
+                       <string>Wildcard right for adding rights.  Anyone is allowed to add any (non-wildcard) rights.</string>
                </dict>
                <key>config.config.</key>
                <dict>
                        <key>class</key>
                        <string>deny</string>
                        <key>comment</key>
                </dict>
                <key>config.config.</key>
                <dict>
                        <key>class</key>
                        <string>deny</string>
                        <key>comment</key>
-                       <string>wildcard right for any change to meta-rights for db modification.  Not allowed programmatically (just edit this file)</string>
+                       <string>Wildcard right for any change to meta-rights for db modification.  Not allowed programmatically (just edit this file).</string>
                </dict>
                <key>config.modify.</key>
                <dict>
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
                </dict>
                <key>config.modify.</key>
                <dict>
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
-                       <string>wildcard right for modifying rights.  Admins are allowed to modify any (non-wildcard) rights.  Root does not require authentication.</string>
+                       <string>Wildcard right for modifying rights.  Admins are allowed to modify any (non-wildcard) rights.  Root does not require authentication.</string>
                        <key>k-of-n</key>
                        <integer>1</integer>
                        <key>rule</key>
                        <key>k-of-n</key>
                        <integer>1</integer>
                        <key>rule</key>
@@ -67,7 +67,7 @@ See remaining rules for examples.
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
-                       <string>wildcard right for deleting rights.  Admins are allowed to delete any (non-wildcard) rights.  Root does not require authentication.</string>
+                       <string>Wildcard right for deleting rights.  Admins are allowed to delete any (non-wildcard) rights.  Root does not require authentication.</string>
                        <key>k-of-n</key>
                        <integer>1</integer>
                        <key>rule</key>
                        <key>k-of-n</key>
                        <integer>1</integer>
                        <key>rule</key>
@@ -81,7 +81,7 @@ See remaining rules for examples.
                        <key>class</key>
                        <string>deny</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>deny</string>
                        <key>comment</key>
-                       <string>wildcard right for deleting system rights.</string>
+                       <string>Wildcard right for deleting system rights.</string>
                </dict>
                <key>com.apple.</key>
                <dict>
                </dict>
                <key>com.apple.</key>
                <dict>
@@ -111,9 +111,7 @@ See remaining rules for examples.
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>Used by the dvd player to set the regioncode the first time.  Note that changed the region code after it has been set requires a different right (system.device.dvd.setregion.change)
-Credentials remain valid indefinitely after they've been obtained.
-An acquired credential is shared amongst all clients.</string>
+                       <string>Used by the DVD player to set the region code the first time.  Note that changing the region code after it has been set requires a different right (system.device.dvd.setregion.change).</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -124,52 +122,35 @@ An acquired credential is shared amongst all clients.</string>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                        <key>comment</key>
-                       <string>Login mechanism based rule.  Not for general use, yet.
-builtin:krb5authenticate can be used to hinge local authentication on a successful kerberos authentication and kdc verification.
-builtin:krb5authnoverify skips the kdc verification.  Both fall back on local authentication.</string>
+                       <string>Login mechanism based rule.  Not for general use, yet.</string>
                        <key>mechanisms</key>
                        <array>
                        <key>mechanisms</key>
                        <array>
-                               <string>builtin:auto-login,privileged</string>
-                               <string>loginwindow_builtin:login</string>
+                               <string>builtin:smartcard-sniffer,privileged</string>
+                               <string>loginwindow:login</string>
                                <string>builtin:reset-password,privileged</string>
                                <string>builtin:reset-password,privileged</string>
-                               <string>authinternal</string>
-                               <string>builtin:getuserinfo,privileged</string>
-                               <string>builtin:sso,privileged</string>
+                               <string>builtin:auto-login,privileged</string>
+                               <string>builtin:authenticate,privileged</string>
                                <string>HomeDirMechanism:login,privileged</string>
                                <string>HomeDirMechanism:status</string>
                                <string>MCXMechanism:login</string>
                                <string>HomeDirMechanism:login,privileged</string>
                                <string>HomeDirMechanism:status</string>
                                <string>MCXMechanism:login</string>
-                               <string>loginwindow_builtin:success</string>
-                               <string>loginwindow_builtin:done</string>
+                               <string>loginwindow:success</string>
+                               <string>loginwindow:done</string>
                        </array>
                </dict>
                <key>system.login.done</key>
                <dict>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                        </array>
                </dict>
                <key>system.login.done</key>
                <dict>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
-                       <key>comment</key>
-                       <string>builtin:krb5login can be used to do kerberos authentication as a side-effect of logging in.  Local username/password will be used.</string>
                        <key>mechanisms</key>
                        <array>
                        </array>
                </dict>
                        <key>mechanisms</key>
                        <array>
                        </array>
                </dict>
-               <key>system.login.pam</key>
-               <dict>
-                       <key>class</key>
-                       <string>evaluate-mechanisms</string>
-                       <key>tries</key>
-                       <integer>1</integer>
-                       <key>mechanisms</key>
-                       <array>
-                               <string>push_hints_to_context</string>
-                               <string>authinternal</string>
-                       </array>
-               </dict>
                <key>system.login.screensaver</key>
                <dict>
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
                <key>system.login.screensaver</key>
                <dict>
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
-                       <string>the owner as well as any admin can unlock the screensaver;modify the group key to change this.</string>
+                       <string>The owner or any administrator can unlock the screensaver.</string>
                        <key>rule</key>
                        <string>authenticate-session-owner-or-admin</string>
                </dict>
                        <key>rule</key>
                        <string>authenticate-session-owner-or-admin</string>
                </dict>
@@ -192,7 +173,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                        <key>comment</key>
-                       <string>Used by Security framework when you add an item to a unconfigured default keychain</string>
+                       <string>Used by the Security framework when you add an item to an unconfigured default keychain.</string>
                        <key>mechanisms</key>
                        <array>
                                <string>loginKC:queryCreate</string>
                        <key>mechanisms</key>
                        <array>
                                <string>loginKC:queryCreate</string>
@@ -224,7 +205,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>This right is checked by the Admin framework when making changes to the system preferences.</string>
+                       <string>Checked by the Admin framework when making changes to certain System Preferences.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -237,20 +218,22 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>This right is checked by the Admin framework when making changes to the accounts preference pane</string>
+                       <string>Checked by the Admin framework when making changes to the Accounts preference pane.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <false/>
                </dict>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <false/>
                </dict>
-               <key>system.printingmanager</key>
+               <key>system.preferences.parental-controls</key>
                <dict>
                        <key>class</key>
                <dict>
                        <key>class</key>
-                       <string>rule</string>
+                       <string>user</string>
                        <key>comment</key>
                        <key>comment</key>
-                       <string>The following right is checked for printing to locked printers.</string>
-                       <key>rule</key>
-                       <string>authenticate-admin</string>
+                       <string>Checked when making changes to the Parental Controls preference pane.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
                </dict>
                <key>system.preferences.accessibility</key>
                <dict>
                </dict>
                <key>system.preferences.accessibility</key>
                <dict>
@@ -259,7 +242,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>This right is checked by the Admin framework when enabling or disabling the Accessibility APIs</string>
+                       <string>Checked by the Admin framework when enabling or disabling the Accessibility APIs.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -267,12 +250,93 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>timeout</key>
                        <integer>0</integer>
                </dict>
                        <key>timeout</key>
                        <integer>0</integer>
                </dict>
+               <key>system.printingmanager</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>For printing to locked printers.</string>
+                       <key>rule</key>
+                       <string>authenticate-admin</string>
+               </dict>
+               <key>system.print.admin</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-lpadmin</string>
+                               <string>is-admin</string>
+                               <string>default</string>
+                       </array>
+               </dict>
+               <key>system.identity.write.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>For creating, changing or deleting local user accounts and groups.</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-admin</string>
+                               <string>authenticate-admin</string>
+                       </array>
+               </dict>
+               <key>system.identity.write.credential</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>comment</key>
+                       <string>Checked when changing authentication credentials (password or certificate) for a local user account.</string>
+                       <key>rule</key>
+                       <string>default</string>
+               </dict>
+               <key>system.identity.write.self</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when changing authentication credentials (password or certificate) for the current user's account.</string>
+                       <key>authenticate-user</key>
+                       <false/>
+                       <key>session-owner</key>
+                       <true/>
+               </dict>
+               <key>system.global-login-items.</key>
+               <dict>
+                       <key>class</key>
+                       <string>rule</string>
+                       <key>k-of-n</key>
+                       <integer>1</integer>
+                       <key>rule</key>
+                       <array>
+                               <string>is-admin</string>
+                               <string>default</string>
+                       </array>
+               </dict>
+               <key>system.sharepoints.</key>
+               <dict>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Checked when making changes to the Sharepoints.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
                <key>com.apple.activitymonitor.kill</key>
                <dict>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                <key>com.apple.activitymonitor.kill</key>
                <dict>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>Used by Activity Monitor to authorize killing processes not owned by the user</string>
+                       <string>Used by Activity Monitor to authorize killing processes not owned by the user.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -287,7 +351,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>This right is checked when changing parental controls for Safari</string>
+                       <string>Checked when changing parental controls for Safari.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -295,6 +359,17 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>timeout</key>
                        <integer>0</integer>
                </dict>
                        <key>timeout</key>
                        <integer>0</integer>
                </dict>
+               <key>com.apple.docset.install</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by Xcode to restrict access to a daemon it uses to install and update documentation sets.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+               </dict>
                <key>system.privilege.admin</key>
                <dict>
                        <key>allow-root</key>
                <key>system.privilege.admin</key>
                <dict>
                        <key>allow-root</key>
@@ -302,13 +377,9 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>Used by AuthorizationExecuteWithPrivileges(...)
-               AuthorizationExecuteWithPrivileges is used by programs requesting
-               to run a tool as root (ie. some installers).
-               Credentials remain valid 5 minutes after they've been obtained.
-               An acquired credential isn't shared with other clients.
-               Clients running as root will be granted this right automatically.
-                       </string>
+                       <string>Used by AuthorizationExecuteWithPrivileges(...).  
+               AuthorizationExecuteWithPrivileges() is used by programs requesting
+               to run a tool as root (e.g., some installers).</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -316,12 +387,29 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>timeout</key>
                        <integer>300</integer>
                </dict>
                        <key>timeout</key>
                        <integer>300</integer>
                </dict>
+               <key>system.privilege.taskport</key>
+               <dict>
+                       <key>allow-root</key>
+                       <false/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Used by task_for_pid(...).
+               Task_for_pid is called by programs requesting full control over another program
+               for things like debugging or performance analysis. This authorization only applies
+               if the requesting and target programs are run by the same user; it will never
+               authorize access to the program of another user.</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <true/>
+               </dict>
                <key>system.restart</key>
                <dict>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                        <key>comment</key>
                <key>system.restart</key>
                <dict>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                        <key>comment</key>
-                       <string>Multisession restart mechanisms</string>
+                       <string>Checked if the foreground console user tries to restart the system while other users are logged in via fast-user switching.</string>
                        <key>mechanisms</key>
                        <array>
                                <string>RestartAuthorization:restart</string>
                        <key>mechanisms</key>
                        <array>
                                <string>RestartAuthorization:restart</string>
@@ -334,7 +422,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                        <key>comment</key>
-                       <string>Multisession shutdown mechanisms</string>
+                       <string>Checked if the foreground console user tries to shut down the system while other users are logged in via fast-user switching.</string>
                        <key>mechanisms</key>
                        <array>
                                        <string>RestartAuthorization:shutdown</string>
                        <key>mechanisms</key>
                        <array>
                                        <string>RestartAuthorization:shutdown</string>
@@ -347,7 +435,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>allow</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>allow</string>
                        <key>comment</key>
-                       <string>authorization to burn media</string>
+                       <string>For burning media.</string>
                </dict>
                <key>system.services.directory.configure</key>
                <dict>
                </dict>
                <key>system.services.directory.configure</key>
                <dict>
@@ -362,14 +450,14 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>timeout</key>
                        <integer>300</integer>
                        <key>comment</key>
                        <key>timeout</key>
                        <integer>300</integer>
                        <key>comment</key>
-                       <string>authorization to make directory service changes</string>
+                       <string>For making Directory Services changes.</string>
                </dict>
                <key>com.apple.server.admin.streaming</key>
                <dict>
                        <key>class</key>
                        <string>user</string>   
                        <key>comment</key>
                </dict>
                <key>com.apple.server.admin.streaming</key>
                <dict>
                        <key>class</key>
                        <string>user</string>   
                        <key>comment</key>
-                       <string>Used for admin requests with the QuickTime Streaming Server.</string>
+                       <string>For making administrative requests to the QuickTime Streaming Server.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -379,12 +467,30 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>timeout</key>
                        <integer>0</integer>
                </dict>
                        <key>timeout</key>
                        <integer>0</integer>
                </dict>
+               <key>com.apple.trust-settings.admin</key>
+               <dict>
+                       <key>comment</key>
+                       <string>For modifying Trust Settings in the Local Admin domain.</string>
+                       <key>allow-root</key>
+                       <true/>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+               </dict>
+               <key>com.apple.trust-settings.user</key>
+               <dict>
+                       <key>rule</key>
+                       <string>authenticate-session-owner</string>
+                       <key>comment</key>
+                       <string>For modifying per-user Trust Settings.</string>
+               </dict>
                <key>system.install.admin.user</key>
                <dict>
                        <key>class</key>
                        <string>user</string>   
                        <key>comment</key>
                <key>system.install.admin.user</key>
                <dict>
                        <key>class</key>
                        <string>user</string>   
                        <key>comment</key>
-                       <string>Used by installer tool: user installling in admin domain (/Applications)</string>       
+                       <string>Checked when user is installing in admin domain (/Applications).</string>       
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -397,7 +503,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>   
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>   
                        <key>comment</key>
-                       <string>Used by installer tool: user installling in root domain (/System)</string>      
+                       <string>Checked when user is installing in root domain (/System).</string>      
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -410,7 +516,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>   
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>   
                        <key>comment</key>
-                       <string>Used by installer tool: admin installling in root domain (/System)</string>     
+                       <string>Checked when admin is installing in root domain (/System).</string>     
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -423,7 +529,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
-                       <string>Used to determine administrative access to the Application Server management tool.</string>
+                       <string>For administrative access to the Application Server management tool.</string>
                        <key>rule</key>
                        <string>appserver-admin</string>
                </dict>
                        <key>rule</key>
                        <string>appserver-admin</string>
                </dict>
@@ -432,7 +538,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>rule</string>
                        <key>comment</key>
-                       <string>Used to determine user access to the Application Server management tool.</string>
+                       <string>For user access to the Application Server management tool.</string>
                        <key>k-of-n</key>
                        <integer>1</integer>
                        <key>rule</key>
                        <key>k-of-n</key>
                        <integer>1</integer>
                        <key>rule</key>
@@ -441,12 +547,23 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                                <string>appserver-user</string>
                        </array>
                </dict>
                                <string>appserver-user</string>
                        </array>
                </dict>
+               <key>com.apple.dashboard.advisory.allow</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>group</key>
+                       <string>admin</string>
+                       <key>shared</key>
+                       <false/>
+                       <key>timeout</key>
+                       <integer>300</integer>
+               </dict>
                <key>com.apple.desktopservices</key>
                <dict>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                <key>com.apple.desktopservices</key>
                <dict>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>authorize privileged file operations from the finder</string>
+                       <string>For privileged file operations from within the Finder.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -476,6 +593,8 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                <dict>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
                <dict>
                        <key>class</key>
                        <string>evaluate-mechanisms</string>
+                       <key>tries</key>
+                       <integer>1</integer>
                        <key>mechanisms</key>
                        <array>
                                <string>builtin:confirm-access</string>
                        <key>mechanisms</key>
                        <array>
                                <string>builtin:confirm-access</string>
@@ -498,14 +617,14 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>allow</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>allow</string>
                        <key>comment</key>
-                       <string>allow anyone</string>
+                       <string>Allow anyone.</string>
                </dict>
                <key>authenticate-admin</key>
                <dict>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                </dict>
                <key>authenticate-admin</key>
                <dict>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>require the user asking for authorization to authenticate as an admin</string>
+                       <string>Authenticate as an administrator.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>shared</key>
@@ -513,21 +632,12 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>timeout</key>
                        <integer>0</integer>
                </dict>
                        <key>timeout</key>
                        <integer>0</integer>
                </dict>
-               <key>authenticate-session-user</key>
-               <dict>
-                       <key>class</key>
-                       <string>user</string>
-                       <key>comment</key>
-                       <string>authenticate session owner</string>
-                       <key>session-owner</key>
-                       <true/>
-               </dict>
                <key>authenticate-session-owner</key>
                <dict>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                <key>authenticate-session-owner</key>
                <dict>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>authenticate session owner</string>
+                       <string>Authenticate as the session owner.</string>
                        <key>session-owner</key>
                        <true/>
                </dict>
                        <key>session-owner</key>
                        <true/>
                </dict>
@@ -538,7 +648,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>the owner as well as any admin can authorize</string>
+                       <string>Authenticate either as the owner or as an administrator.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>session-owner</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>session-owner</key>
@@ -551,7 +661,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>verify the user asking for authorization is an admin</string>
+                       <string>Verify that the user asking for authorization is an administrator.</string>
                        <key>group</key>
                        <string>admin</string>
                        <key>authenticate-user</key>
                        <key>group</key>
                        <string>admin</string>
                        <key>authenticate-user</key>
@@ -559,6 +669,17 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>shared</key>
                        <string>true</string>
                </dict>
                        <key>shared</key>
                        <string>true</string>
                </dict>
+               <key>is-lpadmin</key>
+               <dict>
+                       <key>class</key>
+                       <string>user</string>
+                       <key>comment</key>
+                       <string>Verify that the user asking for authorization is an lp administrator.</string>
+                       <key>group</key>
+                       <string>lpadmin</string>
+                       <key>authenticate-user</key>
+                       <false/>
+               </dict>
                <key>is-root</key>
                <dict>
                        <key>allow-root</key>
                <key>is-root</key>
                <dict>
                        <key>allow-root</key>
@@ -568,7 +689,7 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>authenticate-user</key>
                        <false/>
                        <key>comment</key>
                        <key>authenticate-user</key>
                        <false/>
                        <key>comment</key>
-                       <string>verify the process that created this authref is root</string>
+                       <string>Verify that the process that created this AuthorizationRef is running as root.</string>
                </dict>
                <key>appserver-user</key>
                <dict>
                </dict>
                <key>appserver-user</key>
                <dict>
@@ -589,8 +710,9 @@ builtin:krb5authnoverify skips the kdc verification.  Both fall back on local au
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
                        <key>class</key>
                        <string>user</string>
                        <key>comment</key>
-                       <string>All other rights will be matched by this rule.  Credentials remain valid 5 minutes after they've been obtained.
-An acquired credential is shared amongst all clients.
+                       <string>Default rule.   
+            Credentials remain valid for 5 minutes after they've been obtained. 
+            An acquired credential is shared by all clients.
                        </string>
                        <key>group</key>
                        <string>admin</string>
                        </string>
                        <key>group</key>
                        <string>admin</string>
@@ -605,8 +727,9 @@ An acquired credential is shared amongst all clients.
                        <string>evaluate-mechanisms</string>
                        <key>mechanisms</key>
                        <array>
                        <string>evaluate-mechanisms</string>
                        <key>mechanisms</key>
                        <array>
+                               <string>builtin:smartcard-sniffer,privileged</string>
                                <string>builtin:authenticate</string>
                                <string>builtin:authenticate</string>
-                               <string>authinternal</string>
+                               <string>builtin:authenticate,privileged</string>
                        </array>
                </dict>
        </dict>
                        </array>
                </dict>
        </dict>
diff --git a/etc/com.apple.securityd.plist b/etc/com.apple.securityd.plist
new file mode 100644 (file)
index 0000000..d9f2292
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>Label</key>
+       <string>com.apple.SecurityServer</string>
+       <key>ProgramArguments</key>
+       <array>
+               <string>/usr/sbin/securityd</string>
+               <string>-i</string>
+       </array>
+       <key>MachServices</key>
+       <dict>
+               <key>com.apple.SecurityServer</key>
+               <dict>
+                       <key>ResetAtClose</key>
+                       <true/>
+               </dict>
+       </dict>
+       <key>RunAtLoad</key>
+       <true/>
+       <key>LaunchOnlyOnce</key>
+       <true/>
+</dict>
+</plist>
diff --git a/etc/securityd-installCD.plist b/etc/securityd-installCD.plist
deleted file mode 100644 (file)
index ce87d8d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-        <key>ServiceName</key>
-        <string>com.apple.securityd</string>
-        <key>Command</key>
-        <string>/usr/sbin/securityd -c /var/tmp/tokencache -s off</string>
-        <key>OnDemand</key>
-        <false/>
-</dict>
-</plist>
diff --git a/etc/securityd.plist b/etc/securityd.plist
deleted file mode 100644 (file)
index 82d83c3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-        <key>ServiceName</key>
-        <string>com.apple.securityd</string>
-        <key>Command</key>
-        <string>/usr/sbin/securityd</string>
-        <key>OnDemand</key>
-        <false/>
-</dict>
-</plist>
index f3912c30f749ccb3aae80d01616bf2e0231e1f2a..04c77e04e723fb9286f18ac8af9ae8c184b76870 100644 (file)
@@ -8,12 +8,12 @@
 SYSTEM_LIBRARY_DIR=$(DSTROOT)/System/Library
 SYSTEM_CORE_SERVICES_DIR=/System/Library/CoreServices
 ETC_DIR=$(DSTROOT)/private/etc
 SYSTEM_LIBRARY_DIR=$(DSTROOT)/System/Library
 SYSTEM_CORE_SERVICES_DIR=/System/Library/CoreServices
 ETC_DIR=$(DSTROOT)/private/etc
+LAUNCH_DIR=$(DSTROOT)/System/Library/LaunchDaemons
 AUTHORIZATION_LOCATION=$(ETC_DIR)
 AUTHORIZATION_PLIST=$(AUTHORIZATION_LOCATION)/authorization
 VARDB=$(DSTROOT)/private/var/db
 CANDIDATES=$(VARDB)/CodeEquivalenceCandidates
 
 AUTHORIZATION_LOCATION=$(ETC_DIR)
 AUTHORIZATION_PLIST=$(AUTHORIZATION_LOCATION)/authorization
 VARDB=$(DSTROOT)/private/var/db
 CANDIDATES=$(VARDB)/CodeEquivalenceCandidates
 
-DST=$(ETC_DIR)/mach_init.d
 SRC=$(SRCROOT)/etc
 
 
 SRC=$(SRCROOT)/etc
 
 
@@ -33,8 +33,8 @@ profile:
 # Install
 #
 install:
 # Install
 #
 install:
-       mkdir -p $(DST)
-       cp $(SRC)/securityd.plist $(SRC)/securityd-installCD.plist $(DST)
+       mkdir -p $(LAUNCH_DIR)
+       cp $(SRC)/com.apple.securityd.plist $(LAUNCH_DIR)
        mkdir -p $(AUTHORIZATION_LOCATION)
        cp $(SRC)/authorization.plist $(AUTHORIZATION_PLIST)
        chown root:wheel $(AUTHORIZATION_PLIST)
        mkdir -p $(AUTHORIZATION_LOCATION)
        cp $(SRC)/authorization.plist $(AUTHORIZATION_PLIST)
        chown root:wheel $(AUTHORIZATION_PLIST)
diff --git a/securityd.xcode/project.pbxproj b/securityd.xcode/project.pbxproj
deleted file mode 100644 (file)
index 52f503b..0000000
+++ /dev/null
@@ -1,1942 +0,0 @@
-// !$*UTF8*$!
-{
-       archiveVersion = 1;
-       classes = {
-       };
-       objectVersion = 39;
-       objects = {
-               405845650663B2010083E58C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = AuthorizationMechEval.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               405845660663B2010083E58C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = AuthorizationMechEval.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               405845670663B2010083E58C = {
-                       fileRef = 405845650663B2010083E58C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               405845680663B2010083E58C = {
-                       fileRef = 405845660663B2010083E58C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               40689F840725DCE00021A502 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = authhost.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               40689F850725DCE00021A502 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = authhost.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               40689F860725DCE00021A502 = {
-                       fileRef = 40689F840725DCE00021A502;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               40689F870725DCE00021A502 = {
-                       fileRef = 40689F850725DCE00021A502;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-//400
-//401
-//402
-//403
-//404
-//4C0
-//4C1
-//4C2
-//4C3
-//4C4
-               4C01B3D706FFC621004B3A01 = {
-                       buildActionMask = 8;
-                       dstPath = /usr/share/man/man1/;
-                       dstSubfolderSpec = 0;
-                       files = (
-                               4C01B3DA06FFC640004B3A01,
-                       );
-                       isa = PBXCopyFilesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 1;
-               };
-               4C01B3DA06FFC640004B3A01 = {
-                       fileRef = 4CE1878706FFC5D60079D235;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264970534866F004B0E72 = {
-                       children = (
-                               4C9264B70534866F004B0E72,
-                               C28AE81406CD7DA100BE0061,
-                               C2C8B29806F8A60F000EBDA2,
-                               C28AE81706CD7DC500BE0061,
-                               C28AE81A06CD7DE200BE0061,
-                               C28AE82306CD7E0F00BE0061,
-                               C28AE82606CD7E4700BE0061,
-                               C28AE81106CD7D7800BE0061,
-                               C28AE83906CD7EE900BE0061,
-                       );
-                       isa = PBXGroup;
-                       path = src;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264980534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = acl_keychain.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264990534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = acl_keychain.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C92649A0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = acls.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C92649B0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = acls.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C92649C0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = agentquery.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C92649D0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = agentquery.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C92649E0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = authority.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C92649F0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = authority.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264A00534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = AuthorizationDBPlist.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264A10534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = AuthorizationDBPlist.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264A20534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = AuthorizationEngine.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264A30534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = AuthorizationEngine.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264A40534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = AuthorizationRule.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264A50534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = AuthorizationRule.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264A80534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = codesigdb.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264A90534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = codesigdb.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264AA0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = connection.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264AB0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = connection.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264AC0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = dbcrypto.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264AD0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = dbcrypto.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264AE0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = entropy.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264AF0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = entropy.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B00534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = flippers.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B10534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = flippers.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B20534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = generate.cf;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B30534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = generate.mk;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B40534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.script.perl;
-                       path = generate.pl;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B50534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = key.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B60534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = key.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B70534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = main.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B80534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = notifications.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264B90534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = notifications.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264BA0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = process.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264BB0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = process.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264BC0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = securityd.order;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264BE0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = server.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264BF0534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = server.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264C00534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = session.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264C10534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = session.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264C20534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = transition.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264C30534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = transwalkers.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264C40534866F004B0E72 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = transwalkers.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4C9264C80534866F004B0E72 = {
-                       fileRef = 4C9264980534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264C90534866F004B0E72 = {
-                       fileRef = 4C9264990534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264CA0534866F004B0E72 = {
-                       fileRef = 4C92649A0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264CB0534866F004B0E72 = {
-                       fileRef = 4C92649B0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264CC0534866F004B0E72 = {
-                       fileRef = 4C92649C0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264CD0534866F004B0E72 = {
-                       fileRef = 4C92649D0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264CE0534866F004B0E72 = {
-                       fileRef = 4C92649E0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264CF0534866F004B0E72 = {
-                       fileRef = 4C92649F0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264D00534866F004B0E72 = {
-                       fileRef = 4C9264A00534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264D10534866F004B0E72 = {
-                       fileRef = 4C9264A10534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264D20534866F004B0E72 = {
-                       fileRef = 4C9264A20534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264D30534866F004B0E72 = {
-                       fileRef = 4C9264A30534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264D40534866F004B0E72 = {
-                       fileRef = 4C9264A40534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264D50534866F004B0E72 = {
-                       fileRef = 4C9264A50534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264D80534866F004B0E72 = {
-                       fileRef = 4C9264A80534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264D90534866F004B0E72 = {
-                       fileRef = 4C9264A90534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264DA0534866F004B0E72 = {
-                       fileRef = 4C9264AA0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264DB0534866F004B0E72 = {
-                       fileRef = 4C9264AB0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264DC0534866F004B0E72 = {
-                       fileRef = 4C9264AC0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264DD0534866F004B0E72 = {
-                       fileRef = 4C9264AD0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264DE0534866F004B0E72 = {
-                       fileRef = 4C9264AE0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264DF0534866F004B0E72 = {
-                       fileRef = 4C9264AF0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264E00534866F004B0E72 = {
-                       fileRef = 4C9264B00534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264E10534866F004B0E72 = {
-                       fileRef = 4C9264B10534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264E20534866F004B0E72 = {
-                       fileRef = 4C9264B50534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264E30534866F004B0E72 = {
-                       fileRef = 4C9264B60534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264E40534866F004B0E72 = {
-                       fileRef = 4C9264B70534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264E50534866F004B0E72 = {
-                       fileRef = 4C9264B80534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264E60534866F004B0E72 = {
-                       fileRef = 4C9264B90534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264E70534866F004B0E72 = {
-                       fileRef = 4C9264BA0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264E80534866F004B0E72 = {
-                       fileRef = 4C9264BB0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264EA0534866F004B0E72 = {
-                       fileRef = 4C9264BE0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264EB0534866F004B0E72 = {
-                       fileRef = 4C9264BF0534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264EC0534866F004B0E72 = {
-                       fileRef = 4C9264C00534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264ED0534866F004B0E72 = {
-                       fileRef = 4C9264C10534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264EE0534866F004B0E72 = {
-                       fileRef = 4C9264C20534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264EF0534866F004B0E72 = {
-                       fileRef = 4C9264C30534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4C9264F00534866F004B0E72 = {
-                       fileRef = 4C9264C40534866F004B0E72;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4CA1FEAC052A3C5800F22E42 = {
-                       children = (
-                               4C9264970534866F004B0E72,
-                               C209B39106ADBB19007B9E6D,
-                               4CE1878506FFC5D60079D235,
-                               C209B39406ADBB2B007B9E6D,
-                               C28AE82006CD7DF500BE0061,
-                               4CDD50150537658500FEC36D,
-                               4CA1FEB7052A3C6D00F22E42,
-                               4CD8CCBB055884E0006B3584,
-                       );
-                       isa = PBXGroup;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CA1FEAE052A3C5800F22E42 = {
-                       buildSettings = {
-                               BUILD_VARIANTS = debug;
-                               COPY_PHASE_STRIP = NO;
-                               GCC_DYNAMIC_NO_PIC = NO;
-                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-                               GCC_OPTIMIZATION_LEVEL = 0;
-                               ZERO_LINK = YES;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Development;
-               };
-               4CA1FEAF052A3C5800F22E42 = {
-                       buildSettings = {
-                               DEAD_CODE_STRIPPING = YES;
-                               GCC_DYNAMIC_NO_PIC = NO;
-                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-                               ZERO_LINK = NO;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Deployment;
-               };
-               4CA1FEB0052A3C5800F22E42 = {
-                       buildSettings = {
-                       };
-                       buildStyles = (
-                               4CA1FEAE052A3C5800F22E42,
-                               4CA1FEAF052A3C5800F22E42,
-                               C265A4DB06F12750000E5CFC,
-                       );
-                       hasScannedForEncodings = 1;
-                       isa = PBXProject;
-                       mainGroup = 4CA1FEAC052A3C5800F22E42;
-                       productRefGroup = 4CA1FEB7052A3C6D00F22E42;
-                       projectDirPath = "";
-                       targets = (
-                               4CA1FEB5052A3C6D00F22E42,
-                               4CDD4F7A053751FF00FEC36D,
-                               4CA4EB2C0558848900CF7791,
-                               C209B3A506ADBCAC007B9E6D,
-                       );
-               };
-               4CA1FEB1052A3C6D00F22E42 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               4C9264C90534866F004B0E72,
-                               4C9264CB0534866F004B0E72,
-                               4C9264CD0534866F004B0E72,
-                               4C9264CF0534866F004B0E72,
-                               4C9264D10534866F004B0E72,
-                               4C9264D30534866F004B0E72,
-                               405845680663B2010083E58C,
-                               4C9264D50534866F004B0E72,
-                               4CB5ACBC06680AE000F359A9,
-                               4C9264D90534866F004B0E72,
-                               4C9264DB0534866F004B0E72,
-                               C2B8DBCC05E6C3CE00E6E67C,
-                               4C9264DD0534866F004B0E72,
-                               4C9264DF0534866F004B0E72,
-                               4C9264E10534866F004B0E72,
-                               C2B8DBCE05E6C3CE00E6E67C,
-                               C207646605EAD713004FEEDA,
-                               4C9264E30534866F004B0E72,
-                               C20764E905ED250F004FEEDA,
-                               C20764EB05ED250F004FEEDA,
-                               4C9264E60534866F004B0E72,
-                               C2FDCAC60663CD5B0013F64C,
-                               4C9264E80534866F004B0E72,
-                               C2FDCAC80663CD5B0013F64C,
-                               4C9264EB0534866F004B0E72,
-                               4C9264ED0534866F004B0E72,
-                               C28ACF9D05C9940B00447176,
-                               C20AF37F05F689540055732C,
-                               C2FDCACA0663CD5B0013F64C,
-                               C2D425F405F3C07400CB11F8,
-                               4C9264F00534866F004B0E72,
-                               C26EA9540688CF34007CE21D,
-                               C209B3B506ADBE64007B9E6D,
-                               C22A7F8F06AF06D9006087B7,
-                               C26D533A06C1E70A00062E1E,
-                               C28654B306DBC2A30021E6E5,
-                               C2813C820730534A00E243E8,
-                               40689F860725DCE00021A502,
-                       );
-                       isa = PBXHeadersBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               4CA1FEB2052A3C6D00F22E42 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               4C9264C80534866F004B0E72,
-                               4C9264CA0534866F004B0E72,
-                               4C9264CC0534866F004B0E72,
-                               4C9264CE0534866F004B0E72,
-                               4C9264D00534866F004B0E72,
-                               4C9264D20534866F004B0E72,
-                               405845670663B2010083E58C,
-                               4C9264D40534866F004B0E72,
-                               4CB5ACBB06680AE000F359A9,
-                               4C9264D80534866F004B0E72,
-                               4C9264DA0534866F004B0E72,
-                               C2B8DBCB05E6C3CE00E6E67C,
-                               4C9264DC0534866F004B0E72,
-                               4C9264DE0534866F004B0E72,
-                               4C9264E00534866F004B0E72,
-                               C2B8DBCD05E6C3CE00E6E67C,
-                               C207646505EAD713004FEEDA,
-                               4C9264E20534866F004B0E72,
-                               C20764E805ED250F004FEEDA,
-                               C20764EA05ED250F004FEEDA,
-                               4C9264E40534866F004B0E72,
-                               4C9264E50534866F004B0E72,
-                               C2FDCAC50663CD5B0013F64C,
-                               4C9264E70534866F004B0E72,
-                               C2FDCAC70663CD5B0013F64C,
-                               4C9264EA0534866F004B0E72,
-                               4C9264EC0534866F004B0E72,
-                               C28ACF9C05C9940B00447176,
-                               C20AF37E05F689540055732C,
-                               C2FDCAC90663CD5B0013F64C,
-                               C2D425F305F3C07400CB11F8,
-                               4C9264EE0534866F004B0E72,
-                               4C9264EF0534866F004B0E72,
-                               C26EA9530688CF34007CE21D,
-                               C209B3B606ADBE64007B9E6D,
-                               C209B3B706ADBE64007B9E6D,
-                               C22A7F8E06AF06D9006087B7,
-                               C26D533906C1E70A00062E1E,
-                               C28654B206DBC2A30021E6E5,
-                               C2813C810730534A00E243E8,
-                               40689F870725DCE00021A502,
-                       );
-                       isa = PBXSourcesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               4CA1FEB3052A3C6D00F22E42 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       isa = PBXFrameworksBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               4CA1FEB5052A3C6D00F22E42 = {
-                       buildPhases = (
-                               4CA1FEB1052A3C6D00F22E42,
-                               4CA1FEB2052A3C6D00F22E42,
-                               4CA1FEB3052A3C6D00F22E42,
-                               4C01B3D706FFC621004B3A01,
-                       );
-                       buildSettings = {
-                               BUILD_VARIANTS = "normal debug";
-                               CURRENT_PROJECT_VERSION = 1;
-                               FRAMEWORK_SEARCH_PATHS = "/usr/local/SecurityPieces/Frameworks /usr/local/SecurityPieces/Components/securityd $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
-                               INSTALL_PATH = /usr/sbin;
-                               OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
-                               OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)";
-                               OPT_INLINEXFLAGS = "-finline-functions";
-                               OPT_LDXFLAGS = "-dead_strip";
-                               OPT_LDXNOPIC = ",_nopic";
-                               OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
-                               OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
-                               OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
-                               OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O1 -fno-inline";
-                               OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)";
-                               OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
-                               OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
-                               OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)";
-                               OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
-                               OTHER_LDFLAGS = "-lbsm";
-                               OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)  \"-framework\" \"Security,_debug\" \"-framework\" \"PCSC,_debug\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_debug\" \"-framework\" \"security_tokend_client,_debug\" \"-framework\" \"security_cdsa_client,_debug\" \"-framework\" \"securityd_server,_debug\" \"-framework\" \"securityd_client,_debug\" \"-framework\" \"security_cdsa_utilities,_debug\" \"-framework\" \"security_utilities,_debug\"";
-                               OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS)  \"-framework\" \"Security\" \"-framework\" \"PCSC\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_tokend_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_client$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_server$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_utilities$(OPT_LDXNOPIC)\" \"-framework\" \"security_utilities$(OPT_LDXNOPIC)\"";
-                               OTHER_LDFLAGS_profile = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -pg \"-framework\" \"Security,_profile\"  \"-framework\" \"PCSC,_profile\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_profile\" \"-framework\" \"security_tokend_client,_profile\" \"-framework\" \"security_cdsa_client,_profile\" \"-framework\" \"securityd_server,_profile\" \"-framework\" \"securityd_client,_profile\" \"-framework\" \"security_cdsa_utilities,_profile\" \"-framework\" \"security_utilities,_profile\"";
-                               PRODUCT_NAME = securityd;
-                               SECTORDER_FLAGS = "-sectorder __TEXT __text src/securityd.order -e start";
-                               VERSIONING_SYSTEM = "apple-generic";
-                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
-                       };
-                       dependencies = (
-                               C209B3AA06ADBD6D007B9E6D,
-                               4CDD4FB80537552600FEC36D,
-                               4CD8CCB6055884BD006B3584,
-                       );
-                       isa = PBXToolTarget;
-                       name = securityd;
-                       productInstallPath = /usr/sbin;
-                       productName = securityd;
-                       productReference = 4CA1FEB6052A3C6D00F22E42;
-               };
-               4CA1FEB6052A3C6D00F22E42 = {
-                       explicitFileType = "compiled.mach-o.executable";
-                       isa = PBXFileReference;
-                       path = securityd;
-                       refType = 3;
-                       sourceTree = BUILT_PRODUCTS_DIR;
-               };
-               4CA1FEB7052A3C6D00F22E42 = {
-                       children = (
-                               4CA1FEB6052A3C6D00F22E42,
-                               C2904F9606D116A3005FF97E,
-                       );
-                       isa = PBXGroup;
-                       name = Products;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CA4EB2C0558848900CF7791 = {
-                       buildArgumentsString = "-f $(SRCROOT)/etc/startup.mk $(ACTION)";
-                       buildPhases = (
-                       );
-                       buildSettings = {
-                               OTHER_CFLAGS = "";
-                               OTHER_LDFLAGS = "";
-                               OTHER_REZFLAGS = "";
-                               PRODUCT_NAME = startup;
-                               SECTORDER_FLAGS = "";
-                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
-                       };
-                       buildToolPath = /usr/bin/gnumake;
-                       buildWorkingDirectory = "";
-                       dependencies = (
-                       );
-                       isa = PBXLegacyTarget;
-                       name = startup;
-                       passBuildSettingsInEnvironment = 1;
-                       productName = startup;
-               };
-               4CB5ACB906680AE000F359A9 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = child.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CB5ACBA06680AE000F359A9 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = child.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CB5ACBB06680AE000F359A9 = {
-                       fileRef = 4CB5ACB906680AE000F359A9;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4CB5ACBC06680AE000F359A9 = {
-                       fileRef = 4CB5ACBA06680AE000F359A9;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               4CD8CCB5055884BD006B3584 = {
-                       containerPortal = 4CA1FEB0052A3C5800F22E42;
-                       isa = PBXContainerItemProxy;
-                       proxyType = 1;
-                       remoteGlobalIDString = 4CA4EB2C0558848900CF7791;
-                       remoteInfo = startup;
-               };
-               4CD8CCB6055884BD006B3584 = {
-                       isa = PBXTargetDependency;
-                       target = 4CA4EB2C0558848900CF7791;
-                       targetProxy = 4CD8CCB5055884BD006B3584;
-               };
-               4CD8CCBB055884E0006B3584 = {
-                       children = (
-                               4CD8CCBC055884E0006B3584,
-                               4CD8CCBD055884E0006B3584,
-                               C2A7B20F079F3A90000DB673,
-                               C2A7B20E079F3A90000DB673,
-                               4CD8CCC0055884E0006B3584,
-                       );
-                       isa = PBXGroup;
-                       name = "Other Installs";
-                       path = etc;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CD8CCBC055884E0006B3584 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.plist;
-                       path = authorization.plist;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CD8CCBD055884E0006B3584 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = CodeEquivalenceCandidates;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CD8CCC0055884E0006B3584 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = startup.mk;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CDD4F79053751FF00FEC36D = {
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       inputPaths = (
-                       );
-                       isa = PBXShellScriptBuildPhase;
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-                       shellPath = /bin/sh;
-                       shellScript = "THEADER=$BUILT_PRODUCTS_DIR/include/flip_gen.h\nTCPP=$BUILT_PRODUCTS_DIR/include/flip_gen.cpp\nmkdir -p $BUILT_PRODUCTS_DIR/include\nsrc/generate.pl src/generate.cf $THEADER.new $TCPP.new cssmtype.h $CSSM_HEADERS\ncmp -s $THEADER.new $THEADER || mv $THEADER.new $THEADER\ncmp -s $TCPP.new $TCPP || mv $TCPP.new $TCPP\n";
-               };
-               4CDD4F7A053751FF00FEC36D = {
-                       buildPhases = (
-                               4CDD4F79053751FF00FEC36D,
-                       );
-                       buildSettings = {
-                               CSSM_HEADERS = "$(BUILT_PRODUCTS_DIR)/Security.framework/Headers:$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Headers";
-                               OTHER_CFLAGS = "";
-                               OTHER_LDFLAGS = "";
-                               OTHER_REZFLAGS = "";
-                               PRODUCT_NAME = flippers;
-                               REZ_EXECUTABLE = YES;
-                               SECTORDER_FLAGS = "";
-                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
-                       };
-                       dependencies = (
-                       );
-                       isa = PBXToolTarget;
-                       name = flippers;
-                       productInstallPath = /usr/local/bin;
-                       productName = flippers;
-                       productReference = C2904F9606D116A3005FF97E;
-               };
-               4CDD4FB70537552600FEC36D = {
-                       containerPortal = 4CA1FEB0052A3C5800F22E42;
-                       isa = PBXContainerItemProxy;
-                       proxyType = 1;
-                       remoteGlobalIDString = 4CDD4F7A053751FF00FEC36D;
-                       remoteInfo = flippers;
-               };
-               4CDD4FB80537552600FEC36D = {
-                       isa = PBXTargetDependency;
-                       target = 4CDD4F7A053751FF00FEC36D;
-                       targetProxy = 4CDD4FB70537552600FEC36D;
-               };
-               4CDD50150537658500FEC36D = {
-                       children = (
-                               4CDD5018053765A900FEC36D,
-                               4CDD506B0537666500FEC36D,
-                               C276AAD60663E7A400B57276,
-                               4CDD5019053765A900FEC36D,
-                       );
-                       isa = PBXGroup;
-                       name = "Linked Frameworks";
-                       path = src;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CDD5018053765A900FEC36D = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = CoreFoundation.framework;
-                       path = /System/Library/Frameworks/CoreFoundation.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               4CDD5019053765A900FEC36D = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = Security.framework;
-                       path = /System/Library/Frameworks/Security.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               4CDD506B0537666500FEC36D = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = IOKit.framework;
-                       path = /System/Library/Frameworks/IOKit.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               4CE1878506FFC5D60079D235 = {
-                       children = (
-                               4CE1878606FFC5D60079D235,
-                               4CE1878706FFC5D60079D235,
-                       );
-                       isa = PBXGroup;
-                       path = doc;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CE1878606FFC5D60079D235 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = BLOBFORMAT;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               4CE1878706FFC5D60079D235 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.man;
-                       path = securityd.1;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//4C0
-//4C1
-//4C2
-//4C3
-//4C4
-//C20
-//C21
-//C22
-//C23
-//C24
-               C207646305EAD713004FEEDA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = kckey.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C207646405EAD713004FEEDA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = kckey.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C207646505EAD713004FEEDA = {
-                       fileRef = C207646305EAD713004FEEDA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C207646605EAD713004FEEDA = {
-                       fileRef = C207646405EAD713004FEEDA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C20764E405ED250F004FEEDA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = localdatabase.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C20764E505ED250F004FEEDA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = localdatabase.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C20764E605ED250F004FEEDA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = localkey.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C20764E705ED250F004FEEDA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = localkey.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C20764E805ED250F004FEEDA = {
-                       fileRef = C20764E405ED250F004FEEDA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C20764E905ED250F004FEEDA = {
-                       fileRef = C20764E505ED250F004FEEDA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C20764EA05ED250F004FEEDA = {
-                       fileRef = C20764E605ED250F004FEEDA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C20764EB05ED250F004FEEDA = {
-                       fileRef = C20764E705ED250F004FEEDA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C209B39106ADBB19007B9E6D = {
-                       children = (
-                               C209B3AD06ADBDB4007B9E6D,
-                               C209B3AE06ADBDB4007B9E6D,
-                       );
-                       isa = PBXGroup;
-                       path = mig;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C209B39406ADBB2B007B9E6D = {
-                       children = (
-                               C209B3B206ADBE64007B9E6D,
-                               C209B3B306ADBE64007B9E6D,
-                               C209B3B406ADBE64007B9E6D,
-                       );
-                       isa = PBXGroup;
-                       path = derived_src;
-                       refType = 3;
-                       sourceTree = BUILT_PRODUCTS_DIR;
-               };
-               C209B3A406ADBCAC007B9E6D = {
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       inputPaths = (
-                       );
-                       isa = PBXShellScriptBuildPhase;
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-                       shellPath = /bin/bash;
-                       shellScript = "make -f mig/mig.mk\n";
-               };
-               C209B3A506ADBCAC007B9E6D = {
-                       buildPhases = (
-                               C209B3A406ADBCAC007B9E6D,
-                       );
-                       buildSettings = {
-                               OTHER_CFLAGS = "";
-                               OTHER_LDFLAGS = "";
-                               OTHER_REZFLAGS = "";
-                               PRODUCT_NAME = generate;
-                               SECTORDER_FLAGS = "";
-                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
-                       };
-                       dependencies = (
-                       );
-                       isa = PBXAggregateTarget;
-                       name = mig;
-                       productName = generate;
-               };
-               C209B3A906ADBD6D007B9E6D = {
-                       containerPortal = 4CA1FEB0052A3C5800F22E42;
-                       isa = PBXContainerItemProxy;
-                       proxyType = 1;
-                       remoteGlobalIDString = C209B3A506ADBCAC007B9E6D;
-                       remoteInfo = mig;
-               };
-               C209B3AA06ADBD6D007B9E6D = {
-                       isa = PBXTargetDependency;
-                       target = C209B3A506ADBCAC007B9E6D;
-                       targetProxy = C209B3A906ADBD6D007B9E6D;
-               };
-               C209B3AD06ADBDB4007B9E6D = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = mig.mk;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C209B3AE06ADBDB4007B9E6D = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.mig;
-                       path = self.defs;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C209B3B206ADBE64007B9E6D = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = self.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C209B3B306ADBE64007B9E6D = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = selfServer.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C209B3B406ADBE64007B9E6D = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = selfUser.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C209B3B506ADBE64007B9E6D = {
-                       fileRef = C209B3B206ADBE64007B9E6D;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C209B3B606ADBE64007B9E6D = {
-                       fileRef = C209B3B306ADBE64007B9E6D;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C209B3B706ADBE64007B9E6D = {
-                       fileRef = C209B3B406ADBE64007B9E6D;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C20AF37C05F689540055732C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = tempdatabase.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C20AF37D05F689540055732C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = tempdatabase.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C20AF37E05F689540055732C = {
-                       fileRef = C20AF37C05F689540055732C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C20AF37F05F689540055732C = {
-                       fileRef = C20AF37D05F689540055732C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C22A7F8C06AF06D9006087B7 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = tokend.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C22A7F8D06AF06D9006087B7 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = tokend.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C22A7F8E06AF06D9006087B7 = {
-                       fileRef = C22A7F8C06AF06D9006087B7;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C22A7F8F06AF06D9006087B7 = {
-                       fileRef = C22A7F8D06AF06D9006087B7;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C265A4DB06F12750000E5CFC = {
-                       buildSettings = {
-                               BUILD_VARIANTS = normal;
-                               COPY_PHASE_STRIP = NO;
-                               OPT_LDFLAGS = "";
-                               OPT_LDXFLAGS = "";
-                               OPT_LDXNOPIC = "";
-                               OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O1 -fno-inline";
-                               OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
-                       };
-                       isa = PBXBuildStyle;
-                       name = "normal with debug";
-               };
-               C26D533706C1E70A00062E1E = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = tokenkey.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C26D533806C1E70A00062E1E = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = tokenkey.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C26D533906C1E70A00062E1E = {
-                       fileRef = C26D533706C1E70A00062E1E;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C26D533A06C1E70A00062E1E = {
-                       fileRef = C26D533806C1E70A00062E1E;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C26EA9510688CF34007CE21D = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = tokencache.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C26EA9520688CF34007CE21D = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = tokencache.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C26EA9530688CF34007CE21D = {
-                       fileRef = C26EA9510688CF34007CE21D;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C26EA9540688CF34007CE21D = {
-                       fileRef = C26EA9520688CF34007CE21D;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C276AAD60663E7A400B57276 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = PCSC.framework;
-                       path = /System/Library/Frameworks/PCSC.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               C2813C7F0730534A00E243E8 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = tokenaccess.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2813C800730534A00E243E8 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = tokenaccess.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2813C810730534A00E243E8 = {
-                       fileRef = C2813C7F0730534A00E243E8;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2813C820730534A00E243E8 = {
-                       fileRef = C2813C800730534A00E243E8;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C28654B006DBC2A30021E6E5 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = tokenacl.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28654B106DBC2A30021E6E5 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = tokenacl.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28654B206DBC2A30021E6E5 = {
-                       fileRef = C28654B006DBC2A30021E6E5;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C28654B306DBC2A30021E6E5 = {
-                       fileRef = C28654B106DBC2A30021E6E5;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C28ACF9A05C9940B00447176 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = structure.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28ACF9B05C9940B00447176 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = structure.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28ACF9C05C9940B00447176 = {
-                       fileRef = C28ACF9A05C9940B00447176;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C28ACF9D05C9940B00447176 = {
-                       fileRef = C28ACF9B05C9940B00447176;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C28AE7FE06CD7CFF00BE0061 = {
-                       children = (
-                               C2D425F205F3C07400CB11F8,
-                               C2D425F105F3C07400CB11F8,
-                               C26D533806C1E70A00062E1E,
-                               C26D533706C1E70A00062E1E,
-                               C2813C800730534A00E243E8,
-                               C2813C7F0730534A00E243E8,
-                       );
-                       isa = PBXGroup;
-                       name = Token;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE80106CD7D0E00BE0061 = {
-                       children = (
-                               C20AF37D05F689540055732C,
-                               C20AF37C05F689540055732C,
-                       );
-                       isa = PBXGroup;
-                       name = Temporary;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE80406CD7D1D00BE0061 = {
-                       children = (
-                               C20764E505ED250F004FEEDA,
-                               C20764E405ED250F004FEEDA,
-                               C20764E705ED250F004FEEDA,
-                               C20764E605ED250F004FEEDA,
-                       );
-                       isa = PBXGroup;
-                       name = Local;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE80706CD7D2700BE0061 = {
-                       children = (
-                               C2B8DBCA05E6C3CE00E6E67C,
-                               C2B8DBC905E6C3CE00E6E67C,
-                               C207646405EAD713004FEEDA,
-                               C207646305EAD713004FEEDA,
-                       );
-                       isa = PBXGroup;
-                       name = Keychain;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE80A06CD7D3000BE0061 = {
-                       children = (
-                               4C9264B40534866F004B0E72,
-                               4C9264B20534866F004B0E72,
-                               4C9264B30534866F004B0E72,
-                       );
-                       isa = PBXGroup;
-                       name = Generate;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE80E06CD7D5300BE0061 = {
-                       children = (
-                               4C9264B10534866F004B0E72,
-                               4C9264B00534866F004B0E72,
-                               C28AE80A06CD7D3000BE0061,
-                       );
-                       isa = PBXGroup;
-                       name = Flippers;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE81106CD7D7800BE0061 = {
-                       children = (
-                               40689F840725DCE00021A502,
-                               40689F850725DCE00021A502,
-                               4C92649F0534866F004B0E72,
-                               4C92649E0534866F004B0E72,
-                               4C9264A10534866F004B0E72,
-                               4C9264A00534866F004B0E72,
-                               4C9264A30534866F004B0E72,
-                               4C9264A20534866F004B0E72,
-                               405845660663B2010083E58C,
-                               405845650663B2010083E58C,
-                               4C9264A50534866F004B0E72,
-                               4C9264A40534866F004B0E72,
-                       );
-                       isa = PBXGroup;
-                       name = Authorization;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE81406CD7DA100BE0061 = {
-                       children = (
-                               4C9264AB0534866F004B0E72,
-                               4C9264AA0534866F004B0E72,
-                               C2B8DBC805E6C3CE00E6E67C,
-                               C2B8DBC705E6C3CE00E6E67C,
-                               4C9264B60534866F004B0E72,
-                               4C9264B50534866F004B0E72,
-                               4C9264BB0534866F004B0E72,
-                               4C9264BA0534866F004B0E72,
-                               4C9264BF0534866F004B0E72,
-                               4C9264BE0534866F004B0E72,
-                               4C9264C10534866F004B0E72,
-                               4C9264C00534866F004B0E72,
-                               C28ACF9B05C9940B00447176,
-                               C28ACF9A05C9940B00447176,
-                       );
-                       isa = PBXGroup;
-                       name = "Core Structure";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE81706CD7DC500BE0061 = {
-                       children = (
-                               C28AE80406CD7D1D00BE0061,
-                               C28AE80706CD7D2700BE0061,
-                               C28AE80106CD7D0E00BE0061,
-                               C28AE7FE06CD7CFF00BE0061,
-                       );
-                       isa = PBXGroup;
-                       name = "Database Types";
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE81A06CD7DE200BE0061 = {
-                       children = (
-                               C2FDCABE0663CD5B0013F64C,
-                               C2FDCABD0663CD5B0013F64C,
-                               C2FDCAC00663CD5B0013F64C,
-                               C2FDCABF0663CD5B0013F64C,
-                               C2FDCAC20663CD5B0013F64C,
-                               C2FDCAC10663CD5B0013F64C,
-                               C22A7F8D06AF06D9006087B7,
-                               C22A7F8C06AF06D9006087B7,
-                               C26EA9520688CF34007CE21D,
-                               C26EA9510688CF34007CE21D,
-                       );
-                       isa = PBXGroup;
-                       name = Smartcards;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE82006CD7DF500BE0061 = {
-                       children = (
-                               4C9264BC0534866F004B0E72,
-                       );
-                       isa = PBXGroup;
-                       name = "Build Stuff";
-                       path = src;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE82306CD7E0F00BE0061 = {
-                       children = (
-                               4C9264C20534866F004B0E72,
-                               4C9264C40534866F004B0E72,
-                               4C9264C30534866F004B0E72,
-                               C28AE80E06CD7D5300BE0061,
-                       );
-                       isa = PBXGroup;
-                       name = Transit;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE82606CD7E4700BE0061 = {
-                       children = (
-                               4C92649B0534866F004B0E72,
-                               4C92649A0534866F004B0E72,
-                               C28654B106DBC2A30021E6E5,
-                               C28654B006DBC2A30021E6E5,
-                               4C9264990534866F004B0E72,
-                               4C9264980534866F004B0E72,
-                       );
-                       isa = PBXGroup;
-                       name = ACLs;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C28AE83906CD7EE900BE0061 = {
-                       children = (
-                               4C92649D0534866F004B0E72,
-                               4C92649C0534866F004B0E72,
-                               4CB5ACBA06680AE000F359A9,
-                               4CB5ACB906680AE000F359A9,
-                               4C9264AF0534866F004B0E72,
-                               4C9264AE0534866F004B0E72,
-                               4C9264B90534866F004B0E72,
-                               4C9264B80534866F004B0E72,
-                               4C9264A90534866F004B0E72,
-                               4C9264A80534866F004B0E72,
-                       );
-                       isa = PBXGroup;
-                       name = Support;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2904F9606D116A3005FF97E = {
-                       explicitFileType = "compiled.mach-o.executable";
-                       includeInIndex = 0;
-                       isa = PBXFileReference;
-                       path = flippers;
-                       refType = 3;
-                       sourceTree = BUILT_PRODUCTS_DIR;
-               };
-               C2A7B20E079F3A90000DB673 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = "securityd-installCD.plist";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2A7B20F079F3A90000DB673 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = securityd.plist;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2B8DBC705E6C3CE00E6E67C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = database.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2B8DBC805E6C3CE00E6E67C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = database.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2B8DBC905E6C3CE00E6E67C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = kcdatabase.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2B8DBCA05E6C3CE00E6E67C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = kcdatabase.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2B8DBCB05E6C3CE00E6E67C = {
-                       fileRef = C2B8DBC705E6C3CE00E6E67C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2B8DBCC05E6C3CE00E6E67C = {
-                       fileRef = C2B8DBC805E6C3CE00E6E67C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2B8DBCD05E6C3CE00E6E67C = {
-                       fileRef = C2B8DBC905E6C3CE00E6E67C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2B8DBCE05E6C3CE00E6E67C = {
-                       fileRef = C2B8DBCA05E6C3CE00E6E67C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2C8B29806F8A60F000EBDA2 = {
-                       children = (
-                               4C9264AD0534866F004B0E72,
-                               4C9264AC0534866F004B0E72,
-                       );
-                       isa = PBXGroup;
-                       name = Crypto;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2D425F105F3C07400CB11F8 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = tokendatabase.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2D425F205F3C07400CB11F8 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = tokendatabase.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2D425F305F3C07400CB11F8 = {
-                       fileRef = C2D425F105F3C07400CB11F8;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2D425F405F3C07400CB11F8 = {
-                       fileRef = C2D425F205F3C07400CB11F8;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2FDCABD0663CD5B0013F64C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = pcscmonitor.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2FDCABE0663CD5B0013F64C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = pcscmonitor.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2FDCABF0663CD5B0013F64C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = reader.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2FDCAC00663CD5B0013F64C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = reader.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2FDCAC10663CD5B0013F64C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = token.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2FDCAC20663CD5B0013F64C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = token.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               C2FDCAC50663CD5B0013F64C = {
-                       fileRef = C2FDCABD0663CD5B0013F64C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2FDCAC60663CD5B0013F64C = {
-                       fileRef = C2FDCABE0663CD5B0013F64C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2FDCAC70663CD5B0013F64C = {
-                       fileRef = C2FDCABF0663CD5B0013F64C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2FDCAC80663CD5B0013F64C = {
-                       fileRef = C2FDCAC00663CD5B0013F64C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2FDCAC90663CD5B0013F64C = {
-                       fileRef = C2FDCAC10663CD5B0013F64C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               C2FDCACA0663CD5B0013F64C = {
-                       fileRef = C2FDCAC20663CD5B0013F64C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-       };
-       rootObject = 4CA1FEB0052A3C5800F22E42;
-}
diff --git a/securityd.xcodeproj/project.pbxproj b/securityd.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..1dcd18c
--- /dev/null
@@ -0,0 +1,1213 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 42;
+       objects = {
+
+/* Begin PBXAggregateTarget section */
+               C209B3A506ADBCAC007B9E6D /* mig */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = C27AD4990987FCF4001272E0 /* Build configuration list for PBXAggregateTarget "mig" */;
+                       buildPhases = (
+                               C209B3A406ADBCAC007B9E6D /* ShellScript */,
+                       );
+                       dependencies = (
+                       );
+                       name = mig;
+                       productName = generate;
+               };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+               405845670663B2010083E58C /* AuthorizationMechEval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 405845650663B2010083E58C /* AuthorizationMechEval.cpp */; };
+               405845680663B2010083E58C /* AuthorizationMechEval.h in Headers */ = {isa = PBXBuildFile; fileRef = 405845660663B2010083E58C /* AuthorizationMechEval.h */; };
+               40689F860725DCE00021A502 /* authhost.h in Headers */ = {isa = PBXBuildFile; fileRef = 40689F840725DCE00021A502 /* authhost.h */; };
+               40689F870725DCE00021A502 /* authhost.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 40689F850725DCE00021A502 /* authhost.cpp */; };
+               407ACD080AE5B57700A9DA90 /* credential.h in Headers */ = {isa = PBXBuildFile; fileRef = 407ACD060AE5B57700A9DA90 /* credential.h */; };
+               407ACD090AE5B57700A9DA90 /* credential.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 407ACD070AE5B57700A9DA90 /* credential.cpp */; };
+               4C01B3DA06FFC640004B3A01 /* securityd.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CE1878706FFC5D60079D235 /* securityd.1 */; };
+               4C9264C80534866F004B0E72 /* acl_keychain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264980534866F004B0E72 /* acl_keychain.cpp */; };
+               4C9264C90534866F004B0E72 /* acl_keychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264990534866F004B0E72 /* acl_keychain.h */; };
+               4C9264CA0534866F004B0E72 /* acls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C92649A0534866F004B0E72 /* acls.cpp */; };
+               4C9264CB0534866F004B0E72 /* acls.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C92649B0534866F004B0E72 /* acls.h */; };
+               4C9264CC0534866F004B0E72 /* agentquery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C92649C0534866F004B0E72 /* agentquery.cpp */; };
+               4C9264CD0534866F004B0E72 /* agentquery.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C92649D0534866F004B0E72 /* agentquery.h */; };
+               4C9264CE0534866F004B0E72 /* authority.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C92649E0534866F004B0E72 /* authority.cpp */; };
+               4C9264CF0534866F004B0E72 /* authority.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C92649F0534866F004B0E72 /* authority.h */; };
+               4C9264D00534866F004B0E72 /* AuthorizationDBPlist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264A00534866F004B0E72 /* AuthorizationDBPlist.cpp */; };
+               4C9264D10534866F004B0E72 /* AuthorizationDBPlist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264A10534866F004B0E72 /* AuthorizationDBPlist.h */; };
+               4C9264D20534866F004B0E72 /* AuthorizationEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264A20534866F004B0E72 /* AuthorizationEngine.cpp */; };
+               4C9264D30534866F004B0E72 /* AuthorizationEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264A30534866F004B0E72 /* AuthorizationEngine.h */; };
+               4C9264D40534866F004B0E72 /* AuthorizationRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264A40534866F004B0E72 /* AuthorizationRule.cpp */; };
+               4C9264D50534866F004B0E72 /* AuthorizationRule.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264A50534866F004B0E72 /* AuthorizationRule.h */; };
+               4C9264D80534866F004B0E72 /* codesigdb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264A80534866F004B0E72 /* codesigdb.cpp */; };
+               4C9264D90534866F004B0E72 /* codesigdb.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264A90534866F004B0E72 /* codesigdb.h */; };
+               4C9264DA0534866F004B0E72 /* connection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264AA0534866F004B0E72 /* connection.cpp */; };
+               4C9264DB0534866F004B0E72 /* connection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264AB0534866F004B0E72 /* connection.h */; };
+               4C9264DC0534866F004B0E72 /* dbcrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264AC0534866F004B0E72 /* dbcrypto.cpp */; };
+               4C9264DD0534866F004B0E72 /* dbcrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264AD0534866F004B0E72 /* dbcrypto.h */; };
+               4C9264DE0534866F004B0E72 /* entropy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264AE0534866F004B0E72 /* entropy.cpp */; };
+               4C9264DF0534866F004B0E72 /* entropy.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264AF0534866F004B0E72 /* entropy.h */; };
+               4C9264E20534866F004B0E72 /* key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264B50534866F004B0E72 /* key.cpp */; };
+               4C9264E30534866F004B0E72 /* key.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264B60534866F004B0E72 /* key.h */; };
+               4C9264E40534866F004B0E72 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264B70534866F004B0E72 /* main.cpp */; };
+               4C9264E50534866F004B0E72 /* notifications.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264B80534866F004B0E72 /* notifications.cpp */; };
+               4C9264E60534866F004B0E72 /* notifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264B90534866F004B0E72 /* notifications.h */; };
+               4C9264E70534866F004B0E72 /* process.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264BA0534866F004B0E72 /* process.cpp */; };
+               4C9264E80534866F004B0E72 /* process.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264BB0534866F004B0E72 /* process.h */; };
+               4C9264EA0534866F004B0E72 /* server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264BE0534866F004B0E72 /* server.cpp */; };
+               4C9264EB0534866F004B0E72 /* server.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264BF0534866F004B0E72 /* server.h */; };
+               4C9264EC0534866F004B0E72 /* session.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264C00534866F004B0E72 /* session.cpp */; };
+               4C9264ED0534866F004B0E72 /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C9264C10534866F004B0E72 /* session.h */; };
+               4C9264EE0534866F004B0E72 /* transition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C9264C20534866F004B0E72 /* transition.cpp */; };
+               4CB5ACBB06680AE000F359A9 /* child.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CB5ACB906680AE000F359A9 /* child.cpp */; };
+               4CB5ACBC06680AE000F359A9 /* child.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CB5ACBA06680AE000F359A9 /* child.h */; };
+               C207646505EAD713004FEEDA /* kckey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C207646305EAD713004FEEDA /* kckey.cpp */; };
+               C207646605EAD713004FEEDA /* kckey.h in Headers */ = {isa = PBXBuildFile; fileRef = C207646405EAD713004FEEDA /* kckey.h */; };
+               C20764E805ED250F004FEEDA /* localdatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C20764E405ED250F004FEEDA /* localdatabase.cpp */; };
+               C20764E905ED250F004FEEDA /* localdatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = C20764E505ED250F004FEEDA /* localdatabase.h */; };
+               C20764EA05ED250F004FEEDA /* localkey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C20764E605ED250F004FEEDA /* localkey.cpp */; };
+               C20764EB05ED250F004FEEDA /* localkey.h in Headers */ = {isa = PBXBuildFile; fileRef = C20764E705ED250F004FEEDA /* localkey.h */; };
+               C209B3B506ADBE64007B9E6D /* self.h in Headers */ = {isa = PBXBuildFile; fileRef = C209B3B206ADBE64007B9E6D /* self.h */; };
+               C209B3B606ADBE64007B9E6D /* selfServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C209B3B306ADBE64007B9E6D /* selfServer.cpp */; settings = {COMPILER_FLAGS = "-D__MigTypeCheck=1"; }; };
+               C209B3B706ADBE64007B9E6D /* selfUser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C209B3B406ADBE64007B9E6D /* selfUser.cpp */; };
+               C20AF37E05F689540055732C /* tempdatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C20AF37C05F689540055732C /* tempdatabase.cpp */; };
+               C20AF37F05F689540055732C /* tempdatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = C20AF37D05F689540055732C /* tempdatabase.h */; };
+               C22A7F8E06AF06D9006087B7 /* tokend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C22A7F8C06AF06D9006087B7 /* tokend.cpp */; };
+               C22A7F8F06AF06D9006087B7 /* tokend.h in Headers */ = {isa = PBXBuildFile; fileRef = C22A7F8D06AF06D9006087B7 /* tokend.h */; };
+               C22C344E0B278E770009368E /* osxcodewrap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C22C344C0B278E770009368E /* osxcodewrap.cpp */; };
+               C22C344F0B278E770009368E /* osxcodewrap.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C344D0B278E770009368E /* osxcodewrap.h */; };
+               C22C34540B278EB60009368E /* clientid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C22C34520B278EB60009368E /* clientid.cpp */; };
+               C22C34550B278EB60009368E /* clientid.h in Headers */ = {isa = PBXBuildFile; fileRef = C22C34530B278EB60009368E /* clientid.h */; };
+               C26D533906C1E70A00062E1E /* tokenkey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C26D533706C1E70A00062E1E /* tokenkey.cpp */; };
+               C26D533A06C1E70A00062E1E /* tokenkey.h in Headers */ = {isa = PBXBuildFile; fileRef = C26D533806C1E70A00062E1E /* tokenkey.h */; };
+               C26EA9530688CF34007CE21D /* tokencache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C26EA9510688CF34007CE21D /* tokencache.cpp */; };
+               C26EA9540688CF34007CE21D /* tokencache.h in Headers */ = {isa = PBXBuildFile; fileRef = C26EA9520688CF34007CE21D /* tokencache.h */; };
+               C2813C810730534A00E243E8 /* tokenaccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2813C7F0730534A00E243E8 /* tokenaccess.cpp */; };
+               C2813C820730534A00E243E8 /* tokenaccess.h in Headers */ = {isa = PBXBuildFile; fileRef = C2813C800730534A00E243E8 /* tokenaccess.h */; };
+               C28654B206DBC2A30021E6E5 /* tokenacl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C28654B006DBC2A30021E6E5 /* tokenacl.cpp */; };
+               C28654B306DBC2A30021E6E5 /* tokenacl.h in Headers */ = {isa = PBXBuildFile; fileRef = C28654B106DBC2A30021E6E5 /* tokenacl.h */; };
+               C28ACF9C05C9940B00447176 /* structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C28ACF9A05C9940B00447176 /* structure.cpp */; };
+               C28ACF9D05C9940B00447176 /* structure.h in Headers */ = {isa = PBXBuildFile; fileRef = C28ACF9B05C9940B00447176 /* structure.h */; };
+               C2B8DBCB05E6C3CE00E6E67C /* database.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2B8DBC705E6C3CE00E6E67C /* database.cpp */; };
+               C2B8DBCC05E6C3CE00E6E67C /* database.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B8DBC805E6C3CE00E6E67C /* database.h */; };
+               C2B8DBCD05E6C3CE00E6E67C /* kcdatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2B8DBC905E6C3CE00E6E67C /* kcdatabase.cpp */; };
+               C2B8DBCE05E6C3CE00E6E67C /* kcdatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B8DBCA05E6C3CE00E6E67C /* kcdatabase.h */; };
+               C2BD5FDC0AC47E850057FD3D /* csproxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2BD5FDA0AC47E850057FD3D /* csproxy.cpp */; };
+               C2BD5FDD0AC47E850057FD3D /* csproxy.h in Headers */ = {isa = PBXBuildFile; fileRef = C2BD5FDB0AC47E850057FD3D /* csproxy.h */; };
+               C2D425F305F3C07400CB11F8 /* tokendatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2D425F105F3C07400CB11F8 /* tokendatabase.cpp */; };
+               C2D425F405F3C07400CB11F8 /* tokendatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = C2D425F205F3C07400CB11F8 /* tokendatabase.h */; };
+               C2FDCAC50663CD5B0013F64C /* pcscmonitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2FDCABD0663CD5B0013F64C /* pcscmonitor.cpp */; };
+               C2FDCAC60663CD5B0013F64C /* pcscmonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FDCABE0663CD5B0013F64C /* pcscmonitor.h */; };
+               C2FDCAC70663CD5B0013F64C /* reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2FDCABF0663CD5B0013F64C /* reader.cpp */; };
+               C2FDCAC80663CD5B0013F64C /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FDCAC00663CD5B0013F64C /* reader.h */; };
+               C2FDCAC90663CD5B0013F64C /* token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2FDCAC10663CD5B0013F64C /* token.cpp */; };
+               C2FDCACA0663CD5B0013F64C /* token.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FDCAC20663CD5B0013F64C /* token.h */; };
+               D6C887F00A55B6220044DFD2 /* SharedMemoryServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6C887ED0A55B6220044DFD2 /* SharedMemoryServer.cpp */; };
+               D6C887F10A55B6220044DFD2 /* SharedMemoryServer.h in Headers */ = {isa = PBXBuildFile; fileRef = D6C887EE0A55B6220044DFD2 /* SharedMemoryServer.h */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+               4CD8CCB5055884BD006B3584 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4CA1FEB0052A3C5800F22E42 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 4CA4EB2C0558848900CF7791;
+                       remoteInfo = startup;
+               };
+               C209B3A906ADBD6D007B9E6D /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 4CA1FEB0052A3C5800F22E42 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = C209B3A506ADBCAC007B9E6D;
+                       remoteInfo = mig;
+               };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+               4C01B3D706FFC621004B3A01 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 8;
+                       dstPath = /usr/share/man/man1/;
+                       dstSubfolderSpec = 0;
+                       files = (
+                               4C01B3DA06FFC640004B3A01 /* securityd.1 in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+               };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+               405845650663B2010083E58C /* AuthorizationMechEval.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AuthorizationMechEval.cpp; sourceTree = "<group>"; };
+               405845660663B2010083E58C /* AuthorizationMechEval.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AuthorizationMechEval.h; sourceTree = "<group>"; };
+               40689F840725DCE00021A502 /* authhost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = authhost.h; sourceTree = "<group>"; };
+               40689F850725DCE00021A502 /* authhost.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = authhost.cpp; sourceTree = "<group>"; };
+               407ACD060AE5B57700A9DA90 /* credential.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = credential.h; sourceTree = "<group>"; };
+               407ACD070AE5B57700A9DA90 /* credential.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = credential.cpp; sourceTree = "<group>"; };
+               4C9264980534866F004B0E72 /* acl_keychain.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = acl_keychain.cpp; sourceTree = "<group>"; };
+               4C9264990534866F004B0E72 /* acl_keychain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = acl_keychain.h; sourceTree = "<group>"; };
+               4C92649A0534866F004B0E72 /* acls.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = acls.cpp; sourceTree = "<group>"; };
+               4C92649B0534866F004B0E72 /* acls.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = acls.h; sourceTree = "<group>"; };
+               4C92649C0534866F004B0E72 /* agentquery.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = agentquery.cpp; sourceTree = "<group>"; };
+               4C92649D0534866F004B0E72 /* agentquery.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = agentquery.h; sourceTree = "<group>"; };
+               4C92649E0534866F004B0E72 /* authority.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = authority.cpp; sourceTree = "<group>"; };
+               4C92649F0534866F004B0E72 /* authority.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = authority.h; sourceTree = "<group>"; };
+               4C9264A00534866F004B0E72 /* AuthorizationDBPlist.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AuthorizationDBPlist.cpp; sourceTree = "<group>"; };
+               4C9264A10534866F004B0E72 /* AuthorizationDBPlist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AuthorizationDBPlist.h; sourceTree = "<group>"; };
+               4C9264A20534866F004B0E72 /* AuthorizationEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AuthorizationEngine.cpp; sourceTree = "<group>"; };
+               4C9264A30534866F004B0E72 /* AuthorizationEngine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AuthorizationEngine.h; sourceTree = "<group>"; };
+               4C9264A40534866F004B0E72 /* AuthorizationRule.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AuthorizationRule.cpp; sourceTree = "<group>"; };
+               4C9264A50534866F004B0E72 /* AuthorizationRule.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AuthorizationRule.h; sourceTree = "<group>"; };
+               4C9264A80534866F004B0E72 /* codesigdb.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = codesigdb.cpp; sourceTree = "<group>"; };
+               4C9264A90534866F004B0E72 /* codesigdb.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = codesigdb.h; sourceTree = "<group>"; };
+               4C9264AA0534866F004B0E72 /* connection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = connection.cpp; sourceTree = "<group>"; };
+               4C9264AB0534866F004B0E72 /* connection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = connection.h; sourceTree = "<group>"; };
+               4C9264AC0534866F004B0E72 /* dbcrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = dbcrypto.cpp; sourceTree = "<group>"; };
+               4C9264AD0534866F004B0E72 /* dbcrypto.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dbcrypto.h; sourceTree = "<group>"; };
+               4C9264AE0534866F004B0E72 /* entropy.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = entropy.cpp; sourceTree = "<group>"; };
+               4C9264AF0534866F004B0E72 /* entropy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = entropy.h; sourceTree = "<group>"; };
+               4C9264B50534866F004B0E72 /* key.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = key.cpp; sourceTree = "<group>"; };
+               4C9264B60534866F004B0E72 /* key.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = key.h; sourceTree = "<group>"; };
+               4C9264B70534866F004B0E72 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+               4C9264B80534866F004B0E72 /* notifications.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = notifications.cpp; sourceTree = "<group>"; };
+               4C9264B90534866F004B0E72 /* notifications.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = notifications.h; sourceTree = "<group>"; };
+               4C9264BA0534866F004B0E72 /* process.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = process.cpp; sourceTree = "<group>"; };
+               4C9264BB0534866F004B0E72 /* process.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = process.h; sourceTree = "<group>"; };
+               4C9264BC0534866F004B0E72 /* securityd.order */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = securityd.order; sourceTree = "<group>"; };
+               4C9264BE0534866F004B0E72 /* server.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = server.cpp; sourceTree = "<group>"; };
+               4C9264BF0534866F004B0E72 /* server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = server.h; sourceTree = "<group>"; };
+               4C9264C00534866F004B0E72 /* session.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = session.cpp; sourceTree = "<group>"; };
+               4C9264C10534866F004B0E72 /* session.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session.h; sourceTree = "<group>"; };
+               4C9264C20534866F004B0E72 /* transition.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = transition.cpp; sourceTree = "<group>"; };
+               4CA1FEB6052A3C6D00F22E42 /* securityd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; path = securityd; sourceTree = BUILT_PRODUCTS_DIR; };
+               4CB5ACB906680AE000F359A9 /* child.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = child.cpp; sourceTree = "<group>"; };
+               4CB5ACBA06680AE000F359A9 /* child.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = child.h; sourceTree = "<group>"; };
+               4CD8CCBC055884E0006B3584 /* authorization.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist; path = authorization.plist; sourceTree = "<group>"; };
+               4CD8CCBD055884E0006B3584 /* CodeEquivalenceCandidates */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = CodeEquivalenceCandidates; sourceTree = "<group>"; };
+               4CD8CCC0055884E0006B3584 /* startup.mk */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = startup.mk; sourceTree = "<group>"; };
+               4CDD5018053765A900FEC36D /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
+               4CDD5019053765A900FEC36D /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
+               4CDD506B0537666500FEC36D /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+               4CE1878606FFC5D60079D235 /* BLOBFORMAT */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = BLOBFORMAT; sourceTree = "<group>"; };
+               4CE1878706FFC5D60079D235 /* securityd.1 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.man; path = securityd.1; sourceTree = "<group>"; };
+               C207646305EAD713004FEEDA /* kckey.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = kckey.cpp; sourceTree = "<group>"; };
+               C207646405EAD713004FEEDA /* kckey.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = kckey.h; sourceTree = "<group>"; };
+               C20764E405ED250F004FEEDA /* localdatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = localdatabase.cpp; sourceTree = "<group>"; };
+               C20764E505ED250F004FEEDA /* localdatabase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = localdatabase.h; sourceTree = "<group>"; };
+               C20764E605ED250F004FEEDA /* localkey.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = localkey.cpp; sourceTree = "<group>"; };
+               C20764E705ED250F004FEEDA /* localkey.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = localkey.h; sourceTree = "<group>"; };
+               C209B3AD06ADBDB4007B9E6D /* mig.mk */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = mig.mk; sourceTree = "<group>"; };
+               C209B3AE06ADBDB4007B9E6D /* self.defs */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.mig; path = self.defs; sourceTree = "<group>"; };
+               C209B3B206ADBE64007B9E6D /* self.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = self.h; sourceTree = "<group>"; };
+               C209B3B306ADBE64007B9E6D /* selfServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = selfServer.cpp; sourceTree = "<group>"; };
+               C209B3B406ADBE64007B9E6D /* selfUser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = selfUser.cpp; sourceTree = "<group>"; };
+               C20AF37C05F689540055732C /* tempdatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tempdatabase.cpp; sourceTree = "<group>"; };
+               C20AF37D05F689540055732C /* tempdatabase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tempdatabase.h; sourceTree = "<group>"; };
+               C22A7F8C06AF06D9006087B7 /* tokend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tokend.cpp; sourceTree = "<group>"; };
+               C22A7F8D06AF06D9006087B7 /* tokend.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tokend.h; sourceTree = "<group>"; };
+               C22C344C0B278E770009368E /* osxcodewrap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = osxcodewrap.cpp; sourceTree = "<group>"; };
+               C22C344D0B278E770009368E /* osxcodewrap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = osxcodewrap.h; sourceTree = "<group>"; };
+               C22C34520B278EB60009368E /* clientid.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = clientid.cpp; sourceTree = "<group>"; };
+               C22C34530B278EB60009368E /* clientid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = clientid.h; sourceTree = "<group>"; };
+               C26D533706C1E70A00062E1E /* tokenkey.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tokenkey.cpp; sourceTree = "<group>"; };
+               C26D533806C1E70A00062E1E /* tokenkey.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tokenkey.h; sourceTree = "<group>"; };
+               C26EA9510688CF34007CE21D /* tokencache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tokencache.cpp; sourceTree = "<group>"; };
+               C26EA9520688CF34007CE21D /* tokencache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tokencache.h; sourceTree = "<group>"; };
+               C26FB2650BC2C3A300D8EFC8 /* com.apple.securityd.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = com.apple.securityd.plist; sourceTree = "<group>"; };
+               C276AAD60663E7A400B57276 /* PCSC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PCSC.framework; path = /System/Library/Frameworks/PCSC.framework; sourceTree = "<absolute>"; };
+               C2813C7F0730534A00E243E8 /* tokenaccess.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tokenaccess.cpp; sourceTree = "<group>"; };
+               C2813C800730534A00E243E8 /* tokenaccess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tokenaccess.h; sourceTree = "<group>"; };
+               C28654B006DBC2A30021E6E5 /* tokenacl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tokenacl.cpp; sourceTree = "<group>"; };
+               C28654B106DBC2A30021E6E5 /* tokenacl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tokenacl.h; sourceTree = "<group>"; };
+               C28ACF9A05C9940B00447176 /* structure.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = structure.cpp; sourceTree = "<group>"; };
+               C28ACF9B05C9940B00447176 /* structure.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = structure.h; sourceTree = "<group>"; };
+               C2B8DBC705E6C3CE00E6E67C /* database.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = database.cpp; sourceTree = "<group>"; };
+               C2B8DBC805E6C3CE00E6E67C /* database.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = database.h; sourceTree = "<group>"; };
+               C2B8DBC905E6C3CE00E6E67C /* kcdatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = kcdatabase.cpp; sourceTree = "<group>"; };
+               C2B8DBCA05E6C3CE00E6E67C /* kcdatabase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = kcdatabase.h; sourceTree = "<group>"; };
+               C2BD5FDA0AC47E850057FD3D /* csproxy.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = csproxy.cpp; sourceTree = "<group>"; };
+               C2BD5FDB0AC47E850057FD3D /* csproxy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = csproxy.h; sourceTree = "<group>"; };
+               C2D425F105F3C07400CB11F8 /* tokendatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tokendatabase.cpp; sourceTree = "<group>"; };
+               C2D425F205F3C07400CB11F8 /* tokendatabase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tokendatabase.h; sourceTree = "<group>"; };
+               C2FDCABD0663CD5B0013F64C /* pcscmonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = pcscmonitor.cpp; sourceTree = "<group>"; };
+               C2FDCABE0663CD5B0013F64C /* pcscmonitor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = pcscmonitor.h; sourceTree = "<group>"; };
+               C2FDCABF0663CD5B0013F64C /* reader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = reader.cpp; sourceTree = "<group>"; };
+               C2FDCAC00663CD5B0013F64C /* reader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = reader.h; sourceTree = "<group>"; };
+               C2FDCAC10663CD5B0013F64C /* token.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = token.cpp; sourceTree = "<group>"; };
+               C2FDCAC20663CD5B0013F64C /* token.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = token.h; sourceTree = "<group>"; };
+               D6C887ED0A55B6220044DFD2 /* SharedMemoryServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SharedMemoryServer.cpp; sourceTree = "<group>"; };
+               D6C887EE0A55B6220044DFD2 /* SharedMemoryServer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SharedMemoryServer.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               4CA1FEB3052A3C6D00F22E42 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               4C9264970534866F004B0E72 /* src */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C9264B70534866F004B0E72 /* main.cpp */,
+                               C28AE81406CD7DA100BE0061 /* Core Structure */,
+                               C2C8B29806F8A60F000EBDA2 /* Crypto */,
+                               C28AE81706CD7DC500BE0061 /* Database Types */,
+                               C28AE81A06CD7DE200BE0061 /* Smartcards */,
+                               C28AE82306CD7E0F00BE0061 /* Transit */,
+                               C28AE82606CD7E4700BE0061 /* ACLs */,
+                               C28AE81106CD7D7800BE0061 /* Authorization */,
+                               C22C34510B278E950009368E /* Client Identification */,
+                               C28AE83906CD7EE900BE0061 /* Support */,
+                       );
+                       path = src;
+                       sourceTree = "<group>";
+               };
+               4CA1FEAC052A3C5800F22E42 = {
+                       isa = PBXGroup;
+                       children = (
+                               4C9264970534866F004B0E72 /* src */,
+                               C209B39106ADBB19007B9E6D /* mig */,
+                               4CE1878506FFC5D60079D235 /* doc */,
+                               C209B39406ADBB2B007B9E6D /* derived_src */,
+                               C28AE82006CD7DF500BE0061 /* Build Stuff */,
+                               4CDD50150537658500FEC36D /* Linked Frameworks */,
+                               4CA1FEB7052A3C6D00F22E42 /* Products */,
+                               4CD8CCBB055884E0006B3584 /* Other Installs */,
+                       );
+                       sourceTree = "<group>";
+               };
+               4CA1FEB7052A3C6D00F22E42 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CA1FEB6052A3C6D00F22E42 /* securityd */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               4CD8CCBB055884E0006B3584 /* Other Installs */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C26FB2650BC2C3A300D8EFC8 /* com.apple.securityd.plist */,
+                               4CD8CCBC055884E0006B3584 /* authorization.plist */,
+                               4CD8CCBD055884E0006B3584 /* CodeEquivalenceCandidates */,
+                               4CD8CCC0055884E0006B3584 /* startup.mk */,
+                       );
+                       name = "Other Installs";
+                       path = etc;
+                       sourceTree = "<group>";
+               };
+               4CDD50150537658500FEC36D /* Linked Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CDD5018053765A900FEC36D /* CoreFoundation.framework */,
+                               4CDD506B0537666500FEC36D /* IOKit.framework */,
+                               C276AAD60663E7A400B57276 /* PCSC.framework */,
+                               4CDD5019053765A900FEC36D /* Security.framework */,
+                       );
+                       name = "Linked Frameworks";
+                       path = src;
+                       sourceTree = "<group>";
+               };
+               4CE1878506FFC5D60079D235 /* doc */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4CE1878606FFC5D60079D235 /* BLOBFORMAT */,
+                               4CE1878706FFC5D60079D235 /* securityd.1 */,
+                       );
+                       path = doc;
+                       sourceTree = "<group>";
+               };
+               C209B39106ADBB19007B9E6D /* mig */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C209B3AD06ADBDB4007B9E6D /* mig.mk */,
+                               C209B3AE06ADBDB4007B9E6D /* self.defs */,
+                       );
+                       path = mig;
+                       sourceTree = "<group>";
+               };
+               C209B39406ADBB2B007B9E6D /* derived_src */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C209B3B206ADBE64007B9E6D /* self.h */,
+                               C209B3B306ADBE64007B9E6D /* selfServer.cpp */,
+                               C209B3B406ADBE64007B9E6D /* selfUser.cpp */,
+                       );
+                       path = derived_src;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+               C22C34510B278E950009368E /* Client Identification */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C22C34530B278EB60009368E /* clientid.h */,
+                               C22C34520B278EB60009368E /* clientid.cpp */,
+                               C2BD5FDB0AC47E850057FD3D /* csproxy.h */,
+                               C2BD5FDA0AC47E850057FD3D /* csproxy.cpp */,
+                               4C9264A90534866F004B0E72 /* codesigdb.h */,
+                               4C9264A80534866F004B0E72 /* codesigdb.cpp */,
+                       );
+                       name = "Client Identification";
+                       sourceTree = "<group>";
+               };
+               C28AE7FE06CD7CFF00BE0061 /* Token */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C2D425F205F3C07400CB11F8 /* tokendatabase.h */,
+                               C2D425F105F3C07400CB11F8 /* tokendatabase.cpp */,
+                               C26D533806C1E70A00062E1E /* tokenkey.h */,
+                               C26D533706C1E70A00062E1E /* tokenkey.cpp */,
+                               C2813C800730534A00E243E8 /* tokenaccess.h */,
+                               C2813C7F0730534A00E243E8 /* tokenaccess.cpp */,
+                       );
+                       name = Token;
+                       sourceTree = "<group>";
+               };
+               C28AE80106CD7D0E00BE0061 /* Temporary */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C20AF37D05F689540055732C /* tempdatabase.h */,
+                               C20AF37C05F689540055732C /* tempdatabase.cpp */,
+                       );
+                       name = Temporary;
+                       sourceTree = "<group>";
+               };
+               C28AE80406CD7D1D00BE0061 /* Local */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C20764E505ED250F004FEEDA /* localdatabase.h */,
+                               C20764E405ED250F004FEEDA /* localdatabase.cpp */,
+                               C20764E705ED250F004FEEDA /* localkey.h */,
+                               C20764E605ED250F004FEEDA /* localkey.cpp */,
+                       );
+                       name = Local;
+                       sourceTree = "<group>";
+               };
+               C28AE80706CD7D2700BE0061 /* Keychain */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C2B8DBCA05E6C3CE00E6E67C /* kcdatabase.h */,
+                               C2B8DBC905E6C3CE00E6E67C /* kcdatabase.cpp */,
+                               C207646405EAD713004FEEDA /* kckey.h */,
+                               C207646305EAD713004FEEDA /* kckey.cpp */,
+                       );
+                       name = Keychain;
+                       sourceTree = "<group>";
+               };
+               C28AE81106CD7D7800BE0061 /* Authorization */ = {
+                       isa = PBXGroup;
+                       children = (
+                               40689F840725DCE00021A502 /* authhost.h */,
+                               40689F850725DCE00021A502 /* authhost.cpp */,
+                               4C92649F0534866F004B0E72 /* authority.h */,
+                               4C92649E0534866F004B0E72 /* authority.cpp */,
+                               407ACD060AE5B57700A9DA90 /* credential.h */,
+                               407ACD070AE5B57700A9DA90 /* credential.cpp */,
+                               4C9264A10534866F004B0E72 /* AuthorizationDBPlist.h */,
+                               4C9264A00534866F004B0E72 /* AuthorizationDBPlist.cpp */,
+                               4C9264A30534866F004B0E72 /* AuthorizationEngine.h */,
+                               4C9264A20534866F004B0E72 /* AuthorizationEngine.cpp */,
+                               405845660663B2010083E58C /* AuthorizationMechEval.h */,
+                               405845650663B2010083E58C /* AuthorizationMechEval.cpp */,
+                               4C9264A50534866F004B0E72 /* AuthorizationRule.h */,
+                               4C9264A40534866F004B0E72 /* AuthorizationRule.cpp */,
+                       );
+                       name = Authorization;
+                       sourceTree = "<group>";
+               };
+               C28AE81406CD7DA100BE0061 /* Core Structure */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C9264AB0534866F004B0E72 /* connection.h */,
+                               4C9264AA0534866F004B0E72 /* connection.cpp */,
+                               C2B8DBC805E6C3CE00E6E67C /* database.h */,
+                               C2B8DBC705E6C3CE00E6E67C /* database.cpp */,
+                               4C9264B60534866F004B0E72 /* key.h */,
+                               4C9264B50534866F004B0E72 /* key.cpp */,
+                               4C9264BB0534866F004B0E72 /* process.h */,
+                               4C9264BA0534866F004B0E72 /* process.cpp */,
+                               4C9264BF0534866F004B0E72 /* server.h */,
+                               4C9264BE0534866F004B0E72 /* server.cpp */,
+                               4C9264C10534866F004B0E72 /* session.h */,
+                               4C9264C00534866F004B0E72 /* session.cpp */,
+                               C28ACF9B05C9940B00447176 /* structure.h */,
+                               C28ACF9A05C9940B00447176 /* structure.cpp */,
+                       );
+                       name = "Core Structure";
+                       sourceTree = "<group>";
+               };
+               C28AE81706CD7DC500BE0061 /* Database Types */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C28AE80406CD7D1D00BE0061 /* Local */,
+                               C28AE80706CD7D2700BE0061 /* Keychain */,
+                               C28AE80106CD7D0E00BE0061 /* Temporary */,
+                               C28AE7FE06CD7CFF00BE0061 /* Token */,
+                       );
+                       name = "Database Types";
+                       sourceTree = "<group>";
+               };
+               C28AE81A06CD7DE200BE0061 /* Smartcards */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C2FDCABE0663CD5B0013F64C /* pcscmonitor.h */,
+                               C2FDCABD0663CD5B0013F64C /* pcscmonitor.cpp */,
+                               C2FDCAC00663CD5B0013F64C /* reader.h */,
+                               C2FDCABF0663CD5B0013F64C /* reader.cpp */,
+                               C2FDCAC20663CD5B0013F64C /* token.h */,
+                               C2FDCAC10663CD5B0013F64C /* token.cpp */,
+                               C22A7F8D06AF06D9006087B7 /* tokend.h */,
+                               C22A7F8C06AF06D9006087B7 /* tokend.cpp */,
+                               C26EA9520688CF34007CE21D /* tokencache.h */,
+                               C26EA9510688CF34007CE21D /* tokencache.cpp */,
+                       );
+                       name = Smartcards;
+                       sourceTree = "<group>";
+               };
+               C28AE82006CD7DF500BE0061 /* Build Stuff */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C9264BC0534866F004B0E72 /* securityd.order */,
+                       );
+                       name = "Build Stuff";
+                       path = src;
+                       sourceTree = "<group>";
+               };
+               C28AE82306CD7E0F00BE0061 /* Transit */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C9264C20534866F004B0E72 /* transition.cpp */,
+                       );
+                       name = Transit;
+                       sourceTree = "<group>";
+               };
+               C28AE82606CD7E4700BE0061 /* ACLs */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C92649B0534866F004B0E72 /* acls.h */,
+                               4C92649A0534866F004B0E72 /* acls.cpp */,
+                               C28654B106DBC2A30021E6E5 /* tokenacl.h */,
+                               C28654B006DBC2A30021E6E5 /* tokenacl.cpp */,
+                               4C9264990534866F004B0E72 /* acl_keychain.h */,
+                               4C9264980534866F004B0E72 /* acl_keychain.cpp */,
+                       );
+                       name = ACLs;
+                       sourceTree = "<group>";
+               };
+               C28AE83906CD7EE900BE0061 /* Support */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C92649D0534866F004B0E72 /* agentquery.h */,
+                               4C92649C0534866F004B0E72 /* agentquery.cpp */,
+                               4CB5ACBA06680AE000F359A9 /* child.h */,
+                               4CB5ACB906680AE000F359A9 /* child.cpp */,
+                               4C9264AF0534866F004B0E72 /* entropy.h */,
+                               4C9264AE0534866F004B0E72 /* entropy.cpp */,
+                               4C9264B90534866F004B0E72 /* notifications.h */,
+                               4C9264B80534866F004B0E72 /* notifications.cpp */,
+                               C22C344D0B278E770009368E /* osxcodewrap.h */,
+                               C22C344C0B278E770009368E /* osxcodewrap.cpp */,
+                               D6C887EE0A55B6220044DFD2 /* SharedMemoryServer.h */,
+                               D6C887ED0A55B6220044DFD2 /* SharedMemoryServer.cpp */,
+                       );
+                       name = Support;
+                       sourceTree = "<group>";
+               };
+               C2C8B29806F8A60F000EBDA2 /* Crypto */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4C9264AD0534866F004B0E72 /* dbcrypto.h */,
+                               4C9264AC0534866F004B0E72 /* dbcrypto.cpp */,
+                       );
+                       name = Crypto;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               4CA1FEB1052A3C6D00F22E42 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4C9264C90534866F004B0E72 /* acl_keychain.h in Headers */,
+                               4C9264CB0534866F004B0E72 /* acls.h in Headers */,
+                               4C9264CD0534866F004B0E72 /* agentquery.h in Headers */,
+                               4C9264CF0534866F004B0E72 /* authority.h in Headers */,
+                               4C9264D10534866F004B0E72 /* AuthorizationDBPlist.h in Headers */,
+                               4C9264D30534866F004B0E72 /* AuthorizationEngine.h in Headers */,
+                               405845680663B2010083E58C /* AuthorizationMechEval.h in Headers */,
+                               4C9264D50534866F004B0E72 /* AuthorizationRule.h in Headers */,
+                               4CB5ACBC06680AE000F359A9 /* child.h in Headers */,
+                               4C9264D90534866F004B0E72 /* codesigdb.h in Headers */,
+                               4C9264DB0534866F004B0E72 /* connection.h in Headers */,
+                               C2B8DBCC05E6C3CE00E6E67C /* database.h in Headers */,
+                               4C9264DD0534866F004B0E72 /* dbcrypto.h in Headers */,
+                               4C9264DF0534866F004B0E72 /* entropy.h in Headers */,
+                               C2B8DBCE05E6C3CE00E6E67C /* kcdatabase.h in Headers */,
+                               C207646605EAD713004FEEDA /* kckey.h in Headers */,
+                               4C9264E30534866F004B0E72 /* key.h in Headers */,
+                               C20764E905ED250F004FEEDA /* localdatabase.h in Headers */,
+                               C20764EB05ED250F004FEEDA /* localkey.h in Headers */,
+                               4C9264E60534866F004B0E72 /* notifications.h in Headers */,
+                               C2FDCAC60663CD5B0013F64C /* pcscmonitor.h in Headers */,
+                               4C9264E80534866F004B0E72 /* process.h in Headers */,
+                               C2FDCAC80663CD5B0013F64C /* reader.h in Headers */,
+                               4C9264EB0534866F004B0E72 /* server.h in Headers */,
+                               4C9264ED0534866F004B0E72 /* session.h in Headers */,
+                               C28ACF9D05C9940B00447176 /* structure.h in Headers */,
+                               C20AF37F05F689540055732C /* tempdatabase.h in Headers */,
+                               C2FDCACA0663CD5B0013F64C /* token.h in Headers */,
+                               C2D425F405F3C07400CB11F8 /* tokendatabase.h in Headers */,
+                               C26EA9540688CF34007CE21D /* tokencache.h in Headers */,
+                               C209B3B506ADBE64007B9E6D /* self.h in Headers */,
+                               C22A7F8F06AF06D9006087B7 /* tokend.h in Headers */,
+                               C26D533A06C1E70A00062E1E /* tokenkey.h in Headers */,
+                               C28654B306DBC2A30021E6E5 /* tokenacl.h in Headers */,
+                               C2813C820730534A00E243E8 /* tokenaccess.h in Headers */,
+                               40689F860725DCE00021A502 /* authhost.h in Headers */,
+                               D6C887F10A55B6220044DFD2 /* SharedMemoryServer.h in Headers */,
+                               C2BD5FDD0AC47E850057FD3D /* csproxy.h in Headers */,
+                               407ACD080AE5B57700A9DA90 /* credential.h in Headers */,
+                               C22C344F0B278E770009368E /* osxcodewrap.h in Headers */,
+                               C22C34550B278EB60009368E /* clientid.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXLegacyTarget section */
+               4CA4EB2C0558848900CF7791 /* startup */ = {
+                       isa = PBXLegacyTarget;
+                       buildArgumentsString = "-f $(SRCROOT)/etc/startup.mk $(ACTION)";
+                       buildConfigurationList = C27AD4A30987FCF4001272E0 /* Build configuration list for PBXLegacyTarget "startup" */;
+                       buildPhases = (
+                       );
+                       buildToolPath = /usr/bin/gnumake;
+                       buildWorkingDirectory = "";
+                       dependencies = (
+                       );
+                       name = startup;
+                       passBuildSettingsInEnvironment = 1;
+                       productName = startup;
+               };
+/* End PBXLegacyTarget section */
+
+/* Begin PBXProject section */
+               4CA1FEB0052A3C5800F22E42 /* Project object */ = {
+                       isa = PBXProject;
+                       buildConfigurationList = C27AD4AD0987FCF4001272E0 /* Build configuration list for PBXProject "securityd" */;
+                       compatibilityVersion = "Xcode 2.4";
+                       hasScannedForEncodings = 1;
+                       mainGroup = 4CA1FEAC052A3C5800F22E42;
+                       productRefGroup = 4CA1FEB7052A3C6D00F22E42 /* Products */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               4CA1FEB5052A3C6D00F22E42 /* securityd */,
+                               4CA4EB2C0558848900CF7791 /* startup */,
+                               C209B3A506ADBCAC007B9E6D /* mig */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+               C209B3A406ADBCAC007B9E6D /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/bash;
+                       shellScript = "make -f mig/mig.mk\n";
+               };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               4CA1FEB2052A3C6D00F22E42 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               4C9264C80534866F004B0E72 /* acl_keychain.cpp in Sources */,
+                               4C9264CA0534866F004B0E72 /* acls.cpp in Sources */,
+                               4C9264CC0534866F004B0E72 /* agentquery.cpp in Sources */,
+                               4C9264CE0534866F004B0E72 /* authority.cpp in Sources */,
+                               4C9264D00534866F004B0E72 /* AuthorizationDBPlist.cpp in Sources */,
+                               4C9264D20534866F004B0E72 /* AuthorizationEngine.cpp in Sources */,
+                               405845670663B2010083E58C /* AuthorizationMechEval.cpp in Sources */,
+                               4C9264D40534866F004B0E72 /* AuthorizationRule.cpp in Sources */,
+                               4CB5ACBB06680AE000F359A9 /* child.cpp in Sources */,
+                               4C9264D80534866F004B0E72 /* codesigdb.cpp in Sources */,
+                               4C9264DA0534866F004B0E72 /* connection.cpp in Sources */,
+                               C2B8DBCB05E6C3CE00E6E67C /* database.cpp in Sources */,
+                               4C9264DC0534866F004B0E72 /* dbcrypto.cpp in Sources */,
+                               4C9264DE0534866F004B0E72 /* entropy.cpp in Sources */,
+                               C2B8DBCD05E6C3CE00E6E67C /* kcdatabase.cpp in Sources */,
+                               C207646505EAD713004FEEDA /* kckey.cpp in Sources */,
+                               4C9264E20534866F004B0E72 /* key.cpp in Sources */,
+                               C20764E805ED250F004FEEDA /* localdatabase.cpp in Sources */,
+                               C20764EA05ED250F004FEEDA /* localkey.cpp in Sources */,
+                               4C9264E40534866F004B0E72 /* main.cpp in Sources */,
+                               4C9264E50534866F004B0E72 /* notifications.cpp in Sources */,
+                               C2FDCAC50663CD5B0013F64C /* pcscmonitor.cpp in Sources */,
+                               4C9264E70534866F004B0E72 /* process.cpp in Sources */,
+                               C2FDCAC70663CD5B0013F64C /* reader.cpp in Sources */,
+                               4C9264EA0534866F004B0E72 /* server.cpp in Sources */,
+                               4C9264EC0534866F004B0E72 /* session.cpp in Sources */,
+                               C28ACF9C05C9940B00447176 /* structure.cpp in Sources */,
+                               C20AF37E05F689540055732C /* tempdatabase.cpp in Sources */,
+                               C2FDCAC90663CD5B0013F64C /* token.cpp in Sources */,
+                               C2D425F305F3C07400CB11F8 /* tokendatabase.cpp in Sources */,
+                               4C9264EE0534866F004B0E72 /* transition.cpp in Sources */,
+                               C26EA9530688CF34007CE21D /* tokencache.cpp in Sources */,
+                               C209B3B606ADBE64007B9E6D /* selfServer.cpp in Sources */,
+                               C209B3B706ADBE64007B9E6D /* selfUser.cpp in Sources */,
+                               C22A7F8E06AF06D9006087B7 /* tokend.cpp in Sources */,
+                               C26D533906C1E70A00062E1E /* tokenkey.cpp in Sources */,
+                               C28654B206DBC2A30021E6E5 /* tokenacl.cpp in Sources */,
+                               C2813C810730534A00E243E8 /* tokenaccess.cpp in Sources */,
+                               40689F870725DCE00021A502 /* authhost.cpp in Sources */,
+                               D6C887F00A55B6220044DFD2 /* SharedMemoryServer.cpp in Sources */,
+                               C2BD5FDC0AC47E850057FD3D /* csproxy.cpp in Sources */,
+                               407ACD090AE5B57700A9DA90 /* credential.cpp in Sources */,
+                               C22C344E0B278E770009368E /* osxcodewrap.cpp in Sources */,
+                               C22C34540B278EB60009368E /* clientid.cpp in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+               4CD8CCB6055884BD006B3584 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 4CA4EB2C0558848900CF7791 /* startup */;
+                       targetProxy = 4CD8CCB5055884BD006B3584 /* PBXContainerItemProxy */;
+               };
+               C209B3AA06ADBD6D007B9E6D /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = C209B3A506ADBCAC007B9E6D /* mig */;
+                       targetProxy = C209B3A906ADBD6D007B9E6D /* PBXContainerItemProxy */;
+               };
+/* End PBXTargetDependency section */
+
+/* Begin PBXToolTarget section */
+               4CA1FEB5052A3C6D00F22E42 /* securityd */ = {
+                       isa = PBXToolTarget;
+                       buildConfigurationList = C27AD4A80987FCF4001272E0 /* Build configuration list for PBXToolTarget "securityd" */;
+                       buildPhases = (
+                               4CA1FEB1052A3C6D00F22E42 /* Headers */,
+                               4CA1FEB2052A3C6D00F22E42 /* Sources */,
+                               4CA1FEB3052A3C6D00F22E42 /* Frameworks */,
+                               4C01B3D706FFC621004B3A01 /* CopyFiles */,
+                       );
+                       dependencies = (
+                               C209B3AA06ADBD6D007B9E6D /* PBXTargetDependency */,
+                               4CD8CCB6055884BD006B3584 /* PBXTargetDependency */,
+                       );
+                       name = securityd;
+                       productInstallPath = /usr/sbin;
+                       productName = securityd;
+                       productReference = 4CA1FEB6052A3C6D00F22E42 /* securityd */;
+               };
+/* End PBXToolTarget section */
+
+/* Begin XCBuildConfiguration section */
+               C27AD49A0987FCF4001272E0 /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               BUILD_VARIANTS = debug;
+                               COPY_PHASE_STRIP = NO;
+                               CSSM_HEADERS = "$(BUILT_PRODUCTS_DIR)/Security.framework/Headers:$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Headers";
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = generate;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               ZERO_LINK = YES;
+                       };
+                       name = Development;
+               };
+               C27AD49B0987FCF4001272E0 /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CSSM_HEADERS = "$(BUILT_PRODUCTS_DIR)/Security.framework/Headers:$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Headers";
+                               DEAD_CODE_STRIPPING = YES;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = generate;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               ZERO_LINK = NO;
+                       };
+                       name = Deployment;
+               };
+               C27AD49C0987FCF4001272E0 /* normal with debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               BUILD_VARIANTS = normal;
+                               COPY_PHASE_STRIP = NO;
+                               OPT_LDFLAGS = "";
+                               OPT_LDXFLAGS = "";
+                               OPT_LDXNOPIC = "";
+                               OTHER_CFLAGS = "";
+                               OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O1 -fno-inline";
+                               OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = generate;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = "normal with debug";
+               };
+               C27AD49D0987FCF4001272E0 /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = generate;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Default;
+               };
+               C27AD4A40987FCF4001272E0 /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               BUILD_VARIANTS = debug;
+                               COPY_PHASE_STRIP = NO;
+                               CSSM_HEADERS = "$(BUILT_PRODUCTS_DIR)/Security.framework/Headers:$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Headers";
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = startup;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               ZERO_LINK = YES;
+                       };
+                       name = Development;
+               };
+               C27AD4A50987FCF4001272E0 /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CSSM_HEADERS = "$(BUILT_PRODUCTS_DIR)/Security.framework/Headers:$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Headers";
+                               DEAD_CODE_STRIPPING = YES;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = startup;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               ZERO_LINK = NO;
+                       };
+                       name = Deployment;
+               };
+               C27AD4A60987FCF4001272E0 /* normal with debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               BUILD_VARIANTS = normal;
+                               COPY_PHASE_STRIP = NO;
+                               OPT_LDFLAGS = "";
+                               OPT_LDXFLAGS = "";
+                               OPT_LDXNOPIC = "";
+                               OTHER_CFLAGS = "";
+                               OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O1 -fno-inline";
+                               OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = startup;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = "normal with debug";
+               };
+               C27AD4A70987FCF4001272E0 /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = startup;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Default;
+               };
+               C27AD4A90987FCF4001272E0 /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               BUILD_VARIANTS = debug;
+                               COPY_PHASE_STRIP = NO;
+                               CSSM_HEADERS = "$(BUILT_PRODUCTS_DIR)/Security.framework/Headers:$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Headers";
+                               CURRENT_PROJECT_VERSION = 32661;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       /usr/local/SecurityPieces/Frameworks,
+                                       /usr/local/SecurityPieces/Components/securityd,
+                                       /usr/local/SecurityPieces/Components/Security,
+                                       "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               INSTALL_PATH = /usr/sbin;
+                               OPTIMIZATION_CFLAGS = "-O0";
+                               OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
+                               OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)";
+                               OPT_INLINEXFLAGS = "-finline-functions";
+                               OPT_LDXFLAGS = "-dead_strip";
+                               OPT_LDXNOPIC = ",_nopic";
+                               OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+                               OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+                               OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+                               OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -fno-inline";
+                               OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)";
+                               OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
+                               OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -fno-inline";
+                               OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)";
+                               OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
+                               OTHER_LDFLAGS = (
+                                       "-lbsm",
+                                       "-exported_symbols_list",
+                                       "$(SRCROOT)/src/securityd.exp",
+                               );
+                               OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)  \"-framework\" \"Security,_debug\" \"-framework\" \"PCSC,_debug\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_debug\" \"-framework\" \"security_tokend_client,_debug\" \"-framework\" \"security_cdsa_client,_debug\" \"-framework\" \"securityd_server,_debug\" \"-framework\" \"securityd_client,_debug\" \"-framework\" \"security_cdsa_utilities,_debug\" \"-framework\" \"security_utilities,_debug\" \"-framework\" \"security_codesigning,_debug\"";
+                               OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS)  \"-framework\" \"Security\" \"-framework\" \"PCSC\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_tokend_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_client$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_server$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_utilities$(OPT_LDXNOPIC)\" \"-framework\" \"security_utilities$(OPT_LDXNOPIC)\"";
+                               OTHER_LDFLAGS_profile = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -pg \"-framework\" \"Security,_profile\"  \"-framework\" \"PCSC,_profile\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_profile\" \"-framework\" \"security_tokend_client,_profile\" \"-framework\" \"security_cdsa_client,_profile\" \"-framework\" \"securityd_server,_profile\" \"-framework\" \"securityd_client,_profile\" \"-framework\" \"security_cdsa_utilities,_profile\" \"-framework\" \"security_utilities,_profile\"";
+                               PRODUCT_NAME = securityd;
+                               SECTORDER_FLAGS = (
+                                       "-sectorder",
+                                       __TEXT,
+                                       __text,
+                                       src/securityd.order,
+                                       "-e",
+                                       start,
+                               );
+                               VERSIONING_SYSTEM = "apple-generic";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               ZERO_LINK = YES;
+                       };
+                       name = Development;
+               };
+               C27AD4AA0987FCF4001272E0 /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               BUILD_VARIANTS = (
+                                       normal,
+                                       debug,
+                               );
+                               CSSM_HEADERS = "$(BUILT_PRODUCTS_DIR)/Security.framework/Headers:$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Headers";
+                               CURRENT_PROJECT_VERSION = 32661;
+                               DEAD_CODE_STRIPPING = YES;
+                               EXPORTED_SYMBOLS_FILE = "$(SRCROOT)/src/securityd.exp";
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       /usr/local/SecurityPieces/Frameworks,
+                                       /usr/local/SecurityPieces/Components/securityd,
+                                       /usr/local/SecurityPieces/Components/Security,
+                                       "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               INSTALL_PATH = /usr/sbin;
+                               OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
+                               OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)";
+                               OPT_INLINEXFLAGS = "-finline-functions";
+                               OPT_LDXFLAGS = "-dead_strip";
+                               OPT_LDXNOPIC = ",_nopic";
+                               OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+                               OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+                               OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+                               OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O1 -fno-inline";
+                               OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)";
+                               OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
+                               OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
+                               OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)";
+                               OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
+                               OTHER_LDFLAGS = (
+                                       "-lbsm",
+                                       "-exported_symbols_list",
+                                       "$(SRCROOT)/src/securityd.exp",
+                               );
+                               OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)  \"-framework\" \"Security,_debug\" \"-framework\" \"PCSC,_debug\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_debug\" \"-framework\" \"security_tokend_client,_debug\" \"-framework\" \"security_cdsa_client,_debug\" \"-framework\" \"securityd_server,_debug\" \"-framework\" \"securityd_client,_debug\" \"-framework\" \"security_cdsa_utilities,_debug\" \"-framework\" \"security_utilities,_debug\" \"-framework\" \"security_codesigning,_debug\"";
+                               OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS)  \"-framework\" \"Security\" \"-framework\" \"PCSC\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_tokend_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_client$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_server$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_utilities$(OPT_LDXNOPIC)\" \"-framework\" \"security_utilities$(OPT_LDXNOPIC)\"";
+                               OTHER_LDFLAGS_profile = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -pg \"-framework\" \"Security,_profile\"  \"-framework\" \"PCSC,_profile\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_profile\" \"-framework\" \"security_tokend_client,_profile\" \"-framework\" \"security_cdsa_client,_profile\" \"-framework\" \"securityd_server,_profile\" \"-framework\" \"securityd_client,_profile\" \"-framework\" \"security_cdsa_utilities,_profile\" \"-framework\" \"security_utilities,_profile\"";
+                               PRODUCT_NAME = securityd;
+                               SECTORDER_FLAGS = (
+                                       "-sectorder",
+                                       __TEXT,
+                                       __text,
+                                       src/securityd.order,
+                                       "-e",
+                                       start,
+                               );
+                               VERSIONING_SYSTEM = "apple-generic";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                               ZERO_LINK = NO;
+                       };
+                       name = Deployment;
+               };
+               C27AD4AB0987FCF4001272E0 /* normal with debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               BUILD_VARIANTS = normal;
+                               COPY_PHASE_STRIP = NO;
+                               CURRENT_PROJECT_VERSION = 32661;
+                               EXPORTED_SYMBOLS_FILE = "$(SRCROOT)/src/securityd.exp";
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       /usr/local/SecurityPieces/Frameworks,
+                                       /usr/local/SecurityPieces/Components/securityd,
+                                       /usr/local/SecurityPieces/Components/Security,
+                                       "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
+                               INSTALL_PATH = /usr/sbin;
+                               OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
+                               OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)";
+                               OPT_INLINEXFLAGS = "-finline-functions";
+                               OPT_LDFLAGS = "";
+                               OPT_LDXFLAGS = "";
+                               OPT_LDXNOPIC = "";
+                               OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+                               OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+                               OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+                               OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O1 -fno-inline";
+                               OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O1 -fno-inline";
+                               OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
+                               OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
+                               OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
+                               OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
+                               OTHER_LDFLAGS = (
+                                       "-lbsm",
+                                       "-exported_symbols_list",
+                                       "$(SRCROOT)/src/securityd.exp",
+                               );
+                               OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)  \"-framework\" \"Security,_debug\" \"-framework\" \"PCSC,_debug\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_debug\" \"-framework\" \"security_tokend_client,_debug\" \"-framework\" \"security_cdsa_client,_debug\" \"-framework\" \"securityd_server,_debug\" \"-framework\" \"securityd_client,_debug\" \"-framework\" \"security_cdsa_utilities,_debug\" \"-framework\" \"security_utilities,_debug\" \"-framework\" \"security_codesigning,_debug\"";
+                               OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS)  \"-framework\" \"Security\" \"-framework\" \"PCSC\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_tokend_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_client$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_server$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_utilities$(OPT_LDXNOPIC)\" \"-framework\" \"security_utilities$(OPT_LDXNOPIC)\"";
+                               OTHER_LDFLAGS_profile = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -pg \"-framework\" \"Security,_profile\"  \"-framework\" \"PCSC,_profile\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_profile\" \"-framework\" \"security_tokend_client,_profile\" \"-framework\" \"security_cdsa_client,_profile\" \"-framework\" \"securityd_server,_profile\" \"-framework\" \"securityd_client,_profile\" \"-framework\" \"security_cdsa_utilities,_profile\" \"-framework\" \"security_utilities,_profile\"";
+                               PRODUCT_NAME = securityd;
+                               SECTORDER_FLAGS = (
+                                       "-sectorder",
+                                       __TEXT,
+                                       __text,
+                                       src/securityd.order,
+                                       "-e",
+                                       start,
+                               );
+                               VERSIONING_SYSTEM = "apple-generic";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = "normal with debug";
+               };
+               C27AD4AC0987FCF4001272E0 /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               BUILD_VARIANTS = (
+                                       normal,
+                                       debug,
+                               );
+                               CURRENT_PROJECT_VERSION = 32661;
+                               EXPORTED_SYMBOLS_FILE = "$(SRCROOT)/src/securityd.exp";
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       /usr/local/SecurityPieces/Frameworks,
+                                       /usr/local/SecurityPieces/Components/securityd,
+                                       /usr/local/SecurityPieces/Components/Security,
+                                       "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
+                               );
+                               INSTALL_PATH = /usr/sbin;
+                               OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
+                               OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)";
+                               OPT_INLINEXFLAGS = "-finline-functions";
+                               OPT_LDXFLAGS = "-dead_strip";
+                               OPT_LDXNOPIC = ",_nopic";
+                               OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+                               OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+                               OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+                               OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O1 -fno-inline";
+                               OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)";
+                               OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
+                               OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
+                               OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)";
+                               OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
+                               OTHER_LDFLAGS = (
+                                       "-lbsm",
+                                       "-exported_symbols_list",
+                                       "$(SRCROOT)/src/securityd.exp",
+                               );
+                               OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)  \"-framework\" \"Security,_debug\" \"-framework\" \"PCSC,_debug\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_debug\" \"-framework\" \"security_tokend_client,_debug\" \"-framework\" \"security_cdsa_client,_debug\" \"-framework\" \"securityd_server,_debug\" \"-framework\" \"securityd_client,_debug\" \"-framework\" \"security_cdsa_utilities,_debug\" \"-framework\" \"security_utilities,_debug\" \"-framework\" \"security_codesigning,_debug\"";
+                               OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS)  \"-framework\" \"Security\" \"-framework\" \"PCSC\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_tokend_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_client$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_server$(OPT_LDXNOPIC)\" \"-framework\" \"securityd_client$(OPT_LDXNOPIC)\" \"-framework\" \"security_cdsa_utilities$(OPT_LDXNOPIC)\" \"-framework\" \"security_utilities$(OPT_LDXNOPIC)\"";
+                               OTHER_LDFLAGS_profile = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -pg \"-framework\" \"Security,_profile\"  \"-framework\" \"PCSC,_profile\" \"-framework\" \"IOKit\" \"-framework\" \"CoreFoundation\" \"-framework\" \"security_agent_client,_profile\" \"-framework\" \"security_tokend_client,_profile\" \"-framework\" \"security_cdsa_client,_profile\" \"-framework\" \"securityd_server,_profile\" \"-framework\" \"securityd_client,_profile\" \"-framework\" \"security_cdsa_utilities,_profile\" \"-framework\" \"security_utilities,_profile\"";
+                               PRODUCT_NAME = securityd;
+                               SECTORDER_FLAGS = (
+                                       "-sectorder",
+                                       __TEXT,
+                                       __text,
+                                       src/securityd.order,
+                                       "-e",
+                                       start,
+                               );
+                               VERSIONING_SYSTEM = "apple-generic";
+                               WARNING_CFLAGS = (
+                                       "-Wmost",
+                                       "-Wno-four-char-constants",
+                                       "-Wno-unknown-pragmas",
+                               );
+                       };
+                       name = Default;
+               };
+               C27AD4AE0987FCF4001272E0 /* Development */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+                               CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
+                               HEADER_SEARCH_PATHS = (
+                                       "$(BUILT_PRODUCTS_DIR)/SecurityPieces/Headers",
+                                       "$(BUILT_PRODUCTS_DIR)/SecurityPieces/PrivateHeaders",
+                               );
+                       };
+                       name = Development;
+               };
+               C27AD4AF0987FCF4001272E0 /* Deployment */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+                               CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
+                       };
+                       name = Deployment;
+               };
+               C27AD4B00987FCF4001272E0 /* normal with debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+                               CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
+                       };
+                       name = "normal with debug";
+               };
+               C27AD4B10987FCF4001272E0 /* Default */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+                               CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
+                       };
+                       name = Default;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               C27AD4990987FCF4001272E0 /* Build configuration list for PBXAggregateTarget "mig" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               C27AD49A0987FCF4001272E0 /* Development */,
+                               C27AD49B0987FCF4001272E0 /* Deployment */,
+                               C27AD49C0987FCF4001272E0 /* normal with debug */,
+                               C27AD49D0987FCF4001272E0 /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Default;
+               };
+               C27AD4A30987FCF4001272E0 /* Build configuration list for PBXLegacyTarget "startup" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               C27AD4A40987FCF4001272E0 /* Development */,
+                               C27AD4A50987FCF4001272E0 /* Deployment */,
+                               C27AD4A60987FCF4001272E0 /* normal with debug */,
+                               C27AD4A70987FCF4001272E0 /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Default;
+               };
+               C27AD4A80987FCF4001272E0 /* Build configuration list for PBXToolTarget "securityd" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               C27AD4A90987FCF4001272E0 /* Development */,
+                               C27AD4AA0987FCF4001272E0 /* Deployment */,
+                               C27AD4AB0987FCF4001272E0 /* normal with debug */,
+                               C27AD4AC0987FCF4001272E0 /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Default;
+               };
+               C27AD4AD0987FCF4001272E0 /* Build configuration list for PBXProject "securityd" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               C27AD4AE0987FCF4001272E0 /* Development */,
+                               C27AD4AF0987FCF4001272E0 /* Deployment */,
+                               C27AD4B00987FCF4001272E0 /* normal with debug */,
+                               C27AD4B10987FCF4001272E0 /* Default */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Default;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 4CA1FEB0052A3C5800F22E42 /* Project object */;
+}
index 29ae2cb52f0b650a31fd3d898654b801fb56c7f4..5d0bc6f5d49e11afc9fd9cc2f9ca735fcf5ac2f5 100644 (file)
 #include "AuthorizationDBPlist.h"
 #include <security_utilities/logging.h>
 
 #include "AuthorizationDBPlist.h"
 #include <security_utilities/logging.h>
 
+// mLock is held when the database is changed
+// mReadWriteLock is held when the file on disk is changed
+// during load(), save() and parseConfig() mLock is assumed
 
 
-namespace Authorization
-{
+namespace Authorization {
 
 
-AuthorizationDBPlist::AuthorizationDBPlist(const char *configFile) : mFileName(configFile), mLastChecked(DBL_MIN)
+AuthorizationDBPlist::AuthorizationDBPlist(const char *configFile) : 
+    mFileName(configFile), mLastChecked(DBL_MIN)
 {
        memset(&mRulesFileMtimespec, 0, sizeof(mRulesFileMtimespec));
 }
 
 void AuthorizationDBPlist::sync(CFAbsoluteTime now)
 {
 {
        memset(&mRulesFileMtimespec, 0, sizeof(mRulesFileMtimespec));
 }
 
 void AuthorizationDBPlist::sync(CFAbsoluteTime now)
 {
-       if (mRules.empty())
-               load(now);
-       else
-       {
+       if (mRules.empty()) {
+               StLock<Mutex> _(mLock);
+               load();
+       } else {
                // Don't do anything if we checked the timestamp less than 5 seconds ago
                // Don't do anything if we checked the timestamp less than 5 seconds ago
-               if (mLastChecked > now - 5.0)
+               if (mLastChecked > now - 5.0) {
+                       secdebug("authdb", "no sync: last reload %.0f + 5 > %.0f", 
+                               mLastChecked, now);
                        return;
                        return;
-       
-               struct stat st;
-               if (stat(mFileName.c_str(), &st))
-               {
-                       Syslog::error("Stating rules file \"%s\": %s", mFileName.c_str(), strerror(errno));
-                       /* @@@ No rules file found, use defaults: admin group for everything. */
-                       //UnixError::throwMe(errno);
                }
                }
-               else
+               
                {
                {
-                       // @@@ Make sure this is the right way to compare 2 struct timespec thingies
-                       // Technically we should check st_dev and st_ino as well since if either of those change
-                       // we are looking at a different file too.
-                       if (memcmp(&st.st_mtimespec, &mRulesFileMtimespec, sizeof(mRulesFileMtimespec)))
-                               load(now);
+                       struct stat st;
+                       {
+                               StLock<Mutex> _(mReadWriteLock);
+                               if (stat(mFileName.c_str(), &st)) {
+                                       Syslog::error("Stating rules file \"%s\": %s", mFileName.c_str(), 
+                                               strerror(errno));
+                                       return;
+                               }
+                       }
+
+                       if (memcmp(&st.st_mtimespec, &mRulesFileMtimespec, sizeof(mRulesFileMtimespec))) {
+                               StLock<Mutex> _(mLock);
+                               load();
+                       }
                }
        }
                }
        }
-
-       mLastChecked = now;
 }
 
 }
 
-void AuthorizationDBPlist::save() const
+void AuthorizationDBPlist::save()
 {
        if (!mConfig)
                return;
 
        StLock<Mutex> _(mReadWriteLock);
 {
        if (!mConfig)
                return;
 
        StLock<Mutex> _(mReadWriteLock);
-       
+
+    secdebug("authdb", "policy db changed, saving to disk.");
        int fd = -1;
        string tempFile = mFileName + ",";
        
        int fd = -1;
        string tempFile = mFileName + ",";
        
-       for (;;)
-       {
+       for (;;) {
                fd = open(tempFile.c_str(), O_WRONLY|O_CREAT|O_EXCL, 0644);
                fd = open(tempFile.c_str(), O_WRONLY|O_CREAT|O_EXCL, 0644);
-               if (fd == -1)
-               {
-                       if (errno == EEXIST)
-                       {
+               if (fd == -1) {
+                       if (errno == EEXIST) {
                                unlink(tempFile.c_str());
                                continue;
                        }
                                unlink(tempFile.c_str());
                                continue;
                        }
@@ -91,35 +94,32 @@ void AuthorizationDBPlist::save() const
                                continue;
                        else
                                break;
                                continue;
                        else
                                break;
-               }
-               else
+               } else
                        break;
        }
                        
                        break;
        }
                        
-       if (fd == -1)
-       {
-               Syslog::error("Saving rules file \"%s\": %s", tempFile.c_str(), strerror(errno));
+       if (fd == -1) {
+               Syslog::error("Saving rules file \"%s\": %s", tempFile.c_str(), 
+                strerror(errno));
                return;
        }
 
                return;
        }
 
-       // convert config to plist
        CFDataRef configXML = CFPropertyListCreateXMLData(NULL, mConfig);
        CFDataRef configXML = CFPropertyListCreateXMLData(NULL, mConfig);
-       
        if (!configXML)
                return;
 
        if (!configXML)
                return;
 
-       // write out data
-       SInt32 configSize = CFDataGetLength(configXML);
+       CFIndex configSize = CFDataGetLength(configXML);
        size_t bytesWritten = write(fd, CFDataGetBytePtr(configXML), configSize);
        CFRelease(configXML);
        
        size_t bytesWritten = write(fd, CFDataGetBytePtr(configXML), configSize);
        CFRelease(configXML);
        
-       if (bytesWritten != uint32_t(configSize))
-       {
+       if (bytesWritten != configSize) {
                if (bytesWritten == static_cast<size_t>(-1))
                if (bytesWritten == static_cast<size_t>(-1))
-                       Syslog::error("Writing rules file \"%s\": %s", tempFile.c_str(), strerror(errno));
+                       Syslog::error("Problem writing rules file \"%s\": (errno=%s)", 
+                    tempFile.c_str(), strerror(errno));
                else
                else
-                       Syslog::error("Could only write %lu out of %ld bytes from rules file \"%s\"",
-                                               bytesWritten, configSize, tempFile.c_str());
+                       Syslog::error("Problem writing rules file \"%s\": "
+                "only wrote %lu out of %ld bytes",
+                               tempFile.c_str(), bytesWritten, configSize);
 
                close(fd);
                unlink(tempFile.c_str());
 
                close(fd);
                unlink(tempFile.c_str());
@@ -129,49 +129,46 @@ void AuthorizationDBPlist::save() const
                close(fd);
                if (rename(tempFile.c_str(), mFileName.c_str()))
                        unlink(tempFile.c_str());
                close(fd);
                if (rename(tempFile.c_str(), mFileName.c_str()))
                        unlink(tempFile.c_str());
+               else
+                       mLastChecked = CFAbsoluteTimeGetCurrent(); // we have the copy that's on disk now, so don't go loading it right away
        }
        }
-       return;
 }
 
 }
 
-void AuthorizationDBPlist::load(CFTimeInterval now)
+void AuthorizationDBPlist::load()
 {
        StLock<Mutex> _(mReadWriteLock);
 {
        StLock<Mutex> _(mReadWriteLock);
-       
+
+    secdebug("authdb", "(re)loading policy db from disk.");    
        int fd = open(mFileName.c_str(), O_RDONLY, 0);
        int fd = open(mFileName.c_str(), O_RDONLY, 0);
-       if (fd == -1)
-       {
-               Syslog::error("Opening rules file \"%s\": %s", mFileName.c_str(), strerror(errno));
+       if (fd == -1) {
+               Syslog::error("Problem opening rules file \"%s\": %s", 
+                mFileName.c_str(), strerror(errno));
                return;
        }
 
        struct stat st;
                return;
        }
 
        struct stat st;
-       if (fstat(fd, &st))
-       {
+       if (fstat(fd, &st)) {
                int error = errno;
                close(fd);
                UnixError::throwMe(error);
        }
                int error = errno;
                close(fd);
                UnixError::throwMe(error);
        }
-               
 
        mRulesFileMtimespec = st.st_mtimespec;
 
        mRulesFileMtimespec = st.st_mtimespec;
-
        off_t fileSize = st.st_size;
        off_t fileSize = st.st_size;
-
        CFMutableDataRef xmlData = CFDataCreateMutable(NULL, fileSize);
        CFDataSetLength(xmlData, fileSize);
        void *buffer = CFDataGetMutableBytePtr(xmlData);
        size_t bytesRead = read(fd, buffer, fileSize);
        CFMutableDataRef xmlData = CFDataCreateMutable(NULL, fileSize);
        CFDataSetLength(xmlData, fileSize);
        void *buffer = CFDataGetMutableBytePtr(xmlData);
        size_t bytesRead = read(fd, buffer, fileSize);
-       if (bytesRead != fileSize)
-       {
-               if (bytesRead == static_cast<size_t>(-1))
-               {
-                       Syslog::error("Reading rules file \"%s\": %s", mFileName.c_str(), strerror(errno));
+       if (bytesRead != fileSize) {
+               if (bytesRead == static_cast<size_t>(-1)) {
+                       Syslog::error("Problem reading rules file \"%s\": %s", 
+                    mFileName.c_str(), strerror(errno));
                        CFRelease(xmlData);
                        return;
                }
                        CFRelease(xmlData);
                        return;
                }
-
-               Syslog::error("Could only read %ul out of %ul bytes from rules file \"%s\"",
-                                               bytesRead, fileSize, mFileName.c_str());
+               Syslog::error("Problem reading rules file \"%s\": "
+                "only read %ul out of %ul bytes",
+                               bytesRead, fileSize, mFileName.c_str());
                CFRelease(xmlData);
                return;
        }
                CFRelease(xmlData);
                return;
        }
@@ -179,17 +176,18 @@ void AuthorizationDBPlist::load(CFTimeInterval now)
        CFStringRef errorString;
        CFDictionaryRef configPlist = reinterpret_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(NULL, xmlData, kCFPropertyListMutableContainersAndLeaves, &errorString));
        
        CFStringRef errorString;
        CFDictionaryRef configPlist = reinterpret_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(NULL, xmlData, kCFPropertyListMutableContainersAndLeaves, &errorString));
        
-       if (!configPlist)
-       {
+       if (!configPlist) {
                char buffer[512];
                char buffer[512];
-               const char *error = CFStringGetCStringPtr(errorString, kCFStringEncodingUTF8);
-               if (error == NULL)
-               {
-                       if (CFStringGetCString(errorString, buffer, 512, kCFStringEncodingUTF8))
+               const char *error = CFStringGetCStringPtr(errorString, 
+                kCFStringEncodingUTF8);
+               if (error == NULL) {
+                       if (CFStringGetCString(errorString, buffer, 512, 
+                        kCFStringEncodingUTF8))
                                error = buffer;
                }
 
                                error = buffer;
                }
 
-               Syslog::error("Parsing rules file \"%s\": %s", mFileName.c_str(), error);
+               Syslog::error("Parsing rules file \"%s\": %s", 
+                mFileName.c_str(), error);
                if (errorString)
                        CFRelease(errorString);
                
                if (errorString)
                        CFRelease(errorString);
                
@@ -197,70 +195,58 @@ void AuthorizationDBPlist::load(CFTimeInterval now)
                return;
        }
 
                return;
        }
 
-       if (CFGetTypeID(configPlist) != CFDictionaryGetTypeID())
-       {
+       if (CFGetTypeID(configPlist) != CFDictionaryGetTypeID()) {
 
 
-               Syslog::error("Rules file \"%s\": is not a dictionary", mFileName.c_str());
+               Syslog::error("Rules file \"%s\": is not a dictionary", 
+                mFileName.c_str());
 
                CFRelease(xmlData);
                CFRelease(configPlist);
                return;
        }
 
 
                CFRelease(xmlData);
                CFRelease(configPlist);
                return;
        }
 
-       {
-               StLock<Mutex> _(mLock);
-               parseConfig(configPlist);
-               mLastChecked = now;
-       }
+       parseConfig(configPlist);
+
        CFRelease(xmlData);
        CFRelease(configPlist);
 
        close(fd);
        CFRelease(xmlData);
        CFRelease(configPlist);
 
        close(fd);
-}
-
 
 
+       // If all went well, we have the copy that's on disk now, so don't go loading it right away
+       mLastChecked = CFAbsoluteTimeGetCurrent();
+}
 
 
-void
-AuthorizationDBPlist::parseConfig(CFDictionaryRef config)
+void AuthorizationDBPlist::parseConfig(CFDictionaryRef config)
 {
 {
-       // grab items from top-level dictionary that we care about
        CFStringRef rightsKey = CFSTR("rights");
        CFStringRef rulesKey = CFSTR("rules");
        CFMutableDictionaryRef newRights = NULL;
        CFMutableDictionaryRef newRules = NULL;
 
        if (!config)
        CFStringRef rightsKey = CFSTR("rights");
        CFStringRef rulesKey = CFSTR("rules");
        CFMutableDictionaryRef newRights = NULL;
        CFMutableDictionaryRef newRules = NULL;
 
        if (!config)
-               MacOSError::throwMe(errAuthorizationInternal); // XXX/cs invalid rule file
+               MacOSError::throwMe(errAuthorizationInternal); 
 
        if (CFDictionaryContainsKey(config, rulesKey))
 
        if (CFDictionaryContainsKey(config, rulesKey))
-       {
                newRules = reinterpret_cast<CFMutableDictionaryRef>(const_cast<void*>(CFDictionaryGetValue(config, rulesKey)));
                newRules = reinterpret_cast<CFMutableDictionaryRef>(const_cast<void*>(CFDictionaryGetValue(config, rulesKey)));
-       }
 
        if (CFDictionaryContainsKey(config, rightsKey))
 
        if (CFDictionaryContainsKey(config, rightsKey))
-       {
                newRights = reinterpret_cast<CFMutableDictionaryRef>(const_cast<void*>(CFDictionaryGetValue(config, rightsKey)));
                newRights = reinterpret_cast<CFMutableDictionaryRef>(const_cast<void*>(CFDictionaryGetValue(config, rightsKey)));
-       }
        
        
-       if (newRules 
-               && newRights 
+       if (newRules && newRights 
                && (CFDictionaryGetTypeID() == CFGetTypeID(newRules)) 
                && (CFDictionaryGetTypeID() == CFGetTypeID(newRules)) 
-               && (CFDictionaryGetTypeID() == CFGetTypeID(newRights)))
-       {
-               mConfig = config;
-               mConfigRights = static_cast<CFMutableDictionaryRef>(newRights);
-               mConfigRules = static_cast<CFMutableDictionaryRef>(newRules);
+               && (CFDictionaryGetTypeID() == CFGetTypeID(newRights))) 
+    {
+        mConfigRights = static_cast<CFMutableDictionaryRef>(newRights);
+        mConfigRules = static_cast<CFMutableDictionaryRef>(newRules);
                mRules.clear();
                mRules.clear();
-               try
-               {
+               try {
                        CFDictionaryApplyFunction(newRights, parseRule, this);
                        CFDictionaryApplyFunction(newRights, parseRule, this);
-               }
-               catch (...)
-               {
+               } catch (...) {
                        MacOSError::throwMe(errAuthorizationInternal); // XXX/cs invalid rule file
                }
                        MacOSError::throwMe(errAuthorizationInternal); // XXX/cs invalid rule file
                }
+               mConfig = config;
        }
        }
-       else
+       else 
                MacOSError::throwMe(errAuthorizationInternal); // XXX/cs invalid rule file
 }
 
                MacOSError::throwMe(errAuthorizationInternal); // XXX/cs invalid rule file
 }
 
@@ -282,10 +268,9 @@ AuthorizationDBPlist::validateRule(string inRightName, CFDictionaryRef inRightDe
                Rule newRule(inRightName, inRightDefinition, mConfigRules);
                if (newRule->name() == inRightName)
                        return true;
                Rule newRule(inRightName, inRightDefinition, mConfigRules);
                if (newRule->name() == inRightName)
                        return true;
-       } 
-       catch (...)
-       {
-               secdebug("authrule", "invalid definition for rule %s.\n", inRightName.c_str());
+       } catch (...) {
+               secdebug("authrule", "invalid definition for rule %s.\n", 
+                inRightName.c_str());
        }
        return false;
 }
        }
        return false;
 }
@@ -295,14 +280,11 @@ AuthorizationDBPlist::getRuleDefinition(string &key)
 {
        CFStringRef cfKey = makeCFString(key);
     StLock<Mutex> _(mLock);
 {
        CFStringRef cfKey = makeCFString(key);
     StLock<Mutex> _(mLock);
-       if (CFDictionaryContainsKey(mConfigRights, cfKey))
-       {
+       if (CFDictionaryContainsKey(mConfigRights, cfKey)) {
                CFDictionaryRef definition = reinterpret_cast<CFMutableDictionaryRef>(const_cast<void*>(CFDictionaryGetValue(mConfigRights, cfKey)));
                CFRelease(cfKey);
                return CFDictionaryCreateCopy(NULL, definition);
                CFDictionaryRef definition = reinterpret_cast<CFMutableDictionaryRef>(const_cast<void*>(CFDictionaryGetValue(mConfigRights, cfKey)));
                CFRelease(cfKey);
                return CFDictionaryCreateCopy(NULL, definition);
-       }
-       else
-       {
+       } else {
                CFRelease(cfKey);
                return NULL;
        }
                CFRelease(cfKey);
                return NULL;
        }
@@ -328,11 +310,11 @@ AuthorizationDBPlist::getRule(const AuthItemRef &inRight) const
     // Lock the rulemap
     StLock<Mutex> _(mLock);
        
     // Lock the rulemap
     StLock<Mutex> _(mLock);
        
+    secdebug("authdb", "looking up rule %s.", inRight->name());
        if (mRules.empty())
                return Rule();
 
        if (mRules.empty())
                return Rule();
 
-       for (;;)
-       {
+       for (;;) {
                map<string,Rule>::const_iterator rule = mRules.find(key);
                
                if (rule != mRules.end())
                map<string,Rule>::const_iterator rule = mRules.find(key);
                
                if (rule != mRules.end())
@@ -355,39 +337,42 @@ AuthorizationDBPlist::getRule(const AuthItemRef &inRight) const
 void
 AuthorizationDBPlist::setRule(const char *inRightName, CFDictionaryRef inRuleDefinition)
 {
 void
 AuthorizationDBPlist::setRule(const char *inRightName, CFDictionaryRef inRuleDefinition)
 {
+       // if mConfig is now a reasonable guard
        if (!inRuleDefinition || !mConfigRights)
                MacOSError::throwMe(errAuthorizationDenied); // errInvalidRule
 
        if (!inRuleDefinition || !mConfigRights)
                MacOSError::throwMe(errAuthorizationDenied); // errInvalidRule
 
-       CFRef<CFStringRef> keyRef(CFStringCreateWithCString(NULL, inRightName, kCFStringEncodingASCII));
+       CFRef<CFStringRef> keyRef(CFStringCreateWithCString(NULL, inRightName, 
+                kCFStringEncodingASCII));
        if (!keyRef)
                return;
                
        if (!keyRef)
                return;
                
-       StLock<Mutex> _(mLock);
-
-       CFDictionarySetValue(mConfigRights, keyRef, inRuleDefinition);
-       // release modification lock here already?
-       save();
-       mLastChecked = 0.0;
+       {
+               StLock<Mutex> _(mLock);
+               secdebug("authdb", "setting up rule %s.", inRightName);
+               CFDictionarySetValue(mConfigRights, keyRef, inRuleDefinition);
+               save();
+               parseConfig(mConfig);
+       }
 }
 
 void
 AuthorizationDBPlist::removeRule(const char *inRightName)
 {
 }
 
 void
 AuthorizationDBPlist::removeRule(const char *inRightName)
 {
+       // if mConfig is now a reasonable guard
        if (!mConfigRights)
                MacOSError::throwMe(errAuthorizationDenied);
                        
        if (!mConfigRights)
                MacOSError::throwMe(errAuthorizationDenied);
                        
-       CFRef<CFStringRef> keyRef(CFStringCreateWithCString(NULL, inRightName, kCFStringEncodingASCII));
+       CFRef<CFStringRef> keyRef(CFStringCreateWithCString(NULL, inRightName, 
+                kCFStringEncodingASCII));
        if (!keyRef)
                return;
 
        if (!keyRef)
                return;
 
-       StLock<Mutex> _(mLock);
-
-       if (CFDictionaryContainsKey(mConfigRights, keyRef))
        {
        {
+               StLock<Mutex> _(mLock);
+               secdebug("authdb", "removing rule %s.", inRightName);
                CFDictionaryRemoveValue(mConfigRights, keyRef);
                CFDictionaryRemoveValue(mConfigRights, keyRef);
-               // release modification lock here already?
                save();
                save();
-               mLastChecked = 0.0;
+               parseConfig(mConfig);
        }
 }
 
        }
 }
 
index 1a365c87a90e3a02c950ffc6beb72cebf095635c..2c2a134b9340f984bde6fbef5fd6530278b2df2b 100644 (file)
@@ -41,7 +41,7 @@ namespace Authorization
 class AuthorizationDBPlist /* : public AuthorizationDB */
 {
 public:
 class AuthorizationDBPlist /* : public AuthorizationDB */
 {
 public:
-       AuthorizationDBPlist(const char *configFile = "/etc/authorization");
+       AuthorizationDBPlist(const char *configFile);
        
        void sync(CFAbsoluteTime now);
        bool validateRule(string inRightName, CFDictionaryRef inRightDefinition) const;
        
        void sync(CFAbsoluteTime now);
        bool validateRule(string inRightName, CFDictionaryRef inRightDefinition) const;
@@ -54,8 +54,8 @@ public:
        void removeRule(const char *inRightName);
 
 protected:
        void removeRule(const char *inRightName);
 
 protected:
-       void load(CFTimeInterval now);
-       void save() const;
+       void load();
+       void save();
        
 private:
        string mFileName;
        
 private:
        string mFileName;
index 0a41fd1ddbfee0f7fb40456c61f54c57abb7d7c3..cd057645dd25cc9a48e43b2a09e57a08bc84be2b 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-
-/*
- *  AuthorizationEngine.cpp
- *  Authorization
- *
- *  Created by Michael Brouwer on Thu Oct 12 2000.
- *
- */
 #include "AuthorizationEngine.h"
 #include <security_cdsa_utilities/AuthorizationWalkers.h>
 #include <Security/AuthorizationPriv.h>
 #include "AuthorizationEngine.h"
 #include <security_cdsa_utilities/AuthorizationWalkers.h>
 #include <Security/AuthorizationPriv.h>
@@ -53,6 +45,8 @@
 #include <fcntl.h>
 #include <float.h>
 
 #include <fcntl.h>
 #include <float.h>
 
+#include <bsm/audit_uevents.h>
+
 namespace Authorization {
 
 
 namespace Authorization {
 
 
@@ -131,8 +125,6 @@ Engine::authorize(const AuthItemSet &inRights, const AuthItemSet &environment,
 
                if (username.length())
                {
 
                if (username.length())
                {
-                       // Call to checkpw in DS
-                       Server::active().longTermActivity();
                        // Let's create a credential from the passed in username and password.
                        Credential newCredential(username, password, shared);
                        // If it's valid insert it into the credentials list.  Normally this is
                        // Let's create a credential from the passed in username and password.
                        Credential newCredential(username, password, shared);
                        // If it's valid insert it into the credentials list.  Normally this is
@@ -155,15 +147,26 @@ Engine::authorize(const AuthItemSet &inRights, const AuthItemSet &environment,
                secdebug("autheval", "evaluate rule %s for right %s returned %ld.", toplevelRule->name().c_str(), (*it)->name(), result);
 
                {
                secdebug("autheval", "evaluate rule %s for right %s returned %ld.", toplevelRule->name().c_str(), (*it)->name(), result);
 
                {
-                       RefPointer<OSXCode> processCode = Server::process().clientCode();
-                       string processName = processCode ? processCode->canonicalPath() : "unknown";
-                       RefPointer<OSXCode> authCreatorCode = auth.creatorCode();
-                       string authCreatorName = authCreatorCode ? authCreatorCode->canonicalPath() : "unknown";
-                       
-                       if (result == errAuthorizationSuccess)
-                               Syslog::info("Succeeded authorizing right %s by process %s for authorization created by %s.", (*it)->name(), processName.c_str(), authCreatorName.c_str());
-                       else if (result == errAuthorizationDenied)
-                               Syslog::notice("Failed to authorize right %s by process %s for authorization created by %s.", (*it)->name(), processName.c_str(), authCreatorName.c_str());
+                       string processName = "unknown";
+                       if (SecCodeRef code = Server::process().currentGuest()) {
+                               CFRef<CFURLRef> path;
+                               if (!SecCodeCopyPath(code, kSecCSDefaultFlags, &path.aref()))
+                                       processName = cfString(path);
+                       }
+                       string authCreatorName = "unknown";
+                       if (SecStaticCodeRef code = auth.creatorCode()) {
+                               CFRef<CFURLRef> path;
+                               if (!SecCodeCopyPath(code, kSecCSDefaultFlags, &path.aref()))
+                                       authCreatorName = cfString(path);
+                       }
+
+                       if (result == errAuthorizationSuccess) {
+                               Syslog::info("Succeeded authorizing right %s by client %s for authorization created by %s.", (*it)->name(), processName.c_str(), authCreatorName.c_str());
+                               CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken());
+                               auditrec.submit(AUE_ssauthorize, CommonCriteria::errNone, (*it)->name());
+                       } else if (result == errAuthorizationDenied) {
+                               Syslog::notice("Failed to authorize right %s by client %s for authorization created by %s.", (*it)->name(), processName.c_str(), authCreatorName.c_str());
+                       }
                }
                
                if (result == errAuthorizationSuccess)
                }
                
                if (result == errAuthorizationSuccess)
@@ -287,12 +290,6 @@ Engine::getRule(string &inRightName, CFDictionaryRef *outRuleDefinition)
 OSStatus 
 Engine::setRule(const char *inRightName, CFDictionaryRef inRuleDefinition, const CredentialSet *inCredentials, CredentialSet *outCredentials, AuthorizationToken &auth)
 {
 OSStatus 
 Engine::setRule(const char *inRightName, CFDictionaryRef inRuleDefinition, const CredentialSet *inCredentials, CredentialSet *outCredentials, AuthorizationToken &auth)
 {
-       // Get current time of day.
-       CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
-
-       // Update rules from database if needed
-       mAuthdb.sync(now);
-
        // Validate rule by constructing it from the passed dictionary
        if (!mAuthdb.validateRule(inRightName, inRuleDefinition))
                return errAuthorizationDenied; // @@@ separate error for this?
        // Validate rule by constructing it from the passed dictionary
        if (!mAuthdb.validateRule(inRightName, inRuleDefinition))
                return errAuthorizationDenied; // @@@ separate error for this?
index 571cff7084d59524f761f638d8aeaf9954d8ef85..307a14936cda9a05be2c10572459393b77ea6f47 100644 (file)
@@ -54,6 +54,8 @@ AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemS
     
     AuthItemSet hints = inHints;
     AuthItemSet context = inContext;
     
     AuthItemSet hints = inHints;
     AuthItemSet context = inContext;
+    // add saved-off sticky context values to context for evaluation
+    context.insert(mStickyContext.begin(), mStickyContext.end());
        
     while ( (result == kAuthorizationResultAllow)  &&
             (currentMechanism != mMechanisms.end()) ) // iterate mechanisms
        
     while ( (result == kAuthorizationResultAllow)  &&
             (currentMechanism != mMechanisms.end()) ) // iterate mechanisms
@@ -178,7 +180,25 @@ AgentMechanismEvaluator::run(const AuthValueVector &inArguments, const AuthItemS
         (result == kAuthorizationResultAllow))
     {
         mHints = hints;
         (result == kAuthorizationResultAllow))
     {
         mHints = hints;
-        mContext = context;
+        mContext.clear(); 
+        // only make non-sticky context values available externally
+        AuthItemSet::const_iterator end = context.end();
+        for (AuthItemSet::const_iterator it = context.begin(); it != end; ++it) {
+            const AuthItemRef &item = *it;
+            if (item->flags() != kAuthorizationContextFlagSticky)
+                mContext.insert(item);
+        }
+    }
+    else if (result == kAuthorizationResultDeny)
+    {
+        // save off sticky values in context
+        mStickyContext.clear();
+        AuthItemSet::const_iterator end = context.end();
+        for (AuthItemSet::const_iterator it = context.begin(); it != end; ++it) {
+            const AuthItemRef &item = *it;
+            if (item->flags() == kAuthorizationContextFlagSticky)
+                mStickyContext.insert(item);
+        }
     }
     
     // convert AuthorizationResult to OSStatus
     }
     
     // convert AuthorizationResult to OSStatus
@@ -210,17 +230,9 @@ AuthorizationResult AgentMechanismEvaluator::authinternal(AuthItemSet &context)
         string password(static_cast<const char *>((*found)->value().data), (*found)->value().length);
         secdebug("AuthEvalMech", "found password");
 
         string password(static_cast<const char *>((*found)->value().data), (*found)->value().length);
         secdebug("AuthEvalMech", "found password");
 
-               // Call to checkpw in DS
-               Server::active().longTermActivity();            
         Credential newCredential(username, password, true); // create a new shared credential
         Credential newCredential(username, password, true); // create a new shared credential
-        
         if (newCredential->isValid())
         if (newCredential->isValid())
-        {
-            Syslog::info("authinternal authenticated user %s (uid %lu).", newCredential->username().c_str(), newCredential->uid());
             return kAuthorizationResultAllow;
             return kAuthorizationResultAllow;
-        }
-        
-        Syslog::error("authinternal failed to authenticate user %s.", newCredential->username().c_str());
         
     } while (0);
     
         
     } while (0);
     
index dc6d5ea9dd91d1a2dff9f5d2675a8eda21dbaa1e..da8ef57bcb63785fe13eb76f3cefdd3f200001ff 100644 (file)
@@ -63,6 +63,7 @@ private:
     
     AuthItemSet mHints;
     AuthItemSet mContext;
     
     AuthItemSet mHints;
     AuthItemSet mContext;
+    AuthItemSet mStickyContext;
 };
 
 } /* namespace Authorization */
 };
 
 } /* namespace Authorization */
index c1a1b218e16f5ae32d8404337067d2062f305caf..1fc8290fb07eaa70f84f84546d8df39a8b7af67f 100644 (file)
@@ -250,12 +250,12 @@ RuleImpl::RuleImpl(const string &inRightName, CFDictionaryRef cfRight, CFDiction
                        mSessionOwner = Attribute::getBool(cfRight, kSessionOwnerID);
                        // authorization tags can have eval now too
                        mEvalDef = Attribute::getVector(cfRight, kMechanismsID);
                        mSessionOwner = Attribute::getBool(cfRight, kSessionOwnerID);
                        // authorization tags can have eval now too
                        mEvalDef = Attribute::getVector(cfRight, kMechanismsID);
-            if (mEvalDef.size() == 0 && cfRules /*only rights default see appserver-admin*/)
-            {
-                CFDictionaryRef cfRuleDef = reinterpret_cast<CFDictionaryRef>(CFDictionaryGetValue(cfRules, CFSTR("authenticate")));
+                       if (mEvalDef.size() == 0 && cfRules /*only rights default see appserver-admin*/)
+                       {
+                               CFDictionaryRef cfRuleDef = reinterpret_cast<CFDictionaryRef>(CFDictionaryGetValue(cfRules, CFSTR("authenticate")));
                                if (cfRuleDef && CFGetTypeID(cfRuleDef) == CFDictionaryGetTypeID())
                                if (cfRuleDef && CFGetTypeID(cfRuleDef) == CFDictionaryGetTypeID())
-                    mEvalDef = Attribute::getVector(cfRuleDef, kMechanismsID);
-            }
+                                       mEvalDef = Attribute::getVector(cfRuleDef, kMechanismsID);
+                       }
                        mTries = int(Attribute::getDouble(cfRight, kTriesID, false, 3.0)); // XXX/cs double(kAuthorizationMaxTries)
                        mAuthenticateUser = Attribute::getBool(cfRight, kRuleAuthenticateUserID, false, true);
 
                        mTries = int(Attribute::getDouble(cfRight, kTriesID, false, 3.0)); // XXX/cs double(kAuthorizationMaxTries)
                        mAuthenticateUser = Attribute::getBool(cfRight, kRuleAuthenticateUserID, false, true);
 
@@ -276,7 +276,7 @@ RuleImpl::RuleImpl(const string &inRightName, CFDictionaryRef cfRight, CFDiction
                }
                else if (classTag == kAuthorizationRightRule)
                {
                }
                else if (classTag == kAuthorizationRightRule)
                {
-            assert(cfRules); // rules can't delegate to other rules
+                       assert(cfRules); // rules can't delegate to other rules
                        secdebug("authrule", "%s : rule delegate rule", inRightName.c_str());
                        mType = kRuleDelegation;
 
                        secdebug("authrule", "%s : rule delegate rule", inRightName.c_str());
                        mType = kRuleDelegation;
 
@@ -349,36 +349,24 @@ void
 RuleImpl::setAgentHints(const AuthItemRef &inRight, const Rule &inTopLevelRule, AuthItemSet &environmentToClient, AuthorizationToken &auth) const
 {
        string authorizeString(inRight->name());
 RuleImpl::setAgentHints(const AuthItemRef &inRight, const Rule &inTopLevelRule, AuthItemSet &environmentToClient, AuthorizationToken &auth) const
 {
        string authorizeString(inRight->name());
-    environmentToClient.erase(AuthItemRef(AGENT_HINT_AUTHORIZE_RIGHT)); 
+       environmentToClient.erase(AuthItemRef(AGENT_HINT_AUTHORIZE_RIGHT)); 
        environmentToClient.insert(AuthItemRef(AGENT_HINT_AUTHORIZE_RIGHT, AuthValueOverlay(authorizeString)));
 
        pid_t creatorPid = auth.creatorPid();
        environmentToClient.insert(AuthItemRef(AGENT_HINT_AUTHORIZE_RIGHT, AuthValueOverlay(authorizeString)));
 
        pid_t creatorPid = auth.creatorPid();
-    environmentToClient.erase(AuthItemRef(AGENT_HINT_CREATOR_PID)); 
+       environmentToClient.erase(AuthItemRef(AGENT_HINT_CREATOR_PID)); 
        environmentToClient.insert(AuthItemRef(AGENT_HINT_CREATOR_PID, AuthValueOverlay(sizeof(pid_t), &creatorPid)));
 
        Process &thisProcess = Server::process();
        environmentToClient.insert(AuthItemRef(AGENT_HINT_CREATOR_PID, AuthValueOverlay(sizeof(pid_t), &creatorPid)));
 
        Process &thisProcess = Server::process();
-       RefPointer<OSXCode> clientCode = auth.creatorCode();
-       SecurityAgent::RequestorType requestorType = SecurityAgent::unknown;
        string bundlePath;
        string bundlePath;
-       
-       if (clientCode)
-       {
-               string encodedBundle = clientCode->encode();
-               char bundleType = (encodedBundle.c_str())[0]; // yay, no accessor
-               switch(bundleType)
-               {
-                  case 'b': requestorType = SecurityAgent::bundle; break;
-                  case 't': requestorType = SecurityAgent::tool; break;
-               }
-               bundlePath = clientCode->canonicalPath();
-       }
-
-       AuthItemSet processHints = SecurityAgent::Client::clientHints(requestorType, bundlePath, thisProcess.pid(), thisProcess.uid());
-    environmentToClient.erase(AuthItemRef(AGENT_HINT_CLIENT_TYPE));
-    environmentToClient.erase(AuthItemRef(AGENT_HINT_CLIENT_PATH));
-    environmentToClient.erase(AuthItemRef(AGENT_HINT_CLIENT_PID));
-    environmentToClient.erase(AuthItemRef(AGENT_HINT_CLIENT_UID));
-    environmentToClient.insert(processHints.begin(), processHints.end());
+       if (SecStaticCodeRef clientCode = auth.creatorCode())
+               bundlePath = codePath(clientCode);
+       AuthItemSet processHints = SecurityAgent::Client::clientHints(
+               SecurityAgent::bundle, bundlePath, thisProcess.pid(), thisProcess.uid());
+       environmentToClient.erase(AuthItemRef(AGENT_HINT_CLIENT_TYPE));
+       environmentToClient.erase(AuthItemRef(AGENT_HINT_CLIENT_PATH));
+       environmentToClient.erase(AuthItemRef(AGENT_HINT_CLIENT_PID));
+       environmentToClient.erase(AuthItemRef(AGENT_HINT_CLIENT_UID));
+       environmentToClient.insert(processHints.begin(), processHints.end());
 
        map<string,string> defaultPrompts = inTopLevelRule->localizedPrompts();
 
 
        map<string,string> defaultPrompts = inTopLevelRule->localizedPrompts();
 
@@ -402,127 +390,143 @@ RuleImpl::setAgentHints(const AuthItemRef &inRight, const Rule &inTopLevelRule,
        environmentToClient.insert(AuthItemRef(AGENT_HINT_AUTHORIZE_RULE, AuthValueOverlay(ruleName)));
 }
 
        environmentToClient.insert(AuthItemRef(AGENT_HINT_AUTHORIZE_RULE, AuthValueOverlay(ruleName)));
 }
 
+// If a different evaluation for getting a credential is prescribed,
+// we'll run that and validate the credentials from there.
+// we fall back on a default configuration from the authenticate rule
 OSStatus
 OSStatus
-RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule,
-               AuthItemSet &environmentToClient, 
-        AuthorizationFlags flags, CFAbsoluteTime now, 
-        const CredentialSet *inCredentials, 
-        CredentialSet &credentials, AuthorizationToken &auth) const
+RuleImpl::evaluateAuthentication(const AuthItemRef &inRight, const Rule &inRule,AuthItemSet &environmentToClient, AuthorizationFlags flags, CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials, AuthorizationToken &auth) const
 {
 {
-    OSStatus status = errAuthorizationDenied;
-
-    string usernamehint;
-       evaluateSessionOwner(inRight, inRule, environmentToClient, now, auth, usernamehint);
-    if (usernamehint.length())
-               environmentToClient.insert(AuthItemRef(AGENT_HINT_SUGGESTED_USER, AuthValueOverlay(usernamehint)));
+       OSStatus status = errAuthorizationDenied;
+
+       Credential hintCredential;
+       if (errAuthorizationSuccess == evaluateSessionOwner(inRight, inRule, environmentToClient, now, auth, hintCredential)) {
+               if (hintCredential->name().length())
+                       environmentToClient.insert(AuthItemRef(AGENT_HINT_SUGGESTED_USER, AuthValueOverlay(hintCredential->name())));
+               if (hintCredential->realname().length())
+                       environmentToClient.insert(AuthItemRef(AGENT_HINT_SUGGESTED_USER_LONG, AuthValueOverlay(hintCredential->realname())));
+       }
 
 
-    if ((mType == kUser) && (mGroupName.length()))
-        environmentToClient.insert(AuthItemRef(AGENT_HINT_REQUIRE_USER_IN_GROUP, AuthValueOverlay(mGroupName)));
+       if ((mType == kUser) && (mGroupName.length()))
+               environmentToClient.insert(AuthItemRef(AGENT_HINT_REQUIRE_USER_IN_GROUP, AuthValueOverlay(mGroupName)));
 
 
-    uint32 tries;
-    SecurityAgent::Reason reason = SecurityAgent::noReason;
+       uint32 tries;
+       SecurityAgent::Reason reason = SecurityAgent::noReason;
 
        Process &cltProc = Server::process();
 
        Process &cltProc = Server::process();
-    // Authorization preserves creator's UID in setuid processes
-    uid_t cltUid = (cltProc.uid() != 0) ? cltProc.uid() : auth.creatorUid();
-    secdebug("AuthEvalMech", "Mechanism invocation by process %d (UID %d)", cltProc.pid(), cltUid);
+       // Authorization preserves creator's UID in setuid processes
+       uid_t cltUid = (cltProc.uid() != 0) ? cltProc.uid() : auth.creatorUid();
+       secdebug("AuthEvalMech", "Mechanism invocation by process %d (UID %d)", cltProc.pid(), cltUid);
  
  
-    AgentMechanismEvaluator eval(cltUid, auth.session(), mEvalDef);
-        
-    for (tries = 0; tries < mTries; tries++)
-    {
+       AgentMechanismEvaluator eval(cltUid, auth.session(), mEvalDef);
+
+       for (tries = 0; tries < mTries; tries++)
+       {
                AuthItemRef retryHint(AGENT_HINT_RETRY_REASON, AuthValueOverlay(sizeof(reason), &reason));
                environmentToClient.erase(retryHint); environmentToClient.insert(retryHint); // replace
                AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(tries), &tries));
                environmentToClient.erase(triesHint); environmentToClient.insert(triesHint); // replace
 
                AuthItemRef retryHint(AGENT_HINT_RETRY_REASON, AuthValueOverlay(sizeof(reason), &reason));
                environmentToClient.erase(retryHint); environmentToClient.insert(retryHint); // replace
                AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(tries), &tries));
                environmentToClient.erase(triesHint); environmentToClient.insert(triesHint); // replace
 
-        status = eval.run(AuthValueVector(), environmentToClient, auth);
-
-        if ((status == errAuthorizationSuccess) ||
-            (status == errAuthorizationCanceled)) // @@@ can only pass back sideband through context
-        {
-            secdebug("AuthEvalMech", "storing new context for authorization");
-            auth.setInfoSet(eval.context());
-        }
-        
-        // successfully ran mechanisms to obtain credential
-        if (status == errAuthorizationSuccess)
-        {
-            // deny is the default
-            status = errAuthorizationDenied;
-            
-            CredentialSet newCredentials = makeCredentials(auth);
-            // clear context after extracting credentials
-            auth.scrubInfoSet(); 
-            
-            for (CredentialSet::const_iterator it = newCredentials.begin(); it != newCredentials.end(); ++it)
-            {
-                const Credential& newCredential = *it;
+               status = eval.run(AuthValueVector(), environmentToClient, auth);
+
+               if ((status == errAuthorizationSuccess) ||
+                       (status == errAuthorizationCanceled)) // @@@ can only pass back sideband through context
+               {
+                       secdebug("AuthEvalMech", "storing new context for authorization");
+                       auth.setInfoSet(eval.context());
+               }
+
+               // successfully ran mechanisms to obtain credential
+               if (status == errAuthorizationSuccess)
+               {
+                       // deny is the default
+                       status = errAuthorizationDenied;
+                       
+                       CredentialSet newCredentials = makeCredentials(auth);
+                       // clear context after extracting credentials
+                       auth.scrubInfoSet(); 
+                       
+                       CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken());
+                       for (CredentialSet::const_iterator it = newCredentials.begin(); it != newCredentials.end(); ++it)
+                       {
+                               const Credential& newCredential = *it;
 
                                // @@@ we log the uid a process was running under when it created the authref, which is misleading in the case of loginwindow
 
                                // @@@ we log the uid a process was running under when it created the authref, which is misleading in the case of loginwindow
-                               if (newCredential->isValid())
-                                       Syslog::info("uid %lu succeeded authenticating as user %s (uid %lu) for right %s.", auth.creatorUid(), newCredential->username().c_str(), newCredential->uid(), inRight->name());
-                               else
+                               if (newCredential->isValid()) {
+                                       Syslog::info("uid %lu succeeded authenticating as user %s (uid %lu) for right %s.", auth.creatorUid(), newCredential->name().c_str(), newCredential->uid(), inRight->name());
+                                       auditrec.submit(AUE_ssauthint, CommonCriteria::errNone, inRight->name());
+                               } else {
                                        // we can't be sure that the user actually exists so inhibit logging of uid
                                        // we can't be sure that the user actually exists so inhibit logging of uid
-                                       Syslog::error("uid %lu failed to authenticate as user %s for right %s.", auth.creatorUid(), newCredential->username().c_str(), inRight->name());
-                
-                if (!newCredential->isValid())
-                {
-                    reason = SecurityAgent::invalidPassphrase; //invalidPassphrase;
-                    continue;
-                }
-            
-                // verify that this credential authorizes right
-                status = evaluateCredentialForRight(auth, inRight, inRule, environmentToClient, now, newCredential, true);
-
-                if (status == errAuthorizationSuccess)
-                {
-                                       // whack an equivalent credential, so it gets updated to a later achieved credential which must have been more stringent
-                    credentials.erase(newCredential); credentials.insert(newCredential);
-                    // use valid credential to set context info
+                                       Syslog::error("uid %lu failed to authenticate as user %s for right %s.", auth.creatorUid(), newCredential->name().c_str(), inRight->name());
+                                       auditrec.submit(AUE_ssauthint, CommonCriteria::errInvalidCredential, inRight->name());
+                               }
+                               
+                               if (!newCredential->isValid())
+                               {
+                                       reason = SecurityAgent::invalidPassphrase; //invalidPassphrase;
+                                       continue;
+                               }
+
+                               // verify that this credential authorizes right
+                               status = evaluateUserCredentialForRight(auth, inRight, inRule, environmentToClient, now, newCredential, true);
+                               
+                               if (status == errAuthorizationSuccess)
+                               {
+                                       if (auth.operatesAsLeastPrivileged()) {
+                                               Credential rightCredential(inRight->name(), mShared);
+                                               credentials.erase(rightCredential); credentials.insert(rightCredential);
+                                               if (mShared)
+                                                       credentials.insert(Credential(inRight->name(), false));
+                                       } else {
+                                               // whack an equivalent credential, so it gets updated to a later achieved credential which must have been more stringent
+                                               credentials.erase(newCredential); credentials.insert(newCredential);
+                                          // just got a new credential - if it's shared also add a non-shared one that to stick in the authorizationref local cache
+                                          if (mShared)
+                                                          credentials.insert(Credential(newCredential->uid(), newCredential->name(), newCredential->realname(), false));
+                                       }
+                                       
+                                       // use valid credential to set context info
                                        // XXX/cs keeping this for now, such that the uid is passed back
                                        // XXX/cs keeping this for now, such that the uid is passed back
-                    auth.setCredentialInfo(newCredential);
-                    secdebug("SSevalMech", "added valid credential for user %s", newCredential->username().c_str());
-                    status = errAuthorizationSuccess;
-                    break;
-                }
-                else
-                    reason = SecurityAgent::userNotInGroup; //unacceptableUser; // userNotInGroup
-            }
-            
-            if (status == errAuthorizationSuccess)
-                break;
-        }
-        else
-            if ((status == errAuthorizationCanceled) ||
+                                       auth.setCredentialInfo(newCredential);
+                                       secdebug("SSevalMech", "added valid credential for user %s", newCredential->name().c_str());
+                                       status = errAuthorizationSuccess;
+                                       break;
+                               }
+                               else
+                                       reason = SecurityAgent::userNotInGroup; //unacceptableUser; // userNotInGroup
+                       }
+
+                       if (status == errAuthorizationSuccess)
+                               break;
+               }
+               else
+                       if ((status == errAuthorizationCanceled) ||
                (status == errAuthorizationInternal))
                (status == errAuthorizationInternal))
-                {
-                    auth.scrubInfoSet();
-                    break;
-                }
-            else // last mechanism is now authentication - fail
-                if (status == errAuthorizationDenied)
-                    reason = SecurityAgent::invalidPassphrase;
-
-    }
-
-    // If we fell out of the loop because of too many tries, notify user
-    if (tries == mTries)
-    {
-        reason = SecurityAgent::tooManyTries;
+                       {
+                               auth.scrubInfoSet();
+                               break;
+                       }
+                       else // last mechanism is now authentication - fail
+                               if (status == errAuthorizationDenied)
+                                       reason = SecurityAgent::invalidPassphrase;
+}
+
+       // If we fell out of the loop because of too many tries, notify user
+       if (tries == mTries)
+       {
+               reason = SecurityAgent::tooManyTries;
                AuthItemRef retryHint (AGENT_HINT_RETRY_REASON, AuthValueOverlay(sizeof(reason), &reason));
                environmentToClient.erase(retryHint); environmentToClient.insert(retryHint); // replace
                AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(tries), &tries));
                environmentToClient.erase(triesHint); environmentToClient.insert(triesHint); // replace
                AuthItemRef retryHint (AGENT_HINT_RETRY_REASON, AuthValueOverlay(sizeof(reason), &reason));
                environmentToClient.erase(retryHint); environmentToClient.insert(retryHint); // replace
                AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(tries), &tries));
                environmentToClient.erase(triesHint); environmentToClient.insert(triesHint); // replace
-        eval.run(AuthValueVector(), environmentToClient, auth);
-        // XXX/cs is this still necessary?
-        auth.scrubInfoSet();
+               eval.run(AuthValueVector(), environmentToClient, auth);
+               // XXX/cs is this still necessary?
+               auth.scrubInfoSet();
                
                CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken());
                auditrec.submit(AUE_ssauthorize, CommonCriteria::errTooManyTries, inRight->name());
                
                CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken());
                auditrec.submit(AUE_ssauthorize, CommonCriteria::errTooManyTries, inRight->name());
-    }
+       }
 
 
-    return status;
+       return status;
 }
 
 // create externally verified credentials on the basis of 
 }
 
 // create externally verified credentials on the basis of 
@@ -530,114 +534,95 @@ RuleImpl::evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule,
 CredentialSet
 RuleImpl::makeCredentials(const AuthorizationToken &auth) const
 {
 CredentialSet
 RuleImpl::makeCredentials(const AuthorizationToken &auth) const
 {
-    // fetch context and construct a credential to be tested
-    const AuthItemSet &context = const_cast<AuthorizationToken &>(auth).infoSet();
-    CredentialSet newCredentials;
-
-    do {    
-        AuthItemSet::const_iterator found = find_if(context.begin(), context.end(), FindAuthItemByRightName(kAuthorizationEnvironmentUsername) );
-        if (found == context.end())
-            break;
-        string username = (**found).stringValue();
-        secdebug("AuthEvalMech", "found username");
-
-        const uid_t *uid = NULL;
-        found = find_if(context.begin(), context.end(), FindAuthItemByRightName("uid") );
-        if (found != context.end())
-        {
-            uid = static_cast<const uid_t *>((**found).value().data);
-            secdebug("AuthEvalMech", "found uid");
-        }
-
-        const gid_t *gid = NULL;
-        found = find_if(context.begin(), context.end(), FindAuthItemByRightName("gid") );
-        if (found != context.end())
-        {
-            gid = static_cast<const gid_t *>((**found).value().data);
-            secdebug("AuthEvalMech", "found gid");
-        }
-
-        if (username.length() && uid && gid)
-        {
-            // credential is valid because mechanism says so
-            newCredentials.insert(Credential(username, *uid, *gid, mShared));
-        }
-        else
-        {
-            found = find_if(context.begin(), context.end(), FindAuthItemByRightName(kAuthorizationEnvironmentPassword) );
-            if (found != context.end())
-            {
-                secdebug("AuthEvalMech", "found password");
-                string password = (**found).stringValue();
-                secdebug("AuthEvalMech", "falling back on username/password credential if valid");
-                               // Call to checkpw in DS
-                               Server::active().longTermActivity();
-                               Credential newCred(username, password, mShared);
-                newCredentials.insert(newCred);
-                               CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken());
-                               if (newCred->isValid())
-                                       auditrec.submit(AUE_ssauthorize, CommonCriteria::errNone, name().c_str());
-                               else
-                                       auditrec.submit(AUE_ssauthorize, CommonCriteria::errInvalidCredential, name().c_str());
-            }
-        }
-    } while(0);
+       // fetch context and construct a credential to be tested
+       const AuthItemSet &context = const_cast<AuthorizationToken &>(auth).infoSet();
+       CredentialSet newCredentials;
+       
+       do {
+               AuthItemSet::const_iterator found = find_if(context.begin(), context.end(), FindAuthItemByRightName(kAuthorizationEnvironmentUsername) );
+               if (found == context.end())
+                       break;
+               string username = (**found).stringValue();
+               secdebug("AuthEvalMech", "found username");
+               
+               const uid_t *uid = NULL;
+               found = find_if(context.begin(), context.end(), FindAuthItemByRightName("uid") );
+               if (found != context.end())
+               {
+                       uid = static_cast<const uid_t *>((**found).value().data);
+                       secdebug("AuthEvalMech", "found uid");
+               }
+
+               if (username.length() && uid)
+               {
+                       // credential is valid because mechanism says so
+                       newCredentials.insert(Credential(*uid, username, "", mShared));
+               }
+       } while(0);
 
 
-    return newCredentials;
+       return newCredentials;
 }
 
 // evaluate whether a good credential of the current session owner would authorize a right
 OSStatus
 }
 
 // evaluate whether a good credential of the current session owner would authorize a right
 OSStatus
-RuleImpl::evaluateSessionOwner(const AuthItemRef &inRight, const Rule &inRule,
-                           const AuthItemSet &environment,
-                           const CFAbsoluteTime now,
-                           const AuthorizationToken &auth,
-                           string& usernamehint) const
+RuleImpl::evaluateSessionOwner(const AuthItemRef &inRight, const Rule &inRule, const AuthItemSet &environment, const CFAbsoluteTime now, const AuthorizationToken &auth, Credential &credential) const
 {
 {
-    // username hint is taken from the user who created the authorization, unless it's clearly ineligible
-       OSStatus status = noErr;
+       // username hint is taken from the user who created the authorization, unless it's clearly ineligible
        // @@@ we have no access to current requester uid here and the process uid is only taken when the authorization is created
        // meaning that a process like loginwindow that drops privs later is screwed.
        
        uid_t uid;
        Session &session = auth.session();
        // @@@ we have no access to current requester uid here and the process uid is only taken when the authorization is created
        // meaning that a process like loginwindow that drops privs later is screwed.
        
        uid_t uid;
        Session &session = auth.session();
-       
-       if (session.haveOriginatorUid())
-               uid = session.originatorUid();
-       else
+       Credential sessionCredential;
+       if (session.haveOriginatorUid()) {
+               // preflight session credential as if it were a fresh copy
+               const Credential &cred = session.originatorCredential();
+               sessionCredential = Credential(cred->uid(), cred->name(), cred->realname(), mShared/*ignored*/);
+       } else {
                uid = auth.creatorUid();
                uid = auth.creatorUid();
-       
-       Server::active().longTermActivity();
-       struct passwd *pw = getpwuid(uid);
-       if (pw != NULL)
-       {
-               // avoid hinting a locked account
-               if ( (pw->pw_passwd == NULL) ||
+               Server::active().longTermActivity();
+               struct passwd *pw = getpwuid(uid);
+               if (pw != NULL) {
+                       // avoid hinting a locked account
+                       if ( (pw->pw_passwd == NULL) ||
                                strcmp(pw->pw_passwd, "*") ) {
                                strcmp(pw->pw_passwd, "*") ) {
-                       // Check if username will authorize the request and set username to
-                       // be used as a hint to the user if so
-                       secdebug("AuthEvalMech", "preflight credential from current user, result follows:");
-                       status = evaluateCredentialForRight(auth, inRight, inRule, environment, now, Credential(pw->pw_name, pw->pw_uid, pw->pw_gid, mShared), true);
-                       
-                       if (status == errAuthorizationSuccess) 
-                               usernamehint = pw->pw_name;
-               } //fi
-               endpwent();
+                               // Check if username will authorize the request and set username to
+                               // be used as a hint to the user if so
+                               secdebug("AuthEvalMech", "preflight credential from current user, result follows:");
+                               sessionCredential = Credential(pw->pw_uid, pw->pw_name, pw->pw_gecos, mShared/*ignored*/);
+                       } //fi
+                       endpwent();
+               }
        }
        }
+       OSStatus status = evaluateUserCredentialForRight(auth, inRight, inRule, environment, now, sessionCredential, true);
+       if (errAuthorizationSuccess == status)
+               credential = sessionCredential;
+
        return status;
 }
 
 
        return status;
 }
 
 
+OSStatus
+RuleImpl::evaluateCredentialForRight(const AuthorizationToken &auth, const AuthItemRef &inRight, const Rule &inRule, const AuthItemSet &environment, CFAbsoluteTime now, const Credential &credential, bool ignoreShared) const
+{
+       if (auth.operatesAsLeastPrivileged()) {
+               if (credential->isRight() && credential->isValid() && (inRight->name() == credential->name()))
+                       return errAuthorizationSuccess;
+               else
+                       return errAuthorizationDenied;
+       } else
+               return evaluateUserCredentialForRight(auth, inRight, inRule, environment, now, credential, false);
+}
 
 // Return errAuthorizationSuccess if this rule allows access based on the specified credential,
 // return errAuthorizationDenied otherwise.
 OSStatus
 
 // Return errAuthorizationSuccess if this rule allows access based on the specified credential,
 // return errAuthorizationDenied otherwise.
 OSStatus
-RuleImpl::evaluateCredentialForRight(const AuthorizationToken &auth, const AuthItemRef &inRight, const Rule &inRule, const AuthItemSet &environment, CFAbsoluteTime now, const Credential &credential, bool ignoreShared) const
+RuleImpl::evaluateUserCredentialForRight(const AuthorizationToken &auth, const AuthItemRef &inRight, const Rule &inRule, const AuthItemSet &environment, CFAbsoluteTime now, const Credential &credential, bool ignoreShared) const
 {
        assert(mType == kUser);
 
        // Get the username from the credential
 {
        assert(mType == kUser);
 
        // Get the username from the credential
-       const char *user = credential->username().c_str();
+       const char *user = credential->name().c_str();
 
        // If the credential is not valid or it's age is more than the allowed maximum age
        // for a credential, deny.
 
        // If the credential is not valid or it's age is more than the allowed maximum age
        // for a credential, deny.
@@ -666,22 +651,22 @@ RuleImpl::evaluateCredentialForRight(const AuthorizationToken &auth, const AuthI
                return errAuthorizationSuccess;
        }
 
                return errAuthorizationSuccess;
        }
 
-    if (mSessionOwner)
-    {
+       if (mSessionOwner)
+       {
                Session &session = auth.session();
                if (session.haveOriginatorUid())
                {
                        uid_t console_user = session.originatorUid();
 
                Session &session = auth.session();
                if (session.haveOriginatorUid())
                {
                        uid_t console_user = session.originatorUid();
 
-            if (credential->uid() == console_user)
-            {
-                secdebug("autheval", "user %s is session-owner(uid: %d), granting right %s", user, console_user, inRight->name());
-                return errAuthorizationSuccess;
-            }
-        }
-        else
-            secdebug("autheval", "session-owner check failed.");
-    }
+                       if (credential->uid() == console_user)
+                       {
+                               secdebug("autheval", "user %s is session-owner(uid: %d), granting right %s", user, console_user, inRight->name());
+                               return errAuthorizationSuccess;
+                       }
+               }
+               else
+                       secdebug("autheval", "session-owner check failed.");
+       }
        
        if (mGroupName.length())
        {
        
        if (mGroupName.length())
        {
@@ -725,10 +710,7 @@ RuleImpl::evaluateCredentialForRight(const AuthorizationToken &auth, const AuthI
 
 
 OSStatus
 
 
 OSStatus
-RuleImpl::evaluateUser(const AuthItemRef &inRight, const Rule &inRule,
-    AuthItemSet &environmentToClient, AuthorizationFlags flags,
-       CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials,
-       AuthorizationToken &auth) const
+RuleImpl::evaluateUser(const AuthItemRef &inRight, const Rule &inRule, AuthItemSet &environmentToClient, AuthorizationFlags flags, CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials, AuthorizationToken &auth) const
 {
        // If we got here, this is a kUser type rule, let's start looking for a
        // credential that is satisfactory
 {
        // If we got here, this is a kUser type rule, let's start looking for a
        // credential that is satisfactory
@@ -745,8 +727,8 @@ RuleImpl::evaluateUser(const AuthItemRef &inRight, const Rule &inRule,
        // if we're not supposed to authenticate evaluate the session-owner against the group
        if (!mAuthenticateUser)
        {
        // if we're not supposed to authenticate evaluate the session-owner against the group
        if (!mAuthenticateUser)
        {
-               string username;
-               OSStatus status = evaluateSessionOwner(inRight, inRule, environmentToClient, now, auth, username);
+               Credential hintCredential;
+               OSStatus status = evaluateSessionOwner(inRight, inRule, environmentToClient, now, auth, hintCredential);
 
                if (!status)
                        return errAuthorizationSuccess;
 
                if (!status)
                        return errAuthorizationSuccess;
@@ -757,13 +739,28 @@ RuleImpl::evaluateUser(const AuthItemRef &inRight, const Rule &inRule,
        // First -- go though the credentials we either already used or obtained during this authorize operation.
        for (CredentialSet::const_iterator it = credentials.begin(); it != credentials.end(); ++it)
        {
        // First -- go though the credentials we either already used or obtained during this authorize operation.
        for (CredentialSet::const_iterator it = credentials.begin(); it != credentials.end(); ++it)
        {
-               OSStatus status = evaluateCredentialForRight(auth, inRight, inRule, environmentToClient, now, *it, true);
-               if (status != errAuthorizationDenied)
+               // Passed in user credentials are allowed for least privileged mode
+               if (auth.operatesAsLeastPrivileged() && !(*it)->isRight() && (*it)->isValid()) 
                {
                {
+                       OSStatus status = evaluateUserCredentialForRight(auth, inRight, inRule, environmentToClient, now, *it, false);
+                       if (errAuthorizationSuccess == status) {
+                               Credential rightCredential(inRight->name(), mShared);
+                               credentials.erase(rightCredential); credentials.insert(rightCredential);
+                               if (mShared)
+                                       credentials.insert(Credential(inRight->name(), false));
+                               return status;
+                       }
+               }
+
+               // if this is least privileged, this will function differently: match credential to requested right
+               OSStatus status = evaluateCredentialForRight(auth, inRight, inRule, environmentToClient, now, *it, false);
+                       
+               if (status != errAuthorizationDenied) {
                        // add credential to authinfo
                        auth.setCredentialInfo(*it);
                        return status;
                }
                        // add credential to authinfo
                        auth.setCredentialInfo(*it);
                        return status;
                }
+
        }
 
        // Second -- go though the credentials passed in to this authorize operation by the state management layer.
        }
 
        // Second -- go though the credentials passed in to this authorize operation by the state management layer.
@@ -771,14 +768,16 @@ RuleImpl::evaluateUser(const AuthItemRef &inRight, const Rule &inRule,
        {
                for (CredentialSet::const_iterator it = inCredentials->begin(); it != inCredentials->end(); ++it)
                {
        {
                for (CredentialSet::const_iterator it = inCredentials->begin(); it != inCredentials->end(); ++it)
                {
+                       // if this is least privileged, this will function differently: match credential to requested right
                        OSStatus status = evaluateCredentialForRight(auth, inRight, inRule, environmentToClient, now, *it, false);
                        OSStatus status = evaluateCredentialForRight(auth, inRight, inRule, environmentToClient, now, *it, false);
+
                        if (status == errAuthorizationSuccess)
                        {
                                // Add the credential we used to the output set.
                                // whack an equivalent credential, so it gets updated to a later achieved credential which must have been more stringent
                                credentials.erase(*it); credentials.insert(*it);
                        if (status == errAuthorizationSuccess)
                        {
                                // Add the credential we used to the output set.
                                // whack an equivalent credential, so it gets updated to a later achieved credential which must have been more stringent
                                credentials.erase(*it); credentials.insert(*it);
-                // add credential to authinfo
-                auth.setCredentialInfo(*it);
+                               // add credential to authinfo
+                               auth.setCredentialInfo(*it);
 
                                return status;
                        }
 
                                return status;
                        }
@@ -787,8 +786,7 @@ RuleImpl::evaluateUser(const AuthItemRef &inRight, const Rule &inRule,
                }
        }
 
                }
        }
 
-       // Finally -- We didn't find the credential in our passed in credential lists.  Obtain a new credential if
-       // our flags let us do so.
+       // Finally -- We didn't find the credential in our passed in credential lists.  Obtain a new credential if our flags let us do so.
        if (!(flags & kAuthorizationFlagExtendRights))
                return errAuthorizationDenied;
        
        if (!(flags & kAuthorizationFlagExtendRights))
                return errAuthorizationDenied;
        
@@ -805,10 +803,7 @@ RuleImpl::evaluateUser(const AuthItemRef &inRight, const Rule &inRule,
 
        setAgentHints(inRight, inRule, environmentToClient, auth);
 
 
        setAgentHints(inRight, inRule, environmentToClient, auth);
 
-    // If a different evaluation is prescribed,
-    // we'll run that and validate the credentials from there
-    // we fall back on a default configuration
-       return evaluateAuthorization(inRight, inRule, environmentToClient, flags, now, inCredentials, credentials, auth);
+       return evaluateAuthentication(inRight, inRule, environmentToClient, flags, now, inCredentials, credentials, auth);
 }
 
 OSStatus
 }
 
 OSStatus
@@ -818,57 +813,57 @@ RuleImpl::evaluateMechanismOnly(const AuthItemRef &inRight, const Rule &inRule,
        OSStatus status;
 
        Process &cltProc = Server::process();
        OSStatus status;
 
        Process &cltProc = Server::process();
-    // Authorization preserves creator's UID in setuid processes
-    uid_t cltUid = (cltProc.uid() != 0) ? cltProc.uid() : auth.creatorUid();
-    secdebug("AuthEvalMech", "Mechanism invocation by process %d (UID %d)", cltProc.pid(), cltUid);
-
-    {
-        AgentMechanismEvaluator eval(cltUid, auth.session(), mEvalDef);
-        
-        do
-        {
-            setAgentHints(inRight, inRule, environmentToClient, auth);
-            AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(tries), &tries));
-            environmentToClient.erase(triesHint); environmentToClient.insert(triesHint); // replace
-                
-            status = eval.run(AuthValueVector(), environmentToClient, auth);
-            
-            if ((status == errAuthorizationSuccess) ||
-                (status == errAuthorizationCanceled)) // @@@ can only pass back sideband through context
-            {
-                secdebug("AuthEvalMech", "storing new context for authorization");
-                auth.setInfoSet(eval.context());
-                if (status == errAuthorizationSuccess)
-                {
-                    outCredentials = makeCredentials(auth);
-                }
-            }
-                
-            tries++;
-        }
-        while ((status == errAuthorizationDenied) // only if we have an expected failure we continue
-                    && ((mTries == 0)                          // mTries == 0 means we try forever
-                        || ((mTries > 0)                       // mTries > 0 means we try up to mTries times
-                            && (tries < mTries))));
-    }
+       // Authorization preserves creator's UID in setuid processes
+       uid_t cltUid = (cltProc.uid() != 0) ? cltProc.uid() : auth.creatorUid();
+       secdebug("AuthEvalMech", "Mechanism invocation by process %d (UID %d)", cltProc.pid(), cltUid);
+
+       {
+               AgentMechanismEvaluator eval(cltUid, auth.session(), mEvalDef);
+
+               do
+               {
+                       setAgentHints(inRight, inRule, environmentToClient, auth);
+                       AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(tries), &tries));
+                       environmentToClient.erase(triesHint); environmentToClient.insert(triesHint); // replace
+                           
+                       status = eval.run(AuthValueVector(), environmentToClient, auth);
+                       
+                       if ((status == errAuthorizationSuccess) ||
+                               (status == errAuthorizationCanceled)) // @@@ can only pass back sideband through context
+                       {
+                               secdebug("AuthEvalMech", "storing new context for authorization");
+                               auth.setInfoSet(eval.context());
+                               if (status == errAuthorizationSuccess)
+                               {
+                                       if (auth.operatesAsLeastPrivileged())
+                                               outCredentials.insert(Credential(inRight->name(), mShared));
+                                       else
+                                               outCredentials = makeCredentials(auth);
+                               }
+                       }
+
+                       tries++;
+               }
+               while ((status == errAuthorizationDenied) // only if we have an expected failure we continue
+                                       && ((mTries == 0)                               // mTries == 0 means we try forever
+                                       || ((mTries > 0)                        // mTries > 0 means we try up to mTries times
+                                       && (tries < mTries))));
+       }
        
        
-    // HACK kill all hosts to free pages for low memory systems
-       if (name() == "system.login.console")
+       // HACK kill all hosts to free pages for low memory systems
+       if (name() == "system.login.done")
        {
                QueryInvokeMechanism query(securityAgent, auth.session());
                query.terminateAgent();
                QueryInvokeMechanism query2(privilegedAuthHost, auth.session());
                query2.terminateAgent();
        }
        {
                QueryInvokeMechanism query(securityAgent, auth.session());
                query.terminateAgent();
                QueryInvokeMechanism query2(privilegedAuthHost, auth.session());
                query2.terminateAgent();
        }
-    
+
        return status;
 }
 
 OSStatus
        return status;
 }
 
 OSStatus
-RuleImpl::evaluateRules(const AuthItemRef &inRight, const Rule &inRule,
-    AuthItemSet &environmentToClient, AuthorizationFlags flags,
-       CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials,
-       AuthorizationToken &auth) const
+RuleImpl::evaluateRules(const AuthItemRef &inRight, const Rule &inRule, AuthItemSet &environmentToClient, AuthorizationFlags flags, CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials, AuthorizationToken &auth) const
 {
        // line up the rules to try
        if (!mRuleDef.size())
 {
        // line up the rules to try
        if (!mRuleDef.size())
@@ -908,10 +903,7 @@ RuleImpl::evaluateRules(const AuthItemRef &inRight, const Rule &inRule,
 
 
 OSStatus
 
 
 OSStatus
-RuleImpl::evaluate(const AuthItemRef &inRight, const Rule &inRule,
-    AuthItemSet &environmentToClient, AuthorizationFlags flags,
-       CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials,
-       AuthorizationToken &auth) const
+RuleImpl::evaluate(const AuthItemRef &inRight, const Rule &inRule, AuthItemSet &environmentToClient, AuthorizationFlags flags, CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials, AuthorizationToken &auth) const
 {
        switch (mType)
        {
 {
        switch (mType)
        {
@@ -925,15 +917,15 @@ RuleImpl::evaluate(const AuthItemRef &inRight, const Rule &inRule,
                secdebug("autheval", "rule is user");
                return evaluateUser(inRight, inRule, environmentToClient, flags, now, inCredentials, credentials, auth);
        case kRuleDelegation:
                secdebug("autheval", "rule is user");
                return evaluateUser(inRight, inRule, environmentToClient, flags, now, inCredentials, credentials, auth);
        case kRuleDelegation:
-        secdebug("autheval", "rule evaluates rules");
+               secdebug("autheval", "rule evaluates rules");
                return evaluateRules(inRight, inRule, environmentToClient, flags, now, inCredentials, credentials, auth);
        case kKofN:
                return evaluateRules(inRight, inRule, environmentToClient, flags, now, inCredentials, credentials, auth);
        case kKofN:
-        secdebug("autheval", "rule evaluates k-of-n rules");
+               secdebug("autheval", "rule evaluates k-of-n rules");
                return evaluateRules(inRight, inRule, environmentToClient, flags, now, inCredentials, credentials, auth);
                return evaluateRules(inRight, inRule, environmentToClient, flags, now, inCredentials, credentials, auth);
-    case kEvaluateMechanisms:
-        secdebug("autheval", "rule evaluates mechanisms");
-        return evaluateMechanismOnly(inRight, inRule, environmentToClient, auth, credentials);
-    default:
+       case kEvaluateMechanisms:
+               secdebug("autheval", "rule evaluates mechanisms");
+               return evaluateMechanismOnly(inRight, inRule, environmentToClient, auth, credentials);
+       default:
                MacOSError::throwMe(errAuthorizationInternal); // XXX/cs invalid rule
        }
 }
                MacOSError::throwMe(errAuthorizationInternal); // XXX/cs invalid rule
        }
 }
index d83c5a492c4b57e3f90efd89894ea6d47740dc0c..95cf139f115fd01aac457566893efb599ba0f916 100644 (file)
@@ -23,7 +23,6 @@
  *  AuthorizationRule.h
  *  Security
  *
  *  AuthorizationRule.h
  *  Security
  *
- *  Created by Conrad Sauerwald on Wed Mar 19 2003.
  */
 
 #ifndef _H_AUTHORIZATIONRULE
  */
 
 #ifndef _H_AUTHORIZATIONRULE
@@ -57,6 +56,8 @@ private:
        // evaluate credential for right
        OSStatus evaluateCredentialForRight(const AuthorizationToken &auth, const AuthItemRef &inRight, const Rule &inRule, 
                const AuthItemSet &environment, CFAbsoluteTime now, const Credential &credential, bool ignoreShared) const;
        // evaluate credential for right
        OSStatus evaluateCredentialForRight(const AuthorizationToken &auth, const AuthItemRef &inRight, const Rule &inRule, 
                const AuthItemSet &environment, CFAbsoluteTime now, const Credential &credential, bool ignoreShared) const;
+       // evaluate user credential (authentication) for right
+       OSStatus evaluateUserCredentialForRight(const AuthorizationToken &auth, const AuthItemRef &inRight, const Rule &inRule, const AuthItemSet &environment, CFAbsoluteTime now, const Credential &credential, bool ignoreShared) const;
 
        OSStatus evaluateRules(const AuthItemRef &inRight, const Rule &inRule,
     AuthItemSet &environmentToClient, AuthorizationFlags flags,
 
        OSStatus evaluateRules(const AuthItemRef &inRight, const Rule &inRule,
     AuthItemSet &environmentToClient, AuthorizationFlags flags,
@@ -66,7 +67,7 @@ private:
        void setAgentHints(const AuthItemRef &inRight, const Rule &inTopLevelRule, AuthItemSet &environmentToClient, AuthorizationToken &auth) const;
 
        // perform authorization based on running specified mechanisms (see evaluateMechanism)
        void setAgentHints(const AuthItemRef &inRight, const Rule &inTopLevelRule, AuthItemSet &environmentToClient, AuthorizationToken &auth) const;
 
        // perform authorization based on running specified mechanisms (see evaluateMechanism)
-       OSStatus evaluateAuthorization(const AuthItemRef &inRight, const Rule &inRule, AuthItemSet &environmentToClient, AuthorizationFlags flags, CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials, AuthorizationToken &auth) const;
+       OSStatus evaluateAuthentication(const AuthItemRef &inRight, const Rule &inRule, AuthItemSet &environmentToClient, AuthorizationFlags flags, CFAbsoluteTime now, const CredentialSet *inCredentials, CredentialSet &credentials, AuthorizationToken &auth) const;
 
        OSStatus evaluateUser(const AuthItemRef &inRight, const Rule &inRule,
                AuthItemSet &environmentToClient, AuthorizationFlags flags,
 
        OSStatus evaluateUser(const AuthItemRef &inRight, const Rule &inRule,
                AuthItemSet &environmentToClient, AuthorizationFlags flags,
@@ -76,7 +77,7 @@ private:
        OSStatus evaluateMechanismOnly(const AuthItemRef &inRight, const Rule &inRule, AuthItemSet &environmentToClient, AuthorizationToken &auth, CredentialSet &outCredentials) const;
 
        // find username hint based on session owner
        OSStatus evaluateMechanismOnly(const AuthItemRef &inRight, const Rule &inRule, AuthItemSet &environmentToClient, AuthorizationToken &auth, CredentialSet &outCredentials) const;
 
        // find username hint based on session owner
-       OSStatus evaluateSessionOwner(const AuthItemRef &inRight, const Rule &inRule, const AuthItemSet &environment, const CFAbsoluteTime now, const AuthorizationToken &auth, string& usernamehint) const;
+       OSStatus evaluateSessionOwner(const AuthItemRef &inRight, const Rule &inRule, const AuthItemSet &environment, const CFAbsoluteTime now, const AuthorizationToken &auth, Credential &credential) const;
 
        CredentialSet makeCredentials(const AuthorizationToken &auth) const;
        
 
        CredentialSet makeCredentials(const AuthorizationToken &auth) const;
        
diff --git a/src/SharedMemoryServer.cpp b/src/SharedMemoryServer.cpp
new file mode 100644 (file)
index 0000000..46bc1dc
--- /dev/null
@@ -0,0 +1,150 @@
+#include "SharedMemoryServer.h"
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <machine/byte_order.h>
+
+
+SharedMemoryServer::SharedMemoryServer (const char* segmentName, SegmentOffsetType segmentSize) :
+       mSegmentName (segmentName), mSegmentSize (segmentSize)
+{
+       // open the file
+       int segmentDescriptor = shm_open (segmentName, O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
+       if (segmentDescriptor < 0)
+       {
+               return;
+       }
+       
+       // set the segment size
+       ftruncate (segmentDescriptor, segmentSize);
+       
+       // map it into memory
+       mSegment = (u_int8_t*) mmap (NULL, mSegmentSize, PROT_READ | PROT_WRITE, MAP_SHARED, segmentDescriptor, 0);
+       close (segmentDescriptor);
+
+       if (mSegment == (u_int8_t*) -1) // can't map the memory?
+       {
+               mSegment = NULL;
+               shm_unlink (segmentName);
+       }
+       
+       SetProducerCount (0);
+}
+
+
+
+SharedMemoryServer::~SharedMemoryServer ()
+{
+       // go away
+       if (mSegment == NULL)
+       {
+               return;
+       }
+       
+       // get out of memory
+       munmap (mSegment, mSegmentSize);
+       
+       // mark the segment for deletion
+       shm_unlink (mSegmentName.c_str ());
+}
+
+
+
+const SegmentOffsetType
+       kSegmentLength = 0,
+       kDomainOffset = kSegmentLength + sizeof (SegmentOffsetType),
+       kEventTypeOffset = kDomainOffset + sizeof (SegmentOffsetType),
+       kHeaderLength = kEventTypeOffset + sizeof (SegmentOffsetType);
+
+void SharedMemoryServer::WriteMessage (SegmentOffsetType domain, SegmentOffsetType event, const void *message, SegmentOffsetType messageLength)
+{
+       // get the current producer count
+       SegmentOffsetType pCount = GetProducerCount ();
+       
+       SegmentOffsetType actualLength = messageLength + kHeaderLength;
+
+       // for now, write a 0 for the length -- this will give clients the opportunity to not process an
+       // incomplete message
+       WriteOffsetAtOffset (pCount, 0);
+       
+       // extend the overall write count by enough data to hold the message length and message
+       SetProducerCount (pCount + actualLength);
+       
+       // write the data
+       WriteDataAtOffset (pCount + kHeaderLength, message, messageLength);
+       
+       // write the domain
+       WriteOffsetAtOffset (pCount + kDomainOffset, domain);
+       
+       // write the event type
+       WriteOffsetAtOffset (pCount + kEventTypeOffset, event);
+
+       // write the data count
+       WriteOffsetAtOffset (pCount, actualLength);
+}
+
+
+
+const char* SharedMemoryServer::GetSegmentName ()
+{
+       return mSegmentName.c_str ();
+}
+
+
+
+size_t SharedMemoryServer::GetSegmentSize ()
+{
+       return mSegmentSize;
+}
+
+
+
+SegmentOffsetType SharedMemoryServer::GetProducerCount ()
+{
+       // the data is stored in the buffer in network byte order
+       u_int32_t pCount = *(u_int32_t*) mSegment;
+       return OSSwapHostToBigInt32 (pCount);
+}
+
+
+
+void SharedMemoryServer::SetProducerCount (SegmentOffsetType producerCount)
+{
+       *((u_int32_t*) mSegment) = OSSwapHostToBigInt32 (producerCount);
+}
+
+
+
+void SharedMemoryServer::WriteOffsetAtOffset (SegmentOffsetType offset, SegmentOffsetType data)
+{
+       // convert data to network byte order
+       u_int8_t buffer[4];
+       *((u_int32_t*) buffer) = OSSwapHostToBigInt32 (data);
+       
+       WriteDataAtOffset (offset, buffer, sizeof (buffer));
+}
+
+
+
+void SharedMemoryServer::WriteDataAtOffset (SegmentOffsetType offset, const void* data, SegmentOffsetType length)
+{
+       // figure out where in the buffer we actually need to write the data
+       SegmentOffsetType realOffset = offset % kPoolAvailableForData;
+       
+       // figure out how many bytes we can write without overflowing the buffer
+       SegmentOffsetType bytesToEnd = kPoolAvailableForData - realOffset;
+       
+       // figure out how many bytes we can write
+       SegmentOffsetType bytesToWrite = bytesToEnd < length ? bytesToEnd : length;
+       
+       // move the first part of the data, making sure to skip the producer pointer
+       memmove (mSegment + sizeof (SegmentOffsetType) + realOffset, data, bytesToWrite);
+       
+       // deduct the bytes just written
+       length -= bytesToWrite;
+       
+       if (length != 0) // did we wrap around?
+       {
+               memmove (mSegment + sizeof (SegmentOffsetType), ((u_int8_t*) data) + bytesToWrite, length);
+       }
+}
diff --git a/src/SharedMemoryServer.h b/src/SharedMemoryServer.h
new file mode 100644 (file)
index 0000000..27958a4
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef __SHARED_MEMORY_SERVER__
+#define __SHARED_MEMORY_SERVER__
+
+
+
+#include <string>
+#include <stdlib.h>
+#include <securityd_client/SharedMemoryCommon.h>
+
+class SharedMemoryServer
+{
+protected:
+       std::string mSegmentName;
+       size_t mSegmentSize;
+       
+       u_int8_t* mSegment;
+
+       void WriteOffsetAtOffset (SegmentOffsetType offset, SegmentOffsetType data);
+       void WriteDataAtOffset (SegmentOffsetType offset, const void* data, SegmentOffsetType length);
+
+public:
+       SharedMemoryServer (const char* segmentName, SegmentOffsetType segmentSize);
+       virtual ~SharedMemoryServer ();
+       
+       void WriteMessage (SegmentOffsetType domain, SegmentOffsetType event, const void *message, SegmentOffsetType messageLength);
+       
+       const char* GetSegmentName ();
+       size_t GetSegmentSize ();
+       
+       SegmentOffsetType GetProducerCount ();
+       void SetProducerCount (SegmentOffsetType producerCount);
+};
+
+
+
+#endif
index 6ac8eb7144e28a74c66a59ad768edca094500488..aa7b18b4a8aec3cb326c0a4d99831fad58ccdd7d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004,2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
 // On-disk (flattened) representation:
 // In order to accommodate legacy formats nicely, we use the binary-versioning feature
 // of the ACL machinery. Version 0 is the legacy format (storing only the description
 // On-disk (flattened) representation:
 // In order to accommodate legacy formats nicely, we use the binary-versioning feature
 // of the ACL machinery. Version 0 is the legacy format (storing only the description
-// string), while Version 1 contains both selector and description. To allow for
-// maximum backward compatibility, legacy-compatible forms are written out as version 0.
-// See isLegacyCompatible().
-//
-// Some notes on Acl Update Triggers:
-// When the user checks the "don't ask me again" checkbox in the access confirmation
-// dialog, we respond by returning the informational error code
-// CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT, and setting a count-down trigger
-// in the connection. The caller is entitled to bypass our dialog (it succeeds
-// automatically) within the next few (Connection::aclUpdateTriggerLimit == 3)
-// requests, in order to update the object's ACL as requested. It must then retry
-// the original access operation (which will presumably pass because of that edit).
-// These are the rules: for the trigger to apply, the access must be to the same
-// object, from the same connection, and within the next aclUpdateTriggerLimit accesses.
-// (Currently, these are for a "get acl", "get owner", and the "change acl" calls.)
-// Damage Control Department: The worst this mechanism could do, if subverted, is
-// to bypass our confirmation dialog (making it appear to succeed to the ACL validation).
-// But that is exactly what the "don't ask me again" checkbox is meant to do, so any
-// subversion would be based on a (perhaps intentional) miscommunication between user 
-// and client process as to what the user consents not to be asked about (any more).
-// The user can always examine the resulting ACL (in Keychain Access or elsewhere), and
-// edit it to suit her needs.
+// string), while Version 1 contains both selector and description. We are now always
+// writing version-1 data, but will continue to recognize version-0 data indefinitely
+// for really, really old keychain items.
 //
 #include "acl_keychain.h"
 #include "agentquery.h"
 //
 #include "acl_keychain.h"
 #include "agentquery.h"
 #include "connection.h"
 #include "database.h"
 #include "server.h"
 #include "connection.h"
 #include "database.h"
 #include "server.h"
+#include "osxcodewrap.h"
 #include <security_utilities/debugging.h>
 #include <security_utilities/debugging.h>
+#include <security_utilities/logging.h>
+#include <security_cdsa_utilities/osxverifier.h>
 #include <algorithm>
 
 
 #define ACCEPT_LEGACY_FORM 1
 #include <algorithm>
 
 
 #define ACCEPT_LEGACY_FORM 1
-#define FECKLESS_KEYCHAIN_ACCESS_EXCEPTION 1
 
 
 //
 
 
 //
@@ -90,42 +73,76 @@ bool KeychainPromptAclSubject::validate(const AclValidationContext &context,
     const TypedList &sample) const
 {
     if (SecurityServerEnvironment *env = context.environment<SecurityServerEnvironment>()) {
     const TypedList &sample) const
 {
     if (SecurityServerEnvironment *env = context.environment<SecurityServerEnvironment>()) {
-               // check for special ACL-update override
-               if (context.authorization() == CSSM_ACL_AUTHORIZATION_CHANGE_ACL
-                               && Server::connection().aclWasSetForUpdateTrigger(env->acl)) {
-                       secdebug("kcacl", "honoring acl update trigger for %p(%s)", 
-                &env->acl, description.c_str());
-                       return true;
+               Process &process = Server::process();
+               secdebug("kcacl", "Keychain query for process %d (UID %d)", process.pid(), process.uid());
+
+               // assemble the effective validity mode mask
+               uint32_t mode = Maker::defaultMode;
+               const uint16_t &flags = selector.flags;
+               if (flags & CSSM_ACL_KEYCHAIN_PROMPT_UNSIGNED_ACT)
+                       mode = (mode & ~CSSM_ACL_KEYCHAIN_PROMPT_UNSIGNED) | (flags & CSSM_ACL_KEYCHAIN_PROMPT_UNSIGNED);
+               if (flags & CSSM_ACL_KEYCHAIN_PROMPT_INVALID_ACT)
+                       mode = (mode & ~CSSM_ACL_KEYCHAIN_PROMPT_INVALID) | (flags & CSSM_ACL_KEYCHAIN_PROMPT_INVALID);
+               
+               // determine signed/validity status of client, without reference to any particular Code Requirement
+               SecCodeRef clientCode = process.currentGuest();
+               Server::active().longTermActivity();
+               OSStatus validation = clientCode ? SecCodeCheckValidity(clientCode, kSecCSDefaultFlags, NULL) : errSecCSStaticCodeNotFound;
+               switch (validation) {
+               case noErr:                                                     // client is signed and valid
+                       secdebug("kcacl", "client is valid, proceeding");
+                       break;
+               case errSecCSUnsigned:                          // client is not signed
+                       if (!(mode & CSSM_ACL_KEYCHAIN_PROMPT_UNSIGNED)) {
+                               secdebug("kcacl", "client is unsigned, suppressing prompt");
+                               return false;
+                       }
+                       break;
+               case errSecCSSignatureFailed:           // client signed but signature is broken
+               case errSecCSGuestInvalid:                      // client signed but dynamically invalid
+               case errSecCSStaticCodeNotFound:        // client not on disk (or unreadable)
+                       if (!(mode & CSSM_ACL_KEYCHAIN_PROMPT_INVALID)) {
+                               secdebug("kcacl", "client is invalid, suppressing prompt");
+                               Syslog::info("suppressing keychain prompt for invalidly signed client %s(%d)",
+                                       process.getPath().c_str(), process.pid());
+                               return false;
+                       }
+                       Syslog::info("attempting keychain prompt for invalidly signed client %s(%d)",
+                               process.getPath().c_str(), process.pid());
+                       break;
+               default:                                                        // something else went wrong
+                       secdebug("kcacl", "client validation failed rc=%ld, suppressing prompt", validation);
+                       return false;
                }
                
                }
                
+               // At this point, we're committed to try to Pop The Question. Now, how?
+               
                // does the user need to type in the passphrase?
         const Database *db = env->database;
         bool needPassphrase = db && (selector.flags & CSSM_ACL_KEYCHAIN_PROMPT_REQUIRE_PASSPHRASE);
 
                // does the user need to type in the passphrase?
         const Database *db = env->database;
         bool needPassphrase = db && (selector.flags & CSSM_ACL_KEYCHAIN_PROMPT_REQUIRE_PASSPHRASE);
 
-               // ask the user
-#if FECKLESS_KEYCHAIN_ACCESS_EXCEPTION
-               Process &process = Server::process();
-               secdebug("kcacl", "Keychain query from process %d (UID %d)", process.pid(), process.uid());
-               if (process.clientCode())
-                       needPassphrase |=
-                               process.clientCode()->canonicalPath() == "/Applications/Utilities/Keychain Access.app";
-#endif
+               // an application (i.e. Keychain Access.app :-) can force this option
+               if (clientCode) {
+                       CFRef<CFDictionaryRef> dict;
+                       if (!SecCodeCopySigningInformation(clientCode, kSecCSDefaultFlags, &dict.aref()))
+                               if (CFDictionaryRef info = CFDictionaryRef(CFDictionaryGetValue(dict, kSecCodeInfoPList)))
+                                       needPassphrase |=
+                                               (CFDictionaryGetValue(info, CFSTR("SecForcePassphrasePrompt")) != NULL);
+               }
+
+               // pop The Question
                QueryKeychainUse query(needPassphrase, db);
         query.inferHints(Server::process());
                QueryKeychainUse query(needPassphrase, db);
         query.inferHints(Server::process());
-               
+               query.addHint(AGENT_HINT_CLIENT_VALIDITY, &validation, sizeof(validation));
         if (query.queryUser(db ? db->dbName() : NULL, 
         if (query.queryUser(db ? db->dbName() : NULL, 
-                            description.c_str(), context.authorization())
-            != SecurityAgent::noReason)
-                return false;
+                       description.c_str(), context.authorization()) != SecurityAgent::noReason)
+                       return false;
 
 
-               // process "always allow..." response
-               if (query.remember) {
-                       // mark for special ACL-update override (really soon) later
-                       Server::connection().setAclUpdateTrigger(env->acl);
-                       secdebug("kcacl", "setting acl update trigger for %p(%s)", 
-                               &env->acl, description.c_str());
-                       // fail with prejudice (caller will retry)
-                       CssmError::throwMe(CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT);
+               // process an "always allow..." response
+               if (query.remember && clientCode) {
+                       RefPointer<OSXCode> clientXCode = new OSXCodeWrap(clientCode);
+                       RefPointer<AclSubject> subject = new CodeSignatureAclSubject(OSXVerifier(clientXCode));
+                       SecurityServerAcl::addToStandardACL(context, subject);
                }
 
                // finally, return the actual user response
                }
 
                // finally, return the actual user response
@@ -150,6 +167,8 @@ CssmList KeychainPromptAclSubject::toList(Allocator &alloc) const
 //
 // Create a KeychainPromptAclSubject
 //
 //
 // Create a KeychainPromptAclSubject
 //
+uint32_t KeychainPromptAclSubject::Maker::defaultMode;
+
 KeychainPromptAclSubject *KeychainPromptAclSubject::Maker::make(const TypedList &list) const
 {
        switch (list.length()) {
 KeychainPromptAclSubject *KeychainPromptAclSubject::Maker::make(const TypedList &list) const
 {
        switch (list.length()) {
@@ -189,6 +208,8 @@ KeychainPromptAclSubject *KeychainPromptAclSubject::Maker::make(Version version,
                selector.flags = n2h(selector.flags);
                pub(description);
                break;
                selector.flags = n2h(selector.flags);
                pub(description);
                break;
+       default:
+               CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
        }
        return new KeychainPromptAclSubject(description, selector);
 }
        }
        return new KeychainPromptAclSubject(description, selector);
 }
@@ -202,11 +223,8 @@ KeychainPromptAclSubject::KeychainPromptAclSubject(string descr,
        if (selector.version != CSSM_ACL_KEYCHAIN_PROMPT_CURRENT_VERSION)
                CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
 
        if (selector.version != CSSM_ACL_KEYCHAIN_PROMPT_CURRENT_VERSION)
                CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
 
-       // determine binary compatibility version
-       if (selector.flags == 0)        // compatible with old form
-               version(pumaVersion);
-       else
-               version(jaguarVersion);
+       // always use the latest binary version
+       version(currentVersion);
 }
 
 
 }
 
 
@@ -235,16 +253,6 @@ void KeychainPromptAclSubject::exportBlob(Writer &pub, Writer &priv)
 }
 
 
 }
 
 
-//
-// Determine whether this ACL subject is in "legacy compatible" form.
-// Legacy (<10.2) form contained no selector.
-//
-bool KeychainPromptAclSubject::isLegacyCompatible() const
-{
-       return selector.flags == 0;
-}
-
-
 #ifdef DEBUGDUMP
 
 void KeychainPromptAclSubject::debugDump() const
 #ifdef DEBUGDUMP
 
 void KeychainPromptAclSubject::debugDump() const
index bbdec1a23661bc6d8169b9f6606c59041293d995..bfca5ef8f14de6a262ff80b8ed8d21556b0dfabb 100644 (file)
@@ -40,6 +40,7 @@
 class KeychainPromptAclSubject : public SimpleAclSubject {
        static const Version pumaVersion = 0;   // 10.0, 10.1 -> default selector (not stored)
        static const Version jaguarVersion = 1; // 10.2 et al -> first version selector
 class KeychainPromptAclSubject : public SimpleAclSubject {
        static const Version pumaVersion = 0;   // 10.0, 10.1 -> default selector (not stored)
        static const Version jaguarVersion = 1; // 10.2 et al -> first version selector
+       static const Version currentVersion = jaguarVersion; // what we write today
 public:
     bool validate(const AclValidationContext &baseCtx, const TypedList &sample) const;
     CssmList toList(Allocator &alloc) const;
 public:
     bool validate(const AclValidationContext &baseCtx, const TypedList &sample) const;
     CssmList toList(Allocator &alloc) const;
@@ -49,14 +50,22 @@ public:
     void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
     void exportBlob(Writer &pub, Writer &priv);
        
     void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
     void exportBlob(Writer &pub, Writer &priv);
        
+       uint32_t selectorFlags() const                  { return selector.flags; }
+       bool selectorFlag(uint32_t flag) const  { return selectorFlags() & flag; }
+       
        IFDUMP(void debugDump() const);
 
        IFDUMP(void debugDump() const);
 
+public:
     class Maker : public AclSubject::Maker {
     class Maker : public AclSubject::Maker {
+               friend class KeychainPromptAclSubject;
     public:
     public:
-       Maker(CSSM_ACL_SUBJECT_TYPE type = CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT)
-                       : AclSubject::Maker(type) { }
+       Maker(uint32_t mode)
+                       : AclSubject::Maker(CSSM_ACL_SUBJECT_TYPE_KEYCHAIN_PROMPT) { defaultMode = mode; }
        KeychainPromptAclSubject *make(const TypedList &list) const;
        KeychainPromptAclSubject *make(Version version, Reader &pub, Reader &priv) const;
        KeychainPromptAclSubject *make(const TypedList &list) const;
        KeychainPromptAclSubject *make(Version version, Reader &pub, Reader &priv) const;
+       
+       private:
+               static uint32_t defaultMode;
     };
     
 private:
     };
     
 private:
@@ -65,11 +74,6 @@ private:
        
 private:
        static CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR defaultSelector;
        
 private:
        static CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR defaultSelector;
-       
-       typedef uint32 VersionMarker;
-       static const VersionMarker currentVersion = 0x3BD5910D;
-       
-       bool isLegacyCompatible() const;
 };
 
 
 };
 
 
index aa2524a21ac71e91e597864bd4acaa07c6c44dd1..a366b9de9b8eecb7bc9c39aaf53b98a03970d314 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -30,6 +30,7 @@
 #include "server.h"
 #include "agentquery.h"
 #include "tokendatabase.h"
 #include "server.h"
 #include "agentquery.h"
 #include "tokendatabase.h"
+#include "acl_keychain.h"
 
 // ACL subjects whose Environments we implement
 #include <security_cdsa_utilities/acl_any.h>
 
 // ACL subjects whose Environments we implement
 #include <security_cdsa_utilities/acl_any.h>
@@ -53,17 +54,20 @@ SecurityServerAcl::~SecurityServerAcl()
 //
 void SecurityServerAcl::getOwner(AclOwnerPrototype &owner)
 {
 //
 void SecurityServerAcl::getOwner(AclOwnerPrototype &owner)
 {
+       StLock<Mutex> _(aclSequence);
        ObjectAcl::cssmGetOwner(owner);
 }
 
 void SecurityServerAcl::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
 {
        ObjectAcl::cssmGetOwner(owner);
 }
 
 void SecurityServerAcl::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
 {
+       StLock<Mutex> _(aclSequence);
        ObjectAcl::cssmGetAcl(tag, count, acls);
 }
 
 void SecurityServerAcl::changeAcl(const AclEdit &edit, const AccessCredentials *cred,
        Database *db)
 {
        ObjectAcl::cssmGetAcl(tag, count, acls);
 }
 
 void SecurityServerAcl::changeAcl(const AclEdit &edit, const AccessCredentials *cred,
        Database *db)
 {
+       StLock<Mutex> _(aclSequence);
        SecurityServerEnvironment env(*this, db);
        ObjectAcl::cssmChangeAcl(edit, cred, &env);
 }
        SecurityServerEnvironment env(*this, db);
        ObjectAcl::cssmChangeAcl(edit, cred, &env);
 }
@@ -71,6 +75,7 @@ void SecurityServerAcl::changeAcl(const AclEdit &edit, const AccessCredentials *
 void SecurityServerAcl::changeOwner(const AclOwnerPrototype &newOwner,
        const AccessCredentials *cred, Database *db)
 {
 void SecurityServerAcl::changeOwner(const AclOwnerPrototype &newOwner,
        const AccessCredentials *cred, Database *db)
 {
+       StLock<Mutex> _(aclSequence);
        SecurityServerEnvironment env(*this, db);
        ObjectAcl::cssmChangeOwner(newOwner, cred, &env);
 }
        SecurityServerEnvironment env(*this, db);
        ObjectAcl::cssmChangeOwner(newOwner, cred, &env);
 }
@@ -94,6 +99,91 @@ void SecurityServerAcl::validate(AclAuthorization auth, const Context &context,
 }
 
 
 }
 
 
+//
+// This helper tries to add the (new) subject given to the ACL
+// whose validation is currently proceeding through context.
+// This will succeed if the ACL is in standard form, which means
+// a ThresholdAclSubject.
+// The new subject will be added at the front (so it is checked first
+// from now on), and as a side effect we'll notify the client side to
+// re-encode the object.
+// Returns true if the edit could be done, or false if the ACL wasn't
+// standard enough. May throw if the ACL is malformed or otherwise messed up.
+//
+// This is a self-contained helper that is here merely because it's "about"
+// ACLs and has no better home.
+//
+bool SecurityServerAcl::addToStandardACL(const AclValidationContext &context, AclSubject *subject)
+{
+       if (SecurityServerEnvironment *env = context.environment<SecurityServerEnvironment>())
+               if (ThresholdAclSubject *threshold = env->standardSubject(context)) {
+                       unsigned size = threshold->count();
+                       if (dynamic_cast<KeychainPromptAclSubject *>(threshold->subject(size-1))) {
+                               // looks standard enough
+                               secdebug("acl", "adding new subject %p to from of threshold ACL", subject);
+                               threshold->add(subject, 0);
+                               
+                               // tell the ACL it's been modified
+                               context.acl()->changedAcl();
+
+                               // trigger a special notification code on (otherwise successful) return
+                               Server::connection().overrideReturn(CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT);
+                               return true;
+                       }
+               }
+       secdebug("acl", "ACL is not standard form; cannot edit");
+       return false;
+}
+
+
+//
+// Look at the ACL whose validation is currently proceeding through context.
+// If it LOOKS like a plausible version of a legacy "dot mac item" ACL.
+// We don't have access to the database attributes of the item up here in the
+// securityd sky, so we have to apply a heuristic based on which applications (by path)
+// are given access to the item.
+// So this is strictly a heuristic. The potential downside is that we may inadvertently
+// give access to new .Mac authorized Apple (only) applications when the user only intended
+// a limited set of extremely popular Apple (only) applications that just happen to all be
+// .Mac authorized today. We can live with that.
+//
+bool SecurityServerAcl::looksLikeLegacyDotMac(const AclValidationContext &context)
+{
+       static const char * const prototypicalDotMacPath[] = {
+               "/Applications/Mail.app",
+               "/Applications/Safari.app",
+               "/Applications/iSync.app",
+               "/Applications/System Preferences.app",
+               "/Applications/iCal.app",
+               "/Applications/iChat.app",
+               "/Applications/iTunes.app",
+               "/Applications/Address Book.app",
+               "/Applications/iSync.app",
+               NULL    // sentinel
+       };
+       
+       static const unsigned threshold = 6;
+       
+       if (SecurityServerEnvironment *env = context.environment<SecurityServerEnvironment>()) {
+               if (ThresholdAclSubject *list = env->standardSubject(context)) {
+                       unsigned count = list->count();
+                       unsigned matches = 0;
+                       for (unsigned n = 0; n < count; ++n) {
+                               if (CodeSignatureAclSubject *app = dynamic_cast<CodeSignatureAclSubject *>(list->subject(n))) {
+                                       for (const char * const *p = prototypicalDotMacPath; *p; p++)
+                                               if (app->path() == *p)
+                                                       matches++;
+                               }
+                       }
+                       secdebug("codesign", "matched %d of %zd candididates (threshold=%d)",
+                               matches, sizeof(prototypicalDotMacPath) / sizeof(char *) - 1, threshold);
+                       return matches >= threshold;
+               }
+       }
+       return false;
+}
+
+
 //
 // External storage interface
 //
 //
 // External storage interface
 //
@@ -135,10 +225,10 @@ pid_t SecurityServerEnvironment::getpid() const
 //
 // CodeSignatureAclSubject personality: take code signature from active Process object
 //
 //
 // CodeSignatureAclSubject personality: take code signature from active Process object
 //
-bool SecurityServerEnvironment::verifyCodeSignature(const CodeSigning::Signature *signature,
-       const CssmData *comment)
+bool SecurityServerEnvironment::verifyCodeSignature(const OSXVerifier &verifier,
+       const AclValidationContext &context)
 {
 {
-       return Server::codeSignatures().verify(Server::process(), signature, comment);
+       return Server::codeSignatures().verify(Server::process(), verifier, context);
 }
 
 
 }
 
 
@@ -184,6 +274,15 @@ ObjectAcl *SecurityServerEnvironment::preAuthSource()
 }
 
 
 }
 
 
+//
+// Autonomous ACL editing support
+//
+ThresholdAclSubject *SecurityServerEnvironment::standardSubject(const AclValidationContext &context)
+{
+       return dynamic_cast<ThresholdAclSubject *>(context.subject());
+}
+
+
 //
 // The default AclSource denies having an ACL at all
 //
 //
 // The default AclSource denies having an ACL at all
 //
index ed8338b9acc6f973b56f2573b4d7cf38a1c76fd3..20f9270fc5e17e13df76deefff6afda7ca8ac1ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2001,2003-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2001,2003-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -45,6 +45,7 @@
 #include <security_cdsa_utilities/acl_secret.h>
 #include <security_cdsa_utilities/acl_preauth.h>
 #include <security_cdsa_utilities/acl_prompted.h>
 #include <security_cdsa_utilities/acl_secret.h>
 #include <security_cdsa_utilities/acl_preauth.h>
 #include <security_cdsa_utilities/acl_prompted.h>
+#include <security_cdsa_utilities/acl_threshold.h>
 
 using namespace SecurityServer;
 
 
 using namespace SecurityServer;
 
@@ -58,11 +59,11 @@ class Database;
 //
 class SecurityServerAcl : public ObjectAcl {
 public:
 //
 class SecurityServerAcl : public ObjectAcl {
 public:
-       SecurityServerAcl() : ObjectAcl(Allocator::standard()) { }
+       SecurityServerAcl() : ObjectAcl(Allocator::standard()), aclSequence(Mutex::recursive) { }
        virtual ~SecurityServerAcl();
 
     // validation calls restated
        virtual ~SecurityServerAcl();
 
     // validation calls restated
-   virtual void validate(AclAuthorization auth, const AccessCredentials *cred, Database *relatedDatabase);
+       virtual void validate(AclAuthorization auth, const AccessCredentials *cred, Database *relatedDatabase);
        void validate(AclAuthorization auth, const Context &context, Database *relatedDatabase);
 
        // CSSM layer ACL calls
        void validate(AclAuthorization auth, const Context &context, Database *relatedDatabase);
 
        // CSSM layer ACL calls
@@ -76,6 +77,10 @@ public:
        // to be provided by implementations
        virtual AclKind aclKind() const = 0;
        
        // to be provided by implementations
        virtual AclKind aclKind() const = 0;
        
+       // a helper to (try to) add an ACL to a "standard form" item ACL
+       static bool addToStandardACL(const AclValidationContext &context, AclSubject *subject);
+       static bool looksLikeLegacyDotMac(const AclValidationContext &context);
+
        // aclSequence is taken to serialize ACL validations to pick up mutual changes
        Mutex aclSequence;
 };
        // aclSequence is taken to serialize ACL validations to pick up mutual changes
        Mutex aclSequence;
 };
@@ -83,9 +88,8 @@ public:
 
 //
 // Our implementation of an ACL validation environment uses information
 
 //
 // Our implementation of an ACL validation environment uses information
-// derived from a Connection object. It implements context for
-// -- ProcessAclSubjects (getuid/getgid)
-// -- KeychainPromptAclSubjects (connection link)
+// derived from a Connection object. It implements context for a fair number
+// of subject types (see the inheritance list below).
 //
 class SecurityServerEnvironment : public virtual AclValidationEnvironment,
     public virtual ProcessAclSubject::Environment,
 //
 class SecurityServerEnvironment : public virtual AclValidationEnvironment,
     public virtual ProcessAclSubject::Environment,
@@ -100,14 +104,18 @@ public:
        SecurityServerAcl &acl;
        Database * const database;
     
        SecurityServerAcl &acl;
        Database * const database;
     
+       // personalities
     uid_t getuid() const;
     gid_t getgid() const;
        pid_t getpid() const;
     uid_t getuid() const;
     gid_t getgid() const;
        pid_t getpid() const;
-       bool verifyCodeSignature(const CodeSigning::Signature *signature, const CssmData *comment);
+       bool verifyCodeSignature(const OSXVerifier &verifier, const AclValidationContext &context);
        bool validateSecret(const SecretAclSubject *me, const AccessCredentials *cred);
        bool getSecret(CssmOwnedData &secret, const CssmData &prompt) const;
        ObjectAcl *preAuthSource();
        Adornable &store(const AclSubject *subject);
        bool validateSecret(const SecretAclSubject *me, const AccessCredentials *cred);
        bool getSecret(CssmOwnedData &secret, const CssmData &prompt) const;
        ObjectAcl *preAuthSource();
        Adornable &store(const AclSubject *subject);
+       
+       // subject editing
+       ThresholdAclSubject *standardSubject(const AclValidationContext &context);
 };
 
 
 };
 
 
@@ -124,19 +132,22 @@ public:
        virtual SecurityServerAcl &acl();       // defaults to "no ACL; throw exception"
        virtual Database *relatedDatabase(); // optionally, a Database related to me
 
        virtual SecurityServerAcl &acl();       // defaults to "no ACL; throw exception"
        virtual Database *relatedDatabase(); // optionally, a Database related to me
 
-    // forward ACL calls, passing some locally obtained stuff along
-
-       void getOwner(AclOwnerPrototype &owner)
+       //
+    // Forward ACL calls, passing some locally obtained stuff along.
+       // These are virtual so an AclSource can override them. Such overrides
+       // should enhance/post-process rather than replace functionality.
+       //
+       virtual void getOwner(AclOwnerPrototype &owner)
        { return acl().getOwner(owner); }
        { return acl().getOwner(owner); }
-       void getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
+       virtual void getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
        { return acl().getAcl(tag, count, acls); }
        { return acl().getAcl(tag, count, acls); }
-    void changeAcl(const AclEdit &edit, const AccessCredentials *cred)
+       virtual void changeAcl(const AclEdit &edit, const AccessCredentials *cred)
        { return acl().changeAcl(edit, cred, relatedDatabase()); }
        { return acl().changeAcl(edit, cred, relatedDatabase()); }
-       void changeOwner(const AclOwnerPrototype &newOwner, const AccessCredentials *cred)
+       virtual void changeOwner(const AclOwnerPrototype &newOwner, const AccessCredentials *cred)
        { return acl().changeOwner(newOwner, cred, relatedDatabase()); }
        { return acl().changeOwner(newOwner, cred, relatedDatabase()); }
-       void validate(AclAuthorization auth, const AccessCredentials *cred)
+       virtual void validate(AclAuthorization auth, const AccessCredentials *cred)
        { acl().validate(auth, cred, relatedDatabase()); }
        { acl().validate(auth, cred, relatedDatabase()); }
-       void validate(AclAuthorization auth, const Context &context)
+       virtual void validate(AclAuthorization auth, const Context &context)
        { acl().validate(auth, context, relatedDatabase()); }
 };
 
        { acl().validate(auth, context, relatedDatabase()); }
 };
 
index 9878249a3acd2d5567c6146482dd9fbee84a17fb..55a2129af4b91344b637427df23a28e7966855b8 100644 (file)
@@ -109,26 +109,21 @@ SecurityAgentQuery::activate()
 void
 SecurityAgentQuery::inferHints(Process &thisProcess)
 {
 void
 SecurityAgentQuery::inferHints(Process &thisProcess)
 {
-       RefPointer<OSXCode> clientCode = thisProcess.clientCode();
-       SecurityAgent::RequestorType requestorType = SecurityAgent::unknown;
-       string bundlePath;
-       
-       if (clientCode)
-       {
-               string encodedBundle = clientCode->encode();
-               char bundleType = (encodedBundle.c_str())[0]; // yay, no accessor
-               switch(bundleType)
-               {
-                  case 'b': requestorType = SecurityAgent::bundle; break;
-                  case 't': requestorType = SecurityAgent::tool; break;
-               }
-               bundlePath = clientCode->canonicalPath();
-       }
+    string guestPath;
+       if (SecCodeRef clientCode = thisProcess.currentGuest())
+               guestPath = codePath(clientCode);
+       AuthItemSet processHints = clientHints(SecurityAgent::bundle, guestPath,
+               thisProcess.pid(), thisProcess.uid());
+       mClientHints.insert(processHints.begin(), processHints.end());
+}
 
 
-       AuthItemSet processHints = clientHints(requestorType, bundlePath, thisProcess.pid(), thisProcess.uid());
-    mClientHints.insert(processHints.begin(), processHints.end());
+void SecurityAgentQuery::addHint(const char *name, const void *value, UInt32 valueLen, UInt32 flags)
+{
+    AuthorizationItem item = { name, valueLen, const_cast<void *>(value), flags };
+    mClientHints.insert(AuthItemRef(item));
 }
 
 }
 
+
 void
 SecurityAgentQuery::readChoice()
 {
 void
 SecurityAgentQuery::readChoice()
 {
@@ -230,7 +225,7 @@ Reason QueryKeychainUse::queryUser (const char *database, const char *descriptio
        hints.insert(mClientHints.begin(), mClientHints.end());
        
        // put action/operation (sint32) into hints
        hints.insert(mClientHints.begin(), mClientHints.end());
        
        // put action/operation (sint32) into hints
-       hints.insert(AuthItemRef(AGENT_HINT_ACL_TAG, AuthValueOverlay(sizeof(action), static_cast<SInt32*>(&action))));
+       hints.insert(AuthItemRef(AGENT_HINT_ACL_TAG, AuthValueOverlay(sizeof(action), static_cast<sint32*>(&action))));
        
        // item name into hints
 
        
        // item name into hints
 
@@ -623,13 +618,6 @@ Reason QueryGenericPassphrase::query(const char *prompt, bool verify,
 // 
 // Get a DB blob's passphrase--keychain synchronization
 // 
 // 
 // Get a DB blob's passphrase--keychain synchronization
 // 
-
-void QueryDBBlobSecret::addHint(const char *name, const void *value, UInt32 valueLen, UInt32 flags)
-{
-    AuthorizationItem item = { name, valueLen, const_cast<void *>(value), flags };
-    mClientHints.insert(AuthItemRef(item));
-}
-
 Reason QueryDBBlobSecret::operator () (DatabaseCryptoCore &dbCore, const DbBlob *secretsBlob)
 {
     return query(dbCore, secretsBlob);
 Reason QueryDBBlobSecret::operator () (DatabaseCryptoCore &dbCore, const DbBlob *secretsBlob)
 {
     return query(dbCore, secretsBlob);
index 63d244d6528e253110439e7203d1d8f5cbdfec32..f92a15ffebd1f92aaab40af5753cf562660eb9ab 100644 (file)
@@ -48,6 +48,7 @@ public:
        SecurityAgentQuery(const AuthHostType type = securityAgent, Session &session = Server::session());
        
        void inferHints(Process &thisProcess);
        SecurityAgentQuery(const AuthHostType type = securityAgent, Session &session = Server::session());
        
        void inferHints(Process &thisProcess);
+    void addHint(const char *name, const void *value = NULL, UInt32 valueLen = 0, UInt32 flags = 0);
 
        virtual ~SecurityAgentQuery();
 
 
        virtual ~SecurityAgentQuery();
 
@@ -186,8 +187,6 @@ public:
     QueryDBBlobSecret()    { }
     Reason operator () (DatabaseCryptoCore &dbCore, const DbBlob *secretsBlob);
     
     QueryDBBlobSecret()    { }
     Reason operator () (DatabaseCryptoCore &dbCore, const DbBlob *secretsBlob);
     
-    void addHint(const char *name, const void *value = NULL, UInt32 valueLen = 0, UInt32 flags = 0);
-    
 protected:
     Reason query(DatabaseCryptoCore &dbCore, const DbBlob *secretsBlob);
        Reason accept(CssmManagedData &passphrase, DatabaseCryptoCore &dbCore, const DbBlob *secretsBlob);
 protected:
     Reason query(DatabaseCryptoCore &dbCore, const DbBlob *secretsBlob);
        Reason accept(CssmManagedData &passphrase, DatabaseCryptoCore &dbCore, const DbBlob *secretsBlob);
index a35edf12817e40c7619077851b3db8fd7c940e57..bc3f2457555958fa53581d3cb9d905a9c25fe915 100644 (file)
 
 #include <grp.h>
 #include <pwd.h>
 
 #include <grp.h>
 #include <pwd.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <syslog.h>
+#include <pthread.h>
 
 
+static pthread_once_t agent_cred_init = PTHREAD_ONCE_INIT; 
+static gid_t agent_gid = 92;
+static uid_t agent_uid = 92;
 
 
+void initialize_agent_creds()
+{
+    struct passwd *agentUser = getpwnam("securityagent");
+    if (agentUser)
+    {
+        agent_uid = agentUser->pw_uid;
+        agent_gid = agentUser->pw_gid;
+        endpwent();
+    }
+}
+  
 AuthHostInstance::AuthHostInstance(Session &session, AuthHostType host) :
        mHostType(host)
 {
        secdebug("authhost", "authhost born (%p)", this);
        referent(session);
        session.addReference(*this);
 AuthHostInstance::AuthHostInstance(Session &session, AuthHostType host) :
        mHostType(host)
 {
        secdebug("authhost", "authhost born (%p)", this);
        referent(session);
        session.addReference(*this);
+    if (host == securityAgent)
+        pthread_once(&agent_cred_init, initialize_agent_creds); 
 }
 
 AuthHostInstance::~AuthHostInstance()
 { 
        secdebug("authhost", "authhost died (%p)", this);
 }
 
 AuthHostInstance::~AuthHostInstance()
 { 
        secdebug("authhost", "authhost died (%p)", this);
-       
-       // clean up
-       servicePort ().destroy ();
 }
 
 Session &AuthHostInstance::session() const
 }
 
 Session &AuthHostInstance::session() const
@@ -83,7 +100,6 @@ AuthHostInstance::childAction()
        if ((mHostType == userAuthHost) || (mHostType == privilegedAuthHost))
        {
                snprintf(agentExecutable, sizeof(agentExecutable), "%s/Contents/Resources/authorizationhost", path);
        if ((mHostType == userAuthHost) || (mHostType == privilegedAuthHost))
        {
                snprintf(agentExecutable, sizeof(agentExecutable), "%s/Contents/Resources/authorizationhost", path);
-       
                secdebug("AuthHostInstance", "execl(%s)", agentExecutable);
                execl(agentExecutable, agentExecutable, NULL);
        }
                secdebug("AuthHostInstance", "execl(%s)", agentExecutable);
                execl(agentExecutable, agentExecutable, NULL);
        }
@@ -91,25 +107,15 @@ AuthHostInstance::childAction()
        {
                snprintf(agentExecutable, sizeof(agentExecutable), "%s/Contents/MacOS/SecurityAgent", path);
 
        {
                snprintf(agentExecutable, sizeof(agentExecutable), "%s/Contents/MacOS/SecurityAgent", path);
 
-               struct group *agentGroup = getgrnam("securityagent");
-               gid_t agentGID = static_cast<gid_t>(-2);
-               if (agentGroup)
-               {
-                       agentGID = agentGroup->gr_gid;
-                       endgrent();
-               }
+               pid_t pid = getpid();
+               if ((pid <= 0) ||
+            sysctlbyname("vfs.generic.noremotehang", NULL, NULL, &pid, sizeof(pid)))
+                               syslog(LOG_ERR, "Failed to set vfs.generic.noremotehang for pid(%d)", pid);
 
 
-               struct passwd *agentUser = getpwnam("securityagent");
-               uid_t agentUID = static_cast<uid_t>(-2);
-               if (agentUser)
-               {
-                       agentUID = agentUser->pw_uid;
-                       endpwent();
-               }
+               setgroups(1, &agent_gid);
+               setgid(agent_gid);
+               setuid(agent_uid);
 
 
-               setuid(agentUID);
-               setgid(agentGID);
-       
                CFRef<CFDataRef> userPrefs(session().copyUserPrefs());
                
                FILE *mbox = tmpfile();
                CFRef<CFDataRef> userPrefs(session().copyUserPrefs());
                
                FILE *mbox = tmpfile();
@@ -127,7 +133,7 @@ AuthHostInstance::childAction()
                        }
                }
                
                        }
                }
                
-               secdebug("AuthHostInstance", "execl(%s) as user (%d,%d)", agentExecutable, agentUID, agentGID);
+               secdebug("AuthHostInstance", "execl(%s) as user (%d,%d)", agentExecutable, agent_uid, agent_gid);
                execl(agentExecutable, agentExecutable, NULL);
        }
 
                execl(agentExecutable, agentExecutable, NULL);
        }
 
@@ -150,7 +156,8 @@ AuthHostInstance::activate()
        StLock<Mutex> _(*this);
        if (state() != alive)
        {
        StLock<Mutex> _(*this);
        if (state() != alive)
        {
-               if (!(session().attributes() & sessionHasGraphicAccess))
+               if ((mHostType == securityAgent) && 
+                   !(session().attributes() & sessionHasGraphicAccess))
                        CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
 
                Security::MachPlusPlus::StBootstrap bootSaver(session().bootstrapPort());
                        CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
 
                Security::MachPlusPlus::StBootstrap bootSaver(session().bootstrapPort());
index 8e328cbd924aaca454171177673ad9cdd92cb682..dd483546952270cc910694e6bacecaf579beddd9 100644 (file)
@@ -54,14 +54,17 @@ Mutex AuthorizationToken::authMapLock; // lock for mAuthorizations (only)
 // Create an authorization token.
 //
 AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base, 
 // Create an authorization token.
 //
 AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base, 
-const audit_token_t &auditToken)
+const audit_token_t &auditToken, bool operateAsLeastPrivileged)
        : mBaseCreds(base), mTransferCount(INT_MAX), 
        : mBaseCreds(base), mTransferCount(INT_MAX), 
-    mCreatorCode(Server::process().clientCode()),
        mCreatorPid(Server::process().pid()), 
        mCreatorPid(Server::process().pid()), 
-       mCreatorAuditToken(auditToken)
+       mCreatorAuditToken(auditToken),
+       mOperatesAsLeastPrivileged(operateAsLeastPrivileged)
 {
        mCreatorUid = mCreatorAuditToken.euid();
        mCreatorGid = mCreatorAuditToken.egid();
 {
        mCreatorUid = mCreatorAuditToken.euid();
        mCreatorGid = mCreatorAuditToken.egid();
+       
+       if (SecCodeRef code = Server::process().currentGuest())
+               MacOSError::check(SecCodeCopyStaticCode(code, kSecCSDefaultFlags, &mCreatorCode.aref()));
                
        // link to session
        referent(ssn);
                
        // link to session
        referent(ssn);
@@ -74,9 +77,8 @@ const audit_token_t &auditToken)
     authMap[mHandle] = this;
        
     // all ready
     authMap[mHandle] = this;
        
     // all ready
-       secdebug("SSauth", "Authorization %p created using %d credentials; owner=%s",
-               this, int(mBaseCreds.size()),
-        mCreatorCode ? mCreatorCode->encode().c_str() : "unknown");
+       secdebug("SSauth", "Authorization %p created using %d credentials; owner=%p",
+               this, int(mBaseCreds.size()), mCreatorCode.get());
 }
 
 AuthorizationToken::~AuthorizationToken()
 }
 
 AuthorizationToken::~AuthorizationToken()
@@ -254,7 +256,7 @@ AuthorizationToken::setCredentialInfo(const Credential &inCred)
     AuthItemRef uidHint("uid", AuthValueOverlay(uid_string ? strlen(uid_string) + 1 : 0, uid_string), 0);
     dstInfoSet.insert(uidHint);
  
     AuthItemRef uidHint("uid", AuthValueOverlay(uid_string ? strlen(uid_string) + 1 : 0, uid_string), 0);
     dstInfoSet.insert(uidHint);
  
-    AuthItemRef userHint("username", AuthValueOverlay(inCred->username()), 0);
+    AuthItemRef userHint("username", AuthValueOverlay(inCred->name()), 0);
     dstInfoSet.insert(userHint);
  
        setInfoSet(dstInfoSet);
     dstInfoSet.insert(userHint);
  
        setInfoSet(dstInfoSet);
index 7c70d98a2b01c8e81d547f8a84c5f6aa4359a3d6..044ffeea6cee58a95ef187c9959e59db90d8b515 100644 (file)
 #ifndef _H_AUTHORITY
 #define _H_AUTHORITY
 
 #ifndef _H_AUTHORITY
 #define _H_AUTHORITY
 
-#include <security_cdsa_utilities/AuthorizationData.h>
 #include <security_utilities/osxcode.h>
 #include <security_utilities/ccaudit.h>
 #include "database.h"
 #include <security_utilities/osxcode.h>
 #include <security_utilities/ccaudit.h>
 #include "database.h"
+#include "credential.h"
+#include <security_cdsa_utilities/AuthorizationData.h>
 
 
+using Authorization::AuthItemSet;
 using Authorization::Credential;
 using Authorization::CredentialSet;
 using Authorization::Credential;
 using Authorization::CredentialSet;
-using Authorization::AuthItemSet;
 using Security::CommonCriteria::AuditToken;
 
 class Process;
 using Security::CommonCriteria::AuditToken;
 
 class Process;
@@ -43,7 +44,7 @@ class Session;
 
 class AuthorizationToken : public PerSession {
 public:
 
 class AuthorizationToken : public PerSession {
 public:
-       AuthorizationToken(Session &ssn, const CredentialSet &base, const audit_token_t &auditToken);
+       AuthorizationToken(Session &ssn, const CredentialSet &base, const audit_token_t &auditToken, bool operateAsLeastPrivileged = false);
        ~AuthorizationToken();
 
     Session &session() const;
        ~AuthorizationToken();
 
     Session &session() const;
@@ -69,7 +70,7 @@ public:
 
        uid_t creatorUid() const        { return mCreatorUid; }
        gid_t creatorGid() const        { return mCreatorGid; }
 
        uid_t creatorUid() const        { return mCreatorUid; }
        gid_t creatorGid() const        { return mCreatorGid; }
-    OSXCode *creatorCode() const { return mCreatorCode; }
+    SecStaticCodeRef creatorCode() const { return mCreatorCode; }
        pid_t creatorPid() const        { return mCreatorPid; }
        
        const AuditToken &creatorAuditToken() const { return mCreatorAuditToken; }
        pid_t creatorPid() const        { return mCreatorPid; }
        
        const AuditToken &creatorAuditToken() const { return mCreatorAuditToken; }
@@ -79,6 +80,7 @@ public:
     void setCredentialInfo(const Credential &inCred);
     void clearInfoSet();
        void scrubInfoSet();
     void setCredentialInfo(const Credential &inCred);
     void clearInfoSet();
        void scrubInfoSet();
+       bool operatesAsLeastPrivileged() const { return mOperatesAsLeastPrivileged; }
 
 public:
        static AuthorizationToken &find(const AuthorizationBlob &blob);
 
 public:
        static AuthorizationToken &find(const AuthorizationBlob &blob);
@@ -107,20 +109,19 @@ private:
 
        uid_t mCreatorUid;                              // Uid of process that created this authorization
        gid_t mCreatorGid;                              // Gid of process that created this authorization
 
        uid_t mCreatorUid;                              // Uid of process that created this authorization
        gid_t mCreatorGid;                              // Gid of process that created this authorization
-    RefPointer<OSXCode> mCreatorCode; // code id of creator
+       CFCopyRef<SecStaticCodeRef> mCreatorCode; // code reference to creator
        pid_t mCreatorPid;                              // Pid of processs that created this authorization
        
        AuditToken mCreatorAuditToken;  // Audit token of the process that created this authorization
 
     AuthItemSet mInfoSet;                      // Side band info gathered from evaluations in this session
 
        pid_t mCreatorPid;                              // Pid of processs that created this authorization
        
        AuditToken mCreatorAuditToken;  // Audit token of the process that created this authorization
 
     AuthItemSet mInfoSet;                      // Side band info gathered from evaluations in this session
 
+       bool mOperatesAsLeastPrivileged;
+
 private:
        typedef map<AuthorizationBlob, RefPointer<AuthorizationToken> > AuthMap;
        static AuthMap &authMap;                        // set of extant authorizations
     static Mutex authMapLock;          // lock for mAuthorizations (only)
 };
 
 private:
        typedef map<AuthorizationBlob, RefPointer<AuthorizationToken> > AuthMap;
        static AuthMap &authMap;                        // set of extant authorizations
     static Mutex authMapLock;          // lock for mAuthorizations (only)
 };
 
-
-
-
 #endif //_H_AUTHORITY
 #endif //_H_AUTHORITY
index 2a5db79d6af091412da73d79962e35fb0dfaf9e2..a8cd2b05663beb38e22522447d452892cefb9994 100644 (file)
@@ -56,6 +56,8 @@ ServerChild::ServerChild()
 //
 ServerChild::~ServerChild()
 {
 //
 ServerChild::~ServerChild()
 {
+       mServicePort.destroy();
+       
        if (state() == alive) {
                this->kill(SIGTERM);            // shoot it once
                checkChildren();                        // check for quick death
        if (state() == alive) {
                this->kill(SIGTERM);            // shoot it once
                checkChildren();                        // check for quick death
diff --git a/src/clientid.cpp b/src/clientid.cpp
new file mode 100644 (file)
index 0000000..b04b7c6
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2006-2007 Apple 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@
+ */
+//
+// clientid - track and manage identity of securityd clients
+//
+#include "clientid.h"
+#include "server.h"
+#include "osxcodewrap.h"
+
+
+//
+// Constructing a ClientIdentification doesn't do much.
+// We're waiting for setup(), which should be called by the child class's
+// constructor.
+//
+ClientIdentification::ClientIdentification()
+{
+}
+
+
+//
+// Initialize the ClientIdentification.
+// This creates a process-level code object for the client.
+//
+void ClientIdentification::setup(pid_t pid)
+{
+       if (IFDEBUG(OSStatus rc =)SecCodeCreateWithPID(pid, kSecCSDefaultFlags,
+                       &mClientProcess.aref()))
+               secdebug("clientid", "could not get code for process %d: OSStatus=%ld",
+                       pid, rc);
+}
+
+
+//
+// Return a SecCodeRef for the client process itself, regardless of
+// which guest within it is currently active.
+// Think twice before using this.
+//
+SecCodeRef ClientIdentification::processCode() const
+{
+       return mClientProcess;
+}
+
+
+//
+// Return a SecCodeRef for the currently active guest within the client
+// process.
+//
+// We make a fair effort to cache client guest identities without over-growing
+// the cache. Note that there's currently no protocol for being notified of
+// a guest's death or disappearance (independent from the host process's death),
+// so we couldn't track guests live even if we tried.
+//
+// Note that this consults Server::connection for the currently serviced
+// Connection object, so this is not entirely a function of ClientIdentification state.
+//
+SecCodeRef ClientIdentification::currentGuest() const
+{
+       if (GuestState *guest = current())
+               return guest->code;
+       else
+               return mClientProcess;
+}
+
+ClientIdentification::GuestState *ClientIdentification::current() const
+{
+       // if we have no client identification, we can't find a current guest either
+       if (!processCode())
+               return NULL;
+
+       SecGuestRef guestRef = Server::connection().guestRef();
+       
+       // try to deliver an already-cached entry
+       {
+               StLock<Mutex> _(mLock);
+               GuestMap::iterator it = mGuests.find(guestRef);
+               if (it != mGuests.end())
+                       return &it->second;
+       }
+
+       // okay, make a new one (this may take a while)
+       CFRef<CFDictionaryRef> attributes = (guestRef == kSecNoGuest)
+               ? NULL
+               : makeCFDictionary(1, kSecGuestAttributeCanonical, CFTempNumber(guestRef).get());
+       Server::active().longTermActivity();
+       CFRef<SecCodeRef> code;
+       switch (OSStatus rc = SecCodeCopyGuestWithAttributes(processCode(),
+               attributes, kSecCSDefaultFlags, &code.aref())) {
+       case noErr:
+               break;
+       case errSecCSUnsigned:                  // not signed; clearly not a host
+       case errSecCSNotAHost:                  // signed but not marked as a (potential) host
+               code = mClientProcess;
+               break;
+       case errSecCSNoSuchCode:                // potential host, but...
+               if (guestRef == kSecNoGuest) {  //  ... no guests (yet), so return the process
+                       code = mClientProcess;
+                       break;
+               }
+               // else fall through            //  ... the guest we expected to be there isn't
+       default:
+               MacOSError::throwMe(rc);
+       }
+       StLock<Mutex> _(mLock);
+       GuestState &slot = mGuests[guestRef];
+       if (!slot.code) // if another thread didn't get here first...
+               slot.code = code;
+       return &slot;
+}
+
+
+//
+// Support for the legacy hash identification mechanism.
+// The legacy machinery deals exclusively in terms of processes.
+// It knows nothing about guests and their identities.
+//
+string ClientIdentification::getPath() const
+{
+       assert(mClientProcess);
+       return codePath(currentGuest());
+}
+
+const CssmData ClientIdentification::getHash() const
+{
+       if (GuestState *guest = current()) {
+               if (!guest->gotHash) {
+                       RefPointer<OSXCode> clientCode = new OSXCodeWrap(guest->code);
+                       OSXVerifier::makeLegacyHash(clientCode, guest->legacyHash);
+                       guest->gotHash = true;
+               }
+               return CssmData::wrap(guest->legacyHash, SHA1::digestLength);
+       } else
+               return CssmData();
+}
+
+
+//
+// Bonus function: get the path out of a SecCodeRef
+//
+std::string codePath(SecStaticCodeRef code)
+{
+       CFRef<CFURLRef> path;
+       MacOSError::check(SecCodeCopyPath(code, kSecCSDefaultFlags, &path.aref()));
+       return cfString(path);
+}
+
+
+//
+// Debug dump support
+//
+#if defined(DEBUGDUMP)
+
+static void dumpCode(SecCodeRef code)
+{
+       CFRef<CFURLRef> path;
+       if (OSStatus rc = SecCodeCopyPath(code, kSecCSDefaultFlags, &path.aref()))
+               Debug::dump("unknown(rc=%ld)", rc);
+       else
+               Debug::dump("%s", cfString(path).c_str());
+}
+
+void ClientIdentification::dump()
+{
+       Debug::dump(" client=");
+       dumpCode(mClientProcess);
+       for (GuestMap::const_iterator it = mGuests.begin(); it != mGuests.end(); ++it) {
+               Debug::dump(" guest(0x%x)=", it->first);
+               dumpCode(it->second.code);
+               if (it->second.gotHash)
+                       Debug::dump(" [got hash]");
+       }
+}
+
+#endif //DEBUGDUMP
diff --git a/src/clientid.h b/src/clientid.h
new file mode 100644 (file)
index 0000000..c961284
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2000-2004 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@
+ */
+//
+// clientid - track and manage identity of securityd clients
+//
+#ifndef _H_CLIENTID
+#define _H_CLIENTID
+
+#include "codesigdb.h"
+#include <Security/SecCode.h>
+#include <security_utilities/cfutilities.h>
+#include <string>
+
+
+//
+// A ClientIdentification object is a mix-in class that tracks
+// the identity of associated client processes and their sub-entities
+// (aka Code Signing Guest objects).
+//
+class ClientIdentification : public CodeSignatures::Identity {
+public:
+       ClientIdentification();
+       
+       SecCodeRef processCode() const;
+       SecCodeRef currentGuest() const;
+
+       // CodeSignatures::Identity personality
+       string getPath() const;
+       const CssmData getHash() const;
+       
+protected:
+       void setup(pid_t pid);
+
+public:
+       IFDUMP(void dump());
+       
+private:
+       CFRef<SecCodeRef> mClientProcess;       // process-level client object
+
+       mutable Mutex mLock;                            // protects everything below
+       
+       struct GuestState {
+               GuestState() : gotHash(false) { }
+               CFRef<SecCodeRef> code;
+               mutable bool gotHash;
+               mutable SHA1::Digest legacyHash;
+       };
+       typedef std::map<SecGuestRef, GuestState> GuestMap;
+       mutable GuestMap mGuests;
+       
+       GuestState *current() const;
+};
+
+
+//
+// Bonus function
+//
+std::string codePath(SecStaticCodeRef code);
+
+
+#endif //_H_CLIENTID
index 4ff3d6490680958d5ccbbe6150c22110301d403a..411f8ec481f8646b492b227f1a2276f2c36bb495 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2003-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -28,6 +28,7 @@
 #include "codesigdb.h"
 #include "process.h"
 #include "server.h"
 #include "codesigdb.h"
 #include "process.h"
 #include "server.h"
+#include "osxcodewrap.h"
 #include "agentquery.h"
 #include <security_utilities/memutils.h>
 #include <security_utilities/logging.h>
 #include "agentquery.h"
 #include <security_utilities/memutils.h>
 #include <security_utilities/logging.h>
@@ -65,20 +66,15 @@ DbKey::DbKey(char type, const CssmData &key, bool perUser, uid_t user)
 //
 // A subclass of Identity made of whole cloth (from a raw CodeSignature ACL information)
 //
 //
 // A subclass of Identity made of whole cloth (from a raw CodeSignature ACL information)
 //
-class AclIdentity : public CodeSignatures::Identity {
-public:
-       AclIdentity(const CodeSigning::Signature *sig, const char *comment)
-               : mHash(*sig), mPath(comment ? comment : "") { }
-       AclIdentity(const CssmData &hash, const char *comment)
-               : mHash(hash), mPath(comment ? comment : "") { }
+struct AclIdentity : public CodeSignatures::Identity {
+       AclIdentity(const CssmData hash, string path) : mHash(hash), mPath(path) { }
                
                
-protected:
-       std::string getPath() const { return mPath; }
-       const CssmData getHash(CodeSigning::OSXSigner &) const { return mHash; }
-       
+       string getPath() const { return mPath; }
+       const CssmData getHash() const { return mHash; }
+
 private:
        const CssmData mHash;
 private:
        const CssmData mHash;
-       std::string mPath;
+       const string mPath;
 };
 
 
 };
 
 
@@ -116,8 +112,7 @@ CodeSignatures::~CodeSignatures()
 void CodeSignatures::open(const char *path)
 {
        mDb.open(path, O_RDWR | O_CREAT, 0644);
 void CodeSignatures::open(const char *path)
 {
        mDb.open(path, O_RDWR | O_CREAT, 0644);
-       if (mDb)
-               mDb.flush();
+       mDb.flush();
        IFDUMPING("equiv", debugDump("reopen"));
 }
 
        IFDUMPING("equiv", debugDump("reopen"));
 }
 
@@ -145,12 +140,10 @@ string CodeSignatures::Identity::canonicalName(const string &path)
 //
 bool CodeSignatures::find(Identity &id, uid_t user)
 {
 //
 bool CodeSignatures::find(Identity &id, uid_t user)
 {
-       if (!mDb)
-               return false;
        if (id.mState != Identity::untried)
                return id.mState == Identity::valid;
        try {
        if (id.mState != Identity::untried)
                return id.mState == Identity::valid;
        try {
-               DbKey userKey('H', id.getHash(mSigner), true, user);
+               DbKey userKey('H', id.getHash(), true, user);
                CssmData linkValue;
                if (mDb.get(userKey, linkValue)) {
                        id.mName = string(linkValue.interpretedAs<const char>(), linkValue.length());
                CssmData linkValue;
                if (mDb.get(userKey, linkValue)) {
                        id.mName = string(linkValue.interpretedAs<const char>(), linkValue.length());
@@ -158,7 +151,7 @@ bool CodeSignatures::find(Identity &id, uid_t user)
                        id.mState = Identity::valid;
                        return true;
                }
                        id.mState = Identity::valid;
                        return true;
                }
-               DbKey sysKey('H', id.getHash(mSigner));
+               DbKey sysKey('H', id.getHash());
                if (mDb.get(sysKey, linkValue)) {
                        id.mName = string(linkValue.interpretedAs<const char>(), linkValue.length());
                        IFDUMPING("equiv", id.debugDump("found/system"));
                if (mDb.get(sysKey, linkValue)) {
                        id.mName = string(linkValue.interpretedAs<const char>(), linkValue.length());
                        IFDUMPING("equiv", id.debugDump("found/system"));
@@ -174,18 +167,11 @@ bool CodeSignatures::find(Identity &id, uid_t user)
 
 void CodeSignatures::makeLink(Identity &id, const string &ident, bool forUser, uid_t user)
 {
 
 void CodeSignatures::makeLink(Identity &id, const string &ident, bool forUser, uid_t user)
 {
-       if (!mDb)
-               UnixError::throwMe(ENOENT);
-       DbKey key('H', id.getHash(mSigner), forUser, user);
+       DbKey key('H', id.getHash(), forUser, user);
        if (!mDb.put(key, StringData(ident)))
                UnixError::throwMe();
 }
 
        if (!mDb.put(key, StringData(ident)))
                UnixError::throwMe();
 }
 
-void CodeSignatures::makeApplication(const std::string &name, const std::string &path)
-{
-       //@@@ create app record and fill (later)
-}
-
 
 //
 // Administrative manipulation calls
 
 //
 // Administrative manipulation calls
@@ -199,8 +185,8 @@ void CodeSignatures::addLink(const CssmData &oldHash, const CssmData &newHash,
                UnixError::throwMe(EACCES);
        if (!forSystem) // in fact, for now we don't allow per-user calls at all
                UnixError::throwMe(EACCES);
                UnixError::throwMe(EACCES);
        if (!forSystem) // in fact, for now we don't allow per-user calls at all
                UnixError::throwMe(EACCES);
-       AclIdentity oldCode(oldHash, name.c_str());
-       AclIdentity newCode(newHash, name.c_str());
+       AclIdentity oldCode(oldHash, name);
+       AclIdentity newCode(newHash, name);
        secdebug("codesign", "addlink for name %s", name.c_str());
        StLock<Mutex> _(mDatabaseLock);
        if (oldCode) {
        secdebug("codesign", "addlink for name %s", name.c_str());
        StLock<Mutex> _(mDatabaseLock);
        if (oldCode) {
@@ -219,8 +205,6 @@ void CodeSignatures::addLink(const CssmData &oldHash, const CssmData &newHash,
 
 void CodeSignatures::removeLink(const CssmData &hash, const char *name, bool forSystem)
 {
 
 void CodeSignatures::removeLink(const CssmData &hash, const char *name, bool forSystem)
 {
-       if (!mDb)
-               UnixError::throwMe(ENOENT);
        AclIdentity code(hash, name);
        uid_t user = Server::process().uid();
        if (forSystem && user)  // only root user can remove forSystem links
        AclIdentity code(hash, name);
        uid_t user = Server::process().uid();
        if (forSystem && user)  // only root user can remove forSystem links
@@ -233,24 +217,189 @@ void CodeSignatures::removeLink(const CssmData &hash, const char *name, bool for
 
 
 //
 
 
 //
-// Verify signature matches
+// Verify signature matches.
+// This ends up getting called when a CodeSignatureAclSubject is validated.
+// The OSXVerifier describes what we require of the client code; the process represents
+// the requesting client; and the context gives us access to the ACL and its environment
+// in case we want to, well, creatively rewrite it for some reason. 
 //
 bool CodeSignatures::verify(Process &process,
 //
 bool CodeSignatures::verify(Process &process,
-       const CodeSigning::Signature *trustedSignature, const CssmData *comment)
+       const OSXVerifier &verifier, const AclValidationContext &context)
 {
        secdebug("codesign", "start verify");
 
        // if we have no client code, we cannot possibly match this
 {
        secdebug("codesign", "start verify");
 
        // if we have no client code, we cannot possibly match this
-       if (!process.clientCode()) {
+       SecCodeRef code = process.currentGuest();
+       if (!code) {
                secdebug("codesign", "no code base: fail");
                return false;
        }
                secdebug("codesign", "no code base: fail");
                return false;
        }
+       
+       if (SecRequirementRef requirement = verifier.requirement()) {
+               // If the ACL contains a code signature (requirement), we won't match against unsigned code at all.
+               // The legacy hash is ignored (it's for use by pre-Leopard systems).
+               secdebug("codesign", "CS requirement present; ignoring legacy hashes");
+               Server::active().longTermActivity();
+               switch (IFDEBUG(OSStatus rc =) SecCodeCheckValidity(code, kSecCSDefaultFlags, requirement)) {
+               case noErr:
+                       secdebug("codesign", "CS verify passed");
+                       return true;
+               case errSecCSUnsigned:
+                       secdebug("codesign", "CS verify against unsigned binary failed");
+                       return false;
+               default:
+                       secdebug("codesign", "CS verify failed OSStatus=%ld", rc);
+                       return false;
+               }
+       }
+       switch (matchSignedClientToLegacyACL(process, code, verifier, context)) {
+       case noErr:                                             // handled, allow access
+               return true;
+       case errSecCSUnsigned:                  // unsigned client, complete legacy case
+               secdebug("codesign", "no CS requirement - using legacy hash");
+               return verifyLegacy(process,
+                       CssmData::wrap(verifier.legacyHash(), SHA1::digestLength),
+                       verifier.path());
+       default:                                                // client unsuitable, reject this match
+               return false;
+       }
+}
+
+
+//
+// See if we can rewrite the ACL from legacy to Code Signing form without losing too much security.
+// Returns true if the present validation should succeed (we probably rewrote the ACL).
+// Returns false if the present validation shouldn't succeed based on what we did here (we may still
+// have rewritten the ACL, in principle).
+//
+// Note that these checks add nontrivial overhead to ACL processing. We want to eventually phase
+// this out, or at least make it an option that doesn't run all the time - perhaps an "extra legacy
+// effort" per-client mode bit.
+//
+static string trim(string s, char delimiter)
+{
+       string::size_type p = s.rfind(delimiter);
+       if (p != string::npos)
+               s = s.substr(p + 1);
+       return s;
+}
+
+static string trim(string s, char delimiter, string suffix)
+{
+       s = trim(s, delimiter);
+       int preLength = s.length() - suffix.length();
+       if (preLength > 0 && s.substr(preLength) == suffix)
+               s = s.substr(0, preLength);
+       return s;
+}
+
+OSStatus CodeSignatures::matchSignedClientToLegacyACL(Process &process,
+       SecCodeRef code, const OSXVerifier &verifier, const AclValidationContext &context)
+{
+       //
+       // Check whether we seem to be matching a legacy .Mac ACL against a member of the .Mac group
+       //
+       if (SecurityServerAcl::looksLikeLegacyDotMac(context)) {
+               Server::active().longTermActivity();
+               CFRef<SecRequirementRef> dotmac;
+               MacOSError::check(SecRequirementCreateGroup(CFSTR("dot-mac"), NULL, kSecCSDefaultFlags, &dotmac.aref()));
+               if (SecCodeCheckValidity(code, kSecCSDefaultFlags, dotmac) == noErr) {
+                       secdebug("codesign", "client is a dot-mac application; update the ACL accordingly");
+
+                       // create a suitable AclSubject (this is the above-the-API-line way)
+                       CFRef<CFDataRef> reqdata;
+                       MacOSError::check(SecRequirementCopyData(dotmac, kSecCSDefaultFlags, &reqdata.aref()));
+                       RefPointer<CodeSignatureAclSubject> subject = new CodeSignatureAclSubject(NULL, "group://dot-mac");
+                       subject->add((const BlobCore *)CFDataGetBytePtr(reqdata));
+
+                       // add it to the ACL and pass the access check (we just quite literally did it above)
+                       SecurityServerAcl::addToStandardACL(context, subject);
+                       return noErr;
+               }
+       }
 
 
-       // first of all, if the signature directly matches the client's code, we're obviously fine
+       //
+       // Get best names for the ACL (legacy) subject and the (signed) client
+       //
+       CFRef<CFDictionaryRef> info;
+       MacOSError::check(SecCodeCopySigningInformation(code, kSecCSSigningInformation, &info.aref()));
+       CFStringRef signingIdentity = CFStringRef(CFDictionaryGetValue(info, kSecCodeInfoIdentifier));
+       if (!signingIdentity)           // unsigned
+               return errSecCSUnsigned;
+
+       string bundleName;      // client
+       if (CFDictionaryRef infoList = CFDictionaryRef(CFDictionaryGetValue(info, kSecCodeInfoPList)))
+               if (CFStringRef name = CFStringRef(CFDictionaryGetValue(infoList, kCFBundleNameKey)))
+                       bundleName = trim(cfString(name), '.');
+       if (bundleName.empty()) // fall back to signing identifier
+               bundleName = trim(cfString(signingIdentity), '.');
+
+       string aclName = trim(verifier.path(), '/', ".app");    // ACL
+       
+       secdebug("codesign", "matching signed client \"%s\" against legacy ACL \"%s\"",
+               bundleName.c_str(), aclName.c_str());
+       
+       //
+       // Check whether we're matching a signed APPLE application against a legacy ACL by the same name
+       //
+       if (bundleName == aclName) {
+               const unsigned char reqData[] = {               // "anchor apple", version 1 blob, embedded here
+                       0xfa, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10,
+                       0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03
+               };
+               CFRef<SecRequirementRef> apple;
+               MacOSError::check(SecRequirementCreateWithData(CFTempData(reqData, sizeof(reqData)),
+                       kSecCSDefaultFlags, &apple.aref()));
+               Server::active().longTermActivity();
+               switch (OSStatus rc = SecCodeCheckValidity(code, kSecCSDefaultFlags, apple)) {
+               case noErr:
+                       {
+                               secdebug("codesign", "withstands strict scrutiny; quietly adding new ACL");
+                               RefPointer<OSXCode> wrap = new OSXCodeWrap(code);
+                               RefPointer<AclSubject> subject = new CodeSignatureAclSubject(OSXVerifier(wrap));
+                               SecurityServerAcl::addToStandardACL(context, subject);
+                               return noErr;
+                       }
+               default:
+                       secdebug("codesign", "validation fails with rc=%ld, rejecting", rc);
+                       return rc;
+               }
+               secdebug("codesign", "does not withstand strict scrutiny; ask the user");
+               QueryCodeCheck query;
+               query.inferHints(process);
+               if (!query(verifier.path().c_str())) {
+                       secdebug("codesign", "user declined equivalence: cancel the access");
+                       CssmError::throwMe(CSSM_ERRCODE_USER_CANCELED);
+               }
+               RefPointer<OSXCode> wrap = new OSXCodeWrap(code);
+               RefPointer<AclSubject> subject = new CodeSignatureAclSubject(OSXVerifier(wrap));
+               SecurityServerAcl::addToStandardACL(context, subject);
+               return noErr;
+       }
+
+       // not close enough to even ask - this can't match
+       return errSecCSReqFailed;
+}
+
+
+//
+// Perform legacy hash verification.
+// This is the pre-Leopard (Tiger, Panther) code path. Here we only have legacy hashes
+// (called, confusingly, "signatures"), which we're matching against suitably computed
+// "signatures" (hashes) on the requesting application. We consult the CodeEquivalenceDatabase
+// in a doomed attempt to track changes made to applications through updates, and issue
+// equivalence dialogs to users if we have a name match (but hash mismatch). That's all
+// there was before Code Signing; and that's what you'll continue to get if the requesting
+// application is unsigned. Until we throw the whole mess out altogether, hopefully by
+// the Next Big Cat After Leopard.
+//
+bool CodeSignatures::verifyLegacy(Process &process, const CssmData &signature, string path)
+{
+       // First of all, if the signature directly matches the client's code, we're obviously fine
        // we don't even need the database for that...
        Identity &clientIdentity = process;
        try {
        // we don't even need the database for that...
        Identity &clientIdentity = process;
        try {
-               if (clientIdentity.getHash(mSigner) == CssmData(*trustedSignature)) {
+               if (clientIdentity.getHash() == signature) {
                        secdebug("codesign", "direct match: pass");
                        return true;
                }
                        secdebug("codesign", "direct match: pass");
                        return true;
                }
@@ -259,14 +408,8 @@ bool CodeSignatures::verify(Process &process,
                return false;
        }
        
                return false;
        }
        
-       // don't bother the user if the db is MIA
-       if (!mDb) {
-               secdebug("codesign", "database not open; cannot verify");
-               return false;
-       }
-       
-       // ah well. Establish mediator objects for database signature links
-       AclIdentity aclIdentity(trustedSignature, comment ? comment->interpretedAs<const char>() : NULL);
+       // Ah well. Establish mediator objects for database signature links
+       AclIdentity aclIdentity(signature, path);
 
        uid_t user = process.uid();
        {
 
        uid_t user = process.uid();
        {
@@ -297,8 +440,7 @@ bool CodeSignatures::verify(Process &process,
        // The names match - we have a possible update.
        
        // Take the UI lock now to serialize "update rushes".
        // The names match - we have a possible update.
        
        // Take the UI lock now to serialize "update rushes".
-       Server::active().longTermActivity();
-       StLock<Mutex> uiLocker(mUILock);
+       LongtermStLock uiLocker(mUILock);
        
        // re-read the database in case some other thread beat us to the update
        {
        
        // re-read the database in case some other thread beat us to the update
        {
@@ -315,14 +457,14 @@ bool CodeSignatures::verify(Process &process,
                        return false;
                }
        }
                        return false;
                }
        }
-
+       
        // ask the user
        QueryCodeCheck query;
     query.inferHints(process);
        if (!query(aclIdentity.path().c_str()))
     {
        // ask the user
        QueryCodeCheck query;
     query.inferHints(process);
        if (!query(aclIdentity.path().c_str()))
     {
-               secdebug("codesign", "user declined equivalence: fail");
-               return false;
+               secdebug("codesign", "user declined equivalence: cancel the access");
+               CssmError::throwMe(CSSM_ERRCODE_USER_CANCELED);
        }
 
        // take the database lock back for real
        }
 
        // take the database lock back for real
@@ -349,7 +491,6 @@ bool CodeSignatures::verify(Process &process,
        
        // the De Novo case: no links, must create everything
        string ident = clientIdentity.name();
        
        // the De Novo case: no links, must create everything
        string ident = clientIdentity.name();
-       makeApplication(ident, clientIdentity.path());
        makeLink(clientIdentity, ident, true, user);
        makeLink(aclIdentity, ident, true, user);
        mDb.flush();
        makeLink(clientIdentity, ident, true, user);
        makeLink(aclIdentity, ident, true, user);
        mDb.flush();
@@ -370,24 +511,20 @@ void CodeSignatures::debugDump(const char *how) const
        if (!how)
                how = "dump";
        CssmData key, value;
        if (!how)
                how = "dump";
        CssmData key, value;
-       if (!mDb) {
-               dump("CODE EQUIVALENTS DATABASE IS NOT OPEN (%s)", how);
+       if (!mDb.first(key, value)) {
+               dump("CODE EQUIVALENTS DATABASE IS EMPTY (%s)\n", how);
        } else {
        } else {
-               if (!mDb.first(key, value)) {
-                       dump("CODE EQUIVALENTS DATABASE IS EMPTY (%s)\n", how);
-               } else {
-                       dump("CODE EQUIVALENTS DATABASE DUMP (%s)\n", how);
-                       do {
-                               const char *header = key.interpretedAs<const char>();
-                               size_t headerLength = strlen(header) + 1;
-                               dump("%s:", header);
-                               dumpData(key.at(headerLength), key.length() - headerLength);
-                               dump(" => ");
-                               dumpData(value);
-                               dump("\n");
-                       } while (mDb.next(key, value));
-                       dump("END DUMP\n");
-               }
+               dump("CODE EQUIVALENTS DATABASE DUMP (%s)\n", how);
+               do {
+                       const char *header = key.interpretedAs<const char>();
+                       size_t headerLength = strlen(header) + 1;
+                       dump("%s:", header);
+                       dumpData(key.at(headerLength), key.length() - headerLength);
+                       dump(" => ");
+                       dumpData(value);
+                       dump("\n");
+               } while (mDb.next(key, value));
+               dump("END DUMP\n");
        }
 }
 
        }
 }
 
@@ -398,9 +535,8 @@ void CodeSignatures::Identity::debugDump(const char *how) const
                how = "dump";
        dump("IDENTITY (%s) path=%s", how, getPath().c_str());
        dump(" name=%s hash=", mName.empty() ? "(unset)" : mName.c_str());
                how = "dump";
        dump("IDENTITY (%s) path=%s", how, getPath().c_str());
        dump(" name=%s hash=", mName.empty() ? "(unset)" : mName.c_str());
-       CodeSigning::OSXSigner signer;
-       dumpData(getHash(signer));
+       dumpData(getHash());
        dump("\n");
 }
 
        dump("\n");
 }
 
-#endif //DEBUGDUMP
\ No newline at end of file
+#endif //DEBUGDUMP
index 5b38e04a76a74030563e49e8acaa350da185e003..02cf40fc1c416437ddb142098f167f45eda1dc29 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2003-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
 #ifndef _H_CODESIGDB
 #define _H_CODESIGDB
 
 #ifndef _H_CODESIGDB
 #define _H_CODESIGDB
 
+#include "acls.h"
 #include <security_cdsa_utilities/db++.h>
 #include <security_cdsa_utilities/db++.h>
-#include <security_cdsa_client/osxsigner.h>
+#include <security_cdsa_utilities/osxverifier.h>
+#include <Security/CodeSigning.h>
 
 
 class Process;
 
 
 class Process;
@@ -64,7 +66,7 @@ public:
                IFDUMP(void debugDump(const char *how = NULL) const);
                
                virtual std::string getPath() const = 0;
                IFDUMP(void debugDump(const char *how = NULL) const);
                
                virtual std::string getPath() const = 0;
-               virtual const CssmData getHash(CodeSigning::OSXSigner &signer) const = 0;
+               virtual const CssmData getHash() const = 0;
        
        private:
                enum { untried, valid, invalid } mState;
        
        private:
                enum { untried, valid, invalid } mState;
@@ -81,7 +83,6 @@ public:
        bool find(Identity &id, uid_t user);
        
        void makeLink(Identity &id, const std::string &ident, bool forUser = false, uid_t user = 0);
        bool find(Identity &id, uid_t user);
        
        void makeLink(Identity &id, const std::string &ident, bool forUser = false, uid_t user = 0);
-       void makeApplication(const std::string &name, const std::string &path);
 
        void addLink(const CssmData &oldHash, const CssmData &newHash,
                const char *name, bool forSystem);
 
        void addLink(const CssmData &oldHash, const CssmData &newHash,
                const char *name, bool forSystem);
@@ -90,12 +91,15 @@ public:
        IFDUMP(void debugDump(const char *how = NULL) const);
        
 public:
        IFDUMP(void debugDump(const char *how = NULL) const);
        
 public:
-       bool verify(Process &process,
-               const CodeSigning::Signature *trustedSignature, const CssmData *comment);
+       bool verify(Process &process, const OSXVerifier &verifier, const AclValidationContext &context);
+       
+private:
+       OSStatus matchSignedClientToLegacyACL(Process &process, SecCodeRef code,
+               const OSXVerifier &verifier, const AclValidationContext &context);
+       bool verifyLegacy(Process &process, const CssmData &signature, string path);
        
 private:
        UnixPlusPlus::UnixDb mDb;
        
 private:
        UnixPlusPlus::UnixDb mDb;
-       CodeSigning::OSXSigner mSigner;
 
        // lock hierarchy: mUILock first, then mDatabaseLock, no back-off
        Mutex mDatabaseLock;                    // controls mDb access
 
        // lock hierarchy: mUILock first, then mDatabaseLock, no back-off
        Mutex mDatabaseLock;                    // controls mDb access
index ba2e64cba9e0a58aa1aaa9c2427e1ebeaea5a732..ea4fbd71a45d83057e45b53d6c25ee84fecc50fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -49,8 +49,7 @@
 // Construct a Connection object.
 //
 Connection::Connection(Process &proc, Port rPort)
 // Construct a Connection object.
 //
 Connection::Connection(Process &proc, Port rPort)
- : mClientPort(rPort), state(idle), agentWait(NULL),
-   aclUpdateTrigger(NULL)
+ : mClientPort(rPort), mGuestRef(kSecNoGuest), state(idle), agentWait(NULL)
 {
        parent(proc);
        
 {
        parent(proc);
        
@@ -73,6 +72,16 @@ Connection::~Connection()
 }
 
 
 }
 
 
+//
+// Set the (last known) guest handle for this connection.
+//
+void Connection::guestRef(SecGuestRef newGuest, SecCSFlags flags)
+{
+       secdebug("SS", "Connection %p switches to guest 0x%x", this, newGuest);
+       mGuestRef = newGuest;
+}
+
+
 //
 // Terminate a Connection normally.
 // This is assumed to be properly sequenced, so no thread races are possible.
 //
 // Terminate a Connection normally.
 // This is assumed to be properly sequenced, so no thread races are possible.
@@ -125,6 +134,7 @@ void Connection::beginWork()
        switch (state) {
        case idle:
                state = busy;
        switch (state) {
        case idle:
                state = busy;
+               mOverrideReturn = CSSM_OK;      // clear override
                break;
        case busy:
                secdebug("SS", "Attempt to re-enter connection %p(port %d)", this, mClientPort.port());
                break;
        case busy:
                secdebug("SS", "Attempt to re-enter connection %p(port %d)", this, mClientPort.port());
@@ -148,20 +158,12 @@ void Connection::checkWork()
        }
 }
 
        }
 }
 
-void Connection::endWork()
+void Connection::endWork(CSSM_RETURN &rcode)
 {
        switch (state) {
        case busy:
 {
        switch (state) {
        case busy:
-               // process the n-step aclUpdateTrigger
-               if (aclUpdateTrigger) {
-            if (--aclUpdateTriggerCount == 0) {
-                aclUpdateTrigger = NULL;
-                secdebug("kcacl", "acl update trigger expires");
-            } else
-                secdebug("kcacl", "acl update trigger armed for %d calls",
-                    aclUpdateTriggerCount);
-        }
-               // end involvement
+               if (mOverrideReturn && rcode == CSSM_OK)
+                       rcode = mOverrideReturn;
                state = idle;
                return;
        case dying:
                state = idle;
                return;
        case dying:
index 72d5d805504ec4564e185fcb61a001d87ecadb93..551c88826be417114b4ba5f26f8a5d8ecf4433d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
 #define _H_CONNECTION
 
 #include <security_agent_client/agentclient.h>
 #define _H_CONNECTION
 
 #include <security_agent_client/agentclient.h>
-#include <security_utilities/osxcode.h>
 #include "process.h"
 #include "session.h"
 #include "process.h"
 #include "session.h"
-#include "key.h"
+#include "notifications.h"
 #include <string>
 
 using MachPlusPlus::Port;
 #include <string>
 
 using MachPlusPlus::Port;
@@ -43,12 +42,15 @@ class Session;
 
 //
 // A Connection object represents an established connection between a client
 
 //
 // A Connection object represents an established connection between a client
-// and securityd. Note that in principle, a client process can have
-// multiple Connections (each represented by an IPC channel), though there will
-// usually be only one.
+// and securityd. There is a separate Connection object for each Mach reply port
+// that was (ever) used to talk to securityd. In practice, this maps to one reply
+// port (and thus one Connection) for each client thread that (ever) talks to securityd.
 //
 //
-class Connection : public PerConnection {
-       typedef Key::Handle KeyHandle;
+// If a client tricked us into using multiple reply ports from one thread, we'd treat
+// them as distinct client threads (which really doesn't much matter to us). The standard
+// client library (libsecurityd) won't let you do that.
+//
+class Connection : public PerConnection, public Listener::JitterBuffer {
 public:
        Connection(Process &proc, Port rPort);
        virtual ~Connection();
 public:
        Connection(Process &proc, Port rPort);
        virtual ~Connection();
@@ -56,28 +58,31 @@ public:
        void abort(bool keepReplyPort = false); // abnormal termination
        
     Port clientPort() const    { return mClientPort; }
        void abort(bool keepReplyPort = false); // abnormal termination
        
     Port clientPort() const    { return mClientPort; }
+       
+       // Code Signing guest management - tracks current guest id in client
+       SecGuestRef guestRef() const { return mGuestRef; }
+       void guestRef(SecGuestRef newGuest, SecCSFlags flags = 0);
 
        // work framing - called as work threads pick up connection work
        void beginWork();               // I've got it
        void checkWork();               // everything still okay?
 
        // work framing - called as work threads pick up connection work
        void beginWork();               // I've got it
        void checkWork();               // everything still okay?
-       void endWork();                 // Done with this
+       void endWork(CSSM_RETURN &rcode); // Done with this
        
        // notify that a SecurityAgent call may hang the active worker thread for a while
        void useAgent(SecurityAgent::Client *client)
        { StLock<Mutex> _(*this); agentWait = client; }
        
        
        // notify that a SecurityAgent call may hang the active worker thread for a while
        void useAgent(SecurityAgent::Client *client)
        { StLock<Mutex> _(*this); agentWait = client; }
        
-       // special UI convenience - set a don't-ask-again trigger for Keychain-style ACLs
-       void setAclUpdateTrigger(const SecurityServerAcl &object)
-       { aclUpdateTrigger = &object; aclUpdateTriggerCount = aclUpdateTriggerLimit + 1; }
-       bool aclWasSetForUpdateTrigger(const SecurityServerAcl &object) const
-       { return aclUpdateTriggerCount > 0 && aclUpdateTrigger == &object; }
+       // set an overriding CSSM_RETURN to return instead of success
+       void overrideReturn(CSSM_RETURN rc) { mOverrideReturn = rc; }
        
        Process &process() const { return parent<Process>(); }
        Session &session() const { return process().session(); }
        
 private:
        // peer state: established during connection startup; fixed thereafter
        
        Process &process() const { return parent<Process>(); }
        Session &session() const { return process().session(); }
        
 private:
        // peer state: established during connection startup; fixed thereafter
-       Port mClientPort;
+       Port mClientPort;                       // client's Mach reply port
+       SecGuestRef mGuestRef;          // last known Code Signing guest reference for this client thread
+       CSSM_RETURN mOverrideReturn; // override successful return code (only)
        
        // transient state (altered as we go)
        enum State {
        
        // transient state (altered as we go)
        enum State {
@@ -86,11 +91,6 @@ private:
                dying                                   // busy and scheduled to die as soon as possible
        } state;
        SecurityAgent::Client *agentWait;       // SA client session we may be waiting on
                dying                                   // busy and scheduled to die as soon as possible
        } state;
        SecurityAgent::Client *agentWait;       // SA client session we may be waiting on
-       
-       // see KeychainPromptAclSubject in acl_keychain.cpp for more information on this
-       const SecurityServerAcl *aclUpdateTrigger; // update trigger set for this (NULL if none)
-    uint8 aclUpdateTriggerCount; // number of back-to-back requests honored
-    static const uint8 aclUpdateTriggerLimit = 3;      // 3 calls (getAcl+getOwner+changeAcl)
 };
 
 
 };
 
 
diff --git a/src/credential.cpp b/src/credential.cpp
new file mode 100644 (file)
index 0000000..eab7c83
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2000-2004 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 "credential.h"
+#include <pwd.h>
+#include <syslog.h>
+
+#include <Security/checkpw.h>
+extern "C" int checkpw_internal( const struct passwd *pw, const char* password );
+#include "server.h"
+
+namespace Authorization {
+
+// default credential: invalid for everything, needed as a default session credential
+CredentialImpl::CredentialImpl() : mUid(0), mShared(false), mName(""), mRealname(""), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(false), mRight(false)
+{
+}
+
+// only for testing whether this credential is usable
+CredentialImpl::CredentialImpl(const uid_t uid, const string &username, const string &realname, bool shared) : mUid(uid), mShared(shared), mName(username), mRealname(realname), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(true), mRight(false)
+{
+}
+
+CredentialImpl::CredentialImpl(const string &username, const string &password, bool shared) : mShared(shared), mName(username), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(false), mRight(false)
+{
+    Server::active().longTermActivity();
+    const char *user = username.c_str();
+    struct passwd *pw = getpwnam(user);
+
+    do {
+        if (!pw) {
+                       syslog(LOG_ERR, "getpwnam() failed for user %s, creating invalid credential", user);
+            break;
+        }
+
+        mUid = pw->pw_uid;
+        mName = pw->pw_name;
+        mRealname = pw->pw_gecos;
+
+        const char *passwd = password.c_str();
+        int checkpw_status = checkpw_internal(pw, passwd);
+
+        if (checkpw_status != CHECKPW_SUCCESS) {
+            syslog(LOG_ERR, "checkpw() returned %d; failed to authenticate user %s (uid %lu).", checkpw_status, pw->pw_name, pw->pw_uid);
+            break;
+        }
+
+               syslog(LOG_INFO, "checkpw() succeeded, creating%s credential for user %s", mShared ? " shared" : "", user);
+
+        mValid = true;
+
+        endpwent();
+    } while (0);
+}
+
+CredentialImpl::CredentialImpl(const string &right, bool shared) : mUid(-2), mShared(shared), mName(right), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(true), mRight(true)
+{
+}
+
+CredentialImpl::~CredentialImpl()
+{
+}
+
+bool
+CredentialImpl::operator < (const CredentialImpl &other) const
+{
+        if (!mShared && other.mShared)
+                return true;
+        if (!other.mShared && mShared)
+                return false;
+
+        return mUid < other.mUid;
+}
+
+// Returns true if this CredentialImpl should be shared.
+bool
+CredentialImpl::isShared() const
+{
+        return mShared;
+}
+
+// Merge with other
+void
+CredentialImpl::merge(const CredentialImpl &other)
+{
+        assert(mUid == other.mUid);
+
+        if (other.mValid && (!mValid || mCreationTime < other.mCreationTime))
+        {
+                mCreationTime = other.mCreationTime;
+                mValid = true;
+        }
+}
+
+// The time at which this credential was obtained.
+CFAbsoluteTime
+CredentialImpl::creationTime() const
+{
+        return mCreationTime;
+}
+
+// Return true iff this credential is valid.
+bool
+CredentialImpl::isValid() const
+{
+        return mValid;
+}
+
+void
+CredentialImpl::invalidate()
+{
+        mValid = false;
+}
+
+//
+// Credential class
+//
+Credential::Credential() :
+RefPointer<CredentialImpl>(new CredentialImpl())
+{
+}
+
+Credential::Credential(CredentialImpl *impl) :
+RefPointer<CredentialImpl>(impl)
+{
+}
+
+Credential::Credential(const uid_t uid, const string &username, const string &realname, bool shared) :
+RefPointer<CredentialImpl>(new CredentialImpl(uid, username, realname, shared))
+{
+}
+
+Credential::Credential(const string &username, const string &password, bool shared) : RefPointer<CredentialImpl>(new CredentialImpl(username, password, shared))
+{
+}
+
+Credential::Credential(const string &right, bool shared) : RefPointer<CredentialImpl>(new CredentialImpl(right, shared))
+{
+}
+
+Credential::~Credential()
+{
+}
+
+bool
+Credential::operator < (const Credential &other) const
+{
+        if (!*this)
+                return other;
+
+        if (!other)
+                return false;
+
+        return (**this) < (*other);
+}
+
+} // end namespace Authorization
+
+
diff --git a/src/credential.h b/src/credential.h
new file mode 100644 (file)
index 0000000..78363ee
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2000-2004 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@
+ */
+
+#ifndef _H_CREDENTIAL
+#define _H_CREDENTIAL
+
+#include <security_utilities/refcount.h>
+#include <CoreFoundation/CFDate.h>
+#include <set>
+
+namespace Authorization {
+
+/* Credentials are less than comparable so they can be put in sets or maps. */
+class CredentialImpl : public RefCount
+{
+public:
+               CredentialImpl();
+        CredentialImpl(const uid_t uid, const string &username, const string &realname, bool shared);
+        CredentialImpl(const string &username, const string &password, bool shared);
+               CredentialImpl(const string &right, bool shared);
+        ~CredentialImpl();
+
+        bool operator < (const CredentialImpl &other) const;
+
+        // Returns true if this credential should be shared.
+        bool isShared() const;
+
+        // Merge with other
+        void merge(const CredentialImpl &other);
+
+        // The time at which this credential was obtained.
+        CFAbsoluteTime creationTime() const;
+
+        // Return true iff this credential is valid.
+        bool isValid() const;
+
+        // Make this credential invalid.
+        void invalidate();
+
+        // We could make Rule a friend but instead we just expose this for now
+        inline const uid_t uid() const { return mUid; }
+        inline const string& name() const { return mName; }
+        inline const string& realname() const { return mRealname; }
+               inline const bool isRight() const { return mRight; }
+private:
+        // Key
+        uid_t mUid;
+
+        // True iff this credential is shared.
+        bool mShared;
+
+        // Fields below are not used by less than operator
+
+        // The username of the user that provided his password.
+        string mName;
+        string mRealname;
+
+        CFAbsoluteTime mCreationTime;
+        bool mValid;
+               bool mRight;
+};
+
+/* Credentials are less than comparable so they can be put in sets or maps. */
+class Credential : public RefPointer<CredentialImpl>
+{
+public:
+        Credential();
+        Credential(CredentialImpl *impl);
+        Credential(const uid_t uid, const string &username, const string &realname, bool shared);
+        Credential(const string &username, const string &password, bool shared);
+               Credential(const string &right, bool shared);           
+        ~Credential();
+
+        bool operator < (const Credential &other) const;
+};
+
+typedef set<Credential> CredentialSet;
+
+} // namespace Authorization
+
+#endif // _H_CREDENTIAL
diff --git a/src/csproxy.cpp b/src/csproxy.cpp
new file mode 100644 (file)
index 0000000..6511b43
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2006-2007 Apple 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@
+ */
+
+
+//
+// csproxy - Code Signing Hosting Proxy
+//
+#include "csproxy.h"
+#include "server.h"
+#include <securityd_client/cshosting.h>
+
+
+//
+// Construct a CodeSigningHost
+//
+CodeSigningHost::CodeSigningHost()
+       : mHostingState(noHosting)
+{
+}
+
+
+//
+// Cleanup code.
+//
+CodeSigningHost::~CodeSigningHost()
+{
+       reset();
+}
+
+
+//
+// Reset Code Signing Hosting state.
+// This turns hosting off and clears all children.
+//
+void CodeSigningHost::reset()
+{
+       switch (mHostingState) {
+       case noHosting:
+               break;  // nothing to do
+       case dynamicHosting:
+               mHostingPort.destroy();
+               mHostingPort = MACH_PORT_NULL;
+               break;
+       case proxyHosting:
+               Server::active().remove(*this); // unhook service handler
+               mHostingPort.destroy(); // destroy receive right
+               mHostingState = noHosting;
+               mHostingPort = MACH_PORT_NULL;
+               mGuests.erase(mGuests.begin(), mGuests.end());
+               break;
+       }
+}
+
+
+//
+// Given a host reference (possibly NULL for the process itself), locate
+// its most dedicated guest. This descends a contiguous chain of dedicated
+// guests until it find a host that either has no guests, or whose guests
+// are not dedicated.
+//
+CodeSigningHost::Guest *CodeSigningHost::findHost(SecGuestRef hostRef)
+{
+       Guest *host = findGuest(hostRef, true);
+       for (;;) {
+               if (Guest *guest = findGuest(host))
+                       if (guest->dedicated) {
+                               secdebug("hosting", "%p selecting dedicated guest %p of %p", this, guest, host);
+                               host = guest;
+                               continue;
+                       }
+               return host;
+       }
+}
+
+
+//
+// Look up guest by guestRef.
+// Throws if they we don't have a guest by that ref.
+//
+CodeSigningHost::Guest *CodeSigningHost::findGuest(SecGuestRef guestRef, bool hostOk /* = false */)
+{
+       GuestMap::iterator it = mGuests.find(guestRef);
+       if (it == mGuests.end())
+               if (hostOk)
+                       return NULL;
+               else
+                       MacOSError::throwMe(errSecCSNoSuchCode);
+       assert(it->first == it->second->guestRef());
+       return it->second;
+}
+
+
+//
+// Look up guest by attribute set.
+// Returns the host if the attributes can't be found (*loose* interpretation).
+// Throws if multiple guests are found (ambiguity).
+// Implicitly matches dedicated guests no matter what attributes are requested.
+//
+CodeSigningHost::Guest *CodeSigningHost::findGuest(Guest *host, const CssmData &attrData)
+{
+       CFRef<CFDictionaryRef> attrDict = attrData
+               ? makeCFDictionaryFrom(attrData.data(), attrData.length())
+               : makeCFDictionary(0);
+       CFDictionary attrs(attrDict, errSecCSInvalidAttributeValues);
+       
+       // if a guest handle was provided, start with that - it must be valid or we fail
+       if (CFNumberRef canonical = attrs.get<CFNumberRef>(kSecGuestAttributeCanonical)) {
+               // direct lookup by SecGuestRef (canonical guest handle)
+               SecGuestRef guestRef = cfNumber<SecGuestRef>(canonical);
+               secdebug("hosting", "host %p looking for guest handle 0x%x", host, guestRef);
+               if (Guest *guest = findGuest(guestRef, true))   // found guest handle
+                       if (guest->isGuestOf(host, loose)) {
+                               secdebug("hosting", "found guest %p, continuing search", guest);
+                               host = guest;           // new starting point
+                       } else
+                               MacOSError::throwMe(errSecCSNoSuchCode); // not a guest of given host
+               else
+                       MacOSError::throwMe(errSecCSNoSuchCode); // not there at all
+       }
+       
+       // now take the rest of the attrs
+       CFIndex count = CFDictionaryGetCount(attrs);
+       CFTypeRef keys[count], values[count];
+       CFDictionaryGetKeysAndValues(attrs, keys, values);
+       for (;;) {
+               secdebug("hosting", "searching host %p by attributes", host);
+               Guest *match = NULL;    // previous match found
+               for (GuestMap::const_iterator it = mGuests.begin(); it != mGuests.end(); ++it)
+                       if (it->second->isGuestOf(host, strict))
+                               if (it->second->matches(count, keys, values))
+                                       if (match)
+                                               MacOSError::throwMe(errSecCSMultipleGuests);    // ambiguous
+                                       else
+                                               match = it->second;
+               if (!match) {           // nothing found
+                       secdebug("hosting", "nothing found, returning %p", host);
+                       return host;
+               } else {
+                       secdebug("hosting", "found guest %p, continuing", match);
+                       host = match;   // and repeat
+               }
+       }
+}
+
+
+//
+// Find any guest of a given host.
+// This will return a randomly chosen guest of this host if it has any,
+// or NULL if it has none (i.e. it is not a host).
+//
+CodeSigningHost::Guest *CodeSigningHost::findGuest(Guest *host)
+{
+       for (GuestMap::const_iterator it = mGuests.begin(); it != mGuests.end(); ++it)
+               if (it->second->isGuestOf(host, strict))
+                       return it->second;
+       return NULL;
+}
+
+
+//
+// Register a hosting API service port where the host will dynamically
+// answer hosting queries from interested parties. This switches the process
+// to dynamic hosting mode, and is incompatible with proxy hosting.
+//
+void CodeSigningHost::registerCodeSigning(mach_port_t hostingPort, SecCSFlags flags)
+{
+       switch (mHostingState) {
+       case noHosting:
+               secdebug("hosting", "%p registering for dynamic hosting on port %d",
+                       this, hostingPort);
+               mHostingPort = hostingPort;
+               mHostingState = dynamicHosting;
+               break;
+       default:
+               MacOSError::throwMe(errSecCSHostProtocolContradiction);
+       }
+}
+
+
+//
+// Create a guest entry for the given host and prepare to answer for it
+// when dynamic hosting queries are received for it.
+// This engages proxy hosting mode, and is incompatible with dynamic hosting mode.
+//
+SecGuestRef CodeSigningHost::createGuest(SecGuestRef hostRef,
+               uint32_t status, const char *path, const CssmData &attributes, SecCSFlags flags)
+{
+       secdebug("hosting", "%p create guest from host %d", this, hostRef);
+       
+       if (path[0] != '/')             // relative path (relative to what? :-)
+               MacOSError::throwMe(errSecCSHostProtocolRelativePath);
+       
+       // set up for hosting proxy services if nothing's there yet
+       switch (mHostingState) {
+       case noHosting:
+               // set up proxy hosting
+               mHostingPort.allocate();
+               MachServer::Handler::port(mHostingPort);
+               MachServer::active().add(*this);
+               mHostingState = proxyHosting;
+               secdebug("hosting", "%p created hosting port %d for proxy hosting", this, mHostingPort.port());
+               break;
+       case proxyHosting:
+               break;          // all set
+       case dynamicHosting:
+               MacOSError::throwMe(errSecCSHostProtocolContradiction);
+       }
+       
+       RefPointer<Guest> host = findHost(hostRef);
+       RefPointer<Guest> knownGuest = findGuest(host);
+       if ((flags & kSecCSDedicatedHost) && knownGuest)
+               MacOSError::throwMe(errSecCSHostProtocolDedicationError);       // can't dedicate with other guests
+       else if (knownGuest && knownGuest->dedicated)
+               MacOSError::throwMe(errSecCSHostProtocolDedicationError);       // other guest is already dedicated
+
+       // create the new guest
+       RefPointer<Guest> guest = new Guest;
+       if (host)
+               guest->guestPath = host->guestPath;
+       guest->guestPath.push_back(guest->handle());
+       guest->status = status;
+       guest->path = path;
+       guest->setAttributes(attributes);
+       guest->dedicated = (flags & kSecCSDedicatedHost);
+       mGuests[guest->guestRef()] = guest;
+       secdebug("hosting", "guest 0x%x created %sstatus=0x%x path=%s",
+               guest->guestRef(), guest->dedicated ? "dedicated " : "", guest->status, guest->path.c_str());
+       return guest->guestRef();
+}
+
+
+void CodeSigningHost::setGuestStatus(SecGuestRef guestRef, uint32_t status, const CssmData &attributes)
+{
+       secdebug("hosting", "%p set guest 0x%x", this, guestRef);
+       if (mHostingState != proxyHosting)
+               MacOSError::throwMe(errSecCSHostProtocolNotProxy);
+       Guest *guest = findGuest(guestRef);
+
+       // state modification machine
+       if ((status & ~guest->status) & CS_VALID)
+               MacOSError::throwMe(errSecCSHostProtocolStateError); // can't set
+       if ((~status & guest->status) & (CS_HARD | CS_KILL))
+               MacOSError::throwMe(errSecCSHostProtocolStateError); // can't clear
+       guest->status = status;
+
+       // replace attributes if requested
+       if (attributes)
+               guest->setAttributes(attributes);
+}
+
+
+//
+// Remove a guest previously introduced via createGuest().
+//
+void CodeSigningHost::removeGuest(SecGuestRef hostRef, SecGuestRef guestRef)
+{
+       secdebug("hosting", "%p removes guest %d from host %d", this, guestRef, hostRef);
+       if (mHostingState != proxyHosting) 
+               MacOSError::throwMe(errSecCSHostProtocolNotProxy);
+       RefPointer<Guest> host = findHost(hostRef);
+       RefPointer<Guest> guest = findGuest(guestRef);
+       if (guest->dedicated)   // can't remove a dedicated guest
+               MacOSError::throwMe(errSecCSHostProtocolDedicationError);
+       if (!guest->isGuestOf(host, strict))
+               MacOSError::throwMe(errSecCSHostProtocolUnrelated);
+       for (GuestMap::iterator it = mGuests.begin(); it != mGuests.end(); ++it)
+               if (it->second->isGuestOf(guest, loose))
+                       mGuests.erase(it);
+}
+
+
+//
+// The internal Guest object
+//
+CodeSigningHost::Guest::~Guest()
+{
+       secdebug("hosting", "guest %ld destroyed", handle());
+}
+
+void CodeSigningHost::Guest::setAttributes(const CssmData &attrData)
+{
+       CFRef<CFNumberRef> guest = makeCFNumber(guestRef());
+       if (attrData) {
+               CFRef<CFDictionaryRef> inputDict = makeCFDictionaryFrom(attrData.data(), attrData.length());
+               CFRef<CFMutableDictionaryRef> dict = CFDictionaryCreateMutableCopy(NULL, 0, inputDict);
+               CFDictionaryAddValue(dict, kSecGuestAttributeCanonical, guest);
+               attributes.take(dict);
+       } else {
+               attributes.take(makeCFDictionary(1, kSecGuestAttributeCanonical, guest.get()));
+       }
+}
+
+
+bool CodeSigningHost::Guest::isGuestOf(Guest *host, GuestCheck check) const
+{
+       vector<SecGuestRef> hostPath;
+       if (host)
+               hostPath = host->guestPath;
+       if (hostPath.size() <= guestPath.size()
+                       && !memcmp(&hostPath[0], &guestPath[0], sizeof(SecGuestRef) * hostPath.size()))
+               // hostPath is a prefix of guestPath
+               switch (check) {
+               case loose:
+                       return true;
+               case strict:
+                       return guestPath.size() == hostPath.size() + 1; // immediate guest
+               }
+       return false;
+}
+
+
+//
+// Check to see if a given guest matches the (possibly empty) attribute set provided
+// (in broken-open form, for efficiency). A dedicated guest will match all attribute
+// specifications, even empty ones. A non-dedicated guest matches if at least one
+// attribute value requested matches exactly (in the sense of CFEqual) that given
+// by the host for this guest.
+// 
+bool CodeSigningHost::Guest::matches(CFIndex count, CFTypeRef keys[], CFTypeRef values[]) const
+{
+       if (dedicated)
+               return true;
+       for (CFIndex n = 0; n < count; n++) {
+               CFStringRef key = CFStringRef(keys[n]);
+               if (CFEqual(key, kSecGuestAttributeCanonical))  // ignore canonical attribute (handled earlier)
+                       continue;
+               if (CFTypeRef value = CFDictionaryGetValue(attributes, key))
+                       if (CFEqual(value, values[n]))
+                               return true;
+       }
+       return false;
+}
+
+
+//
+// The MachServer dispatch handler for proxy hosting.
+//
+boolean_t cshosting_server(mach_msg_header_t *, mach_msg_header_t *);
+
+static ThreadNexus<CodeSigningHost *> context;
+
+boolean_t CodeSigningHost::handle(mach_msg_header_t *in, mach_msg_header_t *out)
+{
+       context() = this;
+       return cshosting_server(in, out);
+}
+
+
+//
+// Proxy implementation of Code Signing Hosting protocol
+//
+#define CSH_ARGS       mach_port_t servicePort, mach_port_t replyPort, OSStatus *rcode
+       
+#define BEGIN_IPC      try {
+#define END_IPC                *rcode = noErr; } \
+       catch (const CommonError &err) { *rcode = err.osStatus(); } \
+       catch (...) { *rcode = errSecCSInternalError; } \
+       return KERN_SUCCESS;
+
+#define DATA_IN(base)  void *base, mach_msg_type_number_t base##Length
+#define DATA_OUT(base) void **base, mach_msg_type_number_t *base##Length
+#define DATA(base)             CssmData(base, base##Length)
+
+
+//
+// Find a guest by arbitrary attribute set.
+//
+// This returns an array of canonical guest references describing the path
+// from the host given to the guest found. If the host itself is returned
+// as a guest, this will be an empty array (zero length).
+//
+// The subhost return argument may in the future return the hosting port for
+// a guest who dynamically manages its hosting (thus breaking out of proxy mode),
+// but this is not yet implemented.
+//
+kern_return_t cshosting_server_findGuest(CSH_ARGS, SecGuestRef hostRef,
+       DATA_IN(attributes),
+       GuestChain *foundGuest, mach_msg_type_number_t *depth, mach_port_t *subhost)
+{
+       BEGIN_IPC
+               
+       *subhost = MACH_PORT_NULL;      // preset no sub-hosting port returned
+       
+       Process::Guest *host = context()->findGuest(hostRef, true);
+       if (Process::Guest *guest = context()->findGuest(host, DATA(attributes))) {
+               *foundGuest = &guest->guestPath[0];
+               *depth = guest->guestPath.size();
+       } else {
+               *foundGuest = NULL;
+               *depth = 0;
+       }
+       END_IPC
+}
+
+
+//
+// Retrieve the path to a guest specified by canonical reference.
+//
+kern_return_t cshosting_server_guestPath(CSH_ARGS, SecGuestRef guestRef, char *path)
+{
+       BEGIN_IPC
+       strncpy(path, context()->findGuest(guestRef)->path.c_str(), MAXPATHLEN);
+       END_IPC
+}
+
+
+//
+// Retrieve the status word for a guest specified by canonical reference.
+//
+kern_return_t cshosting_server_guestStatus(CSH_ARGS, SecGuestRef guestRef, uint32_t *status)
+{
+       BEGIN_IPC
+       *status = context()->findGuest(guestRef)->status;
+       END_IPC
+}
+
+
+//
+// Debug support
+//
+#if defined(DEBUGDUMP)
+
+void CodeSigningHost::dump() const
+{
+       switch (mHostingState) {
+       case noHosting:
+               break;
+       case dynamicHosting:
+               Debug::dump(" dynamic host port=%d", mHostingPort.port());
+               break;
+       case proxyHosting:
+               Debug::dump(" proxy-host port=%d", mHostingPort.port());
+               if (!mGuests.empty()) {
+                       Debug::dump(" %d guests={", int(mGuests.size()));
+                       for (GuestMap::const_iterator it = mGuests.begin(); it != mGuests.end(); ++it) {
+                               if (it != mGuests.begin())
+                                       Debug::dump(", ");
+                               it->second->dump();
+                       }
+                       Debug::dump("}");
+               }
+               break;
+       }
+}
+
+void CodeSigningHost::Guest::dump() const
+{
+       Debug::dump("%s[", path.c_str());
+       for (vector<SecGuestRef>::const_iterator it = guestPath.begin(); it != guestPath.end(); ++it) {
+               if (it != guestPath.begin())
+                       Debug::dump("/");
+               Debug::dump("0x%x", *it);
+       }
+       Debug::dump("; status=0x%x attrs=%s]",
+               status, cfString(CFCopyDescription(attributes), true).c_str());
+}
+
+#endif //DEBUGDUMP
diff --git a/src/csproxy.h b/src/csproxy.h
new file mode 100644 (file)
index 0000000..33a3662
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2006-2007 Apple 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@
+ */
+
+
+//
+// csproxy - Code Signing Hosting Proxy
+//
+#ifndef _H_CSPROXY
+#define _H_CSPROXY
+
+#include <security_utilities/cfutilities.h>
+#include <security_cdsa_utilities/handleobject.h>
+#include <security_utilities/mach++.h>
+#include <security_utilities/machserver.h>
+#include <security_cdsa_utilities/cssmdata.h>
+#include <Security/SecCodeHost.h>
+#include <string>
+#include <map>
+
+using MachPlusPlus::Port;
+using MachPlusPlus::MachServer;
+
+
+//
+// CodeSigningHost is a mix-in for an object representing a primary
+// Code Signing host object. It performs two notionally separate functions:
+//  (1) Register a hosting port.
+//  (2) Optionally, maintain a guest registry to offload the host's work.
+//
+class CodeSigningHost : private MachServer::Handler {
+public:
+       CodeSigningHost();
+       ~CodeSigningHost();
+       void reset();
+       
+       enum HostingState {
+               noHosting,                                      // is not a host (yet), could go either way
+               dynamicHosting,                         // gave us its own hosting port to keep
+               proxyHosting                            // we act as a proxy for it
+       };
+       
+       enum GuestCheck {
+               strict,                                         // direct guest relationship required
+               loose                                           // indirect or identity is okay (prefix check)
+       };
+       
+       struct Guest : public RefCount, public HandleObject {
+       public:
+               ~Guest();
+               std::vector<SecGuestRef> guestPath; // guest chain to this guest
+               uint32_t status;                        // dynamic status
+               std::string path;                       // canonical code path
+               CFRef<CFDictionaryRef> attributes; // matching attributes set
+               bool dedicated;                         // host is dedicated (and this is the only guest)
+               
+               operator bool() const { return attributes; }  // exists
+               SecGuestRef guestRef() const { return handle(); }
+               void setAttributes(const CssmData &attrData);
+               
+               bool isGuestOf(Guest *host, GuestCheck check) const;
+               bool matches(CFIndex count, CFTypeRef keys[], CFTypeRef values[]) const;
+               
+               IFDUMP(void dump() const);
+       };
+       
+       void registerCodeSigning(mach_port_t hostingPort, SecCSFlags flags);
+       Port hostingPort() const { return mHostingPort; }
+       
+       SecGuestRef createGuest(SecGuestRef guest,
+               uint32_t status, const char *path, const CssmData &attributes, SecCSFlags flags);
+       void setGuestStatus(SecGuestRef guest, uint32_t status, const CssmData &attributes);
+       void removeGuest(SecGuestRef host, SecGuestRef guest);
+       
+       Guest *findHost(SecGuestRef hostRef); // find most dedicated guest of this host
+       Guest *findGuest(Guest *host, const CssmData &attrData); // by host and attributes
+       Guest *findGuest(SecGuestRef guestRef, bool hostOk = false); // by guest reference
+       Guest *findGuest(Guest *host);          // any guest of this host
+       
+       IFDUMP(void dump() const);
+       
+private:
+       boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out);
+       void eraseGuest(Guest *guest);
+
+private:       
+       // host port registry
+       HostingState mHostingState;                     // status of hosting support
+       Port mHostingPort;                                      // his or ours or NULL
+
+       // guest map (only used if mHostingState == proxyHosting)
+       typedef std::map<SecGuestRef, RefPointer<Guest> > GuestMap;
+       GuestMap mGuests;
+};
+
+
+#endif //_H_CSPROXY
index cb49a92dbfd410ba6e48ec66f08bd32fd5ef99b9..a29cd70bf8f04a9cc8f26186844f0eb3167c011a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -67,7 +67,7 @@ Process& Database::process() const
 {
        return referent<Process>();
 }
 {
        return referent<Process>();
 }
-
+       
 
 //
 // Send a keychain-related notification event about this database
 
 //
 // Send a keychain-related notification event about this database
@@ -87,6 +87,7 @@ void DbCommon::notify(NotificationEvent event, const DLDbIdentifier &ident)
     free (data.data());
 }
 
     free (data.data());
 }
 
+
 //
 // Default behaviors
 //
 //
 // Default behaviors
 //
@@ -186,7 +187,7 @@ SecurityServerAcl &Database::acl()
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
 }
 
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
 }
 
-bool Database::isLocked() const
+bool Database::isLocked()
 {
        secdebug("database", "%p calling unimplemented isLocked", this);
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
 {
        secdebug("database", "%p calling unimplemented isLocked", this);
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
index b6b3bd9659ab7793e7caf2016b613bddb7180912..9534fcfed262de514afad5798cfb7034cfeeed6e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -65,7 +65,7 @@ public:
        DbCommon(Session &ssn);
        
        Session &session() const;
        DbCommon(Session &ssn);
        
        Session &session() const;
-       
+
        virtual void sleepProcessing();         // generic action on system sleep
        virtual void lockProcessing();          // generic action on "lock" requests
 
        virtual void sleepProcessing();         // generic action on system sleep
        virtual void lockProcessing();          // generic action on "lock" requests
 
@@ -148,7 +148,7 @@ public:
        virtual void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred);
        virtual SecurityServerAcl &acl();
 
        virtual void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred);
        virtual SecurityServerAcl &acl();
 
-       virtual bool isLocked() const;
+       virtual bool isLocked();
 
 public:
        class Search : public Subsidiary {
 
 public:
        class Search : public Subsidiary {
index 5054f85d1d6f71605795223fdda52c108599f1ac..98b1caabc4ca3c672887fdd368a4cb279b748167 100644 (file)
@@ -306,31 +306,45 @@ void DatabaseCryptoCore::importSecrets(const DatabaseCryptoCore &src)
 // Encode a key blob
 //
 KeyBlob *DatabaseCryptoCore::encodeKeyCore(const CssmKey &inKey,
 // Encode a key blob
 //
 KeyBlob *DatabaseCryptoCore::encodeKeyCore(const CssmKey &inKey,
-    const CssmData &publicAcl, const CssmData &privateAcl) const
+    const CssmData &publicAcl, const CssmData &privateAcl,
+       bool inTheClear) const
 {
 {
-    assert(isValid());         // need our database secrets
-    
-    // create new IV
-    uint8 iv[8];
-    Server::active().random(iv);
-    
-    // extract and hold some header bits the CSP does not want to see
     CssmKey key = inKey;
     CssmKey key = inKey;
+       uint8 iv[8];
+       CssmKey wrappedKey;
+
+       if(inTheClear && (privateAcl.Length != 0)) {
+               /* can't store private ACL component in the clear */
+               CssmError::throwMe(CSSMERR_DL_INVALID_ACCESS_CREDENTIALS);
+       }
+       
+    // extract and hold some header bits the CSP does not want to see
     uint32 heldAttributes = key.attributes() & managedAttributes;
     key.clearAttribute(managedAttributes);
        key.setAttribute(forcedAttributes);
     
     uint32 heldAttributes = key.attributes() & managedAttributes;
     key.clearAttribute(managedAttributes);
        key.setAttribute(forcedAttributes);
     
-    // use a CMS wrap to encrypt the key
-    WrapKey wrap(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE);
-    wrap.key(mEncryptionKey);
-    wrap.mode(CSSM_ALGMODE_CBCPadIV8);
-    wrap.padding(CSSM_PADDING_PKCS1);
-    CssmData ivd(iv, sizeof(iv)); wrap.initVector(ivd);
-    wrap.add(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT,
-        uint32(CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM));
-    CssmKey wrappedKey;
-    wrap(key, wrappedKey, &privateAcl);
-    
+       if(inTheClear) {
+               /* NULL wrap of public key */
+               WrapKey wrap(Server::csp(), CSSM_ALGID_NONE);
+               wrap(key, wrappedKey, NULL);
+       }
+       else {
+               assert(isValid());              // need our database secrets
+               
+               // create new IV
+               Server::active().random(iv);
+               
+          // use a CMS wrap to encrypt the key
+               WrapKey wrap(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE);
+               wrap.key(mEncryptionKey);
+               wrap.mode(CSSM_ALGMODE_CBCPadIV8);
+               wrap.padding(CSSM_PADDING_PKCS1);
+               CssmData ivd(iv, sizeof(iv)); wrap.initVector(ivd);
+               wrap.add(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT,
+                       uint32(CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM));
+               wrap(key, wrappedKey, &privateAcl);
+    }
+       
     // stick the held attribute bits back in
        key.clearAttribute(forcedAttributes);
     key.setAttribute(heldAttributes);
     // stick the held attribute bits back in
        key.clearAttribute(forcedAttributes);
     key.setAttribute(heldAttributes);
@@ -342,7 +356,9 @@ KeyBlob *DatabaseCryptoCore::encodeKeyCore(const CssmKey &inKey,
     // assemble the KeyBlob
     memset(blob, 0, sizeof(KeyBlob));  // fill alignment gaps
     blob->initialize();
     // assemble the KeyBlob
     memset(blob, 0, sizeof(KeyBlob));  // fill alignment gaps
     blob->initialize();
-    memcpy(blob->iv, iv, sizeof(iv));
+       if(!inTheClear) {
+               memcpy(blob->iv, iv, sizeof(iv));
+       }
     blob->header = key.header();
        h2ni(blob->header);     // endian-correct the header
     blob->wrappedHeader.blobType = wrappedKey.blobType();
     blob->header = key.header();
        h2ni(blob->header);     // endian-correct the header
     blob->wrappedHeader.blobType = wrappedKey.blobType();
@@ -354,17 +370,23 @@ KeyBlob *DatabaseCryptoCore::encodeKeyCore(const CssmKey &inKey,
     memcpy(blob->cryptoBlob(), wrappedKey.data(), wrappedKey.length());
     blob->totalLength = blob->startCryptoBlob + wrappedKey.length();
     
     memcpy(blob->cryptoBlob(), wrappedKey.data(), wrappedKey.length());
     blob->totalLength = blob->startCryptoBlob + wrappedKey.length();
     
-    // sign the blob
-    CssmData signChunk[] = {
-               CssmData(blob->data(), fieldOffsetOf(&KeyBlob::blobSignature)),
-       CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
-       };
-    CssmData signature(blob->blobSignature, sizeof(blob->blobSignature));
-    GenerateMac signer(Server::csp(), CSSM_ALGID_SHA1HMAC_LEGACY);     //@@@!!! CRUD
-    signer.key(mSigningKey);
-    signer.sign(signChunk, 2, signature);
-    assert(signature.length() == sizeof(blob->blobSignature));
-    
+       if(inTheClear) {
+               /* indicate that this is cleartext for decoding */
+               blob->setClearTextSignature();
+       }
+       else {
+               // sign the blob
+               CssmData signChunk[] = {
+                       CssmData(blob->data(), fieldOffsetOf(&KeyBlob::blobSignature)),
+                       CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
+               };
+               CssmData signature(blob->blobSignature, sizeof(blob->blobSignature));
+               GenerateMac signer(Server::csp(), CSSM_ALGID_SHA1HMAC_LEGACY);  //@@@!!! CRUD
+               signer.key(mSigningKey);
+               signer.sign(signChunk, 2, signature);
+               assert(signature.length() == sizeof(blob->blobSignature));
+    }
+       
     // all done. Clean up
     Server::csp()->allocator().free(wrappedKey);
     return blob;
     // all done. Clean up
     Server::csp()->allocator().free(wrappedKey);
     return blob;
@@ -376,9 +398,7 @@ KeyBlob *DatabaseCryptoCore::encodeKeyCore(const CssmKey &inKey,
 //
 void DatabaseCryptoCore::decodeKeyCore(KeyBlob *blob,
     CssmKey &key, void * &pubAcl, void * &privAcl) const
 //
 void DatabaseCryptoCore::decodeKeyCore(KeyBlob *blob,
     CssmKey &key, void * &pubAcl, void * &privAcl) const
-{
-    assert(isValid());         // need our database secrets
-    
+{    
     // Assemble the encrypted blob as a CSSM "wrapped key"
     CssmKey wrappedKey;
     wrappedKey.KeyHeader = blob->header;
     // Assemble the encrypted blob as a CSSM "wrapped key"
     CssmKey wrappedKey;
     wrappedKey.KeyHeader = blob->header;
@@ -389,39 +409,55 @@ void DatabaseCryptoCore::decodeKeyCore(KeyBlob *blob,
     wrappedKey.wrapMode(blob->wrappedHeader.wrapMode);
     wrappedKey.KeyData = CssmData(blob->cryptoBlob(), blob->cryptoBlobLength());
        
     wrappedKey.wrapMode(blob->wrappedHeader.wrapMode);
     wrappedKey.KeyData = CssmData(blob->cryptoBlob(), blob->cryptoBlobLength());
        
-    // verify signature (check against corruption)
-    CssmData signChunk[] = {
-       CssmData::wrap(blob, fieldOffsetOf(&KeyBlob::blobSignature)),
-       CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
-       };
-    CSSM_ALGORITHMS verifyAlgorithm = CSSM_ALGID_SHA1HMAC;
-#if defined(COMPAT_OSX_10_0)
-    if (blob->version() == blob->version_MacOS_10_0)
-        verifyAlgorithm = CSSM_ALGID_SHA1HMAC_LEGACY;  // BSafe bug compatibility
-#endif
-    VerifyMac verifier(Server::csp(), verifyAlgorithm);
-    verifier.key(mSigningKey);
-    CssmData signature(blob->blobSignature, sizeof(blob->blobSignature));
-    verifier.verify(signChunk, 2, signature);
-    
+       bool inTheClear = blob->isClearText();
+       if(!inTheClear) {
+               // verify signature (check against corruption)
+               assert(isValid());              // need our database secrets
+               CssmData signChunk[] = {
+                       CssmData::wrap(blob, fieldOffsetOf(&KeyBlob::blobSignature)),
+                       CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
+               };
+               CSSM_ALGORITHMS verifyAlgorithm = CSSM_ALGID_SHA1HMAC;
+       #if defined(COMPAT_OSX_10_0)
+               if (blob->version() == blob->version_MacOS_10_0)
+                       verifyAlgorithm = CSSM_ALGID_SHA1HMAC_LEGACY;   // BSafe bug compatibility
+       #endif
+               VerifyMac verifier(Server::csp(), verifyAlgorithm);
+               verifier.key(mSigningKey);
+               CssmData signature(blob->blobSignature, sizeof(blob->blobSignature));
+               verifier.verify(signChunk, 2, signature);
+    }
+       /* else signature indicates cleartext */
+       
     // extract and hold some header bits the CSP does not want to see
     uint32 heldAttributes = n2h(blob->header.attributes()) & managedAttributes;
    
     // extract and hold some header bits the CSP does not want to see
     uint32 heldAttributes = n2h(blob->header.attributes()) & managedAttributes;
    
-    // decrypt the key using an unwrapping operation
-    UnwrapKey unwrap(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE);
-    unwrap.key(mEncryptionKey);
-    unwrap.mode(CSSM_ALGMODE_CBCPadIV8);
-    unwrap.padding(CSSM_PADDING_PKCS1);
-    CssmData ivd(blob->iv, sizeof(blob->iv)); unwrap.initVector(ivd);
-    unwrap.add(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT,
-        uint32(CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM));
-    CssmData privAclData;
-    wrappedKey.clearAttribute(managedAttributes);    //@@@ shouldn't be needed(?)
-    unwrap(wrappedKey,
-        KeySpec(n2h(blob->header.usage()),
-                       (n2h(blob->header.attributes()) & ~managedAttributes) | forcedAttributes),
-        key, &privAclData);
-    
+       CssmData privAclData;
+       if(inTheClear) {
+               /* NULL unwrap */
+               UnwrapKey unwrap(Server::csp(), CSSM_ALGID_NONE);
+               wrappedKey.clearAttribute(managedAttributes);    //@@@ shouldn't be needed(?)
+               unwrap(wrappedKey,
+                       KeySpec(n2h(blob->header.usage()),
+                               (n2h(blob->header.attributes()) & ~managedAttributes) | forcedAttributes),
+                       key, &privAclData);
+       }
+       else {
+               // decrypt the key using an unwrapping operation
+               UnwrapKey unwrap(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE);
+               unwrap.key(mEncryptionKey);
+               unwrap.mode(CSSM_ALGMODE_CBCPadIV8);
+               unwrap.padding(CSSM_PADDING_PKCS1);
+               CssmData ivd(blob->iv, sizeof(blob->iv)); unwrap.initVector(ivd);
+               unwrap.add(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT,
+                       uint32(CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM));
+               wrappedKey.clearAttribute(managedAttributes);    //@@@ shouldn't be needed(?)
+               unwrap(wrappedKey,
+                       KeySpec(n2h(blob->header.usage()),
+                               (n2h(blob->header.attributes()) & ~managedAttributes) | forcedAttributes),
+                       key, &privAclData);
+    }
+       
     // compare retrieved key headers with blob headers (sanity check)
     // @@@ this should probably be checked over carefully
     CssmKey::Header &real = key.header();
     // compare retrieved key headers with blob headers (sanity check)
     // @@@ this should probably be checked over carefully
     CssmKey::Header &real = key.header();
@@ -437,9 +473,15 @@ void DatabaseCryptoCore::decodeKeyCore(KeyBlob *blob,
     // re-insert held bits
     key.header().KeyAttr |= heldAttributes;
     
     // re-insert held bits
     key.header().KeyAttr |= heldAttributes;
     
+       if(inTheClear && (real.keyClass() != CSSM_KEYCLASS_PUBLIC_KEY)) {
+               /* Spoof - cleartext KeyBlob passed off as private key */
+        CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
+       }
+       
     // got a valid key: return the pieces
     pubAcl = blob->publicAclBlob();            // points into blob (shared)
     // got a valid key: return the pieces
     pubAcl = blob->publicAclBlob();            // points into blob (shared)
-    privAcl = privAclData;                             // was allocated by CSP decrypt
+    privAcl = privAclData;                             // was allocated by CSP decrypt, else NULL for
+                                                                               // cleatext keys
     // key was set by unwrap operation
 }
 
     // key was set by unwrap operation
 }
 
index 16d42e3f00cd6798dc16af39b348f2e8f4628377..5970f514f5ac25bfafe3f0b4b2e78e4cb8235625 100644 (file)
@@ -61,13 +61,14 @@ public:
        void importSecrets(const DatabaseCryptoCore &src);
         
     KeyBlob *encodeKeyCore(const CssmKey &key,
        void importSecrets(const DatabaseCryptoCore &src);
         
     KeyBlob *encodeKeyCore(const CssmKey &key,
-        const CssmData &publicAcl, const CssmData &privateAcl) const;
+        const CssmData &publicAcl, const CssmData &privateAcl,
+               bool inTheClear) const;
     void decodeKeyCore(KeyBlob *blob,
         CssmKey &key, void * &pubAcl, void * &privAcl) const;
 
     static const uint32 managedAttributes = KeyBlob::managedAttributes;
        static const uint32 forcedAttributes = KeyBlob::forcedAttributes;
     void decodeKeyCore(KeyBlob *blob,
         CssmKey &key, void * &pubAcl, void * &privAcl) const;
 
     static const uint32 managedAttributes = KeyBlob::managedAttributes;
        static const uint32 forcedAttributes = KeyBlob::forcedAttributes;
-
+       
 public:
        bool validatePassphrase(const CssmData &passphrase);
        
 public:
        bool validatePassphrase(const CssmData &passphrase);
        
diff --git a/src/flippers.cpp b/src/flippers.cpp
deleted file mode 100644 (file)
index 4f8fa31..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2003-2004 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@
- */
-
-
-//
-// process - track a single client process and its belongings
-//
-#include "flippers.h"
-#include <security_utilities/memutils.h>
-
-using namespace LowLevelMemoryUtilities;
-
-
-namespace Flippers {
-
-//
-// The raw byte reversal flipper
-//
-void flip(void *addr, size_t size)
-{
-       assert(size > 1 && (size % 2 == 0));
-       Byte *word = reinterpret_cast<uint8 *>(addr);
-       for (size_t n = 0; n < size/2; n++) {
-               Byte b = word[n];
-               word[n] = word[size-1-n];
-               word[size-1-n] = b;
-       }
-}
-
-
-//
-// Basic flippers
-//
-void flip(uint32 &obj)         { flip(&obj, sizeof(obj)); }
-void flip(uint16 &obj)         { flip(&obj, sizeof(obj)); }
-void flip(sint32 &obj)         { flip(&obj, sizeof(obj)); }
-void flip(sint16 &obj)         { flip(&obj, sizeof(obj)); }
-
-
-//
-// Flip a context attribute. This is heavily polymorphic.
-//
-void flip(CSSM_CONTEXT_ATTRIBUTE &obj)
-{
-       flip(obj.AttributeType);
-       flip(obj.AttributeLength);
-       switch (obj.AttributeType & CSSM_ATTRIBUTE_TYPE_MASK) {
-       case CSSM_ATTRIBUTE_DATA_UINT32:
-               flip(obj.Attribute.Uint32);
-               break;
-       // all other alternatives are handled by CSSM_CONTEXT_ATTRIBUTE's walker
-       default:
-               break;
-       }
-}
-
-
-//
-// Flip a CSSM_DB_ATTRIBUTE_INFO, also very polymorphic
-//
-void flip(CSSM_DB_ATTRIBUTE_INFO &obj)
-{
-       bool flippedAttributeNameFormat = false;
-       // check and see if obj is in host byte order.  If not, flip it now
-       if (obj.AttributeNameFormat > CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER)
-       {
-               flip(obj.AttributeNameFormat);
-               flippedAttributeNameFormat = true;
-       }
-
-       switch (obj.AttributeNameFormat)
-       {
-               case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
-               {
-                       flip(obj.Label.AttributeID);
-               }
-               break;
-       }
-       
-       flip (obj.AttributeFormat);
-
-       if (!flippedAttributeNameFormat)
-       {
-               flip(obj.AttributeNameFormat);
-       }
-       
-}
-
-//
-// Automatically generated flippers
-//
-#include "flip_gen.cpp"
-
-
-}      // end namespace Flippers
diff --git a/src/flippers.h b/src/flippers.h
deleted file mode 100644 (file)
index 9d2fb8c..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2003-2004 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@
- */
-
-
-//
-// process - track a single client process and its belongings
-//
-#ifndef _H_FLIPPERS
-#define _H_FLIPPERS
-
-#include <security_utilities/endian.h>
-#include <security_utilities/debugging.h>
-
-// various types we make flippers for
-#include <Security/Authorization.h>
-#include <security_cdsa_utilities/cssmlist.h>
-#include <security_cdsa_utilities/cssmcred.h>
-#include <security_cdsa_utilities/cssmacl.h>
-#include <security_cdsa_utilities/cssmaclpod.h>
-#include <security_cdsa_utilities/context.h>
-#include <security_cdsa_utilities/cssmdb.h>
-
-
-namespace Flippers {
-
-
-//
-// The default flipper does nothing
-//
-template <class T>
-inline void flip(T &obj)
-{ }
-
-
-//
-// It's a bad idea to try to flip a const, so flag that
-//
-template <class T>
-inline void flip(const T &);
-
-
-//
-// Basic flippers
-//
-void flip(uint32 &obj);
-void flip(uint16 &obj);
-void flip(sint32 &obj);
-void flip(sint16 &obj);
-
-template <class Base>
-inline void flip(Base * &obj)                  { flip(&obj, sizeof(obj)); }
-
-
-//
-// The raw byte reversal flipper
-//
-void flip(void *addr, size_t size);
-
-void flip(CSSM_DB_ATTRIBUTE_INFO &obj);
-inline void flip(CssmDbAttributeInfo &obj) { flip(static_cast<CSSM_DB_ATTRIBUTE_INFO &>(obj)); }
-
-//
-// Include automatically generated flipper declarations
-//
-#include "flip_gen.h"
-
-
-}      // end namespace flippers
-
-
-#endif //_H_FLIPPERS
diff --git a/src/generate.cf b/src/generate.cf
deleted file mode 100644 (file)
index fa387c5..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Byte flipper generator configuration.
-#
-# Syntax of each non-comment line:
-#      cssmType[/podwrapperType]       field1 ... fieldn
-#      cssmType[/podwrapperType]       *
-# Generates flippers for each cssmType (with forwarders for podwrapperType if present),
-# flipping the fields given. If '*' is used, take field definitions from cssmtype.h.
-#
-
-#
-# CSSM standard structures
-#
-CSSM_DATA/CssmData     Length
-CSSM_VERSION *
-CSSM_SUBSERVICE_UID/CssmSubserviceUid *
-CSSM_NET_ADDRESS *
-CSSM_LIST_ELEMENT/ListElement  WordID ElementType
-CSSM_DL_DB_HANDLE *
-CSSM_CONTEXT_ATTRIBUTE/Context::Attr CUSTOM
-CSSM_CONTEXT/Context *
-CSSM_LIST/CssmList/TypedList   ListType Tail
-CSSM_SAMPLE/CssmSample *
-CSSM_SAMPLEGROUP/SampleGroup   NumberOfSamples
-CSSM_ACCESS_CREDENTIALS/AccessCredentials      Callback CallerCtx
-CSSM_AUTHORIZATIONGROUP/AuthorizationGroup     NumberOfAuthTags
-CSSM_ACL_VALIDITY_PERIOD *
-CSSM_ACL_ENTRY_PROTOTYPE/AclEntryPrototype     Delegate
-CSSM_ACL_OWNER_PROTOTYPE/AclOwnerPrototype     Delegate
-CSSM_ACL_ENTRY_INPUT/AclEntryInput     Callback CallerContext
-CSSM_ACL_ENTRY_INFO/AclEntryInfo       EntryHandle
-CSSM_RANGE *
-CSSM_KEY_SIZE/CssmKeySize *
-CSSM_KEYHEADER/CssmKey::Header *
-CSSM_KEY/CssmKey       KeyHeader
-CSSM_QUERY/CssmQuery RecordType Conjunctive NumSelectionPredicates QueryLimits QueryFlags
-CSSM_DB_ATTRIBUTE_DATA/CssmDbAttributeData NumberOfValues
-CSSM_DB_RECORD_ATTRIBUTE_DATA/CssmDbRecordAttributeData DataRecordType SemanticInformation NumberOfAttributes
-
-#
-# Authorization structures
-#
-AuthorizationItem              valueLength flags
-AuthorizationItemSet   count
diff --git a/src/generate.mk b/src/generate.mk
deleted file mode 100644 (file)
index 112c477..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-#      Makefile to build MIG-generated sources and headers
-#
-XSRCROOT:=$(shell cd $(SRCROOT) >/dev/null; pwd)
-TARGET:=$(shell cd $(BUILT_PRODUCTS_DIR) >/dev/null; pwd)
-SRC:=$(TARGET)/derived_src
-HDR:=$(TARGET)/include
-
-build: $(SRC)/.mig.ucsp $(SRC)/.mig.secagent
-
-debug: build
-
-profile: build
-
-install: build
-
-installhdrs: build
-
-installsrc:
-
-clean:
-       rm -f $(SRC)/.mig.ucsp $(SRC)/.mig.secagent \
-               $(SRC)/ucsp*.cpp $(SRC)/secagent*.cpp $(HDR)/ucsp.h $(HDR)/secagent.h
-
-$(SRC)/.mig.ucsp: SecurityServer/ucsp.defs SecurityServer/ucspNotify.defs SecurityServer/ucsp_types.h
-       mkdir -p $(SRC)
-       mkdir -p $(HDR)
-       cd /tmp; mig -server $(SRC)/ucspServer.cpp -user $(SRC)/ucspUser.cpp \
-               -header $(HDR)/ucsp.h $(XSRCROOT)/SecurityServer/ucsp.defs
-       cd /tmp; mig -server $(SRC)/ucspNotifyReceiver.cpp -user $(SRC)/ucspNotifySender.cpp \
-               -header $(HDR)/ucspNotify.h $(XSRCROOT)/SecurityServer/ucspNotify.defs
-       touch $(SRC)/.mig.ucsp
-
-$(SRC)/.mig.secagent: SecurityServer/secagent.defs SecurityServer/secagent_types.h
-       mkdir -p $(SRC)
-       mkdir -p $(HDR)
-       cd /tmp; mig -server $(SRC)/secagentServer.cpp -user $(SRC)/secagentUser.cpp \
-               -header $(HDR)/secagent.h $(XSRCROOT)/SecurityServer/secagent.defs
-       touch $(SRC)/.mig.secagent
diff --git a/src/generate.pl b/src/generate.pl
deleted file mode 100755 (executable)
index 4ec7cd1..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/perl
-#
-#
-#
-#use strict;
-
-my $disclaimer = "Automatically generated - do not edit on penalty of futility!";
-
-
-# arguments
-my ($configfile, $out_h, $out_cpp, $types, $hdrpath) = @ARGV;
-
-
-# open configuration file
-open(CFG, "$configfile") || die "$configfile: $!";
-
-# open and load cssmtypes file
-for my $hdrdir (split (/:/, $hdrpath)) {
-  open(TYPES, "$hdrdir/$types") and last;
-}
-TYPES or die "cannot find $types in $hdrpath: $!";
-$/=undef;
-my $types_h = <TYPES>;
-close(TYPES); $/="\n";
-
-# open output files
-open(H, ">$out_h") || die "$out_h: $!";
-open(CPP, ">$out_cpp") || die "$out_cpp: $!";
-
-# cautionary headings to each file
-print H <<EOH;
-//
-// Flipping bytes for securityd transition.
-// $disclaimer
-//
-EOH
-
-print CPP <<EOC;
-//
-// Flipping bytes for securityd transition.
-// $disclaimer
-//
-EOC
-
-# process generation instructions
-while (<CFG>) {
-  chomp;
-  next if /^[  ]*#/;
-  next if /^[  ]*$/;
-  
-  my @args = split;
-  $_ = shift @args;
-  my ($cssmName, @aliases) = split /\//;
-  
-  print H "void flip($cssmName &obj);\n";
-  for my $alias (@aliases) {
-       print H "inline void flip($alias &obj) { flip(static_cast<$cssmName &>(obj)); }\n";
-  }
-  
-  next if ($args[0] eq 'CUSTOM');
-  
-  if ($args[0] eq '*') {
-       # extract definition from types file
-       my ($list) = $types_h =~ /{\s+([^}]+)\s+}\s*$cssmName,/;
-       die "cannot find struct definition for $cssmName in $types" unless $list;
-       @args = $list =~ /([A-Za-z0-9_]+);/gm;
-  }
-
-  print CPP "void flip($cssmName &obj)\n{\n";
-  for my $field (@args) {
-       print CPP "\tflip(obj.$field);\n";
-  }
-  print CPP "}\n\n";
-}
index 32160b54869062b69b567bc2265085e30de8176d..ad5ee8fc1af7143ebe645cad401a5209db421a87 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -46,6 +46,7 @@
 #include <vector>           // @@@  4003540 workaround
 #include <security_agent_client/agentclient.h>
 #include <security_cdsa_utilities/acl_any.h>   // for default owner ACLs
 #include <vector>           // @@@  4003540 workaround
 #include <security_agent_client/agentclient.h>
 #include <security_cdsa_utilities/acl_any.h>   // for default owner ACLs
+#include <security_cdsa_utilities/cssmendian.h>
 #include <security_cdsa_client/wrapkey.h>
 #include <security_cdsa_client/genkey.h>
 #include <security_cdsa_client/signclient.h>
 #include <security_cdsa_client/wrapkey.h>
 #include <security_cdsa_client/genkey.h>
 #include <security_cdsa_client/signclient.h>
@@ -54,6 +55,7 @@
 #include <securityd_client/dictionary.h>
 #include <security_utilities/endian.h>
 
 #include <securityd_client/dictionary.h>
 #include <security_utilities/endian.h>
 
+void unflattenKey(const CssmData &flatKey, CssmKey &rawKey);   //>> make static method on KeychainDatabase
 
 //
 // Create a Database object from initial parameters (create operation)
 
 //
 // Create a Database object from initial parameters (create operation)
@@ -127,13 +129,13 @@ KeychainDatabase::KeychainDatabase(const DLDbIdentifier &id, const DbBlob *blob,
                parent(*dbcom);
                //@@@ arbitrate sequence number here, perhaps update common().mParams
                secdebug("KCdb",
                parent(*dbcom);
                //@@@ arbitrate sequence number here, perhaps update common().mParams
                secdebug("KCdb",
-                       "open database %s(%p) version %lx at known common %p",
+                       "open database %s(%p) version %x at known common %p",
                        common().dbName(), this, blob->version(), &common());
        } else {
                // DbCommon not present; make a new one
                parent(*new KeychainDbCommon(proc.session(), ident));
                common().mParams = blob->params;
                        common().dbName(), this, blob->version(), &common());
        } else {
                // DbCommon not present; make a new one
                parent(*new KeychainDbCommon(proc.session(), ident));
                common().mParams = blob->params;
-               secdebug("KCdb", "open database %s(%p) version %lx with new common %p",
+               secdebug("KCdb", "open database %s(%p) version %x with new common %p",
                        common().dbName(), this, blob->version(), &common());
                // this DbCommon is locked; no timer or reference setting
        }
                        common().dbName(), this, blob->version(), &common());
                // this DbCommon is locked; no timer or reference setting
        }
@@ -336,7 +338,7 @@ void KeychainDatabase::encode()
        Allocator::standard().free(mBlob);
        mBlob = blob;
        version = common().version;
        Allocator::standard().free(mBlob);
        mBlob = blob;
        version = common().version;
-       secdebug("KCdb", "encoded database %p common %p(%s) version %ld params=(%ld,%d)",
+       secdebug("KCdb", "encoded database %p common %p(%s) version %u params=(%u,%u)",
                this, &common(), dbName(), version,
                common().mParams.idleTimeout, common().mParams.lockOnSleep);
 }
                this, &common(), dbName(), version,
                common().mParams.idleTimeout, common().mParams.lockOnSleep);
 }
@@ -464,7 +466,8 @@ void KeychainDatabase::makeUnlocked(const AccessCredentials *cred)
         assert(mBlob || (mValidData && common().hasMaster()));
                establishOldSecrets(cred);
                common().setUnlocked(); // mark unlocked
         assert(mBlob || (mValidData && common().hasMaster()));
                establishOldSecrets(cred);
                common().setUnlocked(); // mark unlocked
-       } else if (!mValidData) {       // need to decode to get our ACLs, master secret available
+       }
+       if (!mValidData) {      // need to decode to get our ACLs, master secret available
                secdebug("KCdb", "%p(%p) is unlocked; decoding for makeUnlocked()", this, &common());
                if (!decode())
                        CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
                secdebug("KCdb", "%p(%p) is unlocked; decoding for makeUnlocked()", this, &common());
                if (!decode())
                        CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
@@ -568,15 +571,8 @@ void KeychainDatabase::establishOldSecrets(const AccessCredentials *creds)
                        switch (sample.type()) {
                        // interactively prompt the user - no additional data
                        case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT:
                        switch (sample.type()) {
                        // interactively prompt the user - no additional data
                        case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT:
-                       {
-                               secdebug("KCdb", "%p attempting interactive unlock", this);
-                               QueryUnlock query(*this);
-                               // Holding DB common lock during UI will deadlock securityd
-                               StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
-                               query.inferHints(Server::process());
-                               if (query() == SecurityAgent::noReason)
+                               if (interactiveUnlock())
                                        return;
                                        return;
-                       }
                                break;
                        // try to use an explicitly given passphrase - Data:passphrase
                        case CSSM_SAMPLE_TYPE_PASSWORD:
                                break;
                        // try to use an explicitly given passphrase - Data:passphrase
                        case CSSM_SAMPLE_TYPE_PASSWORD:
@@ -587,7 +583,8 @@ void KeychainDatabase::establishOldSecrets(const AccessCredentials *creds)
                                        return;
                                break;
                        // try to open with a given master key - Data:CSP or KeyHandle, Data:CssmKey
                                        return;
                                break;
                        // try to open with a given master key - Data:CSP or KeyHandle, Data:CssmKey
-                       case CSSM_WORDID_SYMMETRIC_KEY:
+                       case CSSM_SAMPLE_TYPE_SYMMETRIC_KEY:
+                       case CSSM_SAMPLE_TYPE_ASYMMETRIC_KEY:
                                assert(mBlob);
                                secdebug("KCdb", "%p attempting explicit key unlock", this);
                                common().setup(mBlob, keyFromCreds(sample, 4));
                                assert(mBlob);
                                secdebug("KCdb", "%p attempting explicit key unlock", this);
                                common().setup(mBlob, keyFromCreds(sample, 4));
@@ -605,7 +602,7 @@ void KeychainDatabase::establishOldSecrets(const AccessCredentials *creds)
                                // But instead we try to be tolerant and continue on.
                                // This DOES however count as an explicit attempt at specifying unlock,
                                // so we will no longer try the default case below...
                                // But instead we try to be tolerant and continue on.
                                // This DOES however count as an explicit attempt at specifying unlock,
                                // so we will no longer try the default case below...
-                               secdebug("KCdb", "%p unknown sub-sample unlock (%ld) ignored", this, sample.type());
+                               secdebug("KCdb", "%p unknown sub-sample unlock (%d) ignored", this, sample.type());
                                break;
                        }
                }
                                break;
                        }
                }
@@ -622,11 +619,7 @@ void KeychainDatabase::establishOldSecrets(const AccessCredentials *creds)
                                return;
                }
                
                                return;
                }
                
-               QueryUnlock query(*this);
-               // attempt interactive unlock
-               StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
-               query.inferHints(Server::process());
-               if (query() == SecurityAgent::noReason)
+               if (interactiveUnlock())
                        return;
        }
        
                        return;
        }
        
@@ -634,6 +627,23 @@ void KeychainDatabase::establishOldSecrets(const AccessCredentials *creds)
        CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
 }
 
        CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
 }
 
+bool KeychainDatabase::interactiveUnlock()
+{
+       secdebug("KCdb", "%p attempting interactive unlock", this);
+       QueryUnlock query(*this);
+       // take UI interlock and release DbCommon lock (to avoid deadlocks)
+       StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common());
+       
+       // now that we have the UI lock, interact unless another thread unlocked us first
+       if (isLocked()) {
+               query.inferHints(Server::process());
+               return query() == SecurityAgent::noReason;
+       } else {
+               secdebug("KCdb", "%p was unlocked during uiLock delay", this);
+               return true;
+       }
+}
+
 
 //
 // Same thing, but obtain a new secret somehow and set it into the common.
 
 //
 // Same thing, but obtain a new secret somehow and set it into the common.
@@ -669,6 +679,7 @@ void KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, Secur
                                return;
                        // try to open with a given master key
                        case CSSM_WORDID_SYMMETRIC_KEY:
                                return;
                        // try to open with a given master key
                        case CSSM_WORDID_SYMMETRIC_KEY:
+                       case CSSM_SAMPLE_TYPE_ASYMMETRIC_KEY:
                                secdebug("KCdb", "%p specified explicit master key", this);
                                common().setup(NULL, keyFromCreds(sample, 3));
                                return;
                                secdebug("KCdb", "%p specified explicit master key", this);
                                common().setup(NULL, keyFromCreds(sample, 3));
                                return;
@@ -683,7 +694,7 @@ void KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, Secur
                                // But instead we try to be tolerant and continue on.
                                // This DOES however count as an explicit attempt at specifying unlock,
                                // so we will no longer try the default case below...
                                // But instead we try to be tolerant and continue on.
                                // This DOES however count as an explicit attempt at specifying unlock,
                                // so we will no longer try the default case below...
-                               secdebug("KCdb", "%p unknown sub-sample acquisition (%ld) ignored",
+                               secdebug("KCdb", "%p unknown sub-sample acquisition (%d) ignored",
                                        this, sample.type());
                                break;
                        }
                                        this, sample.type());
                                break;
                        }
@@ -712,7 +723,7 @@ void KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, Secur
 CssmClient::Key KeychainDatabase::keyFromCreds(const TypedList &sample, unsigned int requiredLength)
 {
        // decode TypedList structure (sample type; Data:CSPHandle; Data:CSSM_KEY)
 CssmClient::Key KeychainDatabase::keyFromCreds(const TypedList &sample, unsigned int requiredLength)
 {
        // decode TypedList structure (sample type; Data:CSPHandle; Data:CSSM_KEY)
-       assert(sample.type() == CSSM_WORDID_SYMMETRIC_KEY);
+       assert(sample.type() == CSSM_SAMPLE_TYPE_SYMMETRIC_KEY || sample.type() == CSSM_SAMPLE_TYPE_ASYMMETRIC_KEY);
        if (sample.length() != requiredLength
                || sample[1].type() != CSSM_LIST_ELEMENT_DATUM
                || sample[2].type() != CSSM_LIST_ELEMENT_DATUM
        if (sample.length() != requiredLength
                || sample[1].type() != CSSM_LIST_ELEMENT_DATUM
                || sample[2].type() != CSSM_LIST_ELEMENT_DATUM
@@ -724,7 +735,74 @@ CssmClient::Key KeychainDatabase::keyFromCreds(const TypedList &sample, unsigned
        if (key.header().cspGuid() == gGuidAppleCSPDL) {
                // handleOrKey is a SecurityServer KeyHandle; ignore key argument
                return safer_cast<LocalKey &>(*Server::key(handle));
        if (key.header().cspGuid() == gGuidAppleCSPDL) {
                // handleOrKey is a SecurityServer KeyHandle; ignore key argument
                return safer_cast<LocalKey &>(*Server::key(handle));
-       } else {
+       } else 
+       if (sample.type() == CSSM_SAMPLE_TYPE_ASYMMETRIC_KEY) {
+               /*
+                       Contents (see DefaultCredentials::unlockKey in libsecurity_keychain/defaultcreds.cpp)
+                       
+                       sample[0]       sample type
+                       sample[1]       csp handle for master or wrapping key; is really a keyhandle
+                       sample[2]       masterKey [not used since securityd cannot interpret; use sample[1] handle instead]
+                       sample[3]       UnlockReferralRecord data, in this case the flattened symmetric key
+               */
+
+               // RefPointer<Key> Server::key(KeyHandle key)
+               KeyHandle keyhandle = *sample[1].data().interpretedAs<KeyHandle>(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
+               CssmData &flattenedKey = sample[3].data();
+               RefPointer<Key> unwrappingKey = Server::key(keyhandle);
+               Database &db=unwrappingKey->database();
+               
+               CssmKey rawWrappedKey;
+               unflattenKey(flattenedKey, rawWrappedKey);
+
+               RefPointer<Key> masterKey;
+               CssmData emptyDescriptiveData;
+               const AccessCredentials *cred = NULL;
+               const AclEntryPrototype *owner = NULL;
+               CSSM_KEYUSE usage = CSSM_KEYUSE_ANY;
+               CSSM_KEYATTR_FLAGS attrs = CSSM_KEYATTR_EXTRACTABLE;    //CSSM_KEYATTR_RETURN_REF | 
+
+               // Get default credentials for unwrappingKey (the one on the token)
+               // Copied from Statics::Statics() in libsecurity_keychain/aclclient.cpp
+               // Following KeyItem::getCredentials, one sees that the "operation" parameter
+               // e.g. "CSSM_ACL_AUTHORIZATION_DECRYPT" is ignored
+               Allocator &alloc = Allocator::standard();
+               AutoCredentials promptCred(alloc, 3);// enable interactive prompting
+       
+               // promptCred: a credential permitting user prompt confirmations
+               // contains:
+               //  a KEYCHAIN_PROMPT sample, both by itself and in a THRESHOLD
+               //  a PROMPTED_PASSWORD sample
+               promptCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT);
+               promptCred.sample(1) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD,
+                       new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT)));
+               promptCred.sample(2) = TypedList(alloc, CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD,
+                       new(alloc) ListElement(alloc, CssmData()));
+
+               // This unwrap object is here just to provide a context
+               CssmClient::UnwrapKey unwrap(Server::csp(), CSSM_ALGID_NONE);   //ok to lie about csp here
+               unwrap.mode(CSSM_ALGMODE_NONE);
+               unwrap.padding(CSSM_PADDING_PKCS1);
+               unwrap.cred(promptCred);
+               unwrap.add(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT, uint32(CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7));
+               Security::Context *tmpContext;
+               CSSM_CC_HANDLE CCHandle = unwrap.handle();
+               /*CSSM_RETURN rx = */ CSSM_GetContext (CCHandle, (CSSM_CONTEXT_PTR *)&tmpContext);
+               
+               // OK, this is skanky but necessary. We overwrite fields in the context struct
+
+               tmpContext->ContextType = CSSM_ALGCLASS_ASYMMETRIC;
+               tmpContext->AlgorithmType = CSSM_ALGID_RSA;
+               
+               db.unwrapKey(*tmpContext, cred, owner, unwrappingKey, NULL, usage, attrs,
+                       rawWrappedKey, masterKey, emptyDescriptiveData);
+
+           Allocator::standard().free(rawWrappedKey.KeyData.Data);
+
+               return safer_cast<LocalKey &>(*masterKey).key();
+       }
+       else
+       {
                // not a KeyHandle reference; use key as a raw key
                if (key.header().blobType() != CSSM_KEYBLOB_RAW)
                        CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
                // not a KeyHandle reference; use key as a raw key
                if (key.header().blobType() != CSSM_KEYBLOB_RAW)
                        CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
@@ -734,6 +812,22 @@ CssmClient::Key KeychainDatabase::keyFromCreds(const TypedList &sample, unsigned
        }
 }
 
        }
 }
 
+void unflattenKey(const CssmData &flatKey, CssmKey &rawKey)
+{
+       // unflatten the raw input key naively: key header then key data
+       // We also convert it back to host byte order
+       // A CSSM_KEY is a CSSM_KEYHEADER followed by a CSSM_DATA
+
+       // Now copy: header, then key struct, then key data
+       memcpy(&rawKey.KeyHeader, flatKey.Data, sizeof(CSSM_KEYHEADER));
+       memcpy(&rawKey.KeyData, flatKey.Data + sizeof(CSSM_KEYHEADER), sizeof(CSSM_DATA));
+       const uint32 keyDataLength = flatKey.length() - sizeof(CSSM_KEY);
+       rawKey.KeyData.Data = Allocator::standard().malloc<uint8>(keyDataLength);
+       rawKey.KeyData.Length = keyDataLength;
+       memcpy(rawKey.KeyData.Data, flatKey.Data + sizeof(CSSM_KEY), keyDataLength);
+       Security::n2hi(rawKey.KeyHeader);       // convert it to host byte order
+}
+
 
 //
 // Verify a putative database passphrase.
 
 //
 // Verify a putative database passphrase.
@@ -774,10 +868,18 @@ void KeychainDatabase::lockDb()
 //
 KeyBlob *KeychainDatabase::encodeKey(const CssmKey &key, const CssmData &pubAcl, const CssmData &privAcl)
 {
 //
 KeyBlob *KeychainDatabase::encodeKey(const CssmKey &key, const CssmData &pubAcl, const CssmData &privAcl)
 {
-    unlockDb();
-    
+       bool inTheClear = false;
+       
+       if((key.keyClass() == CSSM_KEYCLASS_PUBLIC_KEY) &&
+          !(key.attribute(CSSM_KEYATTR_PUBLIC_KEY_ENCRYPT))) {
+               inTheClear = true;
+       }
+       if(!inTheClear) {
+               unlockDb();
+    }
+       
     // tell the cryptocore to form the key blob
     // tell the cryptocore to form the key blob
-    return common().encodeKeyCore(key, pubAcl, privAcl);
+    return common().encodeKeyCore(key, pubAcl, privAcl, inTheClear);
 }
 
 
 }
 
 
@@ -787,8 +889,10 @@ KeyBlob *KeychainDatabase::encodeKey(const CssmKey &key, const CssmData &pubAcl,
 //
 void KeychainDatabase::decodeKey(KeyBlob *blob, CssmKey &key, void * &pubAcl, void * &privAcl)
 {
 //
 void KeychainDatabase::decodeKey(KeyBlob *blob, CssmKey &key, void * &pubAcl, void * &privAcl)
 {
-    unlockDb();                                                        // we need our keys
-
+       if(!blob->isClearText()) {
+               unlockDb();                                                     // we need our keys
+       }
+       
     common().decodeKeyCore(blob, key, pubAcl, privAcl);
     // memory protocol: pubAcl points into blob; privAcl was allocated
        
     common().decodeKeyCore(blob, key, pubAcl, privAcl);
     // memory protocol: pubAcl points into blob; privAcl was allocated
        
@@ -808,7 +912,17 @@ KeyBlob *KeychainDatabase::recodeKey(KeychainKey &oldKey)
        CssmData publicAcl, privateAcl;
        oldKey.exportBlob(publicAcl, privateAcl);
        // NB: blob's memory belongs to caller, not the common
        CssmData publicAcl, privateAcl;
        oldKey.exportBlob(publicAcl, privateAcl);
        // NB: blob's memory belongs to caller, not the common
-       KeyBlob *blob = common().encodeKeyCore(oldKey.cssmKey(), publicAcl, privateAcl);
+
+       /* 
+        * Make sure the new key is in the same cleartext/encrypted state.
+        */
+       bool inTheClear = false;
+       assert(oldKey.blob());
+       if(oldKey.blob() && oldKey.blob()->isClearText()) {
+               /* careful....*/
+               inTheClear = true;
+       }
+       KeyBlob *blob = common().encodeKeyCore(oldKey.cssmKey(), publicAcl, privateAcl, inTheClear);
        oldKey.acl().allocator.free(publicAcl);
        oldKey.acl().allocator.free(privateAcl);
        return blob;
        oldKey.acl().allocator.free(publicAcl);
        oldKey.acl().allocator.free(privateAcl);
        return blob;
@@ -825,7 +939,7 @@ void KeychainDatabase::setParameters(const DBParameters &params)
        common().mParams = params;
     common().invalidateBlob();         // invalidate old blobs
     activity();                                // (also resets the timeout timer)
        common().mParams = params;
     common().invalidateBlob();         // invalidate old blobs
     activity();                                // (also resets the timeout timer)
-       secdebug("KCdb", "%p common %p(%s) set params=(%ld,%d)",
+       secdebug("KCdb", "%p common %p(%s) set params=(%u,%u)",
                this, &common(), dbName(), params.idleTimeout, params.lockOnSleep);
 }
 
                this, &common(), dbName(), params.idleTimeout, params.lockOnSleep);
 }
 
@@ -898,7 +1012,7 @@ void KeychainDbCommon::dumpNode()
 {
        PerSession::dumpNode();
        uint32 sig; memcpy(&sig, &mIdentifier.signature(), sizeof(sig));
 {
        PerSession::dumpNode();
        uint32 sig; memcpy(&sig, &mIdentifier.signature(), sizeof(sig));
-       Debug::dump(" %s[%8.8lx]", mIdentifier.dbName(), sig);
+       Debug::dump(" %s[%8.8x]", mIdentifier.dbName(), sig);
        if (isLocked()) {
                Debug::dump(" locked");
        } else {
        if (isLocked()) {
                Debug::dump(" locked");
        } else {
@@ -906,17 +1020,17 @@ void KeychainDbCommon::dumpNode()
                Debug::dump(" unlocked(%24.24s/%.2g)", ctime(&whenTime),
                        (when() - Time::now()).seconds());
        }
                Debug::dump(" unlocked(%24.24s/%.2g)", ctime(&whenTime),
                        (when() - Time::now()).seconds());
        }
-       Debug::dump(" params=(%ld,%d)", mParams.idleTimeout, mParams.lockOnSleep);
+       Debug::dump(" params=(%u,%u)", mParams.idleTimeout, mParams.lockOnSleep);
 }
 
 void KeychainDatabase::dumpNode()
 {
        PerProcess::dumpNode();
 }
 
 void KeychainDatabase::dumpNode()
 {
        PerProcess::dumpNode();
-       Debug::dump(" %s vers=%ld",
+       Debug::dump(" %s vers=%u",
                mValidData ? " data" : " nodata", version);
        if (mBlob) {
                uint32 sig; memcpy(&sig, &mBlob->randomSignature, sizeof(sig));
                mValidData ? " data" : " nodata", version);
        if (mBlob) {
                uint32 sig; memcpy(&sig, &mBlob->randomSignature, sizeof(sig));
-               Debug::dump(" blob=%p[%8.8lx]", mBlob, sig);
+               Debug::dump(" blob=%p[%8.8x]", mBlob, sig);
        } else {
                Debug::dump(" noblob");
        }
        } else {
                Debug::dump(" noblob");
        }
@@ -963,6 +1077,14 @@ KeychainDbGlobal &KeychainDbCommon::global() const
 }
 
 
 }
 
 
+void KeychainDbCommon::select()
+{ this->ref(); }
+
+void KeychainDbCommon::unselect()
+{ this->unref(); }
+
+
+
 void KeychainDbCommon::makeNewSecrets()
 {
        // we already have a master key (right?)
 void KeychainDbCommon::makeNewSecrets()
 {
        // we already have a master key (right?)
@@ -1004,10 +1126,14 @@ bool KeychainDbCommon::unlockDb(DbBlob *blob, void **privateAclBlob)
                mValidParams = true;    // sticky
        }
 
                mValidParams = true;    // sticky
        }
 
+       bool isLocked = mIsLocked;
+       
        setUnlocked();          // mark unlocked
        
        setUnlocked();          // mark unlocked
        
-       // broadcast unlock notification
-       notify(kNotificationEventUnlocked);
+       if (isLocked) {
+               // broadcast unlock notification, but only if we were previously locked
+               notify(kNotificationEventUnlocked);
+       }
     return true;
 }
 
     return true;
 }
 
@@ -1061,25 +1187,6 @@ DbBlob *KeychainDbCommon::encode(KeychainDatabase &db)
 }
 
 
 }
 
 
-//
-// Send a keychain-related notification event about this keychain
-//
-void KeychainDbCommon::notify(NotificationEvent event)
-{
-       // form the data (encoded DLDbIdentifier)
-    NameValueDictionary nvd;
-    NameValueDictionary::MakeNameValueDictionaryFromDLDbIdentifier(identifier(), nvd);
-    CssmData data;
-    nvd.Export(data);
-
-       // inject notification into Security event system
-    Listener::notify(kNotificationDomainDatabase, event, data);
-       
-       // clean up
-    free (data.data());
-}
-
-
 //
 // Perform deferred lock processing for a database.
 //
 //
 // Perform deferred lock processing for a database.
 //
index 69714aa650ab93738e18b9c2ab93a37ea8e9431b..3656bfa7335e6c9bb3bf79afe8bdc75b8e0c2123 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -99,9 +99,9 @@ public:
        
        bool unlockDb(DbBlob *blob, void **privateAclBlob = NULL);
        void lockDb();                          // make locked (if currently unlocked)
        
        bool unlockDb(DbBlob *blob, void **privateAclBlob = NULL);
        void lockDb();                          // make locked (if currently unlocked)
-       bool isLocked() const { return mIsLocked; } // lock status
+       bool isLocked()                 { return mIsLocked; } // lock status
        void setUnlocked();
        void setUnlocked();
-       void invalidateBlob() { version++; }
+       void invalidateBlob()   { version++; }
        
        void activity();                        // reset lock timeout
        
        
        void activity();                        // reset lock timeout
        
@@ -113,7 +113,7 @@ public:
        
        DbBlob *encode(KeychainDatabase &db);
        
        
        DbBlob *encode(KeychainDatabase &db);
        
-       void notify(NotificationEvent event);
+       void notify(NotificationEvent event) { DbCommon::notify(event, identifier()); }
 
        void sleepProcessing();
        void lockProcessing();
 
        void sleepProcessing();
        void lockProcessing();
@@ -124,6 +124,10 @@ public:
        
 protected:
        void action();                          // timer queue action to lock keychain
        
 protected:
        void action();                          // timer queue action to lock keychain
+       
+       // lifetime management for our Timer personality
+       void select();
+       void unselect();
 
 public:
        // all following data locked with object lock
 
 public:
        // all following data locked with object lock
@@ -187,9 +191,9 @@ public:
        bool decode(const CssmData &passphrase);                                // set master key from PP, try unlock
 
        bool validatePassphrase(const CssmData &passphrase) const; // nonthrowing validation
        bool decode(const CssmData &passphrase);                                // set master key from PP, try unlock
 
        bool validatePassphrase(const CssmData &passphrase) const; // nonthrowing validation
-       bool isLocked() const { return common().isLocked(); }   // lock status
+       bool isLocked()                 { return common().isLocked(); } // lock status
     void notify(NotificationEvent event) { return common().notify(event); }
     void notify(NotificationEvent event) { return common().notify(event); }
-    void activity() const { common().activity(); }                     // reset timeout clock
+    void activity() const      { common().activity(); }                // reset timeout clock
        
        // encoding/decoding keys
     void decodeKey(KeyBlob *blob, CssmKey &key, void * &pubAcl, void * &privAcl);
        
        // encoding/decoding keys
     void decodeKey(KeyBlob *blob, CssmKey &key, void * &pubAcl, void * &privAcl);
@@ -228,7 +232,9 @@ protected:
        void establishOldSecrets(const AccessCredentials *creds);
        void establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason);
        
        void establishOldSecrets(const AccessCredentials *creds);
        void establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason);
        
-       static CssmClient::Key keyFromCreds(const TypedList &sample, unsigned int requiredLength);
+       bool interactiveUnlock();
+       
+       CssmClient::Key keyFromCreds(const TypedList &sample, unsigned int requiredLength);
        
        void encode();                                                                  // (re)generate mBlob if needed
        
        
        void encode();                                                                  // (re)generate mBlob if needed
        
index f6ed602e7936b8bc80941f37faf6c3d80901555c..2f966826b094f4d922d5861b9b24e3717be068e1 100644 (file)
@@ -56,7 +56,7 @@ KeychainKey::KeychainKey(Database &db, const KeyBlob *blob)
     mBlob = blob->copy(Allocator::standard());
        mValidBlob = true;
        db.addReference(*this);
     mBlob = blob->copy(Allocator::standard());
        mValidBlob = true;
        db.addReference(*this);
-    secdebug("SSkey", "%p (handle 0x%lx) created from blob version %lx",
+    secdebug("SSkey", "%p (handle 0x%lx) created from blob version %x",
                this, handle(), blob->version());
 }
 
                this, handle(), blob->version());
 }
 
@@ -195,9 +195,13 @@ void KeychainKey::changedAcl()
 void KeychainKey::validate(AclAuthorization auth, const AccessCredentials *cred,
        Database *relatedDatabase)
 {
 void KeychainKey::validate(AclAuthorization auth, const AccessCredentials *cred,
        Database *relatedDatabase)
 {
-       if (KeychainDatabase *db = dynamic_cast<KeychainDatabase *>(relatedDatabase))
-               db->unlockDb();
+       if(!mBlob->isClearText()) {
+               /* unlock not needed for cleartext keys */
+               if (KeychainDatabase *db = dynamic_cast<KeychainDatabase *>(relatedDatabase))
+                       db->unlockDb();
+       }
        SecurityServerAcl::validate(auth, cred, relatedDatabase);
        SecurityServerAcl::validate(auth, cred, relatedDatabase);
+       database().activity();          // upon successful validation
 }
 
 
 }
 
 
index a5d5ce602bad8a00eb81b5e9caf2bee84a89ab7d..ed979e5098ad944362a8e94758f9684596121199 100644 (file)
@@ -57,7 +57,7 @@ public:
     
        KeychainDatabase &database() const;
     
     
        KeychainDatabase &database() const;
     
-    // we can also yield an encoded KeyBlob *if* we belong to a database       
+    // we can also yield an encoded KeyBlob
        KeyBlob *blob();
        
        void invalidateBlob();
        KeyBlob *blob();
        
        void invalidateBlob();
index 1ffc954f99427bc973a048de1f866d9d9374c5cf..30aa4a016d1f6a8b1543404a5b44cf3feffa05fc 100644 (file)
@@ -183,7 +183,8 @@ void LocalDatabase::generateKey(const Context &context,
                privKey, LocalKey::KeySpec(privUsage, privAttrs));
                
        // register and return the generated keys
                privKey, LocalKey::KeySpec(privUsage, privAttrs));
                
        // register and return the generated keys
-       publicKey = makeKey(pubKey, pubAttrs & LocalKey::managedAttributes, owner);
+       publicKey = makeKey(pubKey, pubAttrs & LocalKey::managedAttributes, 
+               (pubAttrs & CSSM_KEYATTR_PUBLIC_KEY_ENCRYPT) ? owner : NULL);
        privateKey = makeKey(privKey, privAttrs & LocalKey::managedAttributes, owner);
 }
 
        privateKey = makeKey(privKey, privAttrs & LocalKey::managedAttributes, owner);
 }
 
index e50d82f93a94df91249ee2e1d3c769b0b2331c4a..37e8c7b133fca78a65b06cf6883444a9db817739 100644 (file)
@@ -39,7 +39,7 @@ LocalKey::LocalKey(Database &db, const CssmKey &newKey, CSSM_KEYATTR_FLAGS moreA
 {
        mValidKey = true;
        setup(newKey, moreAttributes);
 {
        mValidKey = true;
        setup(newKey, moreAttributes);
-    secdebug("SSkey", "%p (handle 0x%lx) created from key alg=%ld use=0x%lx attr=0x%lx db=%p",
+    secdebug("SSkey", "%p (handle 0x%lx) created from key alg=%u use=0x%x attr=0x%x db=%p",
         this, handle(), mKey.header().algorithm(), mKey.header().usage(), mAttributes, &db);
 }
 
         this, handle(), mKey.header().algorithm(), mKey.header().usage(), mAttributes, &db);
 }
 
@@ -101,6 +101,7 @@ LocalDatabase &LocalKey::database() const
 //
 CssmClient::Key LocalKey::keyValue()
 {
 //
 CssmClient::Key LocalKey::keyValue()
 {
+       StLock<Mutex> _(*this);
     if (!mValidKey) {
                getKey();
                mValidKey = true;
     if (!mValidKey) {
                getKey();
                mValidKey = true;
@@ -123,6 +124,8 @@ CSSM_KEYATTR_FLAGS LocalKey::attributes()
 //
 void LocalKey::returnKey(Handle &h, CssmKey::Header &hdr)
 {
 //
 void LocalKey::returnKey(Handle &h, CssmKey::Header &hdr)
 {
+       StLock<Mutex> _(*this);
+
     // return handle
     h = this->handle();
        
     // return handle
     h = this->handle();
        
@@ -145,6 +148,7 @@ void LocalKey::returnKey(Handle &h, CssmKey::Header &hdr)
 //
 const CssmData &LocalKey::canonicalDigest()
 {
 //
 const CssmData &LocalKey::canonicalDigest()
 {
+       StLock<Mutex> _(*this);
        if (!mDigest) {
                CssmClient::PassThrough ctx(Server::csp());
                ctx.key(keyValue());
        if (!mDigest) {
                CssmClient::PassThrough ctx(Server::csp());
                ctx.key(keyValue());
index 5b47f5ee3566f096fade24e7793b7d9e909fa88e..d61e3092b004eb4e30987d919dbb600fbbe869ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -31,6 +31,7 @@
 #include "entropy.h"
 #include "authority.h"
 #include "session.h"
 #include "entropy.h"
 #include "authority.h"
 #include "session.h"
+#include "notifications.h"
 #include "pcscmonitor.h"
 #include "self.h"
 
 #include "pcscmonitor.h"
 #include "self.h"
 
@@ -38,7 +39,8 @@
 #include <security_utilities/machserver.h>
 #include <security_utilities/logging.h>
 #include <security_utilities/ktracecodes.h>
 #include <security_utilities/machserver.h>
 #include <security_utilities/logging.h>
 #include <security_utilities/ktracecodes.h>
-#include <security_cdsa_client/osxsigner.h>
+
+#include <Security/SecKeychainPriv.h>
 
 #include <unistd.h>
 #include <sys/types.h>
 
 #include <unistd.h>
 #include <sys/types.h>
@@ -64,6 +66,7 @@
 #include <security_cdsa_utilities/acl_preauth.h>
 #include "acl_keychain.h"
 
 #include <security_cdsa_utilities/acl_preauth.h>
 #include "acl_keychain.h"
 
+
 //
 // Local functions of the main program driver
 //
 //
 // Local functions of the main program driver
 //
@@ -90,25 +93,37 @@ int main(int argc, char *argv[])
        // clear the umask - we know what we're doing
        secdebug("SS", "starting umask was 0%o", ::umask(0));
        ::umask(0);
        // clear the umask - we know what we're doing
        secdebug("SS", "starting umask was 0%o", ::umask(0));
        ::umask(0);
-    
+
+       // tell the keychain (client) layer to turn off the server interface
+       SecKeychainSetServerMode();
+       
        // program arguments (preset to defaults)
        bool debugMode = false;
        const char *bootstrapName = NULL;
        // program arguments (preset to defaults)
        bool debugMode = false;
        const char *bootstrapName = NULL;
+       const char* messagingName = SECURITY_MESSAGES_NAME;
        bool doFork = false;
        bool reExecute = false;
        int workerTimeout = 0;
        int maxThreads = 0;
        bool doFork = false;
        bool reExecute = false;
        int workerTimeout = 0;
        int maxThreads = 0;
+       bool waitForClients = false;
        const char *authorizationConfig = "/etc/authorization";
        const char *tokenCacheDir = "/var/db/TokenCache";
     const char *entropyFile = "/var/db/SystemEntropyCache";
        const char *equivDbFile = EQUIVALENCEDBPATH;
        const char *smartCardOptions = getenv("SMARTCARDS");
        const char *authorizationConfig = "/etc/authorization";
        const char *tokenCacheDir = "/var/db/TokenCache";
     const char *entropyFile = "/var/db/SystemEntropyCache";
        const char *equivDbFile = EQUIVALENCEDBPATH;
        const char *smartCardOptions = getenv("SMARTCARDS");
+       uint32_t keychainAclDefault = CSSM_ACL_KEYCHAIN_PROMPT_INVALID | CSSM_ACL_KEYCHAIN_PROMPT_UNSIGNED;
+       
+       // check for the Installation-DVD environment and modify some default arguments if found
+       if (access("/etc/rc.cdrom", F_OK) == 0) {       // /etc/rc.cdrom exists
+               secdebug("SS", "configuring for installation");
+               smartCardOptions = "off";       // needs writable directories that aren't
+       }
 
        // parse command line arguments
        extern char *optarg;
        extern int optind;
        int arg;
 
        // parse command line arguments
        extern char *optarg;
        extern int optind;
        int arg;
-       while ((arg = getopt(argc, argv, "a:c:de:E:fN:s:t:T:X")) != -1) {
+       while ((arg = getopt(argc, argv, "a:c:de:E:fiN:s:t:T:Xuw")) != -1) {
                switch (arg) {
                case 'a':
                        authorizationConfig = optarg;
                switch (arg) {
                case 'a':
                        authorizationConfig = optarg;
@@ -128,6 +143,9 @@ int main(int argc, char *argv[])
         case 'f':
             fprintf(stderr, "%s: the -f option is obsolete\n", argv[0]);
             break;
         case 'f':
             fprintf(stderr, "%s: the -f option is obsolete\n", argv[0]);
             break;
+               case 'i':
+                       keychainAclDefault &= ~CSSM_ACL_KEYCHAIN_PROMPT_INVALID;
+                       break;
                case 'N':
                        bootstrapName = optarg;
                        break;
                case 'N':
                        bootstrapName = optarg;
                        break;
@@ -142,6 +160,12 @@ int main(int argc, char *argv[])
                        if ((workerTimeout = atoi(optarg)) < 0)
                                workerTimeout = 0;
                        break;
                        if ((workerTimeout = atoi(optarg)) < 0)
                                workerTimeout = 0;
                        break;
+               case 'w':
+                       waitForClients = true;
+                       break;
+               case 'u':
+                       keychainAclDefault &= ~CSSM_ACL_KEYCHAIN_PROMPT_UNSIGNED;
+                       break;
                case 'X':
                        doFork = true;
                        reExecute = true;
                case 'X':
                        doFork = true;
                        reExecute = true;
@@ -159,9 +183,19 @@ int main(int argc, char *argv[])
     if (!bootstrapName) {
                bootstrapName = getenv(SECURITYSERVER_BOOTSTRAP_ENV);
                if (!bootstrapName)
     if (!bootstrapName) {
                bootstrapName = getenv(SECURITYSERVER_BOOTSTRAP_ENV);
                if (!bootstrapName)
+               {
                        bootstrapName = SECURITYSERVER_BOOTSTRAP_NAME;
                        bootstrapName = SECURITYSERVER_BOOTSTRAP_NAME;
+               }
+               else
+               {
+                       messagingName = bootstrapName;
+               }
        }
        }
-
+       else
+       {
+               messagingName = bootstrapName;
+       }
+       
        // configure logging first
        if (debugMode) {
                Syslog::open(bootstrapName, LOG_AUTHPRIV, LOG_PERROR);
        // configure logging first
        if (debugMode) {
                Syslog::open(bootstrapName, LOG_AUTHPRIV, LOG_PERROR);
@@ -199,18 +233,20 @@ int main(int argc, char *argv[])
         secdebug("SS", "Cannot handle SIGINT: errno=%d", errno);
     if (signal(SIGTERM, handleSignals) == SIG_ERR)
         secdebug("SS", "Cannot handle SIGTERM: errno=%d", errno);
         secdebug("SS", "Cannot handle SIGINT: errno=%d", errno);
     if (signal(SIGTERM, handleSignals) == SIG_ERR)
         secdebug("SS", "Cannot handle SIGTERM: errno=%d", errno);
+    if (signal(SIGPIPE, handleSignals) == SIG_ERR)
+        secdebug("SS", "Cannot handle SIGPIPE: errno=%d", errno);
 #if !defined(NDEBUG)
     if (signal(SIGUSR1, handleSignals) == SIG_ERR)
         secdebug("SS", "Cannot handle SIGHUP: errno=%d", errno);
 #endif //NDEBUG
 #if !defined(NDEBUG)
     if (signal(SIGUSR1, handleSignals) == SIG_ERR)
         secdebug("SS", "Cannot handle SIGHUP: errno=%d", errno);
 #endif //NDEBUG
-       
-       // create a code signing engine
-       CodeSigning::OSXSigner signer;
+
+       // create the shared memory notification hub
+       new SharedMemoryListener(messagingName, kSharedMemoryPoolSize);
        
        // create an Authorization engine
        Authority authority(authorizationConfig);
        
        
        // create an Authorization engine
        Authority authority(authorizationConfig);
        
-       // establish the ACL machinery
+       // introduce all supported ACL subject types
        new AnyAclSubject::Maker();
        new PasswordAclSubject::Maker();
     new ProtectedPasswordAclSubject::Maker();
        new AnyAclSubject::Maker();
        new PasswordAclSubject::Maker();
     new ProtectedPasswordAclSubject::Maker();
@@ -218,8 +254,8 @@ int main(int argc, char *argv[])
        new ThresholdAclSubject::Maker();
     new CommentAclSubject::Maker();
        new ProcessAclSubject::Maker();
        new ThresholdAclSubject::Maker();
     new CommentAclSubject::Maker();
        new ProcessAclSubject::Maker();
-       new CodeSignatureAclSubject::Maker(signer);
-    new KeychainPromptAclSubject::Maker();
+       new CodeSignatureAclSubject::Maker();
+    new KeychainPromptAclSubject::Maker(keychainAclDefault);
     new PreAuthorizationAcls::OriginMaker();
     new PreAuthorizationAcls::SourceMaker();
        
     new PreAuthorizationAcls::OriginMaker();
     new PreAuthorizationAcls::SourceMaker();
        
@@ -237,6 +273,8 @@ int main(int argc, char *argv[])
                server.timeout(workerTimeout);
        if (maxThreads)
                server.maxThreads(maxThreads);
                server.timeout(workerTimeout);
        if (maxThreads)
                server.maxThreads(maxThreads);
+       server.floatingThread(true);
+       server.waitForClients(waitForClients);
     
        // add the RNG seed timer
 # if defined(NDEBUG)
     
        // add the RNG seed timer
 # if defined(NDEBUG)
@@ -252,7 +290,7 @@ int main(int argc, char *argv[])
 #endif //NDEBUG
 
        // create a smartcard monitor to manage external token devices
 #endif //NDEBUG
 
        // create a smartcard monitor to manage external token devices
-       PCSCMonitor secureCards(server, tokenCacheDir, scOptions(smartCardOptions));
+       new PCSCMonitor(server, tokenCacheDir, scOptions(smartCardOptions));
     
     // create the RootSession object (if -d, give it graphics and tty attributes)
     RootSession rootSession(server,
     
     // create the RootSession object (if -d, give it graphics and tty attributes)
     RootSession rootSession(server,
@@ -260,7 +298,7 @@ int main(int argc, char *argv[])
     
     // install MDS and initialize the local CSSM
     server.loadCssm();
     
     // install MDS and initialize the local CSSM
     server.loadCssm();
-
+    
        // okay, we're ready to roll
        Syslog::notice("Entering service");
        secdebug("SS", "%s initialized", bootstrapName);
        // okay, we're ready to roll
        Syslog::notice("Entering service");
        secdebug("SS", "%s initialized", bootstrapName);
@@ -302,7 +340,7 @@ int main(int argc, char *argv[])
 //
 static void usage(const char *me)
 {
 //
 static void usage(const char *me)
 {
-       fprintf(stderr, "Usage: %s [-dX]"
+       fprintf(stderr, "Usage: %s [-dwX]"
                "\n\t[-a authConfigFile]                    Authorization configuration file"
                "\n\t[-c tokencache]                        smartcard token cache directory"
                "\n\t[-e equivDatabase]                                         path to code equivalence database"
                "\n\t[-a authConfigFile]                    Authorization configuration file"
                "\n\t[-c tokencache]                        smartcard token cache directory"
                "\n\t[-e equivDatabase]                                         path to code equivalence database"
index ebee947e35423b3cac0f528b8c7f27fe467359eb..4ad4198e3dde267977d9d1da0f53637e5a649159 100644 (file)
 
 
 //
 
 
 //
-// EntropyManager - manage entropy on the system.
+// notifications - handling of securityd-gated notification messages
 //
 //
+#include <notify.h>
+
 #include "notifications.h"
 #include "server.h"
 #include "notifications.h"
 #include "server.h"
+#include "connection.h"
 #include <securityd_client/ucspNotify.h>
 
 #include <securityd_client/ucspNotify.h>
 
-Listener::ListenerMap Listener::listeners;
-Mutex Listener::setLock;
 
 
+Listener::ListenerMap Listener::listeners;
+Mutex Listener::setLock(Mutex::recursive);
 
 
-Listener::Listener(Port port, NotificationDomain dom, NotificationMask evs)
-       : domain(dom), events(evs), mPort(port)
-{ setup(); }
 
 
-Listener::Listener(NotificationDomain dom, NotificationMask evs)
+//
+// Listener basics
+//
+Listener::Listener(NotificationDomain dom, NotificationMask evs, mach_port_t port)
        : domain(dom), events(evs)
        : domain(dom), events(evs)
-{ setup(); }
-
-void Listener::setup()
 {
        assert(events);         // what's the point?
 {
        assert(events);         // what's the point?
-    
+       
     // register in listener set
     StLock<Mutex> _(setLock);
     // register in listener set
     StLock<Mutex> _(setLock);
-    listeners.insert(ListenerMap::value_type(mPort, this));
+    listeners.insert(ListenerMap::value_type(port, this));
+       
+       secdebug("notify", "%p created for domain 0x%x events 0x%x port %d",
+               this, dom, evs, port);
 }
 
 Listener::~Listener()
 }
 
 Listener::~Listener()
@@ -61,12 +64,32 @@ Listener::~Listener()
 //
 void Listener::notify(NotificationDomain domain,
        NotificationEvent event, const CssmData &data)
 //
 void Listener::notify(NotificationDomain domain,
        NotificationEvent event, const CssmData &data)
+{
+       RefPointer<Notification> message = new Notification(domain, event, 0, data);
+       StLock<Mutex> _(setLock);
+       sendNotification(message);
+}
+
+void Listener::notify(NotificationDomain domain,
+       NotificationEvent event, uint32 sequence, const CssmData &data)
+{
+       Connection &current = Server::active().connection();
+       RefPointer<Notification> message = new Notification(domain, event, sequence, data);
+       if (current.inSequence(message)) {
+               StLock<Mutex> _(setLock);
+               sendNotification(message);
+               while (RefPointer<Notification> next = current.popNotification())
+                       sendNotification(next);
+       }
+}
+
+void Listener::sendNotification(Notification *message)
 {
     for (ListenerMap::const_iterator it = listeners.begin();
             it != listeners.end(); it++) {
                Listener *listener = it->second;
 {
     for (ListenerMap::const_iterator it = listeners.begin();
             it != listeners.end(); it++) {
                Listener *listener = it->second;
-               if (listener->domain == domain && listener->wants(event))
-                       listener->notifyMe(domain, event, data);
+               if (listener->domain == kNotificationDomainAll || (message->domain == listener->domain && listener->wants(message->event)))
+                       listener->notifyMe(message);
        }
 }
 
        }
 }
 
@@ -77,15 +100,20 @@ void Listener::notify(NotificationDomain domain,
 //
 bool Listener::remove(Port port)
 {
 //
 bool Listener::remove(Port port)
 {
-       assert(port);  // Listeners with null ports are eternal
     typedef ListenerMap::iterator Iterator;
     StLock<Mutex> _(setLock);
     pair<Iterator, Iterator> range = listeners.equal_range(port);
     if (range.first == range.second)
         return false;  // not one of ours
 
     typedef ListenerMap::iterator Iterator;
     StLock<Mutex> _(setLock);
     pair<Iterator, Iterator> range = listeners.equal_range(port);
     if (range.first == range.second)
         return false;  // not one of ours
 
-    for (Iterator it = range.first; it != range.second; it++)
-        delete it->second;
+       assert(range.first != listeners.end());
+       secdebug("notify", "remove port %d", port.port());
+#if !defined(NDEBUG)
+    for (Iterator it = range.first; it != range.second; it++) {
+               assert(it->first == port);
+               secdebug("notify", "%p listener removed", it->second.get());
+       }
+#endif //NDEBUG
     listeners.erase(range.first, range.second);
        port.destroy();
     return true;       // got it
     listeners.erase(range.first, range.second);
        port.destroy();
     return true;       // got it
@@ -93,32 +121,91 @@ bool Listener::remove(Port port)
 
 
 //
 
 
 //
-// Construct a new Listener and hook it up
+// Notification message objects
 //
 //
-ProcessListener::ProcessListener(Process &proc, Port receiver,
-       NotificationDomain dom, NotificationMask evs)
-    : Listener(receiver, dom, evs), process(proc)
+Listener::Notification::Notification(NotificationDomain inDomain,
+       NotificationEvent inEvent, uint32 seq, const CssmData &inData)
+       : domain(inDomain), event(inEvent), sequence(seq), data(Allocator::standard(), inData)
 {
 {
-    // let's get told when the receiver port dies
-    Server::active().notifyIfDead(mPort);
-    
-    secdebug("notify", "%p created domain %ld events 0x%lx port %d",
-        this, domain, events, mPort.port());
+       secdebug("notify", "%p notification created domain 0x%lx event %ld seq %ld",
+               this, domain, event, sequence);
+}
+
+Listener::Notification::~Notification()
+{
+       secdebug("notify", "%p notification done domain 0x%lx event %ld seq %ld",
+               this, domain, event, sequence);
 }
 
 
 //
 }
 
 
 //
-// Send a single notification for this listener
+// Jitter buffering
 //
 //
-void ProcessListener::notifyMe(NotificationDomain domain,
-       NotificationEvent event, const CssmData &data)
+bool Listener::JitterBuffer::inSequence(Notification *message)
+{
+       if (message->sequence == mNotifyLast + 1) {     // next in sequence
+               mNotifyLast++;                  // record next sequence
+               return true;                    // go ahead
+       } else {
+               secdebug("notify-jit", "%p out of sequence (last %ld got %ld); buffering",
+                       message, mNotifyLast, message->sequence);
+               mBuffer[message->sequence] = message;   // save for later
+               return false;                   // hold your fire
+       }
+}
+
+RefPointer<Listener::Notification> Listener::JitterBuffer::popNotification()
+{
+       JBuffer::iterator it = mBuffer.find(mNotifyLast + 1);   // have next message?
+       if (it == mBuffer.end())
+               return NULL;                    // nothing here
+       else {
+               RefPointer<Notification> result = it->second;   // save value
+               mBuffer.erase(it);              // remove from buffer
+               secdebug("notify-jit", "%p retrieved from jitter buffer", result.get());
+               return result;                  // return it
+       }
+}
+
+/*
+ * Shared memory listener
+ */
+
+
+SharedMemoryListener::SharedMemoryListener(const char* segmentName, SegmentOffsetType segmentSize) :
+       Listener (kNotificationDomainAll, kNotificationAllEvents),
+       SharedMemoryServer (segmentName, segmentSize),
+       mActive (false)
+{
+       if (segmentName == NULL)
+       {
+               secdebug("notify", "Attempted to start securityd with a NULL segmentName");
+               exit(1);
+       }
+}
+
+SharedMemoryListener::~SharedMemoryListener ()
+{
+}
+
+const double kServerWait = 0.005; // time in seconds before clients will be notified that data is available
+
+void SharedMemoryListener::notifyMe(Notification* notification)
+{
+       const void* data = notification->data.data();
+       UInt32 length = notification->data.length();
+       WriteMessage (notification->domain, notification->event, data, length);
+       
+       if (!mActive)
+       {
+               Server::active().setTimer (this, Time::Interval(kServerWait));
+               mActive = true;
+       }
+}
+
+void SharedMemoryListener::action ()
 {
 {
-    secdebug("notify", "%p sending domain %ld event 0x%lx to port %d process %d",
-        this, domain, event, mPort.port(), process.pid());
-
-    // send mach message (via MIG simpleroutine)
-    if (IFDEBUG(kern_return_t rc =) ucsp_notify_sender_notify(mPort,
-        domain, event, data.data(), data.length(),
-        0 /*@@@ placeholder for sender ID */))
-        secdebug("notify", "%p send failed (error=%d)", this, rc);
+       secdebug("notify", "Posted notification to clients.");
+       notify_post (mSegmentName.c_str ());
+       mActive = false;
 }
 }
index 115df09d11bab508abaea83f94b35e4396abc99f..858e12ef13d147dfd34bd0e7e662a6423f4418e0 100644 (file)
 
 
 //
 
 
 //
-//
+// notifications - handling of securityd-gated notification messages
 //
 #ifndef _H_NOTIFICATIONS
 #define _H_NOTIFICATIONS
 
 #include <security_utilities/mach++.h>
 //
 #ifndef _H_NOTIFICATIONS
 #define _H_NOTIFICATIONS
 
 #include <security_utilities/mach++.h>
+#include <security_utilities/machserver.h>
 #include <security_utilities/globalizer.h>
 #include <securityd_client/ssclient.h>
 #include <map>
 #include <security_utilities/globalizer.h>
 #include <securityd_client/ssclient.h>
 #include <map>
+#include <queue>
+
+#include "SharedMemoryServer.h"
 
 using MachPlusPlus::Port;
 
 using MachPlusPlus::Port;
+using MachPlusPlus::MachServer;
 using SecurityServer::NotificationDomain;
 using SecurityServer::NotificationEvent;
 using SecurityServer::NotificationMask;
 
 using SecurityServer::NotificationDomain;
 using SecurityServer::NotificationEvent;
 using SecurityServer::NotificationMask;
 
+class SharedMemoryListener;
 
 //
 // A registered receiver of notifications.
 
 //
 // A registered receiver of notifications.
@@ -56,20 +62,18 @@ using SecurityServer::NotificationMask;
 // If you need another Listener lifetime management strategy, you will probably
 // have to change things around here.
 //
 // If you need another Listener lifetime management strategy, you will probably
 // have to change things around here.
 //
-class Listener {
+class Listener: public RefCount {
 public:
 public:
-       Listener(Port port, NotificationDomain domain, NotificationMask events);
-       Listener(NotificationDomain domain, NotificationMask events);   
+       Listener(NotificationDomain domain, NotificationMask events,
+               mach_port_t port = MACH_PORT_NULL);     
        virtual ~Listener();
 
        // inject an event into the notification system
     static void notify(NotificationDomain domain,
                NotificationEvent event, const CssmData &data);
        virtual ~Listener();
 
        // inject an event into the notification system
     static void notify(NotificationDomain domain,
                NotificationEvent event, const CssmData &data);
+    static void notify(NotificationDomain domain,
+               NotificationEvent event, uint32 sequence, const CssmData &data);
     static bool remove(Port port);
     static bool remove(Port port);
-       
-       // consume an event for this Listener
-       virtual void notifyMe(NotificationDomain domain,
-               NotificationEvent event, const CssmData &data) = 0;
 
     const NotificationDomain domain;
     const NotificationMask events;
 
     const NotificationDomain domain;
     const NotificationMask events;
@@ -78,37 +82,59 @@ public:
        { return (1 << event) & events; }
 
 protected:
        { return (1 << event) & events; }
 
 protected:
-    Port mPort;
-
+       class Notification : public RefCount {
+       public:
+               Notification(NotificationDomain domain, NotificationEvent event,
+                       uint32 seq, const CssmData &data);
+               virtual ~Notification();
+               
+               const NotificationDomain domain;
+               const NotificationEvent event;
+               const uint32 sequence;
+               const CssmAutoData data;
+               
+               size_t size() const
+               { return data.length(); }       //@@@ add "slop" here for heuristic?
+       };
+       
+       virtual void notifyMe(Notification *message) = 0;
+       
+public:
+       class JitterBuffer {
+       public:
+               JitterBuffer() : mNotifyLast(0) { }
+
+               bool inSequence(Notification *message);
+               RefPointer<Notification> popNotification();
+               
+       private:
+               uint32 mNotifyLast;             // last notification seq processed
+               typedef std::map<uint32, RefPointer<Notification> > JBuffer;
+               JBuffer mBuffer;                // early messages buffer
+       };
+       
 private:
 private:
-       void setup();
+       static void Listener::sendNotification(Notification *message);
     
 private:
     
 private:
-    typedef multimap<mach_port_t, Listener *> ListenerMap;
+    typedef multimap<mach_port_t, RefPointer<Listener> > ListenerMap;
     static ListenerMap listeners;
     static Mutex setLock;
 };
 
 
     static ListenerMap listeners;
     static Mutex setLock;
 };
 
 
-//
-// A registered receiver of notifications.
-// Each one is for a particular database (or all), set of events,
-// and to a particular Mach port. A process may have any number
-// of listeners, each independent; so that multiple notifications can
-// be sent to the same process if it registers repeatedly.
-//
-class Process;
 
 
-class ProcessListener : public Listener {
-public:
-    ProcessListener(Process &proc, Port receiver, NotificationDomain domain,
-               NotificationMask evs = SecurityServer::kNotificationAllEvents);
+class SharedMemoryListener : public Listener, public SharedMemoryServer, public Security::MachPlusPlus::MachServer::Timer
+{
+protected:
+       virtual void action ();
+       virtual void notifyMe(Notification *message);
 
 
-    Process &process;
-    
-       void notifyMe(NotificationDomain domain,
-               NotificationEvent event, const CssmData &data);
-};
+       bool mActive;
 
 
+public:
+       SharedMemoryListener (const char* serverName, u_int32_t serverSize);
+       virtual ~SharedMemoryListener ();
+};
 
 
-#endif //_H_NOTIFICATIONS
+#endif
diff --git a/src/osxcodewrap.cpp b/src/osxcodewrap.cpp
new file mode 100644 (file)
index 0000000..8aeabef
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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@
+ */
+
+
+//
+// osxcodewrap - wrap an OSXCode around a SecCodeRef
+//
+#include "osxcodewrap.h"
+#include <Security/SecCode.h>
+
+
+//
+// We don't really HAVE a canonical encoding, in the sense that
+// the matching OSXCode::decode function won't recognize us.
+// That's not the point; if you want use the old transmission logic,
+// use the canonical OSXCode subclasses.
+//
+string OSXCodeWrap::encode() const
+{
+       return "?:unsupported";
+}
+
+
+//
+// Canonical path directly from the SecCode's mouth
+//     
+string OSXCodeWrap::canonicalPath() const
+{
+       CFURLRef path;
+       MacOSError::check(SecCodeCopyPath(mCode, kSecCSDefaultFlags, &path));
+       return cfString(path, true);
+}
+
+
+//
+// The executable path is a bit annoying to get, but not quite
+// annoying enough to cache the result.
+//
+string OSXCodeWrap::executablePath() const
+{
+       CFRef<CFDictionaryRef> info;
+       MacOSError::check(SecCodeCopySigningInformation(mCode, kSecCSDefaultFlags, &info.aref()));
+       return cfString(CFURLRef(CFDictionaryGetValue(info, kSecCodeInfoMainExecutable)));
+}
diff --git a/src/osxcodewrap.h b/src/osxcodewrap.h
new file mode 100644 (file)
index 0000000..8112fad
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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@
+ */
+
+
+//
+// osxcodewrap - wrap an OSXCode around a SecCodeRef
+//
+#ifndef _H_OSXCODEWRAP
+#define _H_OSXCODEWRAP
+
+#include <security_utilities/osxcode.h>
+#include <Security/SecCode.h>
+#include <string>
+#include <map>
+
+
+//
+// OSXCodeWrap is a partial OSXCode implementation that gets all its information
+// from a SecStaticCodeRef API object. OSXCode and SecStaticCode are in many ways
+// twin brothers, and this class allows the use of a SecStaticCode in places where
+// an OSXCode is required.
+// Note that OSXCodeWrap will not provide the capabilities of the canonical
+// OSXCode subclasses (such as Bundle). its encodings will always specify a type
+// code of '?' (unknown).
+//
+class OSXCodeWrap : public OSXCode {
+public:
+       OSXCodeWrap(SecStaticCodeRef code) : mCode(code) { }
+
+       string encode() const;
+       
+       string canonicalPath() const;
+       string executablePath() const;
+
+private:
+       CFCopyRef<SecStaticCodeRef> mCode;
+};
+
+
+#endif //_H_OSXCODEWRAP
index 6921eca82a02a9bd3df51e08ee896dc30790cbf0..238550711cc829623e24ba3f2e9ee5f1bcc23c28 100644 (file)
@@ -47,6 +47,11 @@ static const char PCSCD_EXEC_PATH[] = "/usr/sbin/pcscd";     // override with $PCSCD
 static const char PCSCD_WORKING_DIR[] = "/var/run/pcscd";      // pcscd's working directory
 static const Time::Interval PCSCD_IDLE_SHUTDOWN(120);          // kill daemon if no devices present
 
 static const char PCSCD_WORKING_DIR[] = "/var/run/pcscd";      // pcscd's working directory
 static const Time::Interval PCSCD_IDLE_SHUTDOWN(120);          // kill daemon if no devices present
 
+// Apple built-in iSight Device VendorID/ProductID: 0x05AC/0x8501
+
+static const uint32_t kVendorProductMask = 0x0000FFFF;
+static const uint32_t kVendorIDApple = 0x05AC;
+static const uint16_t kProductIDBuiltInISight = 0x8501;
 
 //
 // Construct a PCSCMonitor.
 
 //
 // Construct a PCSCMonitor.
@@ -143,6 +148,24 @@ void PCSCMonitor::pollReaders()
        }
 }
 
        }
 }
 
+//
+// Poll PCSC for smartcard status.
+// We are enumerating all readers on each call.
+//
+void PCSCMonitor::clearReaders()
+{
+       if (!mReaders.empty()) {
+               // uh-oh. We had readers connected when pcscd suddenly left
+               secdebug("pcsc", "%ld readers were present when pcscd died", mReaders.size());
+               for (ReaderMap::const_iterator it = mReaders.begin(); it != mReaders.end(); it++) {
+                       Reader *reader = it->second;
+                       secdebug("pcsc", "removing reader %s", reader->name().c_str());
+                       reader->kill();                                         // prepare to die
+               }
+               mReaders.erase(mReaders.begin(), mReaders.end());
+               secdebug("pcsc", "orphaned readers cleared");
+       }
+}
 
 TokenCache& PCSCMonitor::getTokenCache ()
 {
 
 TokenCache& PCSCMonitor::getTokenCache ()
 {
@@ -204,12 +227,16 @@ void PCSCMonitor::childAction()
 // Event notifier.
 // These events are sent by pcscd for our (sole) benefit.
 //
 // Event notifier.
 // These events are sent by pcscd for our (sole) benefit.
 //
-void PCSCMonitor::notifyMe(SecurityServer::NotificationDomain domain,
-               SecurityServer::NotificationEvent event, const CssmData &data)
+void PCSCMonitor::notifyMe(Notification *message)
 {
        Server::active().longTermActivity();
        StLock<Mutex> _(*this);
        assert(mServiceLevel == externalDaemon || Child::state() == alive);
 {
        Server::active().longTermActivity();
        StLock<Mutex> _(*this);
        assert(mServiceLevel == externalDaemon || Child::state() == alive);
+       if (message->event == kNotificationPCSCInitialized)
+       {
+               clearReaders();
+//             mSession.close();
+       }
        pollReaders();
        scheduleTimer(mReaders.empty() && !mGoingToSleep);
 }
        pollReaders();
        scheduleTimer(mReaders.empty() && !mGoingToSleep);
 }
@@ -373,20 +400,31 @@ PCSCMonitor::DeviceSupport PCSCMonitor::deviceSupport(const IOKit::Device &dev)
                                return definite;
                        case kUSBVendorSpecificInterfaceClass:
                                secdebug("scsel", "  Vendor-specific interface - possible match");
                                return definite;
                        case kUSBVendorSpecificInterfaceClass:
                                secdebug("scsel", "  Vendor-specific interface - possible match");
+                               if (isExcludedDevice(dev))
+                               {
+                                       secdebug("scsel", "  interface class %d is not a smartcard device (excluded)", clas);
+                                       return impossible;
+                               }
                                return possible;
                        default:
                                return possible;
                        default:
-                               secdebug("scsel", "  interface class %ld is not a smartcard device", clas);
+                               secdebug("scsel", "  interface class %d is not a smartcard device", clas);
                                return impossible;
                        }
 
                // noncomposite USB device
                if (CFRef<CFNumberRef> cfDevice = dev.property<CFNumberRef>("bDeviceClass"))
                                return impossible;
                        }
 
                // noncomposite USB device
                if (CFRef<CFNumberRef> cfDevice = dev.property<CFNumberRef>("bDeviceClass"))
-                       if (cfNumber(cfDevice) == kUSBVendorSpecificClass) {
+                       if (cfNumber(cfDevice) == kUSBVendorSpecificClass)
+                       {
+                               if (isExcludedDevice(dev))
+                               {
+                                       secdebug("scsel", "  device class %d is not a smartcard device (excluded)", cfNumber(cfDevice));
+                                       return impossible;
+                               }
                                secdebug("scsel", "  Vendor-specific device - possible match");
                                return possible;
                        }
 
                                secdebug("scsel", "  Vendor-specific device - possible match");
                                return possible;
                        }
 
-               // PCCard (aka PCMCIA aka ...) interface (don't know how to recognize a reader here)
+              // PCCard (aka PCMCIA aka ...) interface (don't know how to recognize a reader here)
                if (CFRef<CFStringRef> ioName = dev.property<CFStringRef>("IOName"))
                        if (cfString(ioName).find("pccard", 0, 1) == 0) {
                                secdebug("scsel", "  PCCard - possible match");
                if (CFRef<CFStringRef> ioName = dev.property<CFStringRef>("IOName"))
                        if (cfString(ioName).find("pccard", 0, 1) == 0) {
                                secdebug("scsel", "  PCCard - possible match");
@@ -399,6 +437,19 @@ PCSCMonitor::DeviceSupport PCSCMonitor::deviceSupport(const IOKit::Device &dev)
        }
 }
 
        }
 }
 
+bool PCSCMonitor::isExcludedDevice(const IOKit::Device &dev)
+{
+       uint32_t vendorID = 0, productID = 0;
+       // Simplified version of getVendorAndProductID in pcscd
+       if (CFRef<CFNumberRef> cfVendorID = dev.property<CFNumberRef>(kUSBVendorID))
+               vendorID = cfNumber(cfVendorID);
+
+       if (CFRef<CFNumberRef> cfProductID = dev.property<CFNumberRef>(kUSBProductID))
+               productID = cfNumber(cfProductID);
+       
+       secdebug("scsel", "  checking device for possible exclusion [vendor id: 0x%08X, product id: 0x%08X]", vendorID, productID);
+       return ((vendorID & kVendorProductMask) == kVendorIDApple && (productID & kVendorProductMask) == kProductIDBuiltInISight);
+}
 
 //
 // This gets called (by the Unix/Child system) when pcscd has died for any reason
 
 //
 // This gets called (by the Unix/Child system) when pcscd has died for any reason
@@ -408,16 +459,6 @@ void PCSCMonitor::dying()
        Server::active().longTermActivity();
        StLock<Mutex> _(*this);
        assert(Child::state() == dead);
        Server::active().longTermActivity();
        StLock<Mutex> _(*this);
        assert(Child::state() == dead);
-       if (!mReaders.empty()) {
-               // uh-oh. We had readers connected when pcscd suddenly left
-               secdebug("pcsc", "%ld readers were present when pcscd died", mReaders.size());
-               for (ReaderMap::const_iterator it = mReaders.begin(); it != mReaders.end(); it++) {
-                       Reader *reader = it->second;
-                       secdebug("pcsc", "removing reader %s", reader->name().c_str());
-                       reader->kill();                                         // prepare to die
-               }
-               mReaders.erase(mReaders.begin(), mReaders.end());
-               secdebug("pcsc", "orphaned readers cleared");
-       }
+       clearReaders();
        //@@@ this is where we would attempt a restart, if we wanted to...
 }
        //@@@ this is where we would attempt a restart, if we wanted to...
 }
index 4e48d5e444536c9eab24df7712be190fa7caee38..6b023e14099ca852815725c0f769ec8ba330e465 100644 (file)
@@ -65,7 +65,8 @@ public:
 
 protected:
        void pollReaders();
 
 protected:
        void pollReaders();
-       
+       void clearReaders();
+
        Server &server;
        TokenCache *cache;
        std::string cachePath;
        Server &server;
        TokenCache *cache;
        std::string cachePath;
@@ -73,8 +74,7 @@ protected:
 
 protected:
        // Listener
 
 protected:
        // Listener
-       void notifyMe(SecurityServer::NotificationDomain domain,
-               SecurityServer::NotificationEvent event, const CssmData &data);
+       void notifyMe(Notification *message);
        
        // MachServer::Timer
        void action();
        
        // MachServer::Timer
        void action();
@@ -102,7 +102,8 @@ protected:
                possible                                // perhaps... we're not sure
        };
        DeviceSupport deviceSupport(const IOKit::Device &dev);
                possible                                // perhaps... we're not sure
        };
        DeviceSupport deviceSupport(const IOKit::Device &dev);
-       
+       bool isExcludedDevice(const IOKit::Device &dev);
+
 private:
        ServiceLevel mServiceLevel;     // level of service requested/determined
        void (PCSCMonitor::*mTimerAction)(); // what to do when our timer fires 
 private:
        ServiceLevel mServiceLevel;     // level of service requested/determined
        void (PCSCMonitor::*mTimerAction)(); // what to do when our timer fires 
index 87caf658978007d4a93f75bb64ef61fec246694c..4f482f8edf31a584488abd01cef8c52ad1d54c38 100644 (file)
@@ -30,7 +30,9 @@
 #include "session.h"
 #include "tempdatabase.h"
 #include "authority.h"
 #include "session.h"
 #include "tempdatabase.h"
 #include "authority.h"
-#include "flippers.h"
+
+#include <security_utilities/logging.h>        //@@@ debug only
+#include "agentquery.h"
 
 
 //
 
 
 //
@@ -51,8 +53,9 @@ Process::Process(Port servicePort, TaskPort taskPort,
                CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED);     // you lied!
        }
 
                CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED);     // you lied!
        }
 
-       setup(info, identity);
-       
+       setup(info);
+       ClientIdentification::setup(this->pid());
+
        secdebug("SS", "New process %p(%d) uid=%d gid=%d session=%p TP=%d %sfor %s",
                this, mPid, mUid, mGid, &session(),
         mTaskPort.port(),
        secdebug("SS", "New process %p(%d) uid=%d gid=%d session=%p TP=%d %sfor %s",
                this, mPid, mUid, mGid, &session(),
         mTaskPort.port(),
@@ -63,8 +66,9 @@ Process::Process(Port servicePort, TaskPort taskPort,
 
 //
 // Screen a process setup request for an existing process.
 
 //
 // Screen a process setup request for an existing process.
-// This usually means the client has called exec(2) and forgotten all about itself.
-// Though it could be a nefarious attempt to fool us...
+// This means the client has requested intialization even though we remember having
+// talked to it in the past. This could either be an exec(2), or the client could just
+// have forgotten all about its securityd client state. Or it could be an attack...
 //
 void Process::reset(Port servicePort, TaskPort taskPort,
        const ClientSetupInfo *info, const char *identity, const CommonCriteria::AuditToken &audit)
 //
 void Process::reset(Port servicePort, TaskPort taskPort,
        const ClientSetupInfo *info, const char *identity, const CommonCriteria::AuditToken &audit)
@@ -73,10 +77,24 @@ void Process::reset(Port servicePort, TaskPort taskPort,
                secdebug("SS", "Process %p(%d) reset mismatch (sp %d-%d, tp %d-%d) for %s",
                        this, pid(), servicePort.port(), session().servicePort().port(), taskPort.port(), mTaskPort.port(),
                        (identity && identity[0]) ? identity : "(unknown)");
                secdebug("SS", "Process %p(%d) reset mismatch (sp %d-%d, tp %d-%d) for %s",
                        this, pid(), servicePort.port(), session().servicePort().port(), taskPort.port(), mTaskPort.port(),
                        (identity && identity[0]) ? identity : "(unknown)");
-               CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED);             // liar
+               Session &newSession = Session::find(servicePort);
+               Syslog::alert("Process reset %p(%d) session %d(0x%x:0x%x)->%d(0x%x:0x%x) for %s",
+                       this, pid(),
+                       session().servicePort().port(), &session(), session().attributes(),
+                       newSession.servicePort().port(), &newSession, newSession.attributes(),
+                       (identity && identity[0]) ? identity : "(unknown)");
+               //CssmError::throwMe(CSSM_ERRCODE_VERIFICATION_FAILURE);                // liar
+       }
+       
+       string oldPath = codePath(processCode());
+       setup(info);
+       ClientIdentification::setup(this->pid());
+       if (codePath(processCode()) == oldPath) {
+               secdebug("SS", "process %p(%d) path unchanged; assuming client-side reset", this, mPid);
+       } else {
+               secdebug("SS", "process %p(%d) path changed; assuming exec with full reset", this, mPid);
+               CodeSigningHost::reset();
        }
        }
-
-       setup(info, identity);
        
        secdebug("SS", "process %p(%d) has reset; now %sfor %s",
                this, mPid, mByteFlipped ? "FLIP " : "",
        
        secdebug("SS", "process %p(%d) has reset; now %sfor %s",
                this, mPid, mByteFlipped ? "FLIP " : "",
@@ -87,13 +105,14 @@ void Process::reset(Port servicePort, TaskPort taskPort,
 //
 // Common set processing
 //
 //
 // Common set processing
 //
-void Process::setup(const ClientSetupInfo *info, const char *identity)
+void Process::setup(const ClientSetupInfo *info)
 {
        // process setup info
        assert(info);
        uint32 pversion;
        if (info->order == 0x1234) {    // right side up
                pversion = info->version;
 {
        // process setup info
        assert(info);
        uint32 pversion;
        if (info->order == 0x1234) {    // right side up
                pversion = info->version;
+               mByteFlipped = false;
        } else if (info->order == 0x34120000) { // flip side up
                pversion = ntohl(info->version);
                mByteFlipped = true;
        } else if (info->order == 0x34120000) { // flip side up
                pversion = ntohl(info->version);
                mByteFlipped = true;
@@ -103,17 +122,6 @@ void Process::setup(const ClientSetupInfo *info, const char *identity)
        // check wire protocol version
        if (pversion != SSPROTOVERSION)
                CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION);
        // check wire protocol version
        if (pversion != SSPROTOVERSION)
                CssmError::throwMe(CSSM_ERRCODE_INCOMPATIBLE_VERSION);
-
-       // process identity (if given)
-       try {
-               mClientCode = OSXCode::decode(identity);
-               mClientIdent = deferred;        // will calculate code identity when needed
-       } catch (...) {
-               secdebug("SS", "process %p(%d) identity decode threw exception", this, pid());
-               mClientCode = NULL;
-               mClientIdent = unknown;         // no chance to squeeze a code identity from this
-               secdebug("SS", "process %p(%d) no clientCode - marked anonymous", this, pid());
-       }
 }
 
 
 }
 
 
@@ -188,43 +196,6 @@ void Process::changeSession(Port servicePort)
 }
 
 
 }
 
 
-//
-// CodeSignatures implementation of Identity.
-// The caller must make sure we have a valid (not necessarily hash-able) clientCode().
-//
-string Process::getPath() const
-{
-       assert(mClientCode);
-       return mClientCode->canonicalPath();
-}
-
-const CssmData Process::getHash(CodeSigning::OSXSigner &signer) const
-{
-       switch (mClientIdent) {
-       case deferred:
-               try {
-                       // try to calculate our signature hash (first time use)
-                       mCachedSignature.reset(mClientCode->sign(signer));
-                       assert(mCachedSignature.get());
-                       mClientIdent = known;
-                       secdebug("SS", "process %p(%d) code signature computed", this, pid());
-                       break;
-               } catch (...) {
-                       // couldn't get client signature (unreadable, gone, hack attack, ...)
-                       mClientIdent = unknown;
-                       secdebug("SS", "process %p(%d) no code signature - anonymous", this, pid());
-                       CssmError::throwMe(CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION);
-               }
-       case known:
-               assert(mCachedSignature.get());
-               break;
-       case unknown:
-               CssmError::throwMe(CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION);
-       }
-       return CssmData(*mCachedSignature);
-}
-
-
 //
 // Authorization set maintainance
 //
 //
 // Authorization set maintainance
 //
@@ -267,21 +238,6 @@ bool Process::removeAuthorization(AuthorizationToken *auth)
 }
 
 
 }
 
 
-//
-// Notification client maintainance
-//
-void Process::requestNotifications(Port port, SecurityServer::NotificationDomain domain, SecurityServer::NotificationMask events)
-{
-    new ProcessListener(*this, port, domain, events);
-}
-
-void Process::stopNotifications(Port port)
-{
-    if (!Listener::remove(port))
-        CssmError::throwMe(CSSMERR_CSSM_INVALID_HANDLE_USAGE); //@@@ bad name (should be "no such callback")
-}
-
-
 //
 // Debug dump support
 //
 //
 // Debug dump support
 //
@@ -294,21 +250,8 @@ void Process::dumpNode()
                Debug::dump(" FLIPPED");
        Debug::dump(" task=%d pid=%d uid/gid=%d/%d",
                mTaskPort.port(), mPid, mUid, mGid);
                Debug::dump(" FLIPPED");
        Debug::dump(" task=%d pid=%d uid/gid=%d/%d",
                mTaskPort.port(), mPid, mUid, mGid);
-       if (mClientCode) {
-               Debug::dump(" client=%s", mClientCode->canonicalPath().c_str());
-               switch (mClientIdent) {
-               case deferred:
-                       break;
-               case known:
-                       Debug::dump("[OK]");
-                       break;
-               case unknown:
-                       Debug::dump("[UNKNOWN]");
-                       break;
-               }
-       } else {
-               Debug::dump(" NO CLIENT ID");
-       }
+       CodeSigningHost::dump();
+       ClientIdentification::dump();
 }
 
 #endif //DEBUGDUMP
 }
 
 #endif //DEBUGDUMP
index 97735f3f17e6c674263b7fa344d230c58dc9fd89..59cc330f079d937629fb4e1fe1340c8c8fd12a01 100644 (file)
@@ -32,8 +32,9 @@
 #include <security_agent_client/agentclient.h>
 #include <security_utilities/refcount.h>
 #include <security_utilities/ccaudit.h>
 #include <security_agent_client/agentclient.h>
 #include <security_utilities/refcount.h>
 #include <security_utilities/ccaudit.h>
+#include "clientid.h"
+#include "csproxy.h"
 #include "localkey.h"
 #include "localkey.h"
-#include "codesigdb.h"
 #include "notifications.h"
 #include <string>
 
 #include "notifications.h"
 #include <string>
 
@@ -47,9 +48,25 @@ class AuthorizationToken;
 
 //
 // A Process object represents a UNIX process (and associated Mach Task) that has
 
 //
 // A Process object represents a UNIX process (and associated Mach Task) that has
-// had contact with us and may have some state associated with it.
+// had contact with us and may have some state associated with it. It primarily tracks
+// the process nature of the client. Individual threads in the client are tracked by
+// Connection objects.
 //
 //
-class Process : public PerProcess, public CodeSignatures::Identity {
+// Code Signing-style Guest identities are managed in two of our mix-ins. The two play
+// distinct but related roles:
+// * CodeSigningHost manages the public identity of guests within the client.
+//   In this relationship, securityd provides registry and proxy services to the client.
+// * ClientIdentification tracks the identity of guests in the client *as securityd clients*.
+//   It is concerned with which guest is asking for securityd services, and whether this
+//   should be granted.
+// Often, the two form a loop: ClientIdentification uses CodeSigningHost to determine
+// the guest client identity, but it does so through public (Mach IPC) interfaces, because
+// clients may implement their own proxy (though currently not registry) services.
+// We could short-circuit the IPC leg in those cases where securityd serves itself,
+// but there's no evidence (yet) that this is worth the trouble.
+//
+class Process : public PerProcess,
+       public CodeSigningHost, public ClientIdentification {
 public:
        Process(Port servicePort, TaskPort tPort,
                const ClientSetupInfo *info, const char *identity,
 public:
        Process(Port servicePort, TaskPort tPort,
                const ClientSetupInfo *info, const char *identity,
@@ -66,8 +83,6 @@ public:
     TaskPort taskPort() const  { return mTaskPort; }
        bool byteFlipped() const        { return mByteFlipped; }
        
     TaskPort taskPort() const  { return mTaskPort; }
        bool byteFlipped() const        { return mByteFlipped; }
        
-       OSXCode *clientCode() const { return (mClientIdent == unknown) ? NULL : mClientCode; }
-       
        void addAuthorization(AuthorizationToken *auth);
        void checkAuthorization(AuthorizationToken *auth);
        bool removeAuthorization(AuthorizationToken *auth);
        void addAuthorization(AuthorizationToken *auth);
        void checkAuthorization(AuthorizationToken *auth);
        bool removeAuthorization(AuthorizationToken *auth);
@@ -77,9 +92,6 @@ public:
        
        void changeSession(Port servicePort);   // very special indeed
     
        
        void changeSession(Port servicePort);   // very special indeed
     
-    void requestNotifications(Port port, NotificationDomain domain, NotificationMask events);
-    void stopNotifications(Port port);
-    
        Session& session() const;
        
        LocalDatabase &localStore();
        Session& session() const;
        
        LocalDatabase &localStore();
@@ -91,11 +103,8 @@ public:
        
        IFDUMP(void dumpNode());
        
        
        IFDUMP(void dumpNode());
        
-protected:
-       std::string getPath() const;
-       const CssmData getHash(CodeSigning::OSXSigner &signer) const;
-
-       void setup(const ClientSetupInfo *info, const char *identity);
+private:
+       void setup(const ClientSetupInfo *info);
        
 private:
        // peer state: established during connection startup; fixed thereafter
        
 private:
        // peer state: established during connection startup; fixed thereafter
@@ -105,10 +114,6 @@ private:
     uid_t mUid;                                                        // UNIX uid credential
     gid_t mGid;                                                        // primary UNIX gid credential
        
     uid_t mUid;                                                        // UNIX uid credential
     gid_t mGid;                                                        // primary UNIX gid credential
        
-       RefPointer<OSXCode> mClientCode; // code object for client (NULL if unknown)
-       mutable enum { deferred, known, unknown } mClientIdent; // state of client identity
-       mutable auto_ptr<CodeSigning::Signature> mCachedSignature; // cached signature (if already known)
-       
        // authorization dictionary
        typedef multiset<AuthorizationToken *> AuthorizationSet;
        AuthorizationSet mAuthorizations;       // set of valid authorizations for process
        // authorization dictionary
        typedef multiset<AuthorizationToken *> AuthorizationSet;
        AuthorizationSet mAuthorizations;       // set of valid authorizations for process
diff --git a/src/securityd.exp b/src/securityd.exp
new file mode 100644 (file)
index 0000000..e69de29
index e18129662b5f6011730fa02caf2438d914c1c715..bd1a5ae4d55f5511e796837126682a00a5acce3e 100644 (file)
@@ -321,7 +321,6 @@ _uw_install_context_1
 _init_dwarf_reg_size_table
 eh_rest_world_r10
 rest_world_eh_r7r8
 _init_dwarf_reg_size_table
 eh_rest_world_r10
 rest_world_eh_r7r8
-__Unwind_Resume
 ___cxa_begin_catch
 __ZN8Security9CssmError9cssmErrorERKNS_11CommonErrorEl
 __ZNK13Authorization5Error8osStatusEv
 ___cxa_begin_catch
 __ZN8Security9CssmError9cssmErrorERKNS_11CommonErrorEl
 __ZNK13Authorization5Error8osStatusEv
index f440a7d8fff07b252ceb20bbbb092377c7aaaab5..f07241d870948cedc08c462da452128b2066058e 100644 (file)
@@ -37,6 +37,9 @@
 #include <mach/mach_error.h>
 #include <security_utilities/ccaudit.h>
 
 #include <mach/mach_error.h>
 #include <security_utilities/ccaudit.h>
 
+#include "agentquery.h"
+
+
 using namespace MachPlusPlus;
 
 //
 using namespace MachPlusPlus;
 
 //
@@ -57,6 +60,7 @@ Authority::~Authority()
 Server::Server(Authority &authority, CodeSignatures &signatures, const char *bootstrapName)
   : MachServer(bootstrapName),
     mBootstrapName(bootstrapName),
 Server::Server(Authority &authority, CodeSignatures &signatures, const char *bootstrapName)
   : MachServer(bootstrapName),
     mBootstrapName(bootstrapName),
+       mShutdown(shutdownImmediately),
     mCSPModule(gGuidAppleCSP, mCssm), mCSP(mCSPModule),
     mAuthority(authority),
        mCodeSignatures(signatures), 
     mCSPModule(gGuidAppleCSP, mCssm), mCSP(mCSPModule),
     mAuthority(authority),
        mCodeSignatures(signatures), 
@@ -106,11 +110,11 @@ Connection &Server::connection(bool tolerant)
        return *conn;
 }
 
        return *conn;
 }
 
-void Server::requestComplete()
+void Server::requestComplete(CSSM_RETURN &rcode)
 {
        // note: there may not be an active connection if connection setup failed
        if (RefPointer<Connection> &conn = active().mCurrentConnection()) {
 {
        // note: there may not be an active connection if connection setup failed
        if (RefPointer<Connection> &conn = active().mCurrentConnection()) {
-               conn->endWork();
+               conn->endWork(rcode);
                conn = NULL;
        }
        IFDUMPING("state", NodeCore::dumpAll());
                conn = NULL;
        }
        IFDUMPING("state", NodeCore::dumpAll());
@@ -199,21 +203,18 @@ void Server::threadLimitReached(UInt32 limit)
 boolean_t ucsp_server(mach_msg_header_t *, mach_msg_header_t *);
 boolean_t self_server(mach_msg_header_t *, mach_msg_header_t *);
 
 boolean_t ucsp_server(mach_msg_header_t *, mach_msg_header_t *);
 boolean_t self_server(mach_msg_header_t *, mach_msg_header_t *);
 
-#if defined(NDEBUG)
-
-boolean_t Server::handle(mach_msg_header_t *in, mach_msg_header_t *out)
-{
-       return ucsp_server(in, out) || self_server(in, out);
-}
 
 
-#else //NDEBUG
+#if !defined(NDEBUG)
 
 struct IPCName { const char *name; int ipc; };
 static IPCName ucspNames[] = { subsystem_to_name_map_ucsp }; // generated by MIG
 static IPCName selfNames[] = { subsystem_to_name_map_self }; // generated by MIG
 
 
 struct IPCName { const char *name; int ipc; };
 static IPCName ucspNames[] = { subsystem_to_name_map_ucsp }; // generated by MIG
 static IPCName selfNames[] = { subsystem_to_name_map_self }; // generated by MIG
 
+#endif //NDEBUG
+
 boolean_t Server::handle(mach_msg_header_t *in, mach_msg_header_t *out)
 {
 boolean_t Server::handle(mach_msg_header_t *in, mach_msg_header_t *out)
 {
+#if !defined(NDEBUG)
        const int id = in->msgh_id;
        const int ucspBase = ucspNames[0].ipc;
        const int selfBase = selfNames[0].ipc;
        const int id = in->msgh_id;
        const int ucspBase = ucspNames[0].ipc;
        const int selfBase = selfNames[0].ipc;
@@ -222,13 +223,14 @@ boolean_t Server::handle(mach_msg_header_t *in, mach_msg_header_t *out)
                (id >= selfBase && id < selfBase + self_MSG_COUNT) ? selfNames[id - selfBase].name :
                "OUT OF BOUNDS";
     secdebug("SSreq", "begin %s (%d)", name, in->msgh_id);
                (id >= selfBase && id < selfBase + self_MSG_COUNT) ? selfNames[id - selfBase].name :
                "OUT OF BOUNDS";
     secdebug("SSreq", "begin %s (%d)", name, in->msgh_id);
+#endif //NDEBUG
+
        boolean_t result = ucsp_server(in, out) || self_server(in, out);
        boolean_t result = ucsp_server(in, out) || self_server(in, out);
-    secdebug("SSreq", "end %s (%d)", name, in->msgh_id);
+       IFDEBUG(secdebug("SSreq", "end %s (%d)", name, in->msgh_id));
+               
     return result;
 }
 
     return result;
 }
 
-#endif //NDEBUG
-
 
 //
 // Set up a new Connection. This establishes the environment (process et al) as needed
 
 //
 // Set up a new Connection. This establishes the environment (process et al) as needed
@@ -251,6 +253,7 @@ void Server::setupConnection(ConnectLevel type, Port servicePort, Port replyPort
                // the client has amnesia - reset it
                assert(info && identity);
                proc->reset(servicePort, taskPort, info, identity, AuditToken(auditToken));
                // the client has amnesia - reset it
                assert(info && identity);
                proc->reset(servicePort, taskPort, info, identity, AuditToken(auditToken));
+               proc->changeSession(servicePort);
        }
        if (!proc) {
                if (type == connectNewThread)   // client error (or attack)
        }
        if (!proc) {
                if (type == connectNewThread)   // client error (or attack)
@@ -258,6 +261,7 @@ void Server::setupConnection(ConnectLevel type, Port servicePort, Port replyPort
                assert(info && identity);
                proc = new Process(servicePort, taskPort, info, identity, AuditToken(auditToken));
                notifyIfDead(taskPort);
                assert(info && identity);
                proc = new Process(servicePort, taskPort, info, identity, AuditToken(auditToken));
                notifyIfDead(taskPort);
+               mPids[proc->pid()] = proc;
        }
 
        // now, establish a connection and register it in the server
        }
 
        // now, establish a connection and register it in the server
@@ -305,15 +309,13 @@ void Server::notifyDeadName(Port port)
     // is it a process?
     PortMap<Process>::iterator procIt = mProcesses.find(port);
     if (procIt != mProcesses.end()) {
     // is it a process?
     PortMap<Process>::iterator procIt = mProcesses.find(port);
     if (procIt != mProcesses.end()) {
-               procIt->second->kill();
+               Process *proc = procIt->second;
+               proc->kill();
+               mPids.erase(proc->pid());
                mProcesses.erase(procIt);
         return;
     }
     
                mProcesses.erase(procIt);
         return;
     }
     
-    // is it a notification client?
-    if (Listener::remove(port))
-        return;
-    
        // well, what IS IT?!
        secdebug("server", "spurious dead port notification for port %d", port.port());
 }
        // well, what IS IT?!
        secdebug("server", "spurious dead port notification for port %d", port.port());
 }
@@ -342,7 +344,7 @@ kern_return_t self_server_handleSignal(mach_port_t sport,
         if (taskPort != mach_task_self()) {
             Syslog::error("handleSignal: received from someone other than myself");
                        secdebug("SS", "unauthorized handleSignal");
         if (taskPort != mach_task_self()) {
             Syslog::error("handleSignal: received from someone other than myself");
                        secdebug("SS", "unauthorized handleSignal");
-                       return 0;
+                       return KERN_SUCCESS;
                }
                secdebug("SS", "dispatching indirect signal %d", sig);
                switch (sig) {
                }
                secdebug("SS", "dispatching indirect signal %d", sig);
                switch (sig) {
@@ -350,10 +352,23 @@ kern_return_t self_server_handleSignal(mach_port_t sport,
                        ServerChild::checkChildren();
                        break;
                case SIGINT:
                        ServerChild::checkChildren();
                        break;
                case SIGINT:
-               case SIGTERM:
-                       secdebug("SS", "signal %d received: terminating", sig);
-                       Syslog::notice("securityd terminating due to signal %d", sig);
+                       secdebug("SS", "SIGINT received: terminating immediately");
+                       Syslog::notice("securityd terminated due to SIGINT");
                        exit(0);
                        exit(0);
+               case SIGTERM:
+                       if (Server::active().beginShutdown()) {
+                               Syslog::notice("securityd shutting down; lingering for remaining clients");
+                       } else {
+                               secdebug("SS", "SIGTERM received: terminating immediately");
+                               Syslog::notice("securityd terminated due to SIGTERM");
+                               exit(0);
+                       }
+                       break;
+               case SIGPIPE:
+                       secdebug("SS", "SIGPIPE received: ignoring");
+                       Syslog::notice("securityd ignoring SIGPIPE received");
+                       break;
+
 #if defined(DEBUGDUMP)
                case SIGUSR1:
                        NodeCore::dumpAll();
 #if defined(DEBUGDUMP)
                case SIGUSR1:
                        NodeCore::dumpAll();
@@ -366,7 +381,7 @@ kern_return_t self_server_handleSignal(mach_port_t sport,
                secdebug("SS", "exception handling a signal (ignored)");
        }
     mach_port_deallocate(mach_task_self(), taskPort);
                secdebug("SS", "exception handling a signal (ignored)");
        }
     mach_port_deallocate(mach_task_self(), taskPort);
-    return 0;
+    return KERN_SUCCESS;
 }
 
 
 }
 
 
@@ -402,6 +417,85 @@ void Server::SleepWatcher::remove(PowerWatcher *client)
 }
 
 
 }
 
 
+//
+// Expose the process/pid map to the outside
+//
+Process *Server::findPid(pid_t pid) const
+{
+       PidMap::const_iterator it = mPids.find(pid);
+       return (it == mPids.end()) ? NULL : it->second;
+}
+
+
+//
+// Set delayed shutdown mode
+//
+void Server::waitForClients(bool waiting)
+{
+       if (mShutdown == shuttingDown)          // too late to change your mind now
+               return;
+       if (waiting)
+               mShutdown = shutdownDelayed;
+       else
+               mShutdown = shutdownImmediately;
+}
+
+
+//
+// Shutdown processing
+//
+bool Server::beginShutdown()
+{
+       if (mShutdown != shutdownDelayed)
+               return false;
+
+       secdebug("server", "beginning shutdown with %d client(s)", int(mProcesses.size()));
+       mShutdown = shuttingDown;
+
+#if defined(SHUTDOWN_SNITCH)
+       struct Snitch : public MachServer::Timer {
+               void action() { Server::active().shutdownSnitch(); }
+       };
+       setTimer(new Snitch, Time::Interval(29));       // right before we get SIGKILLed
+#endif
+
+       return true;
+}
+
+
+void Server::eventDone()
+{
+       if (mShutdown == shuttingDown) {
+               if (mProcesses.empty()) {
+                       secdebug("SS", "out of clients - shutdown complete");
+                       Syslog::notice("securityd has finished serving its clients - terminating now");
+                       exit(0);
+               } else {
+                       secdebug("SS", "shutdown in progress - %d process(es) left", int(mProcesses.size()));
+                       IFDUMPING("shutdown", NodeCore::dumpAll());
+               }
+       }
+}
+
+#if defined(SHUTDOWN_SNITCH)
+
+void Server::shutdownSnitch()
+{
+       Syslog::notice("29 seconds after shutdown began, securityd still has %d clients:", int(mPids.size()));
+       for (PidMap::const_iterator it = mPids.begin(); it != mPids.end(); ++it)
+               if (SecCodeRef clientCode = it->second->processCode()) {
+                       CFRef<CFURLRef> path;
+                       SecCodeCopyPath(clientCode, kSecCSDefaultFlags, &path.aref());
+                       if (path)
+                               Syslog::notice(" %s (%d)", cfString(path).c_str(), it->first);
+                       else
+                               Syslog::notice(" pid=%d", it->first);
+               }
+}
+
+#endif //SHUTDOWN_SNITCH
+
+
 //
 // Initialize the CSSM/MDS subsystem.
 // This was once done lazily on demand. These days, we are setting up the
 //
 // Initialize the CSSM/MDS subsystem.
 // This was once done lazily on demand. These days, we are setting up the
@@ -414,7 +508,8 @@ void Server::loadCssm()
                StLock<Mutex> _(*this);
                if (!mCssm->isActive()) {
                        secdebug("SS", "Installing MDS");
                StLock<Mutex> _(*this);
                if (!mCssm->isActive()) {
                        secdebug("SS", "Installing MDS");
-                       MDSClient::mds().install();
+                       IFDEBUG(if (geteuid() == 0))
+                               MDSClient::mds().install();
                        secdebug("SS", "CSSM initializing");
                        mCssm->init();
                        mCSP->attach();
                        secdebug("SS", "CSSM initializing");
                        mCssm->init();
                        mCSP->attach();
@@ -422,3 +517,18 @@ void Server::loadCssm()
                }
        }
 }
                }
        }
 }
+
+
+//
+// LongtermActivity/lock combo
+//
+LongtermStLock::LongtermStLock(Mutex &lck)
+       : StLock<Mutex>(lck, false)     // don't take the lock yet
+{
+       if (lck.tryLock()) {    // uncontested
+               this->mActive = true;
+       } else {                                // contested - need backup thread
+               Server::active().longTermActivity();
+               this->lock();
+       }
+}
index 011a649fc95a6dfa1d16a0bd1182b93cc083f812..5d6717b9cb11ff16fa6856d251a3350acc6417b2 100644 (file)
@@ -20,6 +20,7 @@
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
+#define SHUTDOWN_SNITCH
 
 
 //
 
 
 //
@@ -34,7 +35,6 @@
 #include <security_utilities/ccaudit.h>
 #include <security_cdsa_client/cssmclient.h>
 #include <security_cdsa_client/cspclient.h>
 #include <security_utilities/ccaudit.h>
 #include <security_cdsa_client/cssmclient.h>
 #include <security_cdsa_client/cspclient.h>
-#include <security_cdsa_client/osxsigner.h>
 #include <security_utilities/devrandom.h>
 #include <security_cdsa_utilities/uniformrandom.h>
 #include "codesigdb.h"
 #include <security_utilities/devrandom.h>
 #include <security_cdsa_utilities/uniformrandom.h>
 #include "codesigdb.h"
@@ -94,7 +94,7 @@ public:
        //
        static Connection &connection(mach_port_t replyPort);   // find by reply port and make active
        static Connection &connection(bool tolerant = false);   // return active (or fail unless tolerant)
        //
        static Connection &connection(mach_port_t replyPort);   // find by reply port and make active
        static Connection &connection(bool tolerant = false);   // return active (or fail unless tolerant)
-       static void requestComplete();                                                  // de-activate active connection
+       static void requestComplete(CSSM_RETURN &rcode);                // de-activate active connection
        
        //
        // Process and session of the active Connection
        
        //
        // Process and session of the active Connection
@@ -161,6 +161,7 @@ protected:
        void notifyDeadName(Port port);
        void notifyNoSenders(Port port, mach_port_mscount_t);
        void threadLimitReached(UInt32 count);
        void notifyDeadName(Port port);
        void notifyNoSenders(Port port, mach_port_mscount_t);
        void threadLimitReached(UInt32 count);
+       void eventDone();
 
 private:
        class SleepWatcher : public MachPlusPlus::PortPowerWatcher {
 
 private:
        class SleepWatcher : public MachPlusPlus::PortPowerWatcher {
@@ -182,6 +183,12 @@ public:
        using MachServer::remove;
        void add(MachPlusPlus::PowerWatcher *client)    { StLock<Mutex> _(*this); sleepWatcher.add(client); }
        void remove(MachPlusPlus::PowerWatcher *client) { StLock<Mutex> _(*this); sleepWatcher.remove(client); }
        using MachServer::remove;
        void add(MachPlusPlus::PowerWatcher *client)    { StLock<Mutex> _(*this); sleepWatcher.add(client); }
        void remove(MachPlusPlus::PowerWatcher *client) { StLock<Mutex> _(*this); sleepWatcher.remove(client); }
+       
+public:
+       Process *findPid(pid_t pid) const;
+
+       void waitForClients(bool waiting);                              // set waiting behavior
+       bool beginShutdown();                                                   // start delayed shutdown if configured
     
 private:
        // mach bootstrap registration name
     
 private:
        // mach bootstrap registration name
@@ -191,7 +198,16 @@ private:
        PortMap<Connection> mConnections;
 
        // process map (by process task port)
        PortMap<Connection> mConnections;
 
        // process map (by process task port)
-       PortMap<Process> mProcesses;
+       typedef std::map<pid_t, Process *> PidMap;
+       PortMap<Process> mProcesses;                                    // strong reference
+       PidMap mPids;                                                                   // weak reference (subsidiary to mProcesses)
+       
+       enum ShutdownMode {
+               shutdownImmediately,                                            // shut down immediately on SIGTERM
+               shutdownDelayed,                                                        // wait for clients on SIGTERM
+               shuttingDown                                                            // delayed shutdown in progress
+       } mShutdown;                                                                    // shutdown mode
+       void shutdownSnitch();                                                  // rat out lingering clients (to syslog)
        
        // Current connection, if any (per thread).
        // Set as a side effect of calling connection(mach_port_t)
        
        // Current connection, if any (per thread).
        // Set as a side effect of calling connection(mach_port_t)
@@ -210,4 +226,14 @@ private:
     CommonCriteria::AuditSession mAudit;
 };
 
     CommonCriteria::AuditSession mAudit;
 };
 
+
+//
+// A StLock that (also) declares a longTermActivity (only) once it's been entered.
+//
+class LongtermStLock : public StLock<Mutex> {
+public:
+       LongtermStLock(Mutex &lck);
+       // destructor inherited
+};
+
 #endif //_H_SERVER
 #endif //_H_SERVER
index 7cabc913cbebd61d89e124dfc85a26e759b2d0d3..105b2af611ad35b1fffbec0d7d022735139b87d8 100644 (file)
 //
 // Sessions are multi-threaded objects.
 //
 //
 // Sessions are multi-threaded objects.
 //
+#include <pwd.h>
+#include <Security/AuthorizationPriv.h> // kAuthorizationFlagLeastPrivileged
+
 #include "session.h"
 #include "connection.h"
 #include "database.h"
 #include "server.h"
 
 #include "session.h"
 #include "connection.h"
 #include "database.h"
 #include "server.h"
 
-
 //
 // The static session map
 //
 PortMap<Session> Session::mSessions;
 
 //
 // The static session map
 //
 PortMap<Session> Session::mSessions;
 
+std::string Session::kUsername = "username";
+std::string Session::kRealname = "realname";
 
 //
 // Create a Session object from initial parameters (create)
 
 //
 // Create a Session object from initial parameters (create)
@@ -164,21 +168,11 @@ RootSession::RootSession(Server &server, SessionAttributeBits attrs)
        mSessions[mServicePort] = this;
 }
 
        mSessions[mServicePort] = this;
 }
 
-uid_t RootSession::originatorUid() const
-{
-       return 0;       // it's root, obviously
-}
-
-CFDataRef RootSession::copyUserPrefs()
-{
-       return NULL;
-}
-
 //
 // Dynamic sessions use the given bootstrap and re-register in it
 //
 DynamicSession::DynamicSession(TaskPort taskPort)
 //
 // Dynamic sessions use the given bootstrap and re-register in it
 //
 DynamicSession::DynamicSession(TaskPort taskPort)
-       : ReceivePort(Server::active().bootstrapName(), taskPort.bootstrap()),
+       : ReceivePort(Server::active().bootstrapName(), taskPort.bootstrap(), false),
          Session(taskPort.bootstrap(), *this),
          mOriginatorTask(taskPort), mHaveOriginatorUid(false)
 {
          Session(taskPort.bootstrap(), *this),
          mOriginatorTask(taskPort), mHaveOriginatorUid(false)
 {
@@ -265,10 +259,19 @@ void DynamicSession::originatorUid(uid_t uid)
                MacOSError::throwMe(errSessionAuthorizationDenied);
        mHaveOriginatorUid = true;
        mOriginatorUid = uid;
                MacOSError::throwMe(errSessionAuthorizationDenied);
        mHaveOriginatorUid = true;
        mOriginatorUid = uid;
+
+       Server::active().longTermActivity();
+       struct passwd *pw = getpwuid(uid);
+
+       if (pw != NULL) {
+
+        mOriginatorCredential = Credential(uid, pw->pw_name ? pw->pw_name : "", pw->pw_gecos ? pw->pw_gecos : "", true/*shared*/);
+        endpwent();
+       }
+
        secdebug("SSsession", "%p session uid set to %d", this, uid);
 }
 
        secdebug("SSsession", "%p session uid set to %d", this, uid);
 }
 
-
 //
 // Authorization operations
 //
 //
 // Authorization operations
 //
@@ -282,7 +285,7 @@ OSStatus Session::authCreate(const AuthItemSet &rights,
        CredentialSet resultCreds;
        
        // this will acquire the object lock, so we delay acquiring it (@@@ no longer needed)
        CredentialSet resultCreds;
        
        // this will acquire the object lock, so we delay acquiring it (@@@ no longer needed)
-       auto_ptr<AuthorizationToken> auth(new AuthorizationToken(*this, resultCreds, auditToken));
+       auto_ptr<AuthorizationToken> auth(new AuthorizationToken(*this, resultCreds, auditToken, (flags&kAuthorizationFlagLeastPrivileged)));
 
     // Make a copy of the mSessionCreds
     CredentialSet sessionCreds;
 
     // Make a copy of the mSessionCreds
     CredentialSet sessionCreds;
@@ -335,9 +338,17 @@ OSStatus Session::authGetRights(const AuthorizationBlob &authBlob,
        const AuthItemSet &rights, const AuthItemSet &environment,
        AuthorizationFlags flags,
        AuthItemSet &grantedRights)
        const AuthItemSet &rights, const AuthItemSet &environment,
        AuthorizationFlags flags,
        AuthItemSet &grantedRights)
+{
+       AuthorizationToken &auth = authorization(authBlob);
+       return auth.session().authGetRights(auth, rights, environment, flags, grantedRights);
+}
+
+OSStatus Session::authGetRights(AuthorizationToken &auth,
+       const AuthItemSet &rights, const AuthItemSet &environment,
+       AuthorizationFlags flags,
+       AuthItemSet &grantedRights)
 {
     CredentialSet resultCreds;
 {
     CredentialSet resultCreds;
-    AuthorizationToken &auth = authorization(authBlob);
     CredentialSet effective;
     {
         StLock<Mutex> _(mCredsLock);
     CredentialSet effective;
     {
         StLock<Mutex> _(mCredsLock);
@@ -355,7 +366,7 @@ OSStatus Session::authGetRights(const AuthorizationBlob &authBlob,
        }
 
        secdebug("SSauth", "Authorization %p copyRights asked for %d got %d",
        }
 
        secdebug("SSauth", "Authorization %p copyRights asked for %d got %d",
-               &authorization(authBlob), int(rights.size()), int(grantedRights.size()));
+               &auth, int(rights.size()), int(grantedRights.size()));
        return result;
 }
 
        return result;
 }
 
@@ -487,7 +498,7 @@ void Session::mergeCredentials(CredentialSet &creds)
     secdebug("SSsession", "%p merge creds @%p", this, &creds);
        CredentialSet updatedCredentials = creds;
        for (CredentialSet::const_iterator it = creds.begin(); it != creds.end(); it++)
     secdebug("SSsession", "%p merge creds @%p", this, &creds);
        CredentialSet updatedCredentials = creds;
        for (CredentialSet::const_iterator it = creds.begin(); it != creds.end(); it++)
-               if (((*it)->isShared() && (*it)->isValid())) {
+               if ((*it)->isShared() && (*it)->isValid()) {
                        CredentialSet::iterator old = mSessionCreds.find(*it);
                        if (old == mSessionCreds.end()) {
                                mSessionCreds.insert(*it);
                        CredentialSet::iterator old = mSessionCreds.find(*it);
                        if (old == mSessionCreds.end()) {
                                mSessionCreds.insert(*it);
@@ -542,6 +553,8 @@ Session::authhost(const AuthHostType hostType, const bool restart)
 void DynamicSession::setUserPrefs(CFDataRef userPrefsDict)
 {
        checkOriginator();
 void DynamicSession::setUserPrefs(CFDataRef userPrefsDict)
 {
        checkOriginator();
+       if (Server::process().uid() != 0)
+               MacOSError::throwMe(errSessionAuthorizationDenied);
        StLock<Mutex> _(*this);
        mSessionAgentPrefs = userPrefsDict;
 }
        StLock<Mutex> _(*this);
        mSessionAgentPrefs = userPrefsDict;
 }
index 7799cc4dc028f4cf6a45e3ec113c35c5e4f751ab..257579460094600cb895f987e70a7d84d72ee93f 100644 (file)
@@ -77,10 +77,16 @@ public:
     bool attribute(SessionAttributeBits bits) const    { return mAttributes & bits; }
        
     virtual void setupAttributes(SessionCreationFlags flags, SessionAttributeBits attrs);
     bool attribute(SessionAttributeBits bits) const    { return mAttributes & bits; }
        
     virtual void setupAttributes(SessionCreationFlags flags, SessionAttributeBits attrs);
+
        virtual bool haveOriginatorUid() const = 0;
        virtual uid_t originatorUid() const = 0;
        virtual bool haveOriginatorUid() const = 0;
        virtual uid_t originatorUid() const = 0;
+    Credential originatorCredential() const { return mOriginatorCredential; }
+
        virtual CFDataRef copyUserPrefs() = 0;
 
        virtual CFDataRef copyUserPrefs() = 0;
 
+       static std::string kUsername;
+    static std::string kRealname;
+    
 protected:
     void setAttributes(SessionAttributeBits attrs)     { mAttributes |= attrs; }
     
 protected:
     void setAttributes(SessionAttributeBits attrs)     { mAttributes |= attrs; }
     
@@ -90,7 +96,7 @@ public:
        OSStatus authCreate(const AuthItemSet &rights, const AuthItemSet &environment,
                AuthorizationFlags flags, AuthorizationBlob &newHandle, const audit_token_t &auditToken);
        void authFree(const AuthorizationBlob &auth, AuthorizationFlags flags);
        OSStatus authCreate(const AuthItemSet &rights, const AuthItemSet &environment,
                AuthorizationFlags flags, AuthorizationBlob &newHandle, const audit_token_t &auditToken);
        void authFree(const AuthorizationBlob &auth, AuthorizationFlags flags);
-       OSStatus authGetRights(const AuthorizationBlob &auth,
+       static OSStatus authGetRights(const AuthorizationBlob &auth,
                const AuthItemSet &requestedRights, const AuthItemSet &environment,
                AuthorizationFlags flags, AuthItemSet &grantedRights);
        OSStatus authGetInfo(const AuthorizationBlob &auth, const char *tag, AuthItemSet &contextInfo);
                const AuthItemSet &requestedRights, const AuthItemSet &environment,
                AuthorizationFlags flags, AuthItemSet &grantedRights);
        OSStatus authGetInfo(const AuthorizationBlob &auth, const char *tag, AuthItemSet &contextInfo);
@@ -109,7 +115,10 @@ private:
     };
        
 protected:
     };
        
 protected:
-    AuthorizationToken &authorization(const AuthorizationBlob &blob);
+    static AuthorizationToken &authorization(const AuthorizationBlob &blob);
+       OSStatus authGetRights(AuthorizationToken &auth,
+               const AuthItemSet &requestedRights, const AuthItemSet &environment,
+               AuthorizationFlags flags, AuthItemSet &grantedRights);
        void mergeCredentials(CredentialSet &creds);
 
 public:
        void mergeCredentials(CredentialSet &creds);
 
 public:
@@ -134,8 +143,9 @@ protected:
        mutable Mutex mAuthHostLock;
        AuthHostInstance *mSecurityAgent;
        AuthHostInstance *mAuthHost;
        mutable Mutex mAuthHostLock;
        AuthHostInstance *mSecurityAgent;
        AuthHostInstance *mAuthHost;
-
+    
        CFRef<CFDataRef> mSessionAgentPrefs;
        CFRef<CFDataRef> mSessionAgentPrefs;
+    Credential mOriginatorCredential;
        
        void kill();
        
        
        void kill();
        
@@ -165,8 +175,8 @@ public:
     RootSession(Server &server, SessionAttributeBits attrs = 0);
        
        bool haveOriginatorUid() const          { return true; }
     RootSession(Server &server, SessionAttributeBits attrs = 0);
        
        bool haveOriginatorUid() const          { return true; }
-       uid_t originatorUid() const;
-       CFDataRef copyUserPrefs();
+       uid_t originatorUid() const         { return 0; }
+       CFDataRef copyUserPrefs()           { return NULL; }
 };
 
 
 };
 
 
index 2f3381bff2ebd732935c211683a369c765f7ee11..9b3de21094b5041b37cec0fa09c48e3848382ec3 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2004,2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -67,7 +67,7 @@ Token::Token()
 
 Token::~Token()
 {
 
 Token::~Token()
 {
-       secdebug("token", "%p (%s:%ld) destroyed",
+       secdebug("token", "%p (%s:%d) destroyed",
                this, mGuid.toString().c_str(), mSubservice);
 }
 
                this, mGuid.toString().c_str(), mSubservice);
 }
 
@@ -128,6 +128,27 @@ RefPointer<Token> Token::find(uint32 ssid)
 }
 
 
 }
 
 
+//
+// We override getAcl to provide PIN state feedback
+//
+void Token::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
+{
+       if (pinFromAclTag(tag, "?")) {  // read from tokend - do not cache
+               AclEntryInfo *racls;
+               token().tokend().getAcl(aclKind(), tokenHandle(), tag, count, racls);
+               // make a chunk-copy because that's the contract we have with the caller
+               acls = Allocator::standard().alloc<AclEntryInfo>(count * sizeof(AclEntryInfo));
+               memcpy(acls, racls, count * sizeof(AclEntryInfo));
+               ChunkCopyWalker copy;
+               for (uint32 n = 0; n < count; n++)
+                       walk(copy, acls[n]);
+               return;
+       }
+
+       TokenAcl::cssmGetAcl(tag, count, acls);
+}
+
+
 //
 // Reset management.
 // A Token has a "reset level", a number that is incremented whenever a token
 //
 // Reset management.
 // A Token has a "reset level", a number that is incremented whenever a token
@@ -154,8 +175,8 @@ void Token::resetAcls()
                // Make a copy to avoid deadlock with TokenDbCommon lock
                tmpCommons = mCommons;
        }
                // Make a copy to avoid deadlock with TokenDbCommon lock
                tmpCommons = mCommons;
        }
-       for (CommonSet::const_iterator it = tmpCommons.begin(); it != tmpCommons.end(); it++)
-               RefPointer<TokenDbCommon>(*it)->resetAcls();
+       for (CommonSet::const_iterator it = tmpCommons.begin(); it != tmpCommons.end();)
+               RefPointer<TokenDbCommon>(*it++)->resetAcls();
 }
 
 void Token::addCommon(TokenDbCommon &dbc)
 }
 
 void Token::addCommon(TokenDbCommon &dbc)
@@ -205,12 +226,12 @@ void Token::insert(::Reader &slot)
 
                // locate or establish cache directories
                if (tokend->hasTokenUid()) {
 
                // locate or establish cache directories
                if (tokend->hasTokenUid()) {
-                       secdebug("token", "%p CHOOSING %s (score=%ld, uid=\"%s\")",
+                       secdebug("token", "%p CHOOSING %s (score=%d, uid=\"%s\")",
                                this, tokend->bundlePath().c_str(), tokend->score(), tokend->tokenUid().c_str());
                        mCache = new TokenCache::Token(reader().cache,
                                tokend->bundleIdentifier() + ":" + tokend->tokenUid());
                } else {
                                this, tokend->bundlePath().c_str(), tokend->score(), tokend->tokenUid().c_str());
                        mCache = new TokenCache::Token(reader().cache,
                                tokend->bundleIdentifier() + ":" + tokend->tokenUid());
                } else {
-                       secdebug("token", "%p CHOOSING %s (score=%ld, temporary)",
+                       secdebug("token", "%p CHOOSING %s (score=%d, temporary)",
                                this, tokend->bundlePath().c_str(), tokend->score());
                        mCache = new TokenCache::Token(reader().cache);
                }
                                this, tokend->bundlePath().c_str(), tokend->score());
                        mCache = new TokenCache::Token(reader().cache);
                }
@@ -237,7 +258,7 @@ void Token::insert(::Reader &slot)
                        mPrintName = printName;
                if (mPrintName.empty()) {
                        // last resort - new card and tokend didn't give us one
                        mPrintName = printName;
                if (mPrintName.empty()) {
                        // last resort - new card and tokend didn't give us one
-                       snprintf(printName, sizeof(printName), "smart card #%ld", mSubservice);
+                       snprintf(printName, sizeof(printName), "smart card #%d", mSubservice);
                        mPrintName = printName;
                }
                if (mCache->type() != TokenCache::Token::existing)
                        mPrintName = printName;
                }
                if (mCache->type() != TokenCache::Token::existing)
@@ -276,7 +297,7 @@ void Token::insert(::Reader &slot)
                        slot.name().c_str(), mPrintName.c_str(),
                        mTokend->hasTokenUid() ? mTokend->tokenUid().c_str() : "NO UID",
                        mSubservice, mTokend->bundleIdentifier().c_str());
                        slot.name().c_str(), mPrintName.c_str(),
                        mTokend->hasTokenUid() ? mTokend->tokenUid().c_str() : "NO UID",
                        mSubservice, mTokend->bundleIdentifier().c_str());
-               secdebug("token", "%p inserted as %s:%ld", this, mGuid.toString().c_str(), mSubservice);
+               secdebug("token", "%p inserted as %s:%d", this, mGuid.toString().c_str(), mSubservice);
        } catch (const CommonError &err) {
                Syslog::notice("token in reader %s cannot be used (error %ld)", slot.name().c_str(), err.osStatus());
                secdebug("token", "exception during insertion processing");
        } catch (const CommonError &err) {
                Syslog::notice("token in reader %s cannot be used (error %ld)", slot.name().c_str(), err.osStatus());
                secdebug("token", "exception during insertion processing");
@@ -345,7 +366,7 @@ void Token::fault(bool async)
                notify(kNotificationCDSAFailure);
                
                // cast off our TokenDaemon for good
                notify(kNotificationCDSAFailure);
                
                // cast off our TokenDaemon for good
-               mTokend = NULL;
+//>>>          mTokend = NULL;
        }
        
        // if this is a synchronous fault, abort this operation now
        }
        
        // if this is a synchronous fault, abort this operation now
@@ -420,12 +441,12 @@ void Token::notify(NotificationEvent event)
 RefPointer<TokenDaemon> Token::chooseTokend()
 {
        //@@@ CodeRepository should learn to update from disk changes to be re-usable
 RefPointer<TokenDaemon> Token::chooseTokend()
 {
        //@@@ CodeRepository should learn to update from disk changes to be re-usable
-       CodeRepository<GenericBundle> candidates("Security/tokend", ".tokend", "TOKENDAEMONPATH", false);
+       CodeRepository<Bundle> candidates("Security/tokend", ".tokend", "TOKENDAEMONPATH", false);
        candidates.update();
        //@@@ we could sort by reverse "maxScore" and avoid launching those who won't cut it anyway...
        
        RefPointer<TokenDaemon> leader;
        candidates.update();
        //@@@ we could sort by reverse "maxScore" and avoid launching those who won't cut it anyway...
        
        RefPointer<TokenDaemon> leader;
-       for (CodeRepository<GenericBundle>::const_iterator it = candidates.begin();
+       for (CodeRepository<Bundle>::const_iterator it = candidates.begin();
                        it != candidates.end(); it++) {
                try {
                        // any pre-launch screening of candidate *it goes here
                        it != candidates.end(); it++) {
                try {
                        // any pre-launch screening of candidate *it goes here
@@ -473,7 +494,7 @@ Token::Access::~Access()
 void Token::dumpNode()
 {
        PerGlobal::dumpNode();
 void Token::dumpNode()
 {
        PerGlobal::dumpNode();
-       Debug::dump(" %s[%ld] tokend=%p",
+       Debug::dump(" %s[%d] tokend=%p",
                mGuid.toString().c_str(), mSubservice, mTokend.get());
 }
 
                mGuid.toString().c_str(), mSubservice, mTokend.get());
 }
 
index 06a118d79ffa856de3b0988cb58e520154de964e..3acd721624272fed20d33e920f856e621d1c77c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2004,2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -71,6 +71,7 @@ public:
        
        static RefPointer<Token> find(uint32 ssid);
        
        
        static RefPointer<Token> find(uint32 ssid);
        
+       void getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls);
        ResetGeneration resetGeneration() const;
        bool resetGeneration(ResetGeneration rg) const { return rg == resetGeneration(); }
        void resetAcls();
        ResetGeneration resetGeneration() const;
        bool resetGeneration(ResetGeneration rg) const { return rg == resetGeneration(); }
        void resetAcls();
index e6a1d00a64bc2b5fa19e553fcdec2ca2bf519653..0fe9955afd9f43aa02131ec5fee7859e883adb27 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -110,8 +110,7 @@ void TokenAcl::changeAcl(const AclEdit &edit, const AccessCredentials *cred, Dat
        if (TokenDatabase *tokenDb = dynamic_cast<TokenDatabase *>(db))
                if (edit.mode() == CSSM_ACL_EDIT_MODE_REPLACE)
                        if (const AclEntryInput *input = edit.newEntry()) {
        if (TokenDatabase *tokenDb = dynamic_cast<TokenDatabase *>(db))
                if (edit.mode() == CSSM_ACL_EDIT_MODE_REPLACE)
                        if (const AclEntryInput *input = edit.newEntry()) {
-                               unsigned int pin;
-                               if (sscanf(input->proto().s_tag().c_str(), "PIN%d", &pin) == 1) {
+                               if (unsigned pin = pinFromAclTag(input->proto().tag())) {
                                        // assume this is a PIN change request
                                        pinChange(pin, edit.handle(), *tokenDb);
                                        invalidateAcl();
                                        // assume this is a PIN change request
                                        pinChange(pin, edit.handle(), *tokenDb);
                                        invalidateAcl();
@@ -160,7 +159,7 @@ SecurityAgent::Reason QueryNewPin::accept(CssmManagedData &passphrase, CssmData
                        new(alloc) ListElement(passphrase)
                        ));
                proto.authorization() = AuthorizationGroup(CSSM_ACL_AUTHORIZATION_PREAUTH(pin), alloc);
                        new(alloc) ListElement(passphrase)
                        ));
                proto.authorization() = AuthorizationGroup(CSSM_ACL_AUTHORIZATION_PREAUTH(pin), alloc);
-               char pintag[10]; sprintf(pintag, "PIN%d", pin);
+               char pintag[20]; sprintf(pintag, "PIN%d", pin);
                proto.tag(pintag);
                AclEntryInput input(proto);
                AclEdit edit(CSSM_ACL_EDIT_MODE_REPLACE, handle, &input);
                proto.tag(pintag);
                AclEntryInput input(proto);
                AclEdit edit(CSSM_ACL_EDIT_MODE_REPLACE, handle, &input);
index c8433404c09c46cff0e0f4c0c1bf8d82f833ba40..2460db14709665561aa6ff2165d5a0933f17a65c 100644 (file)
@@ -68,7 +68,7 @@ static const char cacheDir[] = "cache";
 static uint32 getFile(const string &path, uint32 defaultValue)
 {
        try {
 static uint32 getFile(const string &path, uint32 defaultValue)
 {
        try {
-               FileDesc fd(path);
+               AutoFileDesc fd(path);
                string s; fd.readAll(s);
                uint32 value; sscanf(s.c_str(), "%ld", &value);
                return value;
                string s; fd.readAll(s);
                uint32 value; sscanf(s.c_str(), "%ld", &value);
                return value;
@@ -80,7 +80,7 @@ static uint32 getFile(const string &path, uint32 defaultValue)
 static string getFile(const string &path, const string &defaultValue)
 {
        try {
 static string getFile(const string &path, const string &defaultValue)
 {
        try {
-               FileDesc fd(path);
+               AutoFileDesc fd(path);
                string s; fd.readAll(s);
                return s;
        } catch (...) {
                string s; fd.readAll(s);
                return s;
        } catch (...) {
@@ -93,12 +93,12 @@ static void putFile(const string &path, uint32 value)
 {
        char buffer[64];
        snprintf(buffer, sizeof(buffer), "%ld\n", value);
 {
        char buffer[64];
        snprintf(buffer, sizeof(buffer), "%ld\n", value);
-       FileDesc(path, O_WRONLY | O_CREAT | O_TRUNC).writeAll(buffer);
+       AutoFileDesc(path, O_WRONLY | O_CREAT | O_TRUNC).writeAll(buffer);
 }
 
 static void putFile(const string &path, const string &value)
 {
 }
 
 static void putFile(const string &path, const string &value)
 {
-       FileDesc(path, O_WRONLY | O_CREAT | O_TRUNC).writeAll(value);
+       AutoFileDesc(path, O_WRONLY | O_CREAT | O_TRUNC).writeAll(value);
 }
 
 
 }
 
 
index 350752fa20907b0e9f31675f336a80f24ac79ae5..2b14dc7a894e0a65077d9c8d7f72dbe62dec016a 100644 (file)
@@ -37,7 +37,7 @@
 // it has died (or been unable to start at all). It's then our owner's responsibility
 // to manage us from there, including deleting us eventually.
 //
 // it has died (or been unable to start at all). It's then our owner's responsibility
 // to manage us from there, including deleting us eventually.
 //
-TokenDaemon::TokenDaemon(RefPointer<GenericBundle> code,
+TokenDaemon::TokenDaemon(RefPointer<Bundle> code,
                const string &reader, const PCSC::ReaderState &readerState, TokenCache &cache)
        : Tokend::ClientSession(Allocator::standard(), Allocator::standard()),
          mMe(code), mReaderName(reader), mState(readerState),
                const string &reader, const PCSC::ReaderState &readerState, TokenCache &cache)
        : Tokend::ClientSession(Allocator::standard(), Allocator::standard()),
          mMe(code), mReaderName(reader), mState(readerState),
@@ -171,7 +171,7 @@ bool TokenDaemon::probe()
 {
        secdebug("tokend", "%p probing", this);
        ClientSession::probe(mScore, mTokenUid);
 {
        secdebug("tokend", "%p probing", this);
        ClientSession::probe(mScore, mTokenUid);
-       secdebug("tokend", "%p probed score=%ld tokenUid=\"%s\"", this, mScore, mTokenUid.c_str());
+       secdebug("tokend", "%p probed score=%d tokenUid=\"%s\"", this, mScore, mTokenUid.c_str());
        mProbed = true;
        return mScore > 0;
 }
        mProbed = true;
        return mScore > 0;
 }
index e4b808a5904338337025605cc7b1604428c64fcc..63d9750142e5c3eb08c2deebf9f1b7689aef0682 100644 (file)
@@ -62,12 +62,12 @@ public:
 // it right there and then. That's good enough for hard error recovery, though you may
 // try to let it down easier to allow it to save its caches and wind down. Caller's choice.
 //
 // it right there and then. That's good enough for hard error recovery, though you may
 // try to let it down easier to allow it to save its caches and wind down. Caller's choice.
 //
-// NB: If you ever want to make TokenDaemon BE a GenericBundle, you must switch NodeCore
+// NB: If you ever want to make TokenDaemon BE a Bundle, you must switch NodeCore
 // AND OSXCode to virtually derive RefCount.
 //
 class TokenDaemon : public PerGlobal, public ServerChild, public Tokend::ClientSession {
 public:
 // AND OSXCode to virtually derive RefCount.
 //
 class TokenDaemon : public PerGlobal, public ServerChild, public Tokend::ClientSession {
 public:
-       TokenDaemon(RefPointer<GenericBundle> code,
+       TokenDaemon(RefPointer<Bundle> code,
                const std::string &reader, const PCSC::ReaderState &state, TokenCache &cache);
        virtual ~TokenDaemon();
        
                const std::string &reader, const PCSC::ReaderState &state, TokenCache &cache);
        virtual ~TokenDaemon();
        
@@ -100,7 +100,7 @@ protected:
        void fault();                           // relay from Tokend::ClientSession
 
 private:
        void fault();                           // relay from Tokend::ClientSession
 
 private:
-       RefPointer<GenericBundle> mMe; // code object for the tokend (it's an Application)
+       RefPointer<Bundle> mMe; // code object for the tokend (it's an Application)
        std::string mReaderName;        // PCSC name of reader we're working with
        PCSC::ReaderState mState;       // card state at time of creation (not updated after that)
 
        std::string mReaderName;        // PCSC name of reader we're working with
        PCSC::ReaderState mState;       // card state at time of creation (not updated after that)
 
index 2251d7e0d979946434db0943830cc0046cf0965f..2525623df82c4df79f440474cfd716d973202a72 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -38,7 +38,7 @@
 // Construct a TokenDbCommon
 //
 TokenDbCommon::TokenDbCommon(Session &ssn, Token &tk, const char *name)
 // Construct a TokenDbCommon
 //
 TokenDbCommon::TokenDbCommon(Session &ssn, Token &tk, const char *name)
-       : DbCommon(ssn), mDbName(name ? name : ""), mResetLevel(0)
+       : DbCommon(ssn), mDbName(name ? name : ""), mHasAclState(false), mResetLevel(0)
 {
        secdebug("tokendb", "creating tokendbcommon %p: with token %p", this, &tk);
        parent(tk);
 {
        secdebug("tokendb", "creating tokendbcommon %p: with token %p", this, &tk);
        parent(tk);
@@ -55,7 +55,7 @@ Token &TokenDbCommon::token() const
        return parent<Token>();
 }
 
        return parent<Token>();
 }
 
-const std::string &TokenDbCommon::dbName() const
+std::string TokenDbCommon::dbName() const
 {
        return token().printName();
 }
 {
        return token().printName();
 }
@@ -69,25 +69,29 @@ Adornable &TokenDbCommon::store()
        StLock<Mutex> _(*this);
        
        // if this is the first one, hook for lifetime
        StLock<Mutex> _(*this);
        
        // if this is the first one, hook for lifetime
-       if (mAdornments.empty()) {
+       if (!mHasAclState) {
                session().addReference(*this);          // hold and slave to SSN lifetime
                token().addCommon(*this);                       // register with Token
                session().addReference(*this);          // hold and slave to SSN lifetime
                token().addCommon(*this);                       // register with Token
+               mHasAclState = true;
        }
 
        // return our (now active) adornments
        }
 
        // return our (now active) adornments
-       return mAdornments;
+       return *this;
 }
 
 void TokenDbCommon::resetAcls()
 {
        StLock<Mutex> _(*this);
 }
 
 void TokenDbCommon::resetAcls()
 {
        StLock<Mutex> _(*this);
-       if (!mAdornments.empty()) {
-               mAdornments.clearAdornments();          // clear ACL state
+       if (mHasAclState) {
+               clearAdornments();                                      // clear ACL state
                session().removeReference(*this);       // unhook from SSN
                session().removeReference(*this);       // unhook from SSN
+               mHasAclState = false;
        }
        token().removeCommon(*this);                    // unregister from Token
 }
 
        }
        token().removeCommon(*this);                    // unregister from Token
 }
 
+
+//
 // Send out a "keychain" notification for this database
 //
 void TokenDbCommon::notify(NotificationEvent event)
 // Send out a "keychain" notification for this database
 //
 void TokenDbCommon::notify(NotificationEvent event)
@@ -124,12 +128,12 @@ TokenDatabase::TokenDatabase(uint32 ssid, Process &proc,
        StLock<Mutex> _(session);
        if (TokenDbCommon *dbcom = session.findFirst<TokenDbCommon, uint32>(&TokenDbCommon::subservice, ssid)) {
                parent(*dbcom);
        StLock<Mutex> _(session);
        if (TokenDbCommon *dbcom = session.findFirst<TokenDbCommon, uint32>(&TokenDbCommon::subservice, ssid)) {
                parent(*dbcom);
-               secdebug("tokendb", "open tokendb %p(%ld) at known common %p",
+               secdebug("tokendb", "open tokendb %p(%d) at known common %p",
                        this, subservice(), dbcom);
        } else {
                // DbCommon not present; make a new one
                parent(*new TokenDbCommon(proc.session(), *token, name));
                        this, subservice(), dbcom);
        } else {
                // DbCommon not present; make a new one
                parent(*new TokenDbCommon(proc.session(), *token, name));
-               secdebug("tokendb", "open tokendb %p(%ld) with new common %p",
+               secdebug("tokendb", "open tokendb %p(%d) with new common %p",
                        this, subservice(), &common());
        }
        mOpenCreds = copy(cred, Allocator::standard());
                        this, subservice(), &common());
        }
        mOpenCreds = copy(cred, Allocator::standard());
@@ -167,15 +171,103 @@ bool TokenDatabase::transient() const
 }
 
 
 }
 
 
+//
+// Our ObjectAcl resides in the Token object.
+//
 SecurityServerAcl &TokenDatabase::acl()
 {
        return token();
 }
 
 SecurityServerAcl &TokenDatabase::acl()
 {
        return token();
 }
 
-bool TokenDatabase::isLocked() const
+
+//
+// We post-process the status version of getAcl to account for virtual (per-session)
+// PIN lock status.
+//
+void TokenDatabase::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
+{
+       AclSource::getAcl(tag, count, acls);
+       
+       for (unsigned n = 0; n < count; n++) {
+               AclEntryPrototype &proto = acls[n];
+               if (unsigned pin = pinFromAclTag(proto.tag(), "?")) {   // pin state response
+                       secdebug("tokendb", "%p updating PIN%d state response", this, pin);
+                       TypedList &subject = proto.subject();
+                       // subject == { CSSM_WORID_PIN, pin-number, status [, count ] } # all numbers
+                       if (subject.length() > 2
+                               && subject[0].is(CSSM_LIST_ELEMENT_WORDID)
+                               && subject[0] == CSSM_WORDID_PIN
+                               && subject[1].is(CSSM_LIST_ELEMENT_WORDID)
+                               && subject[2].is(CSSM_LIST_ELEMENT_WORDID)) {
+                               uint32 pin = subject[1];
+                               if (!common().attachment<PreAuthorizationAcls::AclState>((void *)pin).accepted) {
+                                       // we are not pre-authorized in this session
+                                       secdebug("tokendb", "%p session state forces PIN%d reporting unauthorized", this, pin);
+                                       uint32 status = subject[2];
+                                       status &= ~CSSM_ACL_PREAUTH_TRACKING_AUTHORIZED;        // clear authorized bit
+                                       subject[2] = status;
+#if !defined(NDEBUG)
+                               if (subject.length() > 3 && subject[3].is(CSSM_LIST_ELEMENT_WORDID))
+                                       secdebug("tokendb", "%p PIN%d count=%d", this, pin, subject[3].word());
+#endif //NDEBUG
+                               }
+                       }
+               }
+       }
+}
+
+
+bool TokenDatabase::isLocked()
 {
        Access access(token());
 {
        Access access(token());
-       return access().isLocked();
+       
+       bool lockState = pinState(1);
+//     bool lockState = access().isLocked();
+       
+       secdebug("tokendb", "returning isLocked=%d", lockState);
+       return lockState;
+}
+
+bool TokenDatabase::pinState(uint32 pin, int *pinCount /* = NULL */)
+{
+       uint32 count;
+       AclEntryInfo *acls;
+       this->getAcl("PIN1?", count, acls);
+       bool locked = true;     // preset locked
+       if (pinCount)
+               *pinCount = -1;         // preset unknown
+       switch (count) {
+       case 0:
+               secdebug("tokendb", "PIN%d query returned no entries", pin);
+               break;
+       default:
+               secdebug("tokendb", "PIN%d query returned multiple entries", pin);
+               break;
+       case 1:
+               {
+                       TypedList &subject = acls[0].proto().subject();
+                       if (subject.length() > 2
+                               && subject[0].is(CSSM_LIST_ELEMENT_WORDID)
+                               && subject[0] == CSSM_WORDID_PIN
+                               && subject[1].is(CSSM_LIST_ELEMENT_WORDID)
+                               && subject[2].is(CSSM_LIST_ELEMENT_WORDID)) {
+                               uint32 status = subject[2];
+                               locked = !(status & CSSM_ACL_PREAUTH_TRACKING_AUTHORIZED);
+                               if (pinCount && locked && subject.length() > 3 && subject[3].is(CSSM_LIST_ELEMENT_WORDID))
+                                       *pinCount = subject[3];
+                       }
+               }
+               break;
+       }
+       
+       // release memory allocated by getAcl
+       ChunkFreeWalker free;
+       for (uint32 n = 0; n < count; n++)
+                       walk(free, acls[n]);
+       Allocator::standard().free(acls);
+
+       // return status
+       return locked;
 }
 
 
 }
 
 
@@ -197,13 +289,13 @@ void TokenDatabase::dbName(const char *name)
 // local transient store.
 //
 RefPointer<Key> TokenDatabase::makeKey(KeyHandle hKey, const CssmKey *key,
 // local transient store.
 //
 RefPointer<Key> TokenDatabase::makeKey(KeyHandle hKey, const CssmKey *key,
-       const AclEntryPrototype *owner)
+       uint32 moreAttributes, const AclEntryPrototype *owner)
 {
        switch (key->blobType()) {
        case CSSM_KEYBLOB_REFERENCE:
                return new TokenKey(*this, hKey, key->header());
        case CSSM_KEYBLOB_RAW:
 {
        switch (key->blobType()) {
        case CSSM_KEYBLOB_REFERENCE:
                return new TokenKey(*this, hKey, key->header());
        case CSSM_KEYBLOB_RAW:
-               return process().makeTemporaryKey(*key, 0, owner);
+               return process().makeTemporaryKey(*key, moreAttributes, owner);
        default:
                CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);        // bad key return from tokend
        }
        default:
                CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);        // bad key return from tokend
        }
@@ -359,7 +451,7 @@ void TokenDatabase::generateKey(const Context &context,
        KeyHandle hKey;
        CssmKey *result;
        access().generateKey(context, cred, owner, usage, modattrs(attrs), hKey, result);
        KeyHandle hKey;
        CssmKey *result;
        access().generateKey(context, cred, owner, usage, modattrs(attrs), hKey, result);
-       newKey = makeKey(hKey, result, owner);
+       newKey = makeKey(hKey, result, 0, owner);
        DONE
 }
 
        DONE
 }
 
@@ -377,8 +469,8 @@ void TokenDatabase::generateKey(const Context &context,
        access().generateKey(context, cred, owner,
                pubUsage, modattrs(pubAttrs), privUsage, modattrs(privAttrs),
                hPublic, pubKey, hPrivate, privKey);
        access().generateKey(context, cred, owner,
                pubUsage, modattrs(pubAttrs), privUsage, modattrs(privAttrs),
                hPublic, pubKey, hPrivate, privKey);
-       publicKey = makeKey(hPublic, pubKey, owner);
-       privateKey = makeKey(hPrivate, privKey, owner);
+       publicKey = makeKey(hPublic, pubKey, 0, owner);
+       privateKey = makeKey(hPrivate, privKey, 0, owner);
        DONE
 }
 
        DONE
 }
 
@@ -429,7 +521,7 @@ void TokenDatabase::unwrapKey(const Context &context,
        access().unwrapKey(context, cred, owner,
                cWrappingKey, cWrappingKey, cPublicKey, cPublicKey,
                wrappedKey, usage, modattrs(attrs), descriptiveData, hKey, result);
        access().unwrapKey(context, cred, owner,
                cWrappingKey, cWrappingKey, cPublicKey, cPublicKey,
                wrappedKey, usage, modattrs(attrs), descriptiveData, hKey, result);
-       unwrappedKey = makeKey(hKey, result, owner);
+       unwrappedKey = makeKey(hKey, result, modattrs(attrs) & LocalKey::managedAttributes, owner);
        DONE
 }
 
        DONE
 }
 
@@ -458,7 +550,7 @@ void TokenDatabase::deriveKey(const Context &context, Key *sourceKey,
                *param = params;
                //@@@ leak? what's the rule here?
        }
                *param = params;
                //@@@ leak? what's the rule here?
        }
-       derivedKey = makeKey(hKey, result, owner);
+       derivedKey = makeKey(hKey, result, 0, owner);
        DONE
 }
 
        DONE
 }
 
@@ -488,9 +580,7 @@ void TokenDatabase::authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentia
        GUARD
        if (mode != CSSM_DB_ACCESS_RESET && cred) {
                secdebug("tokendb", "%p authenticate calling validate", this);
        GUARD
        if (mode != CSSM_DB_ACCESS_RESET && cred) {
                secdebug("tokendb", "%p authenticate calling validate", this);
-               int pin;
-               if (sscanf(cred->EntryTag, "PIN%d", &pin) == 1)
-               {
+               if (unsigned pin = pinFromAclTag(cred->EntryTag)) {
                        validate(CSSM_ACL_AUTHORIZATION_PREAUTH(pin), cred);
                        notify(kNotificationEventUnlocked);
                        return;
                        validate(CSSM_ACL_AUTHORIZATION_PREAUTH(pin), cred);
                        notify(kNotificationEventUnlocked);
                        return;
@@ -505,15 +595,15 @@ void TokenDatabase::authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentia
                notify(kNotificationEventLocked);
                break;
        default:
                notify(kNotificationEventLocked);
                break;
        default:
-       {
-               // no idea what that did to the token; 
-               // But let's remember the new creds for our own sake.
-               AccessCredentials *newCred = copy(cred, Allocator::standard());
-               Allocator::standard().free(mOpenCreds);
-               mOpenCreds = newCred;
+               {
+                       // no idea what that did to the token; 
+                       // But let's remember the new creds for our own sake.
+                       AccessCredentials *newCred = copy(cred, Allocator::standard());
+                       Allocator::standard().free(mOpenCreds);
+                       mOpenCreds = newCred;
+               }
                break;
        }
                break;
        }
-       }
        DONE
 }
 
        DONE
 }
 
index 437158dc86a19441495dcddfa2bce6777b9a2812..cf390629c61e162b4120f4e49e023d0103adafe3 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -60,20 +60,20 @@ public:
        Token &token() const;
        
        uint32 subservice() const { return token().subservice(); }
        Token &token() const;
        
        uint32 subservice() const { return token().subservice(); }
-       const std::string &dbName() const;
-
+       std::string dbName() const;
+       
        Adornable &store();
        void resetAcls();
        Adornable &store();
        void resetAcls();
-       
-       void notify(NotificationEvent event);
 
 
+       void notify(NotificationEvent event);
+       
        void lockProcessing();
 
        typedef Token::ResetGeneration ResetGeneration;
 
 private:
        std::string mDbName;                    // name given during open
        void lockProcessing();
 
        typedef Token::ResetGeneration ResetGeneration;
 
 private:
        std::string mDbName;                    // name given during open
-       Adornable mAdornments;                  // Adornable for ACL store
+       bool mHasAclState;                              // Adornment is carrying active ACL state
 
        ResetGeneration mResetLevel;    // validity tag
 };
 
        ResetGeneration mResetLevel;    // validity tag
 };
@@ -97,10 +97,12 @@ public:
        bool transient() const;
        
        SecurityServerAcl &acl();               // it's our Token
        bool transient() const;
        
        SecurityServerAcl &acl();               // it's our Token
+       void getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls);       // post-processing
 
 
-       bool isLocked() const;
+       bool isLocked();
+       bool pinState(uint32 pin, int *count = NULL);
 
 
-       void notify(NotificationEvent event) { return common().notify(event); }
+    void notify(NotificationEvent event) { return common().notify(event); }
 
        bool validateSecret(const AclSubject *subject, const AccessCredentials *cred);
        
 
        bool validateSecret(const AclSubject *subject, const AccessCredentials *cred);
        
@@ -215,7 +217,7 @@ public:
 private:
        // internal utilities
        RefPointer<Key> makeKey(KeyHandle hKey, const CssmKey *key,
 private:
        // internal utilities
        RefPointer<Key> makeKey(KeyHandle hKey, const CssmKey *key,
-               const AclEntryPrototype *owner);
+               uint32 moreAttributes, const AclEntryPrototype *owner);
        
        class InputKey {
        public:
        
        class InputKey {
        public:
index c83169ba5a7fd51e7034f62463e82472a2acc750..b18fa2b1eb1da51ca3a72474a3bf0644bca7fd6a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
 //
 // transition - securityd IPC-to-class-methods transition layer
 //
 //
 // transition - securityd IPC-to-class-methods transition layer
 //
+// This file contains all server-side MIG implementations for the main
+// securityd protocol ("ucsp"). It dispatches them into the vast object
+// conspiracy that is securityd, anchored in the Server object.
+//
+#include <securityd_client/ss_types.h>
 #include <securityd_client/ucsp.h>
 #include "server.h"
 #include "session.h"
 #include <securityd_client/ucsp.h>
 #include "server.h"
 #include "session.h"
 #include "kcdatabase.h"
 #include "tokendatabase.h"
 #include "kckey.h"
 #include "kcdatabase.h"
 #include "tokendatabase.h"
 #include "kckey.h"
-#include "transwalkers.h"
 #include "child.h"
 #include <mach/mach_error.h>
 #include "child.h"
 #include <mach/mach_error.h>
+#include <securityd_client/xdr_cssm.h>
+#include <securityd_client/xdr_auth.h>
+#include <securityd_client/xdr_dldb.h>
 
 #include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFPropertyList.h>
 
 
 #include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFPropertyList.h>
 
-
 //
 // Bracket Macros
 //
 //
 // Bracket Macros
 //
-#define UCSP_ARGS      mach_port_t servicePort, mach_port_t replyPort, audit_token_t auditToken, \
-                    CSSM_RETURN *rcode
-#define CONTEXT_ARGS Context context, Pointer contextBase, Context::Attr *attributes, mach_msg_type_number_t attrSize
+#define UCSP_ARGS      mach_port_t servicePort, mach_port_t replyPort, \
+       audit_token_t auditToken, CSSM_RETURN *rcode
 
 #define BEGIN_IPCN     *rcode = CSSM_OK; try {
 #define BEGIN_IPC      BEGIN_IPCN RefPointer<Connection> connRef(&Server::connection(replyPort)); \
 
 #define BEGIN_IPCN     *rcode = CSSM_OK; try {
 #define BEGIN_IPC      BEGIN_IPCN RefPointer<Connection> connRef(&Server::connection(replyPort)); \
-Connection &connection __attribute__((unused)) = *connRef;
-#define END_IPC(base)  END_IPCN(base) Server::requestComplete(); return KERN_SUCCESS;
+               Connection &connection __attribute__((unused)) = *connRef;
+#define END_IPC(base)  END_IPCN(base) Server::requestComplete(*rcode); return KERN_SUCCESS;
 #define END_IPCN(base)         } \
        catch (const CommonError &err) { *rcode = CssmError::cssmError(err, CSSM_ ## base ## _BASE_ERROR); } \
        catch (const std::bad_alloc &) { *rcode = CssmError::merge(CSSM_ERRCODE_MEMORY_ERROR, CSSM_ ## base ## _BASE_ERROR); } \
 #define END_IPCN(base)         } \
        catch (const CommonError &err) { *rcode = CssmError::cssmError(err, CSSM_ ## base ## _BASE_ERROR); } \
        catch (const std::bad_alloc &) { *rcode = CssmError::merge(CSSM_ERRCODE_MEMORY_ERROR, CSSM_ ## base ## _BASE_ERROR); } \
@@ -64,18 +69,144 @@ Connection &connection __attribute__((unused)) = *connRef;
 #define DATA_IN(base)  void *base, mach_msg_type_number_t base##Length
 #define DATA_OUT(base) void **base, mach_msg_type_number_t *base##Length
 #define DATA(base)             CssmData(base, base##Length)
 #define DATA_IN(base)  void *base, mach_msg_type_number_t base##Length
 #define DATA_OUT(base) void **base, mach_msg_type_number_t *base##Length
 #define DATA(base)             CssmData(base, base##Length)
-#define OPTDATA(base)  (base ? &CssmData(base, base##Length) : NULL)
 
 #define SSBLOB(Type, name) makeBlob<Type>(DATA(name))
 
 
 #define SSBLOB(Type, name) makeBlob<Type>(DATA(name))
 
-#define COPY_IN(type,name)     type *name, mach_msg_type_number_t name##Length, type *name##Base
-#define COPY_OUT(type,name)    \
-       type **name, mach_msg_type_number_t *name##Length, type **name##Base
-       
-
 using LowLevelMemoryUtilities::increment;
 using LowLevelMemoryUtilities::difference;
 
 using LowLevelMemoryUtilities::increment;
 using LowLevelMemoryUtilities::difference;
 
+class CopyOutAccessCredentials : public CopyOut {
+public:
+       CopyOutAccessCredentials(void *copy, size_t size) : CopyOut(copy, size + sizeof(CSSM_ACCESS_CREDENTIALS), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACCESS_CREDENTIALS_PTR)) { }
+       operator AccessCredentials *() { return static_cast<AccessCredentials *>(reinterpret_cast<CSSM_ACCESS_CREDENTIALS_PTR>(data())); }
+};
+
+
+class CopyOutEntryAcl : public CopyOut {
+public:
+       CopyOutEntryAcl(void *copy, size_t size) : CopyOut(copy, size + sizeof(CSSM_ACL_ENTRY_PROTOTYPE), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_PROTOTYPE_PTR)) { }
+       operator AclEntryPrototype *() { return static_cast<AclEntryPrototype *>(reinterpret_cast<CSSM_ACL_ENTRY_PROTOTYPE_PTR>(data())); }
+};
+
+class CopyOutOwnerAcl : public CopyOut {
+public:
+       CopyOutOwnerAcl(void *copy, size_t size) : CopyOut(copy, size + sizeof(CSSM_ACL_OWNER_PROTOTYPE), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_OWNER_PROTOTYPE_PTR)) { }
+       operator AclOwnerPrototype *() { return static_cast<AclOwnerPrototype *>(reinterpret_cast<CSSM_ACL_OWNER_PROTOTYPE_PTR>(data())); }
+};
+
+class CopyOutAclEntryInput : public CopyOut {
+public:
+       CopyOutAclEntryInput(void *copy, size_t size) : CopyOut(copy, size + sizeof(CSSM_ACL_ENTRY_INPUT), reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_INPUT_PTR)) { }
+       operator AclEntryInput *() { return static_cast<AclEntryInput *>(reinterpret_cast<CSSM_ACL_ENTRY_INPUT_PTR>(data())); }
+};
+
+
+class CopyOutDeriveData : public CopyOut {
+public:
+       CopyOutDeriveData(void *copy, size_t size) : CopyOut(copy, size + sizeof(CSSM_DERIVE_DATA), reinterpret_cast<xdrproc_t>(xdr_CSSM_DERIVE_DATA_PTR)) { }
+       CSSM_DERIVE_DATA * derive_data() { return reinterpret_cast<CSSM_DERIVE_DATA *>(data()); }
+       CSSM_DATA &cssm_data() { return derive_data()->baseData; }
+       CSSM_ALGORITHMS algorithm() { return derive_data()->algorithm; }
+};
+
+
+class CopyOutContext : public CopyOut {
+public:
+       CopyOutContext(void *copy, size_t size) : CopyOut(copy, size + sizeof(CSSM_CONTEXT), reinterpret_cast<xdrproc_t>(xdr_CSSM_CONTEXT_PTR)) { }
+       operator Context *() { return static_cast<Context *>(reinterpret_cast<CSSM_CONTEXT_PTR>(data())); }
+       Context &context() { return *static_cast<Context *>(reinterpret_cast<CSSM_CONTEXT_PTR>(data())); }
+};
+
+class CopyOutKey : public CopyOut {
+public:
+       CopyOutKey(void *copy, size_t size) : CopyOut(copy, size + sizeof(CSSM_KEY), reinterpret_cast<xdrproc_t>(xdr_CSSM_KEY_PTR)) { }
+       operator CssmKey *() { return static_cast<CssmKey *>(reinterpret_cast<CSSM_KEY_PTR>(data())); }
+       CssmKey &key() { return *static_cast<CssmKey *>(reinterpret_cast<CSSM_KEY_PTR>(data())); }
+};
+
+class CopyOutDbRecordAttributes : public CopyOut {
+public:
+       CopyOutDbRecordAttributes(void *copy, size_t size) : CopyOut(copy, size + sizeof(CSSM_DB_RECORD_ATTRIBUTE_DATA), reinterpret_cast<xdrproc_t>(xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR)) { }
+       CssmDbRecordAttributeData *attribute_data() { return static_cast<CssmDbRecordAttributeData *>(reinterpret_cast<CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR>(data())); }
+};
+
+class CopyOutQuery : public CopyOut {
+public:
+       CopyOutQuery(void *copy, size_t size) : CopyOut(copy, size, reinterpret_cast<xdrproc_t>(xdr_CSSM_QUERY_PTR)) { }
+       operator CssmQuery *() { return static_cast<CssmQuery *>(reinterpret_cast<CSSM_QUERY_PTR>(data())); }
+};
+
+//
+// Take a DATA type RPC argument purportedly representing a Blob of some kind,
+// turn it into a Blob, and fail properly if it's not kosher.
+//
+template <class BlobType>
+const BlobType *makeBlob(const CssmData &blobData, CSSM_RETURN error = CSSM_ERRCODE_INVALID_DATA)
+{
+       if (!blobData.data() || blobData.length() < sizeof(BlobType))
+               CssmError::throwMe(error);
+       const BlobType *blob = static_cast<const BlobType *>(blobData.data());
+       if (blob->totalLength != blobData.length())
+               CssmError::throwMe(error);
+       return blob;
+}
+
+//
+// An OutputData object will take memory allocated within securityd,
+// hand it to the MIG return-output parameters, and schedule it to be released
+// after the MIG reply has been sent. It will also get rid of it in case of
+// error.
+//
+class OutputData : public CssmData {
+public:
+       OutputData(void **outP, mach_msg_type_number_t *outLength)
+               : mData(*outP), mLength(*outLength) { }
+       ~OutputData()
+       { mData = data(); mLength = length(); Server::releaseWhenDone(mData); }
+    
+    void operator = (const CssmData &source)
+    { CssmData::operator = (source); }
+       
+private:
+       void * &mData;
+       mach_msg_type_number_t &mLength;
+};
+
+//
+// Choose a Database from a choice of two sources, giving preference
+// to persistent stores and to earlier sources.
+//
+Database *pickDb(Database *db1, Database *db2);
+
+static inline Database *dbOf(Key *key) { return key ? &key->database() : NULL; }
+
+inline Database *pickDb(Key *k1, Key *k2) { return pickDb(dbOf(k1), dbOf(k2)); }
+inline Database *pickDb(Database *db1, Key *k2) { return pickDb(db1, dbOf(k2)); }
+inline Database *pickDb(Key *k1, Database *db2) { return pickDb(dbOf(k1), db2); }
+
+//
+// Choose a Database from a choice of two sources, giving preference
+// to persistent stores and to earlier sources.
+//
+Database *pickDb(Database *db1, Database *db2)
+{
+       // persistent db1 always wins
+       if (db1 && !db1->transient())
+               return db1;
+       
+       // persistent db2 is next choice
+       if (db2 && !db2->transient())
+               return db2;
+       
+       // pick any existing transient database
+       if (db1)
+               return db1;
+       if (db2)
+               return db2;
+       
+       // none at all. use the canonical transient store
+       return Server::optionalDatabase(noDb);
+}
 
 //
 // Setup/Teardown functions.
 
 //
 // Setup/Teardown functions.
@@ -133,18 +264,18 @@ kern_return_t ucsp_server_teardown(UCSP_ARGS)
 //
 // Common database operations
 //
 //
 // Common database operations
 //
-kern_return_t ucsp_server_authenticateDb(UCSP_ARGS, DbHandle db,
-       CSSM_DB_ACCESS_TYPE accessType, COPY_IN(AccessCredentials, cred))
+kern_return_t ucsp_server_authenticateDb(UCSP_ARGS, IPCDbHandle db,
+       CSSM_DB_ACCESS_TYPE accessType, DATA_IN(cred))
 {
        BEGIN_IPC
     secdebug("dl", "authenticateDb");
 {
        BEGIN_IPC
     secdebug("dl", "authenticateDb");
-    relocate(cred, credBase, credLength);
+       CopyOutAccessCredentials creds(cred, credLength);
        // ignoring accessType
        // ignoring accessType
-    Server::database(db)->authenticate(accessType, cred);
+    Server::database(db)->authenticate(accessType, creds);
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_releaseDb(UCSP_ARGS, DbHandle db)
+kern_return_t ucsp_server_releaseDb(UCSP_ARGS, IPCDbHandle db)
 {
        BEGIN_IPC
        connection.process().kill(*Server::database(db));
 {
        BEGIN_IPC
        connection.process().kill(*Server::database(db));
@@ -152,7 +283,7 @@ kern_return_t ucsp_server_releaseDb(UCSP_ARGS, DbHandle db)
 }
 
 
 }
 
 
-kern_return_t ucsp_server_getDbName(UCSP_ARGS, DbHandle db, char name[PATH_MAX])
+kern_return_t ucsp_server_getDbName(UCSP_ARGS, IPCDbHandle db, char name[PATH_MAX])
 {
        BEGIN_IPC
        string result = Server::database(db)->dbName();
 {
        BEGIN_IPC
        string result = Server::database(db)->dbName();
@@ -161,7 +292,7 @@ kern_return_t ucsp_server_getDbName(UCSP_ARGS, DbHandle db, char name[PATH_MAX])
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_setDbName(UCSP_ARGS, DbHandle db, const char *name)
+kern_return_t ucsp_server_setDbName(UCSP_ARGS, IPCDbHandle db, const char *name)
 {
        BEGIN_IPC
        Server::database(db)->dbName(name);
 {
        BEGIN_IPC
        Server::database(db)->dbName(name);
@@ -173,31 +304,30 @@ kern_return_t ucsp_server_setDbName(UCSP_ARGS, DbHandle db, const char *name)
 // External database interface
 //
 kern_return_t ucsp_server_openToken(UCSP_ARGS, uint32 ssid, FilePath name,
 // External database interface
 //
 kern_return_t ucsp_server_openToken(UCSP_ARGS, uint32 ssid, FilePath name,
-       COPY_IN(AccessCredentials, accessCredentials), DbHandle *db)
+       DATA_IN(accessCredentials), IPCDbHandle *db)
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(accessCredentials, accessCredentialsBase, accessCredentialsLength);
-       *db = (new TokenDatabase(ssid, connection.process(), name, accessCredentials))->handle();
+       CopyOutAccessCredentials creds(accessCredentials, accessCredentialsLength);
+       *db = (new TokenDatabase(ssid, connection.process(), name, creds))->handle();
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-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)
+kern_return_t ucsp_server_findFirst(UCSP_ARGS, IPCDbHandle db,
+       DATA_IN(inQuery), DATA_IN(inAttributes), DATA_OUT(outAttributes),
+       boolean_t getData, DATA_OUT(data), 
+    IPCKeyHandle *hKey, IPCSearchHandle *hSearch, IPCRecordHandle *hRecord)
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate (query, queryBase, queryLength);
-       relocate (inAttributes, inAttributesBase, inAttributesLength);
+       CopyOutQuery query(inQuery, inQueryLength);
+       CopyOutDbRecordAttributes attrs(inAttributes, inAttributesLength);
 
        RefPointer<Database::Search> search;
        RefPointer<Database::Record> record;
        RefPointer<Key> key;
 
        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,
+       CssmData outData;
+       CssmDbRecordAttributeData *outAttrs = NULL; mach_msg_type_number_t outAttrsLength;
+       Server::database(db)->findFirst(*query, 
+        attrs.attribute_data(), attrs.length(),
                getData ? &outData : NULL, key, search, record, outAttrs, outAttrsLength);
        
        // handle nothing-found case without exceptions
                getData ? &outData : NULL, key, search, record, outAttrs, outAttrsLength);
        
        // handle nothing-found case without exceptions
@@ -211,39 +341,43 @@ kern_return_t ucsp_server_findFirst(UCSP_ARGS, DbHandle db,
                *hSearch = search->handle();
                *hKey = key ? key->handle() : noKey;
 
                *hSearch = search->handle();
                *hKey = key ? key->handle() : noKey;
 
-               // return attributes (assumes relocated flat blob)
-               flips(outAttrs, outAttributes, outAttributesBase); 
-               // flipCssmDbAttributeData(outAttrs, outAttributes, outAttributesBase); 
-               *outAttributesLength = outAttrsLength;
-
+        if (outAttrsLength && outAttrs) {
+            Server::releaseWhenDone(outAttrs); // exception proof it against next line
+            if (!copyin(outAttrs, reinterpret_cast<xdrproc_t> (xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA), outAttributes, outAttributesLength))
+                CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+            Server::releaseWhenDone(*outAttributes);
+        }
+        
                // return data (temporary fix)
                if (getData) {
                // return data (temporary fix)
                if (getData) {
-                       if (key) {
-                               flip (*outData.interpretedAs<CssmKey>());
-                       }
-                       
-                       *data = outData.data();
-                       *dataLength = outData.length();
+                       Server::releaseWhenDone(outData.data());
+            xdrproc_t encode_proc = reinterpret_cast<xdrproc_t>(xdr_CSSM_NO_KEY_IN_DATA);
+            if (key)
+                encode_proc = reinterpret_cast<xdrproc_t>(xdr_CSSM_KEY_IN_DATA);
+                       if (!copyin(&outData, encode_proc, data, dataLength))
+                               CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+                       Server::releaseWhenDone(*data);
                }
        }
        END_IPC(DL)
 }
 
                }
        }
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_findNext(UCSP_ARGS, SearchHandle hSearch,
-       COPY_IN(CssmDbRecordAttributeData, inAttributes),
-       COPY_OUT(CssmDbRecordAttributeData, outAttributes),
-       boolean_t getData, DATA_OUT(data), KeyHandle *hKey,
-       RecordHandle *hRecord)
+
+kern_return_t ucsp_server_findNext(UCSP_ARGS, IPCSearchHandle hSearch,
+       DATA_IN(inAttributes),
+       DATA_OUT(outAttributes),
+       boolean_t getData, DATA_OUT(data), IPCKeyHandle *hKey,
+       IPCRecordHandle *hRecord)
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(inAttributes, inAttributesBase, inAttributesLength);
+       CopyOutDbRecordAttributes attrs(inAttributes, inAttributesLength);
        RefPointer<Database::Search> search =
                Server::find<Database::Search>(hSearch, CSSMERR_DL_INVALID_RESULTS_HANDLE);
        RefPointer<Database::Record> record;
        RefPointer<Key> key;
        RefPointer<Database::Search> search =
                Server::find<Database::Search>(hSearch, CSSMERR_DL_INVALID_RESULTS_HANDLE);
        RefPointer<Database::Record> record;
        RefPointer<Key> key;
-       CssmData outData; //OutputData outData(data, dataLength);
-       CssmDbRecordAttributeData *outAttrs; mach_msg_type_number_t outAttrsLength;
-       search->database().findNext(search, inAttributes, inAttributesLength,
+       CssmData outData;
+       CssmDbRecordAttributeData *outAttrs = NULL; mach_msg_type_number_t outAttrsLength;
+       search->database().findNext(search, attrs.attribute_data(), attrs.length(),
                getData ? &outData : NULL, key, record, outAttrs, outAttrsLength);
        
        // handle nothing-found case without exceptions
                getData ? &outData : NULL, key, record, outAttrs, outAttrsLength);
        
        // handle nothing-found case without exceptions
@@ -255,84 +389,95 @@ kern_return_t ucsp_server_findNext(UCSP_ARGS, SearchHandle hSearch,
                *hRecord = record->handle();
                *hKey = key ? key->handle() : noKey;
 
                *hRecord = record->handle();
                *hKey = key ? key->handle() : noKey;
 
-               // return attributes (assumes relocated flat blob)
-               flips(outAttrs, outAttributes, outAttributesBase);
-               *outAttributesLength = outAttrsLength;
-
+        if (outAttrsLength && outAttrs) {
+                       secdebug("attrmem", "Found attrs: %p of length: %d", outAttrs, outAttrsLength);
+            Server::releaseWhenDone(outAttrs); // exception proof it against next line
+            if (!copyin(outAttrs, reinterpret_cast<xdrproc_t> (xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA), outAttributes, outAttributesLength))
+                CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+                       secdebug("attrmem", "Copied attrs: %p of length: %d", *outAttributes, *outAttributesLength);
+            Server::releaseWhenDone(*outAttributes);
+        }
+        
                // return data (temporary fix)
                if (getData) {
                // return data (temporary fix)
                if (getData) {
-                       if (key) {
-                               flip (*outData.interpretedAs<CssmKey>());
-                       }
-                       
-                       *data = outData.data();
-                       *dataLength = outData.length();
+                       Server::releaseWhenDone(outData.data());
+            xdrproc_t encode_proc = reinterpret_cast<xdrproc_t>(xdr_CSSM_NO_KEY_IN_DATA);
+            if (key)
+                encode_proc = reinterpret_cast<xdrproc_t>(xdr_CSSM_KEY_IN_DATA);
+            if (!copyin(&outData, encode_proc, data, dataLength))
+                CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+                       Server::releaseWhenDone(*data);
                }
        }
        END_IPC(DL)
 }
 
                }
        }
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_findRecordHandle(UCSP_ARGS, RecordHandle hRecord,
-       COPY_IN(CssmDbRecordAttributeData, inAttributes),
-       COPY_OUT(CssmDbRecordAttributeData, outAttributes),
-       boolean_t getData, DATA_OUT(data), KeyHandle *hKey)
+kern_return_t ucsp_server_findRecordHandle(UCSP_ARGS, IPCRecordHandle hRecord,
+       DATA_IN(inAttributes), DATA_OUT(outAttributes),
+       boolean_t getData, DATA_OUT(data), IPCKeyHandle *hKey)
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(inAttributes, inAttributesBase, inAttributesLength);
+       CopyOutDbRecordAttributes attrs(inAttributes, inAttributesLength);
        RefPointer<Database::Record> record =
                Server::find<Database::Record>(hRecord, CSSMERR_DL_INVALID_RECORD_UID);
        RefPointer<Key> key;
        RefPointer<Database::Record> record =
                Server::find<Database::Record>(hRecord, CSSMERR_DL_INVALID_RECORD_UID);
        RefPointer<Key> key;
-       CssmData outData; //OutputData outData(data, dataLength);
+       CssmData outData;
        CssmDbRecordAttributeData *outAttrs; mach_msg_type_number_t outAttrsLength;
        CssmDbRecordAttributeData *outAttrs; mach_msg_type_number_t outAttrsLength;
-       record->database().findRecordHandle(record, inAttributes, inAttributesLength,
+       record->database().findRecordHandle(record, attrs.attribute_data(), attrs.length(),
                getData ? &outData : NULL, key, outAttrs, outAttrsLength);
        
        // return handles
        *hKey = key ? key->handle() : noKey;
 
                getData ? &outData : NULL, key, outAttrs, outAttrsLength);
        
        // return handles
        *hKey = key ? key->handle() : noKey;
 
-       // return attributes (assumes relocated flat blob)
-       flips(outAttrs, outAttributes, outAttributesBase);
-       *outAttributesLength = outAttrsLength;
-
+    if (outAttrsLength && outAttrs) {
+        Server::releaseWhenDone(outAttrs); // exception proof it against next line
+        if (!copyin(outAttrs, reinterpret_cast<xdrproc_t> (xdr_CSSM_DB_RECORD_ATTRIBUTE_DATA), outAttributes, outAttributesLength))
+            CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+        Server::releaseWhenDone(*outAttributes);
+    }
+    
        // return data (temporary fix)
        if (getData) {
        // return data (temporary fix)
        if (getData) {
-               if (key) {
-                       flip (*outData.interpretedAs<CssmKey>());
-               }
-                       
-               *data = outData.data();
-               *dataLength = outData.length();
+               Server::releaseWhenDone(outData.data());
+        xdrproc_t encode_proc = reinterpret_cast<xdrproc_t>(xdr_CSSM_NO_KEY_IN_DATA);
+        if (key)
+            encode_proc = reinterpret_cast<xdrproc_t>(xdr_CSSM_KEY_IN_DATA);
+        if (!copyin(&outData, encode_proc, data, dataLength))
+            CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+        Server::releaseWhenDone(*data);
        }
        END_IPC(DL)
 }
 
        }
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_insertRecord(UCSP_ARGS, DbHandle db, CSSM_DB_RECORDTYPE recordType,
-       COPY_IN(CssmDbRecordAttributeData, attributes), DATA_IN(data), RecordHandle *record)
+kern_return_t ucsp_server_insertRecord(UCSP_ARGS, IPCDbHandle db, CSSM_DB_RECORDTYPE recordType,
+       DATA_IN(inAttributes), DATA_IN(data), IPCRecordHandle *record)
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(attributes, attributesBase, attributesLength);
-       Server::database(db)->insertRecord(recordType, attributes, attributesLength,
-               DATA(data), *record);
+       RecordHandle recordHandle;
+       CopyOutDbRecordAttributes attrs(inAttributes, inAttributesLength);
+       Server::database(db)->insertRecord(recordType, attrs.attribute_data(), attrs.length(),
+               DATA(data), recordHandle);
+       *record = recordHandle;
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_modifyRecord(UCSP_ARGS, DbHandle db, RecordHandle *hRecord,
-       CSSM_DB_RECORDTYPE recordType, COPY_IN(CssmDbRecordAttributeData, attributes),
+kern_return_t ucsp_server_modifyRecord(UCSP_ARGS, IPCDbHandle db, IPCRecordHandle *hRecord,
+       CSSM_DB_RECORDTYPE recordType, DATA_IN(attributes),
        boolean_t setData, DATA_IN(data), CSSM_DB_MODIFY_MODE modifyMode)
 {
        BEGIN_IPC
        boolean_t setData, DATA_IN(data), CSSM_DB_MODIFY_MODE modifyMode)
 {
        BEGIN_IPC
-       relocate(attributes, attributesBase, attributesLength);
+       CopyOutDbRecordAttributes attrs(attributes, attributesLength);
        CssmData newData(DATA(data));
        RefPointer<Database::Record> record =
                Server::find<Database::Record>(*hRecord, CSSMERR_DL_INVALID_RECORD_UID);
        CssmData newData(DATA(data));
        RefPointer<Database::Record> record =
                Server::find<Database::Record>(*hRecord, CSSMERR_DL_INVALID_RECORD_UID);
-       Server::database(db)->modifyRecord(recordType, record, attributes, attributesLength,
+       Server::database(db)->modifyRecord(recordType, record, attrs.attribute_data(), attrs.length(),
                setData ? &newData : NULL, modifyMode);
        // note that the record handle presented to the client never changes here
        // (we could, but have no reason to - our record handles are just always up to date)
        END_IPC(DL)
 }
 
                setData ? &newData : NULL, modifyMode);
        // note that the record handle presented to the client never changes here
        // (we could, but have no reason to - our record handles are just always up to date)
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_deleteRecord(UCSP_ARGS, DbHandle db, RecordHandle hRecord)
+kern_return_t ucsp_server_deleteRecord(UCSP_ARGS, IPCDbHandle db, IPCRecordHandle hRecord)
 {
        BEGIN_IPC
        Server::database(db)->deleteRecord(
 {
        BEGIN_IPC
        Server::database(db)->deleteRecord(
@@ -340,7 +485,7 @@ kern_return_t ucsp_server_deleteRecord(UCSP_ARGS, DbHandle db, RecordHandle hRec
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_releaseSearch(UCSP_ARGS, SearchHandle hSearch)
+kern_return_t ucsp_server_releaseSearch(UCSP_ARGS, IPCSearchHandle hSearch)
 {
        BEGIN_IPC
        RefPointer<Database::Search> search = Server::find<Database::Search>(hSearch, 0);
 {
        BEGIN_IPC
        RefPointer<Database::Search> search = Server::find<Database::Search>(hSearch, 0);
@@ -348,7 +493,7 @@ kern_return_t ucsp_server_releaseSearch(UCSP_ARGS, SearchHandle hSearch)
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_releaseRecord(UCSP_ARGS, RecordHandle hRecord)
+kern_return_t ucsp_server_releaseRecord(UCSP_ARGS, IPCRecordHandle hRecord)
 {
        BEGIN_IPC
        RefPointer<Database::Record> record = Server::find<Database::Record>(hRecord, 0);
 {
        BEGIN_IPC
        RefPointer<Database::Record> record = Server::find<Database::Record>(hRecord, 0);
@@ -356,33 +501,19 @@ kern_return_t ucsp_server_releaseRecord(UCSP_ARGS, RecordHandle hRecord)
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_getRecordFromHandle(UCSP_ARGS, RecordHandle record,
-       COPY_IN(CssmDbRecordAttributeData, inAttributes),
-       COPY_OUT(CssmDbRecordAttributeData, outAttributes),
-       boolean_t getData,
-       DATA_OUT(data))
-{
-       BEGIN_IPC
-    secdebug("dl", "getRecordFromHandle");
-       relocate(inAttributes, inAttributesBase, inAttributesLength);
-       // @@@
-       END_IPC(DL)
-}
-
 
 //
 // Internal database management
 //
 
 //
 // Internal database management
 //
-kern_return_t ucsp_server_createDb(UCSP_ARGS, DbHandle *db,
-       COPY_IN(DLDbFlatIdentifier, ident),
-    COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
+kern_return_t ucsp_server_createDb(UCSP_ARGS, IPCDbHandle *db,
+       DATA_IN(ident), DATA_IN(cred), DATA_IN(owner),
     DBParameters params)
 {
        BEGIN_IPC
     DBParameters params)
 {
        BEGIN_IPC
-       relocate(cred, credBase, credLength);
-       relocate(owner, ownerBase, ownerLength);
-    relocate(ident, identBase, identLength);
-       *db = (new KeychainDatabase(*ident, params, connection.process(), cred, owner))->handle();
+       CopyOutAccessCredentials creds(cred, credLength);
+       CopyOutEntryAcl owneracl(owner, ownerLength);
+       CopyOut flatident(ident, identLength, reinterpret_cast<xdrproc_t>(xdr_DLDbFlatIdentifierRef));
+       *db = (new KeychainDatabase(*reinterpret_cast<DLDbFlatIdentifier*>(flatident.data()), params, connection.process(), creds, owneracl))->handle();
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
@@ -390,7 +521,7 @@ kern_return_t ucsp_server_createDb(UCSP_ARGS, DbHandle *db,
 // @@@  caller should be required to call decodeDb() to get a DbHandle
 //      instead of passing the blob itself
 kern_return_t ucsp_server_cloneDbForSync(UCSP_ARGS, DATA_IN(blob), 
 // @@@  caller should be required to call decodeDb() to get a DbHandle
 //      instead of passing the blob itself
 kern_return_t ucsp_server_cloneDbForSync(UCSP_ARGS, DATA_IN(blob), 
-       DbHandle srcDb, DATA_IN(agentData), DbHandle *newDb)
+       IPCDbHandle srcDb, DATA_IN(agentData), IPCDbHandle *newDb)
 {
        BEGIN_IPC
        RefPointer<KeychainDatabase> srcKC = Server::keychain(srcDb);
 {
        BEGIN_IPC
        RefPointer<KeychainDatabase> srcKC = Server::keychain(srcDb);
@@ -399,8 +530,8 @@ kern_return_t ucsp_server_cloneDbForSync(UCSP_ARGS, DATA_IN(blob),
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_commitDbForSync(UCSP_ARGS, DbHandle srcDb,
-    DbHandle cloneDb, DATA_OUT(blob))
+kern_return_t ucsp_server_commitDbForSync(UCSP_ARGS, IPCDbHandle srcDb,
+    IPCDbHandle cloneDb, DATA_OUT(blob))
 {
        BEGIN_IPC
     RefPointer<KeychainDatabase> srcKC = Server::keychain(srcDb);
 {
        BEGIN_IPC
     RefPointer<KeychainDatabase> srcKC = Server::keychain(srcDb);
@@ -418,18 +549,18 @@ kern_return_t ucsp_server_commitDbForSync(UCSP_ARGS, DbHandle srcDb,
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_decodeDb(UCSP_ARGS, DbHandle *db,
-    COPY_IN(DLDbFlatIdentifier, ident), COPY_IN(AccessCredentials, cred), DATA_IN(blob))
+kern_return_t ucsp_server_decodeDb(UCSP_ARGS, IPCDbHandle *db,
+    DATA_IN(ident), DATA_IN(cred), DATA_IN(blob))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(cred, credBase, credLength);
-    relocate(ident, identBase, identLength);
-       *db = (new KeychainDatabase(*ident, SSBLOB(DbBlob, blob),
-        connection.process(), cred))->handle();
+       CopyOutAccessCredentials creds(cred, credLength);
+       CopyOut flatident(ident, identLength, reinterpret_cast<xdrproc_t>(xdr_DLDbFlatIdentifierRef));
+       *db = (new KeychainDatabase(*reinterpret_cast<DLDbFlatIdentifier*>(flatident.data()), SSBLOB(DbBlob, blob),
+        connection.process(), creds))->handle();
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_encodeDb(UCSP_ARGS, DbHandle db, DATA_OUT(blob))
+kern_return_t ucsp_server_encodeDb(UCSP_ARGS, IPCDbHandle db, DATA_OUT(blob))
 {
        BEGIN_IPC
     DbBlob *dbBlob = Server::keychain(db)->blob();     // memory owned by database
 {
        BEGIN_IPC
     DbBlob *dbBlob = Server::keychain(db)->blob();     // memory owned by database
@@ -438,26 +569,26 @@ kern_return_t ucsp_server_encodeDb(UCSP_ARGS, DbHandle db, DATA_OUT(blob))
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_setDbParameters(UCSP_ARGS, DbHandle db, DBParameters params)
+kern_return_t ucsp_server_setDbParameters(UCSP_ARGS, IPCDbHandle db, DBParameters params)
 {
        BEGIN_IPC
        Server::keychain(db)->setParameters(params);
        END_IPC(DL)
 }
 
 {
        BEGIN_IPC
        Server::keychain(db)->setParameters(params);
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_getDbParameters(UCSP_ARGS, DbHandle db, DBParameters *params)
+kern_return_t ucsp_server_getDbParameters(UCSP_ARGS, IPCDbHandle db, DBParameters *params)
 {
        BEGIN_IPC
        Server::keychain(db)->getParameters(*params);
        END_IPC(DL)
 }
 
 {
        BEGIN_IPC
        Server::keychain(db)->getParameters(*params);
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_changePassphrase(UCSP_ARGS, DbHandle db,
-    COPY_IN(AccessCredentials, cred))
+kern_return_t ucsp_server_changePassphrase(UCSP_ARGS, IPCDbHandle db,
+    DATA_IN(cred))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-    relocate(cred, credBase, credLength);
-       Server::keychain(db)->changePassphrase(cred);
+       CopyOutAccessCredentials creds(cred, credLength);
+       Server::keychain(db)->changePassphrase(creds);
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
@@ -468,21 +599,21 @@ kern_return_t ucsp_server_lockAll (UCSP_ARGS, boolean_t)
        END_IPC(DL)
 }
 
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_unlockDb(UCSP_ARGS, DbHandle db)
+kern_return_t ucsp_server_unlockDb(UCSP_ARGS, IPCDbHandle db)
 {
        BEGIN_IPC
        Server::keychain(db)->unlockDb();
        END_IPC(DL)
 }
 
 {
        BEGIN_IPC
        Server::keychain(db)->unlockDb();
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_unlockDbWithPassphrase(UCSP_ARGS, DbHandle db, DATA_IN(passphrase))
+kern_return_t ucsp_server_unlockDbWithPassphrase(UCSP_ARGS, IPCDbHandle db, DATA_IN(passphrase))
 {
        BEGIN_IPC
        Server::keychain(db)->unlockDb(DATA(passphrase));
        END_IPC(DL)
 }
 
 {
        BEGIN_IPC
        Server::keychain(db)->unlockDb(DATA(passphrase));
        END_IPC(DL)
 }
 
-kern_return_t ucsp_server_isLocked(UCSP_ARGS, DbHandle db, boolean_t *locked)
+kern_return_t ucsp_server_isLocked(UCSP_ARGS, IPCDbHandle db, boolean_t *locked)
 {
     BEGIN_IPC
     *locked = Server::database(db)->isLocked();
 {
     BEGIN_IPC
     *locked = Server::database(db)->isLocked();
@@ -493,7 +624,7 @@ kern_return_t ucsp_server_isLocked(UCSP_ARGS, DbHandle db, boolean_t *locked)
 //
 // Key management
 //
 //
 // Key management
 //
-kern_return_t ucsp_server_encodeKey(UCSP_ARGS, KeyHandle keyh, DATA_OUT(blob),
+kern_return_t ucsp_server_encodeKey(UCSP_ARGS, IPCKeyHandle keyh, DATA_OUT(blob),
     boolean_t wantUid, DATA_OUT(uid))
 {
        BEGIN_IPC
     boolean_t wantUid, DATA_OUT(uid))
 {
        BEGIN_IPC
@@ -513,19 +644,24 @@ kern_return_t ucsp_server_encodeKey(UCSP_ARGS, KeyHandle keyh, DATA_OUT(blob),
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_decodeKey(UCSP_ARGS, KeyHandle *keyh, CssmKey::Header *header,
-       DbHandle db, DATA_IN(blob))
+kern_return_t ucsp_server_decodeKey(UCSP_ARGS, IPCKeyHandle *keyh, DATA_OUT(keyHeader),
+       IPCDbHandle db, DATA_IN(blob))
 {
        BEGIN_IPC
     RefPointer<Key> key = new KeychainKey(*Server::keychain(db), SSBLOB(KeyBlob, blob));
 {
        BEGIN_IPC
     RefPointer<Key> key = new KeychainKey(*Server::keychain(db), SSBLOB(KeyBlob, blob));
-    key->returnKey(*keyh, *header);
-       flip(*header);
+       CssmKey::Header header;
+       KeyHandle keyHandle;
+    key->returnKey(keyHandle, header);
+       *keyh = keyHandle;
+       if (!copyin(&header, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), keyHeader, keyHeaderLength))
+               CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+       Server::releaseWhenDone(*keyHeader);
        END_IPC(CSP)
 }
 
 // keychain synchronization
        END_IPC(CSP)
 }
 
 // keychain synchronization
-kern_return_t ucsp_server_recodeKey(UCSP_ARGS, DbHandle oldDb, KeyHandle keyh, 
-       DbHandle newDb, DATA_OUT(newBlob))
+kern_return_t ucsp_server_recodeKey(UCSP_ARGS, IPCDbHandle oldDb, IPCKeyHandle keyh, 
+       IPCDbHandle newDb, DATA_OUT(newBlob))
 {
        BEGIN_IPC
        // If the old key is passed in as DATA_IN(oldBlob):
 {
        BEGIN_IPC
        // If the old key is passed in as DATA_IN(oldBlob):
@@ -543,7 +679,7 @@ kern_return_t ucsp_server_recodeKey(UCSP_ARGS, DbHandle oldDb, KeyHandle keyh,
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_releaseKey(UCSP_ARGS, KeyHandle keyh)
+kern_return_t ucsp_server_releaseKey(UCSP_ARGS, IPCKeyHandle keyh)
 {
        BEGIN_IPC
        RefPointer<Key> key = Server::key(keyh);
 {
        BEGIN_IPC
        RefPointer<Key> key = Server::key(keyh);
@@ -551,7 +687,7 @@ kern_return_t ucsp_server_releaseKey(UCSP_ARGS, KeyHandle keyh)
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_queryKeySizeInBits(UCSP_ARGS, KeyHandle keyh, CSSM_KEY_SIZE *length)
+kern_return_t ucsp_server_queryKeySizeInBits(UCSP_ARGS, IPCKeyHandle keyh, CSSM_KEY_SIZE *length)
 {
        BEGIN_IPC
        RefPointer<Key> key = Server::key(keyh);
 {
        BEGIN_IPC
        RefPointer<Key> key = Server::key(keyh);
@@ -559,17 +695,17 @@ kern_return_t ucsp_server_queryKeySizeInBits(UCSP_ARGS, KeyHandle keyh, CSSM_KEY
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_getOutputSize(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
+kern_return_t ucsp_server_getOutputSize(UCSP_ARGS, DATA_IN(context), IPCKeyHandle keyh,
     uint32 inputSize, boolean_t encrypt, uint32 *outputSize)
 {
     BEGIN_IPC
     uint32 inputSize, boolean_t encrypt, uint32 *outputSize)
 {
     BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
+       CopyOutContext ctx(context, contextLength);
        RefPointer<Key> key = Server::key(keyh);
        RefPointer<Key> key = Server::key(keyh);
-    key->database().getOutputSize(context, *key, inputSize, encrypt, *outputSize);
+    key->database().getOutputSize(*ctx, *key, inputSize, encrypt, *outputSize);
     END_IPC(CSP)
 }
 
     END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_getKeyDigest(UCSP_ARGS, KeyHandle key, DATA_OUT(digest))
+kern_return_t ucsp_server_getKeyDigest(UCSP_ARGS, IPCKeyHandle key, DATA_OUT(digest))
 {
        BEGIN_IPC
        CssmData digestData = Server::key(key)->canonicalDigest();
 {
        BEGIN_IPC
        CssmData digestData = Server::key(key)->canonicalDigest();
@@ -582,47 +718,47 @@ kern_return_t ucsp_server_getKeyDigest(UCSP_ARGS, KeyHandle key, DATA_OUT(digest
 //
 // Signatures and MACs
 //
 //
 // Signatures and MACs
 //
-kern_return_t ucsp_server_generateSignature(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
+kern_return_t ucsp_server_generateSignature(UCSP_ARGS, DATA_IN(context), IPCKeyHandle keyh,
         CSSM_ALGORITHMS signOnlyAlgorithm, DATA_IN(data), DATA_OUT(signature))
 {
        BEGIN_IPC
         CSSM_ALGORITHMS signOnlyAlgorithm, DATA_IN(data), DATA_OUT(signature))
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
+       CopyOutContext ctx(context, contextLength);
        RefPointer<Key> key = Server::key(keyh);
        OutputData sigData(signature, signatureLength);
        RefPointer<Key> key = Server::key(keyh);
        OutputData sigData(signature, signatureLength);
-       key->database().generateSignature(context, *key, signOnlyAlgorithm,
+       key->database().generateSignature(*ctx, *key, signOnlyAlgorithm,
                DATA(data), sigData);
        END_IPC(CSP)
 }
 
                DATA(data), sigData);
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_verifySignature(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
+kern_return_t ucsp_server_verifySignature(UCSP_ARGS, DATA_IN(context), IPCKeyHandle keyh,
                CSSM_ALGORITHMS verifyOnlyAlgorithm, DATA_IN(data), DATA_IN(signature))
 {
        BEGIN_IPC
                CSSM_ALGORITHMS verifyOnlyAlgorithm, DATA_IN(data), DATA_IN(signature))
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
+       CopyOutContext ctx(context, contextLength);
        RefPointer<Key> key = Server::key(keyh);
        RefPointer<Key> key = Server::key(keyh);
-       key->database().verifySignature(context, *key, verifyOnlyAlgorithm,
+       key->database().verifySignature(*ctx, *key, verifyOnlyAlgorithm,
                DATA(data), DATA(signature));
        END_IPC(CSP)
 }
 
                DATA(data), DATA(signature));
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_generateMac(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
+kern_return_t ucsp_server_generateMac(UCSP_ARGS, DATA_IN(context), IPCKeyHandle keyh,
                DATA_IN(data), DATA_OUT(mac))
 {
        BEGIN_IPC
                DATA_IN(data), DATA_OUT(mac))
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
+       CopyOutContext ctx(context, contextLength);
        RefPointer<Key> key = Server::key(keyh);
        OutputData macData(mac, macLength);
        RefPointer<Key> key = Server::key(keyh);
        OutputData macData(mac, macLength);
-       key->database().generateMac(context, *key, DATA(data), macData);
+       key->database().generateMac(*ctx, *key, DATA(data), macData);
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_verifyMac(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
+kern_return_t ucsp_server_verifyMac(UCSP_ARGS, DATA_IN(context), IPCKeyHandle keyh,
                DATA_IN(data), DATA_IN(mac))
 {
        BEGIN_IPC
                DATA_IN(data), DATA_IN(mac))
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
+       CopyOutContext ctx(context, contextLength);
        RefPointer<Key> key = Server::key(keyh);
        RefPointer<Key> key = Server::key(keyh);
-       key->database().verifyMac(context, *key, DATA(data), DATA(mac));
+       key->database().verifyMac(*ctx, *key, DATA(data), DATA(mac));
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
@@ -630,25 +766,25 @@ kern_return_t ucsp_server_verifyMac(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
 //
 // Encryption/Decryption
 //
 //
 // Encryption/Decryption
 //
-kern_return_t ucsp_server_encrypt(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
+kern_return_t ucsp_server_encrypt(UCSP_ARGS, DATA_IN(context), IPCKeyHandle keyh,
        DATA_IN(clear), DATA_OUT(cipher))
 {
        BEGIN_IPC
        DATA_IN(clear), DATA_OUT(cipher))
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
+       CopyOutContext ctx(context, contextLength);
        RefPointer<Key> key = Server::key(keyh);
        OutputData cipherOut(cipher, cipherLength);
        RefPointer<Key> key = Server::key(keyh);
        OutputData cipherOut(cipher, cipherLength);
-       key->database().encrypt(context, *key, DATA(clear), cipherOut);
+       key->database().encrypt(*ctx, *key, DATA(clear), cipherOut);
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_decrypt(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
+kern_return_t ucsp_server_decrypt(UCSP_ARGS, DATA_IN(context), IPCKeyHandle keyh,
        DATA_IN(cipher), DATA_OUT(clear))
 {
        BEGIN_IPC
        DATA_IN(cipher), DATA_OUT(clear))
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
+       CopyOutContext ctx(context, contextLength);
        RefPointer<Key> key = Server::key(keyh);
        OutputData clearOut(clear, clearLength);
        RefPointer<Key> key = Server::key(keyh);
        OutputData clearOut(clear, clearLength);
-       key->database().decrypt(context, *key, DATA(cipher), clearOut);
+       key->database().decrypt(*ctx, *key, DATA(cipher), clearOut);
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
@@ -656,42 +792,60 @@ kern_return_t ucsp_server_decrypt(UCSP_ARGS, CONTEXT_ARGS, KeyHandle keyh,
 //
 // Key generation
 //
 //
 // Key generation
 //
-kern_return_t ucsp_server_generateKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
-       COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
-       uint32 usage, uint32 attrs, KeyHandle *newKey, CssmKey::Header *newHeader)
+kern_return_t ucsp_server_generateKey(UCSP_ARGS, IPCDbHandle db, DATA_IN(context),
+       DATA_IN(cred), DATA_IN(owner),
+       uint32 usage, uint32 attrs, IPCKeyHandle *newKey, DATA_OUT(keyHeader))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
-    relocate(cred, credBase, credLength);
-       relocate(owner, ownerBase, ownerLength);
+       CopyOutContext ctx(context, contextLength);
+       CopyOutAccessCredentials creds(cred, credLength);
+
+       CopyOutEntryAcl owneracl(owner, ownerLength);
        //@@@ preliminary interpretation - will get "type handle"
        RefPointer<Database> database =
                Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT);
        RefPointer<Key> key;
        //@@@ preliminary interpretation - will get "type handle"
        RefPointer<Database> database =
                Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT);
        RefPointer<Key> key;
-       database->generateKey(context, cred, owner, usage, attrs, key);
-    key->returnKey(*newKey, *newHeader);
-       flip(*newHeader);
+       database->generateKey(*ctx, creds, owneracl, usage, attrs, key);
+       CssmKey::Header newHeader;
+       KeyHandle keyHandle;
+    key->returnKey(keyHandle, newHeader);
+       *newKey = keyHandle;
+
+       if (!copyin(&newHeader, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), keyHeader, keyHeaderLength))
+               CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+       Server::releaseWhenDone(*keyHeader);
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_generateKeyPair(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
-       COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
+kern_return_t ucsp_server_generateKeyPair(UCSP_ARGS, IPCDbHandle db, DATA_IN(context),
+       DATA_IN(cred), DATA_IN(owner),
        uint32 pubUsage, uint32 pubAttrs, uint32 privUsage, uint32 privAttrs,
        uint32 pubUsage, uint32 pubAttrs, uint32 privUsage, uint32 privAttrs,
-       KeyHandle *pubKey, CssmKey::Header *pubHeader, KeyHandle *privKey, CssmKey::Header *privHeader)
+       IPCKeyHandle *pubKey, DATA_OUT(pubHeader), IPCKeyHandle *privKey, DATA_OUT(privHeader))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
-    relocate(cred, credBase, credLength);
-       relocate(owner, ownerBase, ownerLength);
+       CopyOutContext ctx(context, contextLength);
+       CopyOutAccessCredentials creds(cred, credLength);
+       CopyOutEntryAcl owneracl(owner, ownerLength);
        RefPointer<Database> database =
                Server::optionalDatabase(db, (privAttrs | pubAttrs) & CSSM_KEYATTR_PERMANENT);
        RefPointer<Key> pub, priv;
        RefPointer<Database> database =
                Server::optionalDatabase(db, (privAttrs | pubAttrs) & CSSM_KEYATTR_PERMANENT);
        RefPointer<Key> pub, priv;
-       database->generateKey(context, cred, owner,
+       database->generateKey(*ctx, creds, owneracl,
                pubUsage, pubAttrs, privUsage, privAttrs, pub, priv);
                pubUsage, pubAttrs, privUsage, privAttrs, pub, priv);
-    pub->returnKey(*pubKey, *pubHeader);
-       flip(*pubHeader);
-    priv->returnKey(*privKey, *privHeader);
-       flip(*privHeader);
+       CssmKey::Header tmpPubHeader, tmpPrivHeader;
+       KeyHandle pubKeyHandle, privKeyHandle;
+       
+    pub->returnKey(pubKeyHandle, tmpPubHeader);
+       *pubKey = pubKeyHandle;
+       if (!copyin(&tmpPubHeader, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), pubHeader, pubHeaderLength))
+               CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+       Server::releaseWhenDone(*pubHeader);
+
+    priv->returnKey(privKeyHandle, tmpPrivHeader);
+       *privKey = privKeyHandle;
+       if (!copyin(&tmpPrivHeader, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), privHeader, privHeaderLength))
+               CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+       Server::releaseWhenDone(*privHeader);
+
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
@@ -699,47 +853,55 @@ kern_return_t ucsp_server_generateKeyPair(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
 //
 // Key wrapping and unwrapping
 //
 //
 // Key wrapping and unwrapping
 //
-kern_return_t ucsp_server_wrapKey(UCSP_ARGS, CONTEXT_ARGS, KeyHandle hWrappingKey,
-       COPY_IN(AccessCredentials, cred), KeyHandle hKeyToBeWrapped,
-       DATA_IN(descriptiveData), CssmKey *wrappedKey, DATA_OUT(keyData))
+kern_return_t ucsp_server_wrapKey(UCSP_ARGS, DATA_IN(context), IPCKeyHandle hWrappingKey,
+       DATA_IN(cred), IPCKeyHandle hKeyToBeWrapped,
+       DATA_IN(descriptiveData), DATA_OUT(wrappedKeyData))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
-    relocate(cred, credBase, credLength);
+       CssmKey wrappedKey;
+       CopyOutContext ctx(context, contextLength);
+       CopyOutAccessCredentials creds(cred, credLength);
        RefPointer<Key> subjectKey = Server::key(hKeyToBeWrapped);
        RefPointer<Key> wrappingKey = Server::optionalKey(hWrappingKey);
        RefPointer<Key> subjectKey = Server::key(hKeyToBeWrapped);
        RefPointer<Key> wrappingKey = Server::optionalKey(hWrappingKey);
-       if ((context.algorithm() == CSSM_ALGID_NONE && subjectKey->attribute(CSSM_KEYATTR_SENSITIVE))
+       if ((ctx.context().algorithm() == CSSM_ALGID_NONE && subjectKey->attribute(CSSM_KEYATTR_SENSITIVE))
                || !subjectKey->attribute(CSSM_KEYATTR_EXTRACTABLE))
                CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
                || !subjectKey->attribute(CSSM_KEYATTR_EXTRACTABLE))
                CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
-       pickDb(subjectKey, wrappingKey)->wrapKey(context, cred, wrappingKey, *subjectKey, DATA(descriptiveData), *wrappedKey);
+       pickDb(subjectKey, wrappingKey)->wrapKey(*ctx, creds, wrappingKey, *subjectKey, DATA(descriptiveData), wrappedKey);
+       Server::releaseWhenDone(wrappedKey.keyData().data());
 
 
-    // transmit key data back as a separate blob
-       OutputData keyDatas(keyData, keyDataLength);
-       keyDatas = wrappedKey->keyData();
-       flip(*wrappedKey);
+       if (!copyin(&wrappedKey, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEY), wrappedKeyData, wrappedKeyDataLength))
+               CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+        
+       Server::releaseWhenDone(*wrappedKeyData);
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_unwrapKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
-       KeyHandle hWrappingKey, COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
-       KeyHandle hPublicKey, CssmKey wrappedKey, DATA_IN(wrappedKeyData),
+kern_return_t ucsp_server_unwrapKey(UCSP_ARGS, IPCDbHandle db, DATA_IN(context),
+       IPCKeyHandle hWrappingKey, DATA_IN(cred), DATA_IN(owner),
+       IPCKeyHandle hPublicKey, DATA_IN(wrappedKeyData),
        CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs, DATA_OUT(descriptiveData),
        CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs, DATA_OUT(descriptiveData),
-    KeyHandle *newKey, CssmKey::Header *newHeader)
+    IPCKeyHandle *newKey, DATA_OUT(keyHeader)/*CssmKey::Header *newHeader*/)
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
-       flip(wrappedKey);
-       wrappedKey.keyData() = DATA(wrappedKeyData);
-    relocate(cred, credBase, credLength);
-       relocate(owner, ownerBase, ownerLength);
+       CopyOutContext ctx(context, contextLength);
+       CopyOutKey wrappedKey(wrappedKeyData, wrappedKeyDataLength);
+       CopyOutAccessCredentials creds(cred, credLength);
+       CopyOutEntryAcl owneracl(owner, ownerLength);
        OutputData descriptiveDatas(descriptiveData, descriptiveDataLength);
        RefPointer<Key> wrappingKey = Server::optionalKey(hWrappingKey);
     RefPointer<Key> unwrappedKey;
        OutputData descriptiveDatas(descriptiveData, descriptiveDataLength);
        RefPointer<Key> wrappingKey = Server::optionalKey(hWrappingKey);
     RefPointer<Key> unwrappedKey;
-       pickDb(Server::optionalDatabase(db), wrappingKey)->unwrapKey(context, cred, owner,
+       pickDb(Server::optionalDatabase(db), wrappingKey)->unwrapKey(*ctx, creds, owneracl,
                wrappingKey, Server::optionalKey(hPublicKey),
                wrappingKey, Server::optionalKey(hPublicKey),
-               usage, attrs, wrappedKey, unwrappedKey, descriptiveDatas);
-       unwrappedKey->returnKey(*newKey, *newHeader);
-       flip(*newHeader);
+               usage, attrs, wrappedKey.key(), unwrappedKey, descriptiveDatas);
+               
+       CssmKey::Header newHeader;
+       KeyHandle keyHandle;
+       unwrappedKey->returnKey(keyHandle, newHeader);
+       *newKey = keyHandle;
+       if (!copyin(&newHeader, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), keyHeader, keyHeaderLength))
+               CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+       Server::releaseWhenDone(*keyHeader);
+
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
@@ -751,34 +913,40 @@ kern_return_t ucsp_server_unwrapKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
 // (artificial) POD CssmDeriveData handles those that are known; if you add
 // an algorithm with structured param, you need to add a case there.
 //
 // (artificial) POD CssmDeriveData handles those that are known; if you add
 // an algorithm with structured param, you need to add a case there.
 //
-kern_return_t ucsp_server_deriveKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS, KeyHandle hKey,
-       COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
-    COPY_IN(CssmDeriveData, paramInput), DATA_OUT(paramOutput),
-       uint32 usage, uint32 attrs, KeyHandle *newKey, CssmKey::Header *newHeader)
+kern_return_t ucsp_server_deriveKey(UCSP_ARGS, IPCDbHandle db, DATA_IN(context), IPCKeyHandle hKey,
+       DATA_IN(cred), DATA_IN(owner),
+    DATA_IN(paramInput), DATA_OUT(paramOutput),
+       uint32 usage, uint32 attrs, IPCKeyHandle *newKey, DATA_OUT(keyHeader))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
-    relocate(cred, credBase, credLength);
-       relocate(owner, ownerBase, ownerLength);
-       relocate(paramInput, paramInputBase, paramInputLength);
-       if (!paramInput || paramInput->algorithm != context.algorithm())
+       CopyOutContext ctx(context, contextLength);
+       CopyOutAccessCredentials creds(cred, credLength);
+       CopyOutEntryAcl owneracl(owner, ownerLength);
+       CopyOutDeriveData deriveParam(paramInput, paramInputLength);
+       if (deriveParam.algorithm() != ctx.context().algorithm())
                CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); // client layer fault
     
        RefPointer<Database> database =
                Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT);
        RefPointer<Key> key = Server::optionalKey(hKey);
                CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); // client layer fault
     
        RefPointer<Database> database =
                Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT);
        RefPointer<Key> key = Server::optionalKey(hKey);
-       CssmData *param = paramInput ? &paramInput->baseData : NULL;
-    RefPointer<Key> derivedKey;
+       CSSM_DATA param = deriveParam.cssm_data();
+       RefPointer<Key> derivedKey;
        pickDb(Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT),
        pickDb(Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT),
-               key)->deriveKey(context, key, cred, owner, param, usage, attrs, derivedKey);
-       derivedKey->returnKey(*newKey, *newHeader);
-       flip(*newHeader);
-       if (param && param->length()) {
-        if (!param->data())    // CSP screwed up
+               key)->deriveKey(*ctx, key, creds, owneracl, static_cast<CssmData*>(&param), usage, attrs, derivedKey);
+               
+       CssmKey::Header newHeader;
+       KeyHandle keyHandle;
+       derivedKey->returnKey(keyHandle, newHeader);
+       *newKey = keyHandle;
+       
+       if (!copyin(&newHeader, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), keyHeader, keyHeaderLength))
+               CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+       Server::releaseWhenDone(*keyHeader);
+               
+       if (param.Length) {
+        if (!param.Data)       // CSP screwed up
             CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
             CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
-        if (paramInputLength)          // using incoming buffer; make a copy
-            *param = CssmAutoData(Server::csp().allocator(), *param).release();
-        OutputData(paramOutput, paramOutputLength) = *param;   // return the data
+               OutputData(paramOutput, paramOutputLength) = CssmAutoData(Server::csp().allocator(), param).release();
     }
        END_IPC(CSP)
 }
     }
        END_IPC(CSP)
 }
@@ -787,16 +955,16 @@ kern_return_t ucsp_server_deriveKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS, KeyHan
 //
 // Random generation
 //
 //
 // Random generation
 //
-kern_return_t ucsp_server_generateRandom(UCSP_ARGS, uint32 ssid, CONTEXT_ARGS, DATA_OUT(data))
+kern_return_t ucsp_server_generateRandom(UCSP_ARGS, uint32 ssid, DATA_IN(context), DATA_OUT(data))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(context, contextBase, attributes, attrSize);
+       CopyOutContext ctx(context, contextLength);
        if (ssid)
                CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
        
        // default version (use /dev/random)
        Allocator &allocator = Allocator::standard(Allocator::sensitive);
        if (ssid)
                CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
        
        // default version (use /dev/random)
        Allocator &allocator = Allocator::standard(Allocator::sensitive);
-       if (size_t bytes = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE)) {
+       if (size_t bytes = ctx.context().getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE)) {
                void *buffer = allocator.malloc(bytes);
                Server::active().random(buffer, bytes);
                *data = buffer;
                void *buffer = allocator.malloc(bytes);
                Server::active().random(buffer, bytes);
                *data = buffer;
@@ -811,72 +979,73 @@ kern_return_t ucsp_server_generateRandom(UCSP_ARGS, uint32 ssid, CONTEXT_ARGS, D
 // ACL management.
 // Watch out for the memory-management tap-dance.
 //
 // ACL management.
 // Watch out for the memory-management tap-dance.
 //
-kern_return_t ucsp_server_getOwner(UCSP_ARGS, AclKind kind, KeyHandle key,
-       COPY_OUT(AclOwnerPrototype, ownerOut))
+kern_return_t ucsp_server_getOwner(UCSP_ARGS, AclKind kind, IPCKeyHandle key,
+       DATA_OUT(ownerOut))
 {
        BEGIN_IPC
        AclOwnerPrototype owner;
        Server::aclBearer(kind, key).getOwner(owner);   // allocates memory in owner
 {
        BEGIN_IPC
        AclOwnerPrototype owner;
        Server::aclBearer(kind, key).getOwner(owner);   // allocates memory in owner
-       Copier<AclOwnerPrototype> owners(&owner, Allocator::standard()); // make flat copy
+       void *owners_data; u_int owners_length;
+       if (!::copyin(&owner, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_OWNER_PROTOTYPE), &owners_data, &owners_length))
+                       CssmError::throwMe(CSSM_ERRCODE_MEMORY_ERROR);  
+
        { ChunkFreeWalker free; walk(free, owner); } // release chunked original
        { ChunkFreeWalker free; walk(free, owner); } // release chunked original
-       *ownerOutLength = owners.length();
-       flips(owners.value(), ownerOut, ownerOutBase);
-       Server::releaseWhenDone(owners.keep()); // throw flat copy out when done
+       Server::releaseWhenDone(owners_data); // throw flat copy out when done
+       *ownerOut = owners_data;
+       *ownerOutLength = owners_length;
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_setOwner(UCSP_ARGS, AclKind kind, KeyHandle key,
-       COPY_IN(AccessCredentials, cred), COPY_IN(AclOwnerPrototype, owner))
+kern_return_t ucsp_server_setOwner(UCSP_ARGS, AclKind kind, IPCKeyHandle key,
+       DATA_IN(cred), DATA_IN(owner))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-    relocate(cred, credBase, credLength);
-       relocate(owner, ownerBase, ownerLength);
-       Server::aclBearer(kind, key).changeOwner(*owner, cred);
+       CopyOutAccessCredentials creds(cred, credLength);
+       CopyOutOwnerAcl owneracl(owner, ownerLength);
+       Server::aclBearer(kind, key).changeOwner(*owneracl, creds);
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
-kern_return_t ucsp_server_getAcl(UCSP_ARGS, AclKind kind, KeyHandle key,
+kern_return_t ucsp_server_getAcl(UCSP_ARGS, AclKind kind, IPCKeyHandle key,
        boolean_t haveTag, const char *tag,
        boolean_t haveTag, const char *tag,
-       uint32 *countp, COPY_OUT(AclEntryInfo, acls))
+       uint32 *countp, DATA_OUT(acls))
 {
        BEGIN_IPC
        uint32 count;
        AclEntryInfo *aclList;
        Server::aclBearer(kind, key).getAcl(haveTag ? tag : NULL, count, aclList);
 {
        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);
-       }
+       CSSM_ACL_ENTRY_INFO_ARRAY aclsArray = { count, aclList };
+       void *acls_data; u_int acls_length;
+       if (!::copyin(&aclsArray, reinterpret_cast<xdrproc_t>(xdr_CSSM_ACL_ENTRY_INFO_ARRAY), &acls_data, &acls_length))
+                       CssmError::throwMe(CSSM_ERRCODE_MEMORY_ERROR);  
        
        
-       // 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);
+       {       // 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);
        }
        }
-       Server::releaseWhenDone(aclsOut.keep());
+       
+       
+       *countp = count; // XXX/cs count becomes part of the blob
+       *aclsLength = acls_length;
+       *acls = acls_data;
+       Server::releaseWhenDone(acls_data);
        END_IPC(CSP)
 }
 
        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))
+kern_return_t ucsp_server_changeAcl(UCSP_ARGS, AclKind kind, IPCKeyHandle key,
+       DATA_IN(cred), CSSM_ACL_EDIT_MODE mode, IPCGenericHandle handle,
+       DATA_IN(acl))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-    relocate(cred, credBase, credLength);
-       relocate(acl, aclBase, aclLength);
-       Server::aclBearer(kind, key).changeAcl(AclEdit(mode, handle, acl), cred);
+       CopyOutAccessCredentials creds(cred, credLength);
+       CopyOutAclEntryInput entryacl(acl, aclLength);
+
+       Server::aclBearer(kind, key).changeAcl(AclEdit(mode, handle, entryacl), creds);
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
@@ -884,10 +1053,10 @@ kern_return_t ucsp_server_changeAcl(UCSP_ARGS, AclKind kind, KeyHandle key,
 //
 // Login/Logout
 //
 //
 // Login/Logout
 //
-kern_return_t ucsp_server_login(UCSP_ARGS, COPY_IN(AccessCredentials, cred), DATA_IN(name))
+kern_return_t ucsp_server_login(UCSP_ARGS, DATA_IN(cred), DATA_IN(name))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(cred, credBase, credLength);
+       CopyOutAccessCredentials creds(cred, credLength);
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
        END_IPC(CSP)
 }
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
        END_IPC(CSP)
 }
@@ -903,7 +1072,7 @@ kern_return_t ucsp_server_logout(UCSP_ARGS)
 //
 // Miscellaneous CSP-related calls
 //
 //
 // Miscellaneous CSP-related calls
 //
-kern_return_t ucsp_server_getStatistics(UCSP_ARGS, uint32 ssid, CSPOperationalStatistics *statistics)
+kern_return_t ucsp_server_getStatistics(UCSP_ARGS, uint32 ssid, CSSM_CSP_OPERATIONAL_STATISTICS *statistics)
 {
        BEGIN_IPC
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
 {
        BEGIN_IPC
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
@@ -935,8 +1104,8 @@ kern_return_t ucsp_server_selfVerify(UCSP_ARGS, uint32 ssid)
 //
 // Passthrough calls (separate for CSP and DL passthroughs)
 //
 //
 // Passthrough calls (separate for CSP and DL passthroughs)
 //
-kern_return_t ucsp_server_cspPassThrough(UCSP_ARGS, uint32 ssid, uint32 id, CONTEXT_ARGS,
-       KeyHandle hKey, DATA_IN(inData), DATA_OUT(outData))
+kern_return_t ucsp_server_cspPassThrough(UCSP_ARGS, uint32 ssid, uint32 id, DATA_IN(context),
+       IPCKeyHandle hKey, DATA_IN(inData), DATA_OUT(outData))
 {
        BEGIN_IPC
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
 {
        BEGIN_IPC
        CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
@@ -957,20 +1126,25 @@ kern_return_t ucsp_server_dlPassThrough(UCSP_ARGS, uint32 ssid, uint32 id,
 // ExtractMasterKey looks vaguely like a key derivation operation, and is in fact
 // presented by the CSPDL's CSSM layer as such.
 //
 // ExtractMasterKey looks vaguely like a key derivation operation, and is in fact
 // presented by the CSPDL's CSSM layer as such.
 //
-kern_return_t ucsp_server_extractMasterKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS, DbHandle sourceDb,
-       COPY_IN(AccessCredentials, cred), COPY_IN(AclEntryPrototype, owner),
-       uint32 usage, uint32 attrs, KeyHandle *newKey, CssmKey::Header *newHeader)
+kern_return_t ucsp_server_extractMasterKey(UCSP_ARGS, IPCDbHandle db, DATA_IN(context), IPCDbHandle sourceDb,
+       DATA_IN(cred), DATA_IN(owner),
+       uint32 usage, uint32 attrs, IPCKeyHandle *newKey, DATA_OUT(keyHeader))
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       context.postIPC(contextBase, attributes);
-    relocate(cred, credBase, credLength);
-       relocate(owner, ownerBase, ownerLength);
+       CopyOutAccessCredentials creds(cred, credLength);
+       CopyOutEntryAcl owneracl(owner, ownerLength);
+       CopyOutContext ctx(context, contextLength);
        RefPointer<KeychainDatabase> keychain = Server::keychain(sourceDb);
        RefPointer<Key> masterKey = keychain->extractMasterKey(
                *Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT),
        RefPointer<KeychainDatabase> keychain = Server::keychain(sourceDb);
        RefPointer<Key> masterKey = keychain->extractMasterKey(
                *Server::optionalDatabase(db, attrs & CSSM_KEYATTR_PERMANENT),
-               cred, owner, usage, attrs);
-       masterKey->returnKey(*newKey, *newHeader);
-       flip(*newHeader);
+               creds, owneracl, usage, attrs);
+       KeyHandle keyHandle;
+       CssmKey::Header header;
+       masterKey->returnKey(keyHandle, header);
+       *newKey = keyHandle;
+       if (!copyin(&header, reinterpret_cast<xdrproc_t> (xdr_CSSM_KEYHEADER), keyHeader, keyHeaderLength))
+               CssmError::throwMe(CSSMERR_CSSM_MEMORY_ERROR);
+       Server::releaseWhenDone(*keyHeader);
        END_IPC(CSP)
 }
 
        END_IPC(CSP)
 }
 
@@ -979,18 +1153,36 @@ kern_return_t ucsp_server_extractMasterKey(UCSP_ARGS, DbHandle db, CONTEXT_ARGS,
 // Authorization subsystem support
 //
 kern_return_t ucsp_server_authorizationCreate(UCSP_ARGS,
 // Authorization subsystem support
 //
 kern_return_t ucsp_server_authorizationCreate(UCSP_ARGS,
-       COPY_IN(AuthorizationItemSet, inRights),
+       void *inRights, mach_msg_type_number_t inRightsLength,
        uint32 flags,
        uint32 flags,
-       COPY_IN(AuthorizationItemSet, inEnvironment),
+       void *inEnvironment, mach_msg_type_number_t inEnvironmentLength,
        AuthorizationBlob *authorization)
 {
        BEGIN_IPC
        AuthorizationBlob *authorization)
 {
        BEGIN_IPC
-       relocate(inRights, inRightsBase, inRightsLength);
-       relocate(inEnvironment, inEnvironmentBase, inEnvironmentLength);
-       Authorization::AuthItemSet rights(inRights), environment(inEnvironment);
+       AuthorizationItemSet *authrights = NULL, *authenvironment = NULL;
+
+       if (inRights && !copyout_AuthorizationItemSet(inRights, inRightsLength, &authrights))
+               CssmError::throwMe(errAuthorizationInternal); // allocation error probably
+
+       if (inEnvironment && !copyout_AuthorizationItemSet(inEnvironment, inEnvironmentLength, &authenvironment))
+       {
+               free(authrights);
+               CssmError::throwMe(errAuthorizationInternal); // allocation error probably
+       }
+
+       Authorization::AuthItemSet rights(authrights), environment(authenvironment);
 
        *rcode = connection.process().session().authCreate(rights, environment, 
                flags, *authorization, auditToken);
 
        *rcode = connection.process().session().authCreate(rights, environment, 
                flags, *authorization, auditToken);
+
+       // @@@ safe-guard against code throw()ing in here
+
+       if (authrights)
+               free(authrights);
+
+       if (authenvironment)
+               free(authenvironment);
+       
        END_IPC(CSSM)
 }
 
        END_IPC(CSSM)
 }
 
@@ -1004,24 +1196,43 @@ kern_return_t ucsp_server_authorizationRelease(UCSP_ARGS,
 
 kern_return_t ucsp_server_authorizationCopyRights(UCSP_ARGS,
        AuthorizationBlob authorization,
 
 kern_return_t ucsp_server_authorizationCopyRights(UCSP_ARGS,
        AuthorizationBlob authorization,
-       COPY_IN(AuthorizationItemSet, inRights),
+       void *inRights, mach_msg_type_number_t inRightsLength,
        uint32 flags,
        uint32 flags,
-       COPY_IN(AuthorizationItemSet, inEnvironment),
-       COPY_OUT(AuthorizationItemSet, result))
+       void *inEnvironment, mach_msg_type_number_t inEnvironmentLength,
+       void **result, mach_msg_type_number_t *resultLength)
 {
        BEGIN_IPC
 {
        BEGIN_IPC
-       relocate(inRights, inRightsBase, inRightsLength);
-       relocate(inEnvironment, inEnvironmentBase, inEnvironmentLength);
-       Authorization::AuthItemSet rights(inRights), environment(inEnvironment), grantedRights;
-       *rcode = connection.process().session().authGetRights(authorization,
-               rights, environment, flags, grantedRights);
+       AuthorizationItemSet *authrights = NULL, *authenvironment = NULL;
+
+       if (inRights && !copyout_AuthorizationItemSet(inRights, inRightsLength, &authrights))
+               CssmError::throwMe(errAuthorizationInternal); // allocation error probably
+
+       if (inEnvironment && !copyout_AuthorizationItemSet(inEnvironment, inEnvironmentLength, &authenvironment))
+       {
+               free(authrights);
+               CssmError::throwMe(errAuthorizationInternal); // allocation error probably
+       }
+
+       Authorization::AuthItemSet rights(authrights), environment(authenvironment), grantedRights;
+       *rcode = Session::authGetRights(authorization, rights, environment, flags, grantedRights);
+
+       // @@@ safe-guard against code throw()ing in here
+
+       if (authrights)
+               free(authrights);
+
+       if (authenvironment)
+               free(authenvironment);
+       
        if (result && resultLength)
        {
        if (result && resultLength)
        {
-               size_t resultSize;
-               grantedRights.copy(*result, resultSize);
-               *resultLength = resultSize;
-               *resultBase = *result;
-               flips(*result, result, resultBase);
+               AuthorizationItemSet *copyout = grantedRights.copy();
+               if (!copyin_AuthorizationItemSet(copyout, result, resultLength))
+               {
+                       free(copyout);
+                       CssmError::throwMe(errAuthorizationInternal);
+               }
+               free(copyout);
                Server::releaseWhenDone(*result);
        }
        END_IPC(CSSM)
                Server::releaseWhenDone(*result);
        }
        END_IPC(CSSM)
@@ -1030,20 +1241,23 @@ kern_return_t ucsp_server_authorizationCopyRights(UCSP_ARGS,
 kern_return_t ucsp_server_authorizationCopyInfo(UCSP_ARGS,
        AuthorizationBlob authorization,
        AuthorizationString tag,
 kern_return_t ucsp_server_authorizationCopyInfo(UCSP_ARGS,
        AuthorizationBlob authorization,
        AuthorizationString tag,
-       COPY_OUT(AuthorizationItemSet, info))
+       void **info, mach_msg_type_number_t *infoLength)
 {
        BEGIN_IPC
     Authorization::AuthItemSet infoSet;
 {
        BEGIN_IPC
     Authorization::AuthItemSet infoSet;
-    *info = *infoBase = NULL;
+    *info = NULL;
     *infoLength = 0;
     *rcode = connection.process().session().authGetInfo(authorization,
         tag[0] ? tag : NULL, infoSet);
     *infoLength = 0;
     *rcode = connection.process().session().authGetInfo(authorization,
         tag[0] ? tag : NULL, infoSet);
-    if (*rcode == noErr) {
-               size_t infoSize;
-               infoSet.copy(*info, infoSize);
-               *infoLength = infoSize;
-               *infoBase = *info;
-               flips(*info, info, infoBase);
+    if (*rcode == noErr)
+       {
+               AuthorizationItemSet *copyout = infoSet.copy();
+               if (!copyin_AuthorizationItemSet(copyout, info, infoLength))
+               {
+                       free(copyout);
+                       CssmError::throwMe(errAuthorizationInternal);
+               }
+               free(copyout);
         Server::releaseWhenDone(*info);
     }
     END_IPC(CSSM)
         Server::releaseWhenDone(*info);
     }
     END_IPC(CSSM)
@@ -1125,25 +1339,13 @@ kern_return_t ucsp_server_setSessionUserPrefs(UCSP_ARGS, SecuritySessionId sessi
 //
 // Notification core subsystem
 //
 //
 // Notification core subsystem
 //
-kern_return_t ucsp_server_requestNotification(UCSP_ARGS, mach_port_t receiver, uint32 domain, uint32 events)
-{
-    BEGIN_IPC
-    connection.process().requestNotifications(receiver, domain, events);
-    END_IPC(CSSM)
-}
-
-kern_return_t ucsp_server_stopNotification(UCSP_ARGS, mach_port_t receiver)
-{
-    BEGIN_IPC
-    connection.process().stopNotifications(receiver);
-    END_IPC(CSSM)
-}
 
 
-kern_return_t ucsp_server_postNotification(mach_port_t serverPort, uint32 domain, uint32 event, DATA_IN(data))
+kern_return_t ucsp_server_postNotification(UCSP_ARGS, uint32 domain, uint32 event,
+       DATA_IN(data), uint32 sequence)
 {
 {
-       BEGIN_IPCS
-               Listener::notify(domain, event, DATA(data));
-       END_IPCS()
+       BEGIN_IPC
+               Listener::notify(domain, event, sequence, DATA(data));
+       END_IPC(CSSM)
 }
 
 
 }
 
 
@@ -1244,3 +1446,59 @@ kern_return_t ucsp_server_childCheckIn(mach_port_t serverPort,
                ServerChild::checkIn(servicePort, TaskPort(taskPort).pid());
        END_IPCS(mach_port_deallocate(mach_task_self(), taskPort))
 }
                ServerChild::checkIn(servicePort, TaskPort(taskPort).pid());
        END_IPCS(mach_port_deallocate(mach_task_self(), taskPort))
 }
+
+
+//
+// Code Signing Hosting registration.
+// Note that the Code Signing Proxy facility (implementing the "cshosting"
+// IPC protocol) is elsewhere.
+//
+kern_return_t ucsp_server_registerHosting(UCSP_ARGS, mach_port_t hostingPort, uint32 flags)
+{
+       BEGIN_IPC
+       connection.process().registerCodeSigning(hostingPort, flags);
+       END_IPC(CSSM)
+}
+
+kern_return_t ucsp_server_hostingPort(UCSP_ARGS, pid_t hostPid, mach_port_t *hostingPort)
+{
+       BEGIN_IPC
+       if (RefPointer<Process> process = Server::active().findPid(hostPid))
+               *hostingPort = process->hostingPort();
+       else
+               *hostingPort = MACH_PORT_NULL;
+       secdebug("hosting", "hosting port for for pid=%d is port %d", hostPid, *hostingPort);
+       END_IPC(CSSM)
+}
+
+
+kern_return_t ucsp_server_setGuest(UCSP_ARGS, SecGuestRef guest, SecCSFlags flags)
+{
+       BEGIN_IPC
+       connection.guestRef(guest, flags);
+       END_IPC(CSSM)
+}
+
+
+kern_return_t ucsp_server_createGuest(UCSP_ARGS, SecGuestRef host,
+       uint32_t status, const char *path, DATA_IN(attributes), SecCSFlags flags, SecGuestRef *newGuest)
+{
+       BEGIN_IPC
+       *newGuest = connection.process().createGuest(host, status, path, DATA(attributes), flags);
+       END_IPC(CSSM)
+}
+
+kern_return_t ucsp_server_setGuestStatus(UCSP_ARGS, SecGuestRef guest,
+       uint32_t status, DATA_IN(attributes))
+{
+       BEGIN_IPC
+       connection.process().setGuestStatus(guest, status, DATA(attributes));
+       END_IPC(CSSM)
+}
+
+kern_return_t ucsp_server_removeGuest(UCSP_ARGS, SecGuestRef host, SecGuestRef guest)
+{
+       BEGIN_IPC
+       connection.process().removeGuest(host, guest);
+       END_IPC(CSSM)
+}
diff --git a/src/transwalkers.cpp b/src/transwalkers.cpp
deleted file mode 100644 (file)
index 2a3055a..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2003-2004 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@
- */
-
-
-//
-// transwalkers - server side transition data walking support
-//
-// These are data walker operators for securely marshaling and unmarshaling
-// data structures across IPC. They are also in charge of fixing byte order
-// inconsistencies between server and clients.
-//
-#include <transwalkers.h>
-       
-
-using LowLevelMemoryUtilities::increment;
-using LowLevelMemoryUtilities::difference;
-
-
-bool flipClient()
-{
-       return Server::process().byteFlipped();
-}
-
-
-//
-// CheckingRelocateWalkers
-//
-CheckingReconstituteWalker::CheckingReconstituteWalker(void *ptr, void *base, size_t size, bool flip)
-       : mBase(base), mFlip(flip)
-{
-       if (mFlip)
-               Flippers::flip(mBase);  // came in reversed; fix for base use
-       mOffset = difference(ptr, mBase);
-       mLimit = increment(mBase, size);
-}
-
-
-//
-// Relocation support
-//
-void relocate(Context &context, void *base, Context::Attr *attrs, uint32 attrSize)
-{
-       flip(context);
-       CheckingReconstituteWalker relocator(attrs, base, attrSize, flipClient());
-       context.ContextAttributes = attrs;      // fix context->attr vector link
-       for (uint32 n = 0; n < context.attributesInUse(); n++)
-               walk(relocator, context[n]);
-}
-
-
-//
-// Outbound flipping support
-//
-FlipWalker::~FlipWalker()
-{
-       for (set<Flipper>::const_iterator it = mFlips.begin(); it != mFlips.end(); it++)
-               delete it->impl;
-}
-
-void FlipWalker::doFlips(bool active)
-{
-       if (active) {
-               secdebug("flipwalkers", "starting outbound flips");
-               for (set<Flipper>::const_iterator it = mFlips.begin(); it != mFlips.end(); it++)
-                       it->impl->flip();
-               secdebug("flipwalkers", "outbound flips done");
-       }
-}
-
-
-//
-// Choose a Database from a choice of two sources, giving preference
-// to persistent stores and to earlier sources.
-//
-Database *pickDb(Database *db1, Database *db2)
-{
-       // persistent db1 always wins
-       if (db1 && !db1->transient())
-               return db1;
-       
-       // persistent db2 is next choice
-       if (db2 && !db2->transient())
-               return db2;
-       
-       // pick any existing transient database
-       if (db1)
-               return db1;
-       if (db2)
-               return db2;
-       
-       // none at all. use the canonical transient store
-       return Server::optionalDatabase(noDb);
-}
-
-
-
-void fixDbAttributes (CssmDbAttributeData &data)
-{
-       /*
-               NOTE TO FUTURE MAINTAINERS OF THIS CODE:
-               
-               This code is called by two different routines; the relocation walker on the input attributes, and flips
-               on the output attributtes.  This is bad, because the relocation walker flips the Info data structure,
-               and flips does not.  We could fix this in flips, but flips is a template and does different things
-               depending on what its parameters are.  As a result, the best place to do this is here.
-       */
-
-       // pull this data out first, so that it is unperverted once the flip occurs
-       unsigned limit = data.size ();
-       unsigned format = data.format ();
-       CssmData* values = data.values ();
-       
-       // flip if it is safe to do so
-       if (format > CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX) // is the format screwed up?
-       {
-               flip (data.info ());
-               limit = data.size ();
-               format = data.format ();
-               values = data.values ();
-       }
-       
-       unsigned i;
-
-       for (i = 0; i < limit; ++i)
-       {
-               switch (format)
-               {
-                       case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
-                               Flippers::flip(*(uint32*) values[i].data ());
-                               break;
-                       
-                       case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
-                       {
-                               CssmData& d = values[i];
-                               int numValues = d.length() / sizeof (UInt32);
-                               int j;
-                               UInt32* v = (UInt32*) d.data();
-                               for (j = 0; j < numValues; ++j)
-                               {
-                                       Flippers::flip (v[j]);
-                               }
-                       }
-                       break;
-               }
-       }
-}
-
-
-
-void fixDbAttributes (CssmQuery &query)
-{
-       unsigned i;
-       unsigned numItems = query.size ();
-       for (i = 0; i < numItems; ++i)
-       {
-               fixDbAttributes(query.predicates()[i].attribute());
-       }
-}
-
-
-
-void fixDbAttributes (CssmDbRecordAttributeData &data)
-{
-       unsigned i;
-       unsigned numItems = data.size ();
-       for (i = 0; i < numItems; ++i)
-       {
-               fixDbAttributes(data.attributes()[i]);
-       }
-}
diff --git a/src/transwalkers.h b/src/transwalkers.h
deleted file mode 100644 (file)
index e9476a7..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (c) 2003-2004 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@
- */
-
-
-//
-// transwalkers - server side transition data walking support
-//
-// These are data walker operators for securely marshaling and unmarshaling
-// data structures across IPC. They are also in charge of fixing byte order
-// inconsistencies between server and clients.
-//
-#ifndef _H_TRANSWALKERS
-#define _H_TRANSWALKERS
-
-#include <security_cdsa_utilities/AuthorizationWalkers.h>
-#include "flippers.h"
-#include "server.h"
-#include <security_cdsa_utilities/context.h>
-       
-using LowLevelMemoryUtilities::increment;
-using LowLevelMemoryUtilities::difference;
-
-
-//
-// Should we flip data?
-// This looks at the current client's process information (a thread-global state)
-// to determine flip status. Valid (only) within BEGIN_IPC/END_IPC brackets.
-//
-bool flipClient();
-
-
-//
-// A CheckingReconstituteWalker is a variant of an ordinary ReconstituteWalker
-// that checks object pointers and sizes against the incoming block limits.
-// It throws an exception if incoming data has pointers outside the incoming block.
-// This avoids trouble inside of securityd caused (by bug or malice)
-// from someone spoofing the client access side.
-//
-class CheckingReconstituteWalker {
-private:
-       void check(void *addr, size_t size)
-       {
-               if (addr < mBase || increment(addr, size) > mLimit)
-                       CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER);
-       }
-
-public:
-    CheckingReconstituteWalker(void *ptr, void *base, size_t size, bool flip);
-       
-       template <class T>
-       void operator () (T &obj, size_t size = sizeof(T))
-       {
-               check(increment(&obj, -mOffset), size);
-               if (mFlip)
-                       Flippers::flip(obj);
-       }
-
-    template <class T>
-    void operator () (T * &addr, size_t size = sizeof(T))
-    {
-               DEBUGWALK("checkreconst:ptr");
-        if (addr) {
-                       // process the pointer
-                       void *p = addr;
-                       blob(p, size);
-                       addr = reinterpret_cast<T *>(p);
-
-                       // now flip the contents
-                       if (mFlip)
-                               Flippers::flip(*addr);
-               }
-    }
-       
-       template <class T>
-       void blob(T * &addr, size_t size)
-       {
-               DEBUGWALK("checkreconst:blob");
-               if (addr) {
-                       // flip the address (the pointer itself)
-                       if (mFlip) {
-                               secdebug("flippers", "flipping %s@%p", Debug::typeName(addr).c_str(), addr);
-                               Flippers::flip(addr);
-                       }
-                       
-                       // check the address against the transmitted bounds
-                       check(addr, size);
-                       
-                       // relocate it
-            addr = increment<T>(addr, mOffset);
-               }
-    }
-       
-    static const bool needsRelinking = true;
-    static const bool needsSize = false;
-    
-private:
-       void *mBase;                    // old base address
-       void *mLimit;                   // old last byte address + 1
-    off_t mOffset;                     // relocation offset
-       bool mFlip;                             // apply byte order flipping
-};
-
-
-//
-// Fix DBAttributes, which have to be processed specially
-//
-void fixDbAttributes (CssmDbAttributeData &data);
-void fixDbAttributes (CssmQuery &query);
-void fixDbAttributes (CssmDbRecordAttributeData &data);
-
-template<class T>
-void fixDbAttributes(T &n) {} // handle the default case
-
-
-//
-// Process an incoming (IPC) data blob of type T.
-// This relocates pointers to fit in the local address space,
-// and fixes byte order issues as needed.
-//
-template <class T>
-void relocate(T *obj, T *base, size_t size)
-{
-    if (obj) {
-               if (base == NULL)       // invalid, could confuse walkers
-                       CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER);
-        CheckingReconstituteWalker relocator(obj, base, size,
-                       Server::process().byteFlipped());
-        walk(relocator, base);
-
-               // resolve weird type interdependency in DB_ATTRIBUTE_DATA
-               if (Server::process().byteFlipped())
-                       fixDbAttributes(*obj);
-    }
-}
-
-
-//
-// Special handling for incoming CSSM contexts.
-//
-void relocate(Context &context, void *base, Context::Attr *attrs, uint32 attrSize);
-
-
-//
-// A FlipWalker is a walker operator that collects its direct invocations
-// into a set of memory objects. These objects can then collectively be
-// byte-flipped (exactly once :-) at the flick of a method.
-//
-class FlipWalker {
-private:
-       struct Base {
-               virtual ~Base() { }
-               virtual void flip() const = 0;
-       };
-
-       template <class T>
-       struct FlipRef : public Base {
-               T &obj;
-               FlipRef(T &s) : obj(s)          { }
-               void flip() const                       { Flippers::flip(obj); }
-       };
-
-       template <class T>
-       struct FlipPtr : public Base {
-               T * &obj;
-               FlipPtr(T * &s) : obj(s)        { }
-               void flip() const                       { Flippers::flip(*obj); Flippers::flip(obj); }
-       };
-
-       template <class T>
-       struct FlipBlob : public Base {
-               T * &obj;
-               FlipBlob(T * &s) : obj(s)       { }
-               void flip() const                       { Flippers::flip(obj); }
-       };
-       
-       struct Flipper {
-               Base *impl;
-               Flipper(Base *p) : impl(p)      { }
-               bool operator < (const Flipper &other) const
-                       { return impl < other.impl; }
-       };
-       
-public:
-       ~FlipWalker();
-       void doFlips(bool active = true);
-       
-       template <class T>
-       void operator () (T &obj, size_t = sizeof(T))
-       { mFlips.insert(new FlipRef<T>(obj)); }
-       
-       template <class T>
-       T *operator () (T * &addr, size_t size = sizeof(T))
-       { mFlips.insert(new FlipPtr<T>(addr)); return addr; }
-       
-       template <class T>
-       void blob(T * &addr, size_t size)
-       { mFlips.insert(new FlipBlob<T>(addr)); }
-       
-       static const bool needsRelinking = true;
-       static const bool needsSize = true;
-       
-private:
-       set<Flipper> mFlips;
-};
-
-
-//
-// A raw flip, conditioned on the client's flip state
-//
-template <class T>
-void flip(T &addr)
-{
-       if (flipClient()) {
-               secdebug("flippers", "raw flipping %s", Debug::typeName(addr).c_str());
-               Flippers::flip(addr);
-       }
-}
-
-
-void flipCssmDbAttributeData (CssmDbRecordAttributeData *value, CssmDbRecordAttributeData **&addr, CssmDbRecordAttributeData **&base);
-
-//
-// Take an object at value, flip it, and return appropriately flipped
-// addr/base pointers ready to be returned through IPC.
-// Note that this doesn't set the outgoing length (aka 'fooLength') field.
-//
-template <class T>
-void flips(T *value, T ** &addr, T ** &base)
-{
-       *addr = *base = value;
-       if (flipClient()) {
-               // resolve weird type inter-dependency in DB_ATTRIBUTE_DATA
-               if (value)
-                       fixDbAttributes(*value);
-               FlipWalker w;           // collector
-               walk(w, value);         // collect all flippings needed
-               w.doFlips();            // execute flips (flips value but leaves addr alone)
-               Flippers::flip(*base); // flip base (so it arrives right side up)
-       }
-}
-
-//
-// Take a DATA type RPC argument purportedly representing a Blob of some kind,
-// turn it into a Blob, and fail properly if it's not kosher.
-//
-template <class BlobType>
-const BlobType *makeBlob(const CssmData &blobData, CSSM_RETURN error = CSSM_ERRCODE_INVALID_DATA)
-{
-       if (!blobData.data() || blobData.length() < sizeof(BlobType))
-               CssmError::throwMe(error);
-       const BlobType *blob = static_cast<const BlobType *>(blobData.data());
-       if (blob->totalLength != blobData.length())
-               CssmError::throwMe(error);
-       return blob;
-}
-
-
-//
-// An OutputData object will take memory allocated within securityd,
-// hand it to the MIG return-output parameters, and schedule it to be released
-// after the MIG reply has been sent. It will also get rid of it in case of
-// error.
-//
-class OutputData : public CssmData {
-public:
-       OutputData(void **outP, mach_msg_type_number_t *outLength)
-               : mData(*outP), mLength(*outLength) { }
-       ~OutputData()
-       { mData = data(); mLength = length(); Server::releaseWhenDone(mData); }
-    
-    void operator = (const CssmData &source)
-    { CssmData::operator = (source); }
-       
-private:
-       void * &mData;
-       mach_msg_type_number_t &mLength;
-};
-
-
-//
-// Choose a Database from a choice of two sources, giving preference
-// to persistent stores and to earlier sources.
-//
-Database *pickDb(Database *db1, Database *db2);
-
-static inline Database *dbOf(Key *key) { return key ? &key->database() : NULL; }
-
-inline Database *pickDb(Key *k1, Key *k2) { return pickDb(dbOf(k1), dbOf(k2)); }
-inline Database *pickDb(Database *db1, Key *k2) { return pickDb(db1, dbOf(k2)); }
-inline Database *pickDb(Key *k1, Database *db2) { return pickDb(dbOf(k1), db2); }
-
-
-#endif //_H_TRANSWALKERS