Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

request_port_forward is not reenterant #1710

Open
pyhedgehog opened this issue Jun 24, 2020 · 4 comments · May be fixed by #2381
Open

request_port_forward is not reenterant #1710

pyhedgehog opened this issue Jun 24, 2020 · 4 comments · May be fixed by #2381

Comments

@pyhedgehog
Copy link

Let's pretend we've configured everything to allow loopback connection without password...

import paramiko, socket
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('localhost')
def handler1(chan, source, target):
    chan.send('test1')
    chan.close()
def handler2(chan, source, target):
    chan.send('test2')
    chan.close()
client.get_transport().request_port_forward('127.0.0.1', 30001, handler1)
s = socket.create_connection(('127.0.0.1', 30001))
print(s.recv(10).decode('latin1'))
s.close()
client.get_transport().request_port_forward('127.0.0.1', 30002, handler2)
s = socket.create_connection(('127.0.0.1', 30002))
print(s.recv(10).decode('latin1'))
s.close()
s = socket.create_connection(('127.0.0.1', 30001))
print(s.recv(10).decode('latin1'))
s.close()

Real output:

test1
test2
test2

Expected output:

test1
test2
test1
@pyhedgehog
Copy link
Author

It's still here.

@gns24
Copy link

gns24 commented Feb 22, 2022

The issue is simpler than that - multiple port forwards just don't work.

import paramiko, socket
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('localhost')

def handler1(chan, source, target):
    chan.send('test1')
    chan.close()

def handler2(chan, source, target):
    chan.send('test2')
    chan.close()

client.get_transport().request_port_forward('127.0.0.1', 30001, handler1)
client.get_transport().request_port_forward('127.0.0.1', 30002, handler2)

s = socket.create_connection(('127.0.0.1', 30001))
print(s.recv(10).decode())
s.close()

s = socket.create_connection(('127.0.0.1', 30002))
print(s.recv(10).decode())
s.close()

gives

test2
test2

@SiriusXT
Copy link

SiriusXT commented Feb 9, 2023

I have the same problem

@pyhedgehog
Copy link
Author

pyhedgehog commented Apr 5, 2024

In 3.4.0 it's still exists.
Cause of problem is following line:

self._tcp_handler = handler

This overrides handler for every new forwarded port. We need dictionary that will map (listening) (address, port) to handler.
Obviously in cancel_port_forward() we should delete only one item of dictionary:
https://github.com/paramiko/paramiko/blob/main/paramiko/transport.py#L1168

@pyhedgehog pyhedgehog linked a pull request Apr 9, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants