[cpp-sp] branch main updated: Draft impl of ModuleConfig class for IIS

Scott Cantor cantor.2 at osu.edu
Thu Jan 9 20:20:25 UTC 2025


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository cpp-sp.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=fb9ba32bcaf7e015f2ea6f52ab3709f858d0048c

The following commit(s) were added to refs/heads/main by this push:
     new fb9ba32b Draft impl of ModuleConfig class for IIS
fb9ba32b is described below

commit fb9ba32bcaf7e015f2ea6f52ab3709f858d0048c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Jan 9 15:20:21 2025 -0500

    Draft impl of ModuleConfig class for IIS
---
 iis7_shib/ModuleConfig.cpp       | 182 +++++++++++++++++++++++++++++++++++++++
 iis7_shib/headers/ModuleConfig.h |  49 +++++++++++
 2 files changed, 231 insertions(+)

diff --git a/iis7_shib/ModuleConfig.cpp b/iis7_shib/ModuleConfig.cpp
new file mode 100644
index 00000000..ad297e04
--- /dev/null
+++ b/iis7_shib/ModuleConfig.cpp
@@ -0,0 +1,182 @@
+/**
+ * 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
+ *
+ *    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.
+ */
+
+
+#include "ModuleConfig.h"
+
+#include <shibsp/Agent.h>
+#include <shibsp/AgentConfig.h>
+#include <shibsp/logging/Category.h>
+#include <shibsp/util/BoostPropertySet.h>
+#include <shibsp/util/PathResolver.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <boost/algorithm/string.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/ini_parser.hpp>
+#include <boost/property_tree/xml_parser.hpp>
+
+using namespace shibsp;
+using namespace shibsp::iis;
+using namespace boost::property_tree;
+using namespace std;
+
+namespace {
+
+    class ModuleConfigImpl : public virtual ModuleConfig, public virtual BoostPropertySet {
+    public:
+        ModuleConfigImpl(unique_ptr<ptree> pt, bool xml);
+
+        const PropertySet* getSiteConfig(const char* id) const;
+
+        virtual ~ModuleConfigImpl() {}
+
+    private:
+        void doSites(ptree& parent);
+
+        Category& m_log;
+        unique_ptr<ptree> m_root;
+        map<string,unique_ptr<PropertySet>> m_sites;
+    };
+
+};
+
+ModuleConfig::ModuleConfig() {}
+
+ModuleConfig::~ModuleConfig() {}
+
+ModuleConfigImpl::ModuleConfigImpl(unique_ptr<ptree> pt, bool xml)
+    : m_log(Category::getInstance(SHIBSP_LOGCAT ".IIS")), m_root(move(pt))
+{
+    if (xml) {
+        // Size was checked by caller as 1, so a single child exists.
+        ptree& child = m_root->front().second;
+
+        // Migrate Roles element's attributes to this child for compatibility with INI format.
+        const boost::optional<ptree&> roles = child.get_child_optional("Roles");
+        if (roles) {
+            const boost::optional<ptree&> xmlattr = roles->get_child_optional("<xmlattr>");
+            if (xmlattr) {
+                boost::optional<string> prop = xmlattr->get_optional<string>("authNRole");
+                if (prop) {
+                    child.add("<xmlattr>.authenticatedRole", *prop);
+                }
+                prop = xmlattr->get_optional<string>("roleAttributes");
+                if (prop) {
+                    child.add("<xmlattr>.roleAttributes", *prop);
+                }
+            }
+        }
+
+        // Load the final property set.
+        load(child);
+
+        // Sites are in children of the root element, which is the first child.
+        doSites(child);
+    } else {
+        const boost::optional<ptree&> global = m_root->get_child_optional("global");
+        if (global) {
+            load(global.get());
+        }
+        else {
+            m_log.warn("IIS configuration missing [global] section, using defaults");
+        }
+        // Sites are in children of the root of the tree.
+        doSites(*m_root);
+    }
+}
+
+void ModuleConfigImpl::doSites(ptree& parent)
+{
+    for (auto& child : parent) {
+        if (child.first == "Site") {
+            unique_ptr<BoostPropertySet> propset(new BoostPropertySet());
+            propset->load(child.second);
+
+            const char* id = propset->getString("id");
+
+            if (!id || !propset->hasProperty("name")) {
+                m_log.warn("ignoring Site element without 'id' or 'name' attributes");
+                continue;
+            }
+
+            // Check for Alias children to remap into a delimited string.
+            string aliases;
+            for (const auto& alias : child.second) {
+                if (alias.first == "Alias" && !alias.second.get_value<string>().empty()) {
+                    aliases += alias.second.get_value<string>() + ' ';
+                }
+            }
+            if (!aliases.empty()) {
+                child.second.add("<xmlattr>.aliases", aliases);
+            }
+
+            m_sites[id] = move(propset);
+            m_log.info("installed Site mapping for (%s)", id);
+        }
+        else if (child.first == "<xmlattr>" || child.first == "Roles") {
+            continue;
+        }
+        else {
+            // This is assumed to be an INI format site section. If not, so be it.
+
+            if (!child.second.get_child_optional("name").has_value()) {
+                m_log.warn("ignoring Site section (%s) with no 'name' property", child.first.c_str());
+                continue;
+            }
+
+            unique_ptr<BoostPropertySet> propset(new BoostPropertySet());
+            propset->load(child.second);
+            m_sites[child.first] = move(propset);
+            m_log.info("installed Site mapping for (%s)", child.first.c_str());
+        }
+    }
+}
+
+const PropertySet* ModuleConfigImpl::getSiteConfig(const char* id) const
+{
+    if (id) {
+        auto site = m_sites.find(id);
+        if (site != m_sites.end()) {
+            return site->second.get();
+        }
+    }
+    return nullptr;
+}
+
+unique_ptr<ModuleConfig> ModuleConfig::newModuleConfig()
+{
+    static const char IIS_CONFIG_PATH_PROP_PATH[] = "IISConfigPath";
+
+    string path(AgentConfig::getConfig().getAgent().getString(IIS_CONFIG_PATH_PROP_PATH, "iis-config.ini"));
+    AgentConfig::getConfig().getPathResolver().resolve(path, PathResolver::SHIBSP_CFG_FILE);
+
+    unique_ptr<ptree> config_root(new ptree());
+
+    bool xml = false;
+    if (boost::ends_with(path, ".xml")) {
+        xml_parser::read_xml(path, *config_root, xml_parser::trim_whitespace | xml_parser::no_comments);
+        xml = true;
+        if (config_root->size() != 1) {
+            throw xml_parser_error("XML-based IIS module config did not contain a root element?", path, 1);
+        }
+    }
+    else {
+        ini_parser::read_ini(path, *config_root);
+    }
+
+    return unique_ptr<ModuleConfig>(new ModuleConfigImpl(move(config_root), xml));
+}
diff --git a/iis7_shib/headers/ModuleConfig.h b/iis7_shib/headers/ModuleConfig.h
new file mode 100644
index 00000000..f64a460e
--- /dev/null
+++ b/iis7_shib/headers/ModuleConfig.h
@@ -0,0 +1,49 @@
+/**
+ * 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
+ *
+ *    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.
+ */
+
+#ifndef __shibsp_iisconfig_h__
+#define __shibsp_iisconfig_h__
+
+#include <shibsp/util/BoostPropertySet.h>
+
+#include <memory>
+
+namespace shibsp {
+    namespace iis {
+
+        class ModuleConfig : public virtual PropertySet {
+            MAKE_NONCOPYABLE(ModuleConfig);
+        public:
+            ModuleConfig();
+            virtual ~ModuleConfig();
+
+            /**
+             * Get the configuration for a specific IIS site.
+             * 
+             * @param id site ID
+             * @return site configuration expressed as a PropertySet
+             */
+            const PropertySet* getSiteConfig(const char* id) const;
+
+            /**
+             * Create and return an instance of this class for use.
+             * 
+             * <p>The underlying agent library must be initialized before calling this method.</p>
+             */
+            static std::unique_ptr<ModuleConfig> newModuleConfig();
+        };
+    };
+};
+
+#endif // __shibsp_iisconfig_h__

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list