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

5340 Commits

Author SHA1 Message Date
Pavel I. Kryukov
61dec9a07a sshmac.c: remove excessive return statement 2019-01-02 22:50:08 +00:00
Simon Tatham
92eedabf49 Actually allocate the new strbuf.
Oops - the one build platform whose warnings would have pointed out
that goof is the one that doesn't run in my usual pre-push test...
2019-01-02 22:16:33 +00:00
Simon Tatham
2af10ee8d1 Mention 'no VLAs' in the C-standards UDP section.
Now we're enforcing it in the build, it ought to be documented as
well.
2019-01-02 22:14:15 +00:00
Simon Tatham
8d6d7a3615 Use a strbuf in ssh_ecdhkex_m_setup.
This removes the one remaining failure at -Wvla. (Of course, that
array isn't for a _hash_ function, so it wouldn't have been quite
appropriate to make it a static array of size MAX_HASH_LEN.)
2019-01-02 22:14:15 +00:00
Pavel I. Kryukov
53f0ce3d0c Forbid variable length arrays
Although C99 introduces variable length array (VLA) feature, it is
not supported by MS Visual Studio (being C++ compiler first of all).
In this commit, we add Clang and GCC options to disable VLA, so they
would be disabled in non-MSVC builds as well.
2019-01-02 22:14:15 +00:00
Simon Tatham
38e0a3d22e Rename SSH2_KEX_MAX_HASH_LEN to be more general.
I'm about to want to use it for purposes other than KEX, so it's now
just called MAX_HASH_LEN and is supposed to be an upper bound on any
hash function we implement at all. Of course this makes no difference
to its value, because the largest hash we have is SHA-512 which
already fit inside that limit.
2019-01-02 22:05:07 +00:00
Pavel I. Kryukov
bcf6f52bf2 sshmd5.c: remove excessive return statement 2019-01-02 17:30:04 +00:00
Simon Tatham
24b9e6716d Check for null pointers in dh_cleanup.
If we have to abandon a Diffie-Hellman key exchange part way through
(e.g. the connection slams shut), and we haven't yet run all the
stages of the DH algorithm, then some of the mp_ints in the dh_ctx
will be NULL. So we shouldn't mp_free them without checking first.
2019-01-02 08:55:03 +00:00
Simon Tatham
606cf4c22b Fix pasto in ssh2_mac_setkey, and start using it.
The macro wrapper for the MAC setkey function expanded to completely
the wrong vtable method due to a cut and paste error. And I never
noticed, because what _should_ have been its two call sites in
ssh2bpp.c were directly calling the _right_ vtable method instead.
2019-01-02 08:54:07 +00:00
Simon Tatham
2ee23472ce Reinstate a missing free.
In commit 869ce8867 I sank an sfree(fingerprint) into an if statement
that had previously been before it - but I only put it in two of the
three branches of the if. Now added it in the third one, preventing a
minor memory leak if you use SSH-1 with the -hostkey option (and the
actual host key presented by the server matches it).
2019-01-01 17:34:19 +00:00
Jacob Nevins
a718881af8 It's a new year. 2019-01-01 15:13:32 +00:00
Jacob Nevins
4f54dc0c5f Try to ensure a C99 compiler.
Some still-supported Linux distributions (Debian jessie and Ubuntu 14.04
at least) still use GCC 4, where C99 isn't the default.

For autoconf, we do it the autotools way. For the standalone Makefiles,
we go for -std=gnu99 rather than c99, to avoid trouble with fdopen().
2019-01-01 15:12:08 +00:00
Jacob Nevins
b6f296a17a Fix use of LDFLAGS in Makefile.ux.
Same idea as commit 68b1933326 for Makefile.gtk.
2019-01-01 13:38:05 +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
d73a1716f6 Remove static list of primes in sshprime.c.
It wasn't really doing any serious harm, but I just got tired of
having to scroll past 700 lines of pointless static data every time I
wanted to look at the actual code in the file. Now primes[] is
initialised as necessary when genprime is first called.

(Since we only use primes up to 2^16, I didn't see any point in doing
anything fancy; this is the most trivial Sieve of Eratosthenes.)
2018-12-31 14:12:16 +00:00
Simon Tatham
814665fb22 Clean up RSA and DSA host-key cache formatters.
These were both using the old-fashioned strategy of 'count up the
length first, then go back over the same data trying not to do
anything different', which these days I'm trying to replace with
strbufs.

Also, while I was in ssh.h, removed the prototype of rsasanitise()
which doesn't even exist any more.
2018-12-31 14:12:01 +00:00
Simon Tatham
5b0f32a100 Centralise RSA PKCS1 signature formatting.
There was no point in rsa2_sign and rsa2_verify having mirrored
versions of the same code to construct the cleartext of the RSA
signature integer, just because one is building it and the other is
checking it. Much more sensible to have a single function that builds
it, and then rsa2_verify can compare the received integer against that
while rsa2_sign encodes it into an output integer.
2018-12-31 14:11:24 +00:00
Simon Tatham
a80edab4b5 Move some manual freeing into freersakey().
Several pieces of old code were disposing of pieces of an RSAKey by
manually freeing them one at a time. We have a centralised
freersakey(), so we should use that instead wherever possible.

Where it wasn't possible to switch over to that, it was because we
were only freeing the private fields of the key - so I've fixed that
by cutting freersakey() down the middle and exposing the private-only
half as freersapriv().
2018-12-31 14:11:19 +00:00
Simon Tatham
55cea187e9 Fix some minor memory leaks in cmdgen.
I happened to run cmdgen under Leak Sanitiser, and found it was
_almost_ clean - clean enough that if I fix the last few leaks then it
might be worth running it again from time to time.
2018-12-31 14:10:41 +00:00
Simon Tatham
869ce8867e Fix use after free in ssh1login.
I was freeing the textual key fingerprint _before_ passing it to
seat_verify_ssh_host_key. Ahem.
2018-12-31 14:10:08 +00:00
Simon Tatham
1270d445e8 Fix crash if key exchange fails.
In the new modular SSH architecture, ssh2transport.c delegates the
actual KEX packet exchange to ssh2kex_coroutine, which has different
implementations for client and server. The KEX code actually in
ssh2transport.c consists of looping on the coroutine until it zeroes
out its state field in the ssh2transport state.

But if something goes wrong enough during KEX that we call
ssh_proto_error or any other fatal connection-terminating function,
then when we return to ssh2transport.c, the ssh2transport state won't
even exist for it to check that flag. Address Sanitiser pointed that
out to me recently, so here's a fix in which we set an 'aborted' flag
to tell the caller that its state has already been freed.
2018-12-31 14:07:45 +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
383a16d5e5 Fix handling of backspace at beginning of line.
In the big boolification commit (3214563d8) I accidentally rewrote
"term->wrap == 0" as "term->wrap" instead of as "!term->wrap", so now
sending the backspace character to the terminal at the start of a line
causes the cursor to wrap round to the end of the previous line if and
only if it _shouldn't_ have done.
2018-12-08 16:12:05 +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
50b9448450 Makefile.clangcl: move $(CCTARGET) out of $(CC).
Now $(CC) is defined to be nothing but the name of the clang-cl binary
itself, which makes it easier to drop in a different one for a special
purpose.

(I tried to use this for static analysis recently - unsuccessfully, as
yet, but I think this change will make anything else along the same
lines easier as well.)
2018-12-06 18:41:30 +00:00
Simon Tatham
2cdff46d98 Remove the old in_commasep_string system.
It's just silly to have _two_ systems for traversing a string of
comma-separated protocol ids. I think the new get_commasep_word
technique for looping over the elements of a string is simpler and
more general than the old membership-testing approach, and also it's
necessary for the modern KEX untangling system (which has to be able
to loop over one string, even if it used a membership test to check
things in the other). So this commit rewrites the two remaining uses
of in_commasep_string to use get_commasep_word instead, and deletes
the former.
2018-12-06 18:35:27 +00:00
Simon Tatham
c99d37a7fe Avoid hanging on GSSAPI acquire_cred failure.
If GSSAPI authentication fails because we call the GSS acquire_cred
function on the client side and find it doesn't give us anything
useful, then that authentication attempt has to terminate - but since
_we_ decided to terminate it, on the client side, the server will be
sending us neither a formal USERAUTH_FAILURE nor any other kind of
packet.

So when we go back round to the top of the auth loop, we have to avoid
_either_ assuming we're sitting on a USERAUTH_FAILURE we can parse for
its method list, _or_ waiting to receive one. Instead we just have to
push on and try the next auth method in the list from the last
USERAUTH_FAILURE we did see.

Hence, a new flag lets us suppress the usual behaviour of waiting
until we have a response packet on the queue, and then all references
to pktin after that are tested for NULL.
2018-12-06 18:08:56 +00:00
Simon Tatham
6002b272f4 Retain permitted methods list in userauth layer state.
There are situations - or _should_ be, at any rate - in which we
terminate a userauth attempt without having received a
USERAUTH_FAILURE from the server, which means that we can't depend on
always starting a userauth loop iteration by extracting the server's
list of permitted methods from the current failure message. If there
isn't a current failure message, the best we can do is remember the
state from last time.

That's already what we do for actually deciding which methods to
attempt (we set s->can_foo from the methods string). But we should
also keep the full original version of the string, for use in error
message.
2018-12-06 18:06:15 +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
1e1f06b2ec Check by assertion that we cross-certified the right key type.
The flag 'cross_certifying' in the SSH-2 transport layer state is now
a pointer to the host key algorithm we expect to be certifying,
instead of a plain bool. That lets me check by assertion that it's
what we expected it to be after all the complicated key exchange has
happened.

(I have no reason to think this _will_ go wrong. When we cross-
certify, the desired algorithm should be the only one we put into our
KEXINIT host key algorithm list, so it should also be the only one we
can come out of the far end of KEXINIT having selected. But if
anything ever does go wrong with my KEXINIT handling then I'd prefer
an assertion failure to silently certifying the wrong key, and also,
this makes it clearer to static analysers - and perhaps also humans
reading the code - what we expect the situation to be.)
2018-12-01 17:02:20 +00:00
Simon Tatham
e9b49fdced psftp: stop checking the return of canonify() for NULL.
It hasn't been possible for canonify() to return a null pointer since
commit 094dd30d9, in 2001. But the whole of psftp.c is full of error
checking clauses that allow for the possibility that it might!
2018-12-01 17:01:32 +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
d2ff948207 Mark a few functions as __attribute__((noreturn)).
This is mostly to make static analysers and compiler warnings a bit
happier - now they know that a call to, say, modalfatalbox() means
they don't have to worry about what the rest of the function will do.
2018-12-01 16:59:24 +00:00
Simon Tatham
144b738f31 pscp, psftp: use a bufchain in ssh_scp_recv.
The ad-hoc code that received data from the SCP or SFTP server
predated even not-very-modern conveniences such as bufchain, and was
quite horrible and cumbersome.

Particularly nasty was the part where ssh_scp_recv set a _global_
pointer variable to the buffer it was in the middle of writing to, and
then recursed and expected a callback to use that pointer. That caused
clang-analyzer to grumble at me, in a particular case where the output
buffer was in the ultimate caller's stack frame; even though I'm
confident the code _worked_, I can't blame clang for being unhappy!

So now we do things the modern and much simpler way: the callback when
data comes in just puts it on a bufchain, and the top-level
ssh_scp_recv repeatedly waits until data arrives in the bufchain and
then copies it to the output buffer.
2018-12-01 16:56:25 +00:00
Simon Tatham
dbb2c0030a Use strbuf and BinarySource for scrollback compression.
'struct str' in terminal.c was an earlier and less good implementation
of the same concept as misc.h's strbuf, so I've replaced it with the
same strbuf we have everywhere. As a bonus, this means I can also use
put_uint{16,32} to save a bit of effort writing out the compressed
scrollback data.

On the decompression side, I've also switched to using BinarySource,
which has the advantage that now if the decoding goes wrong we can at
least be sure of not reading beyond the end of the buffer.

(The flip side of that is that now we _store_ the length of each
compressed line buffer, which costs a bit of memory. But I think it's
worth it for the safety and code consistency.)
2018-12-01 16:54:25 +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
Simon Tatham
915be1f6f0 testbn: add a missing initialisation in argument setup.
The code that parses hexadecimal test arguments out of test lines
writes them into a buffer in binary form, and sets ptrs[i] to be the
starting point of each argument. The idea is that ptrs[i+1]-ptrs[i] is
the length of each argument - but for that to apply to the _final_
argument, we need to have set one final element in ptrs[], which I
forgot to do.
2018-12-01 16:51:09 +00:00
Simon Tatham
b2078a3c51 Add a missing initialisation.
The variable 'toret' in ssh2_transport_get_specials would have been
returned while uninitialised in the case where neither of the if
statements in the function set it to true.
2018-12-01 16:49:11 +00:00
Simon Tatham
1074a9be4c Stop BPPs from handling EOF before reading all data.
The BPP_READ macros in all four BPP implementations (including
sshverstring) had the same bug: if EOF had been seen on the network
input but there was _also_ enough data in the input queue to satisfy
the current request, they would jump straight to complaining about the
EOF rather than processing the available data first.

I spotted this while trying to pipe in test data from a disk file, but
it could easily also lead to us failing to handle the final message in
the connection, e.g. losing the error message sent by the remote in a
DISCONNECT message.
2018-11-28 20:19:59 +00:00
Volker Rümelin
dfe88e792a x11fwd.c: Handle empty display number in authfile
An empty display number matches any display number.

For example xauth list :1 returns auth cookies where the
display number matches and where the display number is empty.
2018-11-28 19:58:19 +00:00
Simon Tatham
84d5eb4287 Move the ZLIB_STANDALONE main() into its own file.
Now, instead of getting the zlib test/helper program by manually
compiling a source file with unusual options, it gets built as
standard by the ordinary Makefile.
2018-11-27 19:59:45 +00:00
Simon Tatham
abec9e1c7e Move the malloc helpers out of misc.c.
Now they live in their own file memory.c. The advantage of this is
that you can link them into a binary without also pulling in the rest
of misc.c with its various dependencies on other parts of the code,
such as conf.c.
2018-11-27 19:59:45 +00:00
Simon Tatham
1586a41656 Remove the 'bool compress' parameter to lz77_compress.
It stopped being useful in commit 20a9bd564, where I removed the only
code that called it. I've only just noticed that this part of the
mechanism is still lying around.
2018-11-27 19:24:48 +00:00
Simon Tatham
6329890046 Add some missing 'const' in the compressor API. 2018-11-27 19:24:48 +00:00
Simon Tatham
898cb8835a Make ssh_key and ssh{2,1}_cipher into structs.
In commit 884a7df94 I claimed that all my trait-like vtable systems
now had the generic object type being a struct rather than a bare
vtable pointer (e.g. instead of 'Socket' being a typedef for a pointer
to a const Socket_vtable, it's a typedef for a struct _containing_ a
vtable pointer).

In fact, I missed a few. This commit converts ssh_key, ssh2_cipher and
ssh1_cipher into the same form as the rest.
2018-11-26 21:02:28 +00:00
Simon Tatham
85770b2036 Add missing expire_timer_context in ssh2_transport_free.
This should have been moved over from the main ssh_free function back
when I did the original splitting-up of ssh.c: the transport layer
schedules a timer for rekeying (and also for GSSAPI credential
checks), so when it's freed, it needs to ensure the timer doesn't get
called anyway on a stale pointer.

Two users reported this in the form of an assertion failure in
conf_get_int (when ssh2_transport_timer asks for CONF_ssh_rekey_time,
if the tree234 call inside conf_get_int is confused by the contents of
the freed memory into returning failure). In other circumstances (if
the freed memory has different contents) it manifests as a segfault,
but it's the same underlying bug either way.
2018-11-23 19:21:01 +00:00
Simon Tatham
6de69d001f Update UDP to mention the inttypes.h exception.
Of course this wouldn't have prevented me from making that mistake
myself - it's not as if I carefully re-read the design principles
appendix before writing each code change! - but it might help explain
to _someone_ at some point...
2018-11-22 07:09:06 +00:00
Simon Tatham
fa8f1cd9a0 Fix a build failure.
When I added a use of PRIx32 to one of Pageant's debugging messages a
couple of days ago, I forgot that one of my build setups can't cope
with inclusion of <inttypes.h>, and somehow also forgot the
precautionary pre-push full build that would have reminded me.
2018-11-22 07:05:58 +00:00