def parse_auth_line(line): ldata = line.split(b"|") log("found %s fields", len(ldata)) assert len(ldata) >= 4, "not enough fields" #parse fields: username = ldata[0] password = ldata[1] def getsysid(s, get_default_value): if s: try: return int(s) except: pass return get_default_value() uid = getsysid(ldata[2], os.getuid) gid = getsysid(ldata[3], os.getgid) displays = ldata[4].split(b",") env_options = {} session_options = {} if len(ldata) >= 6: env_options = parse_simple_dict(ldata[5], ";") if len(ldata) >= 7: session_options = parse_simple_dict(ldata[6], ";") return username, password, uid, gid, displays, env_options, session_options
def authenticate(self, challenge_response, client_salt): if not self.salt: log.error("Error: illegal challenge response received - salt cleared or unset") return None #ensure this salt does not get re-used: if client_salt is None: salt = self.salt else: salt = xor(self.salt, client_salt) self.salt = None password = self.get_password() if not password: log.error("Error: authentication failed") log.error(" no password for '%s' in '%s'", self.username, self.password_filename) return False verify = hmac.HMAC(strtobytes(password), strtobytes(salt), digestmod=hashlib.md5).hexdigest() log("authenticate(%s) password='******', hex(salt)=%s, hash=%s", challenge_response, nonl(password), binascii.hexlify(strtobytes(salt)), verify) if hasattr(hmac, "compare_digest"): eq = hmac.compare_digest(verify, challenge_response) else: eq = verify==challenge_response if not eq: log("expected '%s' but got '%s'", verify, challenge_response) log.error("Error: hmac password challenge for '%s' does not match", self.username) return False return True
def getgid(v): try: return int(v) except: log("gid '%s' is not an int", v) if os.name=="posix": try: import grp #@UnresolvedImport return grp.getgrnam(v or "nobody").gr_gid except Exception as e: log.error("Error: cannot find gid of '%s': %s", v, e) return os.getgid() return -1
def getuid(v): try: return int(v) except: log("uid '%s' is not an int", v) if os.name=="posix": try: import pwd return pwd.getpwnam(v or "nobody").pw_uid except Exception as e: log.error("Error: cannot find uid of '%s': %s", v, e) return os.getuid() return -1
def getgid(v): try: return int(v) except: log("gid '%s' is not an int", v) if os.name == "posix": try: import grp #@UnresolvedImport return grp.getgrnam(v or "nobody").gr_gid except Exception as e: log.error("Error: cannot find gid of '%s': %s", v, e) return os.getgid() return -1
def getuid(v): try: return int(v) except: log("uid '%s' is not an int", v) if os.name == "posix": try: import pwd return pwd.getpwnam(v or "nobody").pw_uid except Exception as e: log.error("Error: cannot find uid of '%s': %s", v, e) return os.getuid() return -1
def authenticate_hmac(self, challenge_response, client_salt): log("authenticate_hmac(%s, %s)", challenge_response, client_salt) self.sessions = None if not self.salt: log.error( "Error: illegal challenge response received - salt cleared or unset" ) return None #ensure this salt does not get re-used: salt = self.get_response_salt(client_salt) entry = self.get_auth_info() if entry is None: log.error("Error: authentication failed") log.error(" no password for '%s' in '%s'", self.username, self.password_filename) return None log("authenticate: auth-info(%s)=%s", self.username, entry) fpassword, uid, gid, displays, env_options, session_options = entry digestmod = get_digest_module(self.digest) verify = hmac.HMAC(strtobytes(fpassword), strtobytes(salt), digestmod=digestmod).hexdigest() log( "multifile authenticate_hmac(%s) password='******', hex(salt)=%s, hash=%s", challenge_response, fpassword, binascii.hexlify(strtobytes(salt)), verify) if not hmac.compare_digest(verify, challenge_response): log("expected '%s' but got '%s'", verify, challenge_response) log.error("Error: hmac password challenge for '%s' does not match", self.username) return False self.sessions = uid, gid, displays, env_options, session_options return True
def authenticate_hmac(self, challenge_response, client_salt=None): if not self.salt: log.error("Error: illegal challenge response received - salt cleared or unset") return None salt = self.get_response_salt(client_salt) password = self.get_password() log("authenticate_hmac() get_password()=%s", obsc(password)) if not password: log.warn("Warning: authentication failed") log.warn(" no password for '%s' in '%s'", self.username, self.password_filename) return False if not verify_digest(self.digest, password, salt, challenge_response): log.warn("Warning: %s challenge for '%s' does not match", self.digest, self.username) return False return True
def parse_auth_line(line): ldata = line.split(b"|") log("found %s fields", len(ldata)) assert len(ldata) >= 4, "not enough fields" #parse fields: username = ldata[0] password = ldata[1] uid = getuid(ldata[2]) gid = getgid(ldata[3]) displays = ldata[4].split(b",") env_options = {} session_options = {} if len(ldata) >= 6: env_options = parse_simple_dict(ldata[5], ";") if len(ldata) >= 7: session_options = parse_simple_dict(ldata[6], ";") return username, password, uid, gid, displays, env_options, session_options
def parse_auth_line(line): ldata = line.split(b"|") log("found %s fields", len(ldata)) assert len(ldata)>=4, "not enough fields" #parse fields: username = ldata[0] password = ldata[1] uid = getuid(ldata[2]) gid = getgid(ldata[3]) displays = ldata[4].split(b",") env_options = {} session_options = {} if len(ldata)>=6: env_options = parse_simple_dict(ldata[5], ";") if len(ldata)>=7: session_options = parse_simple_dict(ldata[6], ";") return username, password, uid, gid, displays, env_options, session_options
def authenticate(self, challenge_response, client_salt): if not self.salt: log.error( "Error: illegal challenge response received - salt cleared or unset" ) return None salt = self.get_response_salt(client_salt) password = self.get_password() if not password: log.error("Error: authentication failed") log.error(" no password for '%s' in '%s'", self.username, self.password_filename) return False if not self.verify_hmac_md5(password, salt): log("expected '%s' but got '%s'", verify, challenge_response) log.error("Error: hmac password challenge for '%s' does not match", self.username) return False return True
def authenticate_hmac(self, challenge_response, client_salt=None): log("authenticate_hmac(%r, %r)", challenge_response, client_salt) self.sessions = None if not self.salt: log.error( "Error: illegal challenge response received - salt cleared or unset" ) return None #ensure this salt does not get re-used: salt = self.get_response_salt(client_salt) entry = self.get_auth_info() if entry is None: log.warn("Warning: authentication failed") log.warn(" no password for '%s' in '%s'", self.username, self.password_filename) return None log("authenticate: auth-info(%s)=%s", self.username, entry) fpassword, uid, gid, displays, env_options, session_options = entry log("multifile authenticate_hmac password='******', hex(salt)=%s", fpassword, hexstr(salt)) if not verify_digest(self.digest, fpassword, salt, challenge_response): log.warn("Warning: %s challenge for '%s' does not match", self.digest, self.username) return False self.sessions = uid, gid, displays, env_options, session_options return True
def parse_filedata(self, data): if not data: return {} auth_data = {} i = 0 for line in data.splitlines(): i += 1 line = line.strip() log("line %s: %s", i, line) if not line or line.startswith(b"#"): continue try: v = parse_auth_line(line) if v: username, password, uid, gid, displays, env_options, session_options = v if username in auth_data: log.error("Error: duplicate entry for username '%s' in '%s'", username, self.password_filename) else: auth_data[username] = password, uid, gid, displays, env_options, session_options except Exception as e: log("parsing error", exc_info=True) log.error("Error parsing password file '%s' at line %i:", self.password_filename, i) log.error(" '%s'", bytestostr(line)) log.error(" %s", e) continue log("parsed auth data from file %s: %s", self.password_filename, auth_data) return auth_data
def authenticate_hmac(self, challenge_response, client_salt): self.sessions = None if not self.salt: log.error("Error: illegal challenge response received - salt cleared or unset") return None #ensure this salt does not get re-used: if client_salt is None: salt = self.salt else: salt = xor(self.salt, client_salt) self.salt = None entry = self.get_auth_info() log("authenticate(%s) auth-info=%s", self.username, entry) if entry is None: log.error("Error: authentication failed") log.error(" no password for '%s' in '%s'", self.username, self.password_filename) return None fpassword, uid, gid, displays, env_options, session_options = entry verify = hmac.HMAC(strtobytes(fpassword), strtobytes(salt), digestmod=hashlib.md5).hexdigest() log("authenticate(%s) password='******', hex(salt)=%s, hash=%s", challenge_response, fpassword, binascii.hexlify(strtobytes(salt)), verify) if not hmac.compare_digest(verify, challenge_response): log("expected '%s' but got '%s'", verify, challenge_response) log.error("Error: hmac password challenge for '%s' does not match", self.username) return False self.sessions = uid, gid, displays, env_options, session_options return True
def parse_filedata(self, data): global socket_dir, socket_dirs if not data: return {} auth_data = {} i = 0 for line in data.splitlines(): i += 1 line = line.strip() log("line %s: %s", i, line) if len(line)==0 or line.startswith(b"#"): continue try: v = parse_auth_line(line) if v: username, password, uid, gid, displays, env_options, session_options = v if username in auth_data: log.error("Error: duplicate entry for username '%s' in '%s'", username, self.password_filename) else: auth_data[username] = password, uid, gid, displays, env_options, session_options except Exception as e: log("parsing error", exc_info=True) log.error("Error parsing password file '%s' at line %i:", self.password_filename, i) log.error(" '%s'", line) log.error(" %s", e) continue log("parsed auth data from file %s: %s", self.password_filename, auth_data) return auth_data
def authenticate(self, challenge_response, client_salt): if not self.salt: log.error("Error: illegal challenge response received - salt cleared or unset") return None #ensure this salt does not get re-used: if client_salt is None: salt = self.salt else: salt = xor(self.salt, client_salt) self.salt = None password = self.get_password() if not password: log.error("Error: authentication failed") log.error(" no password for '%s' in '%s'", self.username, self.password_filename) return False verify = hmac.HMAC(strtobytes(password), strtobytes(salt), digestmod=hashlib.md5).hexdigest() log("authenticate(%s) password='******', hex(salt)=%s, hash=%s", challenge_response, nonl(password), binascii.hexlify(strtobytes(salt)), verify) if not hmac.compare_digest(verify, challenge_response): log("expected '%s' but got '%s'", verify, challenge_response) log.error("Error: hmac password challenge for '%s' does not match", self.username) return False return True
def authenticate_hmac(self, challenge_response, client_salt): if not self.salt: log.error("Error: illegal challenge response received - salt cleared or unset") return None salt = self.get_response_salt(client_salt) password = self.get_password() if not password: log.error("Error: authentication failed") log.error(" no password for '%s' in '%s'", self.username, self.password_filename) return False digestmod = get_digest_module(self.digest) if not digestmod: log.error("Error: %s authentication failed", self) log.error(" digest module '%s' is invalid", self.digest) return False verify = hmac.HMAC(strtobytes(password), strtobytes(salt), digestmod=digestmod).hexdigest() log("file authenticate(%s) password='******', salt=%s, hash=%s", nonl(challenge_response), nonl(password), binascii.hexlify(strtobytes(salt)), verify) if not hmac.compare_digest(verify, challenge_response): log("expected '%s' but got '%s'", verify, challenge_response) log.error("Error: hmac password challenge for '%s' does not match", self.username) return False return True
def parse_auth_line(line): ldata = line.split(b"|") assert len(ldata)>=2, "not enough fields: %i" % (len(ldata)) log("found %s fields", len(ldata)) #parse fields: username = ldata[0] password = ldata[1] if len(ldata)>=5: uid = parse_uid(bytestostr(ldata[2])) gid = parse_gid(bytestostr(ldata[3])) displays = bytestostr(ldata[4]).split(",") else: #this will use the default value, usually "nobody": uid = parse_uid(None) gid = parse_gid(None) displays = [] env_options = {} session_options = {} if len(ldata)>=6: env_options = parse_simple_dict(ldata[5], b";") if len(ldata)>=7: session_options = parse_simple_dict(ldata[6], b";") return username, password, uid, gid, displays, env_options, session_options
def authenticate_hmac(self, challenge_response, client_salt): self.sessions = None if not self.salt: log.error( "Error: illegal challenge response received - salt cleared or unset" ) return None #ensure this salt does not get re-used: salt = self.get_response_salt(client_salt) entry = self.get_auth_info() log("authenticate(%s) auth-info=%s", self.username, entry) if entry is None: log.error("Error: authentication failed") log.error(" no password for '%s' in '%s'", self.username, self.password_filename) return None fpassword, uid, gid, displays, env_options, session_options = entry if not self.verify_hmac_md5(password, salt): log("expected '%s' but got '%s'", verify, challenge_response) log.error("Error: hmac password challenge for '%s' does not match", self.username) return False self.sessions = uid, gid, displays, env_options, session_options return True
def authenticate_hmac(self, challenge_response, client_salt): self.sessions = None if not self.salt: log.error( "Error: illegal challenge response received - salt cleared or unset" ) return None #ensure this salt does not get re-used: if client_salt is None: salt = self.salt else: salt = xor(self.salt, client_salt) self.salt = None entry = self.get_auth_info() log("authenticate(%s) auth-info=%s", self.username, entry) if entry is None: log.error("Error: authentication failed") log.error(" no password for '%s' in '%s'", self.username, self.password_filename) return None fpassword, uid, gid, displays, env_options, session_options = entry verify = hmac.HMAC(strtobytes(fpassword), strtobytes(salt), digestmod=hashlib.md5).hexdigest() log("authenticate(%s) password='******', hex(salt)=%s, hash=%s", challenge_response, fpassword, binascii.hexlify(strtobytes(salt)), verify) if hasattr(hmac, "compare_digest"): eq = hmac.compare_digest(verify, challenge_response) else: eq = verify == challenge_response if not eq: log("expected '%s' but got '%s'", verify, challenge_response) log.error("Error: hmac password challenge for '%s' does not match", self.username) return False self.sessions = uid, gid, displays, env_options, session_options return True
def get_password(self): entry = self.get_auth_info() log("get_password() found entry=%s", entry) if entry is None: return None return entry[0]