https://issues.shibboleth.net/jira/browse/SSPCPP-326
[shibboleth/cpp-sp.git] / shibsp / handler / impl / MetadataGenerator.cpp
index f60cea7..fe541b2 100644 (file)
@@ -31,6 +31,7 @@
 #include "SPRequest.h"
 #include "handler/AbstractHandler.h"
 #include "handler/RemotedHandler.h"
+#include "util/IPRange.h"
 
 #ifndef SHIBSP_LITE
 # include "attribute/resolver/AttributeExtractor.h"
@@ -110,7 +111,7 @@ namespace shibsp {
             HTTPResponse& httpResponse
             ) const;
 
-        set<string> m_acl;
+        vector<IPRange> m_acl;
 #ifndef SHIBSP_LITE
         string m_salt;
         short m_http,m_https;
@@ -145,18 +146,34 @@ MetadataGenerator::MetadataGenerator(const DOMElement* e, const char* appId)
     string address(appId);
     address += getString("Location").second;
     setAddress(address.c_str());
+
     if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
         pair<bool,const char*> acl = getString("acl");
         if (acl.first) {
             string aclbuf=acl.second;
             int j = 0;
-            for (unsigned int i=0;  i < aclbuf.length();  i++) {
+            for (unsigned int i=0;  i < aclbuf.length();  ++i) {
                 if (aclbuf.at(i)==' ') {
-                    m_acl.insert(aclbuf.substr(j, i-j));
-                    j = i+1;
+                    try {
+                        m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, i-j).c_str()));
+                    }
+                    catch (exception& ex) {
+                        m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, i-j).c_str(), ex.what());
+                    }
+                    j = i + 1;
                 }
             }
-            m_acl.insert(aclbuf.substr(j, aclbuf.length()-j));
+            try {
+                m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, aclbuf.length()-j).c_str()));
+            }
+            catch (exception& ex) {
+                m_log.error("invalid CIDR block (%s): %s", aclbuf.substr(j, aclbuf.length()-j).c_str(), ex.what());
+            }
+
+            if (m_acl.empty()) {
+                m_log.warn("invalid CIDR range(s) in Metadata Generator acl property, allowing 127.0.0.1 as a fall back");
+                m_acl.push_back(IPRange::parseCIDRBlock("127.0.0.1"));
+            }
         }
     }
 
@@ -255,8 +272,12 @@ MetadataGenerator::MetadataGenerator(const DOMElement* e, const char* appId)
 pair<bool,long> MetadataGenerator::run(SPRequest& request, bool isHandler) const
 {
     SPConfig& conf = SPConfig::getConfig();
-    if (conf.isEnabled(SPConfig::InProcess)) {
-        if (!m_acl.empty() && m_acl.count(request.getRemoteAddr()) == 0) {
+    if (conf.isEnabled(SPConfig::InProcess) && !m_acl.empty()) {
+        bool found = false;
+        for (vector<IPRange>::const_iterator acl = m_acl.begin(); !found && acl != m_acl.end(); ++acl) {
+            found = acl->contains(request.getRemoteAddr().c_str());
+        }
+        if (!found) {
             m_log.error("request for metadata blocked from invalid address (%s)", request.getRemoteAddr().c_str());
             istringstream msg("Metadata Request Blocked");
             return make_pair(true,request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN));