Fix leaks in identifier generation
[shibboleth/cpp-sp.git] / shibsp / handler / impl / SAML2SessionInitiator.cpp
index a3377e8..2e10df3 100644 (file)
@@ -84,6 +84,12 @@ namespace shibsp {
             return samlconstants::SAML20P_NS;
         }
 
+#ifndef SHIBSP_LITE
+        void generateMetadata(saml2md::SPSSODescriptor& role, const char* handlerURL) const {
+            doGenerateMetadata(role, handlerURL);
+        }
+#endif
+
     private:
         pair<bool,long> doRequest(
             const Application& application,
@@ -263,7 +269,7 @@ pair<bool,long> SAML2SessionInitiator::run(SPRequest& request, string& entityID,
 
         // Always need to recover target URL to compute handler below.
         recoverRelayState(app, request, request, target, false);
-        limitRelayState(m_log, app, request, target.c_str());
+        app.limitRedirect(request, target.c_str());
 
         pair<bool,bool> flag = getBool("isPassive", request);
         isPassive = (flag.first && flag.second);
@@ -664,21 +670,26 @@ pair<bool,long> SAML2SessionInitiator::doRequest(
     }
 
     pair<bool,bool> requestDelegation = getBool("requestDelegation");
-    if (requestDelegation.first && requestDelegation.second && entity.first) {
-        // Request delegation by including the IdP as an Audience.
-        // Also specify the expected session lifetime as the bound on the assertion lifetime.
-        const PropertySet* sessionProps = app.getPropertySet("Sessions");
-        pair<bool,unsigned int> lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : pair<bool,unsigned int>(true,28800);
-        if (!lifetime.first || lifetime.second == 0)
-            lifetime.second = 28800;
-        if (!req->getConditions())
-            req->setConditions(ConditionsBuilder::buildConditions());
-        req->getConditions()->setNotOnOrAfter(time(nullptr) + lifetime.second + 300);
-        AudienceRestriction* audrest = AudienceRestrictionBuilder::buildAudienceRestriction();
-        req->getConditions()->getConditions().push_back(audrest);
-        Audience* aud = AudienceBuilder::buildAudience();
-        audrest->getAudiences().push_back(aud);
-        aud->setAudienceURI(entity.first->getEntityID());
+    if (requestDelegation.first && requestDelegation.second) {
+        if (entity.first) {
+            // Request delegation by including the IdP as an Audience.
+            // Also specify the expected session lifetime as the bound on the assertion lifetime.
+            const PropertySet* sessionProps = app.getPropertySet("Sessions");
+            pair<bool,unsigned int> lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : pair<bool,unsigned int>(true,28800);
+            if (!lifetime.first || lifetime.second == 0)
+                lifetime.second = 28800;
+            if (!req->getConditions())
+                req->setConditions(ConditionsBuilder::buildConditions());
+            req->getConditions()->setNotOnOrAfter(time(nullptr) + lifetime.second + 300);
+            AudienceRestriction* audrest = AudienceRestrictionBuilder::buildAudienceRestriction();
+            req->getConditions()->getConditions().push_back(audrest);
+            Audience* aud = AudienceBuilder::buildAudience();
+            audrest->getAudiences().push_back(aud);
+            aud->setAudienceURI(entity.first->getEntityID());
+        }
+        else {
+            m_log.warn("requestDelegation set, but IdP unknown at request time");
+        }
     }
 
     if (ECP && entityID) {
@@ -702,7 +713,9 @@ pair<bool,long> SAML2SessionInitiator::doRequest(
         }
     }
 
-    req->setID(SAMLConfig::getConfig().generateIdentifier());
+    XMLCh* genid = SAMLConfig::getConfig().generateIdentifier();
+    req->setID(genid);
+    XMLString::release(&genid);
     req->setIssueInstant(time(nullptr));
 
     scoped_ptr<AuthnRequestEvent> ar_event(newAuthnRequestEvent(app, httpRequest));