def generateRevokedCertsFile(location=None): """ Generate a single CA file with all the PEMs :param str location: we can specify a specific location in CS :return file crls.pem which contains all revoked certificates """ caDir = Locations.getCAsLocation() for fn in (os.path.join(os.path.dirname(caDir), "crls.pem"), os.path.join(os.path.dirname(Locations.getHostCertificateAndKeyLocation(location)[0]), "crls.pem"), False): if not fn: fn = tempfile.mkstemp(prefix="crls", suffix=".pem")[1] try: with open(fn, "w") as fd: for caFile in os.listdir(caDir): caFile = os.path.join(caDir, caFile) result = X509CRL.X509CRL.instanceFromFile(caFile) if not result['OK']: continue chain = result['Value'] fd.write(chain.dumpAllToString()['Value']) return S_OK(fn) except IOError: continue return S_ERROR(caDir)
def __getDirsToBundle( self ): dirsToBundle = {} result = gConfig.getOptionsDict( "%s/DirsToBundle" % self.__csPath ) if result[ 'OK' ]: dB = result[ 'Value' ] for bId in dB: dirsToBundle[ bId ] = List.fromChar( dB[ bId ] ) if gConfig.getValue( "%s/BundleCAs" % self.__csPath, True ): dirsToBundle[ 'CAs' ] = [ "%s/*.0" % Locations.getCAsLocation(), "%s/*.signing_policy" % Locations.getCAsLocation(), "%s/*.pem" % Locations.getCAsLocation() ] if gConfig.getValue( "%s/BundleCRLs" % self.__csPath, True ): dirsToBundle[ 'CRLs' ] = [ "%s/*.r0" % Locations.getCAsLocation() ] return dirsToBundle
def syncCAs(self): X509_CERT_DIR = False if 'X509_CERT_DIR' in os.environ: X509_CERT_DIR = os.environ['X509_CERT_DIR'] del os.environ['X509_CERT_DIR'] casLocation = Locations.getCAsLocation() if not casLocation: casLocation = Locations.getCAsDefaultLocation() result = self.syncDir("CAs", casLocation) if X509_CERT_DIR: os.environ['X509_CERT_DIR'] = X509_CERT_DIR return result
def syncCAs( self ): X509_CERT_DIR = False if 'X509_CERT_DIR' in os.environ: X509_CERT_DIR = os.environ['X509_CERT_DIR'] del os.environ['X509_CERT_DIR'] casLocation = Locations.getCAsLocation() if not casLocation: casLocation = Locations.getCAsDefaultLocation() result = self.syncDir( "CAs", casLocation ) if X509_CERT_DIR: os.environ['X509_CERT_DIR'] = X509_CERT_DIR return result
def startTornado(self): """ Starts the tornado server when ready. This method never returns. """ sLog.debug("Starting Tornado") self._initMonitoring() router = Application(self.urls, debug=False, compress_response=True) certs = Locations.getHostCertificateAndKeyLocation() if certs is False: sLog.fatal("Host certificates not found ! Can't start the Server") raise ImportError("Unable to load certificates") ca = Locations.getCAsLocation() ssl_options = { "certfile": certs[0], "keyfile": certs[1], "cert_reqs": M2Crypto.SSL.verify_peer, "ca_certs": ca, "sslDebug": DEBUG_M2CRYPTO, # Set to true if you want to see the TLS debug messages } self.__monitorLastStatsUpdate = time.time() self.__report = self.__startReportToMonitoringLoop() # Starting monitoring, IOLoop waiting time in ms, __monitoringLoopDelay is defined in seconds tornado.ioloop.PeriodicCallback(self.__reportToMonitoring, self.__monitoringLoopDelay * 1000).start() # If we are running with python3, Tornado will use asyncio, # and we have to convince it to let us run in a different thread # Doing this ensures a consistent behavior between py2 and py3 if six.PY3: import asyncio # pylint: disable=import-error asyncio.set_event_loop_policy(tornado.platform.asyncio.AnyThreadEventLoopPolicy()) # Start server server = HTTPServer(router, ssl_options=ssl_options, decompress_request=True) try: server.listen(self.port) except Exception as e: # pylint: disable=broad-except sLog.exception("Exception starting HTTPServer", e) raise sLog.always("Listening on port %s" % self.port) for service in self.urls: sLog.debug("Available service: %s" % service) IOLoop.current().start()
def generateCAFile(location=None): """ Generate/find a single CA file with all the PEMs :param str location: we can specify a specific CS location where it's written a directory where to find the CAs and CRLs :return: directory where the file cas.pem which contains all certificates is found/created """ caDir = Locations.getCAsLocation() if not caDir: return S_ERROR('No CAs dir found') # look in what's normally /etc/grid-security/certificates if os.path.isfile(os.path.join(os.path.dirname(caDir), "cas.pem")): return S_OK(os.path.join(os.path.dirname(caDir), "cas.pem")) # look in what's normally /opt/dirac/etc/grid-security diracCADirPEM = os.path.join( os.path.dirname( Locations.getHostCertificateAndKeyLocation(location)[0]), "cas.pem") if os.path.isfile(diracCADirPEM): return S_OK(diracCADirPEM) # Now we create it in tmpdir fn = tempfile.mkstemp(prefix="cas.", suffix=".pem")[1] try: with open(fn, "w") as fd: for caFile in os.listdir(caDir): caFile = os.path.join(caDir, caFile) chain = X509Chain.X509Chain() result = chain.loadChainFromFile(caFile) if not result['OK']: continue expired = chain.hasExpired() if not expired['OK'] or expired['Value']: continue fd.write(chain.dumpAllToString()['Value']) gLogger.info("CAs used from: %s" % str(fn)) return S_OK(fn) except IOError as err: gLogger.warn(err) return S_ERROR("Could not find/generate CAs")
def main(): params = Params() Script.registerSwitch("f:", "file=", "File to use as proxy", params.setProxyLocation) Script.registerSwitch("D", "DN", "Use DN as myproxy username", params.setDNAsUsername) Script.addDefaultOptionValue("LogLevel", "always") Script.parseCommandLine() from DIRAC.Core.Security.MyProxy import MyProxy from DIRAC.Core.Security import Locations if not params.proxyLoc: params.proxyLoc = Locations.getProxyLocation() if not params.proxyLoc: print("Can't find any valid proxy") sys.exit(1) print("Uploading proxy file %s" % params.proxyLoc) mp = MyProxy() retVal = mp.uploadProxy(params.proxyLoc, params.dnAsUsername) if not retVal["OK"]: print("Can't upload proxy:") print(" ", retVal["Message"]) sys.exit(1) print("Proxy uploaded") sys.exit(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
def __init__(self, server=False, serverCert=False, serverKey=False, timeout=False): if timeout: self._secCmdTimeout = timeout else: self._secCmdTimeout = 30 if not server: self._secServer = gConfig.getValue("/DIRAC/VOPolicy/MyProxyServer", "myproxy.cern.ch") else: self._secServer = server ckLoc = Locations.getHostCertificateAndKeyLocation() if serverCert: self._secCertLoc = serverCert else: if ckLoc: self._secCertLoc = ckLoc[0] else: self._secCertLoc = "%s/etc/grid-security/servercert.pem" % DIRAC.rootPath if serverKey: self._secKeyLoc = serverKey else: if ckLoc: self._secKeyLoc = ckLoc[1] else: self._secKeyLoc = "%s/etc/grid-security/serverkey.pem" % DIRAC.rootPath self._secRunningFromTrustedHost = gConfig.getValue( "/DIRAC/VOPolicy/MyProxyTrustedHost", "True").lower() in ("y", "yes", "true") self._secMaxProxyHours = gConfig.getValue( "/DIRAC/VOPolicy/MyProxyMaxDelegationTime", 168)
def __getDirsToBundle(self): dirsToBundle = {} result = gConfig.getOptionsDict("%s/DirsToBundle" % self.__csPath) if result['OK']: dB = result['Value'] for bId in dB: dirsToBundle[bId] = List.fromChar(dB[bId]) if gConfig.getValue("%s/BundleCAs" % self.__csPath, True): dirsToBundle['CAs'] = [ "%s/*.0" % Locations.getCAsLocation(), "%s/*.signing_policy" % Locations.getCAsLocation(), "%s/*.pem" % Locations.getCAsLocation() ] if gConfig.getValue("%s/BundleCRLs" % self.__csPath, True): dirsToBundle['CRLs'] = ["%s/*.r0" % Locations.getCAsLocation()] return dirsToBundle
def HTTPSCert(): cert = Locations.getHostCertificateAndKeyLocation() if cert: cert = cert[0] else: cert = "/opt/dirac/etc/grid-security/hostcert.pem" return getCSValue("HTTPS/Cert", cert)
def generateCAFile(): """ Generate a single CA file with all the PEMs """ caDir = Locations.getCAsLocation() for fn in (os.path.join(os.path.dirname(caDir), "cas.pem"), os.path.join(os.path.dirname(HTTPSCert()), "cas.pem"), False): if not fn: fn = tempfile.mkstemp(prefix="cas.", suffix=".pem")[1] try: fd = open(fn, "w") except IOError: continue for caFile in os.listdir(caDir): caFile = os.path.join(caDir, caFile) result = X509Chain.X509Chain.instanceFromFile(caFile) if not result['OK']: continue chain = result['Value'] expired = chain.hasExpired() if not expired['OK'] or expired['Value']: continue fd.write(chain.dumpAllToString()['Value']) fd.close() return fn return False
def HTTPSKey(): key = Locations.getHostCertificateAndKeyLocation() if key: key = key[1] else: key = "/opt/dirac/etc/grid-security/hostkey.pem" return getCSValue("HTTPS/Key", key)
def __init__( self, server = False, serverCert = False, serverKey = False, voName = False, timeout = False ): if timeout: self._secCmdTimeout = timeout else: self._secCmdTimeout = 30 if not server: self._secServer = gConfig.getValue( "/DIRAC/VOPolicy/MyProxyServer", "myproxy.cern.ch" ) else: self._secServer = server if not voName: self._secVO = getVO( "unknown" ) else: self._secVO = voName ckLoc = Locations.getHostCertificateAndKeyLocation() if serverCert: self._secCertLoc = serverCert else: if ckLoc: self._secCertLoc = ckLoc[0] else: self._secCertLoc = "%s/etc/grid-security/servercert.pem" % DIRAC.rootPath if serverKey: self._secKeyLoc = serverKey else: if ckLoc: self._secKeyLoc = ckLoc[1] else: self._secKeyLoc = "%s/etc/grid-security/serverkey.pem" % DIRAC.rootPath self._secRunningFromTrustedHost = gConfig.getValue( "/DIRAC/VOPolicy/MyProxyTrustedHost", "True" ).lower() in ( "y", "yes", "true" ) self._secMaxProxyHours = gConfig.getValue( "/DIRAC/VOPolicy/MyProxyMaxDelegationTime", 168 )
def syncCAs(self): """Synchronize CAs :return: S_OK(bool)/S_ERROR() """ X509_CERT_DIR = False if "X509_CERT_DIR" in os.environ: X509_CERT_DIR = os.environ["X509_CERT_DIR"] del os.environ["X509_CERT_DIR"] casLocation = Locations.getCAsLocation() if not casLocation: casLocation = Locations.getCAsDefaultLocation() result = self.syncDir("CAs", casLocation) if X509_CERT_DIR: os.environ["X509_CERT_DIR"] = X509_CERT_DIR return result
def generateCAFile(): """ Generate a single CA file with all the PEMs """ caDir = Locations.getCAsLocation() for fn in (os.path.join(os.path.dirname(caDir), "cas.pem"), os.path.join(os.path.dirname(getCert()), "cas.pem"), False): if not fn: fn = tempfile.mkstemp(prefix="cas.", suffix=".pem")[1] try: with open(fn, "w") as fd: for caFile in os.listdir(caDir): caFile = os.path.join(caDir, caFile) result = X509Chain.X509Chain.instanceFromFile(caFile) if not result['OK']: continue chain = result['Value'] expired = chain.hasExpired() if not expired['OK'] or expired['Value']: continue fd.write(chain.dumpAllToString()['Value']) gLogger.info("CAs used from: %s" % str(fn)) return fn except IOError as err: gLogger.warn(err) return False
def HTTPSKey(): key = Locations.getHostCertificateAndKeyLocation() if key: key = key[1] else: key = "/opt/dirac/etc/grid-security/hostkey.pem" return getCSValue( "HTTPS/Key", key )
def generateCAFile(): """ Generate a single CA file with all the PEMs """ caDir = Locations.getCAsLocation() for fn in ( os.path.join( os.path.dirname( caDir ), "cas.pem" ), os.path.join( os.path.dirname( HTTPSCert() ), "cas.pem" ), False ): if not fn: fn = tempfile.mkstemp( prefix = "cas.", suffix = ".pem" ) try: fd = open( fn, "w" ) except IOError: continue for caFile in os.listdir( caDir ): caFile = os.path.join( caDir, caFile ) result = X509Chain.X509Chain.instanceFromFile( caFile ) if not result[ 'OK' ]: continue chain = result[ 'Value' ] expired = chain.hasExpired() if not expired[ 'OK' ] or expired[ 'Value' ]: continue fd.write( chain.dumpAllToString()[ 'Value' ] ) fd.close() return fn return False
def HTTPSCert(): cert = Locations.getHostCertificateAndKeyLocation() if cert: cert = cert[0] else: cert = "/opt/dirac/etc/grid-security/hostcert.pem" return getCSValue( "HTTPS/Cert", cert )
def startTornado(self): """ Starts the tornado server when ready. This method never returns. """ sLog.debug("Starting Tornado") self._initMonitoring() router = Application(self.urls, debug=False, compress_response=True) certs = Locations.getHostCertificateAndKeyLocation() if certs is False: sLog.fatal("Host certificates not found ! Can't start the Server") raise ImportError("Unable to load certificates") ca = Locations.getCAsLocation() ssl_options = { 'certfile': certs[0], 'keyfile': certs[1], 'cert_reqs': M2Crypto.SSL.verify_peer, 'ca_certs': ca, 'sslDebug': False, # Set to true if you want to see the TLS debug messages } self.__monitorLastStatsUpdate = time.time() self.__report = self.__startReportToMonitoringLoop() # Starting monitoring, IOLoop waiting time in ms, __monitoringLoopDelay is defined in seconds tornado.ioloop.PeriodicCallback(self.__reportToMonitoring, self.__monitoringLoopDelay * 1000).start() # Start server server = HTTPServer(router, ssl_options=ssl_options, decompress_request=True) try: server.listen(self.port) except Exception as e: # pylint: disable=broad-except sLog.exception("Exception starting HTTPServer", e) raise sLog.always("Listening on port %s" % self.port) for service in self.urls: sLog.debug("Available service: %s" % service) IOLoop.current().start()
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'])
def uploadProxy( self, proxy = False, diracGroup = False, chainToConnect = False, restrictLifeTime = 0, rfcIfPossible = False ): """ Upload a proxy to the proxy management service using delegation """ #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 isinstance( proxy, basestring ): 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, rfc = rfcIfPossible) 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()
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()
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)
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"])
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 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 )
def syncCRLs( self ): X509_CERT_DIR = False if 'X509_CERT_DIR' in os.environ: X509_CERT_DIR = os.environ['X509_CERT_DIR'] del os.environ['X509_CERT_DIR'] result = self.syncDir( "CRLs", Locations.getCAsLocation() ) if X509_CERT_DIR: os.environ['X509_CERT_DIR'] = X509_CERT_DIR return result
def syncCRLs(self): X509_CERT_DIR = False if 'X509_CERT_DIR' in os.environ: X509_CERT_DIR = os.environ['X509_CERT_DIR'] del os.environ['X509_CERT_DIR'] result = self.syncDir("CRLs", Locations.getCAsLocation()) if X509_CERT_DIR: os.environ['X509_CERT_DIR'] = X509_CERT_DIR return result
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)
def main(): """ main program entry point """ options = Params() options.registerCLISwitches() Script.parseCommandLine(ignoreErrors=True) if options.delete_all and options.vos: gLogger.error( "-a and -v options are mutually exclusive. Please pick one or the other." ) return 1 proxyLoc = Locations.getDefaultProxyLocation() if not os.path.exists(proxyLoc): gLogger.error("No local proxy found in %s, exiting." % proxyLoc) return 1 result = ProxyInfo.getProxyInfo(proxyLoc, True) if not result['OK']: raise RuntimeError('Failed to get local proxy info.') if result['Value']['secondsLeft'] < 60 and options.needsValidProxy(): raise RuntimeError( 'Lifetime of local proxy too short, please renew proxy.') userDN = result['Value']['identity'] if options.delete_all: # delete remote proxies remote_groups = getProxyGroups() if not remote_groups: gLogger.notice('No remote proxies found.') for vo_group in remote_groups: deleteRemoteProxy(userDN, vo_group) # delete local proxy deleteLocalProxy(proxyLoc) elif options.vos: vo_groups = set() for voname in options.vos: vo_groups.update(mapVoToGroups(voname)) # filter set of all groups to only contain groups for which there is a user proxy user_groups = getProxyGroups() vo_groups.intersection_update(user_groups) if not vo_groups: gLogger.notice( 'You have no proxies registered for any of the specified VOs.') for group in vo_groups: deleteRemoteProxy(userDN, group) else: deleteLocalProxy(proxyLoc) return 0
def getCert(): """ get the host certificate """ cert = Locations.getHostCertificateAndKeyLocation() if cert: cert = cert[0] else: cert = "/opt/dirac/etc/grid-security/hostcert.pem" return cert
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 )
def generateRevokedCertsFile(location=None): """ Generate a single CA file with all the PEMs :param str location: we can specify a specific CS location where it's written a directory where to find the CAs and CRLs :return: directory where the file crls.pem which contains all CRLs is created """ caDir = Locations.getCAsLocation() if not caDir: return S_ERROR("No CAs dir found") # look in what's normally /etc/grid-security/certificates if os.path.isfile(os.path.join(os.path.dirname(caDir), "crls.pem")): return S_OK(os.path.join(os.path.dirname(caDir), "crls.pem")) # look in what's normally /opt/dirac/etc/grid-security diracCADirPEM = os.path.join( os.path.dirname( Locations.getHostCertificateAndKeyLocation(location)[0]), "crls.pem") if os.path.isfile(diracCADirPEM): return S_OK(diracCADirPEM) # Now we create it in tmpdir fn = tempfile.mkstemp(prefix="crls", suffix=".pem")[1] try: with open(fn, "wb") as fd: for caFile in os.listdir(caDir): caFile = os.path.join(caDir, caFile) result = X509CRL.X509CRL.instanceFromFile(caFile) if not result["OK"]: continue chain = result["Value"] fd.write(chain.dumpAllToString()["Value"]) return S_OK(fn) except IOError as err: gLogger.warn(err) return S_ERROR("Could not find/generate CRLs")
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)
def delegate( delegationRequest, kwargs ): """ Check delegate! """ if "useCertificates" in kwargs and kwargs[ '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 )
def generateCAFile(location=None): """ Generate a single CA file with all the PEMs :param str location: we can specify a specific location in CS :return: file cas.pem which contains all certificates """ caDir = Locations.getCAsLocation() for fn in ( os.path.join(os.path.dirname(caDir), "cas.pem"), os.path.join( os.path.dirname( Locations.getHostCertificateAndKeyLocation(location)[0]), "cas.pem"), False): if not fn: fn = tempfile.mkstemp(prefix="cas.", suffix=".pem")[1] try: with open(fn, "w") as fd: for caFile in os.listdir(caDir): caFile = os.path.join(caDir, caFile) chain = X509Chain.X509Chain() result = chain.loadChainFromFile(caFile) if not result['OK']: continue expired = chain.hasExpired() if not expired['OK'] or expired['Value']: continue fd.write(chain.dumpAllToString()['Value']) gLogger.info("CAs used from: %s" % str(fn)) return S_OK(fn) except IOError as err: gLogger.warn(err) return S_ERROR(caDir)
def main(): """ main program entry point """ options = Params() options.registerCLISwitches() Script.parseCommandLine( ignoreErrors = True ) if options.delete_all and options.vos: gLogger.error( "-a and -v options are mutually exclusive. Please pick one or the other." ) return 1 proxyLoc = Locations.getDefaultProxyLocation() if not os.path.exists( proxyLoc ): gLogger.error( "No local proxy found in %s, exiting." % proxyLoc ) return 1 result = ProxyInfo.getProxyInfo( proxyLoc, True ) if not result[ 'OK' ]: raise RuntimeError( 'Failed to get local proxy info.' ) if result[ 'Value' ][ 'secondsLeft' ] < 60 and options.needsValidProxy(): raise RuntimeError( 'Lifetime of local proxy too short, please renew proxy.' ) userDN=result[ 'Value' ][ 'identity' ] if options.delete_all: # delete remote proxies remote_groups = getProxyGroups() if not remote_groups: gLogger.notice( 'No remote proxies found.' ) for vo_group in remote_groups: deleteRemoteProxy( userDN, vo_group ) # delete local proxy deleteLocalProxy( proxyLoc ) elif options.vos: vo_groups = set() for voname in options.vos: vo_groups.update(mapVoToGroups( voname ) ) # filter set of all groups to only contain groups for which there is a user proxy user_groups = getProxyGroups() vo_groups.intersection_update( user_groups ) if not vo_groups: gLogger.notice( 'You have no proxies registered for any of the specified VOs.' ) for group in vo_groups: deleteRemoteProxy( userDN, group ) else: deleteLocalProxy( proxyLoc ) return 0
def syncCRLs(self): """Synchronize CRLs :return: S_OK(bool)/S_ERROR() """ X509_CERT_DIR = False if "X509_CERT_DIR" in os.environ: X509_CERT_DIR = os.environ["X509_CERT_DIR"] del os.environ["X509_CERT_DIR"] result = self.syncDir("CRLs", Locations.getCAsLocation()) if X509_CERT_DIR: os.environ["X509_CERT_DIR"] = X509_CERT_DIR return result
def __loadM2SSLCTXProxy(ctx, proxyPath=None): """ Load proxy from proxyPath (or default location if not specified) and set it as the certificate & key to use for this SSL context. Returns None. """ if not proxyPath: proxyPath = Locations.getProxyLocation() if not proxyPath: raise RuntimeError("Proxy location not set") if not os.path.isfile(proxyPath): raise RuntimeError("Proxy file (%s) is missing" % proxyPath) # See __loadM2SSLCTXHostcert for description of why lambda is needed. ctx.load_cert_chain(proxyPath, proxyPath, callback=lambda: "")
def __generateContextWithCerts(self): certKeyTuple = Locations.getHostCertificateAndKeyLocation() if not certKeyTuple: return S_ERROR("No valid certificate or key found") self.setLocalCredentialsLocation(certKeyTuple) gLogger.debug("Using certificate %s\nUsing key %s" % certKeyTuple) retVal = self.__createContext() if not retVal['OK']: return retVal # Verify depth to 20 to ensure accepting proxies of proxies of proxies.... self.sslContext.set_verify_depth(VERIFY_DEPTH) self.sslContext.use_certificate_chain_file(certKeyTuple[0]) self.sslContext.use_privatekey_file(certKeyTuple[1]) return S_OK()
def __getCertificateID(self): certLocation = Locations.getHostCertificateAndKeyLocation() if not certLocation: gLogger.error("No certificate found!") return False chain = X509Chain() retVal = chain.loadChainFromFile(certLocation[0]) if not retVal['OK']: gLogger.error("Can't parse certificate!", retVal['Message']) return False idCert = chain.getIssuerCert()['Value'] self.__userDN = idCert.getSubjectDN()['Value'] self.__userGroup = 'host' return True
def __generateContextWithCerts( self ): certKeyTuple = Locations.getHostCertificateAndKeyLocation() if not certKeyTuple: return S_ERROR( "No valid certificate or key found" ) self.setLocalCredentialsLocation( certKeyTuple ) gLogger.debug( "Using certificate %s\nUsing key %s" % certKeyTuple ) retVal = self.__createContext() if not retVal[ 'OK' ]: return retVal #Verify depth to 20 to ensure accepting proxies of proxies of proxies.... self.sslContext.set_verify_depth( 50 ) self.sslContext.use_certificate_chain_file( certKeyTuple[0] ) self.sslContext.use_privatekey_file( certKeyTuple[1] ) return S_OK()
def __getCertificateID( self ): certLocation = Locations.getHostCertificateAndKeyLocation() if not certLocation: gLogger.error( "No certificate found!" ) return False chain = X509Chain() retVal = chain.loadChainFromFile( certLocation[ 0 ] ) if not retVal[ 'OK' ]: gLogger.error( "Can't parse certificate!", retVal[ 'Message' ] ) return False idCert = chain.getIssuerCert()[ 'Value' ] self.__userDN = idCert.getSubjectDN()[ 'Value' ] self.__userGroup = 'host' return True
def generateCAFile(location=None): """ Generate a single CA file with all the PEMs :param str location: we can specify a specific location in CS :return file cas.pem which contains all certificates """ caDir = Locations.getCAsLocation() for fn in (os.path.join(os.path.dirname(caDir), "cas.pem"), os.path.join(os.path.dirname(Locations.getHostCertificateAndKeyLocation(location)[0]), "cas.pem"), False): if not fn: fn = tempfile.mkstemp(prefix="cas.", suffix=".pem")[1] try: with open(fn, "w") as fd: for caFile in os.listdir(caDir): caFile = os.path.join(caDir, caFile) result = X509Chain.X509Chain.instanceFromFile(caFile) if not result['OK']: continue chain = result['Value'] expired = chain.hasExpired() if not expired['OK'] or expired['Value']: continue fd.write(chain.dumpAllToString()['Value']) gLogger.info("CAs used from: %s" % str(fn)) return S_OK(fn) except IOError as err: gLogger.warn(err) return S_ERROR(caDir)
def __loadM2SSLCTXHostcert(ctx): """ Load hostcert & key from the default location and set them as the credentials for SSL context ctx. Returns None. """ certKeyTuple = Locations.getHostCertificateAndKeyLocation() if not certKeyTuple: raise RuntimeError("Hostcert/key location not set") hostcert, hostkey = certKeyTuple if not os.path.isfile(hostcert): raise RuntimeError("Hostcert file (%s) is missing" % hostcert) if not os.path.isfile(hostkey): raise RuntimeError("Hostkey file (%s) is missing" % hostkey) # Make sure we never stall on a password prompt if the hostkey has a password # by specifying a blank string. ctx.load_cert(hostcert, hostkey, callback=lambda: "")
def __deleteSandboxFromExternalBackend(self, SEName, SEPFN): if self.getCSOption("DelayedExternalDeletion", True): gLogger.info("Setting deletion request") try: # We need the hostDN used in order to pass these credentials to the # SandboxStoreDB.. hostCertLocation, _ = Locations.getHostCertificateAndKeyLocation( ) hostCert = X509Certificate.X509Certificate() hostCert.loadFromFile(hostCertLocation) hostDN = hostCert.getSubjectDN().get("Value") # use the host authentication to fetch the data result = self.sandboxDB.getSandboxOwner( SEName, SEPFN, hostDN, "hosts") if not result["OK"]: return result _owner, ownerDN, ownerGroup = result["Value"] request = Request() request.RequestName = "RemoteSBDeletion:%s|%s:%s" % ( SEName, SEPFN, time.time()) request.OwnerDN = ownerDN request.OwnerGroup = ownerGroup physicalRemoval = Operation() physicalRemoval.Type = "PhysicalRemoval" physicalRemoval.TargetSE = SEName fileToRemove = File() fileToRemove.PFN = SEPFN physicalRemoval.addFile(fileToRemove) request.addOperation(physicalRemoval) return ReqClient().putRequest(request) except Exception as e: gLogger.exception("Exception while setting deletion request") return S_ERROR(f"Cannot set deletion request: {e}") else: gLogger.info("Deleting external Sandbox") try: return StorageElement(SEName).removeFile(SEPFN) except Exception: gLogger.exception( "RM raised an exception while trying to delete a remote sandbox" ) return S_ERROR( "RM raised an exception while trying to delete a remote sandbox" )
def __generateContextWithProxy( self ): if 'proxyLocation' in self.infoDict: proxyPath = self.infoDict[ 'proxyLocation' ] if not os.path.isfile( proxyPath ): return S_ERROR( "Defined proxy is not a file" ) else: proxyPath = Locations.getProxyLocation() if not proxyPath: return S_ERROR( "No valid proxy found" ) self.setLocalCredentialsLocation( ( proxyPath, proxyPath ) ) gLogger.debug( "Using proxy %s" % proxyPath ) retVal = self.__createContext() if not retVal[ 'OK' ]: return retVal self.sslContext.use_certificate_chain_file( proxyPath ) self.sslContext.use_privatekey_file( proxyPath ) return S_OK()
def __getProxyID( self ): proxyLocation = Locations.getProxyLocation() if not proxyLocation: gLogger.error( "No proxy found!" ) return False chain = X509Chain() if not chain.loadProxyFromFile( proxyLocation ): gLogger.error( "Can't read proxy!", proxyLocation ) return False retVal = chain.getIssuerCert() if not retVal[ 'OK' ]: gLogger.error( "Can't parse proxy!", retVal[ 'Message' ] ) return False idCert = retVal[ 'Value' ] self.__userDN = idCert.getSubjectDN()[ 'Value' ] self.__userGroup = idCert.getDIRACGroup()[ 'Value' ] return True
def __generateProxy( self ): self.log.info( "Generating proxy..." ) certLoc = Locations.getHostCertificateAndKeyLocation() if not certLoc: self.log.error( "Can not find certificate!" ) return False chain = X509Chain.X509Chain() result = chain.loadChainFromFile( certLoc[0] ) if not result[ 'OK' ]: self.log.error( "Can not load certificate file", "%s : %s" % ( certLoc[0], result[ 'Message' ] ) ) return False result = chain.loadKeyFromFile( certLoc[1] ) if not result[ 'OK' ]: self.log.error( "Can not load key file", "%s : %s" % ( certLoc[1], result[ 'Message' ] ) ) return False result = chain.generateProxyToFile( self.proxyLocation, 3600 ) if not result[ 'OK' ]: self.log.error( "Could not generate proxy file", result[ 'Message' ] ) return False self.log.info( "Proxy generated" ) return True
def _getCurrentUser( self ): """Simple function to return current DIRAC username. """ proxy = Locations.getProxyLocation() if not proxy: return S_ERROR( 'No proxy found in local environment' ) else: self.log.verbose( 'Current proxy is %s' % proxy ) chain = X509Chain() result = chain.loadProxyFromFile( proxy ) if not result[ 'OK' ]: return result result = chain.getIssuerCert() if not result[ 'OK' ]: return result issuerCert = result[ 'Value' ] dn = issuerCert.getSubjectDN()[ 'Value' ] result = CS.getUsernameForDN( dn ) if not result[ 'OK' ]: return result return result
def _getProxyLocation( ): return Locations.getProxyLocation( )
def setupConnection(self, parameters=None): #""" # Establishes a new connection to a Stomp server, e.g. RabbitMQ #:param dict parameters: dictionary with additional MQ parameters if any #:return: S_OK/S_ERROR #""" if parameters is not None: self.parameters.update(parameters) # Check that the minimum set of parameters is present if not all(p in parameters for p in ('Host', 'VHost')): return S_ERROR('Input parameters are missing!') # Make the actual connection host = self.parameters.get('Host') port = self.parameters.get('Port', 61613) vhost = self.parameters.get('VHost') sslVersion = self.parameters.get('SSLVersion') hostcert = self.parameters.get('HostCertificate') hostkey = self.parameters.get('HostKey') # get local key and certificate if not available via configuration if sslVersion and not (hostcert or hostkey): paths = Locations.getHostCertificateAndKeyLocation() if not paths: return S_ERROR('Could not find a certificate!') else: hostcert = paths[0] hostkey = paths[1] try: # get IP addresses of brokers brokers = socket.gethostbyname_ex(host) self.log.info('Broker name resolves to %s IP(s)' % len(brokers[2])) if sslVersion is None: pass elif sslVersion == 'TLSv1': sslVersion = ssl.PROTOCOL_TLSv1 else: return S_ERROR(EMQCONN, 'Invalid SSL version provided: %s' % sslVersion) for ip in brokers[2]: if sslVersion: self.connections[ip] = stomp.Connection( [(ip, int(port))], use_ssl=True, ssl_version=sslVersion, ssl_key_file=hostkey, ssl_cert_file=hostcert, vhost=vhost, keepalive=True ) else: self.connections[ip] = stomp.Connection( [(ip, int(port))], vhost=vhost, keepalive=True ) except Exception as e: return S_ERROR(EMQCONN, 'Failed to setup connection: %s' % e) return S_OK('Setup successful')
def checkSanity( urlTuple, kwargs ): """ Check that all ssl environment is ok """ useCerts = False certFile = '' if "useCertificates" in kwargs and kwargs[ 'useCertificates' ]: certTuple = Locations.getHostCertificateAndKeyLocation() if not certTuple: gLogger.error( "No cert/key found! " ) return S_ERROR( "No cert/key found! " ) certFile = certTuple[0] useCerts = True elif "proxyString" in kwargs: if not isinstance( kwargs[ 'proxyString' ], basestring ): gLogger.error( "proxyString parameter is not a valid type", str( type( kwargs[ 'proxyString' ] ) ) ) return S_ERROR( "proxyString parameter is not a valid type" ) else: if "proxyLocation" in kwargs: certFile = kwargs[ "proxyLocation" ] else: certFile = Locations.getProxyLocation() if not certFile: gLogger.error( "No proxy found" ) return S_ERROR( "No proxy found" ) elif not os.path.isfile( certFile ): gLogger.error( "Proxy file does not exist", certFile ) return S_ERROR( "%s proxy file does not exist" % certFile ) #For certs always check CA's. For clients skipServerIdentityCheck if 'skipCACheck' not in kwargs or not kwargs[ 'skipCACheck' ]: if not Locations.getCAsLocation(): gLogger.error( "No CAs found!" ) return S_ERROR( "No CAs found!" ) if "proxyString" in kwargs: certObj = X509Chain() retVal = certObj.loadChainFromString( kwargs[ 'proxyString' ] ) if not retVal[ 'OK' ]: gLogger.error( "Can't load proxy string" ) return S_ERROR( "Can't load proxy string" ) else: if useCerts: certObj = X509Certificate() certObj.loadFromFile( certFile ) else: certObj = X509Chain() certObj.loadChainFromFile( certFile ) retVal = certObj.hasExpired() if not retVal[ 'OK' ]: gLogger.error( "Can't verify proxy or certificate file", "%s:%s" % ( certFile, retVal[ 'Message' ] ) ) return S_ERROR( "Can't verify file %s:%s" % ( certFile, retVal[ 'Message' ] ) ) else: if retVal[ 'Value' ]: notAfter = certObj.getNotAfterDate() if notAfter[ 'OK' ]: notAfter = notAfter[ 'Value' ] else: notAfter = "unknown" gLogger.error( "PEM file has expired", "%s is not valid after %s" % ( certFile, notAfter ) ) return S_ERROR( "PEM file %s has expired, not valid after %s" % ( certFile, notAfter ) ) idDict = {} retVal = certObj.getDIRACGroup( ignoreDefault = True ) if retVal[ 'OK' ] and retVal[ 'Value' ] != False: idDict[ 'group' ] = retVal[ 'Value' ] if useCerts: idDict[ 'DN' ] = certObj.getSubjectDN()[ 'Value' ] else: idDict[ 'DN' ] = certObj.getIssuerCert()[ 'Value' ].getSubjectDN()[ 'Value' ] return S_OK( idDict )
def __getCAStore( self ): SocketInfo.__cachedCAsCRLsLoadLock.acquire() try: if not SocketInfo.__cachedCAsCRLs or time.time() - SocketInfo.__cachedCAsCRLsLastLoaded > 900: #Need to generate the CA Store casDict = {} crlsDict = {} casPath = Locations.getCAsLocation() if not casPath: return S_ERROR( "No valid CAs location found" ) gLogger.debug( "CAs location is %s" % casPath ) casFound = 0 crlsFound = 0 SocketInfo.__caStore = GSI.crypto.X509Store() for fileName in os.listdir( casPath ): filePath = os.path.join( casPath, fileName ) if not os.path.isfile( filePath ): continue fObj = file( filePath, "rb" ) pemData = fObj.read() fObj.close() #Try to load CA Cert try: caCert = GSI.crypto.load_certificate( GSI.crypto.FILETYPE_PEM, pemData ) if caCert.has_expired(): continue caID = ( caCert.get_subject().one_line(), caCert.get_issuer().one_line() ) caNotAfter = caCert.get_not_after() if caID not in casDict: casDict[ caID ] = ( caNotAfter, caCert ) casFound += 1 else: if casDict[ caID ][0] < caNotAfter: casDict[ caID ] = ( caNotAfter, caCert ) continue except: if fileName.find( ".0" ) == len( fileName ) - 2: gLogger.exception( "LOADING %s" % filePath ) if 'IgnoreCRLs' not in self.infoDict or not self.infoDict[ 'IgnoreCRLs' ]: #Try to load CRL try: crl = GSI.crypto.load_crl( GSI.crypto.FILETYPE_PEM, pemData ) if crl.has_expired(): continue crlID = crl.get_issuer().one_line() crlNotAfter = crl.get_not_after() if crlID not in crlsDict: crlsDict[ crlID ] = ( crlNotAfter, crl ) crlsFound += 1 else: if crlsDict[ crlID ][0] < crlNotAfter: crlsDict[ crlID ] = ( crlNotAfter, crl ) continue except: if fileName.find( ".r0" ) == len( fileName ) - 2: gLogger.exception( "LOADING %s" % filePath ) gLogger.debug( "Loaded %s CAs [%s CRLs]" % ( casFound, crlsFound ) ) SocketInfo.__cachedCAsCRLs = ( [ casDict[k][1] for k in casDict ], [ crlsDict[k][1] for k in crlsDict ] ) SocketInfo.__cachedCAsCRLsLastLoaded = time.time() except: gLogger.exception( "ASD" ) finally: SocketInfo.__cachedCAsCRLsLoadLock.release() #Generate CA Store caStore = GSI.crypto.X509Store() caList = SocketInfo.__cachedCAsCRLs[0] for caCert in caList: caStore.add_cert( caCert ) crlList = SocketInfo.__cachedCAsCRLs[1] for crl in crlList: caStore.add_crl( crl ) return S_OK( caStore )
params = Params() Script.registerSwitch("f:", "file=", "File to use as proxy", params.setProxyLocation) Script.registerSwitch("D", "DN", "Use DN as myproxy username", params.setDNAsUsername) Script.registerSwitch("i", "version", "Print version", params.showVersion) Script.addDefaultOptionValue("LogLevel", "always") Script.parseCommandLine() from DIRAC.FrameworkSystem.Client.ProxyManagerClient import gProxyManager from DIRAC.Core.Security.MyProxy import MyProxy from DIRAC.Core.Security.X509Chain import X509Chain from DIRAC.Core.Security import Locations, CS if not params.proxyLoc: params.proxyLoc = Locations.getProxyLocation() if not params.proxyLoc: print "Can't find any valid proxy" sys.exit(1) print "Uploading proxy file %s" % params.proxyLoc mp = MyProxy() retVal = mp.uploadProxy(params.proxyLoc, params.dnAsUsername) if not retVal["OK"]: print "Can't upload proxy:" print " ", retVal["Message"] sys.exit(1) print "Proxy uploaded" sys.exit(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" ) proxyChain = X509Chain() retVal = proxyChain.loadProxyFromFile( proxyLoc ) if not retVal[ 'OK' ]: return S_ERROR( "Can't load proxy file %s: %s" % ( params.proxyLoc, retVal[ 'Message' ] ) ) 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" ) diracGroup = params.diracGroup if not diracGroup: diracGroup = CS.getDefaultUserGroup() restrictLifeTime = params.proxyLifeTime else: chain = proxyChain diracGroup = False restrictLifeTime = 0 DIRAC.gLogger.info( " Uploading..." ) return gProxyManager.uploadProxy( chain, diracGroup, restrictLifeTime = restrictLifeTime )
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" ) diracGroup = params.diracGroup if not diracGroup: result = chain.getCredentials() if not result['OK']: return result if 'group' not in result['Value']: return S_ERROR( 'Can not get Group from existing credentials' ) diracGroup = result['Value']['group'] 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 diracGroup = params.diracGroup if params.diracGroup: # Check that there is no conflict with the already present DIRAC group result = chain.getDIRACGroup( ignoreDefault = True ) if result['OK'] and result['Value'] and result['Value'] == params.diracGroup: # No need to embed a new DIRAC group diracGroup = False restrictLifeTime = 0 DIRAC.gLogger.info( " Uploading..." ) return gProxyManager.uploadProxy( chain, diracGroup, restrictLifeTime = restrictLifeTime, rfcIfPossible = params.rfcIfPossible )
def generateProxy( params ): if params.checkClock: result = getClockDeviation() if result[ 'OK' ]: deviation = result[ 'Value' ] if deviation > 600: print "Error: Your host clock seems to be off by more than TEN MINUTES! Thats really bad." print "We're cowardly refusing to generate a proxy. Please fix your system time" DIRAC.exit( 1 ) elif deviation > 180: print "Error: Your host clock seems to be off by more than THREE minutes! Thats bad." print "Warn : We'll generate the proxy but please fix your system time" elif deviation > 60: print "Error: Your host clock seems to be off by more than a minute! Thats not good." print "Warn : We'll generate the proxy but please fix your system time" 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] 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 proxyLoc = params.proxyLoc if not proxyLoc: proxyLoc = Locations.getDefaultProxyLocation() if params.debug: h = int( params.proxyLifeTime / 3600 ) m = int( params.proxyLifeTime / 60 ) - h * 60 print "Proxy lifetime will be %02d:%02d" % ( h, m ) print "User cert is %s" % certLoc print "User key is %s" % keyLoc print "Proxy will be written to %s" % proxyLoc if params.diracGroup: print "DIRAC Group will be set to %s" % params.diracGroup else: print "No DIRAC Group will be set" print "Proxy strength will be %s" % params.proxyStrength if params.limitedProxy: print "Proxy will be limited" chain = X509Chain() #Load user cert and key retVal = chain.loadChainFromFile( certLoc ) if not retVal[ 'OK' ]: params.debugMsg( "ERROR: %s" % retVal[ 'Message' ] ) return S_ERROR( "Can't load %s" % certLoc ) retVal = chain.loadKeyFromFile( keyLoc, password = params.userPasswd ) if not retVal[ 'OK' ]: params.debugMsg( "ERROR: %s" % retVal[ 'Message' ] ) return S_ERROR( "Can't load %s" % keyLoc ) if params.checkWithCS and params.diracGroup: retVal = chain.generateProxyToFile( proxyLoc, params.proxyLifeTime, strength = params.proxyStrength, limited = params.limitedProxy ) params.debugMsg( "Contacting CS..." ) retVal = Script.enableCS() if not retVal[ 'OK' ]: params.debugMsg( "ERROR: %s" % retVal[ 'Message' ] ) return S_ERROR( "Can't contact DIRAC CS: %s" % retVal[ 'Message' ] ) if not params.diracGroup: params.diracGroup = CS.getDefaultUserGroup() userDN = chain.getCertInChain( -1 )['Value'].getSubjectDN()['Value'] params.debugMsg( "Checking DN %s" % userDN ) retVal = CS.getUsernameForDN( userDN ) if not retVal[ 'OK' ]: params.debugMsg( "ERROR: %s" % retVal[ 'Message' ] ) return S_ERROR( "DN %s is not registered" % userDN ) username = retVal[ 'Value' ] params.debugMsg( "Username is %s" % username ) retVal = CS.getGroupsForUser( username ) if not retVal[ 'OK' ]: params.debugMsg( "ERROR: %s" % retVal[ 'Message' ] ) return S_ERROR( "User %s has no groups defined" % username ) groups = retVal[ 'Value' ] if params.diracGroup not in groups: return S_ERROR( "Requested group %s is not valid for user %s" % ( params.diracGroup, username ) ) params.debugMsg( "Creating proxy for %s@%s (%s)" % ( username, params.diracGroup, userDN ) ) retVal = chain.generateProxyToFile( proxyLoc, params.proxyLifeTime, params.diracGroup, strength = params.proxyStrength, limited = params.limitedProxy ) if not retVal[ 'OK' ]: params.debugMsg( "ERROR: %s" % retVal[ 'Message' ] ) return S_ERROR( "Couldn't generate proxy: %s" % retVal[ 'Message' ] ) return S_OK( proxyLoc )
def generateProxy( params ): if params.checkClock: result = getClockDeviation() if result[ 'OK' ]: deviation = result[ 'Value' ] if deviation > 600: gLogger.error( "Your host clock seems to be off by more than TEN MINUTES! Thats really bad." ) gLogger.error( "We're cowardly refusing to generate a proxy. Please fix your system time" ) sys.exit( 1 ) elif deviation > 180: gLogger.error( "Your host clock seems to be off by more than THREE minutes! Thats bad." ) gLogger.notice( "We'll generate the proxy but please fix your system time" ) elif deviation > 60: gLogger.error( "Your host clock seems to be off by more than a minute! Thats not good." ) gLogger.notice( "We'll generate the proxy but please fix your system time" ) 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] params.certLoc = certLoc params.keyLoc = keyLoc #Load password testChain = X509Chain() retVal = testChain.loadChainFromFile( params.certLoc ) if not retVal[ 'OK' ]: return S_ERROR( "Cannot load certificate %s: %s" % ( params.certLoc, retVal[ 'Message' ] ) ) timeLeft = testChain.getRemainingSecs()[ 'Value' ] / 86400 if timeLeft < 30: gLogger.notice( "\nYour certificate will expire in %d days. Please renew it!\n" % timeLeft ) retVal = testChain.loadKeyFromFile( params.keyLoc, password = params.userPasswd ) if not retVal[ 'OK' ]: passwdPrompt = "Enter Certificate password:"******"\n" ) else: userPasswd = getpass.getpass( passwdPrompt ) params.userPasswd = userPasswd #Find location proxyLoc = params.proxyLoc if not proxyLoc: proxyLoc = Locations.getDefaultProxyLocation() chain = X509Chain() #Load user cert and key retVal = chain.loadChainFromFile( certLoc ) if not retVal[ 'OK' ]: gLogger.warn( retVal[ 'Message' ] ) return S_ERROR( "Can't load %s" % certLoc ) retVal = chain.loadKeyFromFile( keyLoc, password = params.userPasswd ) 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" % keyLoc ) if params.checkWithCS: retVal = chain.generateProxyToFile( proxyLoc, params.proxyLifeTime, strength = params.proxyStrength, limited = params.limitedProxy, rfc = params.rfc ) gLogger.info( "Contacting CS..." ) retVal = Script.enableCS() if not retVal[ 'OK' ]: gLogger.warn( retVal[ 'Message' ] ) if 'Unauthorized query' in retVal[ 'Message' ]: # add hint for users return S_ERROR( "Can't contact DIRAC CS: %s (User possibly not registered with dirac server) " % retVal[ 'Message' ] ) return S_ERROR( "Can't contact DIRAC CS: %s" % retVal[ 'Message' ] ) userDN = chain.getCertInChain( -1 )['Value'].getSubjectDN()['Value'] if not params.diracGroup: result = Registry.findDefaultGroupForDN( userDN ) if not result[ 'OK' ]: gLogger.warn( "Could not get a default group for DN %s: %s" % ( userDN, result[ 'Message' ] ) ) else: params.diracGroup = result[ 'Value' ] gLogger.info( "Default discovered group is %s" % params.diracGroup ) gLogger.info( "Checking DN %s" % userDN ) retVal = Registry.getUsernameForDN( userDN ) if not retVal[ 'OK' ]: gLogger.warn( retVal[ 'Message' ] ) return S_ERROR( "DN %s is not registered" % userDN ) username = retVal[ 'Value' ] gLogger.info( "Username is %s" % username ) retVal = Registry.getGroupsForUser( username ) if not retVal[ 'OK' ]: gLogger.warn( retVal[ 'Message' ] ) return S_ERROR( "User %s has no groups defined" % username ) groups = retVal[ 'Value' ] if params.diracGroup not in groups: return S_ERROR( "Requested group %s is not valid for DN %s" % ( params.diracGroup, userDN ) ) gLogger.info( "Creating proxy for %s@%s (%s)" % ( username, params.diracGroup, userDN ) ) if params.summary: h = int( params.proxyLifeTime / 3600 ) m = int( params.proxyLifeTime / 60 ) - h * 60 gLogger.notice( "Proxy lifetime will be %02d:%02d" % ( h, m ) ) gLogger.notice( "User cert is %s" % certLoc ) gLogger.notice( "User key is %s" % keyLoc ) gLogger.notice( "Proxy will be written to %s" % proxyLoc ) if params.diracGroup: gLogger.notice( "DIRAC Group will be set to %s" % params.diracGroup ) else: gLogger.notice( "No DIRAC Group will be set" ) gLogger.notice( "Proxy strength will be %s" % params.proxyStrength ) if params.limitedProxy: gLogger.notice( "Proxy will be limited" ) retVal = chain.generateProxyToFile( proxyLoc, params.proxyLifeTime, params.diracGroup, strength = params.proxyStrength, limited = params.limitedProxy, rfc = params.rfc ) if not retVal[ 'OK' ]: gLogger.warn( retVal[ 'Message' ] ) return S_ERROR( "Couldn't generate proxy: %s" % retVal[ 'Message' ] ) return S_OK( proxyLoc )