%PDF- %PDF-
Direktori : /lib/python3.6/site-packages/up2date_client/ |
Current File : //lib/python3.6/site-packages/up2date_client/up2dateAuth.py |
# import os import pickle import sys import time import socket import subprocess from up2date_client import rpcServer try: # python2 from types import DictType except ImportError: # python3 DictType = dict from rhn import rpclib from up2date_client import clientCaps from up2date_client import config from up2date_client import rhnserver from up2date_client import up2dateErrors from up2date_client import up2dateLog from up2date_client import up2dateUtils loginInfo = None pcklAuthFileName = "/var/spool/up2date/loginAuth.pkl" def getSystemId(): cfg = config.initUp2dateConfig() path = cfg["systemIdPath"] if not os.access(path, os.R_OK): return None f = open(path, "r") ret = f.read() f.close() return ret # if a user has upgraded to a newer release of Red Hat but still # has a systemid from their older release, they need to get an updated # systemid from the RHN servers. This takes care of that. def maybeUpdateVersion(): cfg = config.initUp2dateConfig() try: idVer = rpclib.xmlrpclib.loads(getSystemId())[0][0]['os_release'] except: # they may not even have a system id yet. return 0 systemVer = up2dateUtils.getVersion() if idVer != systemVer: s = rhnserver.RhnServer() newSystemId = s.registration.upgrade_version(getSystemId(), systemVer) path = cfg["systemIdPath"] dir = path[:path.rfind("/")] if not os.access(dir, os.W_OK): try: os.mkdir(dir) except: return 0 if not os.access(dir, os.W_OK): return 0 if os.access(path, os.F_OK): # already have systemid file there; let's back it up savePath = path + ".save" try: os.rename(path, savePath) except: return 0 f = open(path, "w") f.write(newSystemId) f.close() try: os.chmod(path, int('0600', 8)) except: pass def writeCachedLogin(): """ Pickle loginInfo to a file Returns: True -- wrote loginInfo to a pickle file False -- did _not_ write loginInfo to a pickle file """ log = up2dateLog.initLog() log.log_debug("writeCachedLogin() invoked") if not loginInfo: log.log_debug("writeCachedLogin() loginInfo is None, so bailing.") return False data = {'time': time.time(), 'loginInfo': loginInfo} pcklDir = os.path.dirname(pcklAuthFileName) if not os.access(pcklDir, os.W_OK): try: os.mkdir(pcklDir) os.chmod(pcklDir, int('0700', 8)) except: log.log_me("Unable to write pickled loginInfo to %s" % pcklDir) return False pcklAuth = open(pcklAuthFileName, 'wb') os.chmod(pcklAuthFileName, int('0600', 8)) pickle.dump(data, pcklAuth) pcklAuth.close() expireTime = data['time'] + float(loginInfo['X-RHN-Auth-Expire-Offset']) log.log_debug("Wrote pickled loginInfo at ", data['time'], " with expiration of ", expireTime, " seconds.") return True def readCachedLogin(): """ Read pickle info from a file Caches authorization info for connecting to the server. """ log = up2dateLog.initLog() log.log_debug("readCachedLogin invoked") if not os.access(pcklAuthFileName, os.R_OK): log.log_debug("Unable to read pickled loginInfo at: %s" % pcklAuthFileName) return False pcklAuth = open(pcklAuthFileName, 'rb') try: data = pickle.load(pcklAuth) except (EOFError, ValueError): log.log_debug("Unexpected EOF. Probably an empty file, \ regenerate auth file") pcklAuth.close() return False pcklAuth.close() # Check if system_id has changed try: idVer = rpclib.xmlrpclib.loads(getSystemId())[0][0]['system_id'] cidVer = "ID-%s" % data['loginInfo']['X-RHN-Server-Id'] if idVer != cidVer: log.log_debug("system id version changed: %s vs %s" % (idVer, cidVer)) return False except: pass createdTime = data['time'] li = data['loginInfo'] currentTime = time.time() expireTime = createdTime + float(li['X-RHN-Auth-Expire-Offset']) #Check if expired, offset is stored in "X-RHN-Auth-Expire-Offset" log.log_debug("Checking pickled loginInfo, currentTime=", currentTime, ", createTime=", createdTime, ", expire-offset=", float(li['X-RHN-Auth-Expire-Offset'])) if (currentTime > expireTime): log.log_debug("Pickled loginInfo has expired, created = %s, expire = %s." \ %(createdTime, expireTime)) return False _updateLoginInfo(li) log.log_debug("readCachedLogin(): using pickled loginInfo set to expire at ", expireTime) return True def _updateLoginInfo(li): """ Update the global var, "loginInfo" """ global loginInfo if type(li) == DictType: if type(loginInfo) == DictType: # must retain the reference. loginInfo.update(li) else: # this had better be the initial login or we lose the reference. loginInfo = li else: loginInfo = None # allow to pass in a system id for use in rhnreg # a bit of a kluge to make caps work correctly def login(systemId=None, forceUpdate=False, timeout=None): log = up2dateLog.initLog() log.log_debug("login(forceUpdate=%s) invoked" % (forceUpdate)) if not forceUpdate and not loginInfo: if readCachedLogin(): return loginInfo server = rhnserver.RhnServer(timeout=timeout) # send up the capabality info headerlist = clientCaps.caps.headerFormat() for (headerName, value) in headerlist: server.add_header(headerName, value) if systemId == None: systemId = getSystemId() if not systemId: return None maybeUpdateVersion() log.log_me("logging into up2date server") li = server.up2date.login(systemId, socket.getfqdn(), _get_panel_name(log)) # figure out if were missing any needed caps server.capabilities.validate() _updateLoginInfo(li) #update global var, loginInfo writeCachedLogin() #pickle global loginInfo if loginInfo: log.log_me("successfully retrieved authentication token " "from up2date server") log.log_debug("logininfo:", loginInfo) return loginInfo def updateLoginInfo(timeout=None): log = up2dateLog.initLog() log.log_me("updateLoginInfo() login info") # NOTE: login() updates the loginInfo object login(forceUpdate=True, timeout=timeout) if not loginInfo: raise up2dateErrors.AuthenticationError("Unable to authenticate") return loginInfo def getLoginInfo(timeout=None): global loginInfo try: loginInfo = loginInfo except NameError: loginInfo = None if loginInfo: return loginInfo # NOTE: login() updates the loginInfo object login(timeout=timeout) return loginInfo class _FailedToGetPanelName(Exception): pass def _get_panel_name(log): try: panel_name = _get_panel_name_via_cldetect() except _FailedToGetPanelName: # Do not spam logs when we're executed from under cldeploy script # and no cloudlinux packages are yet installed. if not _is_cldeploy_running(): log.log_exception(*sys.exc_info()) log.log_me("Failed to get panel name via cldetect, using fallback mechanism") panel_name = _fallback_get_panel_name() return panel_name.lower() def _is_cldeploy_running(): # NOTE(vlebedev): This is more or less a direct port of shell code from cldeploy script. lock_file_path = '/var/lock/cldeploy.lck' cldeploy_running = False pid = None if os.path.exists(lock_file_path): with open(lock_file_path) as f: pid = f.read().strip() if pid: pid_cmdline_path = "/proc/%s/cmdline" % pid if os.path.exists(pid_cmdline_path): with open(pid_cmdline_path) as f: cldeploy_running = 'cldeploy' in f.read() return cldeploy_running def _get_panel_name_via_cldetect(): binary, _ = cmd = ["/usr/bin/cldetect", "--detect-cp-nameonly"] if not os.path.exists(binary): raise _FailedToGetPanelName( "Failed to obtain panel name because '%s' does not exist" % binary ) process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) stdout, stderr = process.communicate() if process.returncode != 0: raise _FailedToGetPanelName( "Failed to obtain panel name using '%s' command; stderr: %s" % (" ".join(cmd), stderr) ) return stdout.strip() def _fallback_get_panel_name(): # NOTE(vlebedev): This is more or less a direct port of shell code from cldeploy script. # TODO(vlebedev): Pass $PANEL from cldeploy instead of duplication? if os.path.isdir("/usr/local/psa/admin/"): return "plesk" if os.path.isdir("/usr/local/interworx/"): return "interworx" if os.path.isdir("/usr/local/cpanel/whostmgr/docroot/"): return "cpanel" if os.path.isdir("/usr/local/ispmgr/"): return "ispmgr" if os.path.isdir("/usr/local/directadmin/"): return "directadmin" if os.path.isfile("/usr/local/mgr5/sbin/mgrctl"): return "ispmgr5" return "unknown"