示例#1
0
 def _process_challenge(self, packet):
     authlog("processing challenge: %s", packet[1:])
     def warn_server_and_exit(code, message, server_message="authentication failed"):
         authlog.error("Error: authentication failed:")
         authlog.error(" %s", message)
         self.disconnect_and_quit(code, server_message)
     if not self.password_file and not os.environ.get('XPRA_PASSWORD'):
         warn_server_and_exit(EXIT_PASSWORD_REQUIRED, "this server requires authentication, please provide a password", "no password available")
         return
     password = self.load_password()
     if not password:
         warn_server_and_exit(EXIT_PASSWORD_FILE_ERROR, "failed to load password from file %s" % self.password_file, "no password available")
         return
     salt = packet[1]
     if self.encryption:
         assert len(packet)>=3, "challenge does not contain encryption details to use for the response"
         server_cipher = typedict(packet[2])
         key = self.get_encryption_key()
         if key is None:
             warn_server_and_exit(EXIT_ENCRYPTION, "the server does not use any encryption", "client requires encryption")
             return
         if not self.set_server_encryption(server_cipher, key):
             return
     #all server versions support a client salt,
     #they also tell us which digest to use:
     digest = packet[3]
     client_salt = get_hex_uuid()+get_hex_uuid()
     #TODO: use some key stretching algorigthm? (meh)
     try:
         from xpra.codecs.xor.cyxor import xor_str           #@UnresolvedImport
         salt = xor_str(salt, client_salt)
     except:
         salt = xor(salt, client_salt)
     if digest==b"hmac":
         import hmac, hashlib
         def s(v):
             try:
                 return v.encode()
             except:
                 return str(v)
         password = s(password)
         salt = s(salt)
         challenge_response = hmac.HMAC(password, salt, digestmod=hashlib.md5).hexdigest()
     elif digest==b"xor":
         #don't send XORed password unencrypted:
         if not self._protocol.cipher_out and not ALLOW_UNENCRYPTED_PASSWORDS:
             warn_server_and_exit(EXIT_ENCRYPTION, "server requested digest %s, cowardly refusing to use it without encryption" % digest, "invalid digest")
             return
         challenge_response = xor(password, salt)
     else:
         warn_server_and_exit(EXIT_PASSWORD_REQUIRED, "server requested an unsupported digest: %s" % digest, "invalid digest")
         return
     if digest:
         authlog("%s(%s, %s)=%s", digest, binascii.hexlify(password), binascii.hexlify(salt), challenge_response)
     self.password_sent = True
     self.remove_packet_handlers("challenge")
     self.send_hello(challenge_response, client_salt)
示例#2
0
 def _process_challenge(self, packet):
     log("processing challenge: %s", packet[1:])
     if not self.password_file:
         self.warn_and_quit(
             EXIT_PASSWORD_REQUIRED,
             "server requires authentication, please provide a password")
         return
     password = self.load_password()
     if not password:
         self.warn_and_quit(
             EXIT_PASSWORD_FILE_ERROR,
             "failed to load password from file %s" % self.password_file)
         return
     salt = packet[1]
     if self.encryption:
         assert len(
             packet
         ) >= 3, "challenge does not contain encryption details to use for the response"
         server_cipher = packet[2]
         key = self.get_encryption_key()
         if key is None:
             self.warn_and_quit(EXIT_ENCRYPTION,
                                "encryption key is missing")
             return
         if not self.set_server_encryption(server_cipher, key):
             return
     digest = "hmac"
     client_can_salt = len(packet) >= 4
     client_salt = None
     if client_can_salt:
         #server supports client salt, and tells us which digest to use:
         digest = packet[3]
         client_salt = get_hex_uuid() + get_hex_uuid()
         #TODO: use some key stretching algorigthm? (meh)
         salt = xor(salt, client_salt)
     if digest == "hmac":
         import hmac
         challenge_response = hmac.HMAC(password, salt).hexdigest()
     elif digest == "xor":
         #don't send XORed password unencrypted:
         if not self._protocol.cipher_out and not ALLOW_UNENCRYPTED_PASSWORDS:
             self.warn_and_quit(
                 EXIT_ENCRYPTION,
                 "server requested digest %s, cowardly refusing to use it without encryption"
                 % digest)
             return
         challenge_response = xor(password, salt)
     else:
         self.warn_and_quit(
             EXIT_PASSWORD_REQUIRED,
             "server requested an unsupported digest: %s" % digest)
         return
     if digest:
         log("%s(%s, %s)=%s", digest, password, salt, challenge_response)
     self.password_sent = True
     self.send_hello(challenge_response, client_salt)
示例#3
0
 def _process_challenge(self, packet):
     log("processing challenge: %s", packet[1:])
     if not self.password_file and not os.environ.get('XPRA_PASSWORD'):
         self.warn_and_quit(EXIT_PASSWORD_REQUIRED, "server requires authentication, please provide a password")
         return
     password = self.load_password()
     if not password:
         self.warn_and_quit(EXIT_PASSWORD_FILE_ERROR, "failed to load password from file %s" % self.password_file)
         return
     salt = packet[1]
     if self.encryption:
         assert len(packet)>=3, "challenge does not contain encryption details to use for the response"
         server_cipher = packet[2]
         key = self.get_encryption_key()
         if key is None:
             self.warn_and_quit(EXIT_ENCRYPTION, "encryption key is missing")
             return
         if not self.set_server_encryption(server_cipher, key):
             return
     digest = "hmac"
     client_can_salt = len(packet)>=4
     client_salt = None
     if client_can_salt:
         #server supports client salt, and tells us which digest to use:
         digest = packet[3]
         client_salt = get_hex_uuid()+get_hex_uuid()
         #TODO: use some key stretching algorigthm? (meh)
         salt = xor(salt, client_salt)
     if digest=="hmac":
         import hmac
         challenge_response = hmac.HMAC(password, salt).hexdigest()
     elif digest=="xor":
         #don't send XORed password unencrypted:
         if not self._protocol.cipher_out and not ALLOW_UNENCRYPTED_PASSWORDS:
             self.warn_and_quit(EXIT_ENCRYPTION, "server requested digest %s, cowardly refusing to use it without encryption" % digest)
             return
         challenge_response = xor(password, salt)
     else:
         self.warn_and_quit(EXIT_PASSWORD_REQUIRED, "server requested an unsupported digest: %s" % digest)
         return
     if digest:
         log("%s(%s, %s)=%s", digest, password, salt, challenge_response)
     self.password_sent = True
     for d in (self._packet_handlers, self._ui_packet_handlers):
         try:
             del d["challenge"]
         except:
             pass
     self.send_hello(challenge_response, client_salt)
示例#4
0
 def authenticate(self, challenge_response, client_salt):
     global password_file
     if not self.salt:
         log.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_entry()
     if entry is None:
         log.error("usename %s does not exist in %s", self.username, password_file)
         return None
     fpassword, uid, gid, displays, env_options, session_options = entry
     verify = hmac.HMAC(fpassword, salt).hexdigest()
     log("authenticate(%s) password=%s, hex(salt)=%s, hash=%s", challenge_response, fpassword, binascii.hexlify(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("hmac password challenge for %s does not match", self.username)
         return False
     self.sessions = uid, gid, displays, env_options, session_options
     return True
示例#5
0
 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
     #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: %s authentication failed", self)
         log.error(" no password defined for '%s'", self.username)
         return False
     verify = hmac.HMAC(strtobytes(password), strtobytes(salt), digestmod=hashlib.md5).hexdigest()
     log("authenticate(%s) password=%s, hex(salt)=%s, hash=%s", challenge_response, 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
示例#6
0
文件: auth_test.py 项目: ljmljz/xpra
	def _test_file_auth(self, name, module, genauthdata):
		#no file, no go:
		a = self._init_auth(module)
		assert a.requires_challenge()
		p = a.get_password()
		assert not p, "got a password from %s: %s" % (a, p) 
		#challenge twice is a fail
		assert a.get_challenge()
		assert not a.get_challenge()
		assert not a.get_challenge()
		for muck in (0, 1):
			f = tempfile.NamedTemporaryFile(prefix=name)
			filename = f.name
			with f:
				a = self._init_auth(module, {"password_file" : filename})
				password, filedata = genauthdata(a)
				print("saving password file data='%s' to '%s'", filedata, filename)
				f.write(strtobytes(filedata))
				f.flush()
				assert a.requires_challenge()
				salt, mac = a.get_challenge()
				assert salt
				assert mac=="hmac"
				password = strtobytes(password)
				client_salt = strtobytes(uuid.uuid4().hex+uuid.uuid4().hex)
				auth_salt = strtobytes(xor(salt, client_salt))
				if muck==0:
					verify = hmac.HMAC(password, auth_salt, digestmod=hashlib.md5).hexdigest()
					assert a.authenticate(verify, client_salt)
					assert not a.authenticate(verify, client_salt)
					assert a.get_password()==password
				elif muck==1:
					for verify in ("whatever", None, "bad"):
						assert not a.authenticate(verify, client_salt)
示例#7
0
 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
     #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: %s authentication failed", self)
         log.error(" no password defined for '%s'", self.username)
         return False
     verify = hmac.HMAC(strtobytes(password),
                        strtobytes(salt),
                        digestmod=hashlib.md5).hexdigest()
     log("authenticate(%s) password=%s, hex(salt)=%s, hash=%s",
         challenge_response, 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
示例#8
0
 def authenticate(self, challenge_response, client_salt):
     global password_file
     if not self.salt:
         log.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_entry()
     if entry is None:
         log.error("usename %s does not exist in %s", self.username,
                   password_file)
         return None
     fpassword, uid, gid, displays, env_options, session_options = entry
     verify = hmac.HMAC(fpassword, salt).hexdigest()
     log("authenticate(%s) password=%s, hex(salt)=%s, hash=%s",
         challenge_response, fpassword, binascii.hexlify(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("hmac password challenge for %s does not match",
                   self.username)
         return False
     self.sessions = uid, gid, displays, env_options, session_options
     return True
示例#9
0
 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
示例#10
0
def main(argv):
    from xpra.util import xor
    from xpra.net.digest import get_salt, get_digests, gendigest
    from xpra.platform import program_context
    with program_context("LDAP-Password-Auth", "LDAP-Password-Authentication"):
        for x in list(argv):
            if x in ("-v", "--verbose"):
                enable_debug_for("auth")
                argv.remove(x)
        if len(argv) not in (3,4,5,6,7):
            sys.stderr.write("%s invalid arguments\n" % argv[0])
            sys.stderr.write("usage: %s username password [host] [port] [tls] [username_format]\n" % argv[0])
            return 1
        username = argv[1]
        password = argv[2]
        kwargs = {}
        if len(argv)>=4:
            kwargs["host"] = argv[3]
        if len(argv)>=5:
            kwargs["port"] = argv[4]
        if len(argv)>=6:
            kwargs["tls"] = argv[5]
        if len(argv)>=7:
            kwargs["username_format"] = argv[6]
        a = Authenticator(username, **kwargs)
        server_salt, digest = a.get_challenge(["xor"])
        salt_digest = a.choose_salt_digest(get_digests())
        assert digest=="xor"
        client_salt = get_salt(len(server_salt))
        combined_salt = gendigest(salt_digest, client_salt, server_salt)
        response = xor(password, combined_salt)
        r = a.authenticate(response, client_salt)
        print("success: %s" % r)
        return int(not r)
示例#11
0
	def _test_file_auth(self, name, module, genauthdata):
		#no file, no go:
		a = self._init_auth(module)
		assert a.requires_challenge()
		p = a.get_password()
		assert not p, "got a password from %s: %s" % (a, p)
		#challenge twice is a fail
		assert a.get_challenge()
		assert not a.get_challenge()
		assert not a.get_challenge()
		for muck in (0, 1):
			f = tempfile.NamedTemporaryFile(prefix=name)
			filename = f.name
			with f:
				a = self._init_auth(module, {"password_file" : filename})
				password, filedata = genauthdata(a)
				#print("saving password file data='%s' to '%s'" % (filedata, filename))
				f.write(strtobytes(filedata))
				f.flush()
				assert a.requires_challenge()
				salt, mac = a.get_challenge()
				assert salt
				assert mac=="hmac"
				password = strtobytes(password)
				client_salt = strtobytes(uuid.uuid4().hex+uuid.uuid4().hex)
				auth_salt = strtobytes(xor(salt, client_salt))
				if muck==0:
					verify = hmac.HMAC(password, auth_salt, digestmod=hashlib.md5).hexdigest()
					assert a.authenticate(verify, client_salt)
					assert not a.authenticate(verify, client_salt)
					assert a.get_password()==password
				elif muck==1:
					for verify in ("whatever", None, "bad"):
						assert not a.authenticate(verify, client_salt)
示例#12
0
def main(argv):
    from xpra.platform import program_context
    with program_context("Kerberos-Password-Auth",
                         "Kerberos-Password-Authentication"):
        if len(argv) not in (3, 4, 5):
            sys.stderr.write("%s invalid arguments\n" % argv[0])
            sys.stderr.write(
                "usage: %s username password [service [realm]]\n" % argv[0])
            return 1
        username = argv[1]
        password = argv[2]
        kwargs = {}
        if len(argv) >= 4:
            kwargs["service"] = argv[3]
        if len(argv) == 5:
            kwargs["realm"] = argv[4]
        a = Authenticator(username, **kwargs)
        server_salt, digest = a.get_challenge(["xor"])
        salt_digest = a.choose_salt_digest(get_digests())
        assert digest == "xor"
        client_salt = get_salt(len(server_salt))
        combined_salt = gendigest(salt_digest, client_salt, server_salt)
        response = xor(password, combined_salt)
        a.authenticate(response, client_salt)
    return 0
示例#13
0
 def authenticate(self, challenge_response, client_salt):
     global socket_dir
     if self.salt is None:
         log.error("got a challenge response with no salt!")
         return False
     if client_salt is None:
         salt = self.salt
     else:
         salt = xor(self.salt, client_salt)
     self.salt = None
     password = xor(challenge_response, salt)
     #warning: enabling logging here would log the actual system password!
     #log("authenticate(%s) password=%s", challenge_response, password)
     #verify login:
     try :
         if not self.check(password):
             return False
     except Exception, e:
         log.error("authentication error: %s", e)
         return False
示例#14
0
 def authenticate(self, challenge_response, client_salt):
     global socket_dir
     if self.salt is None:
         log.error("got a challenge response with no salt!")
         return False
     if client_salt is None:
         salt = self.salt
     else:
         salt = xor(self.salt, client_salt)
     self.salt = None
     password = xor(challenge_response, salt)
     #warning: enabling logging here would log the actual system password!
     #log("authenticate(%s) password=%s", challenge_response, password)
     #verify login:
     try :
         if not self.check(password):
             return False
     except Exception, e:
         log.error("authentication error: %s", e)
         return False
示例#15
0
 def authenticate_check(self, challenge_response, client_salt):
     if self.salt is None:
         log.error("Error: illegal challenge response received - salt cleared or unset")
         return False
     if client_salt is None:
         salt = self.salt
     else:
         salt = xor(self.salt, client_salt)
     self.salt = None
     password = xor(challenge_response, salt)
     #warning: enabling logging here would log the actual system password!
     #log("authenticate(%s) password=%s", challenge_response, password)
     #verify login:
     try :
         ret = self.check(password)
         log("check(..)=%s", ret)
     except Exception as e:
         log.error("Error in %s authentication checks:", self)
         log.error(" %s", e)
         return False
     return ret
示例#16
0
 def authenticate_check(self, challenge_response, client_salt):
     if self.salt is None:
         log.error(
             "Error: illegal challenge response received - salt cleared or unset"
         )
         return False
     if client_salt is None:
         salt = self.salt
     else:
         salt = xor(self.salt, client_salt)
     self.salt = None
     password = xor(challenge_response, salt)
     #warning: enabling logging here would log the actual system password!
     #log("authenticate(%s) password=%s", challenge_response, password)
     #verify login:
     try:
         ret = self.check(password)
         log("authenticate_check(..)=%s", ret)
     except Exception as e:
         log.error("Error: %s authentication check failed:", self)
         log.error(" %s", e)
         return False
     return ret
示例#17
0
	def _test_hmac_auth(self, auth_class, password, **kwargs):
		for x in (password, "somethingelse"):
			a = self._init_auth(auth_class, **kwargs)
			assert a.requires_challenge()
			assert a.get_password()
			salt, mac = a.get_challenge()
			assert salt
			assert mac=="hmac", "invalid mac: %s" % mac
			client_salt = strtobytes(uuid.uuid4().hex+uuid.uuid4().hex)
			auth_salt = strtobytes(xor(salt, client_salt))
			verify = hmac.HMAC(x, auth_salt, digestmod=hashlib.md5).hexdigest()
			passed = a.authenticate(verify, client_salt)
			assert passed == (x==password), "expected authentication to %s with %s vs %s" % (["fail", "succeed"][x==password], x, password)
			assert not a.authenticate(verify, client_salt)
示例#18
0
文件: auth_test.py 项目: ljmljz/xpra
	def _test_hmac_auth(self, auth_class, password, **kwargs):
		for x in (password, "somethingelse"):
			a = self._init_auth(auth_class, **kwargs)
			assert a.requires_challenge()
			assert a.get_password()
			salt, mac = a.get_challenge()
			assert salt
			assert mac=="hmac", "invalid mac: %s" % mac
			client_salt = strtobytes(uuid.uuid4().hex+uuid.uuid4().hex)
			auth_salt = strtobytes(xor(salt, client_salt))
			verify = hmac.HMAC(x, auth_salt, digestmod=hashlib.md5).hexdigest()
			passed = a.authenticate(verify, client_salt)
			assert passed == (x==password), "expected authentication to %s with %s vs %s" % (["fail", "succeed"][x==password], x, password)
			assert not a.authenticate(verify, client_salt)
示例#19
0
def gendigest(digest, password, salt):
    assert digest and password and salt
    salt = memoryview_to_bytes(salt)
    password = strtobytes(password)
    if digest == "xor":
        salt = salt.ljust(len(password), "\x00")[:len(password)]
        return memoryview_to_bytes(xor(password, salt))
    digestmod = get_digest_module(digest)
    if not digestmod:
        log("invalid digest module '%s'", digest)
        return None
        #warn_server_and_exit(EXIT_UNSUPPORTED, "server requested digest '%s' but it is not supported" % digest, "invalid digest")
    v = hmac.HMAC(strtobytes(password), strtobytes(salt),
                  digestmod=digestmod).hexdigest()
    return v
示例#20
0
def main(argv):
    from xpra.platform import program_context
    with program_context("GSS-Auth", "GSS-Authentication"):
        if len(argv) != 3:
            sys.stderr.write("%s invalid arguments\n" % argv[0])
            sys.stderr.write("usage: %s username token\n" % argv[0])
            return 1
        username = argv[1]
        token = argv[2]
        kwargs = {}
        a = Authenticator(username, **kwargs)
        server_salt, digest = a.get_challenge(["xor"])
        salt_digest = a.choose_salt_digest(get_digests())
        assert digest == "xor"
        client_salt = get_salt(len(server_salt))
        combined_salt = gendigest(salt_digest, client_salt, server_salt)
        response = xor(token, combined_salt)
        a.authenticate(response, client_salt)
    return 0
示例#21
0
def gendigest(digest, password, salt):
    assert digest and password and salt
    salt = memoryview_to_bytes(salt)
    password = strtobytes(password)
    if digest == "des":
        from xpra.net.d3des import generate_response
        password = password.ljust(8, "\x00")[:8]
        salt = salt.ljust(16, "\x00")[:16]
        v = generate_response(password, salt)
        return hexstr(v)
    elif digest == "xor":
        salt = salt.ljust(16, "\x00")[:len(password)]
        return memoryview_to_bytes(xor(password, salt))
    digestmod = get_digest_module(digest)
    if not digestmod:
        log("invalid digest module '%s': %s", digest)
        return None
        #warn_server_and_exit(EXIT_UNSUPPORTED, "server requested digest '%s' but it is not supported" % digest, "invalid digest")
    v = hmac.HMAC(strtobytes(password), strtobytes(salt),
                  digestmod=digestmod).hexdigest()
    return v
示例#22
0
 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
示例#23
0
文件: digest.py 项目: tardyp/Xpra
def gendigest(digest, password, salt):
    assert digest and password and salt
    salt = memoryview_to_bytes(salt)
    password = strtobytes(password)
    if digest=="des":
        from xpra.net.d3des import generate_response
        password = password.ljust(8, b"\x00")[:8]
        salt = salt.ljust(16, b"\x00")[:16]
        v = generate_response(password, salt)
        return hexstr(v)
    elif digest in ("xor", "kerberos", "gss"):
        #kerberos and gss use xor because we need to use the actual token
        #at the other end
        salt = salt.ljust(len(password), b"\x00")[:len(password)]
        v = xor(password, salt)
        return memoryview_to_bytes(v)
    digestmod = get_digest_module(digest)
    if not digestmod:
        log("invalid digest module '%s': %s", digest)
        return None
        #warn_server_and_exit(EXIT_UNSUPPORTED, "server requested digest '%s' but it is not supported" % digest, "invalid digest")
    v = hmac.HMAC(strtobytes(password), strtobytes(salt), digestmod=digestmod).hexdigest()
    return v
示例#24
0
    def _process_challenge(self, packet):
        authlog("processing challenge: %s", packet[1:])

        def warn_server_and_exit(code,
                                 message,
                                 server_message="authentication failed"):
            authlog.error("Error: authentication failed:")
            authlog.error(" %s", message)
            self.disconnect_and_quit(code, server_message)

        if not self.has_password():
            warn_server_and_exit(
                EXIT_PASSWORD_REQUIRED,
                "this server requires authentication, please provide a password",
                "no password available")
            return
        password = self.load_password()
        if not password:
            warn_server_and_exit(
                EXIT_PASSWORD_FILE_ERROR,
                "failed to load password from file %s" % self.password_file,
                "no password available")
            return
        server_salt = packet[1]
        if self.encryption:
            assert len(
                packet
            ) >= 3, "challenge does not contain encryption details to use for the response"
            server_cipher = typedict(packet[2])
            key = self.get_encryption_key()
            if key is None:
                warn_server_and_exit(EXIT_ENCRYPTION,
                                     "the server does not use any encryption",
                                     "client requires encryption")
                return
            if not self.set_server_encryption(server_cipher, key):
                return
        #all server versions support a client salt,
        #they also tell us which digest to use:
        digest = bytestostr(packet[3])
        l = len(server_salt)
        salt_digest = "xor"
        if len(packet) >= 5:
            salt_digest = bytestostr(packet[4])
        if salt_digest == "xor":
            #with xor, we have to match the size
            assert l >= 16, "server salt is too short: only %i bytes, minimum is 16" % l
            assert l <= 256, "server salt is too long: %i bytes, maximum is 256" % l
        else:
            #other digest, 32 random bytes is enough:
            l = 32
        client_salt = get_salt(l)
        if salt_digest in ("xor", "des"):
            if not LEGACY_SALT_DIGEST:
                warn_server_and_exit(
                    EXIT_INCOMPATIBLE_VERSION,
                    "server uses legacy salt digest '%s'" % salt_digest,
                    "unsupported digest %s" % salt_digest)
                return
            log.warn(
                "Warning: server using legacy support for '%s' salt digest",
                salt_digest)
        salt = gendigest(salt_digest, client_salt, server_salt)
        authlog("combined %s salt(%s, %s)=%s", salt_digest,
                binascii.hexlify(server_salt), binascii.hexlify(client_salt),
                binascii.hexlify(salt))
        if digest.startswith(b"hmac"):
            import hmac
            digestmod = get_digest_module(digest)
            if not digestmod:
                log("invalid digest module '%s': %s", digest)
                warn_server_and_exit(
                    EXIT_UNSUPPORTED,
                    "server requested digest '%s' but it is not supported" %
                    digest, "invalid digest")
                return
            password = strtobytes(password)
            salt = memoryview_to_bytes(salt)
            challenge_response = hmac.HMAC(password, salt,
                                           digestmod=digestmod).hexdigest()
            authlog("hmac.HMAC(%s, %s)=%s", binascii.hexlify(password),
                    binascii.hexlify(salt), challenge_response)
        elif digest == b"xor":
            #don't send XORed password unencrypted:
            encrypted = self._protocol.cipher_out or self._protocol.get_info(
            ).get("type") == "ssl"
            local = self.display_desc.get("local", False)
            authlog("xor challenge, encrypted=%s, local=%s", encrypted, local)
            if local and ALLOW_LOCALHOST_PASSWORDS:
                pass
            elif not encrypted and not ALLOW_UNENCRYPTED_PASSWORDS:
                warn_server_and_exit(
                    EXIT_ENCRYPTION,
                    "server requested digest %s, cowardly refusing to use it without encryption"
                    % digest, "invalid digest")
                return
            salt = salt[:len(password)]
            challenge_response = memoryview_to_bytes(xor(password, salt))
        else:
            warn_server_and_exit(
                EXIT_PASSWORD_REQUIRED,
                "server requested an unsupported digest: %s" % digest,
                "invalid digest")
            return
        if digest:
            authlog("%s(%s, %s)=%s", digest, binascii.hexlify(password),
                    binascii.hexlify(salt),
                    binascii.hexlify(challenge_response))
        self.password_sent = True
        self.remove_packet_handlers("challenge")
        self.send_hello(challenge_response, client_salt)
示例#25
0
文件: util_test.py 项目: tardyp/Xpra
 def test_xor(self):
     self.assertEqual(xor("A", "a"), xor("B", "b"))
示例#26
0
    def _process_challenge(self, packet):
        authlog("processing challenge: %s", packet[1:])

        def warn_server_and_exit(code,
                                 message,
                                 server_message="authentication failed"):
            authlog.error("Error: authentication failed:")
            authlog.error(" %s", message)
            self.disconnect_and_quit(code, server_message)

        if not self.has_password():
            warn_server_and_exit(
                EXIT_PASSWORD_REQUIRED,
                "this server requires authentication, please provide a password",
                "no password available")
            return
        password = self.load_password()
        if not password:
            warn_server_and_exit(
                EXIT_PASSWORD_FILE_ERROR,
                "failed to load password from file %s" % self.password_file,
                "no password available")
            return
        salt = packet[1]
        if self.encryption:
            assert len(
                packet
            ) >= 3, "challenge does not contain encryption details to use for the response"
            server_cipher = typedict(packet[2])
            key = self.get_encryption_key()
            if key is None:
                warn_server_and_exit(EXIT_ENCRYPTION,
                                     "the server does not use any encryption",
                                     "client requires encryption")
                return
            if not self.set_server_encryption(server_cipher, key):
                return
        #all server versions support a client salt,
        #they also tell us which digest to use:
        digest = packet[3]
        client_salt = get_salt(len(salt))
        #TODO: use some key stretching algorigthm? (meh)
        try:
            from xpra.codecs.xor.cyxor import xor_str  #@UnresolvedImport
            salt = xor_str(salt, client_salt)
        except:
            salt = xor(salt, client_salt)
        if digest == b"hmac":
            import hmac, hashlib
            password = strtobytes(password)
            salt = strtobytes(salt)
            challenge_response = hmac.HMAC(password,
                                           salt,
                                           digestmod=hashlib.md5).hexdigest()
        elif digest == b"xor":
            #don't send XORed password unencrypted:
            if not self._protocol.cipher_out and not ALLOW_UNENCRYPTED_PASSWORDS:
                warn_server_and_exit(
                    EXIT_ENCRYPTION,
                    "server requested digest %s, cowardly refusing to use it without encryption"
                    % digest, "invalid digest")
                return
            salt = salt[:len(password)]
            challenge_response = strtobytes(xor(password, salt))
        else:
            warn_server_and_exit(
                EXIT_PASSWORD_REQUIRED,
                "server requested an unsupported digest: %s" % digest,
                "invalid digest")
            return
        if digest:
            authlog("%s(%s, %s)=%s", digest, binascii.hexlify(password),
                    binascii.hexlify(salt), challenge_response)
        self.password_sent = True
        self.remove_packet_handlers("challenge")
        self.send_hello(challenge_response, client_salt)
示例#27
0
    def _process_challenge(self, packet):
        authlog("processing challenge: %s", packet[1:])

        def warn_server_and_exit(code, message, server_message="authentication failed"):
            authlog.error("Error: authentication failed:")
            authlog.error(" %s", message)
            self.disconnect_and_quit(code, server_message)

        if not self.has_password():
            warn_server_and_exit(
                EXIT_PASSWORD_REQUIRED,
                "this server requires authentication, please provide a password",
                "no password available",
            )
            return
        password = self.load_password()
        if not password:
            warn_server_and_exit(
                EXIT_PASSWORD_FILE_ERROR,
                "failed to load password from file %s" % self.password_file,
                "no password available",
            )
            return
        salt = packet[1]
        if self.encryption:
            assert len(packet) >= 3, "challenge does not contain encryption details to use for the response"
            server_cipher = typedict(packet[2])
            key = self.get_encryption_key()
            if key is None:
                warn_server_and_exit(
                    EXIT_ENCRYPTION, "the server does not use any encryption", "client requires encryption"
                )
                return
            if not self.set_server_encryption(server_cipher, key):
                return
        # all server versions support a client salt,
        # they also tell us which digest to use:
        digest = packet[3]
        client_salt = get_salt(len(salt))
        # TODO: use some key stretching algorigthm? (meh)
        salt = xor(salt, client_salt)
        if digest == b"hmac":
            import hmac, hashlib

            password = strtobytes(password)
            salt = strtobytes(salt)
            challenge_response = hmac.HMAC(password, salt, digestmod=hashlib.md5).hexdigest()
        elif digest == b"xor":
            # don't send XORed password unencrypted:
            encrypted = self._protocol.cipher_out or self._protocol.get_info().get("type") == "ssl"
            local = self.display_desc.get("local", False)
            authlog("xor challenge, encrypted=%s, local=%s", encrypted, local)
            if local and ALLOW_LOCALHOST_PASSWORDS:
                pass
            elif not encrypted and not ALLOW_UNENCRYPTED_PASSWORDS:
                warn_server_and_exit(
                    EXIT_ENCRYPTION,
                    "server requested digest %s, cowardly refusing to use it without encryption" % digest,
                    "invalid digest",
                )
                return
            salt = salt[: len(password)]
            challenge_response = strtobytes(xor(password, salt))
        else:
            warn_server_and_exit(
                EXIT_PASSWORD_REQUIRED, "server requested an unsupported digest: %s" % digest, "invalid digest"
            )
            return
        if digest:
            authlog("%s(%s, %s)=%s", digest, binascii.hexlify(password), binascii.hexlify(salt), challenge_response)
        self.password_sent = True
        self.remove_packet_handlers("challenge")
        self.send_hello(challenge_response, client_salt)