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 * MessageRoutingRule.cpp
20 * XML Signature checking SecurityPolicyRule
24 #include "exceptions.h"
25 #include "binding/HTTPRequest.h"
26 #include "binding/MessageRoutingRule.h"
27 #include "saml1/core/Protocols.h"
28 #include "saml2/core/Protocols.h"
30 #include <xmltooling/util/NDC.h>
31 #include <xmltooling/util/ReplayCache.h>
32 #include <log4cpp/Category.hh>
34 using namespace opensaml;
35 using namespace xmltooling;
36 using namespace log4cpp;
40 SecurityPolicyRule* SAML_DLLLOCAL MessageRoutingRuleFactory(const DOMElement* const & e)
42 return new MessageRoutingRule(e);
46 static const XMLCh mandatory[] = UNICODE_LITERAL_9(m,a,n,d,a,t,o,r,y);
48 MessageRoutingRule::MessageRoutingRule(const DOMElement* e) : m_mandatory(false)
51 const XMLCh* attr = e->getAttributeNS(NULL, mandatory);
52 if (attr && (*attr==chLatin_t || *attr==chDigit_1))
57 pair<saml2::Issuer*,const saml2md::RoleDescriptor*> MessageRoutingRule::evaluate(
58 const GenericRequest& request,
59 const XMLObject& message,
60 const saml2md::MetadataProvider* metadataProvider,
62 const opensaml::TrustEngine* trustEngine
65 Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.MessageRouting");
66 log.debug("evaluating message routing policy");
69 const char* to = dynamic_cast<const HTTPRequest&>(request).getRequestURL();
72 throw BindingException("Unable to determine delivery location.");
73 log.debug("unable to determine delivery location, ignoring message");
74 return pair<saml2::Issuer*,const saml2md::RoleDescriptor*>(NULL,NULL);
76 auto_ptr_char dest(getDestination(message));
77 if (dest.get() && *dest.get()) {
78 if (!XMLString::equals(to, dest.get())) {
79 log.error("Message intended for (%s), but delivered to (%s)", dest.get(), to);
80 throw BindingException("Message delivered to incorrect address.");
84 throw BindingException("Message did not contain intended address.");
87 throw BindingException("Message was not of a recognized type.");
89 return pair<saml2::Issuer*,const saml2md::RoleDescriptor*>(NULL,NULL);
92 const XMLCh* MessageRoutingRule::getDestination(const XMLObject& message) const
94 // We just let any bad casts throw here.
96 // Shortcuts some of the casting.
97 const XMLCh* ns = message.getElementQName().getNamespaceURI();
99 if (XMLString::equals(ns, samlconstants::SAML20P_NS)) {
100 const saml2p::StatusResponseType* response = dynamic_cast<const saml2p::StatusResponseType*>(&message);
102 return response->getDestination();
103 return dynamic_cast<const saml2p::RequestAbstractType&>(message).getDestination();
105 else if (XMLString::equals(ns, samlconstants::SAML1P_NS)) {
106 // Should be a samlp:Response, at least in OpenSAML.
107 return dynamic_cast<const saml1p::Response&>(message).getRecipient();