lp://qastaging/~vcs-imports/putty/master

Created by Colin Watson and last modified
Get this branch:
bzr branch lp://qastaging/~vcs-imports/putty/master

Branch merges

Related bugs

Related blueprints

Branch information

Owner:
VCS imports
Project:
PuTTY
Status:
Development

Import details

Import Status: Suspended

This branch is an import of the HEAD branch of the Git repository at git://git.tartarus.org/simon/putty.git.

Last successful import was .

Import started on juju-98ee42-prod-launchpad-codeimport-1 and finished taking 20 seconds — see the log
Import started on juju-98ee42-prod-launchpad-codeimport-0 and finished taking 15 seconds — see the log
Import started on juju-98ee42-prod-launchpad-codeimport-5 and finished taking 20 seconds — see the log
Import started on juju-98ee42-prod-launchpad-codeimport-4 and finished taking 15 seconds — see the log
Import started on juju-98ee42-prod-launchpad-codeimport-4 and finished taking 20 seconds — see the log
Import started on juju-98ee42-prod-launchpad-codeimport-3 and finished taking 15 seconds — see the log
Import started on juju-98ee42-prod-launchpad-codeimport-2 and finished taking 15 seconds — see the log
Import started on juju-98ee42-prod-launchpad-codeimport-2 and finished taking 15 seconds — see the log
Import started on juju-98ee42-prod-launchpad-codeimport-1 and finished taking 20 seconds — see the log
Import started on juju-98ee42-prod-launchpad-codeimport-1 and finished taking 30 seconds — see the log

Recent revisions

6974. By Jacob Nevins <email address hidden>

FAQ: add link from faq-hostkeys to '-hostkey' docs.

6973. By Simon Tatham

Fix pointer-handling bug in write_random_seed().

Thanks to Joshua Rogers for the report: if writing the random seed
took more than one call to write(2), then we'd add the wrong value to
the data pointer between calls. Happily this is very unlikely to have
actually happened, because random seed files are tiny and surely
write() will in practice manage to write it all first time. But still
needs fixing.

6972. By Simon Tatham

Add a FAQ about LLM usage, or rather, the lack thereof.

It was asked this week, and I fear it won't be the last time.

6971. By Simon Tatham

udp.but: fix braino in example function names.

Two of the wrapper functions in my example 'trait' had names
appropriate to the implementation functions for a particular concrete
type. Probably copy-paste with inadequate editing while I was writing
it.

6970. By Simon Tatham

FAQ: update website/hosting/forges section.

The question about a nicer domain name, with answer "we don't want
one", is very out of date now that we actually have one! Also, the
section about putty.org wants updating after the recent drama. While I
was there I decided the Sourceforge question was too old to live, and
replaced it with some more up-to-date thoughts about forges in general
and Github in particular.

The new question faq-putty-org-pivot ("putty.org became weird kookery,
have you been hacked or bought out?") is frequently asked in the sense
that I've seen it twice in the past week or two: once in email, and
once on Mastodon (though someone quickly posted the right answer in
response).

While I'm here, it seems a bit pointless these days for faq-link to
explain the Google pagerank system to everyone. It's been a long time
since Google Search was new enough that it needed explaining, and in
any case, I've no idea if it's still accurate any more!

6969. By Simon Tatham

Makefile rules for icons used on putty.software.

Various web design guidelines asked for an assortment of larger sizes
of PNG to link to in various ways, with and without transparency.

6968. By Simon Tatham

HTTP proxy digest auth: tolerate multiple qop options.

We were rejecting any 'Proxy-Authenticate: Digest' header from the
proxy if the 'qop' setting was not exactly the string "auth", which is
the only quality of protection that this code supports. However 'qop'
is supposed to be a _list_ of possibilities, so we should also be
happy if the proxy presents a list of more than one option, as long as
"auth" is one of them.

6967. By Simon Tatham

Windows: fix stale-netevent problem in the CLI tools.

This fixes in the CLI tools – Plink and friends – the same bug fixed
by the recent commit bb8894ff12f9175: if an HTTP proxy demands
authentication via a 407 response with Connection: close, then PuTTY
immediately makes a second connection to the proxy, which (often)
reuses the same socket id at the Win32 API layer, and then a lingering
activity notification for the previous socket confuses the handling of
the new one.

My entire diagnosis and fix in the previous commit were completely
derived from reasoning about window message queues and WSAAsyncSelect,
so I jumped to the conclusion that the problem would be specific to
the GUI tools, which are the ones that _use_ WSAAsyncSelect. But I
didn't actually test with Plink. When I did, it turns out that for a
completely different reason, cliloop.c has an isomorphic bug, causing
the same symptom by a different route.

In the CLI tools, instead of WSAAsyncSelect, we use WSAEventSelect, in
which Windows signals an event object when socket activity happens. We
respond by calling WSAEnumNetworkEvents, which tells us what kind of
activity it was, as a bitmap of FD_READ, FD_WRITE, FD_CLOSE etc. Then
we iterate over those bits in a particular order, processing each one
with a call to select_result().

In this case, the problem wasn't anything lingering in a _queue_. It
was simply that we call select_result() to process an FD_READ
notification for the socket, which closes the socket and makes a new
one, and then select_result() returns to the for-loop which is still
iterating over the bit mask returned from WSAEnumNetworkEvents, so in
the next loop iteration it tries to process the FD_CLOSE notification
for the old socket, not realising that the socket went away in the
meantime.

I've fixed this by the brute-force technique of moving all the
select_result calls out of the for-loop completely. Now cliloop.c does
the same thing as select-gui.c: it schedules each instance of handling
socket activity as a toplevel callback, and the callbacks don't
actually _happen_ until we've completely finished handling the
signalled event object. So now, when we're handling FD_READ and still
have FD_CLOSE left in a queue somewhere, the queue is the toplevel
callback system instead of a for-loop further up the call stack – and
that means we can clear the queue via delete_callbacks() in the same
way that the previous commit did it for the GUI tools.

# This is the commit message #2:

# fixup! Windows: fix stale-netevent problem in the CLI tools.

6966. By Simon Tatham

Windows: fix memory leak in the stale-netevent fix.

When we delete toplevel callbacks for a defunct socket, we must also
free the tiny parameter structure we allocated for each one.

6965. By Simon Tatham

Windows: clear pending netevents when closing a socket.

I hope that this fixes http-proxy-auth-wsaenotconn, although I've only
tested it on a hacked-up Python tool that mimics a web proxy only far
enough to reproduce the issue, and haven't confirmed a successful
connection through a working HTTP proxy.

Background: the GUI network tools (both PuTTY and Pageant – anything
that links with select-gui.c) use the WSAAsyncSelect method of
reporting socket activity, which sends a window message to a nominated
HWND when activity happens on a socket. When we receive one of those
messages, we don't handle it synchronously in WndProc: instead we
queue a toplevel callback, and deal with the network activity when the
callbacks are next run from the main loop.

This means that when we _close_ a socket, there are two possible
places where unhandled notifications for the old socket might still be
lurking around. They might be in our window's message queue waiting
for GetMessage to retrieve them, or they might have been moved from
there into the toplevel callback queue.

Either way, this is a source of potential bugs, because WinSock
eagerly reuses numeric socket IDs: it's entirely possible in practice
to close a socket, immediately open another one, and find the new
socket has reused the old one's ID. Then those unhandled notifications
don't just refer to a nonexistent socket any more: instead, they
misleadingly look as if they refer to the _new_ socket, and cause
bugs.

The case of this that comes up in practice, described in
http-proxy-auth-wsaenotconn, involves an HTTP proxy sending a 407
Proxy Authentication Required response with Connection: close. In that
situation, PuTTY wants to try again with authentication, but since
that TCP connection is going away, it must make a fresh connection to
the proxy for the retry. So it does close the socket and open a new
one within the same event handler, and the old socket ID is often
reused for the new socket, and a lingering FD_CLOSE notification from
the old socket causes PuTTY to incorrectly believe that the proxy has
slammed the _new_ connection shut.

According to my diagnostics, this particular FD_CLOSE notification
generally seems to have been moved from the window message queue into
a pending toplevel callback. But the other failure mode is possible in
principle too – perhaps more likely in cases where you close a socket
in response to some other window message. So we should deal with both.

In this commit, I deal with stale toplevel callbacks by using the new
delete_callbacks() function introduced in the previous commit, which
takes a predicate function to decide whether to delete each callback.
That lets me distinguish WM_NETEVENT callbacks citing a particular
socket.

Dealing with stale window messages is harder, because as far as I can
tell, there's no Win32 API to trawl the message queue deleting a
subset of messages of this kind. (GetMessage and PeekMessage both have
wMsgFilterMin and wMsgFilterMax parameters which can filter by the
message type, but to narrow down to just one socket, we would also
need to filter on wParam, and there's no call for that.)

So instead I do a nasty bodge. Wherever we call closesocket(),
select-gui.c posts itself a new custom message WM_DONE_WITH_SOCKET,
which goes on to the end of the message queue, and acts as a dividing
line. Any WM_NETEVENT seen for that socket id _before_
WM_DONE_WITH_SOCKET was already in the queue at the time we called
closesocket(), and therefore refers to the old socket and should be
ignored; but WM_NETEVENTs for the same id _after_ WM_DONE_WITH_SOCKET
must refer to some new socket reusing the id, and should be handled
normally. So select-gui.c keeps a tree234 of "moribund" socket ids:
ones for which we've posted a WM_DONE_WITH_SOCKET message to ourself
but not yet got it back, and therefore, until we do, WM_NETEVENTs
should be ignored.

Branch metadata

Branch format:
Branch format 7
Repository format:
Bazaar repository format 2a (needs bzr 1.16 or later)
This branch contains Public information 
Everyone can see this information.

Subscribers