Skip to content

Commit

Permalink
Merge pull request #11547 from RussWhitehead/daliCore
Browse files Browse the repository at this point in the history
HPCC-20220 Dali cores when getPermissions called internally

Reviewed-by: Gavin Halliday <ghalliday@hpccsystems.com>
  • Loading branch information
ghalliday committed Aug 8, 2018
2 parents 038da66 + b86d8ac commit afc4312
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 56 deletions.
3 changes: 2 additions & 1 deletion common/workunit/workunit.cpp
Expand Up @@ -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;
Expand Down
8 changes: 7 additions & 1 deletion dali/base/dadfs.cpp
Expand Up @@ -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;
Expand Down
93 changes: 46 additions & 47 deletions dali/base/dasess.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -453,46 +453,23 @@ class CEnableScopeScansReq : implements IMessageWrapper
}
};


//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
{
Expand Down Expand Up @@ -647,11 +624,13 @@ class CSessionRequestServer: public Thread

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);
Expand Down Expand Up @@ -930,7 +909,7 @@ class CClientSessionManager: public CSessionManagerBase, implements IConnectionM
}


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;
Expand Down Expand Up @@ -958,8 +937,26 @@ class CClientSessionManager: public CSessionManagerBase, implements IConnectionM
#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;
Expand Down Expand Up @@ -1193,12 +1190,13 @@ class CLdapWorkItem : public Thread
{
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;
Expand Down Expand Up @@ -1227,7 +1225,7 @@ class CLdapWorkItem : public Thread
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");
Expand Down Expand Up @@ -1458,7 +1456,8 @@ class CCovenSessionManager: public CSessionManagerBase, implements ISessionManag
}

//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;
Expand Down
4 changes: 3 additions & 1 deletion dali/base/dasess.hpp
Expand Up @@ -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;
Expand All @@ -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:
Expand Down
8 changes: 4 additions & 4 deletions dali/server/daldap.cpp
Expand Up @@ -121,7 +121,7 @@ class CDaliLdapConnection: implements IDaliLdapConnection, public CInterface
}


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;
Expand Down Expand Up @@ -157,11 +157,11 @@ class CDaliLdapConnection: implements IDaliLdapConnection, public CInterface
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
Expand All @@ -171,7 +171,7 @@ class CDaliLdapConnection: implements IDaliLdapConnection, public CInterface
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
Expand Down
2 changes: 1 addition & 1 deletion dali/server/daldap.hpp
Expand Up @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion plugins/workunitservices/workunitservices.cpp
Expand Up @@ -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)
Expand Down

0 comments on commit afc4312

Please sign in to comment.