-
-
Notifications
You must be signed in to change notification settings - Fork 2k
TypeError Excepiton during connect (probably incorrect usage of instance method) #1182
Description
Hello.
The problem looks like a bug, but I don’t sure.
My environment:
###
uname -a
Linux motkb-dev-app 3.10.0-514.el7.x86_64 #1 SMP Wed Oct 19 11:24:13 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux
###
cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.3 (Maipo)
###
yum list installed | grep python36
rh-python36-python.x86_64 3.6.3-1.el7 @asm_dev_local
rh-python36-python-devel.x86_64 3.6.3-1.el7 @asm_dev_local
rh-python36-python-libs.x86_64 3.6.3-1.el7 @asm_dev_local
rh-python36-python-pip.noarch 9.0.1-2.el7 @asm_dev_local
rh-python36-python-setuptools.noarch 36.5.0-1.el7 @asm_dev_local
rh-python36-python-tkinter.x86_64 3.6.3-1.el7 @asm_dev_local
rh-python36-python-tools.x86_64 3.6.3-1.el7 @asm_dev_local
rh-python36-python-virtualenv.noarch 15.1.0-2.el7 @asm_dev_local
rh-python36-runtime.x86_64 2.0-1.el7 @asm_dev_local
###
python --version
Python 3.6.3
###
Python 3.6.3 (default, Oct 25 2017, 13:35:50)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
###
pip list
Package Version
-------------- -------
asn1crypto 0.24.0
bcrypt 3.1.4
cffi 1.11.5
cryptography 2.2
docopt 0.6.2
idna 2.6
jedi 0.11.1
paramiko 2.4.1
parso 0.1.1
pip 9.0.1
prompt-toolkit 1.0.15
ptpython 0.41
pyasn1 0.4.2
pycparser 2.18
Pygments 2.2.0
PyNaCl 1.2.1
setuptools 28.8.0
six 1.11.0
wcwidth 0.1.7
wheel 0.29.0
Steps to reproduce the problem:
steps_to_reproduce_the_problem.py
import paramiko
host = '127.0.0.1'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=host)
stdin, stdout, stderr = client.exec_command('ls -l')
data = stdout.read() + stderr.read()
print(data)
client.close()The execution of the code above produce an error:
Unknown exception: an integer is required (got type bytes)
Traceback (most recent call last):
File "/home/someone/adir/venv_paramiko_test/lib/python3.6/site-packages/paramiko/transport.py", line 1925, in run
self.kex_engine.parse_next(ptype, m)
File "/home/someone/adir/venv_paramiko_test/lib/python3.6/site-packages/paramiko/kex_ecdh_nist.py", line 47, in parse_next
return self._parse_kexecdh_reply(m)
File "/home/someone/adir/venv_paramiko_test/lib/python3.6/site-packages/paramiko/kex_ecdh_nist.py", line 106, in _parse_kexecdh_reply
self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
File "/home/someone/adir/venv_paramiko_test/lib64/python3.6/hashlib.py", line 90, in inner
return func(*args, **kwargs)
TypeError: an integer is required (got type bytes)
Traceback (most recent call last):
File "steps_to_reproduce_the_problem.py", line 9, in <module>
client.connect(hostname=host)
File "/home/someone/adir/venv_paramiko_test/lib/python3.6/site-packages/paramiko/client.py", line 392, in connect
t.start_client(timeout=timeout)
File "/home/someone/adir/venv_paramiko_test/lib/python3.6/site-packages/paramiko/transport.py", line 545, in start_client
raise e
File "/home/someone/adir/venv_paramiko_test/lib/python3.6/site-packages/paramiko/transport.py", line 1925, in run
self.kex_engine.parse_next(ptype, m)
File "/home/someone/adir/venv_paramiko_test/lib/python3.6/site-packages/paramiko/kex_ecdh_nist.py", line 47, in parse_next
return self._parse_kexecdh_reply(m)
File "/home/someone/adir/venv_paramiko_test/lib/python3.6/site-packages/paramiko/kex_ecdh_nist.py", line 106, in _parse_kexecdh_reply
self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
File "/home/someone/adir/venv_paramiko_test/lib64/python3.6/hashlib.py", line 90, in inner
return func(*args, **kwargs)
TypeError: an integer is required (got type bytes)
Preliminary conclusions
I performed some investigation on kex_ecdh_nist.py, and found(I hope so) the reason of the error.
Here is a patch that I used to fix the issue:
21c21
< hash_algo = sha256
---
> hash_algo = staticmethod(sha256)
113c113
< hash_algo = sha384
---
> hash_algo = staticmethod(sha384)
119c119
< hash_algo = sha512
---
> hash_algo = staticmethod(sha512)And some explanations: the class KexNistp256 has an attribute hash_algo, it points to the function sha256(from hashlib), and here is the code:
..................
18 class KexNistp256():
19
20 name = "ecdh-sha2-nistp256"
21 hash_algo = sha256
22 curve = ec.SECP256R1()
23
..................Then, later, the call of the hash_algo:
..................
104 hm.add_string(Q_S_bytes)
105 hm.add_mpint(K)
106 self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
107 self.transport._verify_key(K_S, sig)
108 self.transport._activate_outbound()
..................And the call self.hash_algo(hm.asbytes()) it the reason of the error.
This happened because for the instance of the class, hash_algo, is not a function, but a bind method, and a bind method, during the call of KexNistp256.hash_algo puts object that called the method(in our case it is self) as a first argument of the method, and then, puts all other arguments, so in a nutshell, final call looks like this:
sha256(self, hm.asbytes())