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
SSH2: Decryption Failures During Read #1993
Comments
It's tricky because what's the point of setting a hard limit if you're gonna be all wishy washy about it? Consider the following scenario. You say "I'm gonna spend no more than $500 on food and that's it!" and then you find yourself at $498 for the month. If you're then like "I'm not at $500 yet so imma spend $30 at this restaurant!" then you're moving the goal post and it kinda calls into question your commitment. If your goal, from the get go, is to stop spending once you exceed $500 that'd be one thing but that wasn't the original goal in this scenario. In this case, however, we don't know how much money the restaurant is going to charge for the food. In-so-far as you know it's $30 or it could be $1,000 - you don't know. phpseclib doesn't know how much time it's going to take to receive the packet so if it just ignores the timeout until it's received the entire packet it could, in-so-far as it knows, take 1m for the server to send the rest of the packet, which seems suboptimal. Is there a reason you can't just increase the timeout? You couldn't set the timeout to 0 in phpseclib 3.0.36 but 3.0.37 fixed that. |
Your response to the quote you gave didn't add up for me. Perhaps you were responding to the paragraph above w.r.t. definition of the timeout parameter? It may make the most intuitive sense as a hard limit on execution time for Yes, we have increased the timeout to workaround the issue, but I would still like to use some timeout value and not allow calls to As it stands, the service quality of SSH2 degrades with the close of the timeout window, regardless of any positive timeout value that is used. As initially stated, I think you were right to introduce some timeout value on these previously unlimited There also does not seem to be good handling for when those If maintaining |
Sure, but I think there's a bit of a balancing act between perfection and good enough. The addition of
I guess I could add another |
Thanks for the continued replies. Interesting idea about If the former, I'm not sure the per-packet timeout is necessary. If the latter, then it seems the error potential remains, though is practically removed with sufficient packet timeout, albeit may be to hard to know what "sufficient" is. And since packet retrieval is dispersed across multiple However, it occurs to me that during Spitballing with this, but would it be possible/sane to maintain some sense of packet retrieval time across the ssh2 session and factor that metric into the packet timeout, thereby encapsulating the concern from the user and creating a dynamic behavior. |
Apologies for the delay - I've been vacationing. Anyway,
Neither - you'd just have more fine tuned control over when it's going to error under my proposal. So like if you did
You'd probably want a sliding scale for how close is too close. Like one packet took 9s and you want to timeout after 10s then it seems reasonable to assume that 1s won't be enough time to retrieve the second packet. BUT if you were getting a bunch of packets and each one took 0.1s to receive then having 1s left would still mean that you should, in theory, be able to receive 10 more packets. But even then, packets can take variable amounts of time to be sent. Like maybe you do |
True, though perhaps this scenario is less applicable to the
I mention all that in consideration still as to how to account for or avoid timeout errors which may arise during the multiple stream reads shown above, and which presently result in decrypt error and loss of the partially processed packet. I think now that |
I think your proposal could work but the behavior of I already presented a philosophical argument with my "I'm gonna spend no more than $500 on food and that's it!" from earlier but another reason to keep it is... You can set your alarm to (1) wake up you up at a specific time (eg. 8:00am or some such) or you could (2) have your phone monitor where you're at in your sleep cycle and wake up you up at the lightest point of your sleep cycle to minimize grogginess or whatever. (2) is probably superior to (1) for a narrow use case (eg. using an alarm to wake you up in the morning) but what about the use case where you're already awake and want to set an alarm because you you're walking your dog and need to wrap that up at 1:50pm so you can be ready for that 2:00pm Zoom meeting? I'm open to having alternate timeout implementations living beside one another but I'm not open to replacing one with another. |
Hello again!
In upgrading from 3.0.35 => 3.0.37, I've begun to see
SSH2
data decryption failures usingread()
, the cause of which I believe are related to commit 2fb6f31.The failures are intermittent but consistent enough, particularly in high latency environments with "chatty" servers. Through added logging, I observed
stream_set_timeout
within_get_binary_packet
invoked with smaller and smaller values, coinciding with the decreasingcur_timeout
allotted toread()
, <10,000 usec before erroring. Also just prior to erroring, I observed that the$tag
value within theaes128-gcm@openssh.com|aes256-gcm@openssh.com
decryption algorithm case was smaller than the requested block size of 16.I suspect that the diminishing stream timeout can become prohibitive to retrieving further stream contents necessary for decryption, arising from the multiple
stream_get_contents
invocations withindecrypt
processing.The intent behind commit 2fb6f31 seems sane though, which as best I can tell is to better honor the current timeout while processing packets.
I suppose a deciding factor here is whether the timeout represents a promise to return control to the caller within said time, or, more simply, a limit on time spent blocking. That'd inform whether the
SSH2
client should abandon packet processing upon timeout if the entire payload cannot be retrieved within the time frame, probably buffering read stream contents in the process, or allowing for some additional time spent blocking beyond the timeout to fully retrieve the payload, the prior behavior.Regardless, the decryption errors upon close of the timeout window should be avoided for well-formed packets.
The text was updated successfully, but these errors were encountered: