Reducing header overuse, non-inlining selected methods (CPPOST-35).
[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
31 #if defined (_MSC_VER)
32     #pragma warning( push )
33     #pragma warning( disable : 4250 4251 )
34 #endif
35
36 namespace xmltooling {
37     class XMLTOOL_API GenericRequest;
38     class XMLTOOL_API TrustEngine;
39 };
40
41 namespace opensaml {
42
43     namespace saml2 {
44         class SAML_API Issuer;
45     };
46
47     class SAML_API SecurityPolicyRule;
48
49     /**
50      * A policy used to verify the security of an incoming message.
51      *
52      * <p>Its security mechanisms may be used to examine the transport layer
53      * (e.g client certificates and HTTP basic auth passwords) or to check the
54      * payload of a request to ensure it meets certain criteria (e.g. valid
55      * digital signature, freshness, replay).
56      *
57      * <p>Policy objects can be reused, but are not thread-safe.
58      */
59     class SAML_API SecurityPolicy
60     {
61         MAKE_NONCOPYABLE(SecurityPolicy);
62     public:
63         /**
64          * Constructor for policy.
65          *
66          * @param metadataProvider  locked MetadataProvider instance
67          * @param role              identifies the role (generally IdP or SP) of the policy peer
68          * @param trustEngine       TrustEngine to authenticate policy peer
69          * @param validate          true iff XML parsing should be done with validation
70          */
71         SecurityPolicy(
72             const saml2md::MetadataProvider* metadataProvider=NULL,
73             const xmltooling::QName* role=NULL,
74             const xmltooling::TrustEngine* trustEngine=NULL,
75             bool validate=true
76             );
77
78         virtual ~SecurityPolicy();
79
80         /**
81          * Returns the locked MetadataProvider supplied to the policy.
82          *
83          * @return the supplied MetadataProvider or NULL
84          */
85         const saml2md::MetadataProvider* getMetadataProvider() const {
86             return m_metadata;
87         }
88
89         /**
90          * Returns a reference to a MetadataProvider::Criteria instance suitable for use with the
91          * installed MetadataProvider.
92          *
93          * <p>The object will be cleared/reset when returned, so do not mutate it and then
94          * call the method again before using it.
95          *
96          * @return reference to a MetadataProvider::Criteria instance
97          */
98         virtual saml2md::MetadataProvider::Criteria& getMetadataProviderCriteria() const;
99
100         /**
101          * Returns the peer role element/type supplied to the policy.
102          *
103          * @return the peer role element/type, or an empty QName
104          */
105         const xmltooling::QName* getRole() const {
106             return m_role;
107         }
108
109         /**
110          * Returns the TrustEngine supplied to the policy.
111          *
112          * @return the supplied TrustEngine or NULL
113          */
114         const xmltooling::TrustEngine* getTrustEngine() const {
115             return m_trust;
116         }
117
118         /**
119          * Returns XML message validation setting.
120          *
121          * @return validation flag
122          */
123         bool getValidating() const {
124             return m_validate;
125         }
126
127         /**
128          * Returns flag controlling non-entity issuer support.
129          *
130          * @return flag controlling non-entity issuer support
131          */
132         bool requireEntityIssuer() const {
133             return m_entityOnly;
134         }
135
136         /**
137          * Returns the SAML audiences that represent the receiving peer.
138          *
139          * @return audience values of the peer processing the message
140          */
141         const std::vector<xmltooling::xstring>& getAudiences() const {
142             return m_audiences;
143         }
144
145         /**
146          * Returns the SAML audiences that represent the receiving peer.
147          *
148          * @return audience values of the peer processing the message
149          */
150         std::vector<xmltooling::xstring>& getAudiences() {
151             return m_audiences;
152         }
153
154         /**
155          * Gets the effective time of message processing.
156          *
157          * @return  the time at which the message is being processed
158          */
159         time_t getTime() const {
160             if (m_ts == 0)
161                 return m_ts = time(NULL);
162             return m_ts;
163         }
164
165         /**
166          * Returns the message identifier to which the message being evaluated
167          * is a response.
168          *
169          * @return correlated message identifier
170          */
171         const XMLCh* getCorrelationID() const {
172             return m_correlationID.c_str();
173         }
174
175         /**
176          * Gets a mutable array of installed policy rules.
177          *
178          * <p>If adding rules, their lifetime must be at least as long as the policy object.
179          *
180          * @return  mutable array of rules
181          */
182         std::vector<const SecurityPolicyRule*>& getRules() {
183             return m_rules;
184         }
185
186         /**
187          * Sets a locked MetadataProvider for the policy.
188          *
189          * @param metadata a locked MetadataProvider or NULL
190          */
191         void setMetadataProvider(const saml2md::MetadataProvider* metadata) {
192             m_metadata = metadata;
193         }
194
195         /**
196          * Sets a MetadataProvider::Criteria instance suitable for use with the
197          * installed MetadataProvider.
198          *
199          * <p>The policy will take ownership of the criteria object when this
200          * method completes.
201          *
202          * @param criteria a MetadataProvider::Criteria instance, or NULL
203          */
204         void setMetadataProviderCriteria(saml2md::MetadataProvider::Criteria* criteria);
205
206         /**
207          * Sets a peer role element/type for to the policy.
208          *
209          * @param role the peer role element/type or NULL
210          */
211         void setRole(const xmltooling::QName* role) {
212             delete m_role;
213             m_role = role ? new xmltooling::QName(*role) : NULL;
214         }
215
216         /**
217          * Sets a TrustEngine for the policy.
218          *
219          * @param trust a TrustEngine or NULL
220          */
221         void setTrustEngine(const xmltooling::TrustEngine* trust) {
222             m_trust = trust;
223         }
224
225         /**
226          * Controls schema validation of incoming XML messages.
227          * This is separate from other forms of programmatic validation of objects,
228          * but can detect a much wider range of syntax errors.
229          *
230          * @param validate  validation setting
231          */
232         void setValidating(bool validate=true) {
233             m_validate = validate;
234         }
235
236         /**
237          * Sets flag controlling non-entity issuer support.
238          *
239          * @param entityOnly require that Issuer be in entity format
240          */
241         void requireEntityIssuer(bool entityOnly=true) {
242             m_entityOnly = entityOnly;
243         }
244
245         /**
246          * Sets effective time of message processing.
247          *
248          * <p>Assumed to be the time of policy instantiation, can be adjusted to pre- or post-date
249          * message processing.
250          *
251          * @param ts    the time at which the message is being processed
252          */
253         void setTime(time_t ts) {
254             m_ts = ts;
255         }
256
257         /**
258          * Sets the message identifier to which the message being evaluated
259          * is a response.
260          *
261          * @param correlationID correlated message identifier
262          */
263         void setCorrelationID(const XMLCh* correlationID) {
264             m_correlationID.erase();
265             if (correlationID)
266                 m_correlationID = correlationID;
267         }
268
269         /**
270          * Evaluates the policy against the given request and message,
271          * possibly populating message information in the policy object.
272          *
273          * @param message           the incoming message
274          * @param request           the protocol request
275          *
276          * @throws BindingException raised if the message/request is invalid according to the supplied rules
277          */
278         void evaluate(const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request=NULL);
279
280         /**
281          * Resets the policy object and/or clears any per-message state.
282          *
283          * <p>Resets can be complete (the default) or merely clear the previous message ID and timestamp
284          * when evaluating multiple layers of a message.
285          *
286          * @param messageOnly   true iff security and issuer state should be left in place
287          */
288         virtual void reset(bool messageOnly=false);
289
290         /**
291          * Resets the policy object and/or clears any per-message state for only this specific class.
292          *
293          * <p>Resets can be complete (the default) or merely clear the previous message ID and timestamp
294          * when evaluating multiple layers of a message.
295          *
296          * @param messageOnly   true iff security and issuer state should be left in place
297          */
298         void _reset(bool messageOnly=false);
299
300         /**
301          * Returns the message identifier as determined by the registered policies.
302          *
303          * @return message identifier as determined by the registered policies
304          */
305         const XMLCh* getMessageID() const {
306             return m_messageID.c_str();
307         }
308
309         /**
310          * Returns the message timestamp as determined by the registered policies.
311          *
312          * @return message timestamp as determined by the registered policies
313          */
314         time_t getIssueInstant() const {
315             return m_issueInstant;
316         }
317
318         /**
319          * Gets the issuer of the message as determined by the registered policies.
320          *
321          * @return issuer of the message as determined by the registered policies
322          */
323         const saml2::Issuer* getIssuer() const {
324             return m_issuer;
325         }
326
327         /**
328          * Gets the metadata for the role the issuer is operating in.
329          *
330          * @return metadata for the role the issuer is operating in
331          */
332         const saml2md::RoleDescriptor* getIssuerMetadata() const {
333             return m_issuerRole;
334         }
335
336         /**
337          * Returns the authentication status of the message as determined by the registered policies.
338          *
339          * @return true iff a SecurityPolicyRule has indicated the issuer/message has been authenticated
340          */
341         bool isAuthenticated() const {
342             return m_authenticated;
343         }
344
345         /**
346          * Sets the message identifier as determined by the registered policies.
347          *
348          * @param id message identifier
349          */
350         void setMessageID(const XMLCh* id) {
351             m_messageID.erase();
352             if (id)
353                 m_messageID = id;
354         }
355
356         /**
357          * Sets the message timestamp as determined by the registered policies.
358          *
359          * @param issueInstant message timestamp
360          */
361         void setIssueInstant(time_t issueInstant) {
362             m_issueInstant = issueInstant;
363         }
364
365         /**
366          * Sets the issuer of the message as determined by the registered policies.
367          *
368          * @param issuer issuer of the message
369          */
370         void setIssuer(const saml2::Issuer* issuer);
371
372         /**
373          * Sets the issuer of the message as determined by the registered policies.
374          *
375          * @param issuer issuer of the message
376          */
377         void setIssuer(const XMLCh* issuer);
378
379         /**
380          * Sets the metadata for the role the issuer is operating in.
381          *
382          * @param issuerRole metadata for the role the issuer is operating in
383          */
384         void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
385
386         /**
387          * Sets the authentication status of the message as determined by the registered policies.
388          *
389          * @param auth indicates whether the issuer/message has been authenticated
390          */
391         void setAuthenticated(bool auth) {
392             m_authenticated = auth;
393         }
394
395         /** Allows override of rules for comparing saml2:Issuer information. */
396         class SAML_API IssuerMatchingPolicy {
397             MAKE_NONCOPYABLE(IssuerMatchingPolicy);
398         public:
399             IssuerMatchingPolicy() {}
400             virtual ~IssuerMatchingPolicy() {}
401
402             /**
403              * Returns true iff the two operands "match". Applications can override this method to
404              * support non-standard issuer matching for complex policies.
405              *
406              * <p>The default implementation does a basic comparison of the XML content, treating
407              * an unsupplied Format as an "entityID".
408              *
409              * @param issuer1   the first Issuer to match
410              * @param issuer2   the second Issuer to match
411              * @return  true iff the operands match
412              */
413             virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
414
415             /**
416              * Returns true iff the two operands "match". Applications can override this method to
417              * support non-standard issuer matching for complex policies.
418              *
419              * <p>The default implementation does a basic comparison of the XML content, treating
420              * an unsupplied Format as an "entityID".
421              *
422              * @param issuer1   the first Issuer to match
423              * @param issuer2   the second Issuer to match
424              * @return  true iff the operands match
425              */
426             virtual bool issuerMatches(const saml2::Issuer* issuer1, const XMLCh* issuer2) const;
427         };
428
429         /**
430          * Returns the IssuerMatchingPolicy in effect.
431          *
432          * @return the effective IssuerMatchingPolicy
433          */
434         const IssuerMatchingPolicy& getIssuerMatchingPolicy() const {
435             return m_matchingPolicy ? *m_matchingPolicy : m_defaultMatching;
436         }
437
438         /**
439          * Sets the IssuerMatchingPolicy in effect. Setting no policy will
440          * cause the simple, default approach to be used.
441          *
442          * <p>The matching object will be freed by the SecurityPolicy.
443          *
444          * @param matchingPolicy the IssuerMatchingPolicy to use
445          */
446         void setIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy) {
447             delete m_matchingPolicy;
448             m_matchingPolicy = matchingPolicy;
449         }
450
451     protected:
452         /** A shared matching object that just supports the default matching rules. */
453         static IssuerMatchingPolicy m_defaultMatching;
454
455         /** Manufactured MetadataProvider::Criteria instance. */
456         mutable saml2md::MetadataProvider::Criteria* m_metadataCriteria;
457
458     private:
459         // information extracted from message
460         xmltooling::xstring m_messageID;
461         time_t m_issueInstant;
462         saml2::Issuer* m_issuer;
463         const saml2md::RoleDescriptor* m_issuerRole;
464         bool m_authenticated;
465
466         // components governing policy rules
467         IssuerMatchingPolicy* m_matchingPolicy;
468         std::vector<const SecurityPolicyRule*> m_rules;
469         const saml2md::MetadataProvider* m_metadata;
470         xmltooling::QName* m_role;
471         const xmltooling::TrustEngine* m_trust;
472         bool m_validate;
473         bool m_entityOnly;
474
475         // contextual information
476         mutable time_t m_ts;
477         xmltooling::xstring m_correlationID;
478         std::vector<xmltooling::xstring> m_audiences;
479     };
480
481 };
482
483 #if defined (_MSC_VER)
484     #pragma warning( pop )
485 #endif
486
487 #endif /* __saml_secpol_h__ */