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