Преглед на файлове

HPCC-14698 Security Manager code needed to support plug-in sec managers

This PR implements a new "pluggable" security manager feature, while maintaining
backward camptibility for environment files that continue to specify the legacy
configuration methodologies . If the "<SecurityManager> tag is found, it is
assumed this is a dynamic/pluggable manager, and the SO/DLL will be loaded
and the ISecManager factory method specified in the config will be invoked to
instantiate an instance.

Signed-off-by: Russ Whitehead <william.whitehead@lexisnexis.com>
Russ Whitehead преди 9 години
родител
ревизия
7956a70710
променени са 3 файла, в които са добавени 83 реда и са изтрити 6 реда
  1. 40 4
      esp/bindings/http/platform/httpbinding.cpp
  2. 0 2
      system/security/shared/seclib.hpp
  3. 43 0
      system/security/shared/secloader.hpp

+ 40 - 4
esp/bindings/http/platform/httpbinding.cpp

@@ -177,9 +177,45 @@ EspHttpBinding::EspHttpBinding(IPropertyTree* tree, const char *bindname, const
         Owned<IPropertyTree> authcfg = bnd_cfg->getPropTree("Authenticate");
         if(authcfg != NULL)
         {
+#ifdef _DEBUG
+            StringBuffer authXml;
+            toXML(authcfg, authXml);
+            PROGLOG("\nAUTHENTICATE(%s) PROPS\n%s\n", bindname, authXml.str());
+#endif
+            //Instantiate a Security Manager
             m_authtype.set(authcfg->queryProp("@type"));
             m_authmethod.set(authcfg->queryProp("@method"));
-            PROGLOG("Authenticate method=%s", m_authmethod.str());
+            if (!m_authmethod.isEmpty())
+            {
+                PROGLOG("Authenticate method=%s", m_authmethod.str());
+                Owned<IPropertyTree> process_config = getProcessConfig(tree, procname);
+
+                Owned<IPropertyTree> secMgrCfg;
+                if(process_config.get() != NULL)
+                    secMgrCfg.setown(process_config->getPropTree("SecurityManager"));//Is this a Pluggable Security Manager
+                if (secMgrCfg)
+                {
+#ifdef _DEBUG
+                    StringBuffer secMgrXml;
+                    toXML(secMgrCfg, secMgrXml);
+                    PROGLOG("\nSECURITY MANAGER(%s) PROPS\n%s\n", bindname, secMgrXml.str());
+#endif
+                    //This is a Pluggable Security Manager
+                    StringBuffer secMgrType;
+                    secMgrCfg->getProp("@type", secMgrType);
+                    if (!secMgrType.isEmpty() && 0==strcmp(secMgrType.str(), m_authmethod.str()))
+                    {
+                        m_secmgr.setown(SecLoader::loadPluggableSecManager(bindname, authcfg, secMgrCfg));
+                        m_authmap.setown(m_secmgr->createAuthMap(authcfg));//???
+                    }
+                    else
+                    {
+                        throw MakeStringException(-1, "Authorization type %s not found in SecurityManager configuration for %s", m_authmethod.str(), bindname);
+                    }
+                }
+                else
+                {
+            //Legacy Security Manager
             if(stricmp(m_authmethod.str(), "LdapSecurity") == 0)
             {
                 StringBuffer lsname;
@@ -187,7 +223,6 @@ EspHttpBinding::EspHttpBinding(IPropertyTree* tree, const char *bindname, const
                 Owned<IPropertyTree> lscfg = bnd_cfg->getPropTree(StringBuffer(".//ldapSecurity[@name=").appendf("\"%s\"]", lsname.str()).str());
                 if(lscfg == NULL)
                 {
-                    Owned<IPropertyTree> process_config = getProcessConfig(tree, procname);
                     if(process_config.get() != NULL)
                         lscfg.setown(process_config->getPropTree(StringBuffer("ldapSecurity[@name=").appendf("\"%s\"]", lsname.str()).str()));
                     if(lscfg == NULL)
@@ -202,7 +237,7 @@ EspHttpBinding::EspHttpBinding(IPropertyTree* tree, const char *bindname, const
                 {
                     throw MakeStringException(-1, "error generating SecManager");
                 }
-                
+
                 StringBuffer basednbuf;
                 authcfg->getProp("@resourcesBasedn", basednbuf);
                 m_secmgr->setExtraParam("resourcesBasedn", basednbuf.str());
@@ -221,7 +256,6 @@ EspHttpBinding::EspHttpBinding(IPropertyTree* tree, const char *bindname, const
             else if(stricmp(m_authmethod.str(), "htpasswd") == 0)
             {
                 Owned<IPropertyTree> cfg;
-                Owned<IPropertyTree> process_config = getProcessConfig(tree, procname);
                 if(process_config.get() != NULL)
                     cfg.setown(process_config->getPropTree("htpasswdSecurity"));
                 if(cfg == NULL)
@@ -240,6 +274,8 @@ EspHttpBinding::EspHttpBinding(IPropertyTree* tree, const char *bindname, const
                 if(pHandler!=NULL)
                     restartManager->setRestartHandler(pHandler);
             }
+            }
+            }
         }
     }
 

+ 0 - 2
system/security/shared/seclib.hpp

@@ -324,8 +324,6 @@ interface IRestartManager : extends IInterface
     virtual void setRestartHandler(IRestartHandler * pRestartHandler) = 0;
 };
 
-extern "C" SECLIB_API ISecManager *createSecManager(const char *model_name, const char *serviceName, IPropertyTree &config);
-extern "C" SECLIB_API IAuthMap *createDefaultAuthMap(IPropertyTree* config);
 
 
 #endif

+ 43 - 0
system/security/shared/secloader.hpp

@@ -21,10 +21,53 @@
 
 typedef IAuthMap* (*createDefaultAuthMap_t_)(IPropertyTree* config);
 typedef ISecManager* (*newSecManager_t_)(const char *serviceName, IPropertyTree &config);
+typedef ISecManager* (*newPluggableSecManager_t_)(const char *serviceName, IPropertyTree &secMgrCfg, IPropertyTree &authCfg);
 
 class SecLoader
 {
 public:
+    ///
+    /// Method:  loadPluggableSecManager
+    ///
+    /// Using the given configuration property trees, this method loads the specified
+    /// Security Manager DLL/SO implemented in the specified library file and calls
+    /// its instance factory to create and return an ISecManager security manager instance
+    /// for the given ESP service
+    ///
+    /// @param  svcName         Service name ie 'WsTopology_smc_myesp'
+    /// @param  secMgrCfg       'SecurityManager' IPropertyTree from component config file
+    /// @param  authCfg         'Authenticate' IPropertyTree from EspService component binding
+    ///
+    /// @return an ISecManager Security Manager instance
+    ///
+    static ISecManager* loadPluggableSecManager(const char * svcName, IPropertyTree* authCfg, IPropertyTree* secMgrCfg)
+    {
+        const char * lsm = "Load Security Manager :";
+
+        StringBuffer libName, instFactory;
+        secMgrCfg->getProp("@LibName", libName);
+        if (libName.isEmpty())
+            throw MakeStringException(-1, "%s library name not specified for %s", lsm, svcName);
+        //TODO Search for LibName in plugins folder, or in specified location
+
+        instFactory.set(secMgrCfg->queryProp("@InstanceFactoryName"));
+        if (instFactory.isEmpty())
+            instFactory.set("createInstance");
+
+        //Load the DLL/SO
+        HINSTANCE pluggableSecLib = LoadSharedObject(libName.str(), true, false);
+        if(pluggableSecLib == NULL)
+            throw MakeStringException(-1, "%s can't load library %s for %s", lsm, libName.str(), svcName);
+
+        //Retrieve address of exported ISecManager instance factory
+        newPluggableSecManager_t_ xproc = NULL;
+        xproc = (newPluggableSecManager_t_)GetSharedProcedure(pluggableSecLib, instFactory.str());
+        if (xproc == NULL)
+            throw MakeStringException(-1, "%s cannot locate procedure %s of '%s'", lsm, instFactory.str(), libName.str());
+
+        //Call ISecManager instance factory and return the new instance
+        return xproc(svcName, *secMgrCfg, *authCfg);
+    }
     static ISecManager* loadSecManager(const char* model_name, const char* servicename, IPropertyTree* cfg)
     {
         if (!model_name || !*model_name)