1/*
2 * Copyright (c) 2002-2004 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24//
25// ACL.h - ACL control wrappers
26//
27#ifndef _SECURITY_ACL_H_
28#define _SECURITY_ACL_H_
29
30#include <Security/SecACL.h>
31#include <security_cdsa_utilities/cssmaclpod.h>
32#include <security_cdsa_client/aclclient.h>
33#include <security_cdsa_utilities/cssmdata.h>
34#include <security_utilities/seccfobject.h>
35#include "SecCFTypes.h"
36
37#include <vector>
38
39namespace Security {
40namespace KeychainCore {
41
42using CssmClient::AclBearer;
43
44class Access;
45class TrustedApplication;
46
47
48//
49// An ACL Entry for an Access object
50//
51class ACL : public SecCFObject {
52	NOCOPY(ACL)
53public:
54	SECCFFUNCTIONS(ACL, SecACLRef, errSecInvalidItemRef, gTypes().ACL)
55
56	// create from CSSM layer ACL entry
57	ACL(Access &acc, const AclEntryInfo &info,
58		Allocator &alloc = Allocator::standard());
59	// create from CSSM layer owner prototype
60	ACL(Access &acc, const AclOwnerPrototype &owner,
61		Allocator &alloc = Allocator::standard());
62	// create an "any" ACL
63	ACL(Access &acc, Allocator &alloc = Allocator::standard());
64	// create from "standard form" arguments (with empty application list)
65	ACL(Access &acc, string description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR &promptSelector,
66		Allocator &alloc = Allocator::standard());
67    virtual ~ACL();
68
69	Allocator &allocator;
70
71	enum State {
72		unchanged,					// unchanged from source
73		inserted,					// new
74		modified,					// was changed (replace)
75		deleted						// was deleted (now invalid)
76	};
77	State state() const { return mState; }
78
79	enum Form {
80		invalidForm,				// invalid
81		customForm,					// not a recognized format (but valid)
82		allowAllForm,				// indiscriminate
83		appListForm					// list of apps + prompt confirm
84	};
85	Form form() const { return mForm; }
86	void form(Form f) { mForm = f; }
87
88	Access &access;					// we belong to this Access
89
90public:
91	AclAuthorizationSet &authorizations()	{ return mAuthorizations; }
92	bool authorizes(AclAuthorization right);
93	void setAuthorization(CSSM_ACL_AUTHORIZATION_TAG auth)
94	{ mAuthorizations.clear(); mAuthorizations.insert(auth); }
95
96	typedef vector< SecPointer<TrustedApplication> > ApplicationList;
97	ApplicationList &applications()
98	{ assert(form() == appListForm); return mAppList; }
99	void addApplication(TrustedApplication *app);
100
101	CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR &promptSelector()	{ return mPromptSelector; }
102	string &promptDescription()							{ return mPromptDescription; }
103
104	CSSM_ACL_HANDLE entryHandle() const	{ return mCssmHandle; }
105
106	static const CSSM_ACL_HANDLE ownerHandle = 0xff0e2743;	// pseudo-handle for owner ACL
107	bool isOwner() const			{ return mCssmHandle == ownerHandle; }
108	void makeOwner()				{ mCssmHandle = ownerHandle; }
109
110	void modify();					// mark modified (update on commit)
111	void remove();					// mark removed (delete on commit)
112
113	// produce chunk copies of CSSM forms; caller takes ownership
114	void copyAclEntry(AclEntryPrototype &proto, Allocator &alloc = Allocator::standard());
115	void copyAclOwner(AclOwnerPrototype &proto, Allocator &alloc = Allocator::standard());
116
117public:
118	void setAccess(AclBearer &target, bool update = false,
119		const AccessCredentials *cred = NULL);
120
121public:
122	struct ParseError { };
123
124public:
125	static const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR defaultSelector;
126
127private:
128	void parse(const TypedList &subject);
129	void parsePrompt(const TypedList &subject);
130	void makeSubject();
131	void clearSubjects(Form newForm);
132
133private:
134	State mState;					// change state
135	Form mForm;						// format type
136
137	// AclEntryPrototype fields (minus subject, which is virtually constructed)
138	CSSM_ACL_HANDLE mCssmHandle;	// CSSM entry handle (for updates)
139	string mEntryTag;				// CSSM entry tag (64 bytes or so, they say)
140	bool mDelegate;					// CSSM delegate flag
141	AclAuthorizationSet mAuthorizations; // rights for this ACL entry
142
143	// composite AclEntryPrototype (constructed when needed)
144	TypedList *mSubjectForm;
145
146	// following values valid only if form() == appListForm
147	ApplicationList mAppList;		// list of trusted applications
148	CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR mPromptSelector; // selector field of PROMPT subject
149	string mPromptDescription;		// description field of PROMPT subject
150	Mutex mMutex;
151};
152
153
154} // end namespace KeychainCore
155} // end namespace Security
156
157#endif // !_SECURITY_ACL_H_
158