72d24643028f92aad7741e482d777878b9f5207a
[shibboleth/cpp-opensaml.git] / saml / binding / SecurityPolicy.h
1 /*
2  *  Copyright 2001-2009 Internet2
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file saml/binding/SecurityPolicy.h
19  *
20  * Overall policy used to verify the security of an incoming message.
21  */
22
23 #ifndef __saml_secpol_h__
24 #define __saml_secpol_h__
25
26 #include <saml/saml2/metadata/MetadataProvider.h>
27
28 #include <ctime>
29 #include <vector>
30 #include <xmltooling/io/GenericRequest.h>
31 #include <xmltooling/security/TrustEngine.h>
32
33 #if defined (_MSC_VER)
34     #pragma warning( push )
35     #pragma warning( disable : 4250 4251 )
36 #endif
37
38 namespace opensaml {
39
40     namespace saml2 {
41         class SAML_API Issuer;
42     };
43
44     class SAML_API SecurityPolicyRule;
45
46     /**
47      * A policy used to verify the security of an incoming message.
48      *
49      * <p>Its security mechanisms may be used to examine the transport layer
50      * (e.g client certificates and HTTP basic auth passwords) or to check the
51      * payload of a request to ensure it meets certain criteria (e.g. valid
52      * digital signature, freshness, replay).
53      *
54      * <p>Policy objects can be reused, but are not thread-safe.
55      */
56     class SAML_API SecurityPolicy
57     {
58         MAKE_NONCOPYABLE(SecurityPolicy);
59     public:
60         /**
61          * Constructor for policy.
62          *
63          * @param metadataProvider  locked MetadataProvider instance
64          * @param role              identifies the role (generally IdP or SP) of the policy peer
65          * @param trustEngine       TrustEngine to authenticate policy peer
66          * @param validate          true iff XML parsing should be done with validation
67          */
68         SecurityPolicy(
69             const saml2md::MetadataProvider* metadataProvider=NULL,
70             const xmltooling::QName* role=NULL,
71             const xmltooling::TrustEngine* trustEngine=NULL,
72             bool validate=true
73             ) : m_metadataCriteria(NULL), m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL), m_authenticated(false),
74                 m_matchingPolicy(NULL), m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine), m_validate(validate), m_entityOnly(true) {
75             if (role)
76                 m_role = new xmltooling::QName(*role);
77         }
78
79         virtual ~SecurityPolicy();
80
81         /**
82          * Returns the locked MetadataProvider supplied to the policy.
83          *
84          * @return the supplied MetadataProvider or NULL
85          */
86         const saml2md::MetadataProvider* getMetadataProvider() const {
87             return m_metadata;
88         }
89
90         /**
91          * Returns a reference to a MetadataProvider::Criteria instance suitable for use with the
92          * installed MetadataProvider.
93          *
94          * <p>The object will be cleared/reset when returned, so do not mutate it and then
95          * call the method again before using it.
96          *
97          * @return reference to a MetadataProvider::Criteria instance
98          */
99         virtual saml2md::MetadataProvider::Criteria& getMetadataProviderCriteria() const;
100
101         /**
102          * Returns the peer role element/type supplied to the policy.
103          *
104          * @return the peer role element/type, or an empty QName
105          */
106         const xmltooling::QName* getRole() const {
107             return m_role;
108         }
109
110         /**
111          * Returns the TrustEngine supplied to the policy.
112          *
113          * @return the supplied TrustEngine or NULL
114          */
115         const xmltooling::TrustEngine* getTrustEngine() const {
116             return m_trust;
117         }
118
119         /**
120          * Returns XML message validation setting.
121          *
122          * @return validation flag
123          */
124         bool getValidating() const {
125             return m_validate;
126         }
127
128         /**
129          * Returns flag controlling non-entity issuer support.
130          *
131          * @return flag controlling non-entity issuer support
132          */
133         bool requireEntityIssuer() const {
134             return m_entityOnly;
135         }
136
137         /**
138          * Gets a mutable array of installed policy rules.
139          *
140          * <p>If adding rules, their lifetime must be at least as long as the policy object.
141          *
142          * @return  mutable array of rules
143          */
144         std::vector<const SecurityPolicyRule*>& getRules() {
145             return m_rules;
146         }
147
148         /**
149          * Sets a locked MetadataProvider for the policy.
150          *
151          * @param metadata a locked MetadataProvider or NULL
152          */
153         void setMetadataProvider(const saml2md::MetadataProvider* metadata) {
154             m_metadata = metadata;
155         }
156
157         /**
158          * Sets a MetadataProvider::Criteria instance suitable for use with the
159          * installed MetadataProvider.
160          *
161          * <p>The policy will take ownership of the criteria object when this
162          * method completes.
163          *
164          * @param criteria a MetadataProvider::Criteria instance, or NULL
165          */
166         void setMetadataProviderCriteria(saml2md::MetadataProvider::Criteria* criteria);
167
168         /**
169          * Sets a peer role element/type for to the policy.
170          *
171          * @param role the peer role element/type or NULL
172          */
173         void setRole(const xmltooling::QName* role) {
174             delete m_role;
175             m_role = role ? new xmltooling::QName(*role) : NULL;
176         }
177
178         /**
179          * Sets a TrustEngine for the policy.
180          *
181          * @param trust a TrustEngine or NULL
182          */
183         void setTrustEngine(const xmltooling::TrustEngine* trust) {
184             m_trust = trust;
185         }
186
187         /**
188          * Controls schema validation of incoming XML messages.
189          * This is separate from other forms of programmatic validation of objects,
190          * but can detect a much wider range of syntax errors.
191          *
192          * @param validate  validation setting
193          */
194         void setValidating(bool validate=true) {
195             m_validate = validate;
196         }
197
198         /**
199          * Sets flag controlling non-entity issuer support.
200          *
201          * @param entityOnly require that Issuer be in entity format
202          */
203         void requireEntityIssuer(bool entityOnly=true) {
204             m_entityOnly = entityOnly;
205         }
206
207         /**
208          * Evaluates the policy against the given request and message,
209          * possibly populating message information in the policy object.
210          *
211          * @param message           the incoming message
212          * @param request           the protocol request
213          *
214          * @throws BindingException raised if the message/request is invalid according to the supplied rules
215          */
216         void evaluate(
217             const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request=NULL
218             );
219
220         /**
221          * Resets the policy object and/or clears any per-message state.
222          *
223          * <p>Resets can be complete (the default) or merely clear the previous message ID and timestamp
224          * when evaluating multiple layers of a message.
225          *
226          * @param messageOnly   true iff security and issuer state should be left in place
227          */
228         virtual void reset(bool messageOnly=false);
229
230         /**
231          * Resets the policy object and/or clears any per-message state for only this specific class.
232          *
233          * <p>Resets can be complete (the default) or merely clear the previous message ID and timestamp
234          * when evaluating multiple layers of a message.
235          *
236          * @param messageOnly   true iff security and issuer state should be left in place
237          */
238         void _reset(bool messageOnly=false);
239
240         /**
241          * Returns the message identifier as determined by the registered policies.
242          *
243          * @return message identifier as determined by the registered policies
244          */
245         const XMLCh* getMessageID() const {
246             return m_messageID;
247         }
248
249         /**
250          * Returns the message timestamp as determined by the registered policies.
251          *
252          * @return message timestamp as determined by the registered policies
253          */
254         time_t getIssueInstant() const {
255             return m_issueInstant;
256         }
257
258         /**
259          * Gets the issuer of the message as determined by the registered policies.
260          *
261          * @return issuer of the message as determined by the registered policies
262          */
263         const saml2::Issuer* getIssuer() const {
264             return m_issuer;
265         }
266
267         /**
268          * Gets the metadata for the role the issuer is operating in.
269          *
270          * @return metadata for the role the issuer is operating in
271          */
272         const saml2md::RoleDescriptor* getIssuerMetadata() const {
273             return m_issuerRole;
274         }
275
276         /**
277          * Returns the authentication status of the message as determined by the registered policies.
278          *
279          * @return true iff a SecurityPolicyRule has indicated the issuer/message has been authenticated
280          */
281         bool isAuthenticated() const {
282             return m_authenticated;
283         }
284
285         /**
286          * Sets the message identifier as determined by the registered policies.
287          *
288          * @param id message identifier
289          */
290         void setMessageID(const XMLCh* id) {
291             xercesc::XMLString::release(&m_messageID);
292             m_messageID = xercesc::XMLString::replicate(id);
293         }
294
295         /**
296          * Sets the message timestamp as determined by the registered policies.
297          *
298          * @param issueInstant message timestamp
299          */
300         void setIssueInstant(time_t issueInstant) {
301             m_issueInstant = issueInstant;
302         }
303
304         /**
305          * Sets the issuer of the message as determined by the registered policies.
306          *
307          * @param issuer issuer of the message
308          */
309         void setIssuer(const saml2::Issuer* issuer);
310
311         /**
312          * Sets the issuer of the message as determined by the registered policies.
313          *
314          * @param issuer issuer of the message
315          */
316         void setIssuer(const XMLCh* issuer);
317
318         /**
319          * Sets the metadata for the role the issuer is operating in.
320          *
321          * @param issuerRole metadata for the role the issuer is operating in
322          */
323         void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
324
325         /**
326          * Sets the authentication status of the message as determined by the registered policies.
327          *
328          * @param auth indicates whether the issuer/message has been authenticated
329          */
330         void setAuthenticated(bool auth) {
331             m_authenticated = auth;
332         }
333
334         /** Allows override of rules for comparing saml2:Issuer information. */
335         class SAML_API IssuerMatchingPolicy {
336             MAKE_NONCOPYABLE(IssuerMatchingPolicy);
337         public:
338             IssuerMatchingPolicy() {}
339             virtual ~IssuerMatchingPolicy() {}
340
341             /**
342              * Returns true iff the two operands "match". Applications can override this method to
343              * support non-standard issuer matching for complex policies.
344              *
345              * <p>The default implementation does a basic comparison of the XML content, treating
346              * an unsupplied Format as an "entityID".
347              *
348              * @param issuer1   the first Issuer to match
349              * @param issuer2   the second Issuer to match
350              * @return  true iff the operands match
351              */
352             virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
353
354             /**
355              * Returns true iff the two operands "match". Applications can override this method to
356              * support non-standard issuer matching for complex policies.
357              *
358              * <p>The default implementation does a basic comparison of the XML content, treating
359              * an unsupplied Format as an "entityID".
360              *
361              * @param issuer1   the first Issuer to match
362              * @param issuer2   the second Issuer to match
363              * @return  true iff the operands match
364              */
365             virtual bool issuerMatches(const saml2::Issuer* issuer1, const XMLCh* issuer2) const;
366         };
367
368         /**
369          * Returns the IssuerMatchingPolicy in effect.
370          *
371          * @return the effective IssuerMatchingPolicy
372          */
373         const IssuerMatchingPolicy& getIssuerMatchingPolicy() const {
374             return m_matchingPolicy ? *m_matchingPolicy : m_defaultMatching;
375         }
376
377         /**
378          * Sets the IssuerMatchingPolicy in effect. Setting no policy will
379          * cause the simple, default approach to be used.
380          *
381          * <p>The matching object will be freed by the SecurityPolicy.
382          *
383          * @param matchingPolicy the IssuerMatchingPolicy to use
384          */
385         void setIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy) {
386             delete m_matchingPolicy;
387             m_matchingPolicy = matchingPolicy;
388         }
389
390     protected:
391         /** A shared matching object that just supports the default matching rules. */
392         static IssuerMatchingPolicy m_defaultMatching;
393
394         /** Manufactured MetadataProvider::Criteria instance. */
395         mutable saml2md::MetadataProvider::Criteria* m_metadataCriteria;
396
397     private:
398         // information extracted from message
399         XMLCh* m_messageID;
400         time_t m_issueInstant;
401         saml2::Issuer* m_issuer;
402         const saml2md::RoleDescriptor* m_issuerRole;
403         bool m_authenticated;
404
405         // components governing policy rules
406         IssuerMatchingPolicy* m_matchingPolicy;
407         std::vector<const SecurityPolicyRule*> m_rules;
408         const saml2md::MetadataProvider* m_metadata;
409         xmltooling::QName* m_role;
410         const xmltooling::TrustEngine* m_trust;
411         bool m_validate;
412         bool m_entityOnly;
413     };
414
415 };
416
417 #if defined (_MSC_VER)
418     #pragma warning( pop )
419 #endif
420
421 #endif /* __saml_secpol_h__ */