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

104 Commits

Author SHA1 Message Date
Simon Tatham
2762a2025f Merge the 0.74 release branch back to master.
Two minor memory-leak fixes on 0.74 seem not to be needed on master:
the fix in an early exit path of pageant_add_keyfile is done already
on master in a different way, and the missing sfree(fdlist) in
uxsftp.c is in code that's been completely rewritten in the uxcliloop
refactoring.

Other minor conflicts: the rework in commit b52641644905 of
ssh1login.c collided with the change from FLAG_VERBOSE to
seat_verbose(), and master and 0.74 each added an unrelated extra
field to the end of struct SshServerConfig.
2020-06-27 08:11:22 +01:00
Simon Tatham
caf4802b0a setup_utmp: add error check in case getpwuid fails.
Spotted by Coverity: if there is no password file entry associated
with our numeric uid, we'll press on anyway and dereference NULL.
2020-06-21 16:39:47 +01:00
Simon Tatham
426a2048cc pty_backend_create: set up SIGCHLD handler earlier.
Mark Wooding points out that when running with the +ut flag, we close
pty_utmp_helper_pipe during pty backend setup, which causes the
previously forked helper process to terminate. If that termination
happens quickly enough, then the code later in pty_backend_create
won't have set up the SIGCHLD handler and its pipe yet, so when we get
to the main event loop, we'll fail to notice that subprocess waiting
to be reaped, and leave it lying around as a zombie.

An easy fix is to move the handler and pipe setup to before the code
that potentially closes pty_utmp_helper_pipe, so that there isn't a
race condition any more.

(cherry picked from commit 7ffa6ed41e)
2020-06-14 15:49:36 +01:00
Simon Tatham
5b45c32ab7 uxpty.c: add a missing include.
This file exports several functions defined in sshserver.h, and the
declarations weren't being type-checked against the definitions.

(cherry picked from commit 37d91aabff)
2020-06-14 15:49:36 +01:00
Simon Tatham
7ffa6ed41e pty_backend_create: set up SIGCHLD handler earlier.
Mark Wooding points out that when running with the +ut flag, we close
pty_utmp_helper_pipe during pty backend setup, which causes the
previously forked helper process to terminate. If that termination
happens quickly enough, then the code later in pty_backend_create
won't have set up the SIGCHLD handler and its pipe yet, so when we get
to the main event loop, we'll fail to notice that subprocess waiting
to be reaped, and leave it lying around as a zombie.

An easy fix is to move the handler and pipe setup to before the code
that potentially closes pty_utmp_helper_pipe, so that there isn't a
race condition any more.
2020-05-02 16:32:56 +01:00
Simon Tatham
df2994a05a Make the backend_init error message dynamic. (NFC)
Now, instead of a 'const char *' in the static data segment, error
messages returned from backend setup are dynamically allocated and
freed by the caller.

This will allow me to make the messages much more specific (including
errno values and the like). However, this commit is pure refactoring:
I've _just_ changed the allocation policy, and left all the messages
alone.
2020-04-18 13:33:51 +01:00
Simon Tatham
9fc8320fc3 uxpty: handle $SHELL not being set.
This is unlikely in most situations, but 'psusan' in particular is
intended to be run in a lot of weird environments where things aren't
properly set up yet. I just found out that if you use a Cygwin-built
psusan as the proxy process for Windows PuTTY (to get a local Cygwin
xterm) then it starts up with SHELL unset, and uxpty's forked
subprocess segfaults when it tries to exec a null pointer.
2020-03-21 14:45:03 +00:00
Simon Tatham
b4e1bca2c3 Change vtable defs to use C99 designated initialisers.
This is a sweeping change applied across the whole code base by a spot
of Emacs Lisp. Now, everywhere I declare a vtable filled with function
pointers (and the occasional const data member), all the members of
the vtable structure are initialised by name using the '.fieldname =
value' syntax introduced in C99.

We were already using this syntax for a handful of things in the new
key-generation progress report system, so it's not new to the code
base as a whole.

The advantage is that now, when a vtable only declares a subset of the
available fields, I can initialise the rest to NULL or zero just by
leaving them out. This is most dramatic in a couple of the outlying
vtables in things like psocks (which has a ConnectionLayerVtable
containing only one non-NULL method), but less dramatically, it means
that the new 'flags' field in BackendVtable can be completely left out
of every backend definition except for the SUPDUP one which defines it
to a nonzero value. Similarly, the test_for_upstream method only used
by SSH doesn't have to be mentioned in the rest of the backends;
network Plugs for listening sockets don't have to explicitly null out
'receive' and 'sent', and vice versa for 'accepting', and so on.

While I'm at it, I've normalised the declarations so they don't use
the unnecessarily verbose 'struct' keyword. Also a handful of them
weren't const; now they are.
2020-03-10 21:06:29 +00:00
Simon Tatham
0a09c12edc Pass the BackendVtable pointer to backend_init.
Now I can have multiple BackendVtable structures sharing all their
function pointers, and still tell which is which when init is setting
things up.
2020-02-22 18:27:56 +00:00
Simon Tatham
9482f33739 Give BackendVtable separate id and displayname fields.
The previous 'name' field was awkwardly serving both purposes: it was
a machine-readable identifier for the backend used in the saved
session format, and it was also used in error messages when Plink
wanted to complain that it didn't support a particular backend. Now
there are two separate name fields for those purposes.
2020-02-22 18:27:56 +00:00
Simon Tatham
37d91aabff uxpty.c: add a missing include.
This file exports several functions defined in sshserver.h, and the
declarations weren't being type-checked against the definitions.
2020-02-22 07:03:38 +00:00
Simon Tatham
639810e825 uxpty: remove redundant signal list. (NFC)
In commit 105672e32 I added the pty_backend_exit_signame() function,
which constructs the SSH wire name of the signal that terminated the
pty session process. I did it by having a sequence of inline #ifdefs
for all the translatable signal names, each one guarding the code that
expected that signal to be defined in <signal.h>.

But there was no need to write all that out longhand, because in the
preceding commit 72eca76d2, I made a central list of signal names in
sshsignals.h, so all I should have needed to do was to set up the
macros that header expects, and let _it_ do the iteration over the
locally defined subset of signal ids! So now I do that instead.
2020-01-01 15:47:37 +00:00
Simon Tatham
1547c9c1ec Make dupcat() into a variadic macro.
Up until now, it's been a variadic _function_, whose argument list
consists of 'const char *' ASCIZ strings to concatenate, terminated by
one containing a null pointer. Now, that function is dupcat_fn(), and
it's wrapped by a C99 variadic _macro_ called dupcat(), which
automatically suffixes the null-pointer terminating argument.

This has three benefits. Firstly, it's just less effort at every call
site. Secondly, it protects against the risk of accidentally leaving
off the NULL, causing arbitrary words of stack memory to be
dereferenced as char pointers. And thirdly, it protects against the
more subtle risk of writing a bare 'NULL' as the terminating argument,
instead of casting it explicitly to a pointer. That last one is
necessary because C permits the macro NULL to expand to an integer
constant such as 0, so NULL by itself may not have pointer type, and
worse, it may not be marshalled in a variadic argument list in the
same way as a pointer. (For example, on a 64-bit machine it might only
occupy 32 bits. And yet, on another 64-bit platform, it might work
just fine, so that you don't notice the mistake!)

I was inspired to do this by happening to notice one of those bare
NULL terminators, and thinking I'd better check if there were any
more. Turned out there were quite a few. Now there are none.
2019-10-14 19:42:37 +01: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
3d8563ec9d uxpty.c: silence compiler warning about chdir().
I didn't check the error code, which for some reason didn't give me a
-Werror warning on Ubuntu 18.04, but does on 16.04.
2019-04-01 20:04:48 +01:00
Simon Tatham
d5199e473f Uppity: configurable cwd for session.
All my instincts expect the shell subprocesses to start off in ~, so
it's confusing if they start off in some random PuTTY checkout
directory. So now we default to $HOME, and if I really do want the
latter, I can use the new config option to reselect '.'.
2019-04-01 09:06:12 +01:00
Simon Tatham
e93d9ff305 Uppity: clear some key environment vars in subprocesses.
My helper scripts for invoking Uppity have been manually unsetting
things like XAUTHORITY and SSH_AUTH_SOCK, to avoid accidentally
passing them through from my primary login session, so that I don't
get confused about whether agent forwarding is happening, or end up
with one DISPLAY going with a different XAUTHORITY.

Now I clear these within Uppity itself, so the wrapping script won't
have to.
2019-04-01 09:06:12 +01:00
Simon Tatham
4cd040bced uxpty.c: stop setting DISPLAY to "(null)".
In some contexts (namely pterm on a pure Wayland system, and Uppity),
seat_get_x_display() will return NULL. In that situation uxpty.c was
cheerfully passing it to dupprintf regardless, which in principle is
undefined behaviour and in practice was causing it to construct the
silly environment string "DISPLAY=(null)".

Now we handle that case by unsetenv("DISPLAY") instead.
2019-04-01 09:06:12 +01:00
Simon Tatham
8d84272d80 uxserver: option to generate numeric "exit-signal".
This mimics a bug in some old SSH servers for which PuTTY contains
compensation code (parsing an incoming "exit-signal" two ways and
seeing which one worked). I completely rewrote that code in commit
7535f645a, as part of the BinarySource rework. Now I can finally test
it sensibly.
2019-03-31 10:35:10 +01: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
47202c4e16 Introduce an enum of the uxsel / select_result flags.
Those magic numbers 1,2,4 were getting annoying. Time to replace them
while I can still remember what they do.
2019-03-16 12:25:23 +00:00
Simon Tatham
5eb6c19047 Extra inline helpers seat_{stdout,stderr}_pl.
These take a ptrlen in place of separate buffer and length arguments.
Switched over to them in lots of places.
2019-03-09 16:21:49 +00:00
Simon Tatham
85550641d7 uxpty.c: initialise pty->pending_eof.
valgrind just pointed out that it wasn't.
2019-02-13 19:36:31 +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
bf743bf85c Uppity: properly support _POSIX_VDISABLE in tty modes.
The SSH wire protocol for tty modes corresponding to control
characters (e.g. configuring what Ctrl-Foo you can press to generate
SIGINT or SIGQUIT) specifies (RFC 4254 section 8, under VINTR, saying
'similarly for the other characters') that you should send the value
255 on the wire if you want _no_ character code to map to the action
in question.

But in the <termios.h> API, that's indicated by setting the
appropriate field of 'struct termios' to _POSIX_VDISABLE, which is a
platform-dependent value and varies between (at least) Linux and *BSD.

On the client side, Unix Plink has always known this: when it copies
the local termios settings into a struct ssh_ttymodes to be sent on
the wire, it checks for _POSIX_VDISABLE and replaces it with 255. But
uxpty.c, mapping ssh_ttymodes back to termios for Uppity's pty
sessions, wasn't making the reverse transformation.
2019-01-18 19:14:27 +00:00
Simon Tatham
3322d4c082 Remove a load of obsolete printf string limits.
In the previous commit I happened to notice a %.150s in a ppl_logevent
call, which was probably an important safety precaution a couple of
decades ago when that format string was being used for an sprintf into
a fixed-size buffer, but now it's just pointless cruft.

This commit removes all printf string formatting directives with a
compile-time fixed size, with the one exception of a %.3s used to cut
out a 3-letter month name in scpserver.c. In cases where the format
string in question was already going to an arbitrary-length function
like dupprintf or ppl_logevent, that's all I've done; in cases where
there was still a fixed-size buffer, I've replaced it with a dynamic
buffer and dupprintf.
2018-12-08 21:06:59 +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
1378bb049a Switch some Conf settings over to being bool.
I think this is the full set of things that ought logically to be
boolean.

One annoyance is that quite a few radio-button controls in config.c
address Conf fields that are now bool rather than int, which means
that the shared handler function can't just access them all with
conf_{get,set}_int. Rather than back out the rigorous separation of
int and bool in conf.c itself, I've just added a similar alternative
handler function for the bool-typed ones.
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
Pavel I. Kryukov
a7c7ba0eb1 Add missing #ifndef OMIT_UTMP over pty_utmp_helper_pipe closing 2018-10-21 13:43:44 +01:00
Simon Tatham
a48e897f26 uxpty: support SS_EOF, when in pipe mode.
If the child process's standard input is provided by a pipe that's
separate from its output channels, we can - and should - honour a
request to cause that process to receive input EOF, by closing the
output end of that pipe.

As usual, we do this by setting a pending-EOF flag and calling
try_write, to ensure that any buffered output data is sent before the
pipe actually closes.
2018-10-21 10:02:10 +01:00
Simon Tatham
6b7a1cd1c1 uxpty: option to make three pipes instead of a pty.
Not every "session" channel in SSH allocates a pty at all, of course,
and so I'll need a way to run a subprocess without doing so. The
simplest approach seems to be to expand uxpty's remit so that the pty
is optional: now it can open either a pty or a set of pipes for
stdin/out/err, according to an option provided to pty_backend_create.

(It amuses me that without this option I'd have an SSH server which is
incapable of _not_ honouring the "pty-req" channel request. That's
normally the easy part!)

This breaks the previous one-to-one coupling between pty backend
instances and file descriptors passed to uxsel, which I was using to
look up the Pty structure in a tree234 indexed by fd when an uxsel
notification came back. So now each Pty structure contains a
collection of subobjects of a new type PtyFd, and _those_ are what's
stored in the fd-indexed tree.

Another awkward part is that uxsel_set is not incremental: the rwx
flags you pass to it completely supersede the previous set for that
file descriptor, so I had to set up the logic that decides whether
we're trying to read or write each fd in a way that can cope equally
well with the fd aliasing another one (if it's the pty master) or not
(if there are three completely separate pipes).
2018-10-21 10:02:10 +01:00
Simon Tatham
63d08fc308 uxpty: support SS_SIG* and SS_BRK specials.
The SS_SIGFOO family are implemented by sending a signal directly to
the pid of the immediate child process.

I had had the vague idea that it might be more desirable to send the
specified signal to the foreground process group in the tty. That way,
you'd be able to SIGINT (say) the foreground job in a shell session,
and return to the shell _prompt_ without terminating the whole
session, and you could do this in an emergency even if the job was a
full-screen application which had configured termios so that no
keystroke generated SIGINT.

But as far as I can see there's no actual way to do that. I wasn't
able to find any ioctl or termios call to send a signal to a pty's
foreground pgrp, and you can't even do it manually via kill(2) because
first you'd have to find out what the pgrp id _is_, and according to
the man pages, you can only call tcgetpgrp on the slave end of the pty
and even then only if it's your controlling terminal.

So SS_SIGFOO goes to the child process, because that's the only place
I can find that I _can_ send it to sensibly.

SS_BRK translates to tcsendbreak, of course (though I haven't actually
seen any effect of calling this on a pty master, not even if I set
PARMRK on the slave end which by my understanding _ought_ to show me
when break events occur).
2018-10-21 10:02:10 +01:00
Simon Tatham
f2edea161a uxpty: give pty_backend_create a struct ssh_ttymodes.
This will be applied to the pty's termios settings at creation time,
superseding the default settings uxpty has always used. It works by
including the new sshttymodes.h with TTYMODES_LOCAL_ONLY defined, so
that modes not supported by a particular Unix system are automatically
quietly ignored.

Of course, a struct ssh_ttymodes always has the option of representing
"please make no change to the defaults", and of course, that's
precisely what is done by the one that pty_init constructs for clients
that aren't calling pty_backend_create directly.
2018-10-21 10:02:10 +01:00
Simon Tatham
105672e324 uxpty: new specialist backend-creation API.
The function that does the main pty setup is now called
pty_backend_create(), and has an API better suited to uxpty in
particular than the standard backend_init() virtual constructor. It
leaves off a load of standard parameters to backend_init() which
aren't really relevant to this backend, and it adds the 'argv'
parameter to pass in a split-up command line, which is unique to it.

The old creation function still exists, as a tiny wrapper that calls
the new pty_backend_create. And that version still gets the argv
parameter from the process-global variable pty_argv[], so the call
sites in pterm haven't had to change for this.

This will make it possible to instantiate a pty backend directly from
the SSH server code, without having to do anything really excessively
cumbersome to pass in a subcommand in the form of pre-split argv. (And
I'll add a few more specialist parameters to the new function shortly.)
2018-10-21 10:02:10 +01:00
Simon Tatham
0ee204f699 uxpty: propagate exit code more reliably on pty EIO.
There was a bit of a race condition depending on whether uxpty spotted
the EOF/EIO on the process's output first, or the SIGCHLD for its
actual termination: if the former came first, it would never bother to
reap the exit code at all.

It still doesn't bother if it's closing the session immediately and
the process genuinely _hasn't_ died (say, if it detaches itself
completely from the controlling tty to run in the background like a
weird parody of an old DOS TSR). But now when we see EOF, we make an
immediate (but nonblocking) attempt to wait for the child process, in
case its exit code was already available and we just hadn't noticed
yet.
2018-10-21 10:02:10 +01:00
Simon Tatham
c970d2b694 uxpty: send seat_eof when the pty master gives EIO.
The uxpty backend is going to be reused to implement the "session"
channel type in the upcoming SSH server implementation, which puts
quite a few new requirements on it. The first of them is that when we
get EOF from the subprocess's output channel (or rather, EIO from the
pty), we should actually notify the Seat of this.

In principle we should have been doing this all along, I'm pretty
sure. It hasn't happened to matter until now because the receiving
Seats haven't done much with that notification. But it will matter
when that's what controls the sending of SSH_MSG_CHANNEL_EOF.
2018-10-21 10:02:10 +01:00
Simon Tatham
99c215e761 Change Seat's get_char_cell_size to get_window_pixel_size.
That's more directly useful in uxpty.c (which is currently the only
actual client of the function), and also matches the data that SSH
clients send in "pty-req". Also, it makes that method behave more like
the GUI query function get_window_pixels used by terminal.c (with the
sole exception that unlike g_w_p it's allowed to return failure), so
it becomes even more trivial to implement in the GUI front ends.
2018-10-21 10:02:10 +01: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
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
9396fcc9f7 Rename FROMFIELD to 'container_of'.
Ian Jackson points out that the Linux kernel has a macro of this name
with the same purpose, and suggests that it's a good idea to use the
same name as they do, so that at least some people reading one code
base might recognise it from the other.

I never really thought very hard about what order FROMFIELD's
parameters should go in, and therefore I'm pleasantly surprised to
find that my order agrees with the kernel's, so I don't have to
permute every call site as part of making this change :-)
2018-10-06 07:28:51 +01:00
Simon Tatham
b798230844 Name vtable structure types more consistently.
Now they're all called FooVtable, instead of a mixture of that and
Foo_vtable.
2018-10-06 07:28:51 +01:00
Simon Tatham
96ec2c2500 Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.

All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.

A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 19:10:23 +01:00
Jonathan Liu
b5c840431a Suppress strncpy truncation warnings with GCC 8 and later.
These warnings are bogus as the code is correct so we suppress them in
the places they occur.
2018-09-26 14:40:26 +01:00
Simon Tatham
f4fbaa1bd9 Rework special-commands system to add an integer argument.
In order to list cross-certifiable host keys in the GUI specials menu,
the SSH backend has been inventing new values on the end of the
Telnet_Special enumeration, starting from the value TS_LOCALSTART.
This is inelegant, and also makes it awkward to break up special
handlers (e.g. to dispatch different specials to different SSH
layers), since if all you know about a special is that it's somewhere
in the TS_LOCALSTART+n space, you can't tell what _general kind_ of
thing it is. Also, if I ever need another open-ended set of specials
in future, I'll have to remember which TS_LOCALSTART+n codes are in
which set.

So here's a revamp that causes every special to take an extra integer
argument. For all previously numbered specials, this argument is
passed as zero and ignored, but there's a new main special code for
SSH host key cross-certification, in which the integer argument is an
index into the backend's list of available keys. TS_LOCALSTART is now
a thing of the past: if I need any other open-ended sets of specials
in future, I can add a new top-level code with a nicely separated
space of arguments.

While I'm at it, I've removed the legacy misnomer 'Telnet_Special'
from the code completely; the enum is now SessionSpecialCode, the
struct containing full details of a menu entry is SessionSpecial, and
the enum values now start SS_ rather than TS_.
2018-09-24 09:43:39 +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
eefebaaa9e Turn Backend into a sensible classoid.
Nearly every part of the code that ever handles a full backend
structure has historically done it using a pair of pointer variables,
one pointing at a constant struct full of function pointers, and the
other pointing to a 'void *' state object that's passed to each of
those.

While I'm modernising the rest of the code, this seems like a good
time to turn that into the same more or less type-safe and less
cumbersome system as I'm using for other parts of the code, such as
Socket, Plug, BinaryPacketProtocol and so forth: the Backend structure
contains a vtable pointer, and a system of macro wrappers handles
dispatching through that vtable.
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
e72e8ebe59 Expose the Ldisc structure tag throughout the code.
That's one fewer anonymous 'void *' which might be accidentally
confused with some other pointer type if I misremember the order of
function arguments.

While I'm here, I've made its pointer-nature explicit - that is,
'Ldisc' is now a typedef for the structure type itself rather than a
pointer to it. A stylistic change only, but it feels more natural to
me these days for a thing you're going to eventually pass to a 'free'
function.
2018-09-19 22:10:57 +01:00