If (say) a read handle returns EOF, and its gotdata function responds
by calling handle_free(), then we want the handle to have already had
its defunct flag set so that the handle can be destroyed. Otherwise
handle_free will set the 'done' flag to ask the subthread to
terminate, and then sit and wait for it to say it's done so -
forgetting that it signalled termination already by returning EOF, and
hence will not be responding to that signal.
Ditto for write errors on write handles, though that should happen
less often.
The code for cleaning up handle structures works by the main thread
asking the per-handle subthread to shut down by means of setting its
'done' flag, and then once the subthread signals back through its
event object that it's done so, the main thread frees all its
resources and removes the event object from the list of things being
checked in the program's event loop.
But read threads were not sending back that final event acknowledging
a request to shut down, so their event objects were never being
cleaned up.
Bug spotted by Ronald Weiss.
It would be rare to have a host keypair in .ppk format or on a client
machine to load into PuTTYgen, and it might confuse people into thinking
they are required to do so.
It tries to use the local username as the remote username if it has no
better ideas, but the presence of Default Settings would defeat this,
even if it had no username set. Reported by Jonathan Amery.
We were checking the return value of CreateThread for validity, but
not keeping it to free afterwards if it _was_ valid. Also, we weren't
closing ctx->event in the valid case either. Patch due to Tim Kosse.
If we use getaddrinfo to translate the source IP address into a
sockaddr, then we need to freeaddrinfo the returned data later. Patch
due to Tim Kosse.
I don't think anyone has ever actually called it that, colloquially
_or_ formally, and if anyone ever did (in a bug report, say) I'd
probably have to stop and think to work out what they meant. It's
universally called Plink, and should be officially so as well :-)
This one spotted in the old-fashioned way, by actually attempting a
Plink raw connection and wondering why it didn't seem to be reading
from standard input! Turns out 'bufsize' is uninitialised until the
first send, which can inhibit any stdin reading if it gets a large
enough nonsense value.
mkfiles.pl was giving a couple of annoying perl warnings, because some
makefile_extra strings were never set by Recipe. We already have the
&def function to convert undefs into "" for this reason, but weren't
using it everywhere. Now I think we are.
If a sharing downstream asks for an auth method we don't understand,
we should send them CHANNEL_FAILURE *and then stop processing*. Ahem.
(Spotted while examining this code in the course of Coverity-related
fixes, but not itself a Coverity-found problem.)
If (Msg)WaitForMultipleObjects returns WAIT_TIMEOUT, we expect 'next'
to have been initialised. This can occur without having called
run_timers(), if a toplevel callback was pending, so we can't expect
run_timers to have reliably initialised 'next'.
I'm not actually convinced this could have come up in either of the
affected programs (Windows PSFTP and Plink), due to the list of things
toplevel callbacks are currently used for, but it certainly wants
fixing anyway for the future.
Spotted by Coverity.
Namely, any ldisc that you send actual data through should have a
terminal attached, because the ldisc editing/echoing system is
designed entirely for use with a terminal. The only time you can have
an ldisc with no terminal is when it's only ever used by the backend
to report changes to the front end in edit/echo status, e.g. by Unix
Plink.
Coverity spotted an oddity in ldisc_send which after a while I decided
would never have actually caused a problem, but OTOH I agree that it
was confusing, so now hopefully it's less so.
'p += strcspn' returns p always non-NULL and sometimes pointing at \0,
as opposed to 'p = strchr' which returns p sometimes non-NULL and
never pointing at \0. Test the pointer after the call accordingly.
Thanks, Coverity.
This ought to happen in ssh_do_close alongside the code that shuts
down other local listening things like port forwardings, for the same
obvious reason. In particular, we should get through this _before_ we
put up a modal dialog box telling the user what just went wrong with
the SSH connection, so that further sessions started while that box is
active don't try futilely to connect to the not-really-listening
zombie upstream.
Changing it can't have any useful effect, since we have strictly
enforced that the host key used for rekeys is the same as the first key
exchange since b8e668c.
We should NULL out mac after freeing it, so that the cleanup code
doesn't try to free it again; also if the final key creation fails, we
should avoid freeing ret->comment when we're going to go to that same
cleanup code which will free 'comment' which contains the same pointer.
Thanks to Christopher Staite for pointing these out.
It became bash-dependent in r9229 because I used a bashism to remove
the 'r' from the front of $SVN_REV, but that's not needed any more.
[originally from svn r10281]
[r9229 == bd60f2fc5b]
The symbol alphabet used for encoding ranges of backward distances in
a Deflate compressed block contains 32 symbol values, but two of them
(symbols 30 and 31) have no meaning, and hence it is an encoding error
for them to appear in a compressed block. If a compressed file did so
anyway, this decompressor would index past the end of the distcodes[]
array. Oops.
This is clearly a bug, but I don't believe it's a vulnerability. The
nonsense record we load from distcodes[] in this situation contains an
indeterminate bogus value for 'extrabits' (how many more bits to read
from the input stream to complete the backward distance) and also for
the offset to add to the backward distance after that. But neither of
these can lead to a buffer overflow: if extrabits is so big that
dctx->nbits (which is capped at 32) never exceeds it, then the
decompressor will simply swallow all further data without producing
any output, and otherwise the decompressor will consume _some_ number
of spare bits from the input, work out a backward distance and an
offset in the sliding window which will be utter nonsense and probably
out of bounds, but fortunately will then AND the offset with 0x7FFF at
the last minute, which makes it safe again. So I think the worst that
a malicious compressor can do is to cause the decompressor to generate
strange data, which of course it could do anyway if it wanted to by
sending that same data legally compressed.
[originally from svn r10278]
I've shifted away from using the SVN revision number as a monotonic
version identifier (replacing it in the Windows version resource with
a count of days since an arbitrary epoch), and I've removed all uses
of SVN keyword expansion (replacing them with version information
written out by Buildscr).
While I'm at it, I've done a major rewrite of the affected code which
centralises all the computation of the assorted version numbers and
strings into Buildscr, so that they're all more or less alongside each
other rather than scattered across multiple source files.
I've also retired the MD5-based manifest file system. A long time ago,
it seemed like a good idea to arrange that binaries of PuTTY would
automatically cease to identify themselves as a particular upstream
version number if any changes were made to the source code, so that if
someone made a local tweak and distributed the result then I wouldn't
get blamed for the results. Since then I've decided the whole idea is
more trouble than it's worth, so now distribution tarballs will have
version information baked in and people can just cope with that.
[originally from svn r10262]
The winegcc hack I use for my Coverity builds is currently using a
version of wincrypt.h that's missing a couple of constants I use.
Ensure they're defined by hand, but (just in case I defined them
_wrong_) also provide a command-line define so I can do that only in
the case of Coverity builds.
[originally from svn r10234]