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

1389 Commits

Author SHA1 Message Date
Simon Tatham
4fb20b15f3 Move random_save_seed() into sshrand.c.
It's identical in uxnoise and winnoise, being written entirely in
terms of existing cross-platform functions. Might as well centralise
it into sshrand.c.
2019-05-05 20:28:00 +01:00
Simon Tatham
64fdc85b2d Fix miscellaneous minor memory leaks.
All found by Coverity.
2019-05-05 10:14:24 +01:00
Simon Tatham
e82ba498ff Fix broken error path on open failure in PROXY_FUZZ.
We have to use the file name we just failed to open to format an error
message _before_ freeing it, not after. If that use-after-free managed
not to cause a crash, we'd also leak the file descriptor 'outfd'.

Both spotted by Coverity (which is probably the first thing in years
to look seriously at any of the code designed for Ben's AFL exercise).
2019-05-05 08:39:15 +01:00
Simon Tatham
97a1021202 Fix handling of Return and keypad Enter.
The recent rewriting in both the GTK and Windows keyboard handlers
left the keypad 'Enter' key in a bad state, when no override is
enabled that causes it to generate an escape sequence.

On Windows, a series of fallbacks was causing it to generate \r
regardless of configuration, whereas in Telnet mode it should default
to generating the special Telnet new-line sequence, and in response to
ESC[20h (enabling term->cr_lf_return) it should generate \r\n.

On GTK, it wasn't generating anything _at all_, and also, I can't see
any evidence that the GTK keyboard handler had ever remembered to
implement the cr_lf_return mode.

Now Keypad Enter in non-escape-sequence mode should behave just like
Return, on both platforms.
2019-04-15 20:43:10 +01:00
Simon Tatham
56198afb5c provide_xrm_string: report a more sensible program name.
It was always issuing an error message beginning "pterm:", even when
the application was GTK PuTTY or Unix Plink.
2019-04-13 19:13:45 +01:00
Simon Tatham
2692bfe8ee provide_xrm_string: make argument type const char *.
All call sites so far have happened to pass it a mutable string, but
it doesn't actually need one.
2019-04-13 19:09:56 +01:00
Simon Tatham
f9e2c7b1fe Uppity: option to disallow SSH-1 compression.
With this and the ciphers, I think we've now got the full range of
SSH-1 config options (such as they are) that correspond to varying the
KEXINIT strings in SSH-2.
2019-04-01 20:17:44 +01:00
Simon Tatham
cbff2d1960 Uppity: configurable list of SSH-1 ciphers to allow. 2019-04-01 20:10:09 +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
2e3a1c6d69 Uppity: make a separate AuthPolicy per connection.
Despite the name, AuthPolicy in uxserver.c was also holding the state
of the current connection, including in particular how far through the
multi-step test keyboard-interactive interaction we are. But now that
Uppity can handle multiple connections in the same run, we need to
reset that state between connections. So the tree234s of acceptable
user keys now live in an AuthPolicyShared structure, and AuthPolicy
proper is a field of server_instance.
2019-04-01 09:06:12 +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
efff6b874a Uppity: bring --help up to date.
I've been busily adding new options, and forgot to document them all,
which will annoy me the next time I haven't used it for a week or two
if I don't write them all up now.
2019-03-31 21:17:25 +01:00
Simon Tatham
6d7a6d47e6 Uppity: option to use a pregenerated key for RSA kex.
As and when I make this SSH server into a test suite, I'm not going to
want to wait for a gratuitous RSA key generation in every test run. So
now you can provide one in advance.

It has to be in SSH-1 format, because that's the format for which I
happen to already have internal API routines that return an RSAKey
instead of an opaque ssh_key. But since you also have to store it
without a passphrase, that doesn't really matter anyway.
2019-03-31 21:08:55 +01:00
Simon Tatham
7a49ff9ac1 sk_namelookup: fix memory leak on error exit path.
I remembered to strbuf_free(realhost) on the IPv4-only error exit path
if gethostbyname() returns failure, but not on the _default_ one if
getaddrinfo() does.
2019-03-31 11:14:13 +01:00
Simon Tatham
b9db527102 Uppity: enable the des-cbc cipher.
There was no way to enable it for testing purposes at all until now.
Overriding the server KEX string to mention it doesn't help when it
was prevented from getting into the list that scan_kexinit_lists will
go through afterwards to find pointers to algorithm structures.
2019-03-31 10:35:10 +01:00
Simon Tatham
d990dfc395 Uppity: add a --listen-once option.
This modifies 'uppity --listen' so that it closes the listening socket
after the first connection comes in.
2019-03-31 10:35:10 +01:00
Simon Tatham
443ad75a81 Uppity: add a --listen mode, protected by /proc/net/tcp.
Uppity is not secure enough to listen on a TCP port as if it was a
normal SSH server. Until now, I've been using it by means of a local
proxy command, i.e. PuTTY invokes Uppity in the same way it might
invoke 'plink -nc'. This rigorously prevents any hostile user from
connecting to my utterly insecure test server, but it's a thundering
inconvenience as soon as you want to attach a debugger to the Uppity
process itself - you have to stick a gdbserver somewhere in the middle
of your already complicated shell pipeline, and then find a way to
connect back to it from a gdb in a terminal window.

So I've added an option to make Uppity listen on a TCP port in the
normal way - but it's protected using that /proc/net/tcp trick I just
added in the previous commit.
2019-03-31 10:35:10 +01:00
Simon Tatham
3b51644f2b Add a /proc/net magic authenticator.
This is a Linux-specific trick that I'm quite fond of: I've used it
before in 'agedu' and a lot of my unpublished personal scriptery.

Suppose you want to run a listening network server in such a way that
it can only accept connections from processes under your own control.
Often it's not convenient to do this by adding an authentication step
to the protocol itself (either because the password management gets
hairy or because the protocol is already well defined). The 'right'
answer is to switch from TCP to Unix-domain sockets, because then you
can use the file permissions on the path leading to the socket inode
to ensure that no other user id can connect to it - but that's often
inconvenient as well, because if any _client_ of the server is not
already prepared to speak AF_UNIX your control then you can only trick
it into connecting to an AF_UNIX socket instead of TCP by applying a
downstream patch or resorting to LD_PRELOAD shenanigans.

But on Linux, there's an alternative shenanigan available, in the form
of /proc/net/tcp (or tcp6), which lists every currently active TCP
endpoint known to the kernel, and for each one, lists an owning uid.
Listen on localhost only. Then, when a connection comes in, look up
the far end of it in that file and see if the owning uid is the right
one!

I've always vaguely wondered if there would be uses for this trick in
PuTTY. One potentially useful one might be to protect the listening
sockets created by local-to-remote port forwarding. But for the
moment, I'm only planning to use it for a less security-critical
purpose, which will appear in the next commit.
2019-03-31 10:35:10 +01:00
Simon Tatham
b494ecfcfc Uppity: allow CLI override of the KEXINIT strings.
This is an obviously useful test feature, since if nothing else it
will let me exercise every individual crypto primitive, even the ones
that the client-side configuration is too coarse-grained to describe
in detail (such as the difference between CBC and CTR mode versions of
the same cipher).
2019-03-31 10:35:10 +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
4bb1867788 uxserver.c: 'longoptnoarg' matching function.
Replaces a couple of existing strcmp, and does just slightly better
because as well as matching "--verbose" (say) it also matches
"--verbose=foo" and gives a comprehensible error message about it.
2019-03-31 10:35:10 +01:00
Simon Tatham
e566972f00 Uppity: configurable SSH-2 authentication banner.
I've had to test banner handling several times recently, what with
trust sigils and the fix for CONF_ssh_show_banner. So it's the thing
I've most wanted to keep reconfiguring about Uppity so far.
2019-03-28 18:36:45 +00:00
Simon Tatham
8a884eaef9 Start of an SSH-server-specific config structure.
This is much simpler than Conf, because I don't expect to have to copy
it around, load or save it to disk (or the Windows registry), or
serialise it between processes. So it can be a straightforward struct.

As yet there's nothing actually _in_ it. I've just created the
structure and arranged to pass it through to all the SSH layers. But
now it's here, it will be a place I can add configuration items as I
find I need them.
2019-03-28 18:29:13 +00:00
Simon Tatham
c2df294e9e Autoconf workaround for missing <glob.h>.
glob.h is another missing facility in Android+Termux.

The workaround is to condition out local wildcard support completely,
so that PSFTP commands like 'mput *.txt' won't manage to do anything.
But at least the program will compile.
2019-03-26 19:21:29 +00:00
Simon Tatham
9375d1325f Autoconf workaround for lack of setpwent / endpwent.
Test-building inside Termux on Android, it seems that <pwd.h> in that
environment defines the important functions getpwnam and getpwuid, but
not the setpwent/endpwent with which we bookend them. Tolerate their
absence.
2019-03-26 19:19:28 +00:00
Simon Tatham
235f5bf8ae Check for auxv.h and hwcap.h before including them.
uClibc-ng does not provide <sys/auxv.h>, and a non-Linux-kernel-based
Unixlike system running on Arm will probably not provide
<asm/hwcap.h>. Now we check for both of those headers at autoconf
time, and if either one is absent, we don't do the runtime test for
Arm crypto acceleration.

This should only make a difference on systems where this module
previously failed to compile at all. But obviously it would be nicer
to find alternative ways to check for crypto acceleration on such
systems; patches welcome.
2019-03-26 19:19:28 +00:00
Simon Tatham
94f955fa90 Add an autoconf test and workaround for futimes(3).
Not every system provides it (e.g. uClibc-ng); if one does not, the
Uppity SFTP server should now degrade sensibly to refusing attempts to
set the utimes on an already-open file.
2019-03-26 18:44:19 +00:00
Simon Tatham
e9f0abad2e uxpoll.c: cope with missing #defines in poll.h.
Baruch Siach reports that in a uClibc-ng build environment, POLLRDNORM
and friends are only defined by poll.h if you #define _XOPEN_SOURCE
before including it. So now we do that, in case it helps - and we also
cope with those #defines still being absent, in case on some other
system even that doesn't help.
2019-03-26 18:44:19 +00:00
Simon Tatham
7631875d41 Re-enable trust sigils on Restart Session.
In my eagerness to make sure we didn't _accidentally_ change the
seat's trust status back to trusted at any point, I forgot to do it on
purpose if a second SSH login phase is legitimately run in the same
terminal after the first session has ended.
2019-03-20 15:07:32 +00:00
Simon Tatham
f6d1fef2d7 Handle <limits.h> not defining PIPE_BUF.
According to POSIX, this can legally not be defined 'where the [...]
value is equal to or greater than the stated minimum, but where the
value can vary depending on the file to which it is applied'. So if
limits.h hasn't defined PIPE_BUF, we define it ourself to the stated
minimum, to wit, _POSIX_PIPE_BUF.

Apparently it is actually undefined by <limits.h> on GNU/Hurd: Debian
has been carrying this patch downstream for that reason.
2019-03-20 13:09:34 +00:00
Colin Watson
6ce6fe5712 Use the SELECT_* enum for a few more uxsel flags.
This cleans up some spots that were missed in 47202c4e16.
2019-03-20 11:39:05 +00: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
2a5d8e05e8 Add a TermWin method to draw a 'trust sigil'.
This is not yet used by anything, but the idea is that it'll be a
graphic in the terminal window that can't be replicated by a server
sending escape sequences, and hence can be used as a reliable
indication that the text on a particular terminal line is generated by
PuTTY itself and not passed through from the server. This will make it
possible to detect a malicious server trying to mimic local prompts to
trick you out of information that shouldn't be sent over the wire
(such as private-key passphrases).

The trust sigil I've picked is a small copy of the PuTTY icon, which
is thematically nice (it can be read as if the PuTTY icon is the name
of the speaker in a dialogue) and also convenient because we had that
graphic available already on all platforms. (Though the contortions I
had to go through to make the GTK 1 code draw it were quite annoying.)

The trust sigil has the same dimensions as a CJK double-width
character, i.e. it's 2 character cells wide by 1 high.
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
767a9c6e45 Add a 'from_server' flag in prompts_t.
This goes with the existing 'to_server' flag (indicating whether the
values typed by the user are going to be sent over the wire or remain
local), to indicate whether the _text of the prompts_ has come over
the wire or is originated locally.

Like to_server, nothing yet uses this. It's a hedge against the
possibility of maybe having an option for all the auth prompts to work
via GUI dialog boxes.
2019-03-16 12:25:23 +00:00
Simon Tatham
daf91ef8ae Fix crash on ESC#6 + combining chars + GTK + odd-width terminal.
When we're displaying double-width text as a result of the VT100 ESC#6
escape sequence or its friends, and the terminal width is an odd
number of columns, we divide by 2 the number of characters we'll even
try to display, and round _down_: if there's a rightmost odd column,
it stays blank, and doesn't show the left half of a double-width char.

In the GTK redraw function, that rounding-down can set the 'len'
variable to zero. But when we're displaying a character with Unicode
combining chars on top, that fails an assertion that len == 1, because
at the top of the function we set it to 1.

The fix is just to return early if len is reduced to zero by that
rounding: if we're not displaying any characters, then we don't have
to do anything at all.
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
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
f098dc748d Fix build failures under GTK 1.
My previous dodge to make the GTK 1 headers work with modern compilers
was to manually reset to -std=gnu89, which changed the semantics of
'inline' back to what glib.h was expecting. But that doesn't work now
the PuTTY code base expects to be able to use the rest of C99, so
instead I have to manually override the specific #defines that glib.h
uses to know how 'inline' works.

Also, moved that code in configure.ac out of the fallback branch that
manually detects GTK1, so that it will fire even if autoconf is run on
a system that still has the genuine GTK1 detection code. (Amazingly,
one still exists that I have access to!)

With that fixed, there's one more problem: the nethack_mode and
app_keypad_mode flags in gtkwin.c's key_event() are only used in the
GTK >= 2 branch of the ifdefs, so they should only be declared and set
in that branch as well, on pain of a -Wunused complaint.
2019-03-12 08:06:20 +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
d62a369af8 PSCP, PSFTP: don't duplicate slashes in dir_file_cat.
Now if a pathname ends with a slash already, we detect that (using the
shiny new ptrlen_endswith), and don't bother putting another one in.

No functional change, but this should improve the occasional error
message, e.g. 'pscp remote:some.filename /' will now say it can't
create /some.filename instead of //some.filename.
2019-03-09 16:21:49 +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
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
bde7b6b158 Change sensitive strbufs/sgrowarrays to the new _nm version.
The _nm strategy is slower, so I don't want to just change everything
over no matter what its contents. In this pass I've tried to catch
everything that holds the _really_ sensitive things like passwords,
private keys and session keys.
2019-03-02 06:54:17 +00:00
Simon Tatham
b9f20b84f3 log_proxy_stderr: limit the length of Event Log lines.
If a proxy command jabbers on standard error in a way that doesn't
involve any newline characters, we now won't keep buffering data for
ever.

(Not that I've heard of it happening, but I noticed the theoretical
possibility on the way past in a recent cleanup pass.)
2019-03-02 06:54:17 +00: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
4ecc3f3c09 Fix a couple of syntactically dangerous macros.
The live versions of the dmemdump macros had a trailing semicolon in
the expansion, which would cause them to break if used in the wrong
syntactic context (e.g. between if and else with the natural semicolon
at the call site). The conditioned-out versions of those and of
debug() itself expanded to the empty string in place of the more usual
((void)0). And SECOND_PASS_ONLY in gtkmain.c's command-line handling
should have had the standard do ... while(0) wrapper to make it
reliably a single statement.
2019-02-28 18:00:31 +00:00
Simon Tatham
d07d7d66f6 Replace more ad-hoc growing char buffers with strbuf.
I've fixed a handful of these where I found them in passing, but when
I went systematically looking, there were a lot more that I hadn't
found!

A particular highlight of this collection is the code that formats
Windows clipboard data in RTF, which was absolutely crying out for
strbuf_catf, and now it's got it.
2019-02-28 06:42:37 +00:00
Simon Tatham
91cf47dd0d Plink: default to sanitising non-tty console output.
If Plink's standard output and/or standard error points at a Windows
console or a Unix tty device, and if Plink was not configured to
request a remote pty (and hence to send a terminal-type string), then
we apply the new control-character stripping facility.

The idea is to be a mild defence against malicious remote processes
sending confusing escape sequences through the standard error channel
when Plink is being used as a transport for something like git: it's
OK to have actual sensible error messages come back from the server,
but when you run a git command, you didn't really intend to give the
remote server the implicit licence to write _all over_ your local
terminal display. At the same time, in that scenario, the standard
_output_ of Plink is left completely alone, on the grounds that git
will be expecting it to be 8-bit clean. (And Plink can tell that
because it's redirected away from the console.)

For interactive login sessions using Plink, this behaviour is
disabled, on the grounds that once you've sent a terminal-type string
it's assumed that you were _expecting_ the server to use it to know
what escape sequences to send to you.

So it should be transparent for all the use cases I've so far thought
of. But in case it's not, there's a family of new command-line options
like -no-sanitise-stdout and -sanitise-stderr that you can use to
forcibly override the autodetection of whether to do it.

This all applies the same way to both Unix and Windows Plink.
2019-02-20 07:27:22 +00:00
Simon Tatham
5dadbdf556 ssh_sftp_do_select: don't fail if a callback is pending.
ssh_sftp_loop_iteration() used to return failure if no file handle was
in use for the select loop, on the basis that that means select would
just loop forever. But if there's a toplevel callback pending - in
particular, if it's going to do something like emptying ssh->in_raw
which will put an fd _back into_ the next iteration of the select loop
- then that's not a good enough reason to return permanent failure.
Just go round the loop, run the callback, and try again.
2019-02-17 20:30:14 +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
f133abe521 Give a sensible error when using a too-short RSA key.
The ssh_signkey vtable has grown a new method ssh_key_invalid(), which
checks whether the key is going to be usable for constructing a
signature at all. Currently the only way this can fail is if it's an
RSA key so short that there isn't room to put all the PKCS#1
formatting in the signature preimage integer, but the return value is
an arbitrary error message just in case more reasons are needed later.

This is tested separately rather than at key-creation time because of
the signature flags system: an RSA key of intermediate length could be
valid for SHA-1 signing but not for SHA-512. So really this method
should be called at the point where you've decided what sig flags you
want to use, and you're checking if _those flags_ are OK.

On the verification side, there's no need for a separate check. If
someone presents us with an RSA key so short that it's impossible to
encode a valid signature using it, then we simply regard all
signatures as invalid.
2019-02-10 09:05:47 +00:00
Simon Tatham
8ccbd164c7 uxsftpserver: cast st.st_size to uintmax_t.
This fixes a build failure reported by Colin on platforms (armel,
mipsel) where off_t and PRIu64 don't match.
2019-02-07 20:06:55 +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
0aa8cf7b0d Add some missing 'const'.
plug_receive(), sftp_senddata() and handle_gotdata() in particular now
take const pointers. Also fixed 'char *receive_data' in struct
ProxySocket.
2019-02-06 21:46:10 +00:00
Simon Tatham
acc21c4c0f Stop using unqualified {GET,PUT}_32BIT.
Those were a reasonable abbreviation when the code almost never had to
deal with little-endian numbers, but they've crept into enough places
now (e.g. the ECC formatting) that I think I'd now prefer that every
use of the integer read/write macros was clearly marked with its
endianness.

So all uses of GET_??BIT and PUT_??BIT are now qualified. The special
versions in x11fwd.c, which used variable endianness because so does
the X11 protocol, are suffixed _X11 to make that clear, and where that
pushed line lengths over 80 characters I've taken the opportunity to
name a local variable to remind me of what that extra parameter
actually does.
2019-02-04 20:32:31 +00:00
Simon Tatham
0212b9e5e5 sk_net_close: fix memory leak of output bufchain.
If there was still pending output data on a NetSocket's output_data
bufchain when it was closed, then we wouldn't have freed it, on either
Unix or Windows.
2019-01-29 20:54:19 +00:00
Simon Tatham
8329d192be uxnet: clean up callbacks when closing a NetSocket.
uxnet.c's method for passing socket errors on to the Plug involves
setting up a toplevel callback using the NetSocket itself as the
context. Therefore, it should call delete_callbacks_for_context when
it destroys a NetSocket. For example, if _two_ socket errors manage to
occur, and the first one causes the socket to be closed, you need the
second callback to not happen, or it'll dereference the freed pointer.
2019-01-29 20:54:19 +00:00
Simon Tatham
af3ccd7946 Unix sk_namelookup: fix compile failure at -DNO_IPV6.
The variable 'strbuf *realhost' was only initialised in the branch of
the ifdefs where IPV6 is enabled, so at NO_IPV6, it's used
uninitialised, which in my usual build configuration means a compile
failure.
2019-01-29 20:54:19 +00:00
Simon Tatham
dc2fdb8acf Support hardware SHA-256 and SHA-1 on Arm platforms.
Similarly to my recent addition of NEON-accelerated AES, these new
implementations drop in alongside the SHA-NI ones, under a different
set of ifdefs. All the details of selection and detection are
essentially the same as they were for the AES code.
2019-01-23 22:36:17 +00:00
Simon Tatham
320bf8479f Replace PuTTY's PRNG with a Fortuna-like system.
This tears out the entire previous random-pool system in sshrand.c. In
its place is a system pretty close to Ferguson and Schneier's
'Fortuna' generator, with the main difference being that I use SHA-256
instead of AES for the generation side of the system (rationale given
in comment).

The PRNG implementation lives in sshprng.c, and defines a self-
contained data type with no state stored outside the object, so you
can instantiate however many of them you like. The old sshrand.c still
exists, but in place of the previous random pool system, it's just
become a client of sshprng.c, whose job is to hold a single global
instance of the PRNG type, and manage its reference count, save file,
noise-collection timers and similar administrative business.

Advantages of this change include:

 - Fortuna is designed with a more varied threat model in mind than my
   old home-grown random pool. For example, after any request for
   random numbers, it automatically re-seeds itself, so that if the
   state of the PRNG should be leaked, it won't give enough
   information to find out what past outputs _were_.

 - The PRNG type can be instantiated with any hash function; the
   instance used by the main tools is based on SHA-256, an improvement
   on the old pool's use of SHA-1.

 - The new PRNG only uses the completely standard interface to the
   hash function API, instead of having to have privileged access to
   the internal SHA-1 block transform function. This will make it
   easier to revamp the hash code in general, and also it means that
   hardware-accelerated versions of SHA-256 will automatically be used
   for the PRNG as well as for everything else.

 - The new PRNG can be _tested_! Because it has an actual (if not
   quite explicit) specification for exactly what the output numbers
   _ought_ to be derived from the hashes of, I can (and have) put
   tests in cryptsuite that ensure the output really is being derived
   in the way I think it is. The old pool could have been returning
   any old nonsense and it would have been very hard to tell for sure.
2019-01-23 22:36:17 +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
628e794832 Replace random_byte() with random_read().
This is in preparation for a PRNG revamp which will want to have a
well defined boundary for any given request-for-randomness, so that it
can destroy the evidence afterwards. So no more looping round calling
random_byte() and then stopping when we feel like it: now you say up
front how many random bytes you want, and call random_read() which
gives you that many in one go.

Most of the call sites that had to be fixed are fairly mechanical, and
quite a few ended up more concise afterwards. A few became more
cumbersome, such as mp_random_bits, in which the new API doesn't let
me load the random bytes directly into the target integer without
triggering undefined behaviour, so instead I have to allocate a
separate temporary buffer.

The _most_ interesting call site was in the PKCS#1 v1.5 padding code
in sshrsa.c (used in SSH-1), in which you need a stream of _nonzero_
random bytes. The previous code just looped on random_byte, retrying
if it got a zero. Now I'm doing a much more interesting thing with an
mpint, essentially scaling a binary fraction repeatedly to extract a
number in the range [0,255) and then adding 1 to it.
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
891c2b9616 Uppity X forwarding: fix SockAddr use after free.
Another thing pointed out by ASan: new_unix_listener takes ownership
of the SockAddr you give it, so I shouldn't have been freeing it at
the end of platform_make_x11_server().
2019-01-23 21:19:26 +00:00
Simon Tatham
e7edc6e7ba Uppity: fix an unterminated dupcat in X server setup.
Address Sanitiser pointed this out; I surely can't have run Uppity
under ASan before, or I'd have noticed this months ago.
2019-01-23 21:18:55 +00:00
Simon Tatham
0d2d20aad0 Access all hashes and MACs through the standard API.
All the hash-specific state structures, and the functions that
directly accessed them, are now local to the source files implementing
the hashes themselves. Everywhere we previously used those types or
functions, we're now using the standard ssh_hash or ssh2_mac API.

The 'simple' functions (hmacmd5_simple, SHA_Simple etc) are now a pair
of wrappers in sshauxcrypt.c, each of which takes an algorithm
structure and can do the same conceptual thing regardless of what it
is.
2019-01-20 17:09:24 +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
53747ad3ab Support hardware AES on Arm platforms.
The refactored sshaes.c gives me a convenient slot to drop in a second
hardware-accelerated AES implementation, similar to the existing one
but using Arm NEON intrinsics in place of the x86 AES-NI ones.

This needed a minor structural change, because Arm systems are often
heterogeneous, containing more than one type of CPU which won't
necessarily all support the same set of architecture features. So you
can't test at run time for the presence of AES acceleration by
querying the CPU you're running on - even if you found a way to do it,
the answer wouldn't be reliable once the OS started migrating your
process between CPUs. Instead, you have to ask the OS itself, because
only that knows about _all_ the CPUs on the system. So that means the
aes_hw_available() mechanism has to extend a tentacle into each
platform subdirectory.

The trickiest part was the nest of ifdefs that tries to detect whether
the compiler can support the necessary parts. I had successful
test-compiles on several compilers, and was able to run the code
directly on an AArch64 tablet (so I know it passes cryptsuite), but
it's likely that at least some Arm platforms won't be able to build it
because of some path through the ifdefs that I haven't been able to
test yet.
2019-01-16 22:08:50 +00:00
Simon Tatham
2edae0d9d6 GTK: unregister dialog boxes before delivering the result.
When the user clicks 'yes' to a 'weak crypto primitive' warning, and
another such warning is pending next in line, we were failing an
assertion when ssh2transport called register_dialog() for the second
warning box, because the result callback in gtkdlg.c had not called
unregister_dialog() for the previous one yet. Now that's done before
rather than after delivering the result to the dialog's client.
2019-01-13 17:14:08 +00:00
Simon Tatham
35690040fd Remove a lot of pointless 'struct' keywords.
This is the commit that f3295e0fb _should_ have been. Yesterday I just
added some typedefs so that I didn't have to wear out my fingers
typing 'struct' in new code, but what I ought to have done is to move
all the typedefs into defs.h with the rest, and then go through
cleaning up the legacy 'struct's all through the existing code.

But I was mostly trying to concentrate on getting the test suite
finished, so I just did the minimum. Now it's time to come back and do
it better.
2019-01-04 08:04:39 +00:00
Simon Tatham
0112936ef7 Replace assert(false) with an unreachable() macro.
Taking a leaf out of the LLVM code base: this macro still includes an
assert(false) so that the message will show up in a typical build, but
it follows it up with a call to a function explicitly marked as no-
return.

So this ought to do a better job of convincing compilers that once a
code path hits this function it _really doesn't_ have to still faff
about with making up a bogus return value or filling in a variable
that 'might be used uninitialised' in the following code that won't be
reached anyway.

I've gone through the existing code looking for the assert(false) /
assert(0) idiom and replaced all the ones I found with the new macro,
which also meant I could remove a few pointless return statements and
variable initialisations that I'd already had to put in to placate
compiler front ends.
2019-01-03 08:12:28 +00:00
Simon Tatham
25b034ee39 Complete rewrite of PuTTY's bignum library.
The old 'Bignum' data type is gone completely, and so is sshbn.c. In
its place is a new thing called 'mp_int', handled by an entirely new
library module mpint.c, with API differences both large and small.

The main aim of this change is that the new library should be free of
timing- and cache-related side channels. I've written the code so that
it _should_ - assuming I haven't made any mistakes - do all of its
work without either control flow or memory addressing depending on the
data words of the input numbers. (Though, being an _arbitrary_
precision library, it does have to at least depend on the sizes of the
numbers - but there's a 'formal' size that can vary separately from
the actual magnitude of the represented integer, so if you want to
keep it secret that your number is actually small, it should work fine
to have a very long mp_int and just happen to store 23 in it.) So I've
done all my conditionalisation by means of computing both answers and
doing bit-masking to swap the right one into place, and all loops over
the words of an mp_int go up to the formal size rather than the actual
size.

I haven't actually tested the constant-time property in any rigorous
way yet (I'm still considering the best way to do it). But this code
is surely at the very least a big improvement on the old version, even
if I later find a few more things to fix.

I've also completely rewritten the low-level elliptic curve arithmetic
from sshecc.c; the new ecc.c is closer to being an adjunct of mpint.c
than it is to the SSH end of the code. The new elliptic curve code
keeps all coordinates in Montgomery-multiplication transformed form to
speed up all the multiplications mod the same prime, and only converts
them back when you ask for the affine coordinates. Also, I adopted
extended coordinates for the Edwards curve implementation.

sshecc.c has also had a near-total rewrite in the course of switching
it over to the new system. While I was there, I've separated ECDSA and
EdDSA more completely - they now have separate vtables, instead of a
single vtable in which nearly every function had a big if statement in
it - and also made the externally exposed types for an ECDSA key and
an ECDH context different.

A minor new feature: since the new arithmetic code includes a modular
square root function, we can now support the compressed point
representation for the NIST curves. We seem to have been getting along
fine without that so far, but it seemed a shame not to put it in,
since it was suddenly easy.

In sshrsa.c, one major change is that I've removed the RSA blinding
step in rsa_privkey_op, in which we randomise the ciphertext before
doing the decryption. The purpose of that was to avoid timing leaks
giving away the plaintext - but the new arithmetic code should take
that in its stride in the course of also being careful enough to avoid
leaking the _private key_, which RSA blinding had no way to do
anything about in any case.

Apart from those specific points, most of the rest of the changes are
more or less mechanical, just changing type names and translating code
into the new API.
2018-12-31 14:54:59 +00:00
Simon Tatham
85fbb4216e pscp: replace crash with diagnostic on opendir failure.
A user points out that the call to close_directory() in pscp.c's
rsource() function should have been inside rather than outside the if
statement that checks whether the directory handle is NULL. As a
result, any failed attempt to open a directory during a 'pscp -r'
recursive upload leads to a null-pointer dereference.

Moved the close_directory call to where it should be, and also
arranged to print the OS error code if the directory-open fails, by
also changing the API of open_directory to return an error string on
failure.
2018-12-27 16:52:23 +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
e08641c912 Start using C99 variadic macros.
In the past, I've had a lot of macros which you call with double
parentheses, along the lines of debug(("format string", params)), so
that the inner parens protect the commas and permit the macro to treat
the whole printf-style argument list as one macro argument.

That's all very well, but it's a bit inconvenient (it doesn't leave
you any way to implement such a macro by prepending another argument
to the list), and now this code base's rules allow C99isms, I can
switch all those macros to using a single pair of parens, using the
C99 ability to say '...' in the parameter list of the #define and get
at the corresponding suffix of the arguments as __VA_ARGS__.

So I'm doing it. I've made the following printf-style macros variadic:
bpp_logevent, ppl_logevent, ppl_printf and debug.

While I'm here, I've also fixed up a collection of conditioned-out
calls to debug() in the Windows front end which were clearly expecting
a macro with a different calling syntax, because they had an integer
parameter first. If I ever have a need to condition those back in,
they should actually work now.
2018-12-08 20:48:41 +00:00
Simon Tatham
41e1a586fb Centralise key escape sequences into terminal.c.
A long time ago, in commit 4d77b6567, I moved the generation of the
arrow-key escape sequences into a function format_arrow_key(). Mostly
the reason for that was a special purpose I had in mind at the time
which involved auto-generating the same sequences in response to
things other than a keypress, but I always thought it would be nice to
centralise a lot more of PuTTY's complicated keyboard handling in the
same way - at least the handling of the function keys and their
numerous static and dynamic config options.

In this year's general spirit of tidying up and refactoring, I think
it's finally time. So here I introduce three more centralised
functions for dealing with the numbered function keys, the small
keypad (Ins, Home, PgUp etc) and the numeric keypad. Lots of horrible
and duplicated code from the key handling functions in window.c and
gtkwin.c is now more sensibly centralised: each platform keyboard
handler concerns itself with the local format of a keyboard event and
platform-specific enumeration of key codes, and once it's decided what
the logical key press actually _is_, it hands off to the new functions
in terminal.c to generate the appropriate escape code.

Mostly this is intended to be a refactoring without functional change,
leaving the keyboard handling how it's always been. But in cases where
the Windows and GTK handlers were accidentally inconsistent, I've
fixed the inconsistency rather than carefully keeping both sides how
they were. Known consistency fixes:

 - swapping the arrow keys between normal (ESC [ A) and application
   (ESC O A) is now done by pressing Ctrl with them, and _not_ by
   pressing Shift. That was how it was always supposed to work, and
   how it's worked on GTK all along, but on Windows it's been done by
   Shift as well since 2010, due to a bug at the call site of
   format_arrow_key() introduced when I originally wrote that function.

 - in Xterm function key mode plus application keypad mode, the /*-
   keys on the numeric keypad now send ESC O {o,j,m} in place of ESC O
   {Q,R,S}. That's how the Windows keyboard handler has worked all
   along (it was a deliberate behaviour tweak for the Xterm-like
   function key mode, because in that mode ESC O {Q,R,S} are generated
   by F2-F4). But the GTK keyboard handler omitted that particular
   special case and was still sending ESC O {Q,R,S} for those keys in
   all application keypad modes.

 - also in Xterm function key mode plus app keypad mode, we only
   generates the app-keypad escape sequences if Num Lock is on; with
   Num Lock off, the numeric keypad becomes arrow keys and
   Home/End/etc, just as it would in non-app-keypad mode. Windows has
   done this all along, but again, GTK lacked that special case.
2018-12-08 16:08:47 +00:00
Simon Tatham
66b776ae6e Add some more miscellaneous asserts.
These clarify matters for static checkers (not to mention humans), and
seem inexpensive enough not to worry about adding.
2018-12-01 17:04:44 +00:00
Simon Tatham
b54147de4b Remove some redundant variables and assignments.
This fixes a batch of clang-analyzer warnings of the form 'you
declared / assigned this variable and then never use it'. It doesn't
fix _all_ of them - some are there so that when I add code in the
future _it_ can use the variable without me having to remember to
start setting it - but these are the ones I thought it would make the
code better instead of worse to fix.
2018-12-01 17:00:01 +00:00
Simon Tatham
4251d28f71 Replace several ad-hoc string formatters with strbuf.
uxnet.c's sk_namelookup and the sorting-key construction in
pangofont_enum_fonts() were both using s[n]printf and strncpy into
buffers that had no real need to be fixed-size; format_telnet_command
and the GTK Event Log selection-data builder were doing their own
sresize loops, but now we have strbuf they can just use that and save
redoing the same work.
2018-12-01 16:52:35 +00:00
Pavel I. Kryukov
a4b5f66d93 Remove 'static' qualifier from Conf pointer
Configuration pointer is globally visible from winstuff.h, so it cannot
be 'static' any longer.
2018-11-04 08:29:15 +00:00
Pavel I. Kryukov
80db674648 uxnet.c: initialize atmark variable
GCC 5 does not trace control flow graph and claims that the variable may
be used uninitialized. GCC 7 does not have this bug though.
2018-11-04 00:16:59 +00:00
Simon Tatham
c5895ec292 Move all extern declarations into header files.
This is another cleanup I felt a need for while I was doing
boolification. If you define a function or variable in one .c file and
declare it extern in another, then nothing will check you haven't got
the types of the two declarations mismatched - so when you're
_changing_ the type, it's a pain to make sure you've caught all the
copies of it.

It's better to put all those extern declarations in header files, so
that the declaration in the header is also in scope for the
definition. Then the compiler will complain if they don't match, which
is what I want.
2018-11-03 13:47:29 +00:00
Simon Tatham
91d16881ab Add missing 'static' on file-internal declarations.
sk_startup and sk_nextaddr are entirely internal to winnet.c; nearly
all of import.c and minibidi.c's internal routines should have been
static and weren't; {read,write}_utf8 are internal to charset/utf8.c
(and didn't even need separate declarations at all); do_sftp_cleanup
is internal to psftp.c, and get_listitemheight to gtkdlg.c.

While I was editing those prototypes anyway, I've also added missing
'const' to the 'char *' passphrase parameters in import,c.
2018-11-03 13:45:00 +00:00
Simon Tatham
c089827ea0 Rework mungestr() and unmungestr().
For a start, they now have different names on Windows and Unix,
reflecting their different roles: on Windows they apply escaping to
any string that's going to be used as a registry key (be it a session
name, or a host name for host key storage), whereas on Unix they're
for constructing saved-session file names in particular (and also
handle the special case of filling in "Default Settings" for NULL).

Also, they now produce output by writing to a strbuf, which simplifies
a lot of the call sites. In particular, the strbuf output idiom is
passed on to enum_settings_next, which is especially nice because its
only actual caller was doing an ad-hoc realloc loop that I can now get
rid of completely.

Thirdly, on Windows they're centralised into winmisc.c instead of
living in winstore.c, because that way Pageant can use the unescape
function too. (It was spotting the duplication there that made me
think of doing this in the first place, but once I'd started, I had to
keep unravelling the thread...)
2018-11-03 13:45:00 +00:00
Simon Tatham
3933a27d93 Make send_raw_mouse a field of GtkFrontend.
I came across this unexplained static variable in my boolification
trawl. It seems clearly unintentional that it has only one instance
instead of one per terminal window - the code in question closely
resembles the Windows front end, and I think this must just be a
variable that I never swept up into 'inst' in the very early days when
I was making gtkwin.c out of a cloned-and-hacked window.c in the first
place.

These days it's even a bug, now that the OS X port actually does run
multiple terminal windows in the same process: if one goes into mouse
reporting mode, I'm pretty sure this would have done confusing things
to the effects of mouse actions in the other.
2018-11-03 13:45:00 +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
Simon Tatham
a647f2ba11 Adopt C99 <stdint.h> integer types.
The annoying int64.h is completely retired, since C99 guarantees a
64-bit integer type that you can actually treat like an ordinary
integer. Also, I've replaced the local typedefs uint32 and word32
(scattered through different parts of the crypto code) with the
standard uint32_t.
2018-11-03 13:25:50 +00:00
Simon Tatham
5cb56389bd Remove three uses of bitwise ops on boolean values.
If values are boolean, it's confusing to use & and | in place of &&
and ||. In two of these three cases it was simply a typo and I've used
the other one; in the third, it was a deliberate avoidance of short-
circuit evaluation (and commented as such), but having seen how easy
it is to make the same typo by accident, I've decided it's clearer to
just move the LHS and RHS evaluations outside the expression.
2018-11-03 13:25:16 +00:00
Simon Tatham
1d459fc725 Fix misuse of FALSE for null pointer return values.
x11_char_struct returns a pointer or NULL, so while returning FALSE
would have ended up doing the right thing after macro expansion and
integer->pointer conversion, it wasn't actually how I _meant_ to spell
a failure return.
2018-11-03 08:09:29 +00:00
Simon Tatham
23e98b0afb Uppity: support SSH-2 password change request.
This is the first time I've _ever_ been able to test that feature of
the client userauth code personally, and pleasingly, it seems to work
fine.
2018-10-29 07:23:32 +00:00
Simon Tatham
730af28b99 Stop using deprecated gtk_container_set_focus_chain().
In GTK 2, this function was a new and convenient way to override the
order in which the Tab key cycled through the sub-widgets of a
container, replacing the more verbose mechanism in GTK 1 where you had
to provide a custom implementation of the "focus" method in
GtkContainerClass.

GTK 3.24 has now deprecated gtk_container_set_focus_chain(),
apparently on the grounds that that old system is what they think you
_ought_ to be doing. So I've abandoned set_focus_chain completely, and
switched back to doing it by a custom focus method for _all_ versions
of GTK, with the only slight wrinkle being that between GTK 1 and 2
the method in question moved from GtkContainer to GtkWidget (my guess
is so that an individual non-container widget can still have multiple
separately focusable UI components).
2018-10-28 09:14:53 +00:00
Simon Tatham
6750eb73ab Fix build failure on GTK 2.
In the TermWin revamp, I forgot to make sure I'd changed all the ifdef
branches for different major versions of GTK.
2018-10-26 23:05:53 +01:00
Simon Tatham
64f8f68a34 Remove the 'Frontend' type and replace it with a vtable.
After the recent Seat and LogContext revamps, _nearly_ all the
remaining uses of the type 'Frontend' were in terminal.c, which needs
all sorts of interactions with the GUI window the terminal lives in,
from the obvious (actually drawing text on the window, reading and
writing the clipboard) to the obscure (minimising, maximising and
moving the window in response to particular escape sequences).

All of those functions are now provided by an abstraction called
TermWin. The few remaining uses of Frontend after _that_ are internal
to a particular platform directory, so as to spread the implementation
of that particular kind of Frontend between multiple source files; so
I've renamed all of those so that they take a more specifically named
type that refers to the particular implementation rather than the
general abstraction.

So now the name 'Frontend' no longer exists in the code base at all,
and everywhere one used to be used, it's completely clear whether it
was operating in one of Frontend's three abstract roles (and if so,
which), or whether it was specific to a particular implementation.

Another type that's disappeared is 'Context', which used to be a
typedef defined to something different on each platform, describing
whatever short-lived resources were necessary to draw on the terminal
window: the front end would provide a ready-made one when calling
term_paint, and the terminal could request one with get_ctx/free_ctx
if it wanted to do proactive window updates. Now that drawing context
lives inside the TermWin itself, because there was never any need to
have two of those contexts live at the same time.

(Another minor API change is that the window-title functions - both
reading and writing - have had a missing 'const' added to their char *
parameters / return values.)

I don't expect this change to enable any particularly interesting new
functionality (in particular, I have no plans that need more than one
implementation of TermWin in the same application). But it completes
the tidying-up that began with the Seat and LogContext rework.
2018-10-25 18:49:17 +01:00
Simon Tatham
c9e6118246 Uppity: add challenge-response auth methods.
This adds the server side of the SSH-2 keyboard-interactive protocol,
and the pair of very similar SSH-1 methods AUTH_TIS and AUTH_CCARD
(which basically differ only in message numbers, and each involve a
single challenge from the server and a response from the user).
2018-10-22 20:32:58 +01:00
Simon Tatham
5f03613614 Improve Uppity's online help and command-line errors.
We now show the --help output if invoked with no arguments, and the
help text also includes a big safety warning in the hope of stopping
anyone from mistaking this for a _secure_ SSH server implementation.

While I'm here, the errors now all use appname[] in place of
constantly repeating the program name. (Not because I anticipate a
change right now, but if nothing else, it makes things easier moving
errors out into shared source files or between applications.)
2018-10-22 20:17:47 +01:00
Pavel I. Kryukov
1806b71241 uxsftpserver.c: do not let Clang think we append integer to string 2018-10-21 13:43:44 +01:00
Pavel I. Kryukov
fafb898891 uxserver.c: exit with 0 explicitly to make GCC 4 happy 2018-10-21 13:43:44 +01: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
aa162bbca1 Close standard handles in watchdog subprocesses.
Naturally, there's one really glaring goof I find out instants after
'git push'! If Pageant starts a watchdog subprocess which will wait
until the main process terminates and then clean up the socket, then
it had better not have that subprocess keep the standard I/O handles
open, or else commands like eval $(pageant -X) won't terminate.

I've applied the same fix in the X11 socket creation, though I think
it's less critical there.
2018-10-21 10:16:16 +01:00
Simon Tatham
a081dd0a4c Add an SFTP server to the SSH server code.
Unlike the traditional Unix SSH server organisation, the SFTP server
is built into the same process as all the rest of the code. sesschan.c
spots a subsystem request for "sftp", and responds to it by
instantiating an SftpServer object and swapping out its own vtable for
one that talks to it.

(I rather like the idea of an object swapping its own vtable for a
different one in the middle of its lifetime! This is one of those
tricks that would be absurdly hard to implement in a 'proper' OO
language, but when you're doing vtables by hand in C, it's no more
difficult than any other piece of ordinary pointer manipulation. As
long as the methods in both vtables expect the same physical structure
layout, it doesn't cause a problem.)

The SftpServer object doesn't deal directly with SFTP packet formats;
it implements the SFTP server logic in a more abstract way, by having
a vtable method for each SFTP request type with an appropriate
parameter list. It sends its replies by calling methods in another
vtable called SftpReplyBuilder, which in the normal case will write an
SFTP reply packet to send back to the client. So SftpServer can focus
more or less completely on the details of a particular filesystem API
- and hence, the implementation I've got lives in the unix source
directory, and works directly with file descriptors and struct stat
and the like.

(One purpose of this abstraction layer is that I may well want to
write a second dummy implementation, for test-suite purposes, with
completely controllable behaviour, and now I have a handy place to
plug it in in place of the live filesystem.)

In between sesschan's parsing of the byte stream into SFTP packets and
the SftpServer object, there's a layer in the new file sftpserver.c
which does the actual packet decoding and encoding: each request
packet is passed to that, which pulls the fields out of the request
packet and calls the appropriate method of SftpServer. It also
provides the default SftpReplyBuilder which makes the output packet.

I've moved some code out of the previous SFTP client implementation -
basic packet construction code, and in particular the BinarySink/
BinarySource marshalling fuinction for fxp_attrs - into sftpcommon.c,
so that the two directions can share as much as possible.
2018-10-21 10:02:10 +01:00
Simon Tatham
1d323d5c80 Add an actual SSH server program.
This server is NOT SECURE! If anyone is reading this commit message,
DO NOT DEPLOY IT IN A HOSTILE-FACING ENVIRONMENT! Its purpose is to
speak the server end of everything PuTTY speaks on the client side, so
that I can test that I haven't broken PuTTY when I reorganise its
code, even things like RSA key exchange or chained auth methods which
it's hard to find a server that speaks at all.

(For this reason, it's declared with [UT] in the Recipe file, so that
it falls into the same category as programs like testbn, which won't
be installed by 'make install'.)

Working title is 'Uppity', partly for 'Universal PuTTY Protocol
Interaction Test Yoke', but mostly because it looks quite like the
word 'PuTTY' with part of it reversed. (Apparently 'test yoke' is a
very rarely used term meaning something not altogether unlike 'test
harness', which is a bit of a stretch, but it'll do.)

It doesn't actually _support_ everything I want yet. At the moment,
it's a proof of concept only. But it has most of the machinery
present, and the parts it's missing - such as chained auth methods -
should be easy enough to add because I've built in the required
flexibility, in the form of an AuthPolicy object which can request
them if it wants to. However, the current AuthPolicy object is
entirely trivial, and will let in any user with the password "weasel".

(Another way in which this is not a production-ready server is that it
also has no interaction with the OS's authentication system. In
particular, it will not only let in any user with the same password,
but it won't even change uid - it will open shells and forwardings
under whatever user id you started it up as.)

Currently, the program can only speak the SSH protocol on its standard
I/O channels (using the new FdSocket facility), so if you want it to
listen on a network port, you'll have to run it from some kind of
separate listening program similar to inetd. For my own tests, I'm not
even doing that: I'm just having PuTTY spawn it as a local proxy
process, which also conveniently eliminates the risk of anyone hostile
connecting to it.

The bulk of the actual code reorganisation is already done by previous
commits, so this change is _mostly_ just dropping in a new set of
server-specific source files alongside the client-specific ones I
created recently. The remaining changes in the shared SSH code are
numerous, but all minor:

 - a few extra parameters to BPP and PPL constructors (e.g. 'are you
   in server mode?'), and pass both sets of SSH-1 protocol flags from
   the login to the connection layer
 - in server mode, unconditionally send our version string _before_
   waiting for the remote one
 - a new hook in the SSH-1 BPP to handle enabling compression in
   server mode, where the message exchange works the other way round
 - new code in the SSH-2 BPP to do _deferred_ compression the other
   way round (the non-deferred version is still nicely symmetric)
 - in the SSH-2 transport layer, some adjustments to do key derivation
   either way round (swapping round the identifying letters in the
   various hash preimages, and making sure to list the KEXINITs in the
   right order)
 - also in the SSH-2 transport layer, an if statement that controls
   whether we send SERVICE_REQUEST and wait for SERVICE_ACCEPT, or
   vice versa
 - new ConnectionLayer methods for opening outgoing channels for X and
   agent forwardings
 - new functions in portfwd.c to establish listening sockets suitable
   for remote-to-local port forwarding (i.e. not under the direction
   of a Conf the way it's done on the client side).
2018-10-21 10:02:10 +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
9fe719f47d Server prep: parse a lot of new channel requests.
ssh2connection.c now knows how to unmarshal the message formats for
all the channel requests we'll need to handle when we're the server
and a client sends them. Each one is translated into a call to a new
method in the Channel vtable, which is implemented by a trivial
'always fail' routine in every channel type we know about so far.
2018-10-21 10:02:10 +01:00
Simon Tatham
61976b417e Server prep: routine to create a local X display.
This will be used for the server side of X forwarding. It wraps up the
mechanics of listening on the right TCP port and (if possible) the
associated AF_UNIX socket, and also creates an appropriate X authority
file containing authorisation data provided by its caller.

Like the new platform_create_agent_socket, this function spawns a
watchdog subprocess to clean up the mess afterwards, in the hope of at
least _most_ of the time not leaving old sockets and authority files
lying around /tmp,
2018-10-21 10:02:10 +01:00
Simon Tatham
f4db9196da Factor out Unix Pageant's socket creation.
The code in Pageant that sets up the Unix socket and its containing
directory now lives in a separate file, uxagentsock.c, where it will
also be callable from the upcoming new SSH server when it wants to
create a similar socket for agent forwarding.

While I'm at it, I've also added a feature to create a watchdog
subprocess that will try to clean up the socket and directory once
Pageant itself terminates, in the hope of leaving less cruft lying
around /tmp.
2018-10-21 10:02:10 +01:00
Simon Tatham
d3a9142dac Allow channels not to close immediately after two EOFs.
Some kinds of channel, even after they've sent EOF in both directions,
still have something to do before they initiate the CLOSE mechanism
and wind up the channel completely. For example, a session channel
with a subprocess running inside it will want to be sure to send the
"exit-status" or "exit-signal" notification, even if that happens
after bidirectional EOF of the data channels.

Previously, the SSH-2 connection layer had the standard policy that
once EOF had been both sent and received, it would start the final
close procedure. There's a method chan_want_close() by which a Channel
could vary this policy in one direction, by indicating that it wanted
the close procedure to commence after EOF was sent in only one
direction. Its parameters are a pair of booleans saying whether EOF
has been sent, and whether it's been received.

Now chan_want_close can vary the policy in the other direction as
well: if it returns FALSE even when _both_ parameters are true, the
connection layer will honour that, and not send CHANNEL_CLOSE. If it
does that, the Channel is responsible for indicating when it _does_
want close later, by calling sshfwd_initiate_close.
2018-10-21 10:02:10 +01:00
Simon Tatham
82c83c1894 Improve sk_peer_info.
Previously, it returned a human-readable string suitable for log
files, which tried to say something useful about the remote end of a
socket. Now it returns a whole SocketPeerInfo structure, of which that
human-friendly log string is just one field, but also some of the same
information - remote IP address and port, in particular - is provided
in machine-readable form where it's available.
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
c95b277798 Unix: turn LocalProxySocket into a general FdSocket.
The new FdSocket just takes an arbitrary pair of file descriptors to
read and write, optionally with an extra input fd providing the
standard error output from a command. uxproxy.c now just does the
forking and pipe setup, and once it's got all its fds, it hands off to
FdSocket to actually do the reading and writing.

This is very like the reorganisation I did on the Windows side in
commit 98a6a3553 (back in 2013, in preparation for named-pipe sockets
and connection sharing). The idea is that it should enable me to make
a thing that the PuTTY code base sees as a Socket, but which actually
connects to the standard I/O handles of the process it lives in.
2018-10-21 10:02:10 +01:00
Simon Tatham
d1cd8b2591 Move channel-opening logic out into subroutines.
Each of the new subroutines corresponds to one of the channel types
for which we know how to parse a CHANNEL_OPEN, and has a collection of
parameters corresponding to the fields of that message structure.
ssh2_connection_filter_queue now confines itself to parsing the
message, calling one of those functions, and constructing an
appropriate reply message if any.
2018-10-21 10:02:10 +01:00
Simon Tatham
2339efcd83 Devolve channel-request handling to Channel vtable.
Instead of the central code in ssh2_connection_filter_queue doing both
the job of parsing the channel request and deciding whether it's
acceptable, each Channel vtable now has a method for every channel
request type we recognise.
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
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
a3a8b28528 Tidy up 'eventlog_stuff' structure and fix leak.
This is the structure that stores the truncated version of the Event
Log data to be displayed by the GTK Event Log dialog. It persists for
the lifetime of the parent SSH window, so it was deliberate that it
wasn't freed on destruction of the dialog itself, but I also forgot to
free it on destruction of the SSH window. (This will be more important
in multi-connection process architectures like the OS X port, of
course.)

While I'm at it, I'll follow my recent practice by exposing the
structure tag outside gtkdlg.c so that callers can more easily not
confuse it with some other kind of void *.
2018-10-08 19:30:01 +01:00
Simon Tatham
9072bab11b Unix: fix segfault if ~/.putty/sessions doesn't exist.
Looks as if I introduced this in commit 733fcca2c, where the pointer
returned from enum_settings_start() stopped being the same thing as
the underlying 'DIR *' - I needed to retain a check for the outer
containing structure not being NULL but the DIR * being NULL inside
it.
2018-10-07 14:05:53 +01:00
Simon Tatham
0bbe87f11e Rewrite some comments with FIXMEs in them.
These are things where no fix was actually necessary in the code, but
the FIXME indicated that the comment itself was either in need of a
rewrite or removal.
2018-10-06 11:57:59 +01:00
Simon Tatham
e655053942 Add a couple of missing 'static' qualifiers. 2018-10-06 11:57:59 +01:00
Simon Tatham
07f99e6e82 Remove 'defused' parameter from wc_to_mb.
It's never set to anything but NULL at any call site, and there's been
a FIXME comment in uxucs.c for ages saying it should be removed. I
think it only existed in the first place because it was a facility
supported by the underlying Windows API function and we couldn't see a
reason _not_ to pass it through. But I'm cleaning up FIXMEs, so we
should get rid of it.

(It stood for 'default used', incidentally - as in 'did the function
at any point have to make use of the parameter providing a default
fallback character?'. Nothing to do with _defusing_ things :-)
2018-10-06 11:57:59 +01:00
Simon Tatham
461ade43d1 Return an error message from x11_setup_display.
The lack of one of those has been a long-standing FIXME for ages.
2018-10-06 11:10:13 +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
ed652a70e8 Get rid of #ifdef DEFINE_PLUG_METHOD_MACROS.
I don't actually know why this was ever here; it appeared in the very
first commit that invented Plug in the first place (7b0e08270) without
explanation. Perhaps Dave's original idea was that sometimes you'd
need those macros _not_ to be defined so that the same names could be
reused as the methods for a particular Plug instance? But I don't
think that ever actually happened, and the code base builds just fine
with those macros defined unconditionally just like all the other sets
of method macros we now have, so let's get rid of this piece of cruft
that was apparently unnecessary all along.
2018-10-06 07:28:51 +01:00
Simon Tatham
884a7df94b Make Socket and Plug into structs.
I think that means that _every_ one of my traitoids is now a struct
containing a vtable pointer as one of its fields (albeit sometimes the
only field), and never just a bare pointer.
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
e0130a48ca Switch the unifont system over to using FROMFIELD.
Now that I'm doing that in so many of the new classes as a more
type-safe alternative to ordinary C casts, I should make sure all the
old code is also reaping the benefits. This commit converts the system
of unifont vtables in the GTK front end, and also the 'unifontsel'
structure that exposes only a few of its fields outside gtkfont.c.
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
Simon Tatham
5a6608bda8 Unix GUI: honour 'no close on exit' for connection_fatal.
It was being treated like an application-fatal message box even if
you'd configured the window not to close on an unclean exit.
2018-09-28 19:23:08 +01:00
Simon Tatham
7cd425abab uxproxy: close input pipes that have seen EOF on read.
Otherwise we loop round repeatedly with the event loop continuing to
report the same EOF condition on them over and over again, consuming
CPU pointlessly and probably causing other knock-on trouble too.
2018-09-28 19:23:08 +01:00
Simon Tatham
3085e74807 GTK uxsel handling: lump G_IO_HUP into G_IO_IN.
Without this, we don't receive EOF notifications on pipes, because gtk
uses poll rather than select, which separates those out into distinct
event types.
2018-09-28 19:23:08 +01:00
Simon Tatham
32a0de93bc Defer error callback from localproxy_try_send.
If you call plug_closing directly from localproxy_try_send, which can
in turn be called directly from sk_write, then the plug's
implementation of plug_closing may well free things that the caller of
sk_write expected not to have vanished.

The corresponding routine in uxnet.c pushes that call to plug_closing
into a toplevel callback, so let's do that here too.
2018-09-28 19:23:05 +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
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
aa08e6ca91 Put a layer of abstraction in front of struct ssh_channel.
Clients outside ssh.c - all implementations of Channel - will now not
see the ssh_channel data type itself, but only a subobject of the
interface type SshChannel. All the sshfwd_* functions have become
methods in that interface type's vtable (though, wrapped in the usual
kind of macros, the call sites look identical).

This paves the way for me to split up the SSH-1 and SSH-2 connection
layers and have each one lay out its channel bookkeeping structure as
it sees fit; as long as they each provide an implementation of the
sshfwd_ method family, the types behind that need not look different.

A minor good effect of this is that the sshfwd_ methods are no longer
global symbols, so they don't have to be stubbed in Unix Pageant to
get it to compile.
2018-09-19 23:08:27 +01:00
Simon Tatham
733fcca2cd Invent structure tags for the storage.h abstractions.
Most of these were 'void *' because they weren't even reliably a
structure type underneath - the per-OS storage systems would directly
cast read/write/enum settings handles to and from random things like
FILE *, Unix DIR *, or Windows HKEY. So I've wrapped them in tiny
structs for the sake of having a sensible structure tag visible
elsewhere in the code.
2018-09-19 23:08:07 +01:00
Simon Tatham
7efa4a5305 Clean up a 'void *' in a unix.h typedef.
'struct draw_ctx' has a structure tag inside gtkwin.c, so as per this
week's standard practice, let's expose the tag elsewhere so that
pointers declared that way can't be confused with anything else.
2018-09-19 23:08:07 +01:00
Simon Tatham
3aae1f9d76 Expose the structure tag 'dlgparam'.
This continues my ongoing crusade against dangerous 'void *'
parameters.
2018-09-19 23:08:07 +01:00
Simon Tatham
08b43c0cca Expose structure tags for the connection-sharing data types.
This was a particularly confusing piece of type-danger, because three
different types were passed outside sshshare.c as 'void *' and only
human vigilance prevented one coming back as the wrong one. Now they
all keep their opaque structure tags when they move through other
parts of the code.
2018-09-19 23:08:07 +01:00
Simon Tatham
6a8b9d3813 Replace enum+union of local channel types with a vtable.
There's now an interface called 'Channel', which handles the local
side of an SSH connection-layer channel, in terms of knowing where to
send incoming channel data to, whether to close the channel, etc.

Channel and the previous 'struct ssh_channel' mutually refer. The
latter contains all the SSH-specific parts, and as much of the common
logic as possible: in particular, Channel doesn't have to know
anything about SSH packet formats, or which SSH protocol version is in
use, or deal with all the fiddly stuff about window sizes - with the
exception that x11fwd.c's implementation of it does have to be able to
ask for a small fixed initial window size for the bodgy system that
distinguishes upstream from downstream X forwardings.

I've taken the opportunity to move the code implementing the detailed
behaviour of agent forwarding out of ssh.c, now that all of it is on
the far side of a uniform interface. (This also means that if I later
implement agent forwarding directly to a Unix socket as an
alternative, it'll be a matter of changing just the one call to
agentf_new() that makes the Channel to plug into a forwarding.)
2018-09-19 23:08:04 +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
Simon Tatham
6c924ba862 GPG key rollover.
This commit adds the new ids and fingerprints in the keys appendix of
the manual, and moves the old ones down into the historic-keys
section. I've tweaked a few pieces of wording for ongoing use, so that
they don't imply a specific number of past key rollovers.

The -pgpfp option in all the tools now shows the new Master Key
fingerprint and the previous (2015) one. I've adjusted all the uses of
the #defines in putty.h so that future rollovers should only have to
modify the #defines themselves.

Most importantly, sign.sh bakes in the ids of the current release and
snapshot keys, so that snapshots will automatically be signed with the
new snapshot key and the -r option will invoke the new release key.
2018-08-25 14:38:47 +01:00
Simon Tatham
452114c3d3 New memory management macro 'snew_plus'.
This formalises my occasional habit of using a single malloc to make a
block that contains a header structure and a data buffer that a field
of the structure will point to, allowing it to be freed in one go
later. Previously I had to do this by hand, losing the type-checking
advantages of snew; now I've written an snew-style macro to do the
job, plus an accessor macro to cleanly get the auxiliary buffer
pointer afterwards, and switched existing instances of the pattern
over to using that.
2018-06-06 07:22:06 +01:00
Simon Tatham
0603256964 Unix Pageant: add alias '-L' for '--private-openssh'.
Matches the -L option in Unix PuTTYgen, and is much easier to type.
2018-06-03 16:52:25 +01:00
Simon Tatham
025599ec99 Unix PuTTYgen: switch to /dev/urandom by default.
The general wisdom these days - in particular as given by the Linux
urandom(4) man page - seems to be that there's no need to use the
blocking /dev/random any more unless you're running at very early boot
time when the system random pool is at serious risk of not having any
entropy in it at all.

In case of non-Linux systems that don't think /dev/urandom is a
standard name, I fall back to /dev/random if /dev/urandom can't be
found.
2018-06-03 15:15:51 +01:00
Simon Tatham
7f56e1e365 Remove 'keystr' parameter in get_rsa_ssh1_pub.
This parameter returned a substring of the input, which was used for
two purposes. Firstly, it was used to hash the host and server keys
during the initial SSH-1 key setup phase; secondly, it was used to
check the keys in Pageant against the public key blob of a key
specified on the command line.

Unfortunately, those two purposes didn't agree! The first one needs
just the bare key modulus bytes (without even the SSH-1 mpint length
header); the second needs the entire key blob. So, actually, it seems
to have never worked in SSH-1 to say 'putty -i keyfile' and have PuTTY
find that key in Pageant and not have to ask for the passphrase to
decrypt the version on disk.

Fixed by removing that parameter completely, which simplifies all the
_other_ call sites, and replacing it by custom code in those two
places that each does the actually right thing.
2018-06-03 08:24:59 +01:00
Simon Tatham
6dc6392596 Remove obsolete functions.
There are several old functions that the previous commits have removed
all, or nearly all, of the references to. match_ssh_id is superseded
by ptrlen_eq_string; get_ssh_{string,uint32} is yet another replicated
set of decode functions (this time _partly_ centralised into misc.c);
the old APIs for the SSH-1 RSA decode functions are gone (together
with their last couple of holdout clients), as are
ssh{1,2}_{read,write}_bignum and ssh{1,2}_bignum_length.

Particularly odd was the use of ssh1_{read,write}_bignum in the SSH-2
Diffie-Hellman implementation. I'd completely forgotten I did that!
Now replaced with a raw bignum_from_bytes, which is simpler anyway.
2018-06-02 18:24:12 +01:00
Simon Tatham
876e1589f8 Rewrite conf deserialisation using BinarySource.
Like the corresponding rewrite of conf serialisation, this affects not
just conf_deserialise itself but also the per-platform filename and
fontspec deserialisers.
2018-06-02 17:52:48 +01:00
Simon Tatham
5129c40bea Modernise the Socket/Plug vtable system.
Now I've got FROMFIELD, I can rework it so that structures providing
an implementation of the Socket or Plug trait no longer have to have
the vtable pointer as the very first thing in the structure. In
particular, this means that the ProxySocket structure can now directly
implement _both_ the Socket and Plug traits, which is always
_logically_ how it's worked, but previously it had to be implemented
via two separate structs linked to each other.
2018-05-27 15:28:54 +01:00
Simon Tatham
7babe66a83 Make lots of generic data parameters into 'void *'.
This is a cleanup I started to notice a need for during the BinarySink
work. It removes a lot of faffing about casting things to char * or
unsigned char * so that some API will accept them, even though lots of
such APIs really take a plain 'block of raw binary data' argument and
don't care what C thinks the signedness of that data might be - they
may well reinterpret it back and forth internally.

So I've tried to arrange for all the function call APIs that ought to
have a void * (or const void *) to have one, and those that need to do
pointer arithmetic on the parameter internally can cast it back at the
top of the function. That saves endless ad-hoc casts at the call
sites.
2018-05-26 09:22:43 +01:00
Simon Tatham
c9bad331e6 Centralise TRUE and FALSE definitions into defs.h.
This removes a lot of pointless duplications of those constants.

Of course, _ideally_, I should upgrade to C99 bool throughout the code
base, replacing TRUE and FALSE with true and false and tagging
variables explicitly as bool when that's what they semantically are.
But that's a much bigger piece of work, and shouldn't block this
trivial cleanup!
2018-05-26 09:19:39 +01:00
Simon Tatham
0c44fa85df Build outgoing SSH agent requests in a strbuf.
This simplifies the client code both in ssh.c and in the client side
of Pageant.

I've cheated a tiny bit by preparing agent requests in a strbuf that
has space reserved at the front for the packet frame, which makes life
easier for the code that sends them off.
2018-05-25 14:36:16 +01:00
Simon Tatham
67de463cca Change ssh.h crypto APIs to output to BinarySink.
This affects all the functions that generate public and private key
and signature blobs of all kinds, plus ssh_ecdhkex_getpublic. Instead
of returning a bare block of memory and taking an extra 'int *length'
parameter, all these functions now write to a BinarySink, and it's the
caller's job to have prepared an appropriate one where they want the
output to go (usually a strbuf).

The main value of this change is that those blob-generation functions
were chock full of ad-hoc length-counting and data marshalling. You
have only to look at rsa2_{public,private}_blob, for example, to see
the kind of thing I was keen to get rid of!
2018-05-25 14:36:16 +01:00
Simon Tatham
a990738aca Use the BinarySink system for conf serialisation.
Now instead of iterating through conf twice in separate functions,
once to count up the size of the serialised data and once to write it
out, I just go through once and dump it all in a strbuf.

(Of course, I could still do a two-pass count-then-allocate approach
easily enough in this system; nothing would stop me writing a
BinarySink implementation that didn't actually store any data and just
counted its size, and then I could choose at each call site whether I
preferred to do it that way.)
2018-05-25 14:36:16 +01:00
Simon Tatham
4988fd410c Replace all uses of SHA*_Bytes / MD5Update.
In fact, those functions don't even exist any more. The only way to
get data into a primitive hash state is via the new put_* system. Of
course, that means put_data() is a viable replacement for every
previous call to one of the per-hash update functions - but just
mechanically doing that would have missed the opportunity to simplify
a lot of the call sites.
2018-05-25 14:36:16 +01:00
Simon Tatham
12b38ad9e1 New header file 'defs.h'.
This centralises a few things that multiple header files were
previously defining, and were protecting against each other's
redefinition with ifdefs - small things like structs and typedefs. Now
all those things are in a defs.h which is by definition safe to
include _first_ (out of all the codebase-local headers) and only need
to be defined once.
2018-05-25 14:12:44 +01:00
Simon Tatham
7e8ae41a3f Clean up the crufty old SSH-1 RSA API.
Lots of functions had really generic names (like 'makekey'), or names
that missed out an important concept (like 'rsakey_pubblob', which
loads a public blob from a _file_ and doesn't generate it from an
in-memory representation at all). Also, the opaque 'int order' that
distinguishes the two formats of public key blob is now a mnemonic
enumeration, and while I'm at it, rsa_ssh1_public_blob takes one of
those as an extra argument.
2018-05-25 14:08:24 +01:00
Simon Tatham
b8c4d042bd Fix startup hang in Unix file transfer tools.
This seems to be a knock-on effect of my recent reworking of the SSH
code to be based around queues and callbacks. The loop iteration
function in uxsftp.c (ssh_sftp_do_select) would keep going round its
select loop until something had happened on one of its file
descriptors, and then return to the caller in the assumption that the
resulting data might have triggered whatever condition the caller was
waiting for - and if not, then the caller checks, finds nothing
interesting has happened, and resumes looping with no harm done.

But now, when something happens on an fd, it doesn't _synchronously_
trigger the follow-up condition PSFTP was waiting for (which, at
startup time, happens to be back->sendok() starting to return TRUE).
Instead, it schedules a callback, which will schedule a callback,
which ... ends up setting that flag. But by that time, the loop
function has already returned, the caller has found nothing
interesting and resumed looping, and _now_ the interesting thing
happens but it's too late because ssh_sftp_do_select will wait until
the next file descriptor activity before it next returns.

Solution: give run_toplevel_callbacks a return value which says
whether it's actually done something, and if so, return immediately in
case that was the droid the caller was looking for. As it were.
2018-05-24 16:54:16 +01:00
Simon Tatham
9ee6a220e0 GTK: reinstate accidentally removed calls to term_size.
In commit 528513dde I absentmindedly replaced a write to the local
variable 'need_size' of drawing_area_setup with a write to
inst->drawing_area_setup_needed, imagining that they had the same
effect. But actually, need_size was doing two jobs and I only replaced
one of them: it was also the variable that indicated that the logical
terminal size had changed and so we had to call term_size() to make
the terminal.c data structures resize themselves appropriately. The
loss of that call also inhibited generation of SIGWINCH.
2018-05-19 07:38:22 +01:00
Simon Tatham
9d495b2176 Make {term,}get_userpass_input take a bufchain.
NFC for the moment, because the bufchain is always specially
constructed to hold exactly the same data that would have been passed
in to the function as a (pointer,length) pair. But this API change
allows get_userpass_input to express the idea that it consumed some
but not all of the data in the bufchain, which means that later on
I'll be able to point the same function at a longer-lived bufchain
containing the full stream of keyboard input and avoid dropping
keystrokes that arrive too quickly after the end of an interactive
password prompt.
2018-05-18 07:22:57 +01:00
Simon Tatham
a486318dad Remove unused params from cmdline_get_passwd_input.
NFC; I expect this to be a useful simplification for the same reasons
as the previous commit.
2018-05-18 07:22:56 +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
528513ddea GTK: remember to resize backing surface on a font change.
Changing the window's font size with Alt-< or Alt-> was not setting
any of the flags that make drawing_area_setup consider itself to have
been non-spuriously called, so the real window would enlarge without
the backing surface also doing so.
2018-05-17 11:20:01 +01:00
Simon Tatham
4467fa4d2a Unix Pageant: option to behave like ssh-askpass.
Since Pageant contains its own passphrase prompt system rather than
delegating it to another process, it's not trivial to use it in other
contexts. But having gone to the effort of coming up with my own
askpass system that (I think) does a better job at not revealing the
length of the password, I _want_ to use it in other contexts where a
GUI passphrase or password prompt is needed. Solution: an --askpass
option.
2018-05-14 08:08:34 +01:00
Simon Tatham
e6b06c900f Unix Pageant: options to select askpass type.
Mostly for debugging purposes, because I'm tired of having to use
'setsid' to force Pageant to select the GUI passphrase prompt when I'm
trying to fix bugs in gtkask.c. But I can also imagine situations in
which the ability to force a GUI prompt window might be useful to end
users, for example if the process does _technically_ have a
controlling terminal but it's not a user-visible one (say, in the back
end of some automation tool like expect(1)).

For symmetry, I also provide an option to force the tty prompt. That's
less obviously useful, because that's already the preferred prompt
type when both methods are available - so the only use for it would be
if you wanted to ensure that Pageant didn't _accidentally_ try to
launch a GUI prompt, and aborted with an error if it couldn't use a
tty prompt.
2018-05-14 07:41:08 +01:00
Simon Tatham
a3503fd234 gtkask: rework the mechanism for keyboard grabs.
I've found Unix Pageant's GTK password prompt to be a bit flaky on
Ubuntu 18.04. Part of the reason for that seems to be (I _think_) that
GTK has changed its internal order of setting things up, so that you
can no longer call gtk_widget_show_now() and expect that when it
returns everything is ready to do a gdk_seat_grab. Another part is
that - completely mysteriously as far as I can see - a _failed_
gdk_seat_grab(GDK_SEAT_CAPABILITY_KEYBOARD) has the side effect of
calling gdk_window_hide on the window you gave it!

So I've done a considerable restructuring that means we no longer
attempt to do the keyboard grab synchronously in gtk_askpass_setup.
Instead, we make keyboard grab attempts during the run of gtk_main,
scheduling each one on a timer if the previous attempt fails.

This means I need a visual indication of 'not ready for you to type
anything yet', which I've arranged by filling in the three drawing
areas to mid-grey. At the point when the keyboard grab completes and
the window becomes receptive to input, they turn into the usual one
black and two white.
2018-05-13 23:05:46 +01:00
Simon Tatham
383302d70a GTK 3: be aware of the window's scale factor.
In GTK 3.10 and above, high-DPI support is arranged by each window
having a property called a 'scale factor', which translates logical
pixels as seen by most of the GTK API (widget and window sizes and
positions, coordinates in the "draw" event, etc) into the physical
pixels on the screen. This is handled more or less transparently,
except that one side effect is that your Cairo-based drawing code had
better be able to cope with that scaling without getting confused.

PuTTY's isn't, because we do all our serious drawing on a separate
Cairo surface we made ourselves, and then blit subrectangles of that
to the window during updates. This has two bad consequences. Firstly,
our surface has a size derived from what GTK told us the drawing area
size is, i.e. corresponding to GTK's _logical_ pixels, so when the
scale factor is (say) 2, our drawing takes place at half size and then
gets scaled up by the final blit in the draw event, making it look
blurry and unpleasant. Secondly, those final blits seem to end up
offset by half a pixel, so that a second blit over the same
subrectangle doesn't _quite_ completely wipe out the previously
blitted data - so there's a ghostly rectangle left behind everywhere
the cursor has been.

It's not that GTK doesn't _let_ you find out the scale factor; it's
just that it's in an out-of-the-way piece of API that you have to call
specially. So now we do: our backing surface is now created at a pixel
resolution matching the screen's real pixels, and we translate GTK's
scale factor into an ordinary cairo_scale() before we commence
drawing. So we still end up drawing the same text at the same size -
and this strategy also means that non-text elements like cursor
outlines and underlining will be scaled up with the screen DPI rather
than stubbornly staying one physical pixel thick - but now it's nice
and sharp at full screen resolution, and the subrectangle blits in the
draw event are back to affecting the exact set of pixels we expect
them to.

One silly consequence is that, immediately after removing the last
one, I've installed a handler for the GTK "configure-event" signal!
That's because the GTK 3 docs claim that that's how you get notified
that your scale factor has changed at run time (e.g. if you
reconfigure the scale factor of a whole monitor in the GNOME settings
dialog). Actually in practice I seem to find out via the "draw" event
before "configure" bothers to tell me, but now I've got a usefully
idempotent function for 'check whether the scale factor has changed
and sort it out if so', I don't see any harm in calling it from
anywhere it _might_ be useful.
2018-05-11 09:27:57 +01:00
Simon Tatham
1ca03a186f gtkwin: factor out drawing_area_setup_simple().
I'm about to want to do this operation from more places, so here's a
minor NFC refactoring that will simplify the next commit.
2018-05-11 09:27:16 +01:00
Simon Tatham
412dce1e8a Stop using the GTK "configure-event" signal.
I've been using that signal since the very first commit of this source
file, as a combined way to be notified when the size of the drawing
area changes (typically due to user window resizing actions) and also
when the drawing area is first created and available to be drawn on.

Unfortunately, testing on Ubuntu 18.04, I ran into an oddity, in which
the call to gtk_widget_show(inst->window) in new_session_window() has
the side effect of delivering a spurious configure_event on the
drawing area with size 1x46 pixels. This causes the terminal to resize
itself to 1 column wide, and the mistake isn't rectified until a
followup configure-event arrives after new_session_window returns to
the GTK main loop. But that means terminal output can occur between
those two configure events (the connection-sharing "Reusing a shared
connection to host.name" is a good example), and when it does, it gets
embarrassingly wrapped at one character per line down the left column.

I briefly tried to bodge around this by trying to heuristically guess
which configure events were real and which were spurious, but I have
no faith in that strategy continuing to work. I think a better
approach is to abandon configure-event completely, and move to a
system in which the two purposes I was using it for are handled by two
_different_ GTK signals, namely "size-allocate" (for knowing when we
get resized) and "realize" (for knowing when the drawing area
physically exists for us to start setting up Cairo or GDK machinery).

The result seems to have fixed the silly one-column wrapping bug, and
retained the ability to handle window resizes, on every GTK version I
have conveniently available to test on, including GTK 3 both before
and after these spurious configures started to happen.
2018-05-10 20:22:02 +01:00
Simon Tatham
7fee4e9b43 Basic support for running under GDK Wayland back end.
GTK 3 PuTTY/pterm has always assumed that if it was compiled with
_support_ for talking to the raw X11 layer underneath GTK and GDK,
then it was entitled to expect that raw X11 layer to exist at all
times, i.e. that GDK_DISPLAY_XDISPLAY would return a meaningful X
display that it could do useful things with. So if you ran it over the
GDK Wayland backend, it would immediately segfault.

Modern GTK applications need to cope with multiple GDK backends at run
time. It's fine for GTK PuTTY to _contain_ the code to find and use
underlying X11 primitives like the display and the X window id, but it
should be prepared to find that it's running on Wayland (or something
else again!) so those functions don't return anything useful - in
which case it should degrade gracefully to the subset of functionality
that can be accessed through backend-independent GTK calls.

Accordingly, I've centralised the use of GDK_DISPLAY_XDISPLAY into a
support function get_x_display() in gtkmisc.c, which starts by
checking that there actually is one first. All previous direct uses of
GDK_*_XDISPLAY now go via that function, and check the result for NULL
afterwards. (To save faffing about calling that function too many
times, I'm also caching the display pointer in more places, and
passing it as an extra argument to various subfunctions, mostly in
gtkfont.c.)

Similarly, the get_windowid() function that retrieves the window id to
put in the environment of pterm's child process has to be prepared for
there not to be a window id.

This isn't a complete fix for all Wayland-related problems. The other
one I'm currently aware of is that the default font is "server:fixed",
which is a bad default now that it won't be available on all backends.
And I expect that further problems will show up with more testing. But
it's a start.
2018-05-09 09:21:27 +01:00
Simon Tatham
d515e4f1a3 Support GSS key exchange, for Kerberos 5 only.
This is a heavily edited (by me) version of a patch originally due to
Nico Williams and Viktor Dukhovni. Their comments:

 * Don't delegate credentials when rekeying unless there's a new TGT
   or the old service ticket is nearly expired.

 * Check for the above conditions more frequently (every two minutes
   by default) and rekey when we would delegate credentials.

 * Do not rekey with very short service ticket lifetimes; some GSSAPI
   libraries may lose the race to use an almost expired ticket. Adjust
   the timing of rekey checks to try to avoid this possibility.

My further comments:

The most interesting thing about this patch to me is that the use of
GSS key exchange causes a switch over to a completely different model
of what host keys are for. This comes from RFC 4462 section 2.1: the
basic idea is that when your session is mostly bidirectionally
authenticated by the GSSAPI exchanges happening in initial kex and
every rekey, host keys become more or less vestigial, and their
remaining purpose is to allow a rekey to happen if the requirements of
the SSH protocol demand it at an awkward moment when the GSS
credentials are not currently available (e.g. timed out and haven't
been renewed yet). As such, there's no need for host keys to be
_permanent_ or to be a reliable identifier of a particular host, and
RFC 4462 allows for the possibility that they might be purely
transient and only for this kind of emergency fallback purpose.

Therefore, once PuTTY has done a GSS key exchange, it disconnects
itself completely from the permanent host key cache functions in
storage.h, and instead switches to a _transient_ host key cache stored
in memory with the lifetime of just that SSH session. That cache is
populated with keys received from the server as a side effect of GSS
kex (via the optional SSH2_MSG_KEXGSS_HOSTKEY message), and used if
later in the session we have to fall back to a non-GSS key exchange.
However, in practice servers we've tested against do not send a host
key in that way, so we also have a fallback method of populating the
transient cache by triggering an immediate non-GSS rekey straight
after userauth (reusing the code path we also use to turn on OpenSSH
delayed encryption without the race condition).
2018-04-26 07:21:16 +01:00
Simon Tatham
510187a733 Ignore spurious configure_area events.
Colin Watson reports that on pre-releases of Ubuntu 18.04, configure
events which don't actually involve a change of window size show up
annoyingly often. Our handling of configure events involves throwing
away the backing Cairo surface, making a fresh blank one, and
scheduling a top-level callback to get terminal.c to do a repaint and
populate the new surface; so a draw event before that callback occurs
causes the window contents to flicker off and on again, not to mention
wasting a lot of time.

The simplest solution is to spot spurious configures, and respond by
not throwing away the previous Cairo surface in the first place.
2018-04-04 21:04:18 +01:00
Simon Tatham
97a248b463 Use gdk_display_beep() in place of obsolete gdk_beep().
Except in GTK1 (which doesn't have the former), via a gtkcompat.h
workaround.

Up-to-date GTK3 has deprecated gdk_beep(), causing build failures due
to the default -Werror setting.
2018-03-03 18:26:45 +00:00
Simon Tatham
0476ceaa08 GTK1 build fixes.
Looks as if I haven't retried the GTK1 build for a while, and recent
GTK frontend development has broken it. The selection revamp has
pointed out that GTK1 didn't have the accessor function
gtk_selection_data_get_selection(), the standard GdkAtom value
GDK_SELECTION_CLIPBOARD, or keysyms for alphabetic characters; and
also I had an initialisation of one of my own structure fields
(dp->selparams) accidentally not guarded by the same GTK-versioning
ifdef that controls whether or not it was defined.
2018-03-03 18:24:12 +00:00
Simon Tatham
31a2017af5 Add missing casts in dupcat().
Ahem. I _spotted_ this in code review, and forgot to make the change
before pushing!

Because it's legitimate for a C implementation to define 'NULL' so
that it expands to just 0, it follows that if you use NULL in a
variadic argument list where the callee will expect to extract a
pointer, you run the risk of putting an int-sized rather than
pointer-sized argument on the list and causing the consumer to get out
of sync. So you have to add an explicit cast.
2018-02-13 19:45:54 +00:00
Nico Williams
3447047594 Don't grow logevent buf indefinitely
The PuTTY GUIs (Unix and Windows) maintain an in-memory event log
for display to users as they request.  This uses ints for tracking
eventlog size, which is subject to memory exhaustion and (given
enough heap space) overflow attacks by servers (via, e.g., constant
rekeying).

Also a bounded log is more user-friendly.  It is rare to want more
than the initial logging and the logging from a few recent rekey
events.

The Windows fix has been tested using Dr. Memory as a valgrind
substitute.  No errors corresponding to the affected code showed up.
The Dr. Memory results.txt was split into a file per-error and then

    grep Error $(grep -l windlg *)|cut -d: -f3-|sort |uniq -c

was used to compare.  Differences arose from different usage of the GUI,
but no error could be traced to the code modified in this commit.

The Unix fix has been tested using valgrind.  We don't destroy the
eventlog_stuff eventlog arrays, so we can't be entirely sure that we
don't leak more than we did before, but from code inspection it looks
like we don't (and anyways, if we leaked as much as before, just without
the integer overflow, well, that's still an improvement).
2018-02-13 19:28:19 +00:00
Simon Tatham
b4fde270c6 Better file-existence test on Unix.
Now we don't annoyingly print the 'askappend' prompt if you ask a
PuTTY tool to write its packet log to something that's not a regular
file, such as /dev/fd/1 or /dev/tty or a named pipe.

(In the case of a named pipe, another annoyance fixed by this change
is that we also don't open it for reading in the course of the
existence test.)
2018-02-07 07:34:53 +00:00
Simon Tatham
bbebdc8280 Make file-existence test a per-platform function.
NFC in this commit, but this will allow me to do something more subtle
and OS-specific in each OS's implementation of it.
2018-02-07 07:34:53 +00:00
Simon Tatham
83eb8e0109 Build fixes for GTK2.
Apparently I haven't tried a GTK2 build since the most recent set of
GTK-related code reorganisation. Some functions that were ifdef'ed out
in GTK3 builds were now unused even in GTK2 builds (and, because they
were also declared static, caused a -Werror build failure); and the
pointless stub version of gtkapp.c was missing a stub version of a
recently added function referred to from another module.
2018-01-30 19:22:45 +00:00
Jacob Nevins
5f7604888b Let puttyapp/ptermapp build against old Gtk 3.
gtk_application_set_accels_for_action() is new in Gtk 3.12, but (e.g.)
Ubuntu 14.04 LTS still ships with Gtk 3.10.
On the other hand, the function I've used instead,
gtk_application_add_accelerator(), is deprecated from Gtk 3.14 onwards,
indicating that it will disappear in some future version, so I've left
the newer code in against that day.
2017-12-20 11:55:51 +00:00
Simon Tatham
8ec55ef25f osxlaunch: stop setting DYLD_LIBRARY_PATH.
It actually doesn't seem to be necessary: running 'otool -L' on the
real binary in the application bundle (Pterm-bin or PuTTY-bin) lists a
lot of paths starting with "@executable_path/../Resources/", which I
take to mean that the application is already set up to automatically
load the GTK shared libraries out of its own bundle directory, without
me having to give it the extra hint of DYLD_LIBRARY_PATH.

Moreover, I just got round to upgrading my Mac to High Sierra, and now
the version of osxlaunch _with_ DYLD_LIBRARY_PATH is causing a crash
at program load time, when the libpng in the MacOS system library
directory tries to use the libz in the application bundle and finds
that it doesn't provide an entry point it was expecting
('inflateValidate'). I could try to fix that by updating the libz
version in my OS X PuTTY build environment, but that seems to me to
set a precedent of running to keep up with any further dependencies
the system libraries happen to acquire in later releases. Better to
reset DYLD_LIBRARY_PATH so that the system libpng will load the system
libz and not get confused in the first place.
2017-12-20 10:04:02 +00:00
Simon Tatham
10e570cc79 osxlaunch: fix some uninitialised pointers.
I've been having intermittent segfaults in this launcher program, and
by means of the new TEST_COMPILE_ON_LINUX facility introduced by
commit eef8cac28, I ran it under valgrind which helpfully pointed out
several pointers between linked-list nodes which I'd been relying on
OS memory allocation to happen to have zeroed for me.
2017-12-20 10:03:51 +00:00
Simon Tatham
6b8cd49aa7 osxlaunch: add diagnostics under an #ifdef.
Now I can compile with -DDEBUG_OSXLAUNCH and see exactly what the
program is doing, if I suspect it of misbehaviour.
2017-12-20 10:03:51 +00:00
Simon Tatham
eef8cac28e osxlaunch: bodge to let me test-build on Linux.
By default, the program still builds on Linux to a stub that just
prints 'nothing to see here'. But if you compile with
-DTEST_COMPILE_ON_LINUX, it compiles to a program that still doesn't
do anything _actually_ useful, but goes through all the same motions
that real osxlaunch would go through, until the final execv(2) fails
because of course it's not _really_ living in an application bundle
directory of the right shape.

That allows me to run all the setup code under the debugging tools I'm
most used to, in my preferred environment. (Same rationale as having
puttyapp / ptermapp build for Linux too.)
2017-12-20 10:03:14 +00:00
Simon Tatham
faef0ea679 Rewrite the OS X TODO a bit.
I've filled in the results of some not-entirely-conclusive
investigation into the trackpad scrolling issue, some thoughts on
resizing, and reordered the items into what currently seems the most
sensible order to me.
2017-12-18 14:04:57 +00:00
Simon Tatham
04184c87cc Fill in some more of the OS X menu bar.
This still isn't complete: I also need to add the variable collections
of things like mid-session special commands and saved session names,
and also I need to try to grey out menu items when they're not
applicable. But it's a start.
2017-12-18 11:46:48 +00:00
Simon Tatham
2065fb647f Minor refactoring of gtkapp.c -> gtkwin.c menu triggers.
Just to avoid an endless proliferation of functions too small to see,
I've arranged an enumeration of action ids and a single
app_menu_action function on the receiving end, and in gtkapp.c, a list
macro that means I at least don't have to define the tiny callback
functions and the GActionEntry records by hand and keep them in sync.
2017-12-18 11:19:26 +00:00
Simon Tatham
31080bf8a7 Add keyboard accelerators in the GtkApplication menu.
Now that they actually _work_, it seems more useful to start putting
them in on purpose.
2017-12-18 11:01:42 +00:00
Simon Tatham
1904c404ed OS X: pass Command key back to GTK if it's not being Meta.
This fixes the problem I'd previously noticed, that if you don't
configure the "Command key acts as Meta" setting, then keystrokes like
Command-Q which _ought_ to function as accelerators for the
application menu bar don't.

Turns out that this was for the totally obvious reason: the keyboard
event was still being processed by gtkwin.c's key_event() and
translated via the GTK IM into ordinary keyboard input. If instead I
return FALSE from key_event on detecting that a key event has a
non-Meta-configured Command modifier, then it will go to the next-
level key-event handler inside GTK itself which implements the menu
accelerator behaviour. Another problem ticked off the OS X checklist.
2017-12-18 10:43:13 +00:00
Simon Tatham
3faca7724a Correct the OS X branch of the clipboards ifdef.
That's what I get for not testing on all platforms before I push.
Forgot that, since OS X GTK mimics X11 GTK closely enough to still use
the name "CLIPBOARD" for the unique system clipboard, I had left this
code base's internal name for it as CLIP_CLIPBOARD and not the
CLIP_SYSTEM I used on Windows.
2017-12-18 10:31:42 +00:00
Simon Tatham
136c119da6 Fix linked-list mismanagement.
Oh dear. I have no excuse.
2017-12-17 20:43:44 +00:00
Simon Tatham
7bc637ad07 Sort out clipboard-related menu items.
The gtkapp.c menu now has a Copy as well as Paste option; those menu
items, as well as the corresponding ones on the context menu and Copy
All, now address sets of clipboards parametrised between OS X and
ordinary GTK in unix.h. Also I've tweaked the wording of the
context-menu items to not use the X-specific terminology "CLIPBOARD"
on OS X.
2017-12-17 20:35:45 +00:00
Simon Tatham
1ed2f98c89 Add missing g_application_hold on Duplicate Session.
The omission of this call caused a GTK assertion failure when the
GApplication's use count went negative after two releases and only one
hold.
2017-12-17 20:18:20 +00:00
Simon Tatham
1af9c425ba Better protection against stale clipboard_data_instances.
I had a segfault on OS X today at Pterm.app shutdown. I wasn't able to
reproduce it in a debugger, but the cause seemed to be that
clipboard_clear called term_deselect (this was from before the patch
series that renamed that function) when inst->term was already NULL.

This must be because a clipboard_data_instance outlived its associated
inst->term, and quite likely its associated inst as well. But we can't
free those structures when a gui_data is freed, because GTK callbacks
will still depend on them; so instead we must have each gui_data keep
a list of active cdis pointing at it, and then at destruction time,
walk along the list nulling out each one's pointer to part of itself.
2017-12-17 20:12:52 +00:00
Simon Tatham
2a76f8d4a2 Support custom clipboard names under X.
This required me to turn the drop-lists into combo boxes and add an
extra string-typed Conf setting alongside each enumerated value.
2017-12-17 18:49:00 +00:00
Simon Tatham
018aa57645 Tick off another two OS X todo items.
I've done the general clipboard revamp, and also, since I added
Ctrl-Shift-{C,V} as a new pair of UI actions for copy and paste, I've
also fulfilled the requirement that there should be some method of
non-menu-based pasting that doesn't depend on a middle mouse button or
an Ins key.

I think the list of OS X missing features is now down to details of
the OS X GTK port _itself_, as opposed to structural issues in the
general code base.
2017-12-17 17:02:56 +00:00
Simon Tatham
0e7f0883a9 Add GUI configuration for choice of clipboards.
On all platforms, you can now configure which clipboard the mouse
pastes from, which clipboard Ctrl-Ins and Shift-Ins access, and which
Ctrl-Shift-C and Ctrl-Shift-V access. In each case, the options are:

 - nothing at all
 - a clipboard which is implicitly written by the act of mouse
   selection (the PRIMARY selection on X, CLIP_LOCAL everywhere else)
 - the standard clipboard written by explicit copy/paste UI actions
   (CLIPBOARD on X, the unique system clipboard elsewhere).

Also, you can control whether selecting text with the mouse _also_
writes to the explicitly accessed clipboard.

The wording of the various messages changes between platforms, but the
basic UI shape is the same everywhere.
2017-12-17 17:02:56 +00:00
Simon Tatham
3d9372492d GTK context menu options to copy/paste CLIPBOARD. 2017-12-16 13:52:23 +00:00
Simon Tatham
131a8e9468 Ability to copy to multiple clipboards at once. 2017-12-16 13:52:23 +00:00
Simon Tatham
41aa675a5b Make gtkwin.c able to support multiple selections.
All the data fields referring to the selection in 'struct gui_data'
have been pulled out into a separate structure of which there are now
multiple instances, and I've plumbed through what should be the right
pointers and integer ids to everywhere they should go. So now the GTK
front end defines CLIP_PRIMARY and CLIP_CLIPBOARD in place of the
temporary cop-out CLIP_SYSTEM from the previous commit, and copying
and pasting can be done via either one.

The defaults should be the same as before, except that now the non-Mac
versions of the GtkApplication front ends will access CLIP_PRIMARY in
response to most actions but the 'Paste' menu item will paste from
CLIP_CLIPBOARD. (That's mostly just as a demonstration that accessing
multiple clipboards even works.)
2017-12-16 13:50:47 +00:00
Simon Tatham
1829719639 Add a system of clipboard identifiers.
This lays some groundwork for making PuTTY's cut and paste handling
more flexible in the area of which clipboard(s) it reads and writes,
if more than one is available on the system.

I've introduced a system of list macros which define an enumeration of
integer clipboard ids, some defined centrally in putty.h (at present
just a CLIP_NULL which never has any text in it, because that seems
like the sort of thing that will come in useful for configuring a
given copy or paste UI action to be ignored) and some defined per
platform. All the front end functions that copy and paste take a
clipboard id, and the Terminal structure is now configured at startup
to tell it which clipboard id it should paste from on a mouse click,
and which it should copy from on a selection.

However, I haven't actually added _real_ support for multiple X11
clipboards, in that the Unix front end supports a single CLIP_SYSTEM
regardless of whether it's in OS X or GTK mode. So this is currently a
NFC refactoring which does nothing but prepare the way for real
changes to come.
2017-12-16 13:50:47 +00:00
Simon Tatham
f26654f618 Stop front ends remembering the data of their last paste.
Previously, both the Unix and Windows front ends would respond to a
paste action by retrieving data from the system clipboard, converting
it appropriately, _storing_ it in a persistent dynamic data block
inside the front end, and then calling term_do_paste(term), which in
turn would call back to the front end via get_clip() to retrieve the
current contents of that stored data block.

But, as far as I can tell, this was a completely pointless mechanism,
because after a data block was written into this storage area, it
would be immediately used for exactly one paste, and then never
accessed again until the next paste action caused it to be freed and
replaced with a new chunk of pasted data.

So why on earth was it stored persistently at all, and why that
callback mechanism from frontend to terminal back to frontend to
retrieve it for the actual paste action? I have no idea. This change
removes the entire system and replaces it with the completely obvious
alternative: the character-set-converted version of paste data is
allocated in a _local_ variable in the frontend paste functions,
passed directly to term_do_paste which now takes (buffer,length)
parameters, and freed immediately afterwards. get_clip() is gone.
2017-12-10 09:22:22 +00:00
Simon Tatham
2a2153f4ce Fix assertion failure that prevents pterm starting up.
When testing the previous commit, I went to great lengths to check all
the tricky corner cases of the detailed command-line argument handling
in Plink and PuTTY, on Windows and Unix. And did I also double-check
that I had not completely broken the very simplest possible invocation
of pterm? I did not.

The call to cmdline_host_ok() in gtkmain.c was failing an assertion in
pterm, because that function only expects to have been called by a
program that has the TOOLTYPE_HOST_ARG flag set - if that flag isn't
set, the program is expected to come up with its own answer to the
question (because I wasn't sure what the right fallback answer would
be). And I forgot to conditionalise the call between PuTTY and pterm.
2017-12-08 19:34:35 +00:00
Simon Tatham
b9a25510b0 Centralise PuTTY and Plink's non-option argument handling.
This is another piece of long-overdue refactoring similar to the
recent commit e3796cb77. But where that one dealt with normalisation
of stuff already stored _in_ a Conf by whatever means (including, in
particular, handling a user typing 'username@host.name' into the
Hostname box of the GUI session dialog box), this one deals with
handling argv entries and putting them into the Conf.

This isn't exactly a pure no-functional-change-at-all refactoring. On
the other hand, it isn't a full-on cleanup that completely
rationalises all the user-visible behaviour as well as the code
structure. It's somewhere in between: I've preserved all the behaviour
quirks that I could imagine a reason for having intended, but taken
the opportunity to _not_ faithfully replicate anything I thought was
clearly just a bug.

So, for example, the following inconsistency is carefully preserved:
the command 'plink -load session nextword' treats 'nextword' as a host
name if the loaded session hasn't provided a hostname already, and
otherwise treats 'nextword' as the remote command to execute on the
already-specified remote host, but the same combination of arguments
to GUI PuTTY will _always_ treat 'nextword' as a hostname, overriding
a hostname (if any) in the saved session. That makes some sense to me
because of the different shapes of the overall command lines.

On the other hand, there are two behaviour changes I know of as a
result of this commit: a third argument to GUI PuTTY (after a hostname
and port) now provokes an error message instead of being silently
ignored, and in Plink, if you combine a -P option (specifying a port
number) with the historical comma-separated protocol selection prefix
on the hostname argument (which I'd completely forgotten even existed
until this piece of work), then the -P will now override the selected
protocol's default port number, whereas previously the default port
would win. For example, 'plink -P 12345 telnet,hostname' will now
connect via Telnet to port 12345 instead of to port 23.

There may be scope for removing or rethinking some of the command-
line syntax quirks in the wake of this change. If we do decide to do
anything like that, then hopefully having it all in one place will
make it easier to remove or change things consistently across the
tools.
2017-12-07 20:13:33 +00:00
Geoff Winkless
81345e9a82 ctrl-shift-page-up/down to top or bottom of scrollback
Just a small patch, that I find really useful.
2017-12-03 15:35:40 +00:00
Simon Tatham
247d1b9b78 Unix PuTTY: add missing call to prepare_session.
Now 'putty user@host' will do what you wanted on Unix the same way it
always has on Windows.

(Thanks to Geoff Winkless for pointing out this inconsistency. I've
redone his actual patch my way, but he should still be credited for
the inspiration!)
2017-12-03 15:35:02 +00:00
Simon Tatham
e3796cb779 Factor out common pre-session-launch preparation.
A more or less identical piece of code to sanitise the CONF_host
string prior to session launch existed in Windows PuTTY and both
Windows and Unix Plink. It's long past time it was centralised.

While I'm here, I've added a couple of extra comments in the
centralised version, including one that - unfortunately - tries _but
fails_ to explain why a string of the form "host.name:1234" doesn't
get the suffix moved into CONF_port the way "user@host" moves the
prefix into CONF_username. Commit c1c1bc471 is the one I'm referring
to in the comment, and unfortunately it has an unexplained one-liner
log message from before I got into the habit of being usefully
verbose.
2017-12-03 14:54:49 +00:00
Simon Tatham
46cf862c31 Knock off another refactoring from the OS X to-do list.
Stopping dialog boxes from being modal is now done; post_main() is
defunct; nothing left in gtkwin.c does an inappropriate whole-process
termination in response to a window-level error or closure condition.

(There is still modalfatalbox(), but that's not an _inappropriate_
process termination.)
2017-11-27 20:45:14 +00:00
Simon Tatham
032a9da179 Remove one last stray process exit().
This one's in frontend_keypress(), which is supposed to close the
window on the first keypress after the session inside it terminates
(that is, if your close-on-exit settings haven't made it close already
at that point).

It looks to me as if that behaviour doesn't currently _work_, and
hasn't worked for quite a while (certainly it was broken as of 0.70,
well before I started on this weekend's refactoring), because when the
session terminates we delete inst->ldisc and that's what would
otherwise be calling frontend_keypress. I should probably decide what
to do about that at some point. But for the moment, I'm satisfied to
simply not break this functionality any worse by making it not a
process-global exit :-)
2017-11-27 20:45:14 +00:00
Simon Tatham
4b8baed84a GTK: fix the exit(1) response to startup-time font errors.
For gtkapp-based tools that will have to stop being a program-fatal
error, so I've turned it into a function called window_setup_error
(which I could in principle reuse for other problems in the long and
tortuous progress of new_session_window), and kept the original
handling in gtkmain.c's implementation of that function while gtkapp.c
does something more sensible with a message box.
2017-11-27 20:45:14 +00:00
Simon Tatham
ba55b228a3 Move gtkwin.c's cmdline_error() into gtkmain.c.
Not all gtkwin-based tools use it. Only the ones with one session per
process, which parse a command line describing that session and might
reasonably want to report errors in that command line by writing to
standard error and exiting the program.

In other words, precisely the ones that link in gtkmain.c and not
gtkapp.c. So gtkmain.c is a more sensible place to put that
error-reporting function.
2017-11-27 20:45:14 +00:00
Simon Tatham
61f3e3e299 GTK: handle synchronous connection-setup failures sensibly.
This was one of a handful of remaining places in gtkwin.c where exit()
is called incautiously. Of course, a failure to set up one SSH
connection should only be fatal to that connection, not the whole
process, so really we should be feeding into the connection_fatal
system.
2017-11-27 20:21:22 +00:00
Simon Tatham
71b00097dd Remove the post_main() mechanism.
This existed in order to avoid the various confusions that could
happen if a toplevel callback ran in the context of a subsidiary
instance of gtk_main(). Now there aren't any subsidiary gtk_main
instances any more, this mechanism is no longer needed, and I can
throw it out. It was horrible anyway.
2017-11-26 20:03:12 +00:00
Simon Tatham
ef6e38d8eb Remove the modal message_box function completely.
Now there's nothing left that calls it, it's obsolete.
2017-11-26 20:02:00 +00:00
Simon Tatham
57ceac8f1d Fix stale-pointer bugs in connection-fatal network errors.
I think these began to appear as a consequencce of replacing
fatalbox() calls with more sensible error reports: the more specific a
direction I send a report in, the greater the annoying possibility of
re-entrance when the resulting error handler starts closing stuff.
2017-11-26 19:59:27 +00:00
Simon Tatham
3e24bb610d Make connection_fatal() nonmodal.
This change requires me to break up the general cleanups in
delete_inst() into two halves: one runs when the error message box is
created, and cleans up the network connection and all the stuff
associated with it, and the other runs when the error message is
dismissed and the window can actually close.
2017-11-26 19:59:24 +00:00
Simon Tatham
813c380470 Make nonfatal() nonmodal.
This one was completely trivial, except that while I was at it, I took
the opportunity to put the right program name in the window title.
2017-11-26 17:57:26 +00:00
Simon Tatham
4f3f4ed691 Get rid of fatalbox() completely.
It's an incoherent concept! There should not be any such thing as an
error box that terminates the entire program but is not modal. If it's
bad enough to terminate the whole program, i.e. _all_ currently live
connections, then there's no point in permitting progress to continue
in windows other than the affected one, because all windows are
affected anyway.

So all previous uses of fatalbox() have become modalfatalbox(), except
those which looked to me as if they shouldn't have been fatal in the
first place, e.g. lingering pieces of error handling in winnet.c which
ought to have had the severity of 'give up on this particular Socket
and close it' rather than 'give up on the ENTIRE UNIVERSE'.
2017-11-26 17:43:02 +00:00
Simon Tatham
d1f62c3e0f Make the Licence message box non-modal. 2017-11-26 17:32:01 +00:00
Simon Tatham
a8e9fd7860 Reimplement 'really close session?' as a non-modal message box.
I've also moved it out into gtkwin.c, because it seemed easier to do
the 'find existing instance of this dialog and raise it' dance there
than to split it across source files pointlessly.
2017-11-26 17:21:32 +00:00
Simon Tatham
71ed04dbc3 Make the GTK font setup error box non-modal.
That was the last (in fact, the only) call to the modal version of
message_box() outside gtkdlg.c, so I can remove it from the header
file.
2017-11-26 17:07:47 +00:00
Simon Tatham
8b0d460578 Replace dlg_error_message() with a non-modal message box.
Apart from the specific benefit of non-modality, this also makes it a
lot simpler compared to the previous code! I'm not completely sure why
I wasn't using the standard gtkdlg.c message box system all along.
2017-11-26 17:05:51 +00:00
Simon Tatham
b6ed82321c Make the askappend() prompt non-modal.
This fits into a new dialog-box slot (because it might have to come up
at the same time as a network prompt), and makes use of the existing
callback system in logging.c which buffers the logging data until the
user says what they want done with it.
2017-11-26 16:56:03 +00:00
Simon Tatham
86741a1b09 Expand the dialog registering/unregistering system.
Now it has several 'slots', each named for a particular class of
subsidiary dialog box that a session window can have at most one of,
and register_network_prompt_dialog has a more general name and takes
an enum-typed argument identifying a slot. This lets me avoid writing
a zillion annoyingly similar function pairs and corresponding snippets
of cleanup code in delete_inst.
2017-11-26 16:51:19 +00:00
Simon Tatham
f212e2cbea Change order of cleanup in delete_inst.
If you close a session window with an associated SSH back end, the
back end may call back to notify_remote_exit() from ssh_free(), which
queues a new top-level callback citing the inst structure we were
about to delete.

We could fix this by introducing a special 'moribund' flag which
inhibits notify_remote_exit from queueing a callback, but far easier
is to move the delete_callbacks_for_context() call to _after_ all
subsidiary things have been cleaned up, so that any last-minute
callbacks they might schedule will be promptly unscheduled again
before they do any damage.
2017-11-26 15:38:35 +00:00
Simon Tatham
199f381aa9 Make GTK askalg() and askhk() non-modal.
This follows exactly the same pattern as for verify_ssh_host_key, but
the results of the dialog box are simpler (a plain yes-no response),
so the two dialog types can share a callback.
2017-11-26 15:20:46 +00:00
Simon Tatham
624f5b7d47 Make the GTK host-key verification box non-modal.
I've switched it to using the new non-modal create_message_box, and
provided a callback function which handles the cleanup afterwards.

I had expected this to be a lot more work, because I'd imagined that
I'd have to contort the coroutines in ssh.c to give them the ability
to wait for an asynchronously delivered result from that user prompt.
But in fact that wasn't necessary, because just such a mechanism has
been sitting there unused since commit 8574822b9 in 2005, when I added
it as part of my _previous_ attempt to write an OS X front end! (The
abandoned one written in native ObjC + Cocoa.)
2017-11-26 15:20:46 +00:00
Simon Tatham
671267f44b GTK: system for not leaving stale network prompt dialogs.
When I switch verify_ssh_host_key() and friends over to creating
non-modal message boxes and returning to the main loop, there will be
a risk that their parent window will need to close for some other
reason while the user hasn't answered the pending question yet. (E.g.
if the user presses the main session window's close button, which will
no longer be a prohibited UI action once the transient dialog is not
modal.)

At that point we need to get rid of the pending dialog box, both for
UI purposes (it would look silly and be confusing to leave it lying
around) and for memory management (if the user subsequently clicks OK
in such a dialog it would probably try to leave its result somewhere
stale).

So now there's a mechanism for gtkwin.c remembering what the current
'network prompt dialog' is, if any (in which category I intend to
include everything triggered from ssh.c's various reasons for asking
crypto-related questions), and cleaning it up when the struct gui_data
it belongs to goes away.
2017-11-26 15:20:00 +00:00
Simon Tatham
946405341f Fix a cleanup issue in dlgparam_destroy.
If a dialog box is destroyed by the program before the user has
pressed one of the result-delivering buttons - e.g. because the parent
window closes so the dialog is no longer relevant to anything anyway -
then dlgparam_destroy would never call the client code's provided
callback. That makes sense in terms of the callback wanting to _take
action_ based on the result of the dialog box, but it ignores the
possibility that the callback may simply need to free its own context
structure.

So now dlgparam_destroy always calls the client's callback, even if
the result it passes is negative (meaning 'the user never got round to
pressing any of the dialog-ending buttons'), and all the existing
client callbacks handle the negative-result case by doing nothing
except freeing any allocated memory they might have.
2017-11-26 15:19:11 +00:00
Simon Tatham
46ba9de2c2 Introduce a non-modal create_message_box().
This does the bulk of the work previously done by message_box()
proper, but takes a pointer to a result-reporting callback function
identical to the one we pass to create_config_box().

The modal version of message_box() still exists and is a small wrapper
on this function, running its own subsidiary gtk_main() loop which the
result callback terminates. But now I can start switching over
individual uses of message_box() to the non-modal version, and when
that's done, remove the modal function completely.
2017-11-26 15:19:11 +00:00
Simon Tatham
2d289a9970 Make the GTK message-box function non-variadic.
Now, in place of a variadic argument list with four parameters per
button and a terminating NULL, it takes a pointer to a struct which in
turn contains an (array,length) pair of small per-button structures.

In the process I've renamed the function from messagebox() to
message_box(). Partly that was just because it gave me a convenient
way to search the source for calls I hadn't converted yet, but also
I've thought for a while that that missing underscore didn't really
match the rest of my naming.

NFCI. Partly this minor refactor has the virtue that we can reuse the
more common button layouts without having to type them in at multiple
places in the code (and, indeed, I've provided buttons_yn and
buttons_ok for easy reuse, and could easily provide other things like
yesnocancel any time I need them). But mostly it's because I'm about
to split up message_box into multiple functions, and this saves me the
hassle of deciding which ones to make variadic and which to pass an
actual va_list to - particularly since messagebox() used to go over
its variadic argument list twice, which always makes delegating it to
another function that much more annoying.
2017-11-26 14:05:02 +00:00
Simon Tatham
7891cb1ac1 Remove an item from gtkapp.c's OS X TODO comment.
The last few changes between them have fixed the problem of windows
not closing properly when their sessions terminated. The problem was
really more than one problem - pterm session termination wasn't even
detected due to the missing SIGCHLD handler, window-closing wasn't
done explicitly due to exit_callback() just calling gtk_main_quit
instead of a proper gtk_widget_destroy(), and that in turn wouldn't do
quite the right thing without the g_application_{hold,release} system
which I added in gtkapp.c as part of the non-model config box rework.

Now that all of those are fixed, things seem to be working sensibly;
the OS X Pterm.app and PuTTY.app, and the ordinary X GTK ptermapp and
puttyapp too, now allow windows to be closed independently of each
other, close them automatically in the right way, and automatically
terminate the whole application when the last window is gone.

So I can clean up that TODO item, including its handwavy 'need to work
out some kind of mechanism'. Some kind of mechanism has now been
worked out, and given that there turned out to be a whole cluster of
interacting structural issues, no wonder I wasn't _quite_ sure what it
ought to be!
2017-11-26 11:58:05 +00:00
Simon Tatham
817e4ad2dd Make the configuration dialog non-modal.
Now every call to do_config_box is replaced with a call to
create_config_box, which returns immediately having constructed the
new GTK window object, and is passed a callback function which it will
arrange to be called when the dialog terminates (whether by OK or by
Cancel). That callback is now what triggers the construction of a
session window after 'Open' is pressed in the initial config box, or
the actual mid-session reconfiguration action after 'Apply' is pressed
in a Change Settings box.

We were already prepared to ignore the re-selection of 'Change
Settings' from the context menu of a window that already had a Change
Settings box open (and not accidentally create a second config box for
the same window); but now we do slightly better, by finding the
existing config box and un-minimising and raising it, in case the user
had forgotten it was there.

That's a useful featurelet, but not the main purpose of this change.
The mani point, of course, is that now the multi-window GtkApplication
based front ends now don't do anything confusing to the nesting of
gtk_main() when config boxes are involved. Whether you're changing the
settings of one (or more than one) of your already-running sessions,
preparing to start up a new PuTTY connection, or both at once, we stay
in the same top-level instance of gtk_main() and all sessions' top-
level callbacks continue to run sensibly.
2017-11-26 11:58:02 +00:00