Port up context changes to prevent false spoofing error.
[shibboleth/sp.git] / shibsp / ServiceProvider.cpp
index 18b43f1..df7cf81 100644 (file)
@@ -35,6 +35,7 @@
 #include <sstream>
 #include <xmltooling/XMLToolingConfig.h>
 #include <xmltooling/util/NDC.h>
+#include <xmltooling/util/PathResolver.h>
 #include <xmltooling/util/URLEncoder.h>
 #include <xmltooling/util/XMLHelper.h>
 
@@ -94,7 +95,8 @@ namespace shibsp {
                 pathname=props->getString(page);
         }
         if (pathname.first) {
-            ifstream infile(pathname.second);
+            string fname(pathname.second);
+            ifstream infile(XMLToolingConfig::getConfig().getPathResolver()->resolve(fname, PathResolver::XMLTOOLING_CFG_FILE).c_str());
             if (infile) {
                 tp.setPropertySet(props);
                 stringstream str;
@@ -402,19 +404,10 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
         }
 
         // Export the attributes.
-        bool remoteUserSet = false;
         const multimap<string,const Attribute*>& attributes = session->getIndexedAttributes();
         for (multimap<string,const Attribute*>::const_iterator a = attributes.begin(); a!=attributes.end(); ++a) {
-            const vector<string>& vals = a->second->getSerializedValues();
-
-            // See if this needs to be set as the REMOTE_USER value.
-            if (!remoteUserSet && !vals.empty() && app->getRemoteUserAttributeIds().count(a->first)) {
-                request.setRemoteUser(vals.front().c_str());
-                remoteUserSet = true;
-            }
-
-            // Handle the normal export case.
             string header(request.getSecureHeader(a->first.c_str()));
+            const vector<string>& vals = a->second->getSerializedValues();
             for (vector<string>::const_iterator v = vals.begin(); v!=vals.end(); ++v) {
                 if (!header.empty())
                     header += ";";
@@ -434,6 +427,22 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
             request.setHeader(a->first.c_str(), header.c_str());
         }
 
+        // Check for REMOTE_USER.
+        bool remoteUserSet = false;
+        const vector<string>& rmids = app->getRemoteUserAttributeIds();
+        for (vector<string>::const_iterator rmid = rmids.begin(); !remoteUserSet && rmid != rmids.end(); ++rmid) {
+            pair<multimap<string,const Attribute*>::const_iterator,multimap<string,const Attribute*>::const_iterator> matches =
+                attributes.equal_range(*rmid);
+            while (matches.first != matches.second) {
+                const vector<string>& vals = matches.first->second->getSerializedValues();
+                if (!vals.empty()) {
+                    request.setRemoteUser(vals.front().c_str());
+                    remoteUserSet = true;
+                    break;
+                }
+            }
+        }
+
         return make_pair(false,0L);
     }
     catch (exception& e) {
@@ -457,6 +466,31 @@ pair<bool,long> ServiceProvider::doHandler(SPRequest& request) const
         RequestMapper::Settings settings = request.getRequestSettings();
         app = &(request.getApplication());
 
+        // If not SSL, check to see if we should block or redirect it.
+        if (!request.isSecure()) {
+            pair<bool,const char*> redirectToSSL = settings.first->getString("redirectToSSL");
+            if (redirectToSSL.first) {
+#ifdef HAVE_STRCASECMP
+                if (!strcasecmp("GET",request.getMethod()) || !strcasecmp("HEAD",request.getMethod())) {
+#else
+                if (!stricmp("GET",request.getMethod()) || !stricmp("HEAD",request.getMethod())) {
+#endif
+                    // Compute the new target URL
+                    string redirectURL = string("https://") + request.getHostname();
+                    if (strcmp(redirectToSSL.second,"443")) {
+                        redirectURL = redirectURL + ':' + redirectToSSL.second;
+                    }
+                    redirectURL += request.getRequestURI();
+                    return make_pair(true, request.sendRedirect(redirectURL.c_str()));
+                }
+                else {
+                    TemplateParameters tp;
+                    tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+                    return make_pair(true,sendError(log, request, app, "ssl", tp, false));
+                }
+            }
+        }
+
         const char* handlerURL=request.getHandlerURL(targetURL.c_str());
         if (!handlerURL)
             throw ConfigurationException("Cannot determine handler from resource URL, check configuration.");
@@ -493,6 +527,7 @@ pair<bool,long> ServiceProvider::doHandler(SPRequest& request) const
     catch (exception& e) {
         TemplateParameters tp(&e);
         tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+        tp.m_request = &request;
         return make_pair(true,sendError(log, request, app, "session", tp));
     }
 }