Multi-line svn commit, see body.
[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/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_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL), m_secure(false),
79                 m_matchingPolicy(NULL), 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         virtual ~SecurityPolicy();
85
86         /**
87          * Returns the locked MetadataProvider supplied to the policy.
88          * 
89          * @return the supplied MetadataProvider or NULL
90          */
91         const saml2md::MetadataProvider* getMetadataProvider() const {
92             return m_metadata;
93         }
94
95         /**
96          * Returns the peer role element/type supplied to the policy.
97          * 
98          * @return the peer role element/type, or an empty QName
99          */
100         const xmltooling::QName* getRole() const {
101             return m_role;
102         }
103
104         /**
105          * Returns the TrustEngine supplied to the policy.
106          * 
107          * @return the supplied TrustEngine or NULL
108          */
109         const xmltooling::TrustEngine* getTrustEngine() const {
110             return m_trust;
111         }
112
113         /**
114          * Returns XML message validation setting.
115          * 
116          * @return validation flag
117          */
118         bool getValidating() const {
119             return m_validate;
120         } 
121
122         /**
123          * Gets a mutable array of installed policy rules.
124          *
125          * <p>If adding rules, their lifetime must be at least as long as the policy object.
126          * 
127          * @return  mutable array of rules
128          */
129         std::vector<const SecurityPolicyRule*>& getRules() {
130             return m_rules;
131         }
132
133         /**
134          * Sets a locked MetadataProvider for the policy.
135          * 
136          * @param metadata a locked MetadataProvider or NULL
137          */
138         void setMetadataProvider(const saml2md::MetadataProvider* metadata) {
139             m_metadata = metadata;
140         }
141
142         /**
143          * Sets a peer role element/type for to the policy.
144          * 
145          * @param role the peer role element/type or NULL
146          */
147         void setRole(const xmltooling::QName* role) {
148             delete m_role;
149             m_role = role ? new xmltooling::QName(*role) : NULL;
150         }
151
152         /**
153          * Sets a TrustEngine for the policy.
154          * 
155          * @param trust a TrustEngine or NULL
156          */
157         void setTrustEngine(const xmltooling::TrustEngine* trust) {
158             m_trust = trust;
159         }
160
161         /**
162          * Controls schema validation of incoming XML messages.
163          * This is separate from other forms of programmatic validation of objects,
164          * but can detect a much wider range of syntax errors. 
165          * 
166          * @param validate  validation setting
167          */
168         void setValidating(bool validate=true) {
169             m_validate = validate;
170         }
171         
172         /**
173          * Evaluates the policy against the given request and message,
174          * possibly populating message information in the policy object.
175          * 
176          * @param message           the incoming message
177          * @param request           the protocol request
178          * @param protocol          the protocol family in use
179          *
180          * @throws BindingException raised if the message/request is invalid according to the supplied rules
181          */
182         void evaluate(
183             const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request=NULL, const XMLCh* protocol=NULL
184             );
185
186         /**
187          * Resets the policy object and/or clears any per-message state.
188          *
189          * <p>Resets can be complete (the default) or merely clear the previous message ID and timestamp
190          * when evaluating multiple layers of a message.
191          *
192          * @param messageOnly   true iff security and issuer state should be left in place
193          */
194         void reset(bool messageOnly=false);
195         
196         /**
197          * Returns the message identifier as determined by the registered policies.
198          * 
199          * @return message identifier as determined by the registered policies
200          */
201         const XMLCh* getMessageID() const {
202             return m_messageID;
203         }
204
205         /**
206          * Returns the message timestamp as determined by the registered policies.
207          * 
208          * @return message timestamp as determined by the registered policies
209          */
210         time_t getIssueInstant() const {
211             return m_issueInstant;
212         }
213
214         /**
215          * Gets the issuer of the message as determined by the registered policies.
216          * 
217          * @return issuer of the message as determined by the registered policies
218          */
219         const saml2::Issuer* getIssuer() const {
220             return m_issuer;
221         }
222
223         /**
224          * Gets the metadata for the role the issuer is operating in.
225          * 
226          * @return metadata for the role the issuer is operating in
227          */
228         const saml2md::RoleDescriptor* getIssuerMetadata() const {
229             return m_issuerRole;
230         }
231
232         /**
233          * Returns the security status as determined by the registered policies.
234          * 
235          * @return true iff a SecurityPolicyRule has indicated the issuer/message has been authenticated 
236          */
237         bool isSecure() const {
238             return m_secure;
239         }
240
241         /**
242          * Sets the message identifier as determined by the registered policies.
243          * 
244          * @param id message identifier
245          */
246         void setMessageID(const XMLCh* id) {
247             xercesc::XMLString::release(&m_messageID);
248             m_messageID = xercesc::XMLString::replicate(id);
249         }
250
251         /**
252          * Sets the message timestamp as determined by the registered policies.
253          * 
254          * @param issueInstant message timestamp
255          */
256         void setIssueInstant(time_t issueInstant) {
257             m_issueInstant = issueInstant;
258         }
259
260         /**
261          * Sets the issuer of the message as determined by the registered policies.
262          * 
263          * @param issuer issuer of the message
264          */
265         void setIssuer(const saml2::Issuer* issuer);
266
267         /**
268          * Sets the issuer of the message as determined by the registered policies.
269          * 
270          * @param issuer issuer of the message
271          */
272         void setIssuer(const XMLCh* issuer);
273         
274         /**
275          * Sets the metadata for the role the issuer is operating in.
276          * 
277          * @param issuerRole metadata for the role the issuer is operating in
278          */
279         void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
280
281         /**
282          * Sets the security status as determined by the registered policies.
283          * 
284          * @param secure indicates whether the issuer/message has been authenticated
285          */
286         void setSecure(bool secure) {
287             m_secure = secure;
288         }
289         
290         /** Allows override of rules for comparing saml2:Issuer information. */
291         class SAML_API IssuerMatchingPolicy {
292             MAKE_NONCOPYABLE(IssuerMatchingPolicy);
293         public:
294             IssuerMatchingPolicy() {}
295             virtual ~IssuerMatchingPolicy() {}
296             
297             /**
298              * Returns true iff the two operands "match". Applications can override this method to
299              * support non-standard issuer matching for complex policies. 
300              * 
301              * <p>The default implementation does a basic comparison of the XML content, treating
302              * an unsupplied Format as an "entityID".
303              * 
304              * @param issuer1   the first Issuer to match
305              * @param issuer2   the second Issuer to match
306              * @return  true iff the operands match
307              */
308             virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
309
310             /**
311              * Returns true iff the two operands "match". Applications can override this method to
312              * support non-standard issuer matching for complex policies. 
313              * 
314              * <p>The default implementation does a basic comparison of the XML content, treating
315              * an unsupplied Format as an "entityID".
316              * 
317              * @param issuer1   the first Issuer to match
318              * @param issuer2   the second Issuer to match
319              * @return  true iff the operands match
320              */
321             virtual bool issuerMatches(const saml2::Issuer* issuer1, const XMLCh* issuer2) const;
322         };
323
324         /**
325          * Returns the IssuerMatchingPolicy in effect.
326          * 
327          * @return the effective IssuerMatchingPolicy
328          */
329         const IssuerMatchingPolicy& getIssuerMatchingPolicy() const {
330             return m_matchingPolicy ? *m_matchingPolicy : m_defaultMatching;
331         }
332
333         /**
334          * Sets the IssuerMatchingPolicy in effect. Setting no policy will
335          * cause the simple, default approach to be used.
336          * 
337          * <p>The matching object will be freed by the SecurityPolicy.
338          * 
339          * @param matchingPolicy the IssuerMatchingPolicy to use
340          */
341         void setIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy) {
342             delete m_matchingPolicy;
343             m_matchingPolicy = matchingPolicy;
344         }
345
346     protected:
347         /** A shared matching object that just supports the default matching rules. */
348         static IssuerMatchingPolicy m_defaultMatching;
349
350     private:
351         // information extracted from message 
352         XMLCh* m_messageID;
353         time_t m_issueInstant;
354         saml2::Issuer* m_issuer;
355         const saml2md::RoleDescriptor* m_issuerRole;
356         bool m_secure;
357         
358         // components governing policy rules
359         IssuerMatchingPolicy* m_matchingPolicy;
360         std::vector<const SecurityPolicyRule*> m_rules;
361         const saml2md::MetadataProvider* m_metadata;
362         xmltooling::QName* m_role;
363         const xmltooling::TrustEngine* m_trust;
364         bool m_validate;
365     };
366
367 };
368
369 #if defined (_MSC_VER)
370     #pragma warning( pop )
371 #endif
372
373 #endif /* __saml_secpol_h__ */