Streamline setIssuer call in 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          * 
296          * @param issuer issuer of the message
297          */
298         void setIssuer(const saml2::Issuer* issuer);
299
300         /**
301          * Sets the issuer of the message as determined by the registered policies.
302          * 
303          * @param issuer issuer of the message
304          */
305         void setIssuer(const XMLCh* issuer);
306         
307         /**
308          * Sets the metadata for the role the issuer is operating in.
309          * 
310          * @param issuerRole metadata for the role the issuer is operating in
311          */
312         void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
313
314         /**
315          * Sets the security status as determined by the registered policies.
316          * 
317          * @param secure indicates whether the issuer/message has been authenticated
318          */
319         void setSecure(bool secure) {
320             m_secure = secure;
321         }
322         
323         /** Allows override of rules for comparing saml2:Issuer information. */
324         class SAML_API IssuerMatchingPolicy {
325             MAKE_NONCOPYABLE(IssuerMatchingPolicy);
326         public:
327             IssuerMatchingPolicy() {}
328             virtual ~IssuerMatchingPolicy() {}
329             
330             /**
331              * Returns true iff the two operands "match". Applications can override this method to
332              * support non-standard issuer matching for complex policies. 
333              * 
334              * <p>The default implementation does a basic comparison of the XML content, treating
335              * an unsupplied Format as an "entityID".
336              * 
337              * @param issuer1   the first Issuer to match
338              * @param issuer2   the second Issuer to match
339              * @return  true iff the operands match
340              */
341             virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
342
343             /**
344              * Returns true iff the two operands "match". Applications can override this method to
345              * support non-standard issuer matching for complex policies. 
346              * 
347              * <p>The default implementation does a basic comparison of the XML content, treating
348              * an unsupplied Format as an "entityID".
349              * 
350              * @param issuer1   the first Issuer to match
351              * @param issuer2   the second Issuer to match
352              * @return  true iff the operands match
353              */
354             virtual bool issuerMatches(const saml2::Issuer* issuer1, const XMLCh* issuer2) const;
355         };
356
357         /**
358          * Returns the IssuerMatchingPolicy in effect.
359          * 
360          * @return the effective IssuerMatchingPolicy
361          */
362         const IssuerMatchingPolicy& getIssuerMatchingPolicy() const {
363             return m_matchingPolicy ? *m_matchingPolicy : m_defaultMatching;
364         }
365
366         /**
367          * Sets the IssuerMatchingPolicy in effect. Setting no policy will
368          * cause the simple, default approach to be used.
369          * 
370          * <p>The matching object will be freed by the SecurityPolicy.
371          * 
372          * @param matchingPolicy the IssuerMatchingPolicy to use
373          */
374         void setIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy) {
375             delete m_matchingPolicy;
376             m_matchingPolicy = matchingPolicy;
377         }
378
379     protected:
380         /** A shared matching object that just supports the default matching rules. */
381         static IssuerMatchingPolicy m_defaultMatching;
382
383     private:
384         // information extracted from message 
385         xmltooling::QName* m_messageQName;
386         XMLCh* m_messageID;
387         time_t m_issueInstant;
388         saml2::Issuer* m_issuer;
389         const saml2md::RoleDescriptor* m_issuerRole;
390         bool m_secure;
391         
392         // components governing policy rules
393         IssuerMatchingPolicy* m_matchingPolicy;
394         std::vector<const SecurityPolicyRule*> m_rules;
395         const saml2md::MetadataProvider* m_metadata;
396         xmltooling::QName* m_role;
397         const xmltooling::TrustEngine* m_trust;
398         bool m_validate;
399     };
400
401 };
402
403 #if defined (_MSC_VER)
404     #pragma warning( pop )
405 #endif
406
407 #endif /* __saml_secpol_h__ */