X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=shibsp%2FAbstractSPRequest.cpp;h=fe0de146bbd26bbe96c43db044f00c8e36214065;hb=7a8806efca2d7135ef9a3900b47329dbc5674f72;hp=d76b9107d6059a2621e4144f0b5eee184e679800;hpb=15734309cfc5aa285b82ff19ba214a1dcaf1cada;p=shibboleth%2Fcpp-sp.git diff --git a/shibsp/AbstractSPRequest.cpp b/shibsp/AbstractSPRequest.cpp index d76b910..fe0de14 100644 --- a/shibsp/AbstractSPRequest.cpp +++ b/shibsp/AbstractSPRequest.cpp @@ -1,41 +1,82 @@ -/* - * Copyright 2001-2007 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 +/** + * Licensed to the University Corporation for Advanced Internet + * Development, Inc. (UCAID) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * UCAID licenses this file to you 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. */ /** * AbstractSPRequest.cpp - * - * Abstract base for SPRequest implementations + * + * Abstract base for SPRequest implementations. */ #include "internal.h" +#include "exceptions.h" #include "AbstractSPRequest.h" #include "Application.h" +#include "GSSRequest.h" #include "ServiceProvider.h" #include "SessionCache.h" +#include "util/CGIParser.h" + +#include using namespace shibsp; using namespace opensaml; using namespace xmltooling; using namespace std; +SPRequest::SPRequest() +{ +} + +SPRequest::~SPRequest() +{ +} + +string SPRequest::getSecureHeader(const char* name) const +{ + return getHeader(name); +} + +void SPRequest::setAuthType(const char* authtype) +{ +} + +#ifdef SHIBSP_HAVE_GSSAPI +GSSRequest::GSSRequest() +{ +} + +GSSRequest::~GSSRequest() +{ +} + +gss_name_t GSSRequest::getGSSName() const +{ + return GSS_C_NO_NAME; +} +#endif + AbstractSPRequest::AbstractSPRequest(const char* category) - : m_sp(NULL), m_mapper(NULL), m_app(NULL), m_sessionTried(false), m_session(NULL), - m_log(&Category::getInstance(category)), m_parser(NULL) + : m_sp(SPConfig::getConfig().getServiceProvider()), + m_mapper(nullptr), m_app(nullptr), m_sessionTried(false), m_session(nullptr), + m_log(&Category::getInstance(category)) { - m_sp=SPConfig::getConfig().getServiceProvider(); m_sp->lock(); } @@ -47,33 +88,42 @@ AbstractSPRequest::~AbstractSPRequest() m_mapper->unlock(); if (m_sp) m_sp->unlock(); - delete m_parser; } -RequestMapper::Settings AbstractSPRequest::getRequestSettings() const +const ServiceProvider& AbstractSPRequest::getServiceProvider() const { - if (m_mapper) - return m_settings; + return *m_sp; +} - // Map request to application and content settings. - m_mapper=m_sp->getRequestMapper(); - m_mapper->lock(); - return m_settings = m_mapper->getSettings(*this); +RequestMapper::Settings AbstractSPRequest::getRequestSettings() const +{ + if (!m_mapper) { + // Map request to application and content settings. + m_mapper = m_sp->getRequestMapper(); + m_mapper->lock(); + m_settings = m_mapper->getSettings(*this); + if (reinterpret_cast(m_log)->isDebugEnabled()) { + reinterpret_cast(m_log)->debug( + "mapped %s to %s", getRequestURL(), m_settings.first->getString("applicationId").second + ); + } + } + return m_settings; } const Application& AbstractSPRequest::getApplication() const { if (!m_app) { // Now find the application from the URL settings - m_app=m_sp->getApplication(getRequestSettings().first->getString("applicationId").second); + m_app = m_sp->getApplication(getRequestSettings().first->getString("applicationId").second); if (!m_app) - throw ConfigurationException("Unable to map request to application settings, check configuration."); - } + throw ConfigurationException("Unable to map non-default applicationId to an ApplicationOverride, check configuration."); + } return *m_app; } -Session* AbstractSPRequest::getSession(bool checkTimeout, bool ignoreAddress, bool cache) const +Session* AbstractSPRequest::getSession(bool checkTimeout, bool ignoreAddress, bool cache) { // Only attempt this once. if (cache && m_sessionTried) @@ -82,24 +132,24 @@ Session* AbstractSPRequest::getSession(bool checkTimeout, bool ignoreAddress, bo m_sessionTried = true; // Need address checking and timeout settings. - time_t timeout=0; + time_t timeout = 3600; if (checkTimeout || !ignoreAddress) { - const PropertySet* props=getApplication().getPropertySet("Sessions"); + const PropertySet* props = getApplication().getPropertySet("Sessions"); if (props) { if (checkTimeout) { - pair p=props->getUnsignedInt("timeout"); + pair p = props->getUnsignedInt("timeout"); if (p.first) timeout = p.second; } - pair pcheck=props->getBool("consistentAddress"); + pair pcheck = props->getBool("consistentAddress"); if (pcheck.first) ignoreAddress = !pcheck.second; } } - // The cache will either silently pass a session or NULL back, or throw an exception out. + // The cache will either silently pass a session or nullptr back, or throw an exception out. Session* session = getServiceProvider().getSessionCache()->find( - *this, getApplication(), ignoreAddress ? NULL : getRemoteAddr().c_str(), checkTimeout ? &timeout : NULL + getApplication(), *this, (ignoreAddress ? nullptr : getRemoteAddr().c_str()), (checkTimeout ? &timeout : nullptr) ); if (cache) m_session = session; @@ -127,17 +177,6 @@ void AbstractSPRequest::setRequestURI(const char* uri) m_uri += uri; break; } - else if (*uri == ';') { - // If this is Java being stupid, skip everything up to the query string, if any. - if (!strncmp(uri, ";jsessionid=", 12)) { - if (uri = strchr(uri, '?')) - m_uri += uri; - break; - } - else { - m_uri += *uri; - } - } else if (*uri != '%') { m_uri += *uri; } @@ -153,6 +192,11 @@ void AbstractSPRequest::setRequestURI(const char* uri) } } +const char* AbstractSPRequest::getRequestURI() const +{ + return m_uri.c_str(); +} + const char* AbstractSPRequest::getRequestURL() const { if (m_url.empty()) { @@ -160,32 +204,35 @@ const char* AbstractSPRequest::getRequestURL() const int port = getPort(); const char* scheme = getScheme(); m_url = string(scheme) + "://" + getHostname(); - if ((!strcmp(scheme,"http") && port!=80) || (!strcmp(scheme,"https") && port!=443)) { - ostringstream portstr; - portstr << port; - m_url += ":" + portstr.str(); - } + if (!isDefaultPort()) + m_url += ":" + boost::lexical_cast(port); m_url += m_uri; } return m_url.c_str(); } +string AbstractSPRequest::getRemoteAddr() const +{ + pair addr = getRequestSettings().first->getString("REMOTE_ADDR"); + return addr.first ? getHeader(addr.second) : ""; +} + const char* AbstractSPRequest::getParameter(const char* name) const { - if (!m_parser) - m_parser=new CGIParser(*this); - - pair bounds=m_parser->getParameters(name); - return (bounds.first==bounds.second) ? NULL : bounds.first->second; + if (!m_parser.get()) + m_parser.reset(new CGIParser(*this)); + + pair bounds = m_parser->getParameters(name); + return (bounds.first==bounds.second) ? nullptr : bounds.first->second; } vector::size_type AbstractSPRequest::getParameters(const char* name, vector& values) const { - if (!m_parser) - m_parser=new CGIParser(*this); + if (!m_parser.get()) + m_parser.reset(new CGIParser(*this)); - pair bounds=m_parser->getParameters(name); - while (bounds.first!=bounds.second) { + pair bounds = m_parser->getParameters(name); + while (bounds.first != bounds.second) { values.push_back(bounds.first->second); ++bounds.first; } @@ -197,9 +244,22 @@ const char* AbstractSPRequest::getHandlerURL(const char* resource) const if (!resource) resource = getRequestURL(); - if (!m_handlerURL.empty() && resource && !strcmp(getRequestURL(),resource)) + if (!m_handlerURL.empty() && resource && !strcmp(getRequestURL(), resource)) return m_handlerURL.c_str(); - + + // Check for relative URL. + string stackresource; + if (resource && *resource == '/') { + // Compute a URL to the root of the site and point resource at constructed string. + int port = getPort(); + const char* scheme = getScheme(); + stackresource = string(scheme) + "://" + getHostname(); + if (!isDefaultPort()) + stackresource += ":" + boost::lexical_cast(port); + stackresource += resource; + resource = stackresource.c_str(); + } + #ifdef HAVE_STRCASECMP if (!resource || (strncasecmp(resource,"http://",7) && strncasecmp(resource,"https://",8))) #else @@ -207,24 +267,27 @@ const char* AbstractSPRequest::getHandlerURL(const char* resource) const #endif throw ConfigurationException("Target resource was not an absolute URL."); - bool ssl_only=false; - const char* handler=NULL; - const PropertySet* props=m_app->getPropertySet("Sessions"); + bool ssl_only = true; + const char* handler = nullptr; + const PropertySet* props = getApplication().getPropertySet("Sessions"); if (props) { - pair p=props->getBool("handlerSSL"); + pair p = props->getBool("handlerSSL"); if (p.first) - ssl_only=p.second; - pair p2=props->getString("handlerURL"); + ssl_only = p.second; + pair p2 = props->getString("handlerURL"); if (p2.first) - handler=p2.second; + handler = p2.second; } - - // Should never happen... - if (!handler || (*handler!='/' && strncmp(handler,"http:",5) && strncmp(handler,"https:",6))) + + if (!handler) { + handler = "/Shibboleth.sso"; + } + else if (*handler!='/' && strncmp(handler,"http:",5) && strncmp(handler,"https:",6)) { throw ConfigurationException( - "Invalid handlerURL property ($1) in Application ($2)", + "Invalid handlerURL property ($1) in element for Application ($2)", params(2, handler ? handler : "null", m_app->getId()) ); + } // The "handlerURL" property can be in one of three formats: // @@ -239,7 +302,7 @@ const char* AbstractSPRequest::getHandlerURL(const char* resource) const // // note: if ssl_only is true, make sure the protocol is https - const char* path = NULL; + const char* path = nullptr; // Decide whether to use the handler or the resource for the "protocol" const char* prot; @@ -252,9 +315,9 @@ const char* AbstractSPRequest::getHandlerURL(const char* resource) const } // break apart the "protocol" string into protocol, host, and "the rest" - const char* colon=strchr(prot,':'); + const char* colon = strchr(prot, ':'); colon += 3; - const char* slash=strchr(colon,'/'); + const char* slash = strchr(colon, '/'); if (!path) path = slash;