Example #1
0
DDF& DDF::empty()
{
    if (m_handle) {
        switch (m_handle->type) {
            case ddf_body_t::DDF_STRING:
                if (m_handle->value.string)
                    free(m_handle->value.string);
                break;
            case ddf_body_t::DDF_LIST:
            case ddf_body_t::DDF_STRUCT:
            {
                DDF temp;
                while (m_handle->value.children.first)
                {
                    temp.m_handle=m_handle->value.children.first;
                    temp.destroy();
                }
            }
        }
        m_handle->type=ddf_body_t::DDF_EMPTY;
    }
    return *this;
}
void AbstractHandler::preservePostData(
    const Application& application, const HTTPRequest& request, HTTPResponse& response, const char* relayState
    ) const
{
#ifdef HAVE_STRCASECMP
    if (strcasecmp(request.getMethod(), "POST")) return;
#else
    if (stricmp(request.getMethod(), "POST")) return;
#endif

    // No specs mean no save.
    const PropertySet* props=application.getPropertySet("Sessions");
    pair<bool,const char*> mech = props->getString("postData");
    if (!mech.first) {
        m_log.info("postData property not supplied, form data will not be preserved across SSO");
        return;
    }

    DDF postData = getPostData(application, request);
    if (postData.isnull())
        return;

    if (strstr(mech.second,"ss:") == mech.second) {
        mech.second+=3;
        if (!*mech.second) {
            postData.destroy();
            throw ConfigurationException("Unsupported postData mechanism ($1).", params(1, mech.second - 3));
        }

        string postkey;
        if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
            DDFJanitor postjan(postData);
#ifndef SHIBSP_LITE
            StorageService* storage = application.getServiceProvider().getStorageService(mech.second);
            if (storage) {
                // Use a random key
                string rsKey;
                SAMLConfig::getConfig().generateRandomBytes(rsKey,20);
                rsKey = SAMLArtifact::toHex(rsKey);
                ostringstream out;
                out << postData;
                if (!storage->createString("PostData", rsKey.c_str(), out.str().c_str(), time(NULL) + 600))
                    throw IOException("Attempted to insert duplicate storage key.");
                postkey = string(mech.second-3) + ':' + rsKey;
            }
            else {
                m_log.error("storage-backed PostData mechanism with invalid StorageService ID (%s)", mech.second);
            }
#endif
        }
        else if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
            DDF out,in = DDF("set::PostData").structure();
            DDFJanitor jin(in),jout(out);
            in.addmember("id").string(mech.second);
            in.add(postData);
            out = application.getServiceProvider().getListenerService()->send(in);
            if (!out.isstring())
                throw IOException("StorageService-backed PostData mechanism did not return a state key.");
            postkey = string(mech.second-3) + ':' + out.string();
        }

        // Set a cookie with key info.
        pair<string,const char*> shib_cookie = getPostCookieNameProps(application, relayState);
        postkey += shib_cookie.second;
        response.setCookie(shib_cookie.first.c_str(), postkey.c_str());
    }
    else {
        postData.destroy();
        throw ConfigurationException("Unsupported postData mechanism ($1).", params(1,mech.second));
    }
}