1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00
Commit Graph

34 Commits

Author SHA1 Message Date
Simon Tatham
f7adf7bca0 Fix a few 'triple letter in place of double' typos.
A user wrote in to point out the one in winhandl.c, and out of sheer
curiosity, I grepped the whole source base for '([a-zA-Z])\1\1' to see
if there were any others. Of course there are a lot of perfectly
sensible ones, like 'www' or 'Grrr', not to mention any amount of
0xFFFF and the iiii/bbbb emphasis system in Halibut code paragraphs,
but I did spot one more in the recently added udp.but section on
traits, and another in a variable name in uxagentsock.c.
2021-01-17 09:18:42 +00:00
Simon Tatham
5d718ef64b Whitespace rationalisation of entire code base.
The number of people has been steadily increasing who read our source
code with an editor that thinks tab stops are 4 spaces apart, as
opposed to the traditional tty-derived 8 that the PuTTY code expects.

So I've been wondering for ages about just fixing it, and switching to
a spaces-only policy throughout the code. And I recently found out
about 'git blame -w', which should make this change not too disruptive
for the purposes of source-control archaeology; so perhaps now is the
time.

While I'm at it, I've also taken the opportunity to remove all the
trailing spaces from source lines (on the basis that git dislikes
them, and is the only thing that seems to have a strong opinion one
way or the other).
    
Apologies to anyone downstream of this code who has complicated patch
sets to rebase past this change. I don't intend it to be needed again.
2019-09-08 20:29:21 +01:00
Simon Tatham
e0a76971cc New array-growing macros: sgrowarray and sgrowarrayn.
The idea of these is that they centralise the common idiom along the
lines of

   if (logical_array_len >= physical_array_size) {
       physical_array_size = logical_array_len * 5 / 4 + 256;
       array = sresize(array, physical_array_size, ElementType);
   }

which happens at a zillion call sites throughout this code base, with
different random choices of the geometric factor and additive
constant, sometimes forgetting them completely, and generally doing a
lot of repeated work.

The new macro sgrowarray(array,size,n) has the semantics: here are the
array pointer and its physical size for you to modify, now please
ensure that the nth element exists, so I can write into it. And
sgrowarrayn(array,size,n,m) is the same except that it ensures that
the array has size at least n+m (so sgrowarray is just the special
case where m=1).

Now that this is a single centralised implementation that will be used
everywhere, I've also gone to more effort in the implementation, with
careful overflow checks that would have been painful to put at all the
previous call sites.

This commit also switches over every use of sresize(), apart from a
few where I really didn't think it would gain anything. A consequence
of that is that a lot of array-size variables have to have their types
changed to size_t, because the macros require that (they address-take
the size to pass to the underlying function).
2019-02-28 20:15:38 +00:00
Simon Tatham
bc1aa9c656 Add BinarySink wrappers on existing forms of output.
There's now a stdio_sink, whose write function calls fwrite on the
given FILE *; a bufchain_sink, whose write function appends to the
given bufchain; and on Windows there's a handle_sink whose write
function writes to the given 'struct handle'. (That is, not the raw
Windows HANDLE, but our event-loop-friendly wrapper on it.)

Not yet used for anything, but they're about to be.
2019-02-20 07:27:13 +00:00
Simon Tatham
59f7b24b9d Make bufchain_prefix return a ptrlen.
Now that all the call sites are expecting a size_t instead of an int
length field, it's no longer particularly difficult to make it
actually return the pointer,length pair in the form of a ptrlen.

It would be nice to say that simplifies call sites because those
ptrlens can all be passed straight along to other ptrlen-consuming
functions. Actually almost none of the call sites are like that _yet_,
but this makes it possible to move them in that direction in future
(as part of my general aim to migrate ptrlen-wards as much as I can).
But also it's just nicer to keep the pointer and length together in
one variable, and not have to declare them both in advance with two
extra lines of boilerplate.
2019-02-06 21:46:10 +00:00
Simon Tatham
0cda34c6f8 Make lots of 'int' length fields into size_t.
This is a general cleanup which has been overdue for some time: lots
of length fields are now the machine word type rather than the (in
practice) fixed 'int'.
2019-02-06 21:46:10 +00:00
Simon Tatham
f60fe670ad handle_{got,sent}data: separate length and error params.
Now we pass an error code in a separate dedicated parameter, instead
of overloading the length parameter so that a negative value means an
error code. This enables length to become unsigned without causing
trouble.
2019-02-06 21:46:10 +00:00
Simon Tatham
5087792440 Label random-noise sources with an enum of ids.
The upcoming PRNG revamp will want to tell noise sources apart, so
that it can treat them all fairly. So I've added an extra parameter to
noise_ultralight and random_add_noise, which takes values in an
enumeration covering all the vague classes of entropy source I'm
collecting. In this commit, though, it's simply ignored.
2019-01-23 22:36:17 +00:00
Simon Tatham
76aa3f6f7a Add more random-number noise collection calls.
Mostly on the Unix side: there are lots of places the Windows code was
collecting noise that the corresponding Unix/GTK code wasn't bothering
to, such as mouse movements, keystrokes and various network events.
Also, both platforms had forgotten to collect noise when reading data
from a pipe to a local proxy process, even though in that
configuration that's morally equivalent to the network packet timings
that we'd normally be collecting from.
2019-01-23 22:36:17 +00:00
Simon Tatham
3214563d8e Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.

PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.

I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!

To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.

In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
 - the 'multisel' field in dialog.h's list box structure, for which
   the GTK front end in particular recognises a difference between 1
   and 2 but nearly everything else treats as boolean
 - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
   something about the specific location of the urgent pointer, but
   most clients only care about 0 vs 'something nonzero'
 - the return value of wc_match, where -1 indicates a syntax error in
   the wildcard.
 - the return values from SSH-1 RSA-key loading functions, which use
   -1 for 'wrong passphrase' and 0 for all other failures (so any
   caller which already knows it's not loading an _encrypted private_
   key can treat them as boolean)
 - term->esc_query, and the 'query' parameter in toggle_mode in
   terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
   but can also hold -1 for some other intervening character that we
   don't support.

In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
 - the return value of plug_accepting uses the POSIXish convention of
   0=success and nonzero=error; I think if I made it bool then I'd
   also want to reverse its sense, and that's a job for a separate
   piece of work.
 - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
   represent the default and alternate screens. There's no obvious
   reason why one of those should be considered 'true' or 'positive'
   or 'success' - they're just indices - so I've left it as int.

ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.

In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.

Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-03 13:45:00 +00:00
Simon Tatham
a6f1709c2f Adopt C99 <stdbool.h>'s true/false.
This commit includes <stdbool.h> from defs.h and deletes my
traditional definitions of TRUE and FALSE, but other than that, it's a
100% mechanical search-and-replace transforming all uses of TRUE and
FALSE into the C99-standardised lowercase spellings.

No actual types are changed in this commit; that will come next. This
is just getting the noise out of the way, so that subsequent commits
can have a higher proportion of signal.
2018-11-03 13:45:00 +00:00
Simon Tatham
13d52fcb03 Fix an EOF-testing goof in winhandl.c.
I was having a play with clang's MSVC compatibility mode, just to see
how much of PuTTY it could compile, and one of its warnings pointed
out this error which must have crept in when I was changing the EOF
flags in winhandl.c from booleans to three-state enums - I left the !
on the front of what was previously an if (!thing) and needed to turn
into if (thing == EOF_NO).
2017-02-03 19:33:50 +00:00
Simon Tatham
431f8db862 Fix winhandl.c's failure to ever free a foreign handle.
Handles managed by winhandl.c have a 'busy' flag, which is used to
mean two things: (a) is a subthread currently blocked on this handle
so various operations in the main thread have to be deferred until it
finishes? And (b) is this handle currently one that should be returned
to the main loop to be waited for?

For HT_INPUT and HT_OUTPUT, those things are either both true or both
false, so a single flag covering both of them is fine. But HT_FOREIGN
handles have the property that they should always be waited for in the
main loop, but no subthread is blocked on them. The latter means that
operations done on them in the main thread should not be deferred; the
only such operation is cleaning them up in handle_free().

handle_free() was failing to spot this, and was deferring freeing
HT_FOREIGN handles until their subthread terminated - which of course
never happened. As a result, when a named pipe server was closed, its
actual Windows event object got destroyed, but winhandl.c still kept
passing it back to the main thread, leading to a tight loop because
MsgWaitForMultipleObjects would return ERROR_INVALID_HANDLE and never
block.
2015-09-25 16:03:47 +01:00
Tim Kosse
f2e61275f2 Cast pointers to uintptr_t instead of unsigned {long,int}.
On 64bit Windows, pointers are 64bit whereas both unsigned long and
unsigned int are 32bit. Using uintptr_t avoids truncation.
2015-08-15 13:54:46 +01:00
Simon Tatham
9fec2e7738 Fix a dangerous cross-thread memory access.
When a winhandl.c input thread returns EOF to the main thread, the
latter might immediately delete the input thread's context. I
carefully wrote in a comment that in that case we had to not touch ctx
ever again after signalling to the main thread - but the test for
whether that was true, which also touched ctx, itself came _after_ the
SetEvent which sent that signal. Ahem.

Spotted by Minefield, which it looks as if I haven't run for a while.
2015-04-07 22:17:08 +01:00
Simon Tatham
a87a14ae0f Improve comments in winhandl.c.
To understand the handle leak bug that I fixed in git commit
7549f2da40, I had to think fairly hard
to remind myself what all this code was doing, which means the
comments weren't good enough. Expanded and rewritten some of them in
the hope that things will be clearer next time.
2015-02-07 12:50:37 +00:00
Simon Tatham
087ca595f3 Mark handles defunct before calling gotdata/sentdata.
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.
2015-02-07 12:50:08 +00:00
Simon Tatham
7549f2da40 Fix handle leak in winhandl.c.
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.
2015-02-07 12:50:03 +00:00
Simon Tatham
c0f7178f63 Rename the handle-type enumeration values.
Mike Edenfield points out that modern versions of the Windows SDK have
decided that 'INPUT' is a sensible name for an OS data structure
(sigh), and provided a patch to add a disambiguating prefix to
winhandl.c's enum values INPUT, OUTPUT and FOREIGN.

[originally from svn r10109]
2014-01-07 23:26:10 +00:00
Simon Tatham
1b3edafcff Add support for Windows named pipes.
This commit adds two new support modules, winnpc.c and winnps.c, which
deal respectively with being a client and server of a Windows named
pipe (which, in spite of what Unix programmers will infer from that
name, is actually closer to Windows's analogue of a Unix-domain
socket). Each one provides a fully featured Socket wrapper around the
hairy Windows named pipe API, so that the rest of the code base should
be able to use these interchangeably with ordinary sockets and hardly
notice the difference.

As part of this work, I've introduced a mechanism in winhandl.c to
permit it to store handles of event objects on behalf of other Windows
support modules and deal with passing them to applications' main event
loops as necessary. (Perhaps it would have been cleaner to split
winhandl.c into an event-object tracking layer analogous to uxsel, and
the handle management which is winhandl.c's proper job, but this is
less disruptive for the present.)

[originally from svn r10069]
2013-11-17 14:04:01 +00:00
Simon Tatham
947962e0b9 Revamp of EOF handling in all network connections, pipes and other
data channels. Should comprehensively fix 'half-closed', in principle,
though it's a big and complicated change and so there's a good chance
I've made at least one mistake somewhere.

All connections should now be rigorous about propagating end-of-file
(or end-of-data-stream, or socket shutdown, or whatever) independently
in both directions, except in frontends with no mechanism for sending
explicit EOF (e.g. interactive terminal windows) or backends which are
basically always used for interactive sessions so it's unlikely that
an application would be depending on independent EOF (telnet, rlogin).

EOF should now never accidentally be sent while there's still buffered
data to go out before it. (May help fix 'portfwd-corrupt', and also I
noticed recently that the ssh main session channel can accidentally
have MSG_EOF sent before the output bufchain is clear, leading to
embarrassment when it subsequently does send the output).

[originally from svn r9279]
2011-09-13 11:44:03 +00:00
Simon Tatham
201c2c295b Patch from Gert-Jan Vons: create an event handle to go in the
OVERLAPPED structure in output threads, as we already do for input
threads. This apparently sorts out a hanging issue with serial ports
when trying to do simultaneous read and write, because (GJV says,
and it sounds plausible to me) in the absence of that event object
Windows signals the file handle itself to notify GetOverlappedResult
that it can return - and since the file handle might be being
signalled by a read operation instead, that leads to ambiguity.
Using an explicit event object in both directions means Windows
always knows which way the data is going.

Also a trivial fix in handle_output_new(), which was referencing the
wrong element of a union due to a copy and paste error. (Since the
result was address-taken and cast to void *, this wasn't a
functional error, but it was conceptually wrong.)

[originally from svn r8410]
2009-01-12 20:41:28 +00:00
Simon Tatham
5f410ef051 In the wake of r7415, let's have some better error reporting.
Instead of passing -1 to its gotdata and sentdata callbacks on
error, winhandl.c will now pass the negation of the Windows error
number; and the Plink front end will now format that into an error
message and pass it on to the user.

[originally from svn r7416]
[r7415 == 702a92ceb8]
2007-03-27 19:10:10 +00:00
Simon Tatham
702a92ceb8 Windows apparently sends ERROR_BROKEN_PIPE when a pipe we're reading
from is closed normally from the writing end. This is ludicrous; if
that situation isn't a natural EOF, _nothing_ is. So if we get that
particular error, we pretend it's EOF.

[originally from svn r7415]
2007-03-27 18:49:59 +00:00
Jacob Nevins
46a8859541 Fix Plink, the serial backend, and local-proxy support on Win98SE (at least),
which have been broken since r6797.
(At least some versions of Win9x are gratuitously picky about the arguments to
CreateThread(), requiring lpThreadId not to be NULL.)

[originally from svn r7132]
[r6797 == 291533d3f9]
2007-01-21 23:34:35 +00:00
Simon Tatham
33e827818a Add a mini-rant to the top comment explaining why threads are
required. (I just tried getting rid of them; it worked fine for
serial ports, but not for anything else. The Windows I/O API sucks.)

[originally from svn r6843]
2006-09-03 12:55:16 +00:00
Simon Tatham
a485923ae4 Reading 4K at a time from a serial port turns out to be a bit
unfriendly in an interactive session, because at 19200 baud it takes
nearly two seconds to receive that much data, and as long as the
data is flowing continuously Windows waits until it has a full
buffer. So here's another annoying flag in the winhandl API, which
restricts reads to length 1 so that serial output shows up as it
appears.

(I tried this yesterday, but without the OVERLAPPED fix in r6826 it
behaved very erratically. It now seems solid.)

[originally from svn r6827]
[r6826 == 2aedc83f8d]
2006-08-28 18:26:50 +00:00
Simon Tatham
2aedc83f8d Apparently it helps for an OVERLAPPED structure to contain a valid
event handle. This seems to have fixed _some_, but not all, of the
curious data loss issues in the Windows serial backend.

[originally from svn r6826]
2006-08-28 18:16:49 +00:00
Simon Tatham
17bc654532 Grow some nasty warts on the side of winhandl.c, in preparation for
a serial port backend:
 - In order to do simultaneous reading and writing on the same
   HANDLE, you must enable overlapped access and pass an OVERLAPPED
   structure to each ReadFile and WriteFile call. This would make
   sense if it were an optional thing I could do if I wanted to do
   the reading and writing in the same thread, but making it
   mandatory even if I'm doing them in _different_ threads is just
   annoying and arbitrary.
 - Serial ports occasionally return length 0 from ReadFile, for no
   particularly good reason. Fortunately serial ports also don't
   have a real EOF condition to speak of, so ignoring EOFs is
   actually a viable response in spite of sounding utterly gross.
Hence, handle_{input,output}_new() now accept a flags parameter,
which includes a flag to enable the OVERLAPPED bureaucracy and a
flag to cause EOFs to be ignored on input handles. The current
clients of winhandl.c do not use either of these.

[originally from svn r6813]
2006-08-27 10:00:36 +00:00
Simon Tatham
421a5ece2c We _can_ have handle_throttle() called on defunct handles after all,
so it should just do nothing rather than failing an assertion.

[originally from svn r6807]
2006-08-26 10:58:13 +00:00
Simon Tatham
d5f4ce4611 Another bug fix: always set the busy flag when telling a subthread
to do something, otherwise handle_get_events will forget to tell the
front end to check for that subthread finishing. This applies even
when we're only setting `busy' to tell the subthread to terminate!

[originally from svn r6805]
2006-08-26 10:19:23 +00:00
Simon Tatham
911f43b872 Bug fix: since the input thread does not wait for the event object
until _after_ its first read, we should not start by signalling that
object in order to trigger the first read. Ahem.

[originally from svn r6799]
2006-08-26 08:15:53 +00:00
Simon Tatham
52cdcc6a7c Small tweak to the new handle API: provide a `privdata' field in
each handle structure, set on initialisation and readable by an API
call.

[originally from svn r6798]
2006-08-26 07:41:15 +00:00
Simon Tatham
291533d3f9 New piece of Windows infrastructure: winhandl.c takes Plink's
thread-based approach to stdin and stdout, wraps it in a halfway
sensible API, and makes it a globally available service across all
network tools.

There is no direct functionality enhancement from this checkin:
winplink.c now talks to the new API instead of doing it all
internally, but does nothing different as a result.

However, this should lay the groundwork for several diverse pieces
of work in future: pipe-based ProxyCommand on Windows, a serial port
back end, and (hopefully) a pipe-based means of communicating with
Pageant, which should have sensible blocking behaviour and hence
permit asynchronous agent requests and decrypt-on-demand.

[originally from svn r6797]
2006-08-25 22:10:16 +00:00