Explorar el Código

HPCC-19393 Implement single-use security manager plugin

- User/pass must be provided to ESP.exe via command line params
- User/pass provided in configtree by the espcfg component
- ESPCfg encrypts password
- Defaults user to "admin" if omitted
- Fail to load if initial password is not provided

Signed-off-by: Rodrigo Pastrana <rodrigo.pastrana@lexisnexis.com>
Rodrigo Pastrana hace 7 años
padre
commit
b1347f3945

+ 37 - 2
esp/platform/espcfg.cpp

@@ -246,6 +246,7 @@ CEspConfig::CEspConfig(IProperties* inputs, IPropertyTree* envpt, IPropertyTree*
     if(inputs)
         m_inputs.setown(inputs);
 
+
     if(!envpt || !procpt)
         return;
 
@@ -281,10 +282,44 @@ CEspConfig::CEspConfig(IProperties* inputs, IPropertyTree* envpt, IPropertyTree*
         startPerformanceMonitor(m_cfg->getPropInt("@perfReportDelay", 60)*1000);
 #endif
 
-        //get the local computer name:              
+        if (m_inputs->hasProp("SingleUserPass"))
+        {
+            StringBuffer plainesppass;
+            StringBuffer encesppass;
+            m_inputs->getProp("SingleUserPass", plainesppass);
+            encrypt(encesppass, plainesppass.str());
+            StringBuffer xpath;
+            xpath.setf("SecurityManagers/SecurityManager[@type=\"SingleUserSecurityManager\"]/SingleUserSecurityManager/");
+            pt_iter = m_cfg->getElements(xpath.str());
+            if (pt_iter!=NULL)
+            {
+                IPropertyTree *ptree = NULL;
+                pt_iter->first();
+                while(pt_iter->isValid())
+                {
+                    ptree = &pt_iter->query();
+                    if (ptree)
+                    {
+                        ptree->setProp("@SingleUserPass",  encesppass.str());
+
+                        if (m_inputs->hasProp("SingleUserName"))
+                        {
+                            StringBuffer espusername;
+                            m_inputs->getProp("SingleUserName", espusername);
+                            ptree->setProp("@SingleUserName",  espusername.str());
+                        }
+                    }
+                    pt_iter->next();
+                }
+                pt_iter->Release();
+                pt_iter=NULL;
+            }
+        }
+
+        //get the local computer name:
         m_cfg->getProp("@computer", m_computer);
 
-        //get the local computer information:               
+        //get the local computer information:
         StringBuffer xpath;
         xpath.appendf("Hardware/Computer[@name=\"%s\"]", m_computer.str());
 

+ 1 - 0
system/security/CMakeLists.txt

@@ -27,3 +27,4 @@ endif()
 IF (USE_APR)
   HPCC_ADD_SUBDIRECTORY (plugins/htpasswdSecurity)
 ENDIF(USE_APR)
+HPCC_ADD_SUBDIRECTORY (plugins/singleuserSecurity)

+ 52 - 0
system/security/plugins/singleuserSecurity/CMakeLists.txt

@@ -0,0 +1,52 @@
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems®.
+#
+#    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.
+################################################################################
+
+
+# Component: SingleUserSecurity
+#####################################################
+# Description:
+# ------------
+#    Cmake Input File for SingleUserSecurity
+#####################################################
+
+project( SingleUserSecurity )
+
+HPCC_ADD_SUBDIRECTORY (initfiles)
+
+set (    SRCS
+         ${HPCC_SOURCE_DIR}/system/security/shared/authmap.cpp
+         ${HPCC_SOURCE_DIR}/system/security/shared/caching.cpp
+         ${CMAKE_CURRENT_SOURCE_DIR}/singleUserSecurity.cpp
+    )
+
+include_directories (
+         ${HPCC_SOURCE_DIR}/system/include
+         ${HPCC_SOURCE_DIR}/system/security/shared
+         ${HPCC_SOURCE_DIR}/system/jlib
+         ${HPCC_SOURCE_DIR}/esp/platform
+         ${HPCC_SOURCE_DIR}/dali/base
+    )
+
+ADD_DEFINITIONS( -DSINGLEUSERSECURITY_EXPORTS -D_USRDLL )
+
+HPCC_ADD_LIBRARY( singleUserSecurity SHARED ${SRCS} )
+install ( TARGETS singleUserSecurity RUNTIME DESTINATION ${EXEC_DIR} LIBRARY DESTINATION ${LIB_DIR} )
+target_link_libraries ( singleUserSecurity
+         jlib
+         dalibase
+    )
+
+

+ 20 - 0
system/security/plugins/singleuserSecurity/initfiles/CMakeLists.txt

@@ -0,0 +1,20 @@
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems.
+#
+#    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.
+################################################################################
+
+cmake_minimum_required(VERSION 2.8)
+PROJECT(initfiles)
+
+ADD_SUBDIRECTORY(componentfiles)

+ 17 - 0
system/security/plugins/singleuserSecurity/initfiles/componentfiles/CMakeLists.txt

@@ -0,0 +1,17 @@
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems.
+#
+#    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.
+################################################################################
+
+ADD_SUBDIRECTORY(configxml)

+ 19 - 0
system/security/plugins/singleuserSecurity/initfiles/componentfiles/configxml/CMakeLists.txt

@@ -0,0 +1,19 @@
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems.
+#
+#    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.
+################################################################################
+
+Install ( FILES "${CMAKE_CURRENT_SOURCE_DIR}/singleuser_secmgr.xsd"  DESTINATION "componentfiles/configxml" COMPONENT Runtime)
+Install ( FILES "${CMAKE_CURRENT_SOURCE_DIR}/buildset.xml"           DESTINATION "componentfiles/configxml/plugins/singleuser_secmgr" COMPONENT Runtime)
+Install ( FILES "${CMAKE_CURRENT_SOURCE_DIR}/genenvrules.conf"       DESTINATION "componentfiles/configxml/plugins/singleuser_secmgr" COMPONENT Runtime)

+ 32 - 0
system/security/plugins/singleuserSecurity/initfiles/componentfiles/configxml/buildset.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems.
+#
+#    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.
+################################################################################
+-->
+<Environment>
+  <Programs>
+    <Build name="_" url="/opt/HPCCSystems">
+      <BuildSet deployable="no"
+                installSet="deploy_map.xml"
+                name="singleusersecmgr"
+                path="componentfiles/singleusersecmgr"
+                processName="SingleUserSecurityManager"
+                schema="singleuser_secmgr.xsd">
+      </BuildSet>
+    </Build>
+  </Programs>
+</Environment>
+ 

+ 1 - 0
system/security/plugins/singleuserSecurity/initfiles/componentfiles/configxml/genenvrules.conf

@@ -0,0 +1 @@
+do_not_generate=singleusersecmgr

+ 63 - 0
system/security/plugins/singleuserSecurity/initfiles/componentfiles/configxml/singleuser_secmgr.xsd

@@ -0,0 +1,63 @@
+<!--
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems.
+#
+#    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.
+################################################################################
+-->
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+  <xs:element name="SingleUserSecMgr">
+    <xs:complexType>
+
+      <!-- All SecurityManager Plugins must define the type="SecurityManager" attribute -->
+      <xs:attribute name="type" type="SecurityManager" use="required" default="SecurityManager">
+        <xs:annotation>
+          <xs:appinfo>
+            <viewType>hidden</viewType>
+          </xs:appinfo>
+        </xs:annotation>
+      </xs:attribute>
+
+      <!-- All SecurityManager Plugins must define the libName attribute -->
+      <xs:attribute name="libName" type="xs:string" use="optional" default="libsingleUserSecurity.so">
+        <xs:annotation>
+          <xs:appinfo>
+            <tooltip>The Security Manager library name (.so) and optional path</tooltip>
+          </xs:appinfo>
+        </xs:annotation>
+      </xs:attribute>
+
+      <!-- All SecurityManager Plugins must define the instanceFactoryName attribute -->
+      <xs:attribute name="instanceFactoryName" type="xs:string" use="optional" default="createInstance">
+        <xs:annotation>
+          <xs:appinfo>
+            <tooltip>Class Factory method name in the Security Manager library (.so)</tooltip>
+          </xs:appinfo>
+        </xs:annotation>
+      </xs:attribute>
+
+      <!-- All SecurityManager Plugins must define the (instance) name attribute -->
+      <xs:attribute name="name" type="xs:string" use="required">
+        <xs:annotation>
+          <xs:appinfo>
+            <tooltip>Name for this SingleUser Security Manager instance</tooltip>
+            <required>true</required>
+          </xs:appinfo>
+        </xs:annotation>
+      </xs:attribute>
+
+    </xs:complexType>
+  </xs:element>
+</xs:schema>

+ 210 - 0
system/security/plugins/singleuserSecurity/singleUserSecurity.cpp

@@ -0,0 +1,210 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems®.
+
+    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.
+############################################################################## */
+
+#pragma warning( disable : 4786 )
+
+#include "basesecurity.hpp"
+#include "authmap.ipp"
+#include "singleUserSecurity.hpp"
+
+class CSingleUserSecurityManager : public CBaseSecurityManager
+{
+public:
+    CSingleUserSecurityManager(const char * serviceName, IPropertyTree * secMgrCfg, IPropertyTree * bindConfig) : CBaseSecurityManager(serviceName, (IPropertyTree *)NULL)
+    {
+        if (secMgrCfg)
+        {
+            if (secMgrCfg->hasProp("@SingleUserName"))
+                secMgrCfg->getProp("@SingleUserName", m_userName);
+            else
+                m_userName.set("admin");
+            PROGLOG("SingleUserAuth: User set '%s'", m_userName.str());
+
+            secMgrCfg->getProp("@SingleUserPass", m_userPass);
+            if (m_userPass.isEmpty())
+                throw MakeStringException(-1,"SingleUserAuth: Password not supplied and could not set up security manager!");
+        }
+        else
+           throw MakeStringException(-1, "SingleUserAuth did not receive security manager configuration!");
+    }
+
+    ~CSingleUserSecurityManager() {}
+
+    secManagerType querySecMgrType() override
+    {
+        return SMT_SingleUser;
+    }
+
+    inline virtual const char * querySecMgrTypeName() override { return "singleuser"; }
+
+    IAuthMap * createAuthMap(IPropertyTree * authconfig) override
+    {
+        CAuthMap * authmap = new CAuthMap(this);
+
+        Owned<IPropertyTreeIterator> loc_iter = authconfig->getElements(".//Location");
+        ForEach(*loc_iter)
+        {
+            IPropertyTree & location = loc_iter->query();
+            StringBuffer pathstr, rstr, required, description;
+            location.getProp("@path", pathstr);
+            location.getProp("@resource", rstr);
+            location.getProp("@required", required);
+            location.getProp("@description", description);
+
+            if(pathstr.length() == 0)
+                throw MakeStringException(-1, "path empty in Authenticate/Location");
+            if(rstr.length() == 0)
+                throw MakeStringException(-1, "resource empty in Authenticate/Location");
+
+            ISecResourceList * rlist = authmap->queryResourceList(pathstr.str());
+            if(rlist == NULL)
+            {
+                rlist = createResourceList("singleusersecurity");
+                authmap->add(pathstr.str(), rlist);
+            }
+            ISecResource * rs = rlist->addResource(rstr.str());
+            SecAccessFlags requiredaccess = str2perm(required.str());
+            rs->setRequiredAccessFlags(requiredaccess);
+            rs->setDescription(description.str());
+            rs->setAccessFlags(SecAccess_Full);//grant full access to authenticated users
+        }
+
+        return authmap;
+    }
+
+    IAuthMap * createFeatureMap(IPropertyTree * authconfig) override
+    {
+        CAuthMap * feature_authmap = new CAuthMap(this);
+        Owned<IPropertyTreeIterator> feature_iter = authconfig->getElements(".//Feature");
+        ForEach(*feature_iter)
+        {
+            IPropertyTree * feature = &feature_iter->query();
+            if (feature)
+            {
+                StringBuffer pathstr, rstr, required, description;
+                feature->getProp("@path", pathstr);
+                feature->getProp("@resource", rstr);
+                feature->getProp("@required", required);
+                feature->getProp("@description", description);
+                ISecResourceList * rlist = feature_authmap->queryResourceList(pathstr.str());
+                if(rlist == NULL)
+                {
+                    rlist = createResourceList(pathstr.str());
+                    feature_authmap->add(pathstr.str(), rlist);
+                }
+                if (!rstr.isEmpty())
+                {
+                    ISecResource * rs = rlist->addResource(rstr.str());
+                    SecAccessFlags requiredaccess = str2perm(required.str());
+                    rs->setRequiredAccessFlags(requiredaccess);
+                    rs->setDescription(description.str());
+                    rs->setAccessFlags(SecAccess_Full);//grant full access to authenticated users
+                }
+            }
+        }
+
+        return feature_authmap;
+    }
+    bool logoutUser(ISecUser & user) override { return true; }
+
+protected:
+
+    //ISecManager
+    bool IsPasswordValid(ISecUser& sec_user)
+    {
+        StringBuffer username;
+        username.set(sec_user.getName());
+        if (0 == username.length())
+            throw MakeStringException(-1, "SingleUserAuth name is empty");
+
+        if (sec_user.credentials().getSessionToken() != 0  || !isEmptyString(sec_user.credentials().getSignature()))//Already authenticated it token or signature exist
+            return true;
+
+        if (strcmp(username.str(), m_userName.str())!=0)
+        {
+            WARNLOG("SingleUserAuth: Invalid credentials provided!");
+            return false;
+        }
+
+        if (m_userPass.isEmpty())
+            throw MakeStringException(-1, "SingleUserAuth password was not set!");
+
+        const char * userpass = sec_user.credentials().getPassword();
+        if (!userpass || !*userpass)
+            throw MakeStringException(-1, "SingleUserAuth encountered empty password!");
+
+        StringBuffer encpass;
+        encrypt(encpass, userpass);
+        if (strcmp(m_userPass.str(), encpass.str())!=0)
+        {
+            WARNLOG("SingleUserAuth: Invalid credentials provided!");
+            return false;
+        }
+        return true;
+    }
+
+    const char * getDescription() override
+    {
+        return "SingleUser Security Manager";
+    }
+
+    bool authorize(ISecUser & user, ISecResourceList * resources, IEspSecureContext * secureContext) override
+    {
+        return IsPasswordValid(user);
+    }
+
+    unsigned getPasswordExpirationWarningDays() override
+    {
+        return -2;//never expires
+    }
+
+    SecAccessFlags authorizeEx(SecResourceType rtype, ISecUser & user, const char * resourcename, IEspSecureContext * secureContext) override
+    {
+        return SecAccess_Full;//grant full access to authenticated users
+    }
+
+    SecAccessFlags getAccessFlagsEx(SecResourceType rtype, ISecUser& sec_user, const char * resourcename) override
+    {
+        return SecAccess_Full;//grant full access to authenticated users
+    }
+
+    SecAccessFlags authorizeFileScope(ISecUser & user, const char * filescope) override
+    {
+        return SecAccess_Full;//grant full access to authenticated users
+    }
+
+    SecAccessFlags authorizeWorkunitScope(ISecUser & user, const char * filescope) override
+    {
+        return SecAccess_Full;//grant full access to authenticated users
+    }
+
+private:
+
+private:
+    StringBuffer    m_userPass;
+    StringBuffer    m_userName;
+};
+
+extern "C"
+{
+    SINGLEUSERSECURITY_API ISecManager * createInstance(const char * serviceName, IPropertyTree &secMgrCfg, IPropertyTree &bndCfg)
+    {
+        return new CSingleUserSecurityManager(serviceName, &secMgrCfg, &bndCfg);
+    }
+
+}
+

+ 36 - 0
system/security/plugins/singleuserSecurity/singleUserSecurity.hpp

@@ -0,0 +1,36 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems®.
+
+    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 SINGLEUSERSECURITY_HPP_
+#define SINGLEUSERSECURITY_HPP_
+
+#ifndef SINGLEUSERSECURITY_API
+
+#ifndef SINGLEUSERSECURITY_EXPORTS
+    #define SINGLEUSERSECURITY_API DECL_IMPORT
+#else
+    #define SINGLEUSERSECURITY_API DECL_EXPORT
+#endif //SINGLEUSERSECURITY_EXPORTS
+
+#endif 
+
+extern "C" 
+{
+    SINGLEUSERSECURITY_API ISecManager * createInstance(const char *serviceName, IPropertyTree &secMgrCfg, IPropertyTree &bndCfg);
+}
+
+#endif //  SINGLEUSERSECURITY_HPP

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

@@ -292,6 +292,7 @@ enum secManagerType : int
     SMT_Local,
     SMT_LDAP,
     SMT_HTPasswd,
+    SMT_SingleUser,
     SMT_HTPluggable
 };
 interface IEspSecureContext;