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

64 Commits

Author SHA1 Message Date
Simon Tatham
3c6ab5bbb7 Factor out some common code in {ux,win}cons.c.
The assorted host-key and warning prompt messages have no reason to
differ between the two platforms, so let's centralise them. Also,
while I'm here, some basic support functions that are the same in both
modules.
2021-03-13 11:01:35 +00:00
Simon Tatham
6e85d3fe60 Remove FLAG_STDERR_TTY.
It really had no need to be a global process flag at all: it's used to
signal to uxcons.c that stderr_tty_init() ought to check whether
stderr is a tty (in order to save its termios across interactive
prompts and so forth). But the only _caller_ of stderr_tty_init is
Unix Plink, which always sets that flag! So we already have a
perfectly good system for signalling to uxcons.c that you'd like
stderr_tty_init to do something: _whether you call it or not_.
2020-01-30 06:40:21 +00:00
Simon Tatham
d20d3b20fd Remove FLAG_VERBOSE.
The global 'int flags' has always been an ugly feature of this code
base, and I suddenly thought that perhaps it's time to start throwing
it out, one flag at a time, until it's totally unused.

My first target is FLAG_VERBOSE. This was usually set by cmdline.c
when it saw a -v option on the program's command line, except that GUI
PuTTY itself sets it unconditionally on startup. And then various bits
of the code would check it in order to decide whether to print a given
message.

In the current system of front-end abstraction traits, there's no
_one_ place that I can move it to. But there are two: every place that
checked FLAG_VERBOSE has access to either a Seat or a LogPolicy. So
now each of those traits has a query method for 'do I want verbose
messages?'.

A good effect of this is that subsidiary Seats, like the ones used in
Uppity for the main SSH server module itself and the server end of
shell channels, now get to have their own verbosity setting instead of
inheriting the one global one. In fact I don't expect any code using
those Seats to be generating any messages at all, but if that changes
later, we'll have a way to control it. (Who knows, perhaps logging in
Uppity might become a thing.)

As part of this cleanup, I've added a new flag to cmdline_tooltype,
called TOOLTYPE_NO_VERBOSE_OPTION. The unconditionally-verbose tools
now set that, and it has the effect of making cmdline.c disallow -v
completely. So where 'putty -v' would previously have been silently
ignored ("I was already verbose"), it's now an error, reminding you
that that option doesn't actually do anything.

Finally, the 'default_logpolicy' provided by uxcons.c and wincons.c
(with identical definitions) has had to move into a new file of its
own, because now it has to ask cmdline.c for the verbosity setting as
well as asking console.c for the rest of its methods. So there's a new
file clicons.c which can only be included by programs that link
against both cmdline.c _and_ one of the *cons.c, and I've renamed the
logpolicy to reflect that.
2020-01-30 06:40:21 +00:00
Simon Tatham
7590d0625b Introduce and use strbuf_chomp.
Those chomp operations in wincons.c and uxcons.c looked ugly, and I'm
not totally convinced they couldn't underrun the buffer by 1 byte in
weird circumstances. strbuf_chomp is neater.
2020-01-22 22:30:26 +00:00
Simon Tatham
cd6bc14f04 Use strbuf to store results in prompts_t.
UBsan pointed out another memcpy from NULL (again with length 0) in
the prompts_t system. When I looked at it, I realised that firstly
prompt_ensure_result_size was an early not-so-good implementation of
sgrowarray_nm that would benefit from being replaced with a call to
the real one, and secondly, the whole system for storing prompt
results should really have been replaced with strbufs with the no-move
option, because that's doing all the same jobs better.

So, now each prompt_t holds a strbuf in place of its previous manually
managed string. prompt_ensure_result_size is gone (the console
prompt-reading functions use strbuf_append, and everything else just
adds to the strbuf in the usual marshal.c way). New functions exist to
retrieve a prompt_t's result, either by reference or copied.
2020-01-21 20:39:04 +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
64fdc85b2d Fix miscellaneous minor memory leaks.
All found by Coverity.
2019-05-05 10:14:24 +01:00
Simon Tatham
514796b7e4 Add an interactive anti-spoofing prompt in Plink.
At the point when we change over the seat's trust status to untrusted
for the last time, to finish authentication, Plink will now present a
final interactive prompt saying 'Press Return to begin session'. This
is a hint that anything after that that resembles an auth prompt
should be treated with suspicion, because _PuTTY_ thinks it's finished
authenticating.

This is of course an annoying inconvenience for interactive users, so
I've tried to reduce its impact as much as I can. It doesn't happen in
GUI PuTTY at all (because the trust sigil system is used instead); it
doesn't happen if you use plink -batch (because then the user already
knows that they _never_ expect an interactive prompt); and it doesn't
happen if Plink's standard input is being redirected from anywhere
other than the terminal / console (because then it would be pointless
for the server to try to scam passphrases out of the user anyway,
since the user isn't in a position to enter one in response to a spoof
prompt). So it should only happen to people who are using Plink in a
terminal for interactive login purposes, and that's not _really_ what
I ever intended Plink to be used for (which is why it's never had any
out-of-band control UI like OpenSSH's ~ system).

If anyone _still_ doesn't like this new prompt, it can also be turned
off using the new -no-antispoof flag, if the user is willing to
knowingly assume the risk.
2019-03-16 12:25:23 +00:00
Simon Tatham
76d8d363be Seat method to set the current trust status.
In terminal-based GUI applications, this is passed through to
term_set_trust_status, to toggle whether lines are prefixed with the
new trust sigil. In console applications, the function returns false,
indicating to the backend that it should employ some other technique
for spoofing protection.
2019-03-16 12:25:23 +00:00
Simon Tatham
e21afff605 Move sanitisation of k-i prompts into the SSH code.
Now, instead of each seat's prompt-handling function doing the
control-char sanitisation of prompt text, the SSH code does it. This
means we can do it differently depending on the prompt.

In particular, prompts _we_ generate (e.g. a genuine request for your
private key's passphrase) are not sanitised; but prompts coming from
the server (in keyboard-interactive mode, or its more restricted SSH-1
analogues, TIS and CryptoCard) are not only sanitised but also
line-length limited and surrounded by uncounterfeitable headers, like
I've just done to the authentication banners.

This should mean that if a malicious server tries to fake the local
passphrase prompt (perhaps because it's somehow already got a copy of
your _encrypted_ private key), you can tell the difference.
2019-03-16 12:25:23 +00:00
Simon Tatham
5c926d9ea4 Switch to using poll(2) in place of select(2).
I've always thought poll was more hassle to set up, because if you
want to reuse part of your pollfds list between calls then you have to
index every fd by its position in the list as well as the fd number
itself, which gives you twice as many indices to keep track of than if
the fd is always its own key.

But the problem is that select is fundamentally limited to the range
of fds that can fit in an fd_set, which is not the range of fds that
can _exist_, so I've had a change of heart and now have to go with
poll.

For the moment, I've surrounded it with a 'pollwrapper' structure that
lets me treat it more or less like select, containing a tree234 that
maps each fd to its location in the list, and also translating between
the simple select r/w/x classification and the richer poll flags.
That's let me do the migration with minimal disruption to the call
sites.

In future perhaps I can start using poll more directly, and/or using
the richer flag system (though the latter might be fiddly because of
sometimes being constrained to use the glib event loop). But this will
do for now.
2019-03-16 12:25:23 +00:00
Simon Tatham
d05d2e259f Revise the API for seat_stripctrl_new.
Now instead of taking raw arguments to configure the output
StripCtrlChars with, it takes an enumerated value giving the context
of what's being sanitised, and allows the seat to decide what the
output parameters for that context should be.

The only context currently used is SIC_BANNER (SSH login banners).
I've also added a not-yet-used one for keyboard-interactive prompts.
2019-03-09 16:43:41 +00:00
Simon Tatham
7b48922761 Switch console prompt sanitisation to use StripCtrlChars.
Local functions in uxcons.c and wincons.c were calling the old
simplistic sanitise_term_data to print console-based prompts. Now they
use the same new system as everything else.

This removes the last use of the ASCII-centric sanitise_term_data.
2019-03-06 20:31:26 +00:00
Simon Tatham
d60dcc2c82 Add a Seat vtable method to get a stripctrl.
If centralised code like the SSH implementation wants to sanitise
escape sequences out of a piece of server-provided text, it will need
to do it by making a locale-based StripCtrlChars if it's running in a
console context, or a Terminal-based one if it's in a GUI terminal-
window application.

All the other changes of behaviour needed between those two contexts
are handled by providing reconfigurable methods in the Seat vtable;
this one is no different. So now there's a new method in the Seat
vtable that will construct a StripCtrlChars appropriate to that kind
of seat. Terminal-window seats (gtkwin.c, window.c) implement it by
calling the new stripctrl_new_term(), and console ones use the locale-
based stripctrl_new().
2019-03-06 20:31:26 +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
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
b4c8fd9d86 New abstraction 'Seat', to pass to backends.
This is a new vtable-based abstraction which is passed to a backend in
place of Frontend, and it implements only the subset of the Frontend
functions needed by a backend. (Many other Frontend functions still
exist, notably the wide range of things called by terminal.c providing
platform-independent operations on the GUI terminal window.)

The purpose of making it a vtable is that this opens up the
possibility of creating a backend as an internal implementation detail
of some other activity, by providing just that one backend with a
custom Seat that implements the methods differently.

For example, this refactoring should make it feasible to directly
implement an SSH proxy type, aka the 'jump host' feature supported by
OpenSSH, aka 'open a secondary SSH session in MAINCHAN_DIRECT_TCP
mode, and then expose the main channel of that as the Socket for the
primary connection'. (Which of course you can already do by spawning
'plink -nc' as a separate proxy process, but this would permit it in
the _same_ process without anything getting confused.)

I've centralised a full set of stub methods in misc.c for the new
abstraction, which allows me to get rid of several annoying stubs in
the previous code. Also, while I'm here, I've moved a lot of
duplicated modalfatalbox() type functions from application main
program files into wincons.c / uxcons.c, which I think saves
duplication overall. (A minor visible effect is that the prefixes on
those console-based fatal error messages will now be more consistent
between applications.)
2018-10-11 19:58:42 +01:00
Simon Tatham
109df9f46b Remove frontend_keypress().
This was used by ldisc to communicate back to the front end that a key
had been pressed (or rather, that a keypress had caused a nonzero
amount of session input data). Its only nontrivial implementation was
in gtkwin.c, which used that notification to implement the Unix GUI's
"close window on keypress, if the session was already over" policy.

(Which in turn is Unix-specific, because the rationale is that
sometimes X servers don't have a functioning window manager, so it's
useful to have a way of telling any application to close without using
WM-provided facilities like a close button.)

But gtkwin.c doesn't need to be told by the ldisc that a keypress
happened - it's the one _sending_ those keypresses to ldisc in the
first place! So I've thrown away the three stub implementations of
frontend_keypress, removed the call to it in ldisc.c, and replaced it
with calls in gtkwin.c at all the points during keypress handling
that call ldisc_send.

A visible effect is that pterm's close-on-keypress behaviour will now
only trigger on an actual (input-generating) _keypress_, and not on
other input generation such as a paste action. I think that's an
improvement.
2018-10-11 18:14:05 +01:00
Simon Tatham
ad0c502cef Refactor the LogContext type.
LogContext is now the owner of the logevent() function that back ends
and so forth are constantly calling. Previously, logevent was owned by
the Frontend, which would store the message into its list for the GUI
Event Log dialog (or print it to standard error, or whatever) and then
pass it _back_ to LogContext to write to the currently open log file.
Now it's the other way round: LogContext gets the message from the
back end first, writes it to its log file if it feels so inclined, and
communicates it back to the front end.

This means that lots of parts of the back end system no longer need to
have a pointer to a full-on Frontend; the only thing they needed it
for was logging, so now they just have a LogContext (which many of
them had to have anyway, e.g. for logging SSH packets or session
traffic).

LogContext itself also doesn't get a full Frontend pointer any more:
it now talks back to the front end via a little vtable of its own
called LogPolicy, which contains the method that passes Event Log
entries through, the old askappend() function that decides whether to
truncate a pre-existing log file, and an emergency function for
printing an especially prominent message if the log file can't be
created. One minor nice effect of this is that console and GUI apps
can implement that last function subtly differently, so that Unix
console apps can write it with a plain \n instead of the \r\n
(harmless but inelegant) that the old centralised implementation
generated.

One other consequence of this is that the LogContext has to be
provided to backend_init() so that it's available to backends from the
instant of creation, rather than being provided via a separate API
call a couple of function calls later, because backends have typically
started doing things that need logging (like making network
connections) before the call to backend_provide_logctx. Fortunately,
there's no case in the whole code base where we don't already have
logctx by the time we make a backend (so I don't actually remember why
I ever delayed providing one). So that shortens the backend API by one
function, which is always nice.

While I'm tidying up, I've also moved the printf-style logeventf() and
the handy logevent_and_free() into logging.c, instead of having copies
of them scattered around other places. This has also let me remove
some stub functions from a couple of outlying applications like
Pageant. Finally, I've removed the pointless "_tag" at the end of
LogContext's official struct name.
2018-10-10 21:50:50 +01:00
Simon Tatham
e230751853 Remove FLAG_STDERR completely.
Originally, it controlled whether ssh.c should send terminal messages
(such as login and password prompts) to terminal.c or to stderr. But
we've had the from_backend() abstraction for ages now, which even has
an existing flag to indicate that the data is stderr rather than
stdout data; applications which set FLAG_STDERR are precisely those
that link against uxcons or wincons, so from_backend will do the
expected thing anyway with data sent to it with that flag set. So
there's no reason ssh.c can't just unconditionally pass everything
through that, and remove the special case.

FLAG_STDERR was also used by winproxy and uxproxy to decide whether to
capture standard error from a local proxy command, or whether to let
the proxy command send its diagnostics directly to the usual standard
error. On reflection, I think it's better to unconditionally capture
the proxy's stderr, for three reasons. Firstly, it means proxy
diagnostics are prefixed with 'proxy:' so that you can tell them apart
from any other stderr spew (which used to be particularly confusing if
both the main application and the proxy command were instances of
Plink); secondly, proxy diagnostics are now reliably copied to packet
log files along with all the other Event Log entries, even by
command-line tools; and thirdly, this means the option to suppress
proxy command diagnostics after the main session starts will actually
_work_ in the command-line tools, which it previously couldn't.

A more minor structure change is that copying of Event Log messages to
stderr in verbose mode is now done by wincons/uxcons, instead of
centrally in logging.c (since logging.c can now no longer check
FLAG_STDERR to decide whether to do it). The total amount of code to
do this is considerably smaller than the defensive-sounding comment in
logevent.c explaining why I did it the other way instead :-)
2018-09-21 16:46:03 +01:00
Simon Tatham
63a14f26f7 Rework handling of untrusted terminal data.
Now there's a centralised routine in misc.c to do the sanitisation,
which copies data on to an outgoing bufchain. This allows me to remove
from_backend_untrusted() completely from the frontend API, simplifying
code in several places.

Two use cases for untrusted-terminal-data sanitisation were in the
terminal.c prompts handler, and in the collection of SSH-2 userauth
banners. Both of those were writing output to a bufchain anyway, so
it was very convenient to just replace a bufchain_add with
sanitise_term_data and then not have to worry about it again.

There was also a simplistic sanitiser in uxcons.c, which I've now
replaced with a call to the good one - and in wincons.c there was a
FIXME saying I ought to get round to that, which now I have!
2018-09-19 23:08:28 +01:00
Simon Tatham
8dfb2a1186 Introduce a typedef for frontend handles.
This is another major source of unexplained 'void *' parameters
throughout the code.

In particular, the currently unused testback.c actually gave the wrong
pointer type to its internal store of the frontend handle - it cast
the input void * to a Terminal *, from which it got implicitly cast
back again when calling from_backend, and nobody noticed. Now it uses
the right type internally as well as externally.
2018-09-19 22:10:58 +01:00
Simon Tatham
3814a5cee8 Make 'LogContext' a typedef visible throughout the code.
Same principle again - the more of these structures have globally
visible tags (even if the structure contents are still opaque in most
places), the fewer of them I can mistake for each other.
2018-09-19 22:10:57 +01:00
Simon Tatham
3692c239d7 Remove unused params from console_get_userpass_input.
NFC: this is a preliminary refactoring, intended to make my life
easier when I start changing around the APIs used to pass user
keyboard input around. The fewer functions even _have_ such an API,
the less I'll have to do at that point.
2018-05-18 07:22:56 +01:00
Simon Tatham
e2452f3bd0 Add some missing checks for EINTR after select(2).
I noticed today that Unix Plink responds to SIGWINCH by accidentally
dying of EINTR having interrupted its main select loop, and when I
checked, there turn out to be a couple of other select loops with the
same bug.
2017-01-06 19:29:06 +00:00
Ben Harris
05e802d5fe uxcons: Don't try to include <sys/select.h> on systems that don't have it.
Also include <sys/time.h> for ancient systems that define select()
there.
2016-05-01 18:13:03 +02:00
Kylie McClain
4ae1577b43 uxcons: Fix on musl libc
musl libc exports FD_SET and friends in sys/select.h.
2016-04-29 19:42:59 +01:00
Simon Tatham
940a82fd37 Special host key warning when a better key exists.
If you're connecting to a new server and it _only_ provides host key
types you've configured to be below the warning threshold, it's OK to
give the standard askalg() message. But if you've newly demoted a host
key type and now reconnect to some server for which that type was the
best key you had cached, the askalg() wording isn't really appropriate
(it's not that the key we've settled on is the first type _supported
by the server_, it's that it's the first type _cached by us_), and
also it's potentially helpful to list the better algorithms so that
the user can pick one to cross-certify.
2016-03-27 18:20:37 +01:00
Simon Tatham
bea758a7ae Fix spurious EAGAIN in Plink host key (and other) prompts.
Plink sets standard input into nonblocking mode, meaning that read()
from fd 0 in an interactive context will typically return -1 EAGAIN.
But the prompt functions in uxcons.c, used for verifying SSH host keys
and suchlike, were doing an unguarded read() from fd 0, and then
panicking and aborting the session when they got EAGAIN.

Fixed by inventing a wrapper around read(2) which handles EAGAIN but
passes all other errors back to the caller. (Seemed slightly less
dangerous than the stateful alternative of temporarily re-blockifying
the file descriptor.)
2015-09-24 11:58:44 +01:00
Simon Tatham
89da2ddf56 Giant const-correctness patch of doom!
Having found a lot of unfixed constness issues in recent development,
I thought perhaps it was time to get proactive, so I compiled the
whole codebase with -Wwrite-strings. That turned up a huge load of
const problems, which I've fixed in this commit: the Unix build now
goes cleanly through with -Wwrite-strings, and the Windows build is as
close as I could get it (there are some lingering issues due to
occasional Windows API functions like AcquireCredentialsHandle not
having the right constness).

Notable fallout beyond the purely mechanical changing of types:
 - the stuff saved by cmdline_save_param() is now explicitly
   dupstr()ed, and freed in cmdline_run_saved.
 - I couldn't make both string arguments to cmdline_process_param()
   const, because it intentionally writes to one of them in the case
   where it's the argument to -pw (in the vain hope of being at least
   slightly friendly to 'ps'), so elsewhere I had to temporarily
   dupstr() something for the sake of passing it to that function
 - I had to invent a silly parallel version of const_cmp() so I could
   pass const string literals in to lookup functions.
 - stripslashes() in pscp.c and psftp.c has the annoying strchr nature
2015-05-15 12:47:44 +01:00
Simon Tatham
a5fc95b715 Const-correctness of name fields in struct ssh_*.
All the name strings in ssh_cipher, ssh_mac, ssh_hash, ssh_signkey
point to compile-time string literals, hence should obviously be const
char *.

Most of these const-correctness patches are just a mechanical job of
adding a 'const' in the one place you need it right now, and then
chasing the implications through the code adding further consts until
it compiles. But this one has actually shown up a bug: the 'algorithm'
output parameter in ssh2_userkey_loadpub was sometimes returning a
pointer to a string literal, and sometimes a pointer to dynamically
allocated memory, so callers were forced to either sometimes leak
memory or sometimes free a bad thing. Now it's consistently
dynamically allocated, and should be freed everywhere too.
2015-05-15 10:12:06 +01:00
Ben Harris
d5836982e2 Two related changes to timing code:
First, make absolute times unsigned.  This means that it's safe to 
depend on their overflow behaviour (which is undefined for signed 
integers).  This requires a little extra care in handling comparisons, 
but I think I've correctly adjusted them all.

Second, functions registered with schedule_timer() are guaranteed to be 
called with precisely the time that was returned by schedule_timer().  
Thus, it's only necessary to check these values for equality rather than 
doing risky range checks, so do that.

The timing code still does lots that's undefined, unnecessary, or just
wrong, but this is a good start.

[originally from svn r9667]
2012-09-18 21:42:48 +00:00
Simon Tatham
f030975da7 Conditionalise the calls to premsg and postmsg in uxcons.c's
logevent(), which temporarily turn off the raw mode we've put stderr
into, so that they don't get called if the log_eventlog() call between
them is not _actually_ going to write to stderr.

Fixes a bug in which, if you define a Unix PuTTY saved session which
uses 'plink -nc' as a local proxy command and then run PuTTY
backgrounded from the shell with that session loaded, the subprocess
Plink would get SIGTTOU when it tried to muck about with stderr and
the whole thing would grind to a halt. I'm prepared to consider that
acceptable if Plink _really_ wants to write on standard error, but if
it doesn't, it should just carry on working in the background!

[originally from svn r9462]
2012-04-18 06:36:46 +00:00
Simon Tatham
da66c0656a While I'm crusading against arbitrary limits, here's a redesign of
prompt_t to arrange that the buffer in which each prompt is stored can
be reallocated larger during the input process.

[originally from svn r9317]
2011-10-02 11:50:45 +00:00
Simon Tatham
62cbc7dc0b Turn 'Filename' into a dynamically allocated type with no arbitrary
length limit, just as I did to FontSpec yesterday.

[originally from svn r9316]
2011-10-02 11:01:57 +00:00
Simon Tatham
9fce238b00 If we're printing password prompts to /dev/tty rather than standard
error, we should also read the corresponding password inputs from
/dev/tty. That way, redirection of Plink's standard input will play
nicely with SSH sessions that need interactive login.

(This is what we get for disdaining getpass(3) and going it alone, of
course. But we had no choice, due to the extra output part way through
keyboard-interactive.)

[originally from svn r9262]
2011-08-11 18:13:34 +00:00
Simon Tatham
c347755f87 Unix console utilities should send prompts to /dev/tty or failing
that stderr, not to stdout.

[originally from svn r8878]
2010-02-20 19:15:25 +00:00
Jacob Nevins
4bddcc2b5d Workarounds for compiling with -D_FORTIFY_SOURCE=2 (as Ubuntu does), which
doesn't like you to ignore the return value from read()/write()/etc (and
apparently can't be shut up with a cast to void).

[originally from svn r8614]
2009-08-07 00:19:04 +00:00
Simon Tatham
d0661ca94e Handle more gracefully the possibility of a keyboard-interactive
prompts packet containing no actual prompts (perhaps due to odd
server organisation, or perhaps so it can print a banner message and
do nothing else). Previously, the get_userpass_input functions
always returned failure when in '-batch' mode, even in this case
where no actual input would be required.

[originally from svn r8490]
2009-03-03 18:35:53 +00:00
Jacob Nevins
07a876ce1e r8305 made platform_x11_best_transport[] obsolete, but there still seem to be a
few instances around; expunge them.

[originally from svn r8382]
[r8305 == ca6fc3a4da]
2009-01-04 23:36:24 +00:00
Ben Harris
faa6e26d38 Add support for resetting the terminal modes on stderr to something sensible
before printing error messages to it.  This should fix the stair-stepping
in Plink's progress messages.

[originally from svn r7745]
2007-09-29 12:27:45 +00:00
Jacob Nevins
8719f92c14 Revamp SSH authentication code so that user interaction is more
abstracted out; replace loops structured around a single interaction
per loop with less tortuous code (fixes: `ki-multiprompt-crash',
`ssh1-bad-passphrase-crash'; makes `ssh2-password-expiry' and
`proxy-password-prompt' easier).

The new interaction abstraction has a lot of fields that are unused in
the current code (things like window captions); this is groundwork for
`gui-auth'. However, ssh.c still writes directly to stderr; that may
want to be fixed.

In the GUI apps, user interaction is moved to terminal.c. This should
make it easier to fix things like UTF-8 username entry, although I
haven't attempted to do so. Also, control character filtering can be
tailored to be appropriate for individual front-ends; so far I don't
promise anything other than not having made it any worse.

I've tried to test this fairly exhaustively (although Mac stuff is
untested, as usual). It all seems to basically work, but I bet there
are new bugs. (One I know about is that you can no longer make the
PuTTY window go away with a ^D at the password prompt; this should be
fixed.)

[originally from svn r6437]
[this svn revision also touched putty-wishlist]
2005-10-30 20:24:09 +00:00
Jacob Nevins
5aa719d16e Consistently use a single notation to refer to SSH protocol versions, as
discussed. Use Barrett and Silverman's convention of "SSH-1" for SSH protocol
version 1 and "SSH-2" for protocol 2 ("SSH1"/"SSH2" refer to ssh.com
implementations in this scheme). <http://www.snailbook.com/terms.html>

[originally from svn r5480]
2005-03-10 16:36:05 +00:00
Simon Tatham
f73fcb0424 Add asynchronous callback capability to the askappend() alert box.
This was harder than verify_ssh_host_key() and askalg() put
together, because:
 (a) askappend() can be called at any time, since it's a side effect
     of data-logging functions. Therefore there can be an unfinished
     askappend() alert at any time, and hence the OS X front end has
     to be prepared to _queue_ other alerts which occur during that
     time.
 (b) logging.c has to do something with data that comes in while
     it's waiting for an answer to askappend(). It buffers it until
     it knows what the user wants done with it. This involved
     something of a reorganisation of logging.c.

[originally from svn r5344]
2005-02-18 18:33:31 +00:00
Simon Tatham
8574822b9b Revamp interface to verify_ssh_host_key() and askalg(). Each of them
now returns an integer: 0 means cancel the SSH connection and 1
means continue with it. Additionally, they can return -1, which
means `front end has set an asynchronous alert box in motion, please
wait to be called back with the result', and each one is passed a
callback function pointer and context for this purpose.

I have not yet done the same to askappend() yet, because it will
take a certain amount of reorganisation of logging.c.

Importantly, this checkin means the host key dialog box now works on
OS X.

[originally from svn r5330]
2005-02-17 18:34:24 +00:00
Jacob Nevins
c9116974ac The terminal window can now indicate that PuTTY is busy in various ways, by
changing its mouse pointer. Currently this is only used in the (slightly-
arbitrarily-defined) "heavy" bits of SSH-2 key exchange. We override pointer
hiding while PuTTY is busy, but preserve pointer-hiding state.

Not yet implemented on the Mac.

Also switch to frobbing window-class cursor in Windows rather than relying on
SetCursor().

[originally from svn r5303]
2005-02-15 17:05:58 +00:00
Jacob Nevins
3c98d6e60d Add a preference list for SSH-2 key exchange algorithms, on a new "Kex" panel
(which will gain more content anon).

Retire BUG_SSH2_DH_GEX and add a backwards-compatibility wart, since we never
did find a way of automatically detecting this alleged server bug, and in any
case there was only ever one report (<3D91F3B5.7030309@inwind.it>, FWIW).

Also generalise askcipher() to a new askalg() (thus touching all the
front-ends).

I've made some attempt to document what SSH key exchange is and why you care,
but it could use some review for clarity (and outright lies).

[originally from svn r5022]
2004-12-23 02:24:07 +00:00
Simon Tatham
7ecf13564a New timing infrastructure. There's a new function schedule_timer()
which pretty much any module can call to request a call-back in the
future. So terminal.c can do its own handling of blinking, visual
bells and deferred screen updates, without having to rely on
term_update() being called 50 times a second (fixes: pterm-timer);
and ssh.c and telnet.c both invoke a new module pinger.c which takes
care of sending keepalives, so they get sent uniformly in all front
ends (fixes: plink-keepalives, unix-keepalives).

[originally from svn r4906]
[this svn revision also touched putty-wishlist]
2004-11-27 13:20:21 +00:00