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_authenticated(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          *
179          * @throws BindingException raised if the message/request is invalid according to the supplied rules
180          */
181         void evaluate(
182             const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request=NULL
183             );
184
185         /**
186          * Resets the policy object and/or clears any per-message state.
187          *
188          * <p>Resets can be complete (the default) or merely clear the previous message ID and timestamp
189          * when evaluating multiple layers of a message.
190          *
191          * @param messageOnly   true iff security and issuer state should be left in place
192          */
193         void reset(bool messageOnly=false);
194         
195         /**
196          * Returns the message identifier as determined by the registered policies.
197          * 
198          * @return message identifier as determined by the registered policies
199          */
200         const XMLCh* getMessageID() const {
201             return m_messageID;
202         }
203
204         /**
205          * Returns the message timestamp as determined by the registered policies.
206          * 
207          * @return message timestamp as determined by the registered policies
208          */
209         time_t getIssueInstant() const {
210             return m_issueInstant;
211         }
212
213         /**
214          * Gets the issuer of the message as determined by the registered policies.
215          * 
216          * @return issuer of the message as determined by the registered policies
217          */
218         const saml2::Issuer* getIssuer() const {
219             return m_issuer;
220         }
221
222         /**
223          * Gets the metadata for the role the issuer is operating in.
224          * 
225          * @return metadata for the role the issuer is operating in
226          */
227         const saml2md::RoleDescriptor* getIssuerMetadata() const {
228             return m_issuerRole;
229         }
230
231         /**
232          * Returns the authentication status of the message as determined by the registered policies.
233          * 
234          * @return true iff a SecurityPolicyRule has indicated the issuer/message has been authenticated 
235          */
236         bool isAuthenticated() const {
237             return m_authenticated;
238         }
239
240         /**
241          * Sets the message identifier as determined by the registered policies.
242          * 
243          * @param id message identifier
244          */
245         void setMessageID(const XMLCh* id) {
246             xercesc::XMLString::release(&m_messageID);
247             m_messageID = xercesc::XMLString::replicate(id);
248         }
249
250         /**
251          * Sets the message timestamp as determined by the registered policies.
252          * 
253          * @param issueInstant message timestamp
254          */
255         void setIssueInstant(time_t issueInstant) {
256             m_issueInstant = issueInstant;
257         }
258
259         /**
260          * Sets the issuer of the message as determined by the registered policies.
261          * 
262          * @param issuer issuer of the message
263          */
264         void setIssuer(const saml2::Issuer* issuer);
265
266         /**
267          * Sets the issuer of the message as determined by the registered policies.
268          * 
269          * @param issuer issuer of the message
270          */
271         void setIssuer(const XMLCh* issuer);
272         
273         /**
274          * Sets the metadata for the role the issuer is operating in.
275          * 
276          * @param issuerRole metadata for the role the issuer is operating in
277          */
278         void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
279
280         /**
281          * Sets the authentication status of the message as determined by the registered policies.
282          * 
283          * @param auth indicates whether the issuer/message has been authenticated
284          */
285         void setAuthenticated(bool auth) {
286             m_authenticated = auth;
287         }
288         
289         /** Allows override of rules for comparing saml2:Issuer information. */
290         class SAML_API IssuerMatchingPolicy {
291             MAKE_NONCOPYABLE(IssuerMatchingPolicy);
292         public:
293             IssuerMatchingPolicy() {}
294             virtual ~IssuerMatchingPolicy() {}
295             
296             /**
297              * Returns true iff the two operands "match". Applications can override this method to
298              * support non-standard issuer matching for complex policies. 
299              * 
300              * <p>The default implementation does a basic comparison of the XML content, treating
301              * an unsupplied Format as an "entityID".
302              * 
303              * @param issuer1   the first Issuer to match
304              * @param issuer2   the second Issuer to match
305              * @return  true iff the operands match
306              */
307             virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
308
309             /**
310              * Returns true iff the two operands "match". Applications can override this method to
311              * support non-standard issuer matching for complex policies. 
312              * 
313              * <p>The default implementation does a basic comparison of the XML content, treating
314              * an unsupplied Format as an "entityID".
315              * 
316              * @param issuer1   the first Issuer to match
317              * @param issuer2   the second Issuer to match
318              * @return  true iff the operands match
319              */
320             virtual bool issuerMatches(const saml2::Issuer* issuer1, const XMLCh* issuer2) const;
321         };
322
323         /**
324          * Returns the IssuerMatchingPolicy in effect.
325          * 
326          * @return the effective IssuerMatchingPolicy
327          */
328         const IssuerMatchingPolicy& getIssuerMatchingPolicy() const {
329             return m_matchingPolicy ? *m_matchingPolicy : m_defaultMatching;
330         }
331
332         /**
333          * Sets the IssuerMatchingPolicy in effect. Setting no policy will
334          * cause the simple, default approach to be used.
335          * 
336          * <p>The matching object will be freed by the SecurityPolicy.
337          * 
338          * @param matchingPolicy the IssuerMatchingPolicy to use
339          */
340         void setIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy) {
341             delete m_matchingPolicy;
342             m_matchingPolicy = matchingPolicy;
343         }
344
345     protected:
346         /** A shared matching object that just supports the default matching rules. */
347         static IssuerMatchingPolicy m_defaultMatching;
348
349     private:
350         // information extracted from message 
351         XMLCh* m_messageID;
352         time_t m_issueInstant;
353         saml2::Issuer* m_issuer;
354         const saml2md::RoleDescriptor* m_issuerRole;
355         bool m_authenticated;
356         
357         // components governing policy rules
358         IssuerMatchingPolicy* m_matchingPolicy;
359         std::vector<const SecurityPolicyRule*> m_rules;
360         const saml2md::MetadataProvider* m_metadata;
361         xmltooling::QName* m_role;
362         const xmltooling::TrustEngine* m_trust;
363         bool m_validate;
364     };
365
366 };
367
368 #if defined (_MSC_VER)
369     #pragma warning( pop )
370 #endif
371
372 #endif /* __saml_secpol_h__ */