Policy rule redesign for factor out issuer handling.
[shibboleth/cpp-opensaml.git] / saml / binding / SecurityPolicy.h
1 /*
2  *  Copyright 2001-2006 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          */
71         SecurityPolicy(
72             const saml2md::MetadataProvider* metadataProvider=NULL,
73             const xmltooling::QName* role=NULL,
74             const xmltooling::TrustEngine* trustEngine=NULL
75             ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL),
76                 m_matchingPolicy(NULL), m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine) {
77             if (role)
78                 m_role = new xmltooling::QName(*role);
79         }
80
81         /**
82          * Constructor for policy using existing rules. The lifetime of the policy rules
83          * must be at least as long as the policy object.
84          *
85          * @param rules             reference to array of policy rules to use 
86          * @param metadataProvider  locked MetadataProvider instance
87          * @param role              identifies the role (generally IdP or SP) of the policy peer 
88          * @param trustEngine       TrustEngine to authenticate policy peer
89          */
90         SecurityPolicy(
91             const std::vector<const SecurityPolicyRule*>& rules,
92             const saml2md::MetadataProvider* metadataProvider=NULL,
93             const xmltooling::QName* role=NULL,
94             const xmltooling::TrustEngine* trustEngine=NULL
95             ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL),
96                 m_matchingPolicy(NULL), m_rules(rules), m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine) {
97             if (role)
98                 m_role = new xmltooling::QName(*role);
99         }
100
101         virtual ~SecurityPolicy();
102
103         /**
104          * Returns the locked MetadataProvider supplied to the policy.
105          * 
106          * @return the supplied MetadataProvider or NULL
107          */
108         const saml2md::MetadataProvider* getMetadataProvider() const {
109             return m_metadata;
110         }
111
112         /**
113          * Returns the peer role element/type supplied to the policy.
114          * 
115          * @return the peer role element/type, or an empty QName
116          */
117         const xmltooling::QName* getRole() const {
118             return m_role;
119         }
120
121         /**
122          * Returns the TrustEngine supplied to the policy.
123          * 
124          * @return the supplied TrustEngine or NULL
125          */
126         const xmltooling::TrustEngine* getTrustEngine() const {
127             return m_trust;
128         }
129
130         /**
131          * Adds a SecurityPolicyRule to the policy. The lifetime of the policy rule
132          * must be at least as long as the policy object.
133          * 
134          * @param rule  SecurityPolicyRule to add
135          */
136         void addRule(const SecurityPolicyRule* rule) {
137             m_rules.push_back(rule);
138         }
139
140         /**
141          * Sets a locked MetadataProvider for the policy.
142          * 
143          * @param metadata a locked MetadataProvider or NULL
144          */
145         void setMetadataProvider(const saml2md::MetadataProvider* metadata) {
146             m_metadata = metadata;
147         }
148
149         /**
150          * Sets a peer role element/type for to the policy.
151          * 
152          * @param role the peer role element/type or NULL
153          */
154         void setRole(const xmltooling::QName* role) {
155             delete m_role;
156             m_role = role ? new xmltooling::QName(*role) : NULL;
157         }
158
159         /**
160          * Sets a TrustEngine for the policy.
161          * 
162          * @param trust a TrustEngine or NULL
163          */
164         void setTrustEngine(const xmltooling::TrustEngine* trust) {
165             m_trust = trust;
166         }
167
168         /**
169          * Evaluates the policy against the given request and message,
170          * possibly populating message information in the policy object.
171          * 
172          * @param message           the incoming message
173          * @param request           the protocol request
174          * 
175          * @throws BindingException thrown if the request/message do not meet the requirements of this policy
176          */
177         void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request=NULL);
178
179         /**
180          * Resets the policy object and clears any per-message state.
181          */
182         void reset();
183         
184         /**
185          * Returns the message element/type as determined by the registered policies.
186          * 
187          * @return message element/type as determined by the registered policies
188          */
189         const xmltooling::QName* getMessageQName() const {
190             return m_messageQName;
191         }
192
193         /**
194          * Returns the message identifier as determined by the registered policies.
195          * 
196          * @return message identifier as determined by the registered policies
197          */
198         const XMLCh* getMessageID() const {
199             return m_messageID;
200         }
201
202         /**
203          * Returns the message timestamp as determined by the registered policies.
204          * 
205          * @return message timestamp as determined by the registered policies
206          */
207         time_t getIssueInstant() const {
208             return m_issueInstant;
209         }
210
211         /**
212          * Gets the issuer of the message as determined by the registered policies.
213          * 
214          * @return issuer of the message as determined by the registered policies
215          */
216         const saml2::Issuer* getIssuer() const {
217             return m_issuer;
218         }
219
220         /**
221          * Gets the metadata for the role the issuer is operating in.
222          * 
223          * @return metadata for the role the issuer is operating in
224          */
225         const saml2md::RoleDescriptor* getIssuerMetadata() const {
226             return m_issuerRole;
227         }
228
229         /**
230          * Sets the message element/type as determined by the registered policies.
231          * 
232          * @param messageQName message element/type
233          */
234         void setMessageQName(const xmltooling::QName* messageQName) {
235             delete m_messageQName;
236             m_messageQName = messageQName ? new xmltooling::QName(*messageQName) : NULL;
237         }
238
239         /**
240          * Sets the message identifier as determined by the registered policies.
241          * 
242          * @param id message identifier
243          */
244         void setMessageID(const XMLCh* id) {
245             XMLString::release(&m_messageID);
246             m_messageID = XMLString::replicate(id);
247         }
248
249         /**
250          * Sets the message timestamp as determined by the registered policies.
251          * 
252          * @param issueInstant message timestamp
253          */
254         void setIssueInstant(time_t issueInstant) {
255             m_issueInstant = issueInstant;
256         }
257
258         /**
259          * Sets the issuer of the message as determined by the registered policies.
260          * The policy object takes ownership of the Issuer object.
261          * 
262          * @param issuer issuer of the message
263          */
264         void setIssuer(saml2::Issuer* issuer);
265         
266         /**
267          * Sets the metadata for the role the issuer is operating in.
268          * 
269          * @param issuerRole metadata for the role the issuer is operating in
270          */
271         void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
272         
273         /** Allows override of rules for comparing saml2:Issuer information. */
274         class SAML_API IssuerMatchingPolicy {
275             MAKE_NONCOPYABLE(IssuerMatchingPolicy);
276         public:
277             IssuerMatchingPolicy() {}
278             virtual ~IssuerMatchingPolicy() {}
279             
280             /**
281              * Returns true iff the two operands "match". Applications can override this method to
282              * support non-standard issuer matching for complex policies. 
283              * 
284              * <p>The default implementation does a basic comparison of the XML content, treating
285              * an unsupplied Format as an "entityID".
286              * 
287              * @param issuer1   the first Issuer to match
288              * @param issuer2   the second Issuer to match
289              * @return  true iff the operands match
290              */
291             virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
292         };
293
294         /**
295          * Returns the IssuerMatchingPolicy in effect.
296          * 
297          * @return the effective IssuerMatchingPolicy
298          */
299         const IssuerMatchingPolicy& getIssuerMatchingPolicy() const {
300             return m_matchingPolicy ? *m_matchingPolicy : m_defaultMatching;
301         }
302
303         /**
304          * Sets the IssuerMatchingPolicy in effect. Setting no policy will
305          * cause the simple, default approach to be used.
306          * 
307          * <p>The matching object will be freed by the SecurityPolicy.
308          * 
309          * @param matchingPolicy the IssuerMatchingPolicy to use
310          */
311         void setIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy) {
312             delete m_matchingPolicy;
313             m_matchingPolicy = matchingPolicy;
314         }
315
316     protected:
317         /** A shared matching object that just supports the default matching rules. */
318         static IssuerMatchingPolicy m_defaultMatching;
319
320     private:
321         // information extracted from message 
322         xmltooling::QName* m_messageQName;
323         XMLCh* m_messageID;
324         time_t m_issueInstant;
325         saml2::Issuer* m_issuer;
326         const saml2md::RoleDescriptor* m_issuerRole;
327         
328         // components governing policy rules
329         IssuerMatchingPolicy* m_matchingPolicy;
330         std::vector<const SecurityPolicyRule*> m_rules;
331         const saml2md::MetadataProvider* m_metadata;
332         xmltooling::QName* m_role;
333         const xmltooling::TrustEngine* m_trust;
334     };
335
336 };
337
338 #if defined (_MSC_VER)
339     #pragma warning( pop )
340 #endif
341
342 #endif /* __saml_secpol_h__ */