def __discoverCredentialsToUse(self): """ Discovers which credentials to use for connection. * Server certificate: -> If KW_USE_CERTIFICATES in kwargs, sets it in self.__useCertificates ->If not, check gConfig.useServerCertificate(), and sets it in self.__useCertificates and kwargs[KW_USE_CERTIFICATES] * Certification Authorities check: -> if KW_SKIP_CA_CHECK is not in kwargs and we are using the certificates, set KW_SKIP_CA_CHECK to false in kwargs -> if KW_SKIP_CA_CHECK is not in kwargs and we are not using the certificate, check the CS.skipCACheck * Proxy Chain -> if KW_PROXY_CHAIN in kwargs, we remove it and dump its string form into kwargs[KW_PROXY_STRING] """ # Use certificates? if self.KW_USE_CERTIFICATES in self.kwargs: self.__useCertificates = self.kwargs[self.KW_USE_CERTIFICATES] else: self.__useCertificates = gConfig.useServerCertificate() self.kwargs[self.KW_USE_CERTIFICATES] = self.__useCertificates if self.KW_SKIP_CA_CHECK not in self.kwargs: if self.__useCertificates: self.kwargs[self.KW_SKIP_CA_CHECK] = False else: self.kwargs[self.KW_SKIP_CA_CHECK] = CS.skipCACheck() if self.KW_PROXY_CHAIN in self.kwargs: try: self.kwargs[self.KW_PROXY_STRING] = self.kwargs[self.KW_PROXY_CHAIN].dumpAllToString()['Value'] del self.kwargs[self.KW_PROXY_CHAIN] except BaseException: return S_ERROR("Invalid proxy chain specified on instantiation") return S_OK()
def __discoverCredentialsToUse( self ): """ Discovers which credentials to use for connection. * Server certificate: -> If KW_USE_CERTIFICATES in kwargs, sets it in self.__useCertificates ->If not, check gConfig.useServerCertificate(), and sets it in self.__useCertificates and kwargs[KW_USE_CERTIFICATES] * Certification Authorities check: -> if KW_SKIP_CA_CHECK is not in kwargs and we are using the certificates, set KW_SKIP_CA_CHECK to false in kwargs -> if KW_SKIP_CA_CHECK is not in kwargs and we are not using the certificate, check the CS.skipCACheck * Proxy Chain -> if KW_PROXY_CHAIN in kwargs, we remove it and dump its string form into kwargs[KW_PROXY_STRING] """ #Use certificates? if self.KW_USE_CERTIFICATES in self.kwargs: self.__useCertificates = self.kwargs[ self.KW_USE_CERTIFICATES ] else: self.__useCertificates = gConfig.useServerCertificate() self.kwargs[ self.KW_USE_CERTIFICATES ] = self.__useCertificates if self.KW_SKIP_CA_CHECK not in self.kwargs: if self.__useCertificates: self.kwargs[ self.KW_SKIP_CA_CHECK ] = False else: self.kwargs[ self.KW_SKIP_CA_CHECK ] = CS.skipCACheck() if self.KW_PROXY_CHAIN in self.kwargs: try: self.kwargs[ self.KW_PROXY_STRING ] = self.kwargs[ self.KW_PROXY_CHAIN ].dumpAllToString()[ 'Value' ] del self.kwargs[ self.KW_PROXY_CHAIN ] except: return S_ERROR( "Invalid proxy chain specified on instantiation" ) return S_OK()
def connect( self ): errorMsg = "" for res in socket.getaddrinfo( self.host, self.port, 0, socket.SOCK_STREAM ): _af, _socktype, _proto, _canonname, addTuple = res result = gSSLSocketFactory.createClientSocket( addTuple, useCertificates = gConfig.useServerCertificate() ) if not result[ 'OK' ]: errorMsg = result[ 'Message' ] continue self.sock = result[ 'Value' ] break if not self.sock: raise socket.error, errorMsg
def connect(self): errorMsg = "" for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): _af, _socktype, _proto, _canonname, addTuple = res result = gSSLSocketFactory.createClientSocket( addTuple, useCertificates=gConfig.useServerCertificate()) if not result['OK']: errorMsg = result['Message'] continue self.sock = result['Value'] break if not self.sock: raise socket.error, errorMsg
def __discoverCredentialsToUse( self ): #Use certificates? if self.KW_USE_CERTIFICATES in self.kwargs: self.useCertificates = self.kwargs[ self.KW_USE_CERTIFICATES ] else: self.useCertificates = gConfig.useServerCertificate() self.kwargs[ self.KW_USE_CERTIFICATES ] = self.useCertificates if self.KW_SKIP_CA_CHECK not in self.kwargs: if self.useCertificates: self.kwargs[ self.KW_SKIP_CA_CHECK ] = False else: self.kwargs[ self.KW_SKIP_CA_CHECK ] = CS.skipCACheck() if self.KW_PROXY_CHAIN in self.kwargs: try: self.kwargs[ self.KW_PROXY_STRING ] = self.kwargs[ self.KW_PROXY_CHAIN ].dumpAllToString()[ 'Value' ] del self.kwargs[ self.KW_PROXY_CHAIN ] except: return S_ERROR( "Invalid proxy chain specified on instantiation" ) return S_OK()
def __discoverCredentialsToUse(self): """ Discovers which credentials to use for connection. * Server certificate: -> If KW_USE_CERTIFICATES in kwargs, sets it in self.__useCertificates -> If not, check gConfig.useServerCertificate(), and sets it in self.__useCertificates and kwargs[KW_USE_CERTIFICATES] * Certification Authorities check: -> if KW_SKIP_CA_CHECK is not in kwargs and we are using the certificates, set KW_SKIP_CA_CHECK to false in kwargs -> if KW_SKIP_CA_CHECK is not in kwargs and we are not using the certificate, check the skipCACheck * Proxy Chain WARNING: MOSTLY COPY/PASTE FROM Core/Diset/private/BaseClient """ # Use certificates? if self.KW_USE_CERTIFICATES in self.kwargs: self.__useCertificates = self.kwargs[self.KW_USE_CERTIFICATES] else: self.__useCertificates = gConfig.useServerCertificate() self.kwargs[self.KW_USE_CERTIFICATES] = self.__useCertificates if self.KW_SKIP_CA_CHECK not in self.kwargs: if self.__useCertificates: self.kwargs[self.KW_SKIP_CA_CHECK] = False else: self.kwargs[self.KW_SKIP_CA_CHECK] = skipCACheck() # Rewrite a little bit from here: don't need the proxy string, we use the file if self.KW_PROXY_CHAIN in self.kwargs: try: self.kwargs[self.KW_PROXY_STRING] = self.kwargs[ self.KW_PROXY_CHAIN].dumpAllToString()['Value'] del self.kwargs[self.KW_PROXY_CHAIN] except BaseException: return S_ERROR( "Invalid proxy chain specified on instantiation") # ==== REWRITED FROM HERE ==== # For certs always check CA's. For clients skipServerIdentityCheck return S_OK()
def __discoverCredentialsToUse(self): #Use certificates? if self.KW_USE_CERTIFICATES in self.kwargs: self.useCertificates = self.kwargs[self.KW_USE_CERTIFICATES] else: self.useCertificates = gConfig.useServerCertificate() self.kwargs[self.KW_USE_CERTIFICATES] = self.useCertificates if self.KW_SKIP_CA_CHECK not in self.kwargs: if self.useCertificates: self.kwargs[self.KW_SKIP_CA_CHECK] = False else: self.kwargs[self.KW_SKIP_CA_CHECK] = CS.skipCACheck() if self.KW_PROXY_CHAIN in self.kwargs: try: self.kwargs[self.KW_PROXY_STRING] = self.kwargs[ self.KW_PROXY_CHAIN].dumpAllToString()['Value'] del self.kwargs[self.KW_PROXY_CHAIN] except: return S_ERROR( "Invalid proxy chain specified on instantiation") return S_OK()
def _connect(self): """ Establish the connection. It uses the URL discovered in __discoverURL. In case the connection cannot be established, __discoverURL is called again, and _connect calls itself. We stop after trying self.__nbOfRetry * self.__nbOfUrls :return: S_OK()/S_ERROR() """ # Check if the useServerCertificate configuration changed # Note: I am not really sure that all this block makes # any sense at all since all these variables are # evaluated in __discoverCredentialsToUse if gConfig.useServerCertificate() != self.__useCertificates: if self.__forceUseCertificates is None: self.__useCertificates = gConfig.useServerCertificate() self.kwargs[self.KW_USE_CERTIFICATES] = self.__useCertificates # The server certificate use context changed, rechecking the transport sanity result = self.__checkTransportSanity() if not result['OK']: return result # Take all the extra credentials self.__discoverExtraCredentials() if not self.__initStatus['OK']: return self.__initStatus if self.__enableThreadCheck: self.__checkThreadID() gLogger.debug("Trying to connect to: %s" % self.serviceURL) try: # Calls the transport method of the apropriate protocol. # self.__URLTuple[1:3] = [server name, port, System/Component] transport = gProtocolDict[self.__URLTuple[0]]['transport'](self.__URLTuple[1:3], **self.kwargs) # the socket timeout is the default value which is 1. # later we increase to 5 retVal = transport.initAsClient() # We try at most __nbOfRetry each URLs if not retVal['OK']: gLogger.warn("Issue getting socket:", "%s : %s : %s" % (transport, self.__URLTuple, retVal['Message'])) # We try at most __nbOfRetry each URLs if self.__retry < self.__nbOfRetry * self.__nbOfUrls - 1: # Recompose the URL (why not using self.serviceURL ? ) url = "%s://%s:%d/%s" % (self.__URLTuple[0], self.__URLTuple[1], int(self.__URLTuple[2]), self.__URLTuple[3]) # Add the url to the list of banned URLs if it is not already there. (Can it happen ? I don't think so) if url not in self.__bannedUrls: gLogger.warn("Non-responding URL temporarily banned", "%s" % url) self.__bannedUrls += [url] # Increment the retry counter self.__retry += 1 # 16.07.20 CHRIS: I guess this setSocketTimeout does not behave as expected. # If the initasClient did not work, we anyway re-enter the whole method, # so a new transport object is created. # However, it migh be that this timeout value was propagated down to the # SocketInfoFactory singleton, and thus used, but that means that the timeout # specified in parameter was then void. # If it is our last attempt for each URL, we increase the timeout if self.__retryCounter == self.__nbOfRetry - 1: transport.setSocketTimeout(5) # we increase the socket timeout in case the network is not good gLogger.info("Retry connection", ": %d to %s" % (self.__retry, self.serviceURL)) # If we tried all the URL, we increase the global counter (__retryCounter), and sleep if len(self.__bannedUrls) == self.__nbOfUrls: self.__retryCounter += 1 # we run only one service! In that case we increase the retry delay. self.__retryDelay = 3. / self.__nbOfUrls if self.__nbOfUrls > 1 else 2 gLogger.info("Waiting %f seconds before retry all service(s)" % self.__retryDelay) time.sleep(self.__retryDelay) # rediscover the URL self.__discoverURL() # try to reconnect return self._connect() else: return retVal except Exception as e: gLogger.exception(lException=True, lExcInfo=True) return S_ERROR("Can't connect to %s: %s" % (self.serviceURL, repr(e))) # We add the connection to the transport pool gLogger.debug("Connected to: %s" % self.serviceURL) trid = getGlobalTransportPool().add(transport) return S_OK((trid, transport))
def __discoverCredentialsToUse(self): """Discovers which credentials to use for connection. * Server certificate: -> If KW_USE_CERTIFICATES in kwargs, sets it in self.__useCertificates -> If not, check gConfig.useServerCertificate(), and sets it in self.__useCertificates and kwargs[KW_USE_CERTIFICATES] * Certification Authorities check: -> if KW_SKIP_CA_CHECK is not in kwargs and we are using the certificates, set KW_SKIP_CA_CHECK to false in kwargs -> if KW_SKIP_CA_CHECK is not in kwargs and we are not using the certificate, check the skipCACheck * Bearer token: -> If KW_USE_ACCESS_TOKEN in kwargs, sets it in self.__useAccessToken -> If not, check "/DIRAC/Security/UseTokens", and sets it in self.__useAccessToken and kwargs[KW_USE_ACCESS_TOKEN] -> If not, check 'DIRAC_USE_ACCESS_TOKEN' in os.environ, sets it in self.__useAccessToken and kwargs[KW_USE_ACCESS_TOKEN] * Proxy Chain WARNING: MOSTLY COPY/PASTE FROM Core/Diset/private/BaseClient """ # Use certificates? if self.KW_USE_CERTIFICATES in self.kwargs: self.__useCertificates = self.kwargs[self.KW_USE_CERTIFICATES] else: self.__useCertificates = gConfig.useServerCertificate() self.kwargs[self.KW_USE_CERTIFICATES] = self.__useCertificates if self.KW_SKIP_CA_CHECK not in self.kwargs: if self.__useCertificates: self.kwargs[self.KW_SKIP_CA_CHECK] = False else: self.kwargs[self.KW_SKIP_CA_CHECK] = skipCACheck() # Use tokens? if self.KW_USE_ACCESS_TOKEN in self.kwargs: self.__useAccessToken = self.kwargs[self.KW_USE_ACCESS_TOKEN] elif "DIRAC_USE_ACCESS_TOKEN" in os.environ: self.__useAccessToken = os.environ.get("DIRAC_USE_ACCESS_TOKEN", "false").lower() in ("y", "yes", "true") else: self.__useAccessToken = gConfig.getValue( "/DIRAC/Security/UseTokens", "false").lower() in ( "y", "yes", "true", ) self.kwargs[self.KW_USE_ACCESS_TOKEN] = self.__useAccessToken if self.__useAccessToken: from DIRAC.Resources.IdProvider.IdProviderFactory import IdProviderFactory result = IdProviderFactory().getIdProvider("DIRACCLI") if not result["OK"]: return result self.__idp = result["Value"] # Rewrite a little bit from here: don't need the proxy string, we use the file if self.KW_PROXY_CHAIN in self.kwargs: try: self.kwargs[self.KW_PROXY_STRING] = self.kwargs[ self.KW_PROXY_CHAIN].dumpAllToString()["Value"] del self.kwargs[self.KW_PROXY_CHAIN] except Exception: return S_ERROR( "Invalid proxy chain specified on instantiation") # ==== REWRITED FROM HERE ==== # For certs always check CA's. For clients skipServerIdentityCheck return S_OK()
def __call__( self ): """ generic function to process one Request of a type requestType This method could be run in a thread. :param self: self reference :param str requestType: request type :return: S_OK/S_ERROR """ self.always("executing request %s" % self.requestName ) ################################################################ ## get ownerDN and ownerGroup ownerDN = self.requestObj.getAttribute( "OwnerDN" ) if not ownerDN["OK"]: return ownerDN ownerDN = ownerDN["Value"] ownerGroup = self.requestObj.getAttribute( "OwnerGroup" ) if not ownerGroup["OK"]: return ownerGroup ownerGroup = ownerGroup["Value"] ## save request owner self.requestOwnerDN = ownerDN if ownerDN else "" self.requestOwnerGroup = ownerGroup if ownerGroup else "" ################################################################# ## change proxy ownerProxyFile = None if ownerDN and ownerGroup: ownerProxyFile = self.changeProxy( ownerDN, ownerGroup ) if not ownerProxyFile["OK"]: self.error( "handleReuqest: unable to get proxy for '%s'@'%s': %s" % ( ownerDN, ownerGroup, ownerProxyFile["Message"] ) ) update = self.putBackRequest( self.requestName, self.requestString ) if not update["OK"]: self.error( "handleRequest: error when updating request: %s" % update["Message"] ) return update return ownerProxyFile ownerProxyFile = ownerProxyFile["Value"] #self.ownerProxyFile = ownerProxyFile self.info( "Will execute request for '%s'@'%s' using proxy file %s" % ( ownerDN, ownerGroup, ownerProxyFile ) ) else: self.info( "Will execute request for DataManager using her/his proxy") ################################################################# ## execute handlers ret = { "OK" : False, "Message" : "" } useServerCert = gConfig.useServerCertificate() try: # Execute task with the owner proxy even for contacting DIRAC services if useServerCert: gConfigurationData.setOptionInCFG('/DIRAC/Security/UseServerCertificate','false') ret = self.handleRequest() finally: if useServerCert: gConfigurationData.setOptionInCFG('/DIRAC/Security/UseServerCertificate','true') ## delete owner proxy if self.__dataManagerProxy: os.environ["X509_USER_PROXY"] = self.__dataManagerProxy if ownerProxyFile and os.path.exists( ownerProxyFile ): os.unlink( ownerProxyFile ) if not ret["OK"]: self.error( "handleRequest: error during request processing: %s" % ret["Message"] ) self.error( "handleRequest: will put original request back" ) update = self.putBackRequest( self.requestName, self.requestString ) if not update["OK"]: self.error( "handleRequest: error when putting back request: %s" % update["Message"] ) ## return at least return ret
def _connect(self): """ Establish the connection. It uses the URL discovered in __discoverURL. In case the connection cannot be established, __discoverURL is called again, and _connect calls itself. We stop after trying self.__nbOfRetry * self.__nbOfUrls """ # Check if the useServerCertificate configuration changed # Note: I am not really sure that all this block makes # any sense at all since all these variables are # evaluated in __discoverCredentialsToUse if gConfig.useServerCertificate() != self.__useCertificates: if self.__forceUseCertificates is None: self.__useCertificates = gConfig.useServerCertificate() self.kwargs[self.KW_USE_CERTIFICATES] = self.__useCertificates # The server certificate use context changed, rechecking the transport sanity result = self.__checkTransportSanity() if not result['OK']: return result # Take all the extra credentials self.__discoverExtraCredentials() if not self.__initStatus['OK']: return self.__initStatus if self.__enableThreadCheck: self.__checkThreadID() gLogger.debug("Connecting to: %s" % self.serviceURL) try: # Calls the transport method of the apropriate protocol. # self.__URLTuple[1:3] = [server name, port, System/Component] transport = gProtocolDict[self.__URLTuple[0]]['transport'](self.__URLTuple[1:3], **self.kwargs) # the socket timeout is the default value which is 1. # later we increase to 5 retVal = transport.initAsClient() # If we have an issue connecting if not retVal['OK']: # We try at most __nbOfRetry each URLs if self.__retry < self.__nbOfRetry * self.__nbOfUrls - 1: # Recompose the URL (why not using self.serviceURL ? ) url = "%s://%s:%d/%s" % (self.__URLTuple[0], self.__URLTuple[1], int(self.__URLTuple[2]), self.__URLTuple[3]) # Add the url to the list of banned URLs if it is not already there. (Can it happen ? I don't think so) if url not in self.__bannedUrls: self.__bannedUrls += [url] # Why only printing in this case ? if len(self.__bannedUrls) < self.__nbOfUrls: gLogger.notice("Non-responding URL temporarily banned", "%s" % url) # Increment the retry couunter self.__retry += 1 # If it is our last attempt for each URL, we increase the timeout if self.__retryCounter == self.__nbOfRetry - 1: transport.setSocketTimeout(5) # we increase the socket timeout in case the network is not good gLogger.info("Retry connection", ": %d to %s" % (self.__retry, self.serviceURL)) # If we tried all the URL, we increase the global counter (__retryCounter), and sleep if len(self.__bannedUrls) == self.__nbOfUrls: self.__retryCounter += 1 # we run only one service! In that case we increase the retry delay. self.__retryDelay = 3. / self.__nbOfUrls if self.__nbOfUrls > 1 else 2 gLogger.info("Waiting %f seconds before retry all service(s)" % self.__retryDelay) time.sleep(self.__retryDelay) # rediscover the URL self.__discoverURL() # try to reconnect return self._connect() else: return retVal except Exception as e: gLogger.exception(lException=True, lExcInfo=True) return S_ERROR("Can't connect to %s: %s" % (self.serviceURL, repr(e))) # We add the connection to the transport pool trid = getGlobalTransportPool().add(transport) return S_OK((trid, transport))