X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-sp.git;a=blobdiff_plain;f=nsapi_shib%2Fnsapi_shib.cpp;h=ef979327493df9d640536f5cae6187e8d3e28ae0;hp=1925021e4c151b3174283d416837f1bc466c800b;hb=3ea5b63fd99233bc4aaff07397c5fec840e5a750;hpb=6dfee404fa4fe0b4628d9b33f227e113a824a00e diff --git a/nsapi_shib/nsapi_shib.cpp b/nsapi_shib/nsapi_shib.cpp index 1925021..ef97932 100644 --- a/nsapi_shib/nsapi_shib.cpp +++ b/nsapi_shib/nsapi_shib.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005 Internet2 + * 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. @@ -66,6 +66,7 @@ namespace { ShibTargetConfig* g_Config=NULL; string g_ServerName; string g_unsetHeaderValue; + set g_allowedSchemes; bool g_checkSpoofing = false; bool g_catchAll = true; } @@ -146,14 +147,32 @@ extern "C" NSAPI_PUBLIC int nsapi_shib_init(pblock* pb, Session* sn, Request* rq Locker locker(conf); const IPropertySet* props=conf->getPropertySet("Local"); if (props) { - pair unsetValue=props->getString("unsetHeaderValue"); - if (unsetValue.first) - g_unsetHeaderValue = unsetValue.second; + pair str=props->getString("unsetHeaderValue"); + if (str.first) + g_unsetHeaderValue = str.second; + + str=props->getString("allowedSchemes"); + if (str.first) { + string schemes=str.second; + unsigned int j=0; + for (unsigned int i=0; i < schemes.length(); i++) { + if (schemes.at(i)==' ') { + g_allowedSchemes.insert(schemes.substr(j, i-j)); + j = i+1; + } + } + g_allowedSchemes.insert(schemes.substr(j, schemes.length()-j)); + } + pair flag=props->getBool("checkSpoofing"); g_checkSpoofing = !flag.first || flag.second; flag=props->getBool("catchAll"); g_catchAll = !flag.first || flag.second; } + if (g_allowedSchemes.empty()) { + g_allowedSchemes.insert("https"); + g_allowedSchemes.insert("http"); + } } catch (exception&) { g_Config=NULL; @@ -168,6 +187,14 @@ extern "C" NSAPI_PUBLIC int nsapi_shib_init(pblock* pb, Session* sn, Request* rq class ShibTargetNSAPI : public ShibTarget { + void checkString(const string& s, const char* msg) { + string::const_iterator e = s.end(); + for (string::const_iterator i=s.begin(); i!=e; ++i) { + if (iscntrl(*i)) + throw FatalProfileException(msg); + } + } + public: ShibTargetNSAPI(pblock* pb, Session* sn, Request* rq) : m_pb(pb), m_sn(sn), m_rq(rq), m_firsttime(true) { @@ -350,12 +377,15 @@ public: const string& content_type="text/html", const saml::Iterator& headers=EMPTY(header_t) ) { + checkString(content_type, "Detected control character in a response header."); param_free(pblock_remove("content-type", m_rq->srvhdrs)); pblock_nvinsert("content-type", content_type.c_str(), m_rq->srvhdrs); pblock_nninsert("content-length", msg.length(), m_rq->srvhdrs); pblock_nvinsert("connection","close",m_rq->srvhdrs); while (headers.hasNext()) { const header_t& h=headers.next(); + checkString(h.first, "Detected control character in a response header."); + checkString(h.second, "Detected control character in a response header."); pblock_nvinsert(h.first.c_str(), h.second.c_str(), m_rq->srvhdrs); } protocol_status(m_sn, m_rq, code, NULL); @@ -364,6 +394,9 @@ public: return (void*)REQ_EXIT; } virtual void* sendRedirect(const string& url) { + checkString(url, "Detected control character in an attempted redirect."); + if (g_allowedSchemes.find(url.substr(0, url.find(':'))) == g_allowedSchemes.end()) + throw FatalProfileException("Invalid scheme in attempted redirect."); param_free(pblock_remove("content-type", m_rq->srvhdrs)); pblock_nninsert("content-length", 0, m_rq->srvhdrs); pblock_nvinsert("expires", "01-Jan-1997 12:00:00 GMT", m_rq->srvhdrs);