Пример #1
0
  def _forceGenerateProxyForDN(self, dn, time, group=None):
    """ An additional helper method for creating a proxy without any substantial validation,
        it can be used for a specific case(such as testing) where just need to generate a proxy
        with specific DN on the fly.

        :param str dn: requested proxy DN
        :param int time: expired time in a seconds
        :param str group: if need to add DIRAC group

        :return: S_OK(tuple)/S_ERROR() -- contain proxy as chain and as string
    """
    self.__X509Name = X509.X509_Name()
    result = self.__parseDN(dn)
    if not result['OK']:
      return result
    dnInfoDict = result['Value']

    for field, values in dnInfoDict.items():
      result = self.__fillX509Name(field, values)
      if not result['OK']:
        return result

    result = self.__createCertM2Crypto()
    if result['OK']:
      certStr, keyStr = result['Value']
      chain = X509Chain()
      if chain.loadChainFromString(certStr)['OK'] and chain.loadKeyFromString(keyStr)['OK']:
        result = chain.generateProxyToString(time, rfc=True, diracGroup=group)
    if not result['OK']:
      return result
    chain = X509Chain()
    chain.loadProxyFromString(result['Value'])
    return S_OK((chain, result['Value']))
Пример #2
0
def uploadProxy(params):
    DIRAC.gLogger.info("Loading user proxy")
    proxyLoc = params.proxyLoc
    if not proxyLoc:
        proxyLoc = Locations.getDefaultProxyLocation()
    if not proxyLoc:
        return S_ERROR("Can't find any proxy")

    if params.onTheFly:
        DIRAC.gLogger.info("Uploading proxy on-the-fly")
        certLoc = params.certLoc
        keyLoc = params.keyLoc
        if not certLoc or not keyLoc:
            cakLoc = Locations.getCertificateAndKeyLocation()
            if not cakLoc:
                return S_ERROR("Can't find user certificate and key")
            if not certLoc:
                certLoc = cakLoc[0]
            if not keyLoc:
                keyLoc = cakLoc[1]

        DIRAC.gLogger.info("Cert file %s" % certLoc)
        DIRAC.gLogger.info("Key file  %s" % keyLoc)

        testChain = X509Chain()
        retVal = testChain.loadKeyFromFile(keyLoc, password=params.userPasswd)
        if not retVal['OK']:
            passwdPrompt = "Enter Certificate password:"******"\n")
            else:
                userPasswd = getpass.getpass(passwdPrompt)
            params.userPasswd = userPasswd

        DIRAC.gLogger.info("Loading cert and key")
        chain = X509Chain()
        # Load user cert and key
        retVal = chain.loadChainFromFile(certLoc)
        if not retVal['OK']:
            return S_ERROR("Can't load %s" % certLoc)
        retVal = chain.loadKeyFromFile(keyLoc, password=params.userPasswd)
        if not retVal['OK']:
            return S_ERROR("Can't load %s" % keyLoc)
        DIRAC.gLogger.info("User credentials loaded")
        restrictLifeTime = params.proxyLifeTime

    else:
        proxyChain = X509Chain()
        retVal = proxyChain.loadProxyFromFile(proxyLoc)
        if not retVal['OK']:
            return S_ERROR("Can't load proxy file %s: %s" %
                           (params.proxyLoc, retVal['Message']))

        chain = proxyChain
        restrictLifeTime = 0

    DIRAC.gLogger.info(" Uploading...")
    return gProxyManager.uploadProxy(proxy=chain,
                                     restrictLifeTime=restrictLifeTime,
                                     rfcIfPossible=params.rfcIfPossible)
Пример #3
0
 def createProxy(self,
                 userName,
                 group,
                 time,
                 rfc=True,
                 limit=False,
                 vo=None,
                 role=None,
                 path=None):
     """ Create user proxy
 """
     userCertFile = os.path.join(self.userDir, userName + '.cert.pem')
     userKeyFile = os.path.join(self.userDir, userName + '.key.pem')
     self.proxyPath = path or os.path.join(self.userDir, userName + '.pem')
     if not vo:
         chain = X509Chain()
         # Load user cert and key
         retVal = chain.loadChainFromFile(userCertFile)
         if not retVal['OK']:
             gLogger.warn(retVal['Message'])
             return S_ERROR("Can't load %s" % userCertFile)
         retVal = chain.loadKeyFromFile(userKeyFile)
         if not retVal['OK']:
             gLogger.warn(retVal['Message'])
             if 'bad decrypt' in retVal['Message']:
                 return S_ERROR("Bad passphrase")
             return S_ERROR("Can't load %s" % userKeyFile)
         result = chain.generateProxyToFile(self.proxyPath,
                                            time * 3600,
                                            limited=limit,
                                            diracGroup=group,
                                            rfc=rfc)
         if not result['OK']:
             return result
     else:
         cmd = 'voms-proxy-fake --cert %s --key %s -q' % (userCertFile,
                                                          userKeyFile)
         cmd += ' -hostcert %s -hostkey %s' % (self.hostCert, self.hostKey)
         cmd += ' -uri fakeserver.cern.ch:15000'
         cmd += ' -voms "%s%s"' % (vo, role and ':%s' % role or '')
         cmd += ' -fqan "/%s/Role=%s/Capability=NULL"' % (vo, role)
         cmd += ' -hours %s -out %s' % (time, self.proxyPath)
         if limit:
             cmd += ' -limited'
         if rfc:
             cmd += ' -rfc'
         status, output = commands.getstatusoutput(cmd)
         if status:
             return S_ERROR(output)
     chain = X509Chain()
     result = chain.loadProxyFromFile(self.proxyPath)
     if not result['OK']:
         return result
     result = chain.generateProxyToString(12 * 3600, diracGroup=group)
     if not result['OK']:
         return result
     return S_OK((chain, result['Value']))
Пример #4
0
    def createProxy(self, userName, group, time, vo=None, role=None):
        """Create user proxy

        :param str userName: user name
        :param str group: group name
        :param int time: proxy expired time
        :param str vo: VOMS VO name
        :param str role: VOMS Role

        :return: S_OK(tuple)/S_ERROR() -- contain proxy as and as string
        """
        userCertFile = os.path.join(self.userDir, userName + ".cert.pem")
        userKeyFile = os.path.join(self.userDir, userName + ".key.pem")
        self.proxyPath = os.path.join(self.userDir, userName + ".pem")
        if not vo:
            chain = X509Chain()
            # Load user cert and key
            retVal = chain.loadChainFromFile(userCertFile)
            if not retVal["OK"]:
                gLogger.warn(retVal["Message"])
                return S_ERROR("Can't load %s" % userCertFile)
            retVal = chain.loadKeyFromFile(userKeyFile)
            if not retVal["OK"]:
                gLogger.warn(retVal["Message"])
                if "bad decrypt" in retVal["Message"]:
                    return S_ERROR("Bad passphrase")
                return S_ERROR("Can't load %s" % userKeyFile)
            result = chain.generateProxyToFile(self.proxyPath,
                                               time * 3600,
                                               diracGroup=group)
            if not result["OK"]:
                return result
        else:
            cmd = "voms-proxy-fake --cert %s --key %s -q" % (userCertFile,
                                                             userKeyFile)
            cmd += " -hostcert %s -hostkey %s" % (self.hostCert, self.hostKey)
            cmd += " -uri fakeserver.cern.ch:15000"
            cmd += ' -voms "%s"' % vo
            cmd += ' -fqan "/%s/Role=%s/Capability=NULL"' % (vo, role)
            cmd += " -hours %s -out %s -rfc" % (time, self.proxyPath)
            status, output = commands.getstatusoutput(cmd)
            if status:
                return S_ERROR(output)
        chain = X509Chain()
        result = chain.loadProxyFromFile(self.proxyPath)
        if not result["OK"]:
            return result
        result = chain.generateProxyToString(12 * 3600, diracGroup=group)
        if not result["OK"]:
            return result
        return S_OK((chain, result["Value"]))
Пример #5
0
 def __processCredentials(self):
     """
 Extract the user credentials based on the certificate or what comes from the balancer
 """
     self.__credDict = {}
     #NGINX
     if Conf.balancer() == "nginx":
         headers = self.request.headers
         if headers['X-Scheme'] == "https" and headers[
                 'X-Ssl_client_verify'] == 'SUCCESS':
             DN = headers['X-Ssl_client_s_dn']
             self.__credDict['subject'] = DN
             self.__credDict['issuer'] = headers['X-Ssl_client_i_dn']
             result = Registry.getUsernameForDN(DN)
             if not result['OK']:
                 self.__credDict['validDN'] = False
             else:
                 self.__credDict['validDN'] = True
                 self.__credDict['username'] = result['Value']
         return
     #TORNADO
     if not self.request.protocol == "https":
         return
     derCert = self.request.get_ssl_certificate(binary_form=True)
     if not derCert:
         return
     pemCert = ssl.DER_cert_to_PEM_cert(derCert)
     chain = X509Chain()
     chain.loadChainFromString(pemCert)
     result = chain.getCredentials()
     if not result['OK']:
         self.log.error("Could not get client credentials %s" %
                        result['Message'])
         return
     self.__credDict = result['Value']
Пример #6
0
  def getProxy(self, userDict=None, sessionDict=None):
    """ Generate user proxy

        :param dict userDict: user description dictionary with possible fields:
               FullName, UserName, DN, EMail, DiracGroup
        :param dict sessionDict: session dictionary

        :return: S_OK(dict)/S_ERROR() -- dict contain 'proxy' field with is a proxy string
    """
    result = self.getUserDN(userDict, sessionDict, userDN=userDict.get('DN'))
    if not result['OK']:
      return result

    result = self.__createCertM2Crypto()
    if not result['OK']:
      return result
    certStr, keyStr = result['Value']

    chain = X509Chain()
    result = chain.loadChainFromString(certStr)
    if not result['OK']:
      return result
    result = chain.loadKeyFromString(keyStr)
    if not result['OK']:
      return result

    result = chain.generateProxyToString(365 * 24 * 3600, rfc=True)
    if not result['OK']:
      return result
    return S_OK({'proxy': result['Value']})
Пример #7
0
    def _gatherPeerCredentials(self):
        """
      Load client certchain in DIRAC and extract informations.

      The dictionary returned is designed to work with the AuthManager,
      already written for DISET and re-used for HTTPS.

      :returns: a dict containing the return of :py:meth:`DIRAC.Core.Security.X509Chain.X509Chain.getCredentials`
                (not a DIRAC structure !)
    """

        chainAsText = self.request.get_ssl_certificate().as_pem()
        peerChain = X509Chain()

        # Here we read all certificate chain
        cert_chain = self.request.get_ssl_certificate_chain()
        for cert in cert_chain:
            chainAsText += cert.as_pem()

        peerChain.loadChainFromString(chainAsText)

        # Retrieve the credentials
        res = peerChain.getCredentials(withRegistryInfo=False)
        if not res['OK']:
            raise Exception(res['Message'])

        credDict = res['Value']

        # We check if client sends extra credentials...
        if "extraCredentials" in self.request.arguments:
            extraCred = self.get_argument("extraCredentials")
            if extraCred:
                credDict['extraCredentials'] = decode(extraCred)[0]
        return credDict
Пример #8
0
    def getProxy(self, userDN, userGroup, requiredLifeTime=False):
        """ Get proxy string from the Proxy Repository for use with userDN
        in the userGroup
    """

        retVal = self.__getPemAndTimeLeft(userDN, userGroup)
        if not retVal['OK']:
            return retVal
        pemData = retVal['Value'][0]
        timeLeft = retVal['Value'][1]
        chain = X509Chain()
        retVal = chain.loadProxyFromString(pemData)
        if not retVal['OK']:
            return retVal
        if requiredLifeTime:
            if timeLeft < requiredLifeTime:
                retVal = self.renewFromMyProxy(userDN,
                                               userGroup,
                                               lifeTime=requiredLifeTime,
                                               chain=chain)
                if not retVal['OK']:
                    return S_ERROR("Can't get a proxy for %s seconds: %s" %
                                   (requiredLifeTime, retVal['Message']))
                chain = retVal['Value']
        #Proxy is invalid for some reason, let's delete it
        if not chain.isValidProxy()['Value']:
            self.deleteProxy(userDN, userGroup)
            return S_ERROR("%s@%s has no proxy registered" %
                           (userDN, userGroup))
        return S_OK((chain, timeLeft))
Пример #9
0
def test_generateProxyDN(ppf):
    result = ppf.getProxyProvider("DIRAC_TEST_CA")
    assert result["OK"], result["Message"]
    pp = result["Value"]

    userDict = {
        "FullName": "John Doe",
        "Email": "*****@*****.**",
        "O": "DIRAC",
        "OU": "DIRAC TEST",
        "C": "FR"
    }
    result = pp.generateDN(**userDict)
    assert result["OK"], "\n%s" % result.get(
        "Message") or "Error message is absent."
    result = pp.getProxy(result["Value"])
    assert result["OK"], "\n%s" % result.get(
        "Message") or "Error message is absent."
    chain = X509Chain()
    chain.loadChainFromString(result["Value"])
    result = chain.getCredentials()
    assert result["OK"], "\n%s" % result.get(
        "Message") or "Error message is absent."
    issuer = result["Value"]["issuer"]
    assert issuer == "/C=FR/O=DIRAC/OU=DIRAC TEST/CN=John Doe/[email protected]"
Пример #10
0
    def test_generateProxyDN(self):

        userDict = {
            "FullName": "John Doe",
            "Email": "*****@*****.**",
            "O": 'DIRAC',
            'OU': 'DIRAC TEST',
            'C': 'FR'
        }
        result = self.pp.generateDN(**userDict)
        self.assertTrue(
            result['OK'], '\n%s' % result.get('Message')
            or 'Error message is absent.')
        result = self.pp.getProxy(result['Value'])
        self.assertTrue(
            result['OK'], '\n%s' % result.get('Message')
            or 'Error message is absent.')
        chain = X509Chain()
        chain.loadChainFromString(result['Value'])
        result = chain.getCredentials()
        self.assertTrue(
            result['OK'], '\n%s' % result.get('Message')
            or 'Error message is absent.')
        issuer = result['Value']['issuer']
        self.assertEqual(
            issuer,
            '/C=FR/O=DIRAC/OU=DIRAC TEST/CN=John Doe/[email protected]'
        )
Пример #11
0
  def downloadVOMSProxy( self, userDN, userGroup, limited = False, requiredTimeLeft = 1200, 
                         cacheTime = 43200, requiredVOMSAttribute = False, proxyToConnect = False, token = False ):
    """
    Download a proxy if needed and transform it into a VOMS one
    """

    cacheKey = ( userDN, userGroup, requiredVOMSAttribute, limited )
    if self.__vomsProxiesCache.exists( cacheKey, requiredTimeLeft ):
      return S_OK( self.__vomsProxiesCache.get( cacheKey ) )
    req = X509Request()
    req.generateProxyRequest( limited = limited )
    if proxyToConnect:
      rpcClient = RPCClient( "Framework/ProxyManager", proxyChain = proxyToConnect, timeout = 120 )
    else:
      rpcClient = RPCClient( "Framework/ProxyManager", timeout = 120 )
    if token:
      retVal = rpcClient.getVOMSProxyWithToken( userDN, userGroup, req.dumpRequest()['Value'],
                                                long( cacheTime + requiredTimeLeft ), token, requiredVOMSAttribute )

    else:
      retVal = rpcClient.getVOMSProxy( userDN, userGroup, req.dumpRequest()['Value'],
                                       long( cacheTime + requiredTimeLeft ), requiredVOMSAttribute )
    if not retVal[ 'OK' ]:
      return retVal
    chain = X509Chain( keyObj = req.getPKey() )
    retVal = chain.loadChainFromString( retVal[ 'Value' ] )
    if not retVal[ 'OK' ]:
      return retVal
    self.__vomsProxiesCache.add( cacheKey, chain.getRemainingSecs()['Value'], chain )
    return S_OK( chain )
Пример #12
0
 def gatherPeerCredentials( self ):
   certList = self.sslSocket.get_peer_certificate_chain()
   #Servers don't receive the whole chain, the last cert comes alone
   if not self.infoDict[ 'clientMode' ]:
     certList.insert( 0, self.sslSocket.get_peer_certificate() )
   peerChain = X509Chain( certList = certList )
   isProxyChain = peerChain.isProxy()['Value']
   isLimitedProxyChain = peerChain.isLimitedProxy()['Value']
   if isProxyChain:
     if peerChain.isPUSP()['Value']:
       identitySubject = peerChain.getCertInChain( -2 )['Value'].getSubjectNameObject()[ 'Value' ]
     else:
       identitySubject = peerChain.getIssuerCert()['Value'].getSubjectNameObject()[ 'Value' ]
   else:
     identitySubject = peerChain.getCertInChain( 0 )['Value'].getSubjectNameObject()[ 'Value' ]
   credDict = { 'DN' : identitySubject.one_line(),
                'CN' : identitySubject.commonName,
                'x509Chain' : peerChain,
                'isProxy' : isProxyChain,
                'isLimitedProxy' : isLimitedProxyChain }
   diracGroup = peerChain.getDIRACGroup()
   if diracGroup[ 'OK' ] and diracGroup[ 'Value' ]:
     credDict[ 'group' ] = diracGroup[ 'Value' ]
   self.infoDict[ 'peerCredentials' ] = credDict
   return credDict
Пример #13
0
    def completeDelegation(self, requestId, userDN, delegatedPem):
        """
    Complete a delegation and store it in the db
    """
        retVal = self.retrieveDelegationRequest(requestId, userDN)
        if not retVal['OK']:
            return retVal
        request = retVal['Value']
        chain = X509Chain(keyObj=request.getPKey())
        retVal = chain.loadChainFromString(delegatedPem)
        if not retVal['OK']:
            return retVal
        retVal = chain.isValidProxy(ignoreDefault=True)
        noGroupFlag = False
        if not retVal['OK']:
            if retVal['Message'] == "Proxy does not have an explicit group":
                noGroupFlag = True
            else:
                return retVal

        result = chain.isVOMS()
        if result['OK'] and result['Value']:
            return S_ERROR(
                "Proxies with VOMS extensions are not allowed to be uploaded")

        retVal = request.checkChain(chain)
        if not retVal['OK']:
            return retVal
        if not retVal['Value']:
            return S_ERROR("Received chain does not match request: %s" %
                           retVal['Message'])

        retVal = chain.getDIRACGroup()
        if not retVal['OK']:
            return retVal
        userGroup = retVal['Value']
        if not userGroup:
            userGroup = Registry.getDefaultUserGroup()

        retVal = Registry.getGroupsForDN(userDN)
        if not retVal['OK']:
            return retVal
        if not userGroup in retVal['Value']:
            return S_ERROR("%s group is not valid for %s" %
                           (userGroup, userDN))

        # For proxies without embedded DIRAC group only one default is allowed
        # Cleaning all the proxies for this DN if any before uploading the new one.
        if noGroupFlag:
            retVal = self.deleteProxy(userDN)
            if not retVal['OK']:
                return retVal

        retVal = self.storeProxy(userDN, userGroup, chain)
        if not retVal['OK']:
            return retVal
        retVal = self.deleteRequest(requestId)
        if not retVal['OK']:
            return retVal
        return S_OK()
Пример #14
0
    def getProxy(self, userDN):
        """ Generate user proxy

        :param str userDN: user DN

        :return: S_OK(str)/S_ERROR() -- contain a proxy string
    """
        result = self.checkStatus(userDN)
        if not result['OK']:
            return result

        puspURL = self.parameters['ServiceURL']
        puspURL += "?proxy-renewal=false&disable-voms-proxy=true&rfc-proxy=true"
        puspURL += "&cn-label=user:%s" % userDN.split(":")[-1]

        try:
            proxy = urlopen(puspURL).read()
        except Exception:
            return S_ERROR('Failed to get proxy from the PUSP server')

        chain = X509Chain()
        chain.loadChainFromString(proxy)
        chain.loadKeyFromString(proxy)

        result = chain.getCredentials()
        if not result['OK']:
            return S_ERROR('Failed to get a valid PUSP proxy')
        credDict = result['Value']
        if credDict['identity'] != userDN:
            return S_ERROR(
                'Requested DN does not match the obtained one in the PUSP proxy'
            )

        return chain.generateProxyToString(lifeTime=credDict['secondsLeft'])
Пример #15
0
    def uploadProxy(self,
                    proxy=None,
                    restrictLifeTime: int = 0,
                    rfcIfPossible=None):
        """Upload a proxy to the proxy management service using delegation

        :param X509Chain proxy: proxy as a chain
        :param restrictLifeTime: proxy live time in a seconds

        :return: S_OK(dict)/S_ERROR() -- dict contain proxies
        """
        if rfcIfPossible is not None:
            if os.environ.get("DIRAC_DEPRECATED_FAIL", None):
                raise NotImplementedError(
                    "'rfcIfPossible' argument is deprecated.")
            gLogger.warn("'rfcIfPossible' argument is deprecated.")

        # Discover proxy location
        if isinstance(proxy, X509Chain):
            chain = proxy
            proxyLocation = ""
        else:
            if not proxy:
                proxyLocation = Locations.getProxyLocation()
                if not proxyLocation:
                    return S_ERROR("Can't find a valid proxy")
            elif isinstance(proxy, str):
                proxyLocation = proxy
            else:
                return S_ERROR("Can't find a valid proxy")
            chain = X509Chain()
            result = chain.loadProxyFromFile(proxyLocation)
            if not result["OK"]:
                return S_ERROR(
                    f"Can't load {proxyLocation}: {result['Message']}")

        # Make sure it's valid
        if chain.hasExpired().get("Value"):
            return S_ERROR(f"Proxy {proxyLocation} has expired")
        if chain.getDIRACGroup(ignoreDefault=True).get(
                "Value") or chain.isVOMS().get("Value"):
            return S_ERROR(
                "Cannot upload proxy with DIRAC group or VOMS extensions")

        rpcClient = Client(url="Framework/ProxyManager", timeout=120)
        # Get a delegation request
        result = rpcClient.requestDelegationUpload()
        if not result["OK"]:
            return result
        reqDict = result["Value"]
        # Generate delegated chain
        chainLifeTime = chain.getRemainingSecs()["Value"] - 60
        if restrictLifeTime and restrictLifeTime < chainLifeTime:
            chainLifeTime = restrictLifeTime
        result = chain.generateChainFromRequestString(reqDict["request"],
                                                      lifetime=chainLifeTime)
        if result["OK"]:
            result = rpcClient.completeDelegationUpload(
                reqDict["id"], pemChain := result["Value"])
        return result
Пример #16
0
 def downloadProxy( self, userDN, userGroup, limited = False, requiredTimeLeft = 1200, 
                    cacheTime = 43200, proxyToConnect = False, token = False ):
   """
   Get a proxy Chain from the proxy management
   """
   cacheKey = ( userDN, userGroup )
   if self.__proxiesCache.exists( cacheKey, requiredTimeLeft ):
     return S_OK( self.__proxiesCache.get( cacheKey ) )
   req = X509Request()
   req.generateProxyRequest( limited = limited )
   if proxyToConnect:
     rpcClient = RPCClient( "Framework/ProxyManager", proxyChain = proxyToConnect, timeout = 120 )
   else:
     rpcClient = RPCClient( "Framework/ProxyManager", timeout = 120 )
   if token:
     retVal = rpcClient.getProxyWithToken( userDN, userGroup, req.dumpRequest()['Value'],
                                  long( cacheTime + requiredTimeLeft ), token )
   else:
     retVal = rpcClient.getProxy( userDN, userGroup, req.dumpRequest()['Value'],
                                  long( cacheTime + requiredTimeLeft ) )
   if not retVal[ 'OK' ]:
     return retVal
   chain = X509Chain( keyObj = req.getPKey() )
   retVal = chain.loadChainFromString( retVal[ 'Value' ] )
   if not retVal[ 'OK' ]:
     return retVal
   self.__proxiesCache.add( cacheKey, chain.getRemainingSecs()['Value'], chain )
   return S_OK( chain )
Пример #17
0
        def check(proxyStr, proxyProvider, name):
            """Check proxy

            :param str proxyStr: proxy as string
            :param str proxyProvider: proxy provider name
            :param str name: proxy name
            """
            proxyFile = os.path.join(
                testCAPath, proxyProvider + name.replace(" ", "") + ".pem")
            gLogger.info("Check proxy..")
            chain = X509Chain()
            result = chain.loadProxyFromString(proxyStr)
            self.assertTrue(
                result["OK"],
                "\n" + result.get("Message", "Error message is absent."))
            for result in [
                    chain.getRemainingSecs(),
                    chain.getIssuerCert(),
                    chain.getPKeyObj(),
                    chain.getCertList(),
                    chain.getNumCertsInChain(),
                    chain.generateProxyToString(3600),
                    chain.generateProxyToFile(proxyFile, 3600),
                    chain.isProxy(),
                    chain.isLimitedProxy(),
                    chain.isValidProxy(),
                    chain.isVOMS(),
                    chain.isRFC(),
            ]:
                self.assertTrue(
                    result["OK"],
                    "\n" + result.get("Message", "Error message is absent."))
Пример #18
0
def multiProxyArgument(proxy=False):
    """
  Load a proxy:
    proxyChain param can be:
      : Default -> use current proxy
      : string -> upload file specified as proxy
      : X509Chain -> use chain
    returns:
      S_OK( { 'file' : <string with file location>,
              'chain' : X509Chain object,
              'tempFile' : <True if file is temporal>
            }
      S_ERROR
  """
    tempFile = False
    #Set env
    if type(proxy) == g_X509ChainType:
        tempFile = True
        retVal = writeChainToTemporaryFile(proxy)
        if not retVal['OK']:
            return retVal
        proxyLoc = retVal['Value']
    else:
        if not proxy:
            proxyLoc = getProxyLocation()
            if not proxyLoc:
                return S_ERROR("Can't find proxy")
        if type(proxy) == types.StringType:
            proxyLoc = proxy
        #Load proxy
        proxy = X509Chain()
        retVal = proxy.loadProxyFromFile(proxyLoc)
        if not retVal['OK']:
            return S_ERROR("Can't load proxy at %s" % proxyLoc)
    return S_OK({'file': proxyLoc, 'chain': proxy, 'tempFile': tempFile})
Пример #19
0
 def test_getProxy(self):
     for dn, res in [
         ('/C=FR/O=DIRAC/OU=DIRAC TEST/CN=DIRAC test user/[email protected]',
          True),
         ('/C=FR/OU=DIRAC TEST/[email protected]', False),
         ('/C=FR/OU=DIRAC/O=DIRAC TEST/[email protected]',
          False),
         ('/C=FR/O=DIRAC/BADFIELD=DIRAC TEST/CN=DIRAC test user', False)
     ]:
         result = self.pp.getProxy(dn)
         text = 'Must be ended %s%s' % (
             'successful' if res else 'with error',
             ': %s' % result.get('Message', 'Error message is absent.'))
         self.assertEqual(result['OK'], res, text)
         if res:
             chain = X509Chain()
             chain.loadChainFromString(result['Value'])
             result = chain.getCredentials()
             self.assertTrue(
                 result['OK'], '\n%s' % result.get('Message')
                 or 'Error message is absent.')
             credDict = result['Value']
             self.assertEqual(
                 credDict['username'], 'testuser',
                 '%s, expected %s' % (credDict['username'], 'testuser'))
Пример #20
0
    def downloadVOMSProxy(
        self,
        userDN,
        userGroup,
        limited=False,
        requiredTimeLeft=1200,
        cacheTime=14400,
        requiredVOMSAttribute=None,
        proxyToConnect=None,
        token=None,
    ):
        """Download a proxy if needed and transform it into a VOMS one

        :param str userDN: user DN
        :param str userGroup: user group
        :param boolean limited: if need limited proxy
        :param int requiredTimeLeft: required proxy live time in a seconds
        :param int cacheTime: store in a cache time in a seconds
        :param str requiredVOMSAttribute: VOMS attr to add to the proxy
        :param X509Chain proxyToConnect: proxy as a chain
        :param str token: valid token to get a proxy

        :return: S_OK(X509Chain)/S_ERROR()
        """
        cacheKey = (userDN, userGroup, requiredVOMSAttribute, limited)
        if self.__vomsProxiesCache.exists(cacheKey, requiredTimeLeft):
            return S_OK(self.__vomsProxiesCache.get(cacheKey))
        req = X509Request()
        req.generateProxyRequest(limited=limited)
        if proxyToConnect:
            rpcClient = Client(url="Framework/ProxyManager",
                               proxyChain=proxyToConnect,
                               timeout=120)
        else:
            rpcClient = Client(url="Framework/ProxyManager", timeout=120)
        if token:
            retVal = rpcClient.getVOMSProxyWithToken(
                userDN,
                userGroup,
                req.dumpRequest()["Value"],
                int(cacheTime + requiredTimeLeft),
                token,
                requiredVOMSAttribute,
            )

        else:
            retVal = rpcClient.getVOMSProxy(userDN, userGroup,
                                            req.dumpRequest()["Value"],
                                            int(cacheTime + requiredTimeLeft),
                                            requiredVOMSAttribute)
        if not retVal["OK"]:
            return retVal
        chain = X509Chain(keyObj=req.getPKey())
        retVal = chain.loadChainFromString(retVal["Value"])
        if not retVal["OK"]:
            return retVal
        self.__vomsProxiesCache.add(cacheKey,
                                    chain.getRemainingSecs()["Value"], chain)
        return S_OK(chain)
Пример #21
0
    def __getPUSProxy(self,
                      userDN,
                      userGroup,
                      requiredLifetime,
                      requestedVOMSAttr=None):

        result = Registry.getGroupsForDN(userDN)
        if not result['OK']:
            return result

        validGroups = result['Value']
        if not userGroup in validGroups:
            return S_ERROR('Invalid group %s for user' % userGroup)

        voName = Registry.getVOForGroup(userGroup)
        if not voName:
            return S_ERROR('Can not determine VO for group %s' % userGroup)

        retVal = self.__getVOMSAttribute(userGroup, requestedVOMSAttr)
        if not retVal['OK']:
            return retVal
        vomsAttribute = retVal['Value']['attribute']
        vomsVO = retVal['Value']['VOMSVO']

        puspServiceURL = Registry.getVOOption(voName, 'PUSPServiceURL')
        if not puspServiceURL:
            return S_ERROR('Can not determine PUSP service URL for VO %s' %
                           voName)

        user = userDN.split(":")[-1]

        puspURL = "%s?voms=%s:%s&proxy-renewal=false&disable-voms-proxy=false" \
                  "&rfc-proxy=true&cn-label=user:%s" % ( puspServiceURL, vomsVO, vomsAttribute, user )

        try:
            proxy = urllib.urlopen(puspURL).read()
        except Exception as e:
            return S_ERROR('Failed to get proxy from the PUSP server')

        chain = X509Chain()
        chain.loadChainFromString(proxy)
        chain.loadKeyFromString(proxy)

        result = chain.getCredentials()
        if not result['OK']:
            return S_ERROR('Failed to get a valid PUSP proxy')
        credDict = result['Value']
        if credDict['identity'] != userDN:
            return S_ERROR(
                'Requested DN does not match the obtained one in the PUSP proxy'
            )
        timeLeft = credDict['secondsLeft']

        result = chain.generateProxyToString(lifeTime=timeLeft,
                                             diracGroup=userGroup)
        if not result['OK']:
            return result
        proxyString = result['Value']
        return S_OK((proxyString, timeLeft))
Пример #22
0
    def uploadProxy(self, proxy=None, restrictLifeTime=0, rfcIfPossible=False):
        """ Upload a proxy to the proxy management service using delegation

        :param X509Chain proxy: proxy as a chain
        :param int restrictLifeTime: proxy live time in a seconds
        :param boolean rfcIfPossible: make rfc proxy if possible

        :return: S_OK(dict)/S_ERROR() -- dict contain proxies
    """
        # Discover proxy location
        if isinstance(proxy, X509Chain):
            chain = proxy
            proxyLocation = ""
        else:
            if not proxy:
                proxyLocation = Locations.getProxyLocation()
                if not proxyLocation:
                    return S_ERROR("Can't find a valid proxy")
            elif isinstance(proxy, six.string_types):
                proxyLocation = proxy
            else:
                return S_ERROR("Can't find a valid proxy")
            chain = X509Chain()
            result = chain.loadProxyFromFile(proxyLocation)
            if not result['OK']:
                return S_ERROR("Can't load %s: %s " %
                               (proxyLocation, result['Message']))

        # Make sure it's valid
        if chain.hasExpired().get('Value'):
            return S_ERROR("Proxy %s has expired" % proxyLocation)
        if chain.getDIRACGroup().get('Value') or chain.isVOMS().get('Value'):
            return S_ERROR(
                "Cannot upload proxy with DIRAC group or VOMS extensions")

        rpcClient = RPCClient("Framework/ProxyManager", timeout=120)
        # Get a delegation request
        # WARN: Since v7r1 requestDelegationUpload method use only first argument!
        # WARN:   Second argument for compatibility with older versions
        result = rpcClient.requestDelegationUpload(
            chain.getRemainingSecs()['Value'], None)
        if not result['OK']:
            return result
        reqDict = result['Value']
        # Generate delegated chain
        chainLifeTime = chain.getRemainingSecs()['Value'] - 60
        if restrictLifeTime and restrictLifeTime < chainLifeTime:
            chainLifeTime = restrictLifeTime
        retVal = chain.generateChainFromRequestString(reqDict['request'],
                                                      lifetime=chainLifeTime,
                                                      rfc=rfcIfPossible)
        if not retVal['OK']:
            return retVal
        # Upload!
        result = rpcClient.completeDelegationUpload(reqDict['id'],
                                                    retVal['Value'])
        if not result['OK']:
            return result
        return S_OK(result.get('proxies') or result['Value'])
Пример #23
0
  def uploadProxy( self, proxy = False, diracGroup = False, chainToConnect = False, restrictLifeTime = 0 ):
    """
    Upload a proxy to the proxy management service using delgation
    """
    #Discover proxy location
    if type( proxy ) == g_X509ChainType:
      chain = proxy
      proxyLocation = ""
    else:
      if not proxy:
        proxyLocation = Locations.getProxyLocation()
        if not proxyLocation:
          return S_ERROR( "Can't find a valid proxy" )
      elif type( proxy ) in ( types.StringType, types.UnicodeType ):
        proxyLocation = proxy
      else:
        return S_ERROR( "Can't find a valid proxy" )
      chain = X509Chain()
      result = chain.loadProxyFromFile( proxyLocation )
      if not result[ 'OK' ]:
        return S_ERROR( "Can't load %s: %s " % ( proxyLocation, result[ 'Message' ] ) )

    if not chainToConnect:
      chainToConnect = chain

    #Make sure it's valid
    if chain.hasExpired()[ 'Value' ]:
      return S_ERROR( "Proxy %s has expired" % proxyLocation )

    #rpcClient = RPCClient( "Framework/ProxyManager", proxyChain = chainToConnect )
    rpcClient = RPCClient( "Framework/ProxyManager", timeout = 120 )
    #Get a delegation request
    result = rpcClient.requestDelegationUpload( chain.getRemainingSecs()['Value'], diracGroup )
    if not result[ 'OK' ]:
      return result
    #Check if the delegation has been granted
    if 'Value' not in result or not result[ 'Value' ]:
      if 'proxies' in result:
        return S_OK( result[ 'proxies' ] )
      else:
        return S_OK()
    reqDict = result[ 'Value' ]
    #Generate delegated chain
    chainLifeTime = chain.getRemainingSecs()[ 'Value' ] - 60
    if restrictLifeTime and restrictLifeTime < chainLifeTime:
      chainLifeTime = restrictLifeTime
    retVal = chain.generateChainFromRequestString( reqDict[ 'request' ],
                                                   lifetime = chainLifeTime,
                                                   diracGroup = diracGroup )
    if not retVal[ 'OK' ]:
      return retVal
    #Upload!
    result = rpcClient.completeDelegationUpload( reqDict[ 'id' ], retVal[ 'Value' ] )
    if not result[ 'OK' ]:
      return result
    if 'proxies' in result:
      return S_OK( result[ 'proxies' ] )
    return S_OK()
Пример #24
0
def getProxyInfo(proxy=False, disableVOMS=False):
    """
  :Returns: a dict with all the proxy info:

    * values that will be there always
        * 'chain' : chain object containing the proxy
        * 'subject' : subject of the proxy
        * 'issuer' : issuer of the proxy
        * 'isProxy' : bool
        * 'isLimitedProxy' : bool
        * 'validDN' : Valid DN in DIRAC
        * 'validGroup' : Valid Group in DIRAC
        * 'secondsLeft' : Seconds left
    * values that can be there
        * 'path' : path to the file,
        * 'group' : DIRAC group
        * 'groupProperties' : Properties that apply to the DIRAC Group
        * 'username' : DIRAC username
        * 'identity' : DN that generated the proxy
        * 'hostname' : DIRAC host nickname
        * 'VOMS'

  """
    # Discover proxy location
    proxyLocation = False
    if isinstance(proxy, X509Chain):
        chain = proxy
    else:
        if not proxy:
            proxyLocation = Locations.getProxyLocation()
        elif isinstance(proxy, basestring):
            proxyLocation = proxy
        if not proxyLocation:
            return S_ERROR(DErrno.EPROXYFIND)
        chain = X509Chain()
        retVal = chain.loadProxyFromFile(proxyLocation)
        if not retVal['OK']:
            return S_ERROR(DErrno.EPROXYREAD,
                           "%s: %s " % (proxyLocation, retVal['Message']))

    retVal = chain.getCredentials()
    if not retVal['OK']:
        return retVal

    infoDict = retVal['Value']
    infoDict['chain'] = chain
    if proxyLocation:
        infoDict['path'] = proxyLocation

    if not disableVOMS and chain.isVOMS()['Value']:
        infoDict['hasVOMS'] = True
        retVal = VOMS().getVOMSAttributes(chain)
        if retVal['OK']:
            infoDict['VOMS'] = retVal['Value']
        else:
            infoDict['VOMSError'] = retVal['Message'].strip()

    return S_OK(infoDict)
Пример #25
0
    def uploadProxy(self, proxy=None, restrictLifeTime=0, rfcIfPossible=False):
        """Upload a proxy to the proxy management service using delegation

        :param X509Chain proxy: proxy as a chain
        :param int restrictLifeTime: proxy live time in a seconds
        :param boolean rfcIfPossible: make rfc proxy if possible

        :return: S_OK(dict)/S_ERROR() -- dict contain proxies
        """
        # Discover proxy location
        if isinstance(proxy, X509Chain):
            chain = proxy
            proxyLocation = ""
        else:
            if not proxy:
                proxyLocation = Locations.getProxyLocation()
                if not proxyLocation:
                    return S_ERROR("Can't find a valid proxy")
            elif isinstance(proxy, six.string_types):
                proxyLocation = proxy
            else:
                return S_ERROR("Can't find a valid proxy")
            chain = X509Chain()
            result = chain.loadProxyFromFile(proxyLocation)
            if not result["OK"]:
                return S_ERROR("Can't load %s: %s " %
                               (proxyLocation, result["Message"]))

        # Make sure it's valid
        if chain.hasExpired().get("Value"):
            return S_ERROR("Proxy %s has expired" % proxyLocation)
        if chain.getDIRACGroup(ignoreDefault=True).get(
                "Value") or chain.isVOMS().get("Value"):
            return S_ERROR(
                "Cannot upload proxy with DIRAC group or VOMS extensions")

        rpcClient = Client(url="Framework/ProxyManager", timeout=120)
        # Get a delegation request
        result = rpcClient.requestDelegationUpload(
            chain.getRemainingSecs()["Value"])
        if not result["OK"]:
            return result
        reqDict = result["Value"]
        # Generate delegated chain
        chainLifeTime = chain.getRemainingSecs()["Value"] - 60
        if restrictLifeTime and restrictLifeTime < chainLifeTime:
            chainLifeTime = restrictLifeTime
        retVal = chain.generateChainFromRequestString(reqDict["request"],
                                                      lifetime=chainLifeTime,
                                                      rfc=rfcIfPossible)
        if not retVal["OK"]:
            return retVal
        # Upload!
        result = rpcClient.completeDelegationUpload(reqDict["id"],
                                                    retVal["Value"])
        if not result["OK"]:
            return result
        return S_OK(result.get("proxies") or result["Value"])
Пример #26
0
def getProxyInfo(proxy=False, disableVOMS=False):
    """
  Returns a dict with all the proxy info
  * values that will be there always
   'chain' : chain object containing the proxy
   'subject' : subject of the proxy
   'issuer' : issuer of the proxy
   'isProxy' : bool
   'isLimitedProxy' : bool
   'validDN' : Valid DN in DIRAC
   'validGroup' : Valid Group in DIRAC
   'secondsLeft' : Seconds left
  * values that can be there
   'path' : path to the file,
   'group' : DIRAC group
   'groupProperties' : Properties that apply to the DIRAC Group
   'username' : DIRAC username
   'identity' : DN that generated the proxy
   'hostname' : DIRAC host nickname
   'VOMS'
  """
    #Discover proxy location
    proxyLocation = False
    if type(proxy) == g_X509ChainType:
        chain = proxy
    else:
        if not proxy:
            proxyLocation = Locations.getProxyLocation()
        elif type(proxy) in (types.StringType, types.UnicodeType):
            proxyLocation = proxy
        if not proxyLocation:
            return S_ERROR("Can't find a valid proxy")
        chain = X509Chain()
        retVal = chain.loadProxyFromFile(proxyLocation)
        if not retVal['OK']:
            return S_ERROR("Can't load %s: %s " %
                           (proxyLocation, retVal['Message']))

    retVal = chain.getCredentials()
    if not retVal['OK']:
        return retVal

    infoDict = retVal['Value']
    infoDict['chain'] = chain
    if proxyLocation:
        infoDict['path'] = proxyLocation

    if not disableVOMS and chain.isVOMS()['Value']:
        infoDict['hasVOMS'] = True
        retVal = VOMS().getVOMSAttributes(chain)
        if retVal['OK']:
            infoDict['VOMS'] = retVal['Value']
        else:
            infoDict['VOMSError'] = retVal['Message'].strip()

    return S_OK(infoDict)
Пример #27
0
  def getProxy(self, userDN, userGroup, requiredLifeTime=False):
    """ Get proxy string from the Proxy Repository for use with userDN
        in the userGroup
    """

    # Get the Per User SubProxy if one is requested
    if isPUSPdn(userDN):
      result = self.__getPUSProxy(userDN, userGroup, requiredLifeTime)
      if not result['OK']:
        return result
      pemData = result['Value'][0]
      timeLeft = result['Value'][1]
      chain = X509Chain()
      result = chain.loadProxyFromString(pemData)
      if not result['OK']:
        return result
      return S_OK((chain, timeLeft))

    # Standard proxy is requested
    retVal = self.__getPemAndTimeLeft(userDN, userGroup)
    if not retVal['OK']:
      return retVal
    pemData = retVal['Value'][0]
    timeLeft = retVal['Value'][1]
    chain = X509Chain()
    retVal = chain.loadProxyFromString(pemData)
    if not retVal['OK']:
      return retVal
    if requiredLifeTime:
      if timeLeft < requiredLifeTime:
        if self.__useMyProxy:
          retVal = self.renewFromMyProxy(userDN, userGroup, lifeTime=requiredLifeTime, chain=chain)
          if not retVal['OK']:
            return S_ERROR("Can't get a proxy for %s seconds: %s" % (requiredLifeTime, retVal['Message']))
          chain = retVal['Value']
        else:
          return S_ERROR("Can't get a proxy: the required lifetime is less than the time left in the proxy")
    # Proxy is invalid for some reason, let's delete it
    if not chain.isValidProxy()['Value']:
      self.deleteProxy(userDN, userGroup)
      return S_ERROR("%s@%s has no proxy registered" % (userDN, userGroup))

    return S_OK((chain, timeLeft))
Пример #28
0
def delegate(delegationRequest, kwargs):
    """
    Check delegate!
    """
    if kwargs.get("useCertificates"):
        chain = X509Chain()
        certTuple = Locations.getHostCertificateAndKeyLocation()
        chain.loadChainFromFile(certTuple[0])
        chain.loadKeyFromFile(certTuple[1])
    elif "proxyObject" in kwargs:
        chain = kwargs["proxyObject"]
    else:
        if "proxyLocation" in kwargs:
            procLoc = kwargs["proxyLocation"]
        else:
            procLoc = Locations.getProxyLocation()
        chain = X509Chain()
        chain.loadChainFromFile(procLoc)
        chain.loadKeyFromFile(procLoc)
    return chain.generateChainFromRequestString(delegationRequest)
Пример #29
0
  def test_getProxyGroup(self):

    result = self.pp.getProxy(self.userDictGroup)
    self.assertTrue(result['OK'], '\n%s' % result.get('Message') or 'Error message is absent.')
    chain = X509Chain()
    chain.loadChainFromString(result['Value'])
    result = chain.getCredentials()
    self.assertTrue(result['OK'], '\n%s' % result.get('Message') or 'Error message is absent.')
    credDict = result['Value']
    self.assertEqual(credDict['username'], 'testuser',
                     '%s, expected %s' % (credDict['username'], 'testuser'))
    self.assertEqual(credDict['group'], 'dirac_user',
                     '%s, expected %s' % (credDict['group'], 'dirac_user'))
Пример #30
0
    def completeDelegation(self, requestId, userDN, delegatedPem):
        """
    Complete a delegation and store it in the db
    """
        retVal = self.retrieveDelegationRequest(requestId, userDN)
        if not retVal['OK']:
            return retVal
        request = retVal['Value']
        chain = X509Chain(keyObj=request.getPKey())
        retVal = chain.loadChainFromString(delegatedPem)
        if not retVal['OK']:
            return retVal
        retVal = chain.isValidProxy()
        if not retVal['OK']:
            return retVal
        if not retVal['Value']:
            return S_ERROR("Chain received is not a valid proxy: %s" %
                           retVal['Message'])

        retVal = request.checkChain(chain)
        if not retVal['OK']:
            return retVal
        if not retVal['Value']:
            return S_ERROR("Received chain does not match request: %s" %
                           retVal['Message'])

        retVal = chain.getDIRACGroup()
        if not retVal['OK']:
            return retVal
        userGroup = retVal['Value']
        if not userGroup:
            userGroup = CS.getDefaultUserGroup()

        retVal = CS.getGroupsForDN(userDN)
        if not retVal['OK']:
            return retVal
        if not userGroup in retVal['Value']:
            return S_ERROR("%s group is not valid for %s" %
                           (userGroup, userDN))

        retVal = self.__checkVOMSisAlignedWithGroup(userGroup, chain)
        if not retVal['OK']:
            return retVal

        retVal = self.storeProxy(userDN, userGroup, chain)
        if not retVal['OK']:
            return retVal
        retVal = self.deleteRequest(requestId)
        if not retVal['OK']:
            return retVal
        return S_OK()