Skip to content

Instantly share code, notes, and snippets.

@mdellavo
Created December 16, 2015 16:59
Show Gist options
  • Save mdellavo/9dd98e6223c6f815ad45 to your computer and use it in GitHub Desktop.
Save mdellavo/9dd98e6223c6f815ad45 to your computer and use it in GitHub Desktop.
Paramiko leaks Transports and Channels via Transport.server_accepts
import time
import socket
import threading
import paramiko
class ServerInterface(paramiko.ServerInterface):
def get_allowed_auths(self, username):
return "none"
def check_auth_none(self, username):
print "auth", username
return paramiko.AUTH_SUCCESSFUL
def check_channel_request(self, kind, chanid):
return paramiko.OPEN_SUCCEEDED if kind == "session" else paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
key = paramiko.RSAKey.generate(1024)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("127.0.0.1", 2222))
sock.listen(10)
print "listening..."
client, address = sock.accept()
transport = paramiko.Transport(client)
transport.load_server_moduli()
transport.add_server_key(key)
transport.set_subsystem_handler("sftp", paramiko.SFTPServer, paramiko.SFTPServerInterface)
event = threading.Event()
transport.start_server(server=ServerInterface(), event=event)
event.wait()
# Transport.server_accepts is empty
print "BEFORE transport.server_accepts =", transport.server_accepts
# Do work...
while transport.is_active():
time.sleep(1)
# later on after the Transport finishes, we notice Transport.server_accepts has a single entry
# to a closed channel holding a disconnected transport which leaks
print "AFTER transport.server_accepts =", transport.server_accepts
# Example output
# > python sftp-server-test.py
# listening...
# BEFORE transport.server_accepts = []
# auth foo
# AFTER transport.server_accepts = [<paramiko.Channel 1 (closed) -> <paramiko.Transport at 0x68273d50L (unconnected)>>]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment