Convert from NULL macro to nullptr, remove unused zlib code.
[shibboleth/cpp-opensaml.git] / saml / binding / impl / SecurityPolicy.cpp
1 /*
2  *  Copyright 2001-2010 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  * SecurityPolicy.cpp
19  *
20  * Overall policy used to verify the security of an incoming message.
21  */
22
23 #include "internal.h"
24 #include "exceptions.h"
25 #include "binding/SecurityPolicy.h"
26 #include "binding/SecurityPolicyRule.h"
27 #include "saml2/core/Assertions.h"
28
29 #include <xercesc/util/XMLUniDefs.hpp>
30
31 using namespace opensaml::saml2md;
32 using namespace opensaml::saml2;
33 using namespace opensaml;
34 using namespace xmltooling;
35 using namespace std;
36
37 namespace opensaml {
38     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory AudienceRestrictionRuleFactory;
39     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory ClientCertAuthRuleFactory;
40     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory ConditionsRuleFactory;
41     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory IgnoreRuleFactory;
42     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory MessageFlowRuleFactory;
43     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory NullSecurityRuleFactory;
44     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory SimpleSigningRuleFactory;
45     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory XMLSigningRuleFactory;
46
47     namespace saml1 {
48         SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory BrowserSSORuleFactory;
49     }
50
51     namespace saml2 {
52         SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory BearerConfirmationRuleFactory;
53         SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory DelegationRestrictionRuleFactory;
54     }
55 };
56
57 void SAML_API opensaml::registerSecurityPolicyRules()
58 {
59     SAMLConfig& conf=SAMLConfig::getConfig();
60     conf.SecurityPolicyRuleManager.registerFactory(AUDIENCE_POLICY_RULE, AudienceRestrictionRuleFactory);
61     conf.SecurityPolicyRuleManager.registerFactory(CLIENTCERTAUTH_POLICY_RULE, ClientCertAuthRuleFactory);
62     conf.SecurityPolicyRuleManager.registerFactory(CONDITIONS_POLICY_RULE, ConditionsRuleFactory);
63     conf.SecurityPolicyRuleManager.registerFactory(IGNORE_POLICY_RULE, IgnoreRuleFactory);
64     conf.SecurityPolicyRuleManager.registerFactory(MESSAGEFLOW_POLICY_RULE, MessageFlowRuleFactory);
65     conf.SecurityPolicyRuleManager.registerFactory(NULLSECURITY_POLICY_RULE, NullSecurityRuleFactory);
66     conf.SecurityPolicyRuleManager.registerFactory(SIMPLESIGNING_POLICY_RULE, SimpleSigningRuleFactory);
67     conf.SecurityPolicyRuleManager.registerFactory(XMLSIGNING_POLICY_RULE, XMLSigningRuleFactory);
68     conf.SecurityPolicyRuleManager.registerFactory(SAML1BROWSERSSO_POLICY_RULE, saml1::BrowserSSORuleFactory);
69     conf.SecurityPolicyRuleManager.registerFactory(BEARER_POLICY_RULE, saml2::BearerConfirmationRuleFactory);
70     conf.SecurityPolicyRuleManager.registerFactory(DELEGATION_POLICY_RULE, saml2::DelegationRestrictionRuleFactory);
71 }
72
73 SecurityPolicyRule::SecurityPolicyRule()
74 {
75 }
76
77 SecurityPolicyRule::~SecurityPolicyRule()
78 {
79 }
80
81 SecurityPolicy::SecurityPolicy(
82     const saml2md::MetadataProvider* metadataProvider,
83     const xmltooling::QName* role,
84     const xmltooling::TrustEngine* trustEngine,
85     bool validate
86     ) : m_metadataCriteria(nullptr),
87         m_issueInstant(0),
88         m_issuer(nullptr),
89         m_issuerRole(nullptr),
90         m_authenticated(false),
91         m_matchingPolicy(nullptr),
92         m_metadata(metadataProvider),
93         m_role(nullptr),
94         m_trust(trustEngine),
95         m_validate(validate),
96         m_entityOnly(true),
97         m_ts(0)
98 {
99     if (role)
100         m_role = new xmltooling::QName(*role);
101 }
102
103 SecurityPolicy::~SecurityPolicy()
104 {
105     delete m_metadataCriteria;
106     delete m_issuer;
107 }
108
109 const MetadataProvider* SecurityPolicy::getMetadataProvider() const
110 {
111     return m_metadata;
112 }
113
114 MetadataProvider::Criteria& SecurityPolicy::getMetadataProviderCriteria() const
115 {
116     if (!m_metadataCriteria)
117         m_metadataCriteria=new MetadataProvider::Criteria();
118     else
119         m_metadataCriteria->reset();
120     return *m_metadataCriteria;
121 }
122
123 const xmltooling::QName* SecurityPolicy::getRole() const
124 {
125     return m_role;
126 }
127
128 const TrustEngine* SecurityPolicy::getTrustEngine() const
129 {
130     return m_trust;
131 }
132
133 bool SecurityPolicy::getValidating() const
134 {
135     return m_validate;
136 }
137
138 bool SecurityPolicy::requireEntityIssuer() const
139 {
140     return m_entityOnly;
141 }
142
143 const vector<xstring>& SecurityPolicy::getAudiences() const
144 {
145     return m_audiences;
146 }
147
148 vector<xstring>& SecurityPolicy::getAudiences()
149 {
150     return m_audiences;
151 }
152
153 time_t SecurityPolicy::getTime() const
154 {
155     if (m_ts == 0)
156         return m_ts = time(nullptr);
157     return m_ts;
158 }
159
160 const XMLCh* SecurityPolicy::getCorrelationID() const
161 {
162     return m_correlationID.c_str();
163 }
164
165 vector<const SecurityPolicyRule*>& SecurityPolicy::getRules()
166 {
167     return m_rules;
168 }
169
170 void SecurityPolicy::setMetadataProvider(const MetadataProvider* metadata)
171 {
172     m_metadata = metadata;
173 }
174
175 void SecurityPolicy::setMetadataProviderCriteria(MetadataProvider::Criteria* criteria)
176 {
177     if (m_metadataCriteria)
178         delete m_metadataCriteria;
179     m_metadataCriteria=criteria;
180 }
181
182 void SecurityPolicy::setRole(const xmltooling::QName* role)
183 {
184     delete m_role;
185     m_role = role ? new xmltooling::QName(*role) : nullptr;
186 }
187
188 void SecurityPolicy::setTrustEngine(const TrustEngine* trust)
189 {
190     m_trust = trust;
191 }
192
193 void SecurityPolicy::setValidating(bool validate)
194 {
195     m_validate = validate;
196 }
197
198 void SecurityPolicy::requireEntityIssuer(bool entityOnly)
199 {
200     m_entityOnly = entityOnly;
201 }
202
203 void SecurityPolicy::setTime(time_t ts)
204 {
205     m_ts = ts;
206 }
207
208 void SecurityPolicy::setCorrelationID(const XMLCh* correlationID)
209 {
210     m_correlationID.erase();
211     if (correlationID)
212         m_correlationID = correlationID;
213 }
214
215 void SecurityPolicy::evaluate(const XMLObject& message, const GenericRequest* request)
216 {
217     for (vector<const SecurityPolicyRule*>::const_iterator i=m_rules.begin(); i!=m_rules.end(); ++i)
218         (*i)->evaluate(message,request,*this);
219 }
220
221 void SecurityPolicy::reset(bool messageOnly)
222 {
223     _reset(messageOnly);
224 }
225
226 void SecurityPolicy::_reset(bool messageOnly)
227 {
228     m_messageID.erase();
229     m_issueInstant=0;
230     if (!messageOnly) {
231         delete m_issuer;
232         m_issuer=nullptr;
233         m_issuerRole=nullptr;
234         m_authenticated=false;
235     }
236 }
237
238 const XMLCh* SecurityPolicy::getMessageID() const
239 {
240     return m_messageID.c_str();
241 }
242
243 time_t SecurityPolicy::getIssueInstant() const
244 {
245     return m_issueInstant;
246 }
247
248 const Issuer* SecurityPolicy::getIssuer() const
249 {
250     return m_issuer;
251 }
252
253 const RoleDescriptor* SecurityPolicy::getIssuerMetadata() const
254 {
255     return m_issuerRole;
256 }
257
258 bool SecurityPolicy::isAuthenticated() const
259 {
260     return m_authenticated;
261 }
262
263 void SecurityPolicy::setMessageID(const XMLCh* id)
264 {
265     m_messageID.erase();
266     if (id)
267         m_messageID = id;
268 }
269
270 void SecurityPolicy::setIssueInstant(time_t issueInstant)
271 {
272     m_issueInstant = issueInstant;
273 }
274
275 void SecurityPolicy::setIssuer(const Issuer* issuer)
276 {
277     if (!getIssuerMatchingPolicy().issuerMatches(m_issuer, issuer))
278         throw SecurityPolicyException("An Issuer was supplied that conflicts with previous results.");
279
280     if (!m_issuer) {
281         if (m_entityOnly && issuer->getFormat() && !XMLString::equals(issuer->getFormat(), NameIDType::ENTITY))
282             throw SecurityPolicyException("A non-entity Issuer was supplied, violating policy.");
283         m_issuerRole = nullptr;
284         m_issuer=issuer->cloneIssuer();
285     }
286 }
287
288 void SecurityPolicy::setIssuer(const XMLCh* issuer)
289 {
290     if (!getIssuerMatchingPolicy().issuerMatches(m_issuer, issuer))
291         throw SecurityPolicyException("An Issuer was supplied that conflicts with previous results.");
292
293     if (!m_issuer && issuer && *issuer) {
294         m_issuerRole = nullptr;
295         m_issuer = IssuerBuilder::buildIssuer();
296         m_issuer->setName(issuer);
297     }
298 }
299
300 void SecurityPolicy::setIssuerMetadata(const RoleDescriptor* issuerRole)
301 {
302     if (issuerRole && m_issuerRole && issuerRole!=m_issuerRole)
303         throw SecurityPolicyException("A rule supplied a RoleDescriptor that conflicts with previous results.");
304     m_issuerRole=issuerRole;
305 }
306
307 void SecurityPolicy::setAuthenticated(bool auth)
308 {
309     m_authenticated = auth;
310 }
311
312 SecurityPolicy::IssuerMatchingPolicy::IssuerMatchingPolicy()
313 {
314 }
315
316 SecurityPolicy::IssuerMatchingPolicy::~IssuerMatchingPolicy()
317 {
318 }
319
320 bool SecurityPolicy::IssuerMatchingPolicy::issuerMatches(const Issuer* issuer1, const Issuer* issuer2) const
321 {
322     // nullptr matches anything for the purposes of this interface.
323     if (!issuer1 || !issuer2)
324         return true;
325
326     const XMLCh* op1=issuer1->getName();
327     const XMLCh* op2=issuer2->getName();
328     if (!op1 || !op2 || !XMLString::equals(op1,op2))
329         return false;
330
331     op1=issuer1->getFormat();
332     op2=issuer2->getFormat();
333     if (!XMLString::equals(op1 ? op1 : NameIDType::ENTITY, op2 ? op2 : NameIDType::ENTITY))
334         return false;
335
336     op1=issuer1->getNameQualifier();
337     op2=issuer2->getNameQualifier();
338     if (!XMLString::equals(op1 ? op1 : &chNull, op2 ? op2 : &chNull))
339         return false;
340
341     op1=issuer1->getSPNameQualifier();
342     op2=issuer2->getSPNameQualifier();
343     if (!XMLString::equals(op1 ? op1 : &chNull, op2 ? op2 : &chNull))
344         return false;
345
346     return true;
347 }
348
349 bool SecurityPolicy::IssuerMatchingPolicy::issuerMatches(const Issuer* issuer1, const XMLCh* issuer2) const
350 {
351     // nullptr matches anything for the purposes of this interface.
352     if (!issuer1 || !issuer2 || !*issuer2)
353         return true;
354
355     const XMLCh* op1=issuer1->getName();
356     if (!op1 || !XMLString::equals(op1,issuer2))
357         return false;
358
359     op1=issuer1->getFormat();
360     if (op1 && *op1 && !XMLString::equals(op1, NameIDType::ENTITY))
361         return false;
362
363     op1=issuer1->getNameQualifier();
364     if (op1 && *op1)
365         return false;
366
367     op1=issuer1->getSPNameQualifier();
368     if (op1 && *op1)
369         return false;
370
371     return true;
372 }
373
374 SecurityPolicy::IssuerMatchingPolicy SecurityPolicy::m_defaultMatching;
375
376 const SecurityPolicy::IssuerMatchingPolicy& SecurityPolicy::getIssuerMatchingPolicy() const
377 {
378     return m_matchingPolicy ? *m_matchingPolicy : m_defaultMatching;
379 }
380
381 void SecurityPolicy::setIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy)
382 {
383     delete m_matchingPolicy;
384     m_matchingPolicy = matchingPolicy;
385 }