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