]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_cdsa_utilities/lib/aclsubject.h
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_utilities / lib / aclsubject.h
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2000-2004,2006,2011,2013-2014 Apple Inc. All Rights Reserved.
b1ab9ed8
A
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>
fa7225c8 37#include <security_utilities/debugging_internal.h>
b1ab9ed8
A
38#include <map>
39#include <set>
40#include <string>
41#include <limits.h>
42
43
44namespace Security {
45
46class ObjectAcl;
47class AclValidationContext;
48class AclSubject;
49
50
51//
52// An AclValidationEnvironment can be subclassed to add context access to ACL subject
53// validation. If you use ACL subject classes that need context beyond the credential
54// structure itself, add that context to (a virtual subclass of) AclValidationContext, pass that
55// to ObjectAcl::validate() along with the credentials, and have the Subject implementation
56// access validationContext.environment().
57//
58class AclValidationEnvironment {
59 friend class AclValidationContext;
60public:
61 virtual ~AclValidationEnvironment(); // ensure virtual methods (need dynamic_cast)
62
63 // provide an Adornable for a given subject to store data in, or throw if none available (default)
64 virtual Adornable &store(const AclSubject *subject);
e3d460c9
A
65
66 // special-purpose bypass (force validation to succeed)
67 bool forceSuccess = false;
b1ab9ed8
A
68};
69
70
71//
72// An AclValidationContext holds all context for an ACL evaluation in one
73// package. It's designed to provide a uniform representation of credentials, plus
74// any (trusted path and/or implicit) context information useful for ACL validation.
75//
76// Contexts are immutable (constant) for validators; they do not change at all
77// during a validation exercise. Anything that should be mutable must go into
78// the environment (which is indirect and modifyable).
79//
80class AclValidationContext {
81 friend class ObjectAcl;
82public:
83 AclValidationContext(const AccessCredentials *cred,
84 AclAuthorization auth, AclValidationEnvironment *env = NULL)
427c49bc
A
85 : mAcl((ObjectAcl*) 0xDEADDEADDEADDEAD), mSubject((AclSubject*) 0xDEADDEADDEADDEAD), mCred(cred),
86 mAuth(auth), mEnv(env), mEntryTag(NULL) { }
b1ab9ed8
A
87 AclValidationContext(const AclValidationContext &ctx)
88 : mAcl(ctx.mAcl), mSubject(ctx.mSubject), mCred(ctx.mCred),
89 mAuth(ctx.mAuth), mEnv(ctx.mEnv), mEntryTag(NULL) { }
90 virtual ~AclValidationContext();
91
92 // access to (suitably focused) sample set
93 virtual uint32 count() const = 0; // number of samples
94 uint32 size() const { return count(); } // alias
95 virtual const TypedList &sample(uint32 n) const = 0; // retrieve one sample
96 const TypedList &operator [] (uint32 n) const { return sample(n); }
97
98 // context access
99 AclAuthorization authorization() const { return mAuth; }
100 const AccessCredentials *cred() const { return mCred; }
101 AclValidationEnvironment *environment() const { return mEnv; }
102 template <class Env> Env *environment() const { return dynamic_cast<Env *>(mEnv); }
103 AclSubject *subject() const { return mSubject; }
104 ObjectAcl *acl() const { return mAcl; }
105
106 // tag manipulation
107 virtual const char *credTag() const;
108 virtual const char *entryTag() const;
109 std::string s_credTag() const;
110 void entryTag(const char *tag);
111 void entryTag(const std::string &tag);
112
113 // selective match support - not currently implemented
114 virtual void matched(const TypedList *match) const = 0;
115 void matched(const TypedList &match) const { return matched(&match); }
116
117private:
118 void init(ObjectAcl *acl, AclSubject *subject);
119
120private:
121 ObjectAcl *mAcl; // underlying ObjectAcl
122 AclSubject *mSubject; // subject being validated
123 const AccessCredentials *mCred; // original credentials
124 AclAuthorization mAuth; // action requested
125 AclValidationEnvironment *mEnv; // environmental context (if any)
126 const char *mEntryTag; // entry tag
127};
e3d460c9
A
128
129
130//
131// An AclValidationContext that simply presents all top-level credentials
132// to all subjects.
133//
134class BaseValidationContext : public AclValidationContext {
135public:
136 BaseValidationContext(const AccessCredentials *cred,
137 AclAuthorization auth, AclValidationEnvironment *env)
138 : AclValidationContext(cred, auth, env) { }
139
140 uint32 count() const { return cred() ? cred()->samples().length() : 0; }
141 uint32 size() const { return count(); }
142 const TypedList &sample(uint32 n) const
143 { assert(n < count()); return cred()->samples()[n]; }
144
145 void matched(const TypedList *) const { } // ignore match info
146};
b1ab9ed8
A
147
148
149//
150// The AclSubject class models an ACL "subject" object. If you have a new ACL
151// subject type or variant, you make a subclass of this (plus a suitable Maker).
152//
153// Note that AclSubjects can contain both configuration and state information.
154// Configuration is set during AclSubject creation (passwords to check against,
155// evaluation options, etc.) and are typically passed on in the externalized form;
156// it is persistent.
157// On the other hand, state is volatile and is lost when the AclSubject dies.
158// This is stuff that accumulates during a particular lifetime, such as results
159// of previous evaluations (for caching or more nefarious purposes).
160// Be clear what each of your subclass members are, and document accordingly.
161//
162class AclSubject : public RefCount {
163public:
164 typedef LowLevelMemoryUtilities::Writer Writer;
165 typedef LowLevelMemoryUtilities::Reader Reader;
166
167 typedef uint8 Version; // binary version marker
168 static const int versionShift = 24; // highest-order byte of type is version
169 static const uint32 versionMask = 0xff000000;
170
171public:
172 explicit AclSubject(uint32 type, Version v = 0);
173 virtual ~AclSubject();
174 CSSM_ACL_SUBJECT_TYPE type() const { return mType; }
175
176 // validation (evaluation) primitive
e3d460c9 177 virtual bool validates(const AclValidationContext &ctx) const = 0;
b1ab9ed8
A
178
179 // export to CSSM interface
180 virtual CssmList toList(Allocator &alloc) const = 0;
181
182 // export/import for save/restore interface
183 virtual void exportBlob(Writer::Counter &pub, Writer::Counter &priv);
184 virtual void exportBlob(Writer &pub, Writer &priv);
185 virtual void importBlob(Reader &pub, Reader &priv);
186
187 // binary compatibility version management. The version defaults to zero
188 Version version() const { return mVersion; }
189
190 // forget any validation-related state you have acquired
191 virtual void reset();
192
193 // debug suupport (dummied out but present for -UDEBUGDUMP)
194 virtual void debugDump() const;
195 IFDUMP(void dump(const char *title) const);
196
197protected:
198 void version(Version v) { mVersion = v; }
199
200private:
201 CSSM_ACL_SUBJECT_TYPE mType;
202 Version mVersion;
203
204public:
205 class Maker {
206 public:
207 Maker(CSSM_ACL_SUBJECT_TYPE type);
208 virtual ~Maker();
209
210 uint32 type() const { return mType; }
211 virtual AclSubject *make(const TypedList &list) const = 0;
212 virtual AclSubject *make(Version version, Reader &pub, Reader &priv) const = 0;
213
214 protected:
215 // list parsing helpers
216 static void crack(const CssmList &list, uint32 count,
217 ListElement **array = NULL, ...);
218 static CSSM_WORDID_TYPE getWord(const ListElement &list,
219 int min = 0, int max = INT_MAX);
220
221 private:
222 CSSM_ACL_SUBJECT_TYPE mType;
223 };
224};
225
226
227//
228// A SimpleAclSubject validates a credential by scanning its samples
229// one at a time, without any interactions between them. Thus its validate()
230// can be a lot simpler.
231// Note that this layer assumes that subject and sample types have the same
232// value, as is typical when both are derived from a WORDID.
233//
234class SimpleAclSubject : public AclSubject {
235public:
236 SimpleAclSubject(CSSM_ACL_SUBJECT_TYPE type) : AclSubject(type) { }
237
e3d460c9
A
238 virtual bool validates(const AclValidationContext &ctx) const;
239 virtual bool validates(const AclValidationContext &baseCtx,
b1ab9ed8
A
240 const TypedList &sample) const = 0;
241};
242
243
244} // end namespace Security
245
246
247#endif //_ACLSUBJECT