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

717 Commits

Author SHA1 Message Date
Ben Harris
4115ab6e2e Don't completely ignore unknown types of SSH_MSG_CHANNEL_EXTENDED_DATA.
It's important to do the usual window accounting in all cases.  We
still ignore the data themselves, which I think is the right thing to
do.
2016-05-24 22:38:40 +01:00
Ben Harris
f0f191466a Remove CHAN_SOCKDATA_DORMANT.
It's redundant with the halfopen flag and is a misuse of the channel
type field.  Happily, everything that depends on CHAN_SOCKDATA_DORMANT
also checks halfopen, so removing it is trivial.
2016-05-23 10:06:31 +01:00
Ben Harris
066dfb7786 Forward channel messages for shared channels in ssh_channel_msg().
This saves doing it separately in every function that processes such
messages.
2016-05-22 23:59:48 +01:00
Ben Harris
08d4ca0787 More strictness in ssh_channel_msg().
Now it disconnects if the server sends
SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE for
a channel that isn't half-open.  Assertions in the SSH-2 handlers for
these messages rely on this behaviour even though it's never been
enforced before.
2016-05-22 22:57:25 +01:00
Ben Harris
d17b9733a9 Switch SSH-1 channel message handlers to use ssh_channel_msg().
This gives consistent (and stricter) handling of channel messages
directed at non-existent and half-open channels.
2016-05-22 22:21:20 +01:00
Ben Harris
1c8c38555d Generalise ssh2_channel_msg() to ssh_channel_msg().
It now supports both SSH-1 and SSH-2 channel messages.  The SSH-1 code
doesn't yet use it, though.
2016-05-22 22:14:00 +01:00
Ben Harris
d8eff1070d Assert that ssh2_channel_check_close() is only called in SSH-2.
That really should be true, but I don't entirely trust
sshfwd_unclean_close().
2016-05-22 13:50:34 +01:00
Ben Harris
bc48975ce5 In ssh_channel_init(), insert the new channel into the channel tree234.
All but one caller was doing this unconditionally.  The one conditional
call was when initialising the main channel, and in consequence PuTTY
leaked a channel structure when the server refused to open the main
channel.  Now it doesn't.
2016-05-21 23:26:57 +01:00
Ben Harris
acfab518d2 Convert ssh2_channel_init() into ssh_channel_init().
By adding support for initialising SSH-1 channels as well.  Now all
newly-created channels go through this function.
2016-05-21 22:29:57 +01:00
Ben Harris
c7759f300b Unify despatch of incoming channel data between SSH-1 and SSH-2. 2016-05-21 13:13:00 +01:00
Ben Harris
e06833b46b Don't send SSH_MSG_CHANNEL_WINDOW_ADJUST with a zero adjustment. 2016-05-20 21:33:46 +01:00
Ben Harris
0e1b0e24c1 Factor out common parts of ssh_unthrottle and sshfwd_unthrottle.
The SSH-2 code is essentially all shared, but SSH-1 still has some
code specific to the stdout/stderr case.
2016-05-20 21:33:46 +01:00
Simon Tatham
dcf4466305 Send the IUTF8 terminal mode in SSH "pty-req"s.
An opcode for this was recently published in
https://tools.ietf.org/html/draft-sgtatham-secsh-iutf8-00 .

The default setting is conditional on frontend_is_utf8(), which is
consistent with the pty back end's policy for setting the same flag
locally. Of course, users can override the setting either way in the
GUI configurer, the same as all other tty modes.
2016-05-03 11:13:48 +01:00
Simon Tatham
2ce0b680cf Loop over all _supported_, not just configured, SSH tty modes.
Previously, the code that marshalled tty settings into the "pty-req"
request was iterating through the subkeys stored in ssh->conf, meaning
that if a session had been saved before we gained support for a
particular tty mode, the iteration wouldn't visit that mode at all and
hence wouldn't send even the default setting for it.

Now we iterate over the array of known mode identifiers in
ssh_ttymodes[] and look each one up in ssh->conf, rather than vice
versa. This means that when we add support for a new tty mode with a
nontrivial policy for choosing its default state, we should start
using the default handler immediately, rather than bizarrely waiting
for users to save a session after the change.
2016-05-03 11:13:48 +01:00
Ben Harris
8a2797cf0f ssh_pkt_defersend: don't call do_ssh2_transport when using SSH-1.
Also add an assertion to do_ssh2_transport to catch this.

This bug would be highly unlikely to manifest accidentally, but I
think you could trigger it by setting the data-based rekey threshold
very low.
2016-05-01 19:16:22 +02:00
Ben Harris
adc8ae214e Shared ssh_send_channel_data for both SSH-1 and SSH-2.
Saves duplication between agent and port forwarding code.

Conflicts:
	ssh.c
2016-04-23 16:02:12 +01:00
Ben Harris
93988f3ada Call ssh2_try_send() from ssh2_add_channel_data() and rename latter
All calls to ssh2_add_channel_data() were followed by a call to
ssh2_try_send(), so it seems sensible to replace ssh2_add_channel_data()
with ssh2_send_channel_data(), which does both.
2016-04-23 15:51:02 +01:00
Ben Harris
6da1a325cc Simplifiy handling of stdin data in SSH-2.
Specifically, don't try to unblock all channels just because we've got
something to send on the main one.  It looks like the code to do that
was left over from when SSH_MSG_CHANNEL_ADJUST was handled in
do_ssh2_authconn().
2016-04-23 13:10:11 +01:00
Ben Harris
5347f9e69c Put handling of incoming data on agent channels into its own function.
This function can be shared between SSH-1 and SSH-2, and makes the
per-protocol data-handling functions more generic.
2016-04-22 23:45:17 +01:00
Jacob Nevins
697ea87808 Fix plurality in unknown host keys log message. 2016-04-10 15:57:00 +01:00
Ben Harris
c431c63f5c Correct a comment: OUR_V2_WINSIZE is now the default, not maximum. 2016-04-09 00:46:43 +01:00
Jacob Nevins
16dfefcbde Stop supporting fallback between SSH versions.
The UI now only has "1" and "2" options for SSH protocol version, which
behave like the old "1 only" and "2 only" options; old
SSH-N-with-fallback settings are interpreted as SSH-N-only.

This prevents any attempt at a protocol downgrade attack.
Most users should see no difference; those poor souls who still have to
work with SSH-1 equipment now have to explicitly opt in.
2016-04-02 12:46:04 +01:00
Simon Tatham
940a82fd37 Special host key warning when a better key exists.
If you're connecting to a new server and it _only_ provides host key
types you've configured to be below the warning threshold, it's OK to
give the standard askalg() message. But if you've newly demoted a host
key type and now reconnect to some server for which that type was the
best key you had cached, the askalg() wording isn't really appropriate
(it's not that the key we've settled on is the first type _supported
by the server_, it's that it's the first type _cached by us_), and
also it's potentially helpful to list the better algorithms so that
the user can pick one to cross-certify.
2016-03-27 18:20:37 +01:00
Simon Tatham
909a7af07c Fix assertion failure in host keys log message.
When Jacob introduced this message in d0d3c47a0, he was right to
assume that hostkey_algs[] and ssh->uncert_hostkeys[] were sorted in
the same order. Unfortunately, he became wrong less than an hour later
when I committed d06098622. Now we avoid making any such assumption.
2016-03-27 14:59:18 +01:00
Jacob Nevins
6b401c7166 Fix log message about alternate host keys.
Since we got a dynamic preference order, it's been bailing out at a
random point, and listing keys we wouldn't use.
(It would still be nice to only mention keys that we'd actually use, but
that's now quite fiddly.)
2016-03-26 18:47:54 +00:00
Simon Tatham
52746ae793 Add some missing 'const' in ssh.c arrays.
I noticed this in passing while tinkering with the hostkey_algs array:
these arrays are full of pointers-to-const, but are not also
themselves declared const, which they should have been all along.
2016-03-25 16:32:18 +00:00
Simon Tatham
d06098622c Configurable preference list for SSH host key types.
Now we actually have enough of them to worry about, and especially
since some of the types we support are approved by organisations that
people might make their own decisions about whether to trust, it seems
worth having a config list for host keys the same way we have one for
kex types and ciphers.

To make room for this, I've created an SSH > Host Keys config panel,
and moved the existing host-key related configuration (manually
specified fingerprints) into there from the Kex panel.
2016-03-25 16:32:17 +00:00
Jacob Nevins
d0d3c47a08 Log when we avoid using an unknown host key.
Intended as a hint that users may want to use the "Cache new host key type"
special command.
2016-03-25 15:43:28 +00:00
Simon Tatham
221d669e4d Update the specials menu as keys are cross-certified.
If you've just certified a key, you want it to vanish from the menu
immediately, of course.
2016-03-21 19:05:32 +00:00
Simon Tatham
2d217ec862 Ahem. Cross-certify the key the user actually asked for.
I got momentarily confused between whether the special code
(TS_LOCALSTART+i) meant the ith entry in the variable
uncert_hostkeys[] array, or the ith entry in the fixed hostkey_algs[]
array. Now I think everything agrees on it being the latter.
2016-03-21 18:59:01 +00:00
Simon Tatham
e786452cb2 Add manual cross-certification of new host keys.
If a server offers host key algorithms that we don't have a stored key
for, they will now appear in a submenu of the Special Commands menu.
Selecting one will force a repeat key exchange with that key, and if
it succeeds, will add the new host key to the cache. The idea is that
the new key sent by the server is protected by the crypto established
in the previous key exchange, so this is just as safe as typing some
command like 'ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub' at the
server prompt and transcribing the results manually.

This allows switching over to newer host key algorithms if the client
has begun to support them (e.g. people using PuTTY's new ECC
functionality for the first time), or if the server has acquired a new
key (e.g. due to a server OS upgrade).

At the moment, it's only available manually, for a single host key
type at a time. Automating it is potentially controversial for
security policy reasons (what if someone doesn't agree this is what
they want in their host key cache, or doesn't want to switch over to
using whichever of the keys PuTTY would now put top of the list?), for
code plumbing reasons (chaining several of these rekeys might be more
annoying than doing one at a time) and for CPU usage reasons (rekeys
are expensive), but even so, it might turn out to be a good idea in
future.
2016-03-21 07:38:31 +00:00
Simon Tatham
10a48c3591 Allocate the SSH specials list dynamically.
The last list we returned is now stored in the main Ssh structure
rather than being a static array in ssh_get_specials.

The main point of this is that I want to start adding more dynamic
things to it, for which I can't predict the array's max length in
advance.

But also this fixes a conceptual wrongness, in that if a process had
more than one Ssh instance in it then their specials arrays would have
taken turns occupying the old static array, and although the current
single-threaded client code in the GUI front ends wouldn't have minded
(it would have read out the contents just once immediately after
get_specials returned), it still feels as if it was a bug waiting to
happen.
2016-03-21 06:50:50 +00:00
Simon Tatham
984fe3dde8 Merge branch 'pre-0.67' 2016-02-29 19:59:59 +00:00
Simon Tatham
b49a8db1b4 Tighten up pointer handling after ssh_pkt_getstring.
ssh_pkt_getstring can return (NULL,0) if the input packet is too short
to contain a valid string.

In quite a few places we were passing the returned pointer,length pair
to a printf function with "%.*s" type format, which seems in practice
to have not been dereferencing the pointer but the C standard doesn't
actually guarantee that. In one place we were doing the same job by
hand with memcpy, and apparently that _can_ dereference the pointer in
practice (so a server could have caused a NULL-dereference crash by
sending an appropriately malformed "x11" type channel open request).
And also I spotted a logging call in the "forwarded-tcpip" channel
open handler which had forgotten the field width completely, so it was
erroneously relying on the string happening to be NUL-terminated in
the received packet.

I've tightened all of this up in general by normalising (NULL,0) to
("",0) before calling printf("%.*s"), and replacing the two even more
broken cases with the corrected version of that same idiom.
2016-02-29 19:59:37 +00:00
Simon Tatham
7c65b9c57a Option to log proxy setup diagnostics to the terminal.
It has three settings: on, off, and 'only until session starts'. The
idea of the last one is that if you use something like 'ssh -v' as
your proxy command, you probably wanted to see the initial SSH
connection-setup messages while you were waiting to see if the
connection would be set up successfully at all, but probably _didn't_
want a slew of diagnostics from rekeys disrupting your terminal in
mid-emacs once the session had got properly under way.

Default is off, to avoid startling people used to the old behaviour. I
wonder if I should have set it more aggressively, though.
2015-11-22 15:12:10 +00:00
Simon Tatham
a6e76ae453 Factor out the back ends' plug log functions.
I'm about to want to make a change to all those functions at once, and
since they're almost identical, it seemed easiest to pull them out
into a common helper. The new source file be_misc.c is intended to
contain helper code common to all network back ends (crypto and
non-crypto, in particular), and initially it contains a
backend_socket_log() function which is the common part of ssh_log(),
telnet_log(), rlogin_log() etc.
2015-11-22 15:11:00 +00:00
Simon Tatham
37cdfdcd51 Tell the truth about DNS lookups in the Event Log.
We've always had the back-end code unconditionally print 'Looking up
host' before calling name_lookup. But name_lookup doesn't always do an
actual lookup - in cases where the connection will be proxied and
we're configured to let the proxy do the DNS for us, it just calls
sk_nonamelookup to return a dummy SockAddr with the unresolved name
still in it. It's better to print a message that varies depending on
whether we're _really_ doing DNS or not, e.g. so that people can tell
the difference between DNS failure and proxy misconfiguration.

Hence, those log messages are now generated inside name_lookup(),
which takes a couple of extra parameters for the purpose - a frontend
pointer to pass to logevent(), and a reason string so that it can say
what the hostname it's (optionally) looking up is going to be used
for. (The latter is intended for possible use in logging subsidiary
lookups for port forwarding, though  the moment I haven't changed
the current setup where those connection setups aren't logged in
detail - we just pass NULL in that situation.)
2015-11-22 15:10:59 +00:00
Simon Tatham
b003e5cf53 Fix an SSH-breaking bug from the fuzzing merge.
When we set ssh->sc{cipher,mac} to s->sc{cipher,mac}_tobe
conditionally, we should be conditionalising on the values we're
_reading_, not the ones we're about to overwrite.

Thanks to Colin Harrison for this patch.
2015-11-07 20:15:24 +00:00
Simon Tatham
fe16b577ef Fix a build failure coming from the fuzzing branch.
Apparently if you maintain a branch for a long time where you only
compile with a non-default ifdef enabled, it becomes possible to not
notice a typo you left in the default branch :-)
2015-11-07 14:53:48 +00:00
Ben Harris
7a5cb2838f Emit a distinct error message when the SSH server's host key is invalid.
This also means that FUZZING can just ignore host-key verification
failure while preserving invalid-host-key errors.
2015-10-28 22:08:59 +00:00
Ben Harris
af1460d6e5 Add FUZZING support to ssh.c.
This adds the "none" cipher and MAC, and also disables kex signure
verification and host-key checking.  Since a client like this is
completely insecure, it also rewrites the client version string to
start "ISH", which should make it fail to interoperate with a real SSH
server.  The server version string is still expected to begin "SSH" so
the real packet captures can be used against it.
2015-10-28 22:08:58 +00:00
Ben Harris
5471539a67 Handle packets with no type byte by returning SSH_MSG_UNIMPLEMENTED.
The previous assertion failure is obviously wrong, but RFC 4253 doesn't
explicitly declare them to be a protocol error.  Currently, the incoming
packet isn't logged, which might cause some confusion for log parsers.

Bug found with the help of afl-fuzz.
2015-10-28 22:08:58 +00:00
Ben Harris
f7365a2d57 Handle packets with no type byte by returning SSH_MSG_UNIMPLEMENTED.
The previous assertion failure is obviously wrong, but RFC 4253 doesn't
explicitly declare them to be a protocol error.  Currently, the incoming
packet isn't logged, which might cause some confusion for log parsers.

Bug found with the help of afl-fuzz.
2015-10-24 22:45:48 +01:00
Simon Tatham
758ac4c206 Initialise the random state in ssh_test_for_upstream().
This protects the Unix platform sharing code in the case where no salt
file exists yet in the connection-sharing directory, in which case
make_dirname() will want to create one by using some random bytes, and
prior to this commit, would fail an assertion because the random
number generator wasn't set up.

It would be neater to just return FALSE from ssh_test_for_upstream in
that situation - if there's no salt file, then no sharing socket can
be valid anyway - but that would involve doing more violence to the
code structure than I'm currently prepared to do for a minor elegance
gain.
2015-10-24 16:44:37 +01:00
Simon Tatham
d61c6cad0b Don't try to load GSSAPI libs unless we'll use them.
A user reports that in a particular situation one of the calls to
LoadLibrary from wingss.c has unwanted side effects, and points out
that this happens even when the saved session has GSSAPI disabled. So
I've evaluated as much as possible of the condition under which we
check the results of GSS library loading, and deferred the library
loading itself until after that condition says we even care about the
results.

(cherry picked from commit 9a08d9a7c1)
2015-10-17 17:30:17 +01:00
Simon Tatham
7c2ea22784 New Plink operating mode: 'plink -shareexists'.
A Plink invocation of the form 'plink -shareexists <session>' tests
for a currently live connection-sharing upstream for the session in
question. <session> can be any syntax you'd use with Plink to make the
actual connection (a host/port number, a bare saved session name,
-load, whatever).

I envisage this being useful for things like adaptive proxying - e.g.
if you want to connect to host A which you can't route to directly,
and you might already have a connection to either of hosts B or C
which are viable proxies, then you could write a proxy shell script
which checks whether you already have an upstream for B or C and goes
via whichever one is currently active.

Testing for the upstream's existence has to be done by actually
connecting to its socket, because on Unix the mere existence of a
Unix-domain socket file doesn't guarantee that there's a process
listening to it. So we make a test connection, and then immediately
disconnect; hence, that shows up in the upstream's event log.
2015-09-25 12:11:27 +01:00
Simon Tatham
e0252a4a60 Factor out ssh_hostport_setup().
This is the part of ssh.c's connect_to_host() which figures out the
host name and port number that logically identify the connection -
i.e. not necessarily where we physically connected to, but what we'll
use to look up the saved session cache, put in the window title bar,
and give to the connection sharing code to identify other connections
to share with.

I'm about to want to use it for another purpose, so it needs to be
moved out into a separate function.
2015-09-25 12:07:14 +01:00
Simon Tatham
5f6e443b55 Don't try to agree a MAC we'll never use.
If we've chosen the ChaCha20-Poly1305 option for a cipher, then that
forces the use of its associated MAC. In that situation, we should
avoid even _trying_ to figure out a MAC by examining the MAC string
from the server's KEXINIT, because we won't use the MAC selected by
that method anyway, so there's no point imposing the requirement on
servers to present a MAC we believe in just so we know it's there.

This was breaking interoperation with tinysshd, and is in violation of
OpenSSH's spec for the "chacha20-poly1305@openssh.com" cipher.
2015-09-24 11:41:43 +01:00
Simon Tatham
43be90e287 Split ssh2_cipher's keylen field into two.
The revamp of key generation in commit e460f3083 made the assumption
that you could decide how many bytes of key material to generate by
converting cipher->keylen from bits to bytes. This is a good
assumption for all ciphers except DES/3DES: since the SSH DES key
setup ignores one bit in every byte of key material it's given, you
need more bytes than its keylen field would have you believe. So
currently the DES ciphers aren't being keyed correctly.

The original keylen field is used for deciding how big a DH group to
request, and on that basis I think it still makes sense to keep it
reflecting the true entropy of a cipher key. So it turns out we need
two _separate_ key length fields per cipher - one for the real
entropy, and one for the much more obvious purpose of knowing how much
data to ask for from ssh2_mkkey.

A compensatory advantage, though, is that we can now measure the
latter directly in bytes rather than bits, so we no longer have to
faff about with dividing by 8 and rounding up.
2015-09-10 08:11:26 +01:00
Simon Tatham
e460f30831 Remove arbitrary limit SSH2_MKKEY_ITERS.
Tim Kosse points out that we now support some combinations of crypto
primitives which break the hardwired assumption that two blocks of
hash output from the session-key derivation algorithm are sufficient
to key every cipher and MAC in the system.

So now ssh2_mkkey is given the desired key length, and performs as
many iterations as necessary.
2015-08-21 23:41:05 +01:00