Re: Albrecht/Paterson/Watson's attack
Mouse <[email protected]>
| Newsgroups | gmane.ietf.secsh |
|---|---|
| Message-ID | <[email protected]> |
>> moussh does not yet include this defense [partial IGNORE packets]; I >> found it remarkably difficult to do. > I have some code to do this [...]. I have a "push" flag for the > functions to encrypt and send of an ssh package. Packets without > this flag is buffered. When the buffered data exceeds a reasonable > packet size, I send the packet out with no extra ignore message. > If the push flag is set, the packet is sent regardless of the amount > of buffered data, and an extra ignore message is appended to the > buffer. Vastly different internal architecture. My code sends packets by encrypting them and appending to an output queue. There's a separate work procedure (a little like a thread without a stack) that writes from the output queue. In this paradigm, the connection going idle amounts to the output queue draining completely. But, in order for something to be written in the same writev() as the output queue, it has to be ready to be written. But that means running it through the crypto, consuming key material. Since I have no way of telling how much is writable at any given moment (even postulating a call that asks that could fail because the answer could change between query and writev), I can't tell whether the writev() will drain the queue (and I thus want a partial IGNORE packet there) or not (in which case I don't). So I'd have to always append it - but then, to avoid a zillion unnecesasry IGNOREs, I'd need the ability to retract it if no part of it actually gets written. That's where it gets interesting. I could extend the output queue to store a possible IGNORE separately, but that wouldn't help because it has to be encrypted in sequence with the packets on either side of it, which would change (potentially) each time around. I could store it in the clear, but I have no way to tell whether I need to encrypt it; there's no way for writev() to tell me whether it wants more data in a way that lets me compute before providing it. Of course, the output queue draining in userland is not the same as the TCP output queue draining. I'd rather drive it off the latter, but there's no easy way to do that; for most purposes, the userland queue draining is a good enough approximation. I might be able to add something like your `push' flag, but it's not clear to me when I should set it. It sounds to me as though your paradigm will insert IGNOREs at certain points in the output stream even if the connectino _isn't_ going idle - correct? I need to think about this more. I may need a redesign, or I may come up with a clean way to do the crypto rollback, or who knows.... /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML [email protected] / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B