2 * Copyright 2001-2006 Internet2
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * BlacklistMetadataFilter.cpp
20 * Removes blacklisted entities from a metadata instance
24 #include "saml2/metadata/MetadataFilter.h"
25 #include "signature/SignatureProfileValidator.h"
27 #include <log4cpp/Category.hh>
29 #include <xmltooling/util/NDC.h>
30 #include <xmltooling/signature/SignatureValidator.h>
32 using namespace opensaml::saml2md;
33 using namespace opensaml;
34 using namespace xmlsignature;
35 using namespace xmltooling;
36 using namespace log4cpp;
42 class SAML_DLLLOCAL SignatureMetadataFilter : public MetadataFilter
45 SignatureMetadataFilter(const DOMElement* e);
46 ~SignatureMetadataFilter() {
47 delete m_sigValidator;
50 const char* getId() const { return SIGNATURE_METADATA_FILTER; }
51 void doFilter(XMLObject& xmlObject) const;
54 void doFilter(EntitiesDescriptor& entities, bool rootObject=false) const;
55 void verifySignature(Signature* sig) const {
57 m_profileValidator.validate(sig);
58 m_sigValidator->validate(sig);
62 SignatureProfileValidator m_profileValidator;
63 SignatureValidator* m_sigValidator;
66 MetadataFilter* SAML_DLLLOCAL SignatureMetadataFilterFactory(const DOMElement* const & e)
68 return new SignatureMetadataFilter(e);
74 static const XMLCh GenericKeyResolver[] = UNICODE_LITERAL_11(K,e,y,R,e,s,o,l,v,e,r);
75 static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e);
77 SignatureMetadataFilter::SignatureMetadataFilter(const DOMElement* e) : m_sigValidator(NULL)
79 e = XMLHelper::getFirstChildElement(e, GenericKeyResolver);
80 auto_ptr_char t(e ? e->getAttributeNS(NULL,type) : NULL);
82 auto_ptr<KeyResolver> kr(XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(t.get(),e));
83 m_sigValidator = new SignatureValidator(kr.get());
87 throw MetadataFilterException("missing <KeyResolver> element, or no type attribute found");
90 void SignatureMetadataFilter::doFilter(XMLObject& xmlObject) const
97 EntitiesDescriptor& entities = dynamic_cast<EntitiesDescriptor&>(xmlObject);
98 doFilter(entities, true);
105 EntityDescriptor& entity = dynamic_cast<EntityDescriptor&>(xmlObject);
106 if (!entity.getSignature())
107 throw MetadataFilterException("Root metadata element was unsigned.");
108 verifySignature(entity.getSignature());
113 throw MetadataFilterException("SignatureMetadataFilter was given an improper metadata instance to filter.");
116 void SignatureMetadataFilter::doFilter(EntitiesDescriptor& entities, bool rootObject) const
118 Category& log=Category::getInstance(SAML_LOGCAT".Metadata");
120 Signature* sig = entities.getSignature();
121 if (!sig && rootObject)
122 throw MetadataFilterException("Root metadata element was unsigned.");
123 verifySignature(sig);
125 VectorOf(EntityDescriptor) v=entities.getEntityDescriptors();
126 for (VectorOf(EntityDescriptor)::size_type i=0; i<v.size(); ) {
128 verifySignature(v[i]->getSignature());
131 catch (XMLToolingException& e) {
132 auto_ptr_char id(v[i]->getEntityID());
133 log.info("filtering out entity (%s) after failed signature check: ", id.get(), e.what());
134 v.erase(v.begin() + i);
138 VectorOf(EntitiesDescriptor) w=entities.getEntitiesDescriptors();
139 for (VectorOf(EntitiesDescriptor)::size_type j=0; j<w.size(); ) {
141 verifySignature(w[j]->getSignature());
144 catch (XMLToolingException& e) {
145 auto_ptr_char name(w[j]->getName());
146 log.info("filtering out group (%s) after failed signature check: ", name.get(), e.what());
147 w.erase(w.begin() + j);