Browse Source

Merge pull request #11547 from RussWhitehead/daliCore

HPCC-20220 Dali cores when getPermissions called internally

Reviewed-by: Gavin Halliday <ghalliday@hpccsystems.com>
Gavin Halliday 6 years ago
parent
commit
afc4312da0

+ 2 - 1
common/workunit/workunit.cpp

@@ -6426,7 +6426,8 @@ void CLocalWorkUnit::remoteCheckAccess(IUserDescriptor *user, bool writeaccess)
     if (scopename&&*scopename) {
         if (!user)
             user = queryUserDescriptor();
-        perm = querySessionManager().getPermissionsLDAP("workunit",scopename,user,auditflags);
+        CDateTime now;
+        perm = querySessionManager().getPermissionsLDAP("workunit",scopename,user,auditflags,nullptr,now);
         if (perm<0) {
             if (perm == SecAccess_Unavailable)
                 perm = SecAccess_Full;

+ 7 - 1
dali/base/dadfs.cpp

@@ -1256,7 +1256,13 @@ static SecAccessFlags getScopePermissions(const char *scopename,IUserDescriptor
 #endif
             user = queryDistributedFileDirectory().queryDefaultUser();
         }
-        perms = querySessionManager().getPermissionsLDAP(queryDfsXmlBranchName(DXB_Scope),scopename,user,auditflags);
+
+        //Create signature
+        CDateTime now;
+        StringBuffer b64sig;
+        createDaliSignature(scopename, user, now, b64sig);
+
+        perms = querySessionManager().getPermissionsLDAP(queryDfsXmlBranchName(DXB_Scope),scopename,user,auditflags, b64sig.str(), now);
         if (perms<0) {
             if (perms == SecAccess_Unavailable) {
                 scopePermissionsAvail=false;

+ 46 - 47
dali/base/dasess.cpp

@@ -79,7 +79,7 @@ interface ISessionManagerServer: implements IConnectionMonitor
     virtual void addSession(SessionId id) = 0;
     virtual SessionId lookupProcessSession(INode *node) = 0;
     virtual INode *getProcessSessionNode(SessionId id) =0;
-    virtual SecAccessFlags getPermissionsLDAP(const char *key,const char *obj,IUserDescriptor *udesc,unsigned flags, const char * reqSignature, CDateTime * reqUTCTimestamp, int *err)=0;
+    virtual SecAccessFlags getPermissionsLDAP(const char *key,const char *obj,IUserDescriptor *udesc,unsigned flags, const char * reqSignature, CDateTime & reqUTCTimestamp, int *err)=0;
     virtual bool clearPermissionsCache(IUserDescriptor *udesc) = 0;
     virtual void stopSession(SessionId sessid,bool failed) = 0;
     virtual void setClientAuth(IDaliClientAuthConnection *authconn) = 0;
@@ -453,46 +453,23 @@ public:
     }
 };
 
-
-//Helper class to Serialize/deserialize digital signature of "scope;username;timestamp" and request timestamp
-class CDaliMessageSignatureHelper
+bool createDaliSignature(const char * scope, IUserDescriptor *udesc, CDateTime &now, StringBuffer &b64sig)
 {
-public:
-    static void serializeSignature(const char * scope, IUserDescriptor *udesc, MemoryBuffer &mb)
+    IDigitalSignatureManager * pDSM = queryDigitalSignatureManagerInstanceFromEnv();
+    if (pDSM && pDSM->isDigiSignerConfigured())
     {
-		IDigitalSignatureManager * pDSM = queryDigitalSignatureManagerInstanceFromEnv();
-		if (pDSM && pDSM->isDigiSignerConfigured())
-		{
-            //Serialize timestamp and signature of "scope;username;timestamp"
-            //Dali will use this to ensure request came from
-            //valid authenticated user within a reasonable timeframe
-            StringBuffer username;
-            udesc->getUserName(username);
-            CDateTime now;
-            now.setNow();
-            StringBuffer timeStr;
-            now.getString(timeStr, false);//get UTC timestamp
-            VStringBuffer toSign("%s;%s;%s", scope, username.str(), timeStr.str());
+        StringBuffer username;
+        udesc->getUserName(username);
+        StringBuffer timeStr;
+        now.setNow();
+        now.getString(timeStr, false);//get UTC timestamp
+        VStringBuffer toSign("%s;%s;%s", scope, username.str(), timeStr.str());
 
-            StringBuffer b64sig;
-            pDSM->digiSign(toSign, b64sig);//Sign "scope;username;timeStamp"
-
-            //Serialize the signature, and the timestamp object
-            mb.append(b64sig.str());
-            now.serialize(mb);
-        }
-    }
-
-    static void deserializeSignature(MemoryBuffer &mb, StringBuffer & signature, CDateTime & utcTimeStamp)
-    {
-        if (mb.remaining() > 0)
-        {
-            mb.read(signature);
-            utcTimeStamp.deserialize(mb);
-        }
+        pDSM->digiSign(toSign, b64sig);//Sign "scope;username;timeStamp"
+        return true;
     }
-};
-
+    return false;
+}
 
 class CSessionRequestServer: public Thread
 {
@@ -647,11 +624,13 @@ public:
 
                 StringBuffer reqSignature;
                 CDateTime reqUTCTimestamp;
-                if (queryDaliServerVersion().compare("3.15") >= 0)
-                    CDaliMessageSignatureHelper::deserializeSignature(mb, reqSignature, reqUTCTimestamp);
-
+                if (mb.remaining() > 0)
+                {
+                    mb.read(reqSignature);
+                    reqUTCTimestamp.deserialize(mb);
+                }
                 int err = 0;
-                SecAccessFlags perms = manager.getPermissionsLDAP(key,obj,udesc,auditflags,reqSignature.str(),&reqUTCTimestamp,&err);
+                SecAccessFlags perms = manager.getPermissionsLDAP(key,obj,udesc,auditflags,reqSignature.str(),reqUTCTimestamp,&err);
                 mb.clear().append((int)perms);
                 if (err)
                     mb.append(err);
@@ -930,7 +909,7 @@ public:
     }
 
 
-    SecAccessFlags getPermissionsLDAP(const char *key,const char *obj,IUserDescriptor *udesc,unsigned auditflags,const char * reqSignature, CDateTime * reqUTCTimestamp, int *err)
+    SecAccessFlags getPermissionsLDAP(const char *key,const char *obj,IUserDescriptor *udesc,unsigned auditflags,const char * reqSignature, CDateTime & reqUTCTimestamp, int *err)
     {
         if (err)
             *err = 0;
@@ -958,8 +937,26 @@ public:
 #endif
         udesc->serialize(mb);
         mb.append(auditflags);
+
+        //Serialize signature. If not provided, compute it
         if (queryDaliServerVersion().compare("3.15") >= 0)
-            CDaliMessageSignatureHelper::serializeSignature(obj, udesc, mb);//serialize scope, signature, timestamp
+        {
+            if (isEmptyString(reqSignature))
+            {
+                CDateTime now;
+                StringBuffer b64sig;
+                createDaliSignature(obj, udesc, now, b64sig);
+                mb.append(b64sig.str());
+                now.serialize(mb);
+            }
+            else
+            {
+                mb.append(reqSignature);
+                reqUTCTimestamp.serialize(mb);
+            }
+        }
+
+
         if (!queryCoven().sendRecv(mb,RANK_RANDOM,MPTAG_DALI_SESSION_REQUEST,SESSIONREPLYTIMEOUT))
             return SecAccess_None;
         SecAccessFlags perms = SecAccess_Unavailable;
@@ -1193,12 +1190,13 @@ public:
     {
         running = false;
     }
-    void start(const char *_key,const char *_obj,IUserDescriptor *_udesc,unsigned _flags,const char * _reqSignature, CDateTime * _reqUTCTimestamp)
+    void start(const char *_key,const char *_obj,IUserDescriptor *_udesc,unsigned _flags,const char * _reqSignature, CDateTime & _reqUTCTimestamp)
     {
         key.set(_key);
         obj.set(_obj); 
         reqSignature.set(_reqSignature);
-        reqUTCTimestamp.set(*_reqUTCTimestamp);
+        if (!_reqUTCTimestamp.isNull())
+            reqUTCTimestamp.set(_reqUTCTimestamp);
 
 #ifdef NULL_DALIUSER_STACKTRACE
         StringBuffer sb;
@@ -1227,7 +1225,7 @@ public:
             if (!running)
                 break;
             try {
-                ret = ldapconn->getPermissions(key,obj,udesc,flags,reqSignature.str(),&reqUTCTimestamp);
+                ret = ldapconn->getPermissions(key,obj,udesc,flags,reqSignature.str(),reqUTCTimestamp);
             }
             catch(IException *e) {
                 LOG(MCoperatorError, unknownJob, e, "CLdapWorkItem"); 
@@ -1458,7 +1456,8 @@ public:
     }
 
     //ISessionManagerServer
-    virtual SecAccessFlags getPermissionsLDAP(const char *key,const char *obj,IUserDescriptor *udesc,unsigned flags,const char * reqSignature, CDateTime * reqUTCTimestamp, int *err)
+    //Dali method to handle permission request
+    virtual SecAccessFlags getPermissionsLDAP(const char *key,const char *obj,IUserDescriptor *udesc,unsigned flags,const char * reqSignature, CDateTime & reqUTCTimestamp, int *err)
     {
         if (err)
             *err = 0;

+ 3 - 1
dali/base/dasess.hpp

@@ -114,7 +114,7 @@ interface ISessionManager: extends IInterface
     virtual StringBuffer &getClientProcessEndpoint(SessionId id,StringBuffer &buf)=0; // for diagnostics
     virtual unsigned queryClientCount() = 0; // for SNMP
 
-    virtual SecAccessFlags getPermissionsLDAP(const char *key,const char *obj,IUserDescriptor *udesc,unsigned auditflags, const char * reqSignature=nullptr, CDateTime * reqUTCTimestamp=nullptr, int *err=NULL)=0;
+    virtual SecAccessFlags getPermissionsLDAP(const char *key,const char *obj,IUserDescriptor *udesc,unsigned auditflags, const char * reqSignature, CDateTime & reqUTCTimestamp, int *err=NULL)=0;
     virtual bool checkScopeScansLDAP()=0;
     virtual unsigned getLDAPflags()=0;
     virtual void setLDAPflags(unsigned flags)=0;
@@ -136,6 +136,8 @@ extern da_decl ISessionManager &querySessionManager();
 
 #define myProcessSession() (querySessionManager().lookupProcessSession())
 
+extern da_decl bool createDaliSignature(const char * scope, IUserDescriptor *udesc, CDateTime &now, StringBuffer &b64sig);
+
 interface IMessageWrapper
 {
 public:

+ 4 - 4
dali/server/daldap.cpp

@@ -121,7 +121,7 @@ public:
     }
 
 
-    SecAccessFlags getPermissions(const char *key,const char *obj,IUserDescriptor *udesc,unsigned auditflags,const char * reqSignature, CDateTime * reqUTCTimestamp)
+    SecAccessFlags getPermissions(const char *key,const char *obj,IUserDescriptor *udesc,unsigned auditflags,const char * reqSignature, CDateTime & reqUTCTimestamp)
     {
         if (!ldapsecurity||((getLDAPflags()&DLF_ENABLED)==0)) 
             return SecAccess_Full;
@@ -157,11 +157,11 @@ public:
             if (pDSM && pDSM->isDigiVerifierConfigured())
             {
                 StringBuffer requestTimestamp;
-                reqUTCTimestamp->getString(requestTimestamp, false);//extract timestamp string from Dali request
+                reqUTCTimestamp.getString(requestTimestamp, false);//extract timestamp string from Dali request
 
                 CDateTime now;
                 now.setNow();
-                if (now.compare(*reqUTCTimestamp) < 0)//timestamp from the future?
+                if (now.compare(reqUTCTimestamp) < 0)//timestamp from the future?
                 {
                     ERRLOG("LDAP: getPermissions(%s) scope=%s user=%s Request digital signature timestamp %s from the future",key?key:"NULL",obj?obj:"NULL",username.str(), requestTimestamp.str());
                     return SecAccess_None;//deny
@@ -171,7 +171,7 @@ public:
                 expiry.set(now);
                 expiry.adjustTime(requestSignatureExpiryMinutes);//compute expiration timestamp
 
-                if (expiry.compare(*reqUTCTimestamp) < 0)//timestamp too far in the past?
+                if (expiry.compare(reqUTCTimestamp) < 0)//timestamp too far in the past?
                 {
                     ERRLOG("LDAP: getPermissions(%s) scope=%s user=%s Expired request digital signature timestamp %s",key?key:"NULL",obj?obj:"NULL",username.str(), requestTimestamp.str());
                     return SecAccess_None;//deny

+ 1 - 1
dali/server/daldap.hpp

@@ -26,7 +26,7 @@ interface IUserDescriptor;
 
 interface IDaliLdapConnection: extends IInterface
 {
-    virtual SecAccessFlags getPermissions(const char *key,const char *obj,IUserDescriptor *udesc,unsigned auditflags,const char * reqSignature, CDateTime * reqUTCTimestamp)=0;
+    virtual SecAccessFlags getPermissions(const char *key,const char *obj,IUserDescriptor *udesc,unsigned auditflags,const char * reqSignature, CDateTime & reqUTCTimestamp)=0;
     virtual bool checkScopeScans() = 0;
     virtual unsigned getLDAPflags() = 0;
     virtual void setLDAPflags(unsigned flags) = 0;

+ 6 - 1
plugins/workunitservices/workunitservices.cpp

@@ -219,7 +219,12 @@ static bool checkScopeAuthorized(IUserDescriptor *user, const char *scopename)
     SecAccessFlags perm = SecAccess_Full;
     if (scopename && *scopename)
     {
-        perm = querySessionManager().getPermissionsLDAP("workunit",scopename,user,auditflags);
+        //Create signature
+        CDateTime now;
+        StringBuffer b64sig;
+        createDaliSignature(scopename, user, now, b64sig);
+
+        perm = querySessionManager().getPermissionsLDAP("workunit",scopename,user,auditflags, b64sig.str(), now);
         if (perm<0)
         {
             if (perm == SecAccess_Unavailable)