def __discoverExtraCredentials( self ): #Wich extra credentials to use? if self.useCertificates: self.__extraCredentials = self.VAL_EXTRA_CREDENTIALS_HOST else: self.__extraCredentials = "" if self.KW_EXTRA_CREDENTIALS in self.kwargs: self.__extraCredentials = self.kwargs[ self.KW_EXTRA_CREDENTIALS ] #Are we delegating something? delegatedDN, delegatedGroup = self.__threadConfig.getID() if self.KW_DELEGATED_DN in self.kwargs and self.kwargs[ self.KW_DELEGATED_DN ]: delegatedDN = self.kwargs[ self.KW_DELEGATED_DN ] elif delegatedDN: self.kwargs[ self.KW_DELEGATED_DN ] = delegatedDN if self.KW_DELEGATED_GROUP in self.kwargs and self.kwargs[ self.KW_DELEGATED_GROUP ]: delegatedGroup = self.kwargs[ self.KW_DELEGATED_GROUP ] elif delegatedGroup: self.kwargs[ self.KW_DELEGATED_GROUP ] = delegatedGroup if delegatedDN: if not delegatedGroup: result = CS.findDefaultGroupForDN( self.kwargs[ self.KW_DELEGATED_DN ] ) if not result['OK']: return result self.__extraCredentials = ( delegatedDN, delegatedGroup ) return S_OK()
def _getBaseStub( self ): newKwargs = dict( self.kwargs ) #Set DN tDN, tGroup = self.__threadConfig.getID() if not self.KW_DELEGATED_DN in newKwargs: if tDN: newKwargs[ self.KW_DELEGATED_DN ] = tDN elif 'DN' in self.__idDict: newKwargs[ self.KW_DELEGATED_DN ] = self.__idDict[ 'DN' ] #Discover group if not self.KW_DELEGATED_GROUP in newKwargs: if 'group' in self.__idDict: newKwargs[ self.KW_DELEGATED_GROUP ] = self.__idDict[ 'group' ] elif tGroup: newKwargs[ self.KW_DELEGATED_GROUP ] = tGroup else: if self.KW_DELEGATED_DN in newKwargs: if CS.getUsernameForDN( newKwargs[ self.KW_DELEGATED_DN ] )[ 'OK' ]: result = CS.findDefaultGroupForDN( newKwargs[ self.KW_DELEGATED_DN ] ) if result['OK']: newKwargs[ self.KW_DELEGATED_GROUP ] = result['Value'] if CS.getHostnameForDN( newKwargs[ self.KW_DELEGATED_DN ] )[ 'OK' ]: newKwargs[ self.KW_DELEGATED_GROUP ] = self.VAL_EXTRA_CREDENTIALS_HOST if 'useCertificates' in newKwargs: del( newKwargs[ 'useCertificates' ] ) return ( self._destinationSrv, newKwargs )
def getUsername( self, credDict ): """ Discover the username associated to the DN. It will check if the selected group is valid. The username will be included in the credentials dictionary. :type credDict: dictionary :param credDict: Credentials to ckeck :return: Boolean specifying whether the username was found """ if self.KW_DN not in credDict: return True if self.KW_GROUP not in credDict: result = CS.findDefaultGroupForDN( credDict[ self.KW_DN ] ) if not result['OK']: return False credDict[ self.KW_GROUP ] = result['Value'] credDict[ self.KW_PROPERTIES ] = CS.getPropertiesForGroup( credDict[ self.KW_GROUP ], [] ) usersInGroup = CS.getUsersInGroup( credDict[ self.KW_GROUP ], [] ) if not usersInGroup: return False retVal = CS.getUsernameForDN( credDict[ self.KW_DN ], usersInGroup ) if retVal[ 'OK' ]: credDict[ self.KW_USERNAME ] = retVal[ 'Value' ] return True return False
def getShifterProxy(shifterType, fileName=False): """ This method returns a shifter's proxy :param shifterType: ProductionManager / DataManager... """ if fileName: try: os.makedirs(os.path.dirname(fileName)) except OSError: pass opsHelper = Operations() userName = opsHelper.getValue(cfgPath('Shifter', shifterType, 'User'), '') if not userName: return S_ERROR("No shifter User defined for %s" % shifterType) result = CS.getDNForUsername(userName) if not result['OK']: return result userDN = result['Value'][0] result = CS.findDefaultGroupForDN(userDN) if not result['OK']: return result defaultGroup = result['Value'] userGroup = opsHelper.getValue(cfgPath('Shifter', shifterType, 'Group'), defaultGroup) vomsAttr = CS.getVOMSAttributeForGroup(userGroup) if vomsAttr: gLogger.info("Getting VOMS [%s] proxy for shifter %s@%s (%s)" % (vomsAttr, userName, userGroup, userDN)) result = gProxyManager.downloadVOMSProxyToFile(userDN, userGroup, filePath=fileName, requiredTimeLeft=86400, cacheTime=86400) else: gLogger.info("Getting proxy for shifter %s@%s (%s)" % (userName, userGroup, userDN)) result = gProxyManager.downloadProxyToFile(userDN, userGroup, filePath=fileName, requiredTimeLeft=86400, cacheTime=86400) if not result['OK']: return result chain = result['chain'] fileName = result['Value'] return S_OK({ 'DN': userDN, 'username': userName, 'group': userGroup, 'chain': chain, 'proxyFile': fileName })
def getShifterProxy( shifterType, fileName = False ): """ This method returns a shifter's proxy :param shifterType: ProductionManager / DataManager... """ if fileName: try: os.makedirs( os.path.dirname( fileName ) ) except OSError: pass opsHelper = Operations() userName = opsHelper.getValue( cfgPath( 'Shifter', shifterType, 'User' ), '' ) if not userName: return S_ERROR( "No shifter User defined for %s" % shifterType ) result = CS.getDNForUsername( userName ) if not result[ 'OK' ]: return result userDN = result[ 'Value' ][0] result = CS.findDefaultGroupForDN( userDN ) if not result['OK']: return result defaultGroup = result['Value'] userGroup = opsHelper.getValue( cfgPath( 'Shifter', shifterType, 'Group' ), defaultGroup ) vomsAttr = CS.getVOMSAttributeForGroup( userGroup ) if vomsAttr: gLogger.info( "Getting VOMS [%s] proxy for shifter %s@%s (%s)" % ( vomsAttr, userName, userGroup, userDN ) ) result = gProxyManager.downloadVOMSProxyToFile( userDN, userGroup, filePath = fileName, requiredTimeLeft = 86400, cacheTime = 86400 ) else: gLogger.info( "Getting proxy for shifter %s@%s (%s)" % ( userName, userGroup, userDN ) ) result = gProxyManager.downloadProxyToFile( userDN, userGroup, filePath = fileName, requiredTimeLeft = 86400, cacheTime = 86400 ) if not result[ 'OK' ]: return result chain = result[ 'chain' ] fileName = result[ 'Value' ] return S_OK( { 'DN' : userDN, 'username' : userName, 'group' : userGroup, 'chain' : chain, 'proxyFile' : fileName } )
def __getOwnerGroupDN(self, shifterType): opsHelper = Operations() userName = opsHelper.getValue( cfgPath('BoincShifter', shifterType, 'User'), '') if not userName: return S_ERROR("No shifter User defined for %s" % shifterType) result = CS.getDNForUsername(userName) if not result['OK']: return result userDN = result['Value'][0] result = CS.findDefaultGroupForDN(userDN) if not result['OK']: return result defaultGroup = result['Value'] userGroup = opsHelper.getValue( cfgPath('BoincShifter', shifterType, 'Group'), defaultGroup) return userDN, userGroup, userName
def __discoverExtraCredentials( self ): #Wich extra credentials to use? if self.useCertificates: self.__extraCredentials = self.VAL_EXTRA_CREDENTIALS_HOST else: self.__extraCredentials = "" if self.KW_EXTRA_CREDENTIALS in self.kwargs: self.__extraCredentials = self.kwargs[ self.KW_EXTRA_CREDENTIALS ] #Are we delegating something? if self.KW_DELEGATED_DN in self.kwargs and self.kwargs[ self.KW_DELEGATED_DN ]: if self.KW_DELEGATED_GROUP in self.kwargs and self.kwargs[ self.KW_DELEGATED_GROUP ]: self.__extraCredentials = self.kwargs[ self.KW_DELEGATED_GROUP ] else: result = CS.findDefaultGroupForDN( self.kwargs[ self.KW_DELEGATED_DN ] ) if not result['OK']: return result self.__extraCredentials = result['Value'] self.__extraCredentials = ( self.kwargs[ self.KW_DELEGATED_DN ], self.__extraCredentials ) return S_OK()
def getShifterProxy(shifterType, fileName=False): """ This method returns a shifter's proxy - shifterType : ProductionManager / DataManager... """ if fileName: try: os.makedirs(os.path.dirname(fileName)) except OSError: pass opsHelper = Operations() userName = opsHelper.getValue(cfgPath("Shifter", shifterType, "User"), "") if not userName: return S_ERROR("No shifter User defined for %s" % shifterType) result = CS.getDNForUsername(userName) if not result["OK"]: return result userDN = result["Value"][0] result = CS.findDefaultGroupForDN(userDN) if not result["OK"]: return result defaultGroup = result["Value"] userGroup = opsHelper.getValue(cfgPath("Shifter", shifterType, "Group"), defaultGroup) vomsAttr = CS.getVOMSAttributeForGroup(userGroup) if vomsAttr: gLogger.info("Getting VOMS [%s] proxy for shifter %s@%s (%s)" % (vomsAttr, userName, userGroup, userDN)) result = gProxyManager.downloadVOMSProxyToFile( userDN, userGroup, filePath=fileName, requiredTimeLeft=1200, cacheTime=4 * 43200 ) else: gLogger.info("Getting proxy for shifter %s@%s (%s)" % (userName, userGroup, userDN)) result = gProxyManager.downloadProxyToFile( userDN, userGroup, filePath=fileName, requiredTimeLeft=1200, cacheTime=4 * 43200 ) if not result["OK"]: return result chain = result["chain"] fileName = result["Value"] return S_OK({"DN": userDN, "username": userName, "group": userGroup, "chain": chain, "proxyFile": fileName})
def _getBaseStub( self ): """ Returns a tuple with (self._destinationSrv, newKwargs) self._destinationSrv is what was given as first parameter of the init serviceName newKwargs is an updated copy of kwargs: * kwargs has already been updated by all the initialization functions * if a delegated DN is not set, but is found in __threadConfig or in the info returned by the protocol sanitiy check, then we replace it (KW_DELEGATED_DN) * Same goes for the delegated group KW_DELEGATED_GROUP. In the case of a host, the value is the same as for VAL_EXTRA_CREDENTIALS_HOST * if set, we remove the useCertificates (KW_USE_CERTIFICATES) in newKwargs (not sure to know why) This method is just used to return information in case of error in the InnerRPCClient """ newKwargs = dict( self.kwargs ) #Set DN tDN, tGroup = self.__threadConfig.getID() if not self.KW_DELEGATED_DN in newKwargs: if tDN: newKwargs[ self.KW_DELEGATED_DN ] = tDN elif 'DN' in self.__idDict: newKwargs[ self.KW_DELEGATED_DN ] = self.__idDict[ 'DN' ] #Discover group if not self.KW_DELEGATED_GROUP in newKwargs: if 'group' in self.__idDict: newKwargs[ self.KW_DELEGATED_GROUP ] = self.__idDict[ 'group' ] elif tGroup: newKwargs[ self.KW_DELEGATED_GROUP ] = tGroup else: if self.KW_DELEGATED_DN in newKwargs: if CS.getUsernameForDN( newKwargs[ self.KW_DELEGATED_DN ] )[ 'OK' ]: result = CS.findDefaultGroupForDN( newKwargs[ self.KW_DELEGATED_DN ] ) if result['OK']: newKwargs[ self.KW_DELEGATED_GROUP ] = result['Value'] if CS.getHostnameForDN( newKwargs[ self.KW_DELEGATED_DN ] )[ 'OK' ]: newKwargs[ self.KW_DELEGATED_GROUP ] = self.VAL_EXTRA_CREDENTIALS_HOST # Not sure why one would want to remove that... if 'useCertificates' in newKwargs: del newKwargs[ 'useCertificates' ] return ( self._destinationSrv, newKwargs )
def __discoverExtraCredentials(self): """ Add extra credentials informations. * self.__extraCredentials -> if KW_EXTRA_CREDENTIALS in kwargs, we set it -> Otherwise, if we use the server certificate, we set it to VAL_EXTRA_CREDENTIALS_HOST -> If we have a delegation (see bellow), we set it to (delegatedDN, delegatedGroup) -> otherwise it is an empty string * delegation: -> if KW_DELEGATED_DN in kwargs, or delegatedDN in threadConfig, put in in self.kwargs -> if KW_DELEGATED_GROUP in kwargs or delegatedGroup in threadConfig, put it in self.kwargs -> If we have a delegated DN but not group, we find the corresponding group in the CS """ # Wich extra credentials to use? if self.__useCertificates: self.__extraCredentials = self.VAL_EXTRA_CREDENTIALS_HOST else: self.__extraCredentials = "" if self.KW_EXTRA_CREDENTIALS in self.kwargs: self.__extraCredentials = self.kwargs[self.KW_EXTRA_CREDENTIALS] # Are we delegating something? delegatedDN, delegatedGroup = self.__threadConfig.getID() if self.KW_DELEGATED_DN in self.kwargs and self.kwargs[ self.KW_DELEGATED_DN]: delegatedDN = self.kwargs[self.KW_DELEGATED_DN] elif delegatedDN: self.kwargs[self.KW_DELEGATED_DN] = delegatedDN if self.KW_DELEGATED_GROUP in self.kwargs and self.kwargs[ self.KW_DELEGATED_GROUP]: delegatedGroup = self.kwargs[self.KW_DELEGATED_GROUP] elif delegatedGroup: self.kwargs[self.KW_DELEGATED_GROUP] = delegatedGroup if delegatedDN: if not delegatedGroup: result = CS.findDefaultGroupForDN( self.kwargs[self.KW_DELEGATED_DN]) if not result['OK']: return result self.__extraCredentials = (delegatedDN, delegatedGroup) return S_OK()
def __discoverExtraCredentials(self): #Wich extra credentials to use? if self.useCertificates: self.__extraCredentials = self.VAL_EXTRA_CREDENTIALS_HOST else: self.__extraCredentials = "" if self.KW_EXTRA_CREDENTIALS in self.kwargs: self.__extraCredentials = self.kwargs[self.KW_EXTRA_CREDENTIALS] #Are we delegating something? if self.KW_DELEGATED_DN in self.kwargs and self.kwargs[ self.KW_DELEGATED_DN]: if self.KW_DELEGATED_GROUP in self.kwargs and self.kwargs[ self.KW_DELEGATED_GROUP]: self.__extraCredentials = self.kwargs[self.KW_DELEGATED_GROUP] else: result = CS.findDefaultGroupForDN( self.kwargs[self.KW_DELEGATED_DN]) if not result['OK']: return result self.__extraCredentials = result['Value'] self.__extraCredentials = (self.kwargs[self.KW_DELEGATED_DN], self.__extraCredentials) return S_OK()
def __discoverExtraCredentials(self): """ Add extra credentials informations. * self.__extraCredentials -> if KW_EXTRA_CREDENTIALS in kwargs, we set it -> Otherwise, if we use the server certificate, we set it to VAL_EXTRA_CREDENTIALS_HOST -> If we have a delegation (see bellow), we set it to (delegatedDN, delegatedGroup) -> otherwise it is an empty string * delegation: -> if KW_DELEGATED_DN in kwargs, or delegatedDN in threadConfig, put in in self.kwargs -> if KW_DELEGATED_GROUP in kwargs or delegatedGroup in threadConfig, put it in self.kwargs -> If we have a delegated DN but not group, we find the corresponding group in the CS """ # Wich extra credentials to use? if self.__useCertificates: self.__extraCredentials = self.VAL_EXTRA_CREDENTIALS_HOST else: self.__extraCredentials = "" if self.KW_EXTRA_CREDENTIALS in self.kwargs: self.__extraCredentials = self.kwargs[self.KW_EXTRA_CREDENTIALS] # Are we delegating something? delegatedDN, delegatedGroup = self.__threadConfig.getID() if self.KW_DELEGATED_DN in self.kwargs and self.kwargs[self.KW_DELEGATED_DN]: delegatedDN = self.kwargs[self.KW_DELEGATED_DN] elif delegatedDN: self.kwargs[self.KW_DELEGATED_DN] = delegatedDN if self.KW_DELEGATED_GROUP in self.kwargs and self.kwargs[self.KW_DELEGATED_GROUP]: delegatedGroup = self.kwargs[self.KW_DELEGATED_GROUP] elif delegatedGroup: self.kwargs[self.KW_DELEGATED_GROUP] = delegatedGroup if delegatedDN: if not delegatedGroup: result = CS.findDefaultGroupForDN(self.kwargs[self.KW_DELEGATED_DN]) if not result['OK']: return result self.__extraCredentials = (delegatedDN, delegatedGroup) return S_OK()
def authQuery( self, methodQuery, credDict, defaultProperties = False ): """ Check if the query is authorized for a credentials dictionary :type methodQuery: string :param methodQuery: Method to test :type credDict: dictionary :param credDict: dictionary containing credentials for test. The dictionary can contain the DN and selected group. :return: Boolean result of test """ userString = "" if self.KW_DN in credDict: userString += "DN=%s" % credDict[ self.KW_DN ] if self.KW_GROUP in credDict: userString += " group=%s" % credDict[ self.KW_GROUP ] if self.KW_EXTRA_CREDENTIALS in credDict: userString += " extraCredentials=%s" % str( credDict[ self.KW_EXTRA_CREDENTIALS ] ) self.__authLogger.verbose( "Trying to authenticate %s" % userString ) # Get properties requiredProperties = self.getValidPropertiesForMethod( methodQuery, defaultProperties ) # Extract valid groups validGroups = self.getValidGroups( requiredProperties ) lowerCaseProperties = [ prop.lower() for prop in requiredProperties ] if not lowerCaseProperties: lowerCaseProperties = ['any'] allowAll = "any" in lowerCaseProperties or "all" in lowerCaseProperties #Set no properties by default credDict[ self.KW_PROPERTIES ] = [] #Check non secure backends if self.KW_DN not in credDict or not credDict[ self.KW_DN ]: if allowAll and not validGroups: self.__authLogger.verbose( "Accepted request from unsecure transport" ) return True else: self.__authLogger.verbose( "Explicit property required and query seems to be coming through an unsecure transport" ) return False #Check if query comes though a gateway/web server if self.forwardedCredentials( credDict ): self.__authLogger.verbose( "Query comes from a gateway" ) self.unpackForwardedCredentials( credDict ) return self.authQuery( methodQuery, credDict ) #Get the properties #Check for invalid forwarding if self.KW_EXTRA_CREDENTIALS in credDict: #Invalid forwarding? if not isinstance ( credDict[ self.KW_EXTRA_CREDENTIALS ], basestring ): self.__authLogger.verbose( "The credentials seem to be forwarded by a host, but it is not a trusted one" ) return False #Is it a host? if self.KW_EXTRA_CREDENTIALS in credDict and credDict[ self.KW_EXTRA_CREDENTIALS ] == self.KW_HOSTS_GROUP: #Get the nickname of the host credDict[ self.KW_GROUP ] = credDict[ self.KW_EXTRA_CREDENTIALS ] #HACK TO MAINTAIN COMPATIBILITY else: if self.KW_EXTRA_CREDENTIALS in credDict and self.KW_GROUP not in credDict: credDict[ self.KW_GROUP ] = credDict[ self.KW_EXTRA_CREDENTIALS ] #END OF HACK #Get the username if self.KW_DN in credDict and credDict[ self.KW_DN ]: if self.KW_GROUP not in credDict: result = CS.findDefaultGroupForDN( credDict[ self.KW_DN ] ) if not result['OK']: return False credDict[ self.KW_GROUP ] = result['Value'] if credDict[ self.KW_GROUP ] == self.KW_HOSTS_GROUP: #For host if not self.getHostNickName( credDict ): self.__authLogger.warn( "Host is invalid" ) if not allowAll: return False #If all, then set anon credentials credDict[ self.KW_USERNAME ] = "anonymous" credDict[ self.KW_GROUP ] = "visitor" else: #For users if not self.getUsername( credDict ): self.__authLogger.warn( "User is invalid or does not belong to the group it's saying" ) if not allowAll: return False #If all, then set anon credentials credDict[ self.KW_USERNAME ] = "anonymous" credDict[ self.KW_GROUP ] = "visitor" #If any or all in the props, allow allowGroup = not validGroups or credDict[ self.KW_GROUP ] in validGroups if allowAll and allowGroup: return True #Check authorized groups if "authenticated" in lowerCaseProperties and allowGroup: return True if not self.matchProperties( credDict, requiredProperties ): self.__authLogger.warn( "Client is not authorized\nValid properties: %s\nClient: %s" % ( requiredProperties, credDict ) ) return False elif not allowGroup: self.__authLogger.warn( "Client is not authorized\nValid groups: %s\nClient: %s" % ( validGroups, credDict ) ) return False return True