simon-git: putty (main): Simon Tatham

Commits to Tartarus hosted VCS tartarus-commits at lists.tartarus.org
Sat Jul 26 11:20:32 BST 2025


TL;DR:
  0c5fd787 GTK: stop using GDK_CURRENT_TIME.
  edce58d4 HTTP proxy: fix misspelled error message (and comment).
  b7db1869 More general function to delete toplevel callbacks.
  bb8894ff Windows: clear pending netevents when closing a socket.

Repository:     https://git.tartarus.org/simon/putty.git
On the web:     https://git.tartarus.org/?p=simon/putty.git
Branch updated: main
Committer:      Simon Tatham <anakin at pobox.com>
Date:           2025-07-26 11:20:32

commit 0c5fd787135608dc55cc13418ef37cc00236ed64
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=0c5fd787135608dc55cc13418ef37cc00236ed64;hp=26a8ef376daf5f50c441a65691b84f87df49db9b
Author: Simon Tatham <anakin at pobox.com>
Date:   Thu Jul 24 08:18:10 2025 +0100

    GTK: stop using GDK_CURRENT_TIME.
    
    gtk_get_current_event_time() is better: it returns the X server
    timestamp associated with any event currently being handled. And if
    there isn't one, it falls back to returning GDK_CURRENT_TIME, so it
    doesn't do any worse than hardcoding GDK_CURRENT_TIME did.

 unix/askpass.c   | 8 ++++----
 unix/dialog.c    | 2 +-
 unix/gtkcompat.h | 1 +
 3 files changed, 6 insertions(+), 5 deletions(-)

commit edce58d49dfa17586b2f407fd668dd4dcc41496b
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=edce58d49dfa17586b2f407fd668dd4dcc41496b;hp=0c5fd787135608dc55cc13418ef37cc00236ed64
Author: Simon Tatham <anakin at pobox.com>
Date:   Sat Jul 26 09:59:55 2025 +0100

    HTTP proxy: fix misspelled error message (and comment).
    
    A 407 response from the proxy is expected to contain at least one
    header naming an acceptable authentication method. The header name is
    "Proxy-Authenticate". But if no such header is seen, our error message
    incorrectly spelled the missing header name as "Proxy-Authorization".
    
    That's a braino rather than a typo: "Proxy-Authorization" is the
    header the _client_ sends for an actual attempt to authenticate.

 proxy/http.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

commit b7db18690b518dc0e9d668bb50c81b485ea449ba
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=b7db18690b518dc0e9d668bb50c81b485ea449ba;hp=edce58d49dfa17586b2f407fd668dd4dcc41496b
Author: Simon Tatham <anakin at pobox.com>
Date:   Fri Jul 25 08:28:53 2025 +0100

    More general function to delete toplevel callbacks.
    
    For cases where you want a more subtle criterion than "cites this
    particular context structure". I'm going to introduce one in the next
    commit.

 callback.c | 21 +++++++++++++++++----
 putty.h    |  3 +++
 2 files changed, 20 insertions(+), 4 deletions(-)

commit bb8894ff12f9175d8ebc2c0efe2b56a72f091878
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=bb8894ff12f9175d8ebc2c0efe2b56a72f091878;hp=b7db18690b518dc0e9d668bb50c81b485ea449ba
Author: Simon Tatham <anakin at pobox.com>
Date:   Thu Jul 24 08:36:36 2025 +0100

    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.

 windows/network.c    | 22 ++++++++++++++--------
 windows/pageant.c    |  3 ++-
 windows/platform.h   |  6 ++++--
 windows/select-cli.c |  4 ++++
 windows/select-gui.c | 39 ++++++++++++++++++++++++++++++++++++++-
 windows/window.c     |  3 ++-
 6 files changed, 64 insertions(+), 13 deletions(-)



More information about the tartarus-commits mailing list