1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20 
21 /**
22  * @file saml/binding/SecurityPolicy.h
23  *
24  * Overall policy used to verify the security of an incoming message.
25  */
26 
27 #ifndef __saml_secpol_h__
28 #define __saml_secpol_h__
29 
30 #include <saml/saml2/metadata/MetadataProvider.h>
31 
32 #include <ctime>
33 #include <vector>
34 #include <boost/scoped_ptr.hpp>
35 #include <xmltooling/unicode.h>
36 
37 #if defined (_MSC_VER)
38     #pragma warning( push )
39     #pragma warning( disable : 4250 4251 )
40 #endif
41 
42 namespace xmltooling {
43     class XMLTOOL_API GenericRequest;
44     class XMLTOOL_API TrustEngine;
45 };
46 
47 namespace opensaml {
48 
49     namespace saml2 {
50         class SAML_API Issuer;
51     };
52 
53     class SAML_API SecurityPolicyRule;
54 
55     /**
56      * A policy used to verify the security of an incoming message.
57      *
58      * <p>Its security mechanisms may be used to examine the transport layer
59      * (e.g client certificates and HTTP basic auth passwords) or to check the
60      * payload of a request to ensure it meets certain criteria (e.g. valid
61      * digital signature, freshness, replay).
62      *
63      * <p>Policy objects can be reused, but are not thread-safe.
64      */
65     class SAML_API SecurityPolicy
66     {
67         MAKE_NONCOPYABLE(SecurityPolicy);
68     public:
69         /**
70          * Constructor for policy.
71          *
72          * @param metadataProvider  locked MetadataProvider instance
73          * @param role              identifies the role (generally IdP or SP) of the policy peer
74          * @param trustEngine       TrustEngine to authenticate policy peer
75          * @param validate          true iff XML parsing should be done with validation
76          * @param profile           profile identifier
77          */
78         SecurityPolicy(
79             const saml2md::MetadataProvider* metadataProvider=nullptr,
80             const xmltooling::QName* role=nullptr,
81             const xmltooling::TrustEngine* trustEngine=nullptr,
82             bool validate=true,
83             const char* profile=nullptr
84             );
85 
86         virtual ~SecurityPolicy();
87 
88         /**
89          * Returns the profile identifier associated with the transaction.
90          *
91          * @return the profile identifier
92          */
93         const char* getProfile() const;
94 
95         /**
96          * Returns the locked MetadataProvider supplied to the policy.
97          *
98          * @return the supplied MetadataProvider or nullptr
99          */
100         const saml2md::MetadataProvider* getMetadataProvider() const;
101 
102         /**
103          * Returns a reference to a MetadataProvider::Criteria instance suitable for use with the
104          * installed MetadataProvider.
105          *
106          * <p>The object will be cleared/reset when returned, so do not mutate it and then
107          * call the method again before using it.
108          *
109          * @return reference to a MetadataProvider::Criteria instance
110          */
111         virtual saml2md::MetadataProvider::Criteria& getMetadataProviderCriteria() const;
112 
113         /**
114          * Returns the peer role element/type supplied to the policy.
115          *
116          * @return the peer role element/type, or an empty QName
117          */
118         const xmltooling::QName* getRole() const;
119 
120         /**
121          * Returns the TrustEngine supplied to the policy.
122          *
123          * @return the supplied TrustEngine or nullptr
124          */
125         const xmltooling::TrustEngine* getTrustEngine() const;
126 
127         /**
128          * Returns XML message validation setting.
129          *
130          * @return validation flag
131          */
132         bool getValidating() const;
133 
134         /**
135          * Returns flag controlling non-entity issuer support.
136          *
137          * @return flag controlling non-entity issuer support
138          */
139         bool requireEntityIssuer() const;
140 
141         /**
142          * Returns the SAML audiences that represent the receiving peer.
143          *
144          * @return audience values of the peer processing the message
145          */
146         const std::vector<xmltooling::xstring>& getAudiences() const;
147 
148         /**
149          * Returns the SAML audiences that represent the receiving peer.
150          *
151          * @return audience values of the peer processing the message
152          */
153         std::vector<xmltooling::xstring>& getAudiences();
154 
155         /**
156          * Gets the effective time of message processing.
157          *
158          * @return  the time at which the message is being processed
159          */
160         time_t getTime() const;
161 
162         /**
163          * Returns the message identifier to which the message being evaluated
164          * is a response.
165          *
166          * @return correlated message identifier
167          */
168         const XMLCh* getCorrelationID() const;
169 
170         /**
171         * Returns the message identifier to which the message being evaluated
172         * claims to be a response.
173         *
174         * @return correlatable message identifier
175         */
176         const XMLCh* getInResponseTo() const;
177 
178         /**
179          * Gets a mutable array of installed policy rules.
180          *
181          * <p>If adding rules, their lifetime must be at least as long as the policy object.
182          *
183          * @return  mutable array of rules
184          */
185         std::vector<const SecurityPolicyRule*>& getRules();
186 
187         /**
188         * Sets the profile identifier associated with the transaction.
189         *
190         * @param id the profile identifier
191         */
192         void setProfile(const char* id);
193 
194         /**
195          * Sets a locked MetadataProvider for the policy.
196          *
197          * @param metadata a locked MetadataProvider or nullptr
198          */
199         void setMetadataProvider(const saml2md::MetadataProvider* metadata);
200 
201         /**
202          * Sets a MetadataProvider::Criteria instance suitable for use with the
203          * installed MetadataProvider.
204          *
205          * <p>The policy will take ownership of the criteria object when this
206          * method completes.
207          *
208          * @param criteria a MetadataProvider::Criteria instance, or nullptr
209          */
210         void setMetadataProviderCriteria(saml2md::MetadataProvider::Criteria* criteria);
211 
212         /**
213          * Sets a peer role element/type for to the policy.
214          *
215          * @param role the peer role element/type or nullptr
216          */
217         void setRole(const xmltooling::QName* role);
218 
219         /**
220          * Sets a TrustEngine for the policy.
221          *
222          * @param trust a TrustEngine or nullptr
223          */
224         void setTrustEngine(const xmltooling::TrustEngine* trust);
225 
226         /**
227          * Controls schema validation of incoming XML messages.
228          * This is separate from other forms of programmatic validation of objects,
229          * but can detect a much wider range of syntax errors.
230          *
231          * @param validate  validation setting
232          */
233         void setValidating(bool validate=true);
234 
235         /**
236          * Sets flag controlling non-entity issuer support.
237          *
238          * @param entityOnly require that Issuer be in entity format
239          */
240         void requireEntityIssuer(bool entityOnly=true);
241 
242         /**
243          * Sets effective time of message processing.
244          *
245          * <p>Assumed to be the time of policy instantiation, can be adjusted to pre- or post-date
246          * message processing.
247          *
248          * @param ts    the time at which the message is being processed
249          */
250         void setTime(time_t ts);
251 
252         /**
253          * Sets the message identifier to which the message being evaluated
254          * is a response.
255          *
256          * @param correlationID correlated message identifier
257          */
258         void setCorrelationID(const XMLCh* correlationID);
259 
260         /**
261         * Sets the message identifier to which the message being evaluated
262         * was responding (i.e., the value to be compared to the correlation ID).
263         *
264         * @param id correlatable message identifier
265         */
266         void setInResponseTo(const XMLCh* id);
267 
268         /**
269          * Evaluates the policy against the given request and message,
270          * possibly populating message information in the policy object.
271          *
272          * @param message           the incoming message
273          * @param request           the protocol request
274          *
275          * @throws BindingException raised if the message/request is invalid according to the supplied rules
276          */
277         void evaluate(const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request=nullptr);
278 
279         /**
280          * Resets the policy object and/or clears any per-message state.
281          *
282          * <p>Resets can be complete (the default) or merely clear the previous message ID and timestamp
283          * when evaluating multiple layers of a message.
284          *
285          * @param messageOnly   true iff security and issuer state should be left in place
286          */
287         virtual void reset(bool messageOnly=false);
288 
289         /**
290          * Resets the policy object and/or clears any per-message state for only this specific class.
291          *
292          * <p>Resets can be complete (the default) or merely clear the previous message ID and timestamp
293          * when evaluating multiple layers of a message.
294          *
295          * @param messageOnly   true iff security and issuer state should be left in place
296          */
297         void _reset(bool messageOnly=false);
298 
299         /**
300          * Returns the message identifier as determined by the registered policies.
301          *
302          * @return message identifier as determined by the registered policies
303          */
304         const XMLCh* getMessageID() const;
305 
306         /**
307          * Returns the message timestamp as determined by the registered policies.
308          *
309          * @return message timestamp as determined by the registered policies
310          */
311         time_t getIssueInstant() const;
312 
313         /**
314          * Gets the issuer of the message as determined by the registered policies.
315          *
316          * @return issuer of the message as determined by the registered policies
317          */
318         const saml2::Issuer* getIssuer() const;
319 
320         /**
321          * Gets the metadata for the role the issuer is operating in.
322          *
323          * @return metadata for the role the issuer is operating in
324          */
325         const saml2md::RoleDescriptor* getIssuerMetadata() const;
326 
327         /**
328          * Returns the authentication status of the message as determined by the registered policies.
329          *
330          * @return true iff a SecurityPolicyRule has indicated the issuer/message has been authenticated
331          */
332         bool isAuthenticated() const;
333 
334         /**
335          * Sets the message identifier as determined by the registered policies.
336          *
337          * @param id message identifier
338          */
339         void setMessageID(const XMLCh* id);
340 
341         /**
342          * Sets the message timestamp as determined by the registered policies.
343          *
344          * @param issueInstant message timestamp
345          */
346         void setIssueInstant(time_t issueInstant);
347 
348         /**
349          * Sets the issuer of the message as determined by the registered policies.
350          *
351          * @param issuer issuer of the message
352          */
353         void setIssuer(const saml2::Issuer* issuer);
354 
355         /**
356          * Sets the issuer of the message as determined by the registered policies.
357          *
358          * @param issuer issuer of the message
359          */
360         void setIssuer(const XMLCh* issuer);
361 
362         /**
363          * Sets the metadata for the role the issuer is operating in.
364          *
365          * @param issuerRole metadata for the role the issuer is operating in
366          */
367         void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
368 
369         /**
370          * Sets the authentication status of the message as determined by the registered policies.
371          *
372          * @param auth indicates whether the issuer/message has been authenticated
373          */
374         void setAuthenticated(bool auth);
375 
376         /** Allows override of rules for comparing saml2:Issuer information. */
377         class SAML_API IssuerMatchingPolicy {
378             MAKE_NONCOPYABLE(IssuerMatchingPolicy);
379         public:
380             IssuerMatchingPolicy();
381             virtual ~IssuerMatchingPolicy();
382 
383             /**
384              * Returns true iff the two operands "match". Applications can override this method to
385              * support non-standard issuer matching for complex policies.
386              *
387              * <p>The default implementation does a basic comparison of the XML content, treating
388              * an unsupplied Format as an "entityID".
389              *
390              * @param issuer1   the first Issuer to match
391              * @param issuer2   the second Issuer to match
392              * @return  true iff the operands match
393              */
394             virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
395 
396             /**
397              * Returns true iff the two operands "match". Applications can override this method to
398              * support non-standard issuer matching for complex policies.
399              *
400              * <p>The default implementation does a basic comparison of the XML content, treating
401              * an unsupplied Format as an "entityID".
402              *
403              * @param issuer1   the first Issuer to match
404              * @param issuer2   the second Issuer to match
405              * @return  true iff the operands match
406              */
407             virtual bool issuerMatches(const saml2::Issuer* issuer1, const XMLCh* issuer2) const;
408         };
409 
410         /**
411          * Returns the IssuerMatchingPolicy in effect.
412          *
413          * @return the effective IssuerMatchingPolicy
414          */
415         const IssuerMatchingPolicy& getIssuerMatchingPolicy() const;
416 
417         /**
418          * Sets the IssuerMatchingPolicy in effect. Setting no policy will
419          * cause the simple, default approach to be used.
420          *
421          * <p>The matching object will be freed by the SecurityPolicy.
422          *
423          * @param matchingPolicy the IssuerMatchingPolicy to use
424          */
425         void setIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy);
426 
427     protected:
428         /** A shared matching object that just supports the default matching rules. */
429         static IssuerMatchingPolicy m_defaultMatching;
430 
431         /** Manufactured MetadataProvider::Criteria instance. */
432         mutable saml2md::MetadataProvider::Criteria* m_metadataCriteria;
433 
434     private:
435         // information extracted from message
436         xmltooling::xstring m_messageID, m_correlationID, m_inResponseTo;
437         time_t m_issueInstant;
438         boost::scoped_ptr<saml2::Issuer> m_issuer;
439         const saml2md::RoleDescriptor* m_issuerRole;
440         bool m_authenticated;
441 
442         // components governing policy rules
443         boost::scoped_ptr<IssuerMatchingPolicy> m_matchingPolicy;
444         std::vector<const SecurityPolicyRule*> m_rules;
445         const saml2md::MetadataProvider* m_metadata;
446         boost::scoped_ptr<xmltooling::QName> m_role;
447         const xmltooling::TrustEngine* m_trust;
448         bool m_validate;
449         bool m_entityOnly;
450 
451         // contextual information
452         std::string m_profile;
453         mutable time_t m_ts;
454         std::vector<xmltooling::xstring> m_audiences;
455     };
456 
457 };
458 
459 #if defined (_MSC_VER)
460     #pragma warning( pop )
461 #endif
462 
463 #endif /* __saml_secpol_h__ */
464