Add XML validation flag to policy.
[shibboleth/cpp-opensaml.git] / saml / binding / SecurityPolicy.h
1 /*
2  *  Copyright 2001-2007 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/binding/GenericRequest.h>
27
28 #include <ctime>
29 #include <vector>
30 #include <xmltooling/XMLObject.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     namespace saml2md {
44         class SAML_API MetadataProvider;
45         class SAML_API RoleDescriptor;
46     };
47     
48     class SAML_API SecurityPolicyRule;
49     
50     /**
51      * A policy used to verify the security of an incoming message.
52      * 
53      * <p>Its security mechanisms may be used to examine the transport layer
54      * (e.g client certificates and HTTP basic auth passwords) or to check the
55      * payload of a request to ensure it meets certain criteria (e.g. valid
56      * digital signature, freshness, replay).
57      * 
58      * <p>Policy objects can be reused, but are not thread-safe. 
59      */
60     class SAML_API SecurityPolicy
61     {
62         MAKE_NONCOPYABLE(SecurityPolicy);
63     public:
64         /**
65          * Constructor for policy.
66          * 
67          * @param metadataProvider  locked MetadataProvider instance
68          * @param role              identifies the role (generally IdP or SP) of the policy peer 
69          * @param trustEngine       TrustEngine to authenticate policy peer
70          * @param validate          true iff XML parsing should be done with validation
71          */
72         SecurityPolicy(
73             const saml2md::MetadataProvider* metadataProvider=NULL,
74             const xmltooling::QName* role=NULL,
75             const xmltooling::TrustEngine* trustEngine=NULL,
76             bool validate=true
77             ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0),
78                 m_issuer(NULL), m_issuerRole(NULL), m_secure(false), m_matchingPolicy(NULL),
79                 m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine), m_validate(validate) {
80             if (role)
81                 m_role = new xmltooling::QName(*role);
82         }
83
84         /**
85          * Constructor for policy using existing rules. The lifetime of the policy rules
86          * must be at least as long as the policy object.
87          *
88          * @param rules             reference to array of policy rules to use 
89          * @param metadataProvider  locked MetadataProvider instance
90          * @param role              identifies the role (generally IdP or SP) of the policy peer 
91          * @param trustEngine       TrustEngine to authenticate policy peer
92          * @param validate          true iff XML parsing should be done with validation
93          */
94         SecurityPolicy(
95             const std::vector<const SecurityPolicyRule*>& rules,
96             const saml2md::MetadataProvider* metadataProvider=NULL,
97             const xmltooling::QName* role=NULL,
98             const xmltooling::TrustEngine* trustEngine=NULL,
99             bool validate=true
100             ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0),
101                 m_issuer(NULL), m_issuerRole(NULL), m_secure(false), m_matchingPolicy(NULL),
102                 m_rules(rules), m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine), m_validate(validate) {
103             if (role)
104                 m_role = new xmltooling::QName(*role);
105         }
106
107         virtual ~SecurityPolicy();
108
109         /**
110          * Returns the locked MetadataProvider supplied to the policy.
111          * 
112          * @return the supplied MetadataProvider or NULL
113          */
114         const saml2md::MetadataProvider* getMetadataProvider() const {
115             return m_metadata;
116         }
117
118         /**
119          * Returns the peer role element/type supplied to the policy.
120          * 
121          * @return the peer role element/type, or an empty QName
122          */
123         const xmltooling::QName* getRole() const {
124             return m_role;
125         }
126
127         /**
128          * Returns the TrustEngine supplied to the policy.
129          * 
130          * @return the supplied TrustEngine or NULL
131          */
132         const xmltooling::TrustEngine* getTrustEngine() const {
133             return m_trust;
134         }
135
136         /**
137          * Returns XML message validation setting.
138          * 
139          * @return validation flag
140          */
141         bool getValidating() const {
142             return m_validate;
143         } 
144
145         /**
146          * Adds a SecurityPolicyRule to the policy. The lifetime of the policy rule
147          * must be at least as long as the policy object.
148          * 
149          * @param rule  SecurityPolicyRule to add
150          */
151         void addRule(const SecurityPolicyRule* rule) {
152             m_rules.push_back(rule);
153         }
154
155         /**
156          * Sets a locked MetadataProvider for the policy.
157          * 
158          * @param metadata a locked MetadataProvider or NULL
159          */
160         void setMetadataProvider(const saml2md::MetadataProvider* metadata) {
161             m_metadata = metadata;
162         }
163
164         /**
165          * Sets a peer role element/type for to the policy.
166          * 
167          * @param role the peer role element/type or NULL
168          */
169         void setRole(const xmltooling::QName* role) {
170             delete m_role;
171             m_role = role ? new xmltooling::QName(*role) : NULL;
172         }
173
174         /**
175          * Sets a TrustEngine for the policy.
176          * 
177          * @param trust a TrustEngine or NULL
178          */
179         void setTrustEngine(const xmltooling::TrustEngine* trust) {
180             m_trust = trust;
181         }
182
183         /**
184          * Controls schema validation of incoming XML messages.
185          * This is separate from other forms of programmatic validation of objects,
186          * but can detect a much wider range of syntax errors. 
187          * 
188          * @param validate  validation setting
189          */
190         void setValidating(bool validate=true) {
191             m_validate = validate;
192         }
193         
194         /**
195          * Evaluates the policy against the given request and message,
196          * possibly populating message information in the policy object.
197          * 
198          * @param message           the incoming message
199          * @param request           the protocol request
200          *
201          * @throws BindingException raised if the message/request is invalid according to the supplied rules
202          */
203         void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request=NULL);
204
205         /**
206          * Resets the policy object and clears any per-message state.
207          */
208         void reset();
209         
210         /**
211          * Returns the message element/type as determined by the registered policies.
212          * 
213          * @return message element/type as determined by the registered policies
214          */
215         const xmltooling::QName* getMessageQName() const {
216             return m_messageQName;
217         }
218
219         /**
220          * Returns the message identifier as determined by the registered policies.
221          * 
222          * @return message identifier as determined by the registered policies
223          */
224         const XMLCh* getMessageID() const {
225             return m_messageID;
226         }
227
228         /**
229          * Returns the message timestamp as determined by the registered policies.
230          * 
231          * @return message timestamp as determined by the registered policies
232          */
233         time_t getIssueInstant() const {
234             return m_issueInstant;
235         }
236
237         /**
238          * Gets the issuer of the message as determined by the registered policies.
239          * 
240          * @return issuer of the message as determined by the registered policies
241          */
242         const saml2::Issuer* getIssuer() const {
243             return m_issuer;
244         }
245
246         /**
247          * Gets the metadata for the role the issuer is operating in.
248          * 
249          * @return metadata for the role the issuer is operating in
250          */
251         const saml2md::RoleDescriptor* getIssuerMetadata() const {
252             return m_issuerRole;
253         }
254
255         /**
256          * Returns the security status as determined by the registered policies.
257          * 
258          * @return true iff a SecurityPolicyRule has indicated the issuer/message has been authenticated 
259          */
260         bool isSecure() const {
261             return m_secure;
262         }
263
264         /**
265          * Sets the message element/type as determined by the registered policies.
266          * 
267          * @param messageQName message element/type
268          */
269         void setMessageQName(const xmltooling::QName* messageQName) {
270             delete m_messageQName;
271             m_messageQName = messageQName ? new xmltooling::QName(*messageQName) : NULL;
272         }
273
274         /**
275          * Sets the message identifier as determined by the registered policies.
276          * 
277          * @param id message identifier
278          */
279         void setMessageID(const XMLCh* id) {
280             XMLString::release(&m_messageID);
281             m_messageID = XMLString::replicate(id);
282         }
283
284         /**
285          * Sets the message timestamp as determined by the registered policies.
286          * 
287          * @param issueInstant message timestamp
288          */
289         void setIssueInstant(time_t issueInstant) {
290             m_issueInstant = issueInstant;
291         }
292
293         /**
294          * Sets the issuer of the message as determined by the registered policies.
295          * The policy object takes ownership of the Issuer object.
296          * 
297          * @param issuer issuer of the message
298          */
299         void setIssuer(saml2::Issuer* issuer);
300         
301         /**
302          * Sets the metadata for the role the issuer is operating in.
303          * 
304          * @param issuerRole metadata for the role the issuer is operating in
305          */
306         void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
307
308         /**
309          * Sets the security status as determined by the registered policies.
310          * 
311          * @param secure indicates whether the issuer/message has been authenticated
312          */
313         void setSecure(bool secure) {
314             m_secure = secure;
315         }
316         
317         /** Allows override of rules for comparing saml2:Issuer information. */
318         class SAML_API IssuerMatchingPolicy {
319             MAKE_NONCOPYABLE(IssuerMatchingPolicy);
320         public:
321             IssuerMatchingPolicy() {}
322             virtual ~IssuerMatchingPolicy() {}
323             
324             /**
325              * Returns true iff the two operands "match". Applications can override this method to
326              * support non-standard issuer matching for complex policies. 
327              * 
328              * <p>The default implementation does a basic comparison of the XML content, treating
329              * an unsupplied Format as an "entityID".
330              * 
331              * @param issuer1   the first Issuer to match
332              * @param issuer2   the second Issuer to match
333              * @return  true iff the operands match
334              */
335             virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
336         };
337
338         /**
339          * Returns the IssuerMatchingPolicy in effect.
340          * 
341          * @return the effective IssuerMatchingPolicy
342          */
343         const IssuerMatchingPolicy& getIssuerMatchingPolicy() const {
344             return m_matchingPolicy ? *m_matchingPolicy : m_defaultMatching;
345         }
346
347         /**
348          * Sets the IssuerMatchingPolicy in effect. Setting no policy will
349          * cause the simple, default approach to be used.
350          * 
351          * <p>The matching object will be freed by the SecurityPolicy.
352          * 
353          * @param matchingPolicy the IssuerMatchingPolicy to use
354          */
355         void setIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy) {
356             delete m_matchingPolicy;
357             m_matchingPolicy = matchingPolicy;
358         }
359
360     protected:
361         /** A shared matching object that just supports the default matching rules. */
362         static IssuerMatchingPolicy m_defaultMatching;
363
364     private:
365         // information extracted from message 
366         xmltooling::QName* m_messageQName;
367         XMLCh* m_messageID;
368         time_t m_issueInstant;
369         saml2::Issuer* m_issuer;
370         const saml2md::RoleDescriptor* m_issuerRole;
371         bool m_secure;
372         
373         // components governing policy rules
374         IssuerMatchingPolicy* m_matchingPolicy;
375         std::vector<const SecurityPolicyRule*> m_rules;
376         const saml2md::MetadataProvider* m_metadata;
377         xmltooling::QName* m_role;
378         const xmltooling::TrustEngine* m_trust;
379         bool m_validate;
380     };
381
382 };
383
384 #if defined (_MSC_VER)
385     #pragma warning( pop )
386 #endif
387
388 #endif /* __saml_secpol_h__ */