Next integration phase, metadata and trust conversion.
[shibboleth/cpp-sp.git] / shib / Metadata.cpp
1 /*
2  *  Copyright 2001-2005 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 /* Metadata.h - glue classes that interface to metadata providers
18
19    Scott Cantor
20    9/27/02
21
22    $History:$
23 */
24
25 #include "internal.h"
26 #include <xmltooling/util/NDC.h>
27
28 using namespace shibboleth;
29 using namespace opensaml::saml2md;
30 using namespace saml;
31 using namespace std;
32
33 const ICredResolver* Credentials::lookup(const char* id)
34 {
35     if (m_mapper) {
36         m_mapper->unlock();
37         m_mapper=NULL;
38     }
39     const ICredResolver* ret=NULL;
40     m_creds.reset();
41     while (m_creds.hasNext()) {
42         m_mapper=m_creds.next();
43         m_mapper->lock();
44         if (ret=m_mapper->lookup(id)) {
45             return ret;
46         }
47         m_mapper->unlock();
48         m_mapper=NULL;
49     }
50     return NULL;
51 }
52
53 Credentials::~Credentials()
54 {
55     if (m_mapper) {
56         m_mapper->unlock();
57         m_mapper=NULL;
58     }
59 }
60
61 AAP::AAP(const saml::Iterator<IAAP*>& aaps, const XMLCh* attrName, const XMLCh* attrNamespace) : m_mapper(NULL), m_rule(NULL)
62 {
63     aaps.reset();
64     while (aaps.hasNext()) {
65         m_mapper=aaps.next();
66         m_mapper->lock();
67         if (m_rule=m_mapper->lookup(attrName,attrNamespace)) {
68             break;
69         }
70         m_mapper->unlock();
71         m_mapper=NULL;
72     }
73 }
74
75 AAP::AAP(const saml::Iterator<IAAP*>& aaps, const char* alias) : m_mapper(NULL), m_rule(NULL)
76 {
77     aaps.reset();
78     while (aaps.hasNext()) {
79         m_mapper=aaps.next();
80         m_mapper->lock();
81         if (m_rule=m_mapper->lookup(alias)) {
82             break;
83         }
84         m_mapper->unlock();
85         m_mapper=NULL;
86     }
87 }
88
89 AAP::~AAP()
90 {
91     if (m_mapper) {
92         m_mapper->unlock();
93         m_mapper=NULL;
94     }
95 }
96
97 void AAP::apply(const saml::Iterator<IAAP*>& aaps, saml::SAMLAssertion& assertion, const RoleDescriptor* role)
98 {
99 #ifdef _DEBUG
100     xmltooling::NDC("apply");
101 #endif
102     log4cpp::Category& log=log4cpp::Category::getInstance(SHIB_LOGCAT".AAP");
103     
104     // First check for no providers or AnyAttribute.
105     if (aaps.size()==0) {
106         log.info("no filters specified, accepting entire assertion");
107         return;
108     }
109     aaps.reset();
110     while (aaps.hasNext()) {
111         IAAP* p=aaps.next();
112         Locker locker(p);
113         if (p->anyAttribute()) {
114             log.info("any attribute enabled, accepting entire assertion");
115             return;
116         }
117     }
118     
119     // Check each statement.
120     const IAttributeRule* rule=NULL;
121     Iterator<SAMLStatement*> statements=assertion.getStatements();
122     for (unsigned int scount=0; scount < statements.size();) {
123         SAMLAttributeStatement* s=dynamic_cast<SAMLAttributeStatement*>(statements[scount]);
124         if (!s) {
125             scount++;
126             continue;
127         }
128         
129         // Check each attribute, applying any matching rules.
130         Iterator<SAMLAttribute*> attrs=s->getAttributes();
131         for (unsigned long acount=0; acount < attrs.size();) {
132             SAMLAttribute* a=attrs[acount];
133             bool ruleFound=false;
134             aaps.reset();
135             while (aaps.hasNext()) {
136                 IAAP* i=aaps.next();
137                 Locker locker(i);
138                 if (rule=i->lookup(a->getName(),a->getNamespace())) {
139                     ruleFound=true;
140                     try {
141                         rule->apply(*a,role);
142                     }
143                     catch (SAMLException&) {
144                         // The attribute is now defunct.
145                         log.info("no values remain, removing attribute");
146                         s->removeAttribute(acount--);
147                         break;
148                     }
149                 }
150             }
151             if (!ruleFound) {
152                 if (log.isWarnEnabled()) {
153                     auto_ptr_char temp(a->getName());
154                     log.warn("no rule found for attribute (%s), filtering it out",temp.get());
155                 }
156                 s->removeAttribute(acount--);
157             }
158             acount++;
159         }
160
161         try {
162             s->checkValidity();
163             scount++;
164         }
165         catch (SAMLException&) {
166             // The statement is now defunct.
167             log.info("no attributes remain, removing statement");
168             assertion.removeStatement(scount);
169         }
170     }
171     
172     // Now see if we trashed it irrevocably.
173     assertion.checkValidity();
174 }