[project @ Arch-1:robey@lag.net--2005-master-shake%paramiko--dev--1--patch-64]

track channels seen and throw away (without error) messages bound for nonexistent channels that *used* to exist -- fixes a bug found by gordon good
This commit is contained in:
Robey Pointer 2005-10-13 18:51:18 +00:00
parent 7f9677d5ab
commit 8bb5e65499
1 changed files with 25 additions and 15 deletions

View File

@ -20,22 +20,28 @@
L{Transport} handles the core SSH2 protocol. L{Transport} handles the core SSH2 protocol.
""" """
import sys, os, string, threading, socket, struct, time import os
import socket
import string
import struct
import sys
import threading
import time
import weakref import weakref
from common import * from paramiko.common import *
from ssh_exception import SSHException, BadAuthenticationType from paramiko import util
from message import Message from paramiko.ssh_exception import SSHException, BadAuthenticationType
from channel import Channel from paramiko.message import Message
from sftp_client import SFTPClient from paramiko.channel import Channel
import util from paramiko.sftp_client import SFTPClient
from packet import Packetizer from paramiko.packet import Packetizer
from rsakey import RSAKey from paramiko.rsakey import RSAKey
from dsskey import DSSKey from paramiko.dsskey import DSSKey
from kex_group1 import KexGroup1 from paramiko.kex_group1 import KexGroup1
from kex_gex import KexGex from paramiko.kex_gex import KexGex
from primes import ModulusPack from paramiko.primes import ModulusPack
from auth_handler import AuthHandler from paramiko.auth_handler import AuthHandler
# these come from PyCrypt # these come from PyCrypt
# http://www.amk.ca/python/writing/pycrypt/ # http://www.amk.ca/python/writing/pycrypt/
@ -235,6 +241,7 @@ class Transport (threading.Thread):
self.lock = threading.Lock() # synchronization (always higher level than write_lock) self.lock = threading.Lock() # synchronization (always higher level than write_lock)
self.channels = weakref.WeakValueDictionary() # (id -> Channel) self.channels = weakref.WeakValueDictionary() # (id -> Channel)
self.channel_events = { } # (id -> Event) self.channel_events = { } # (id -> Event)
self.channels_seen = { } # (id -> True)
self.channel_counter = 1 self.channel_counter = 1
self.window_size = 65536 self.window_size = 65536
self.max_packet_size = 32768 self.max_packet_size = 32768
@ -582,6 +589,7 @@ class Transport (threading.Thread):
m.add_int(src_addr[1]) m.add_int(src_addr[1])
self.channels[chanid] = chan = Channel(chanid) self.channels[chanid] = chan = Channel(chanid)
self.channel_events[chanid] = event = threading.Event() self.channel_events[chanid] = event = threading.Event()
self.channels_seen[chanid] = True
chan._set_transport(self) chan._set_transport(self)
chan._set_window(self.window_size, self.max_packet_size) chan._set_window(self.window_size, self.max_packet_size)
self._send_user_message(m) self._send_user_message(m)
@ -963,7 +971,6 @@ class Transport (threading.Thread):
raise raise
try: try:
def handler(title, instructions, fields): def handler(title, instructions, fields):
self._log(DEBUG, 'title=%r, instructions=%r, fields=%r' % (title, instructions, fields))
if len(fields) > 1: if len(fields) > 1:
raise SSHException('Fallback authentication failed.') raise SSHException('Fallback authentication failed.')
if len(fields) == 0: if len(fields) == 0:
@ -1264,6 +1271,8 @@ class Transport (threading.Thread):
chanid = m.get_int() chanid = m.get_int()
if self.channels.has_key(chanid): if self.channels.has_key(chanid):
self._channel_handler_table[ptype](self.channels[chanid], m) self._channel_handler_table[ptype](self.channels[chanid], m)
elif self.channels_seen.has_key(chanid):
self._log(DEBUG, 'Ignoring message for dead channel %d' % chanid)
else: else:
self._log(ERROR, 'Channel request for unknown channel %d' % chanid) self._log(ERROR, 'Channel request for unknown channel %d' % chanid)
self.active = False self.active = False
@ -1666,6 +1675,7 @@ class Transport (threading.Thread):
try: try:
self.lock.acquire() self.lock.acquire()
self.channels[my_chanid] = chan self.channels[my_chanid] = chan
self.channels_seen[my_chanid] = True
chan._set_transport(self) chan._set_transport(self)
chan._set_window(self.window_size, self.max_packet_size) chan._set_window(self.window_size, self.max_packet_size)
chan._set_remote_channel(chanid, initial_window_size, max_packet_size) chan._set_remote_channel(chanid, initial_window_size, max_packet_size)