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