]> git.saurik.com Git - apple/security.git/blob - libsecurity_cdsa_utilities/lib/aclsubject.h
Security-55179.11.tar.gz
[apple/security.git] / libsecurity_cdsa_utilities / lib / aclsubject.h
1 /*
2 * Copyright (c) 2000-2004,2006 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 //
26 // aclsubject - abstract ACL subject implementation
27 //
28 #ifndef _ACLSUBJECT
29 #define _ACLSUBJECT
30
31 #include <security_cdsa_utilities/cssmaclpod.h>
32 #include <security_cdsa_utilities/cssmcred.h>
33 #include <security_utilities/refcount.h>
34 #include <security_utilities/globalizer.h>
35 #include <security_utilities/memutils.h>
36 #include <security_utilities/adornments.h>
37 #include <map>
38 #include <set>
39 #include <string>
40 #include <limits.h>
41
42
43 namespace Security {
44
45 class ObjectAcl;
46 class AclValidationContext;
47 class AclSubject;
48
49
50 //
51 // An AclValidationEnvironment can be subclassed to add context access to ACL subject
52 // validation. If you use ACL subject classes that need context beyond the credential
53 // structure itself, add that context to (a virtual subclass of) AclValidationContext, pass that
54 // to ObjectAcl::validate() along with the credentials, and have the Subject implementation
55 // access validationContext.environment().
56 //
57 class AclValidationEnvironment {
58 friend class AclValidationContext;
59 public:
60 virtual ~AclValidationEnvironment(); // ensure virtual methods (need dynamic_cast)
61
62 // provide an Adornable for a given subject to store data in, or throw if none available (default)
63 virtual Adornable &store(const AclSubject *subject);
64 };
65
66
67 //
68 // An AclValidationContext holds all context for an ACL evaluation in one
69 // package. It's designed to provide a uniform representation of credentials, plus
70 // any (trusted path and/or implicit) context information useful for ACL validation.
71 //
72 // Contexts are immutable (constant) for validators; they do not change at all
73 // during a validation exercise. Anything that should be mutable must go into
74 // the environment (which is indirect and modifyable).
75 //
76 class AclValidationContext {
77 friend class ObjectAcl;
78 public:
79 AclValidationContext(const AccessCredentials *cred,
80 AclAuthorization auth, AclValidationEnvironment *env = NULL)
81 : mCred(cred), mAuth(auth), mEnv(env), mEntryTag(NULL) { }
82 AclValidationContext(const AclValidationContext &ctx)
83 : mAcl(ctx.mAcl), mSubject(ctx.mSubject), mCred(ctx.mCred),
84 mAuth(ctx.mAuth), mEnv(ctx.mEnv), mEntryTag(NULL) { }
85 virtual ~AclValidationContext();
86
87 // access to (suitably focused) sample set
88 virtual uint32 count() const = 0; // number of samples
89 uint32 size() const { return count(); } // alias
90 virtual const TypedList &sample(uint32 n) const = 0; // retrieve one sample
91 const TypedList &operator [] (uint32 n) const { return sample(n); }
92
93 // context access
94 AclAuthorization authorization() const { return mAuth; }
95 const AccessCredentials *cred() const { return mCred; }
96 AclValidationEnvironment *environment() const { return mEnv; }
97 template <class Env> Env *environment() const { return dynamic_cast<Env *>(mEnv); }
98 AclSubject *subject() const { return mSubject; }
99 ObjectAcl *acl() const { return mAcl; }
100
101 // tag manipulation
102 virtual const char *credTag() const;
103 virtual const char *entryTag() const;
104 std::string s_credTag() const;
105 void entryTag(const char *tag);
106 void entryTag(const std::string &tag);
107
108 // selective match support - not currently implemented
109 virtual void matched(const TypedList *match) const = 0;
110 void matched(const TypedList &match) const { return matched(&match); }
111
112 private:
113 void init(ObjectAcl *acl, AclSubject *subject);
114
115 private:
116 ObjectAcl *mAcl; // underlying ObjectAcl
117 AclSubject *mSubject; // subject being validated
118 const AccessCredentials *mCred; // original credentials
119 AclAuthorization mAuth; // action requested
120 AclValidationEnvironment *mEnv; // environmental context (if any)
121 const char *mEntryTag; // entry tag
122 };
123
124
125 //
126 // The AclSubject class models an ACL "subject" object. If you have a new ACL
127 // subject type or variant, you make a subclass of this (plus a suitable Maker).
128 //
129 // Note that AclSubjects can contain both configuration and state information.
130 // Configuration is set during AclSubject creation (passwords to check against,
131 // evaluation options, etc.) and are typically passed on in the externalized form;
132 // it is persistent.
133 // On the other hand, state is volatile and is lost when the AclSubject dies.
134 // This is stuff that accumulates during a particular lifetime, such as results
135 // of previous evaluations (for caching or more nefarious purposes).
136 // Be clear what each of your subclass members are, and document accordingly.
137 //
138 class AclSubject : public RefCount {
139 public:
140 typedef LowLevelMemoryUtilities::Writer Writer;
141 typedef LowLevelMemoryUtilities::Reader Reader;
142
143 typedef uint8 Version; // binary version marker
144 static const int versionShift = 24; // highest-order byte of type is version
145 static const uint32 versionMask = 0xff000000;
146
147 public:
148 explicit AclSubject(uint32 type, Version v = 0);
149 virtual ~AclSubject();
150 CSSM_ACL_SUBJECT_TYPE type() const { return mType; }
151
152 // validation (evaluation) primitive
153 virtual bool validate(const AclValidationContext &ctx) const = 0;
154
155 // export to CSSM interface
156 virtual CssmList toList(Allocator &alloc) const = 0;
157
158 // export/import for save/restore interface
159 virtual void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
160 virtual void exportBlob(Writer &pub, Writer &priv);
161 virtual void importBlob(Reader &pub, Reader &priv);
162
163 // binary compatibility version management. The version defaults to zero
164 Version version() const { return mVersion; }
165
166 // forget any validation-related state you have acquired
167 virtual void reset();
168
169 // debug suupport (dummied out but present for -UDEBUGDUMP)
170 virtual void debugDump() const;
171 IFDUMP(void dump(const char *title) const);
172
173 protected:
174 void version(Version v) { mVersion = v; }
175
176 private:
177 CSSM_ACL_SUBJECT_TYPE mType;
178 Version mVersion;
179
180 public:
181 class Maker {
182 public:
183 Maker(CSSM_ACL_SUBJECT_TYPE type);
184 virtual ~Maker();
185
186 uint32 type() const { return mType; }
187 virtual AclSubject *make(const TypedList &list) const = 0;
188 virtual AclSubject *make(Version version, Reader &pub, Reader &priv) const = 0;
189
190 protected:
191 // list parsing helpers
192 static void crack(const CssmList &list, uint32 count,
193 ListElement **array = NULL, ...);
194 static CSSM_WORDID_TYPE getWord(const ListElement &list,
195 int min = 0, int max = INT_MAX);
196
197 private:
198 CSSM_ACL_SUBJECT_TYPE mType;
199 };
200 };
201
202
203 //
204 // A SimpleAclSubject validates a credential by scanning its samples
205 // one at a time, without any interactions between them. Thus its validate()
206 // can be a lot simpler.
207 // Note that this layer assumes that subject and sample types have the same
208 // value, as is typical when both are derived from a WORDID.
209 //
210 class SimpleAclSubject : public AclSubject {
211 public:
212 SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE type) : AclSubject(type) { }
213
214 bool validate(const AclValidationContext &ctx) const;
215 virtual bool validate(const AclValidationContext &baseCtx,
216 const TypedList &sample) const = 0;
217 };
218
219
220 } // end namespace Security
221
222
223 #endif //_ACLSUBJECT