From: Scott Cantor Date: Tue, 31 Mar 2009 18:24:38 +0000 (+0000) Subject: https://issues.shibboleth.net/jira/browse/SSPCPP-196 X-Git-Tag: 2.2.0~86 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;h=fbaac3bd1281e7bf3261ab87239c4828044fa28c;hp=8272fc870b90b6d5c26c7c6afad7b6bc44beb79b;p=shibboleth%2Fcpp-sp.git https://issues.shibboleth.net/jira/browse/SSPCPP-196 --- diff --git a/adfs/adfs.cpp b/adfs/adfs.cpp index ffbb7f7..c002b2f 100644 --- a/adfs/adfs.cpp +++ b/adfs/adfs.cpp @@ -1,6 +1,6 @@ /* * Copyright 2001-2009 Internet2 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -87,7 +87,7 @@ namespace { public: ADFSDecoder() : m_ns(WSTRUST_NS) {} virtual ~ADFSDecoder() {} - + XMLObject* decode(string& relayState, const GenericRequest& genericRequest, SecurityPolicy& policy) const; protected: @@ -121,7 +121,7 @@ namespace { } } virtual ~ADFSSessionInitiator() {} - + void setParent(const PropertySet* parent) { DOMPropertySet::setParent(parent); pair loc = getString("Location"); @@ -196,7 +196,7 @@ namespace { } } virtual ~ADFSLogoutInitiator() {} - + void setParent(const PropertySet* parent) { DOMPropertySet::setParent(parent); pair loc = getString("Location"); @@ -230,8 +230,8 @@ namespace { public: ADFSLogout(const DOMElement* e, const char* appId) : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".Logout.ADFS")), m_login(e, appId) { -#ifndef SHIBSP_LITE m_initiator = false; +#ifndef SHIBSP_LITE m_preserve.push_back("wreply"); string address = string(appId) + getString("Location").second + "::run::ADFSLO"; setAddress(address.c_str()); @@ -563,7 +563,7 @@ XMLObject* ADFSDecoder::decode(string& relayState, const GenericRequest& generic // Parse and bind the document into an XMLObject. istringstream is(param); DOMDocument* doc = (policy.getValidating() ? XMLToolingConfig::getConfig().getValidatingParser() - : XMLToolingConfig::getConfig().getParser()).parse(is); + : XMLToolingConfig::getConfig().getParser()).parse(is); XercesJanitor janitor(doc); auto_ptr xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true)); janitor.release(); @@ -578,7 +578,7 @@ XMLObject* ADFSDecoder::decode(string& relayState, const GenericRequest& generic // Skip policy step here, there's no security in the wrapper. // policy.evaluate(*xmlObject.get(), &genericRequest); - + return xmlObject.release(); } @@ -599,7 +599,7 @@ void ADFSConsumer::implementProtocol( const ElementProxy* response = dynamic_cast(&xmlObject); if (!response || !response->hasChildren()) throw FatalProfileException("Incoming message was not of the proper type or contains no security token."); - + const Assertion* token = NULL; for (vector::const_iterator xo = response->getUnknownXMLObjects().begin(); xo != response->getUnknownXMLObjects().end(); ++xo) { // Look for the RequestedSecurityToken element. @@ -613,20 +613,20 @@ void ADFSConsumer::implementProtocol( break; } } - + // Extract message and issuer details from assertion. extractMessageDetails(*token, m_protocol.get(), policy); // Run the policy over the assertion. Handles replay, freshness, and // signature verification, assuming the relevant rules are configured. policy.evaluate(*token); - + // If no security is in place now, we kick it. if (!policy.isAuthenticated()) throw SecurityPolicyException("Unable to establish security of incoming assertion."); time_t now = time(NULL); - + const PropertySet* sessionProps = application.getPropertySet("Sessions"); const EntityDescriptor* entity = policy.getIssuerMetadata() ? dynamic_cast(policy.getIssuerMetadata()->getParent()) : NULL; @@ -635,7 +635,7 @@ void ADFSConsumer::implementProtocol( const XMLCh* authMethod=NULL; const XMLCh* authInstant=NULL; time_t sessionExp = 0; - + const saml1::Assertion* saml1token = dynamic_cast(token); if (saml1token) { // Now do profile and core semantic validation to ensure we can use it for SSO. @@ -645,7 +645,7 @@ void ADFSConsumer::implementProtocol( throw FatalProfileException("Assertion did not contain time conditions."); else if (saml1token->getAuthenticationStatements().empty()) throw FatalProfileException("Assertion did not contain an authentication statement."); - + // authnskew allows rejection of SSO if AuthnInstant is too old. pair authnskew = sessionProps ? sessionProps->getUnsignedInt("maxTimeSinceAuthn") : pair(false,0); @@ -684,7 +684,7 @@ void ADFSConsumer::implementProtocol( throw FatalProfileException("Assertion did not contain time conditions."); else if (saml2token->getAuthnStatements().empty()) throw FatalProfileException("Assertion did not contain an authentication statement."); - + // authnskew allows rejection of SSO if AuthnInstant is too old. pair authnskew = sessionProps ? sessionProps->getUnsignedInt("maxTimeSinceAuthn") : pair(false,0); @@ -716,7 +716,7 @@ void ADFSConsumer::implementProtocol( else sessionExp = min(sessionExp, now + lifetime.second); // Use the lowest. } - + m_log.debug("ADFS profile processing completed successfully"); // We've successfully "accepted" the SSO token. @@ -827,7 +827,7 @@ void ADFSLogoutInitiator::receive(DDF& in, ostream& out) m_log.error("couldn't find application (%s) for logout", aid ? aid : "(missing)"); throw ConfigurationException("Unable to locate application for logout, deleted?"); } - + // Unpack the request. auto_ptr req(getRequest(in)); @@ -835,7 +835,7 @@ void ADFSLogoutInitiator::receive(DDF& in, ostream& out) DDF ret(NULL); DDFJanitor jout(ret); auto_ptr resp(getResponse(ret)); - + Session* session = NULL; try { session = app->getServiceProvider().getSessionCache()->find(*app, *req.get(), NULL, NULL); @@ -895,7 +895,7 @@ pair ADFSLogoutInitiator::doRequest( "Unable to locate ADFS IdP role for identity provider ($entityID).", namedparams(1, "entityID", session->getEntityID()) ); } - + const EndpointType* ep = EndpointManager( dynamic_cast(entity.second)->getSingleLogoutServices() ).getByBinding(m_binding.get()); diff --git a/isapi_shib/isapi_shib.cpp b/isapi_shib/isapi_shib.cpp index 41a87ca..d4d06bd 100644 --- a/isapi_shib/isapi_shib.cpp +++ b/isapi_shib/isapi_shib.cpp @@ -805,8 +805,10 @@ public: while (datalen) { DWORD buflen=8192; BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen); - if (!ret || !buflen) + if (!ret) throw IOException("Error reading request body from browser."); + else if (!buflen) + throw IOException("Socket closed while reading request body from browser."); m_body.append(buf, buflen); datalen-=buflen; } diff --git a/shibsp/handler/impl/SAML2Logout.cpp b/shibsp/handler/impl/SAML2Logout.cpp index c843897..5753c89 100644 --- a/shibsp/handler/impl/SAML2Logout.cpp +++ b/shibsp/handler/impl/SAML2Logout.cpp @@ -1,6 +1,6 @@ /* * Copyright 2001-2009 Internet2 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,7 +16,7 @@ /** * SAML2Logout.cpp - * + * * Handles SAML 2.0 single logout protocol messages. */ @@ -55,7 +55,7 @@ namespace shibsp { #pragma warning( push ) #pragma warning( disable : 4250 ) #endif - + class SHIBSP_DLLLOCAL SAML2Logout : public AbstractHandler, public LogoutHandler { public: @@ -69,7 +69,7 @@ namespace shibsp { } #endif } - + void receive(DDF& in, ostream& out); pair run(SPRequest& request, bool isHandler=true) const; @@ -133,8 +133,8 @@ SAML2Logout::SAML2Logout(const DOMElement* e, const char* appId) ,m_role(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME), m_decoder(NULL), m_outgoing(NULL) #endif { -#ifndef SHIBSP_LITE m_initiator = false; +#ifndef SHIBSP_LITE m_preserve.push_back("ID"); m_preserve.push_back("entityID"); m_preserve.push_back("RelayState"); @@ -233,7 +233,7 @@ void SAML2Logout::receive(DDF& in, ostream& out) m_log.error("couldn't find application (%s) for logout", aid ? aid : "(missing)"); throw ConfigurationException("Unable to locate application for logout, deleted?"); } - + // Unpack the request. auto_ptr req(getRequest(in)); @@ -241,7 +241,7 @@ void SAML2Logout::receive(DDF& in, ostream& out) DDF ret(NULL); DDFJanitor jout(ret); auto_ptr resp(getResponse(ret)); - + // Since we're remoted, the result should either be a throw, which we pass on, // a false/0 return, which we just return as an empty structure, or a response/redirect, // which we capture in the facade and send back. @@ -324,7 +324,7 @@ pair SAML2Logout::doRequest(const Application& application, const HTT pair policyId = getString("policyId", m_configNS.get()); // namespace-qualified if inside handler element if (!policyId.first) policyId = application.getString("policyId"); // unqualified in Application(s) element - + // Access policy properties. const PropertySet* settings = application.getServiceProvider().getPolicySettings(policyId.second); pair validate = settings->getBool("validate"); @@ -334,7 +334,7 @@ pair SAML2Logout::doRequest(const Application& application, const HTT // Create the policy. shibsp::SecurityPolicy policy(application, &m_role, validate.first && validate.second); - + // Decode the message. string relayState; auto_ptr msg(m_decoder->decode(relayState, request, policy)); @@ -344,7 +344,7 @@ pair SAML2Logout::doRequest(const Application& application, const HTT throw SecurityPolicyException("Security of LogoutRequest not established."); // Message from IdP to logout one or more sessions. - + // If this is front-channel, we have to have a session_id to use already. if (m_decoder->isUserAgentPresent() && session_id.empty()) { m_log.error("no active session"); @@ -483,7 +483,7 @@ pair SAML2Logout::doRequest(const Application& application, const HTT if (result.first) return result; } - + // For back-channel requests, or if no front-channel notification is needed... bool worked1 = false,worked2 = false; worked1 = notifyBackChannel(application, request.getRequestURL(), sessions, false);