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

345 Commits

Author SHA1 Message Date
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
7de8801e73 Factor KEXINIT analysis out into its own function.
The function takes the two KEXINIT packets in their string form,
together with a list of mappings from names to known algorithm
implementations, and returns the selected one of each kind, along with
all the other necessary auxiliary stuff.
2018-10-21 10:02:10 +01:00
Simon Tatham
fe26ddb1d9 Move transient host key cache into its own file.
This is a nice standalone piece of code which doesn't really have to
appear in the middle of ssh2transport.
2018-10-21 10:02:10 +01:00
Simon Tatham
dead35dd0f New system for handling SSH terminal modes.
I've introduced a new POD struct type 'ssh_ttymodes' which stores an
encoding of everything you can specify in the "pty-req" packet or the
SSH-1 equivalent. This allows me to split up
write_ttymodes_to_packet_from_conf() into two separate functions, one
to parse all the ttymode data out of a Conf (and a Seat for fallback)
and return one of those structures, and the other to write it into an
SSH packet.

While I'm at it, I've moved the special case of terminal speeds into
the same mechanism, simplifying the call sites in both versions of the
SSH protocol.

The new master definition of all terminal modes lives in a header
file, with an ifdef around each item, so that later on I'll be able to
include it in a context that only enumerates the modes supported by
the particular target Unix platform.
2018-10-21 10:02:10 +01:00
Simon Tatham
431f92ade9 Move mainchan into its own file, like agentf.
This gets another big pile of logic out of ssh2connection and puts it
somewhere more central. Now the only thing left in ssh2connection is
the formatting and parsing of the various channel requests; the logic
deciding which ones to issue and what to do about them is devolved to
the Channel implementation, as it properly should be.
2018-10-21 10:02:10 +01:00
Simon Tatham
b4c8fd9d86 New abstraction 'Seat', to pass to backends.
This is a new vtable-based abstraction which is passed to a backend in
place of Frontend, and it implements only the subset of the Frontend
functions needed by a backend. (Many other Frontend functions still
exist, notably the wide range of things called by terminal.c providing
platform-independent operations on the GUI terminal window.)

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

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

I've centralised a full set of stub methods in misc.c for the new
abstraction, which allows me to get rid of several annoying stubs in
the previous code. Also, while I'm here, I've moved a lot of
duplicated modalfatalbox() type functions from application main
program files into wincons.c / uxcons.c, which I think saves
duplication overall. (A minor visible effect is that the prefixes on
those console-based fatal error messages will now be more consistent
between applications.)
2018-10-11 19:58:42 +01:00
Simon Tatham
ad0c502cef Refactor the LogContext type.
LogContext is now the owner of the logevent() function that back ends
and so forth are constantly calling. Previously, logevent was owned by
the Frontend, which would store the message into its list for the GUI
Event Log dialog (or print it to standard error, or whatever) and then
pass it _back_ to LogContext to write to the currently open log file.
Now it's the other way round: LogContext gets the message from the
back end first, writes it to its log file if it feels so inclined, and
communicates it back to the front end.

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

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

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

While I'm tidying up, I've also moved the printf-style logeventf() and
the handy logevent_and_free() into logging.c, instead of having copies
of them scattered around other places. This has also let me remove
some stub functions from a couple of outlying applications like
Pageant. Finally, I've removed the pointless "_tag" at the end of
LogContext's official struct name.
2018-10-10 21:50:50 +01:00
Simon Tatham
2e7ced6480 Give BPPs a Frontend, so they can do their own logging.
The sshverstring quasi-frontend is passed a Frontend pointer at setup
time, so that it can generate Event Log entries containing the local
and remote version strings and the results of remote bug detection.

I'm promoting that field of sshverstring to a field of the public BPP
structure, so now all BPPs have the right to talk directly to the
frontend if they want to. This means I can move all the log messages
of the form 'Initialised so-and-so cipher/MAC/compression' down into
the BPPs themselves, where they can live exactly alongside the actual
initialisation of those primitives.

It also means BPPs will be able to log interesting things they detect
at any point in the packet stream, which is about to come in useful
for another purpose.
2018-10-07 09:10:14 +01:00
Simon Tatham
36caf03a5b Utility routines for iterating over a packet queue.
I haven't needed these until now, but I'm about to need to inspect the
entire contents of a packet queue before deciding whether to process
the first item on it.

I've changed the single 'vtable method' in packet queues from get(),
which returned the head of the queue and optionally popped it, to
after() which does the same bug returns the item after a specified
tree node. So if you pass the special end node to after(), then it
behaves like get(), but now you can also use it to retrieve the
successor of a packet.

(Orthogonality says that you can also _pop_ the successor of a packet
by calling after() with prev != pq.end and pop == TRUE. I don't have a
use for that one yet.)
2018-10-07 09:10:14 +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
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
57553bdaac sshshare: notify cl when last downstream goes away.
The check_termination function in ssh2connection is supposed to be
called whenever it's possible that we've run out of (a) channels, and
(b) sharing downstreams. I've been calling it on every channel close,
but apparently completely forgot to add a callback from sshshare.c
that also arranges to call it when we run out of downstreams.
2018-09-28 20:52:36 +01:00
Simon Tatham
0bdda64724 Fix paste error in packet-type list macro.
In commit 8cb68390e I managed to copy the packet contexts inaccurately
from the old implementation of ssh2_pkt_type, and listed the ECDH KEX
packets against SSH2_PKTCTX_DHGEX instead of SSH2_PKTCTX_ECDHKEX,
which led to them appearing as "unknown" in packet log files.
2018-09-25 23:39:10 +01:00
Simon Tatham
2ca0070f89 Move most of ssh.c out into separate source files.
I've tried to separate out as many individually coherent changes from
this work as I could into their own commits, but here's where I run
out and have to commit the rest of this major refactoring as a
big-bang change.

Most of ssh.c is now no longer in ssh.c: all five of the main
coroutines that handle layers of the SSH-1 and SSH-2 protocols now
each have their own source file to live in, and a lot of the
supporting functions have moved into the appropriate one of those too.

The new abstraction is a vtable called 'PacketProtocolLayer', which
has an input and output packet queue. Each layer's main coroutine is
invoked from the method ssh_ppl_process_queue(), which is usually
(though not exclusively) triggered automatically when things are
pushed on the input queue. In SSH-2, the base layer is the transport
protocol, and it contains a pair of subsidiary queues by which it
passes some of its packets to the higher SSH-2 layers - first userauth
and then connection, which are peers at the same level, with the
former abdicating in favour of the latter at the appropriate moment.
SSH-1 is simpler: the whole login phase of the protocol (crypto setup
and authentication) is all in one module, and since SSH-1 has no
repeat key exchange, that setup layer abdicates in favour of the
connection phase when it's done.

ssh.c itself is now about a tenth of its old size (which all by itself
is cause for celebration!). Its main job is to set up all the layers,
hook them up to each other and to the BPP, and to funnel data back and
forth between that collection of modules and external things such as
the network and the terminal. Once it's set up a collection of packet
protocol layers, it communicates with them partly by calling methods
of the base layer (and if that's ssh2transport then it will delegate
some functionality to the corresponding methods of its higher layer),
and partly by talking directly to the connection layer no matter where
it is in the stack by means of the separate ConnectionLayer vtable
which I introduced in commit 8001dd4cb, and to which I've now added
quite a few extra methods replacing services that used to be internal
function calls within ssh.c.

(One effect of this is that the SSH-1 and SSH-2 channel storage is now
no longer shared - there are distinct struct types ssh1_channel and
ssh2_channel. That means a bit more code duplication, but on the plus
side, a lot fewer confusing conditionals in the middle of half-shared
functions, and less risk of a piece of SSH-1 escaping into SSH-2 or
vice versa, which I remember has happened at least once in the past.)

The bulk of this commit introduces the five new source files, their
common header sshppl.h and some shared supporting routines in
sshcommon.c, and rewrites nearly all of ssh.c itself. But it also
includes a couple of other changes that I couldn't separate easily
enough:

Firstly, there's a new handling for socket EOF, in which ssh.c sets an
'input_eof' flag in the BPP, and that responds by checking a flag that
tells it whether to report the EOF as an error or not. (This is the
main reason for those new BPP_READ / BPP_WAITFOR macros - they can
check the EOF flag every time the coroutine is resumed.)

Secondly, the error reporting itself is changed around again. I'd
expected to put some data fields in the public PacketProtocolLayer
structure that it could set to report errors in the same way as the
BPPs have been doing, but in the end, I decided propagating all those
data fields around was a pain and that even the BPPs shouldn't have
been doing it that way. So I've reverted to a system where everything
calls back to functions in ssh.c itself to report any connection-
ending condition. But there's a new family of those functions,
categorising the possible such conditions by semantics, and each one
has a different set of detailed effects (e.g. how rudely to close the
network connection, what exit status should be passed back to the
whole application, whether to send a disconnect message and/or display
a GUI error box).

I don't expect this to be immediately perfect: of course, the code has
been through a big upheaval, new bugs are expected, and I haven't been
able to do a full job of testing (e.g. I haven't tested every auth or
kex method). But I've checked that it _basically_ works - both SSH
protocols, all the different kinds of forwarding channel, more than
one auth method, Windows and Linux, connection sharing - and I think
it's now at the point where the easiest way to find further bugs is to
let it out into the wild and see what users can spot.
2018-09-24 19:45:22 +01:00
Simon Tatham
623c7b720c Put an optional IdempotentCallback in packet queues.
This means that someone putting things on a packet queue doesn't need
to separately hold a pointer to someone who needs notifying about it,
or remember to call the notification function every time they push
things on the queue. It's all taken care of automatically, without
having to put extra stuff at the call sites.

The precise semantics are that the callback will be scheduled whenever
_new_ packets appear on the queue, but not when packets are removed.
(Because the expectation is that the callback is notifying whoever is
consuming the queue.)
2018-09-24 15:32:47 +01:00
Simon Tatham
a703f86731 Defer passing a ConnectionLayer to sshshare.c.
This paves the way for me to reorganise ssh.c in a way that will mean
I don't have a ConnectionLayer available yet at the time I have to
create the connshare. The constructor function now takes a mere
Frontend, for generating setup-time Event Log messages, and there's a
separate ssh_connshare_provide_connlayer() function I can call later
once I have the ConnectionLayer to provide.

NFC for the moment: the new provide_connlayer function is called
immediately after ssh_connection_sharing_init.
2018-09-24 15:32:47 +01:00
Simon Tatham
96622d17a3 Move verify_ssh_manual_host_key into sshcommon.c
This is essentially trivial, because the only thing it needed from the
Ssh structure was the Conf. So the version in sshcommon.c just takes
an actual Conf as an argument, and now it doesn't need access to the
big structure definition any more.
2018-09-24 14:19:52 +01:00
Simon Tatham
f6f8219a3d Replace PktIn reference count with a 'free queue'.
This is a new idea I've had to make memory-management of PktIn even
easier. The idea is that a PktIn is essentially _always_ an element of
some linked-list queue: if it's not one of the queues by which packets
move through ssh.c, then it's a special 'free queue' which holds
packets that are unowned and due to be freed.

pq_pop() on a PktInQueue automatically relinks the packet to the free
queue, and also triggers an idempotent callback which will empty the
queue and really free all the packets on it. Hence, you can pop a
packet off a real queue, parse it, handle it, and then just assume
it'll get tidied up at some point - the only constraint being that you
have to finish with it before returning to the application's main loop.

The exception is that it's OK to pq_push() the packet back on to some
other PktInQueue, because a side effect of that will be to _remove_ it
from the free queue again. (And if _all_ the incoming packets get that
treatment, then when the free-queue handler eventually runs, it may
find it has nothing to do - which is harmless.)
2018-09-24 14:12:56 +01:00
Simon Tatham
09c3439b5a Move SSH_MSG_UNEXPECTED generation into the BPP.
Now I've got a list macro defining all the packet types we recognise,
I can use it to write a test for 'is this a recognised code?', and use
that in turn to centralise detection of completely unrecognised codes
into the binary packet protocol, where any such messages will be
handled entirely internally and never even be seen by the next level
up. This lets me remove another big pile of boilerplate in ssh.c.
2018-09-24 14:12:56 +01:00
Simon Tatham
8cb68390e4 Move SSH packet type codes into list macros.
This allows me to share just one definition of the packet types
between the enum declarations in ssh.h and the string translation
functions in sshcommon.c. No functional change.

The style of list macro is slightly unusual; instead of the
traditional 'X-macro' in which LIST(X) expands to invocations of the
form X(list element), this is an 'X-y macro', where LIST(X,y) expands
to invocations of the form X(y, list element). That style makes it
possible to wrap the list macro up in another macro and pass a
parameter through from the wrapper to the per-element macro. I'm not
using that facility just yet, but I will in the next commit.
2018-09-24 13:29:09 +01:00
Simon Tatham
a19faa4527 Minor header-file cleanups.
Moved the typedef of BinaryPacketProtocol into defs.h on the general
principle that it's just the kind of thing that ought to go there;
also removed the declaration of pq_base_init from ssh.h on the grounds
that there's never been any such function! (At least, not in public
source control - it existed in an early draft of commit 6e24b7d58.)
2018-09-21 16:53:45 +01:00
Simon Tatham
93f2df9b83 New system for tracking data-limit-based rekeys.
I've removed the encrypted_len fields from PktIn and PktOut, which
were used to communicate from the BPP to ssh.c how much each packet
contributed to the amount of data encrypted with a given set of cipher
keys. It seems more sensible to have the BPP itself keep that counter
- especially since only one of the three BPPs even needs to count it
at all. So now there's a new DataTransferStats structure which the BPP
updates, and ssh.c only needs to check it for overflow and reset the
limits.
2018-09-19 23:08:28 +01:00
Simon Tatham
26364bb6a1 Move comma-separated string functions into sshcommon.c.
These are just string handling, after all. They could even move into
misc.c if any non-SSH-related code ever had a need for them.
2018-09-19 23:08:28 +01:00
Simon Tatham
968252bbdc Move alloc_channel_id into sshcommon.c.
That function _did_ depend on ssh.c's internal facilities, namely the
layout of 'struct ssh_channel'. In place of that, it now takes an
extra integer argument telling it where to find the channel id in
whatever data structure you give it a tree of - so now I can split up
the SSH-1 and SSH-2 channel handling without losing the services of
that nice channel-number allocator.
2018-09-19 23:08:28 +01:00
Simon Tatham
12abb95394 Move the ttymode formatter into sshcommon.c.
While I'm at it, I've brought it all into a single function: the
parsing of data from Conf, the list of modes, and even the old
callback system for writing to the destination buffer is now a simple
if statement that formats mode parameters as byte or uint32 depending
on SSH version. Also, the terminal speeds and the end byte are part of
the same setup, so it's all together in one place instead of scattered
all over ssh.c.
2018-09-19 23:08:28 +01:00
Simon Tatham
6a5d4d083a Make pq_empty_on_to_front_of more general.
It's really just a concatenator for a pair of linked lists, but
unhelpfully restricted in which of the lists it replaces with the
output. Better to have a three-argument function that puts the output
wherever you like, whether it overlaps either or neither one of the
inputs.
2018-09-19 23:08:28 +01:00
Simon Tatham
6e24b7d589 Extend PacketQueue to take PktOut as well.
Some upcoming restructuring I've got planned will need to pass output
packets back and forth on queues, as well as input ones. So here's a
change that arranges that we can have a PktInQueue and a PktOutQueue,
sharing most of their implementation via a PacketQueueBase structure
which links together the PacketQueueNode fields in the two packet
structures.

There's a tricksy bit of macro manoeuvring to get all of this
type-checked, so that I can't accidentally link a PktOut on to a
PktInQueue or vice versa. It works by having the main queue functions
wrapped by macros; when receiving a packet structure on input, they
type-check it against the queue structure and then automatically look
up its qnode field to pass to the underlying PacketQueueBase function;
on output, they translate a returned PacketQueueNode back to its
containing packet type by calling a 'get' function pointer.
2018-09-19 23:08:28 +01:00
Simon Tatham
370ff150ab Move bug flag definitions out into ssh.h.
With a new shiny list-macro system that will allocate power-of-2
values for them without me having to manually keep the numbers
straight.
2018-09-19 23:08:28 +01:00
Simon Tatham
a313048763 New utility function logevent_and_free.
This should make it easier to do formatted-string based logging
outside ssh.c, because I can wrap up a local macro in any source file
I like that expands to logevent_and_free(wherever my Frontend is,
dupprintf(macro argument)).

It caused yet another stub function to be needed in testbn, but there
we go.

(Also, while I'm here, removed a redundant declaration of logevent
itself from ssh.h. The one in putty.h is all we need.)
2018-09-19 23:08:28 +01:00
Simon Tatham
8001dd4cbb New abstraction 'ConnectionLayer'.
This is a vtable that wraps up all the functionality required from the
SSH connection layer by associated modules like port forwarding and
connection sharing. This extra layer of indirection adds nothing
useful right now, but when I later separate the SSH-1 and SSH-2
connection layer implementations, it will be convenient for each one
to be able to implement this vtable in terms of its own internal data
structures.

To simplify this vtable, I've moved a lot of the logging duties
relating to connection sharing out of ssh.c into sshshare.c: now it
handles nearly all the logging itself relating to setting up
connection sharing in the first place and downstreams connecting and
disconnecting. The only exception is the 'Reusing a shared connection'
announcement in the console window, which is now done in ssh.c by
detecting downstream status immediately after setup.
2018-09-19 23:08:28 +01:00
Simon Tatham
895b09a4c6 Move port-forwarding setup out of ssh.c.
The tree234 storing currently active port forwardings - both local and
remote - now lives in portfwd.c, as does the complicated function that
updates it based on a Conf listing the new set of desired forwardings.

Local port forwardings are passed to ssh.c via the same route as
before - once the listening port receives a connection and portfwd.c
knows where it should be directed to (in particular, after the SOCKS
exchange, if any), it calls ssh_send_port_open.

Remote forwardings are now initiated by calling ssh_rportfwd_alloc,
which adds an entry to the rportfwds tree (which _is_ still in ssh.c,
and still confusingly sorted by a different criterion depending on SSH
protocol version) and sends out the appropriate protocol request.
ssh_rportfwd_remove cancels one again, sending a protocol request too.

Those functions look enough like ssh_{alloc,remove}_sharing_rportfwd
that I've merged those into the new pair as well - now allocating an
rportfwd allows you to specify either a destination host/port or a
sharing context, and returns a handy pointer you can use to cancel the
forwarding later.
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
d437e5402e Make ssh_compress into a pair of linked classoids.
This was mildly fiddly because there's a single vtable structure that
implements two distinct interface types, one for compression and one
for decompression - and I have actually confused them before now
(commit d4304f1b7), so I think it's important to make them actually be
separate types!
2018-09-19 23:08:07 +01:00
Simon Tatham
03fb4423af Expose the 'dh_ctx' struct tag used for Diffie-Hellman. 2018-09-19 23:08:07 +01:00
Simon Tatham
9738e042f9 Clean up a couple of consts and char pointers.
hmacmd5_do_hmac and hmac_sha1_simple should be consistently referring
to input memory blocks as 'const void *', but one had pointlessly
typed the pointer as 'const unsigned char *' and the other had missed
out the consts.
2018-09-19 23:08:07 +01:00
Simon Tatham
4f9a90fc1a Turn SSH hashes into a classoid.
The new version of ssh_hash has the same nice property as ssh2_mac,
that I can make the generic interface object type function directly as
a BinarySink so that clients don't have to call h->sink() and worry
about the separate sink object they get back from that.
2018-09-19 23:08:07 +01:00
Simon Tatham
853bd8b284 Turn SSH-2 MACs into a classoid.
This piece of tidying-up has come out particularly well in terms of
saving tedious repetition and boilerplate. I've managed to remove
three pointless methods from every MAC implementation by means of
writing them once centrally in terms of the implementation-specific
methods; another method (hmacmd5_sink) vanished because I was able to
make the interface type 'ssh2_mac' be directly usable as a BinarySink
by way of a new delegation system; and because all the method
implementations can now find their own vtable, I was even able to
merge a lot of keying and output functions that had previously
differed only in length parameters by having them look up the lengths
in whatever vtable they were passed.
2018-09-19 23:08:07 +01:00
Simon Tatham
229af2b5bf Turn SSH-2 ciphers into a classoid.
This is more or less the same job as the SSH-1 case, only more
extensive, because we have a wider range of ciphers.

I'm a bit disappointed about the AES case, in particular, because I
feel as if it ought to have been possible to arrange to combine this
layer of vtable dispatch with the subsidiary one that selects between
hardware and software implementations of the underlying cipher. I may
come back later and have another try at that, in fact.
2018-09-19 23:08:07 +01:00
Simon Tatham
6c5cc49e27 Turn SSH-1 ciphers into a classoid.
The interchangeable system of SSH-1 ciphers previously followed the
same pattern as the backends and the public-key algorithms, in that
all the clients would maintain two separate pointers, one to the
vtable and the other to the individual instance / context. Now I've
merged them, just as I did with those other two, so that you only cart
around a single pointer, which has a vtable pointer inside it and a
type distinguishing it from an instance of any of the other
interchangeable sets of algorithms.
2018-09-19 23:08:07 +01:00
Simon Tatham
65b65bb8ef Expose the structure tag 'crcda_ctx'.
This one isn't used in many places, but it's another 'void *' pointer
that ought to come with an identifying structure tag.
2018-09-19 23:08:07 +01:00
Simon Tatham
fc375c0b6a Remove some redundant utility macros.
ATOFFSET in dialog.h became obsolete when the old 'struct Config' gave
way to the new Conf, because its only use was to identify fields in
struct Config for the generic control handlers to update.

And lenof in ssh.h is redundant because there's also a copy in misc.h.
(Which is already included _everywhere_ that lenof is used - I didn't
even need to add any instances of #include "misc.h" after removing the
copy in ssh.h.)
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
c51fe7c217 Pass the Ssh structure to portfwd.c with a tag.
Again, safer than using a 'void *'.
2018-09-19 22:10:58 +01:00
Simon Tatham
20a9bd5642 Move password-packet padding into the BPP module.
Now when we construct a packet containing sensitive data, we just set
a field saying '... and make it take up at least this much space, to
disguise its true size', and nothing in the rest of the system worries
about that flag until ssh2bpp.c acts on it.

Also, I've changed the strategy for doing the padding. Previously, we
were following the real packet with an SSH_MSG_IGNORE to make up the
size. But that was only a partial defence: it works OK against passive
traffic analysis, but an attacker proxying the TCP stream and
dribbling it out one byte at a time could still have found out the
size of the real packet by noting when the dribbled data provoked a
response. Now I put the SSH_MSG_IGNORE _first_, which should defeat
that attack.

But that in turn doesn't work when we're doing compression, because we
can't predict the compressed sizes accurately enough to make that
strategy sensible. Fortunately, compression provides an alternative
strategy anyway: if we've got zlib turned on when we send one of these
sensitive packets, then we can pad out the compressed zlib data as
much as we like by adding empty RFC1951 blocks (effectively chaining
ZLIB_PARTIAL_FLUSHes). So both strategies should now be dribble-proof.
2018-07-10 21:27:43 +01:00
Simon Tatham
bcb94f966e Make compression functions return void.
The return value wasn't used to indicate failure; it only indicated
whether any compression was being done at all or whether the
compression method was ssh_comp_none, and we can tell the latter just
as well by the fact that its init function returns a null context
pointer.
2018-07-10 21:27:43 +01:00
Simon Tatham
679fa90dfe Move binary packet protocols and censoring out of ssh.c.
sshbpp.h now defines a classoid that encapsulates both directions of
an SSH binary packet protocol - that is, a system for reading a
bufchain of incoming data and turning it into a stream of PktIn, and
another system for taking a PktOut and turning it into data on an
outgoing bufchain.

The state structure in each of those files contains everything that
used to be in the 'rdpkt2_state' structure and its friends, and also
quite a lot of bits and pieces like cipher and MAC states that used to
live in the main Ssh structure.

One minor effect of this layer separation is that I've had to extend
the packet dispatch table by one, because the BPP layer can no longer
directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too
short to have a type byte. Instead, I extend the PktIn type field to
use an out-of-range value to encode that, and the easiest way to make
that trigger an UNIMPLEMENTED message is to have the dispatch table
contain an entry for it.

(That's a system that may come in useful again - I was also wondering
about inventing a fake type code to indicate network EOF, so that that
could be propagated through the layers and be handled by whichever one
currently knew best how to respond.)

I've also moved the packet-censoring code into its own pair of files,
partly because I was going to want to do that anyway sooner or later,
and mostly because it's called from the BPP code, and the SSH-2
version in particular has to be called from both the main SSH-2 BPP
and the bare unencrypted protocol used for connection sharing. While I
was at it, I took the opportunity to merge the outgoing and incoming
censor functions, so that the parts that were common between them
(e.g. CHANNEL_DATA messages look the same in both directions) didn't
need to be repeated.
2018-06-09 14:41:30 +01:00
Simon Tatham
ba7571291a Move some ssh.c declarations into header files.
ssh.c has been an unmanageably huge monolith of a source file for too
long, and it's finally time I started breaking it up into smaller
pieces. The first step is to move some declarations - basic types like
packets and packet queues, standard constants, enums, and the
coroutine system - into headers where other files can see them.
2018-06-09 14:41:30 +01:00
Simon Tatham
be6fed13fa Further void * / const fixes.
Yet more of these that commits 7babe66a8 and 8d882756b didn't spot. I
bet these still aren't the last, either.
2018-06-09 14:20:33 +01:00
Simon Tatham
61a972c332 Make share_got_pkt_from_server take a const pointer.
It was horrible - even if harmless in practice - that it wrote the
NATed channel id over its input buffer, and I think it's worth the
extra memory management to avoid doing that.
2018-06-06 07:23:28 +01:00
Simon Tatham
06a14fe8b8 Reorganise ssh_keyalg and use it as a vtable.
After Pavel Kryukov pointed out that I have to put _something_ in the
'ssh_key' structure, I thought of an actually useful thing to put
there: why not make it store a pointer to the ssh_keyalg structure?
Then ssh_key becomes a classoid - or perhaps 'traitoid' is a closer
analogy - in the same style as Socket and Plug. And just like Socket
and Plug, I've also arranged a system of wrapper macros that avoid the
need to mention the 'object' whose method you're invoking twice at
each call site.

The new vtable pointer directly replaces an existing field of struct
ec_key (which was usable by several different ssh_keyalgs, so it
already had to store a pointer to the currently active one), and also
replaces the 'alg' field of the ssh2_userkey structure that wraps up a
cryptographic key with its comment field.

I've also taken the opportunity to clean things up a bit in general:
most of the methods now have new and clearer names (e.g. you'd never
know that 'newkey' made a public-only key while 'createkey' made a
public+private key pair unless you went and looked it up, but now
they're called 'new_pub' and 'new_priv' you might be in with a
chance), and I've completely removed the openssh_private_npieces field
after realising that it was duplicating information that is actually
_more_ conveniently obtained by calling the new_priv_openssh method
(formerly openssh_createkey) and throwing away the result.
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
ff11e10d62 Rename rsa_public_blob_len to mention SSH-1.
It's yet another function with an outdatedly vague name.
2018-06-03 08:12:57 +01:00
Simon Tatham
ae3863679d Give rsa_fingerprint() a new name and API.
It's an SSH-1 specific function, so it should have a name reflecting
that, and it didn't. Also it had one of those outdated APIs involving
passing it a client-allocated buffer and size. Now it has a sensible
name, and internally it constructs the output string using a strbuf
and returns it dynamically allocated.
2018-06-03 08:08:53 +01:00
Simon Tatham
3f1f7c3ce7 Remove downstream remote port forwardings in ssh.c too.
Another piece of half-finished machinery that I can't have tested
properly when I set up connection sharing: I had the function
ssh_alloc_sharing_rportfwd which is how sshshare.c asks ssh.c to start
sending it channel-open requests for a given remote forwarded port,
but I had no companion function that removes one of those requests
again when a downstream remote port forwarding goes away (either by
mid-session cancel-tcpip-forward or by the whole downstream
disconnecting).

As a result, the _second_ attempt to set up the same remote port
forwarding, after a sharing downstream had done so once and then
stopped, would quietly fail.
2018-06-03 07:54:00 +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
ae3edcdfc0 Clean up ssh_keyalg APIs and implementations.
Quite a few of the function pointers in the ssh_keyalg vtable now take
ptrlen arguments in place of separate pointer and length pairs.
Meanwhile, the various key types' implementations of those functions
now work by initialising a BinarySource with the input ptrlen and
using the new decode functions to walk along it.

One exception is the openssh_createkey method which reads a private
key in the wire format used by OpenSSH's SSH-2 agent protocol, which
has to consume a prefix of a larger data stream, and tell the caller
how much of that data was the private key. That function now takes an
actual BinarySource, and passes that directly to the decode functions,
so that on return the caller finds that the BinarySource's read
pointer has been advanced exactly past the private key.

This let me throw away _several_ reimplementations of mpint-reading
functions, one in each of sshrsa, sshdss.c and sshecc.c. Worse still,
they didn't all have exactly the SSH-2 semantics, because the thing in
sshrsa.c whose name suggested it was an mpint-reading function
actually tolerated the wrong number of leading zero bytes, which it
had to be able to do to cope with the "ssh-rsa" signature format which
contains a thing that isn't quite an SSH-2 mpint. Now that deviation
is clearly commented!
2018-06-02 18:00:59 +01:00
Simon Tatham
5be57af173 Rewrite packet parsing in sshshare.c using BinarySource.
Another set of localised decoding routines get thrown away here. Also,
I've changed the APIs of a couple of helper functions in x11fwd.c to
take ptrlens in place of zero-terminated C strings, because that's the
format in which they come back from the decode, and it saves mallocing
a zero-terminated version of each one just to pass to those helpers.
2018-06-02 17:58:15 +01:00
Simon Tatham
7d8312e71f Rewrite SSH-1 RSA handling functions using BinarySource.
The SSH-1 RSA key reading functions now have BinarySource-shaped get_*
forms, although for the moment I'm still supporting the old API as a
wrapper on the new one, because I haven't switched over the client
code yet. Also, rsa_public_blob_len uses the new system internally,
although its API is unchanged.
2018-06-02 17:42:28 +01:00
Simon Tatham
005ca6b257 Introduce a centralised unmarshaller, 'BinarySource'.
This is the companion to the BinarySink system I introduced a couple
of weeks ago, and provides the same type-genericity which will let me
use the same get_* routines on an SSH packet, an SFTP packet or
anything else that chooses to include an implementing substructure.

However, unlike BinarySink which contained a (one-function) vtable,
BinarySource contains only mutable data fields - so another thing you
might very well want to do is to simply instantiate a bare one without
any containing object at all. I couldn't quite coerce C into letting
me use the same setup macro in both cases, so I've arranged a
BinarySource_INIT you can use on larger implementing objects and a
BinarySource_BARE_INIT you can use on a BinarySource not contained in
anything.

The API follows the general principle that even if decoding fails, the
decode functions will always return _some_ kind of value, with the
same dynamically-allocated-ness they would have used for a completely
successful value. But they also set an error flag in the BinarySource
which can be tested later. So instead of having to decode a 10-field
packet by means of 10 separate 'if (!get_foo(src)) throw error'
clauses, you can just write 10 'variable = get_foo(src)' statements
followed by a single check of get_err(src), and if the error check
fails, you have to do exactly the same set of frees you would have
after a successful decode.
2018-06-02 17:37:22 +01:00
Simon Tatham
9e96af59ce Introduce a new 'ptrlen' type.
This wraps up a (pointer, length) pair into a convenient struct that
lets me return it by value from a function, and also pass it through
to other functions in one go.

Ideally quite a lot of this code base could be switched over to using
ptrlen in place of separate pointer and length variables or function
parameters. (In fact, in my personal ideal conception of C, the usual
string type would be of this form, and all the string.h functions
would operate on ptrlens instead of zero-terminated 'char *'.)

For the moment, I'm just introducing it to make some upcoming
refactoring less inconvenient. Bulk migration of existing code to
ptrlen is a project for another time.

Along with the type itself, I've provided a convenient system of
including the contents of a ptrlen in a printf; a constructor function
that wraps up a pointer and length so you can make a ptrlen on the fly
in mid-expression; a function to compare a ptrlen against an ordinary
C string (which I mostly expect to use with string literals); and a
function 'mkstr' to make a dynamically allocated C string out of one.
That last function replaces a function of the same name in sftp.c,
which I'm promoting to a whole-codebase facility and adjusting its
API.
2018-06-02 17:33:23 +01:00
Simon Tatham
8d882756b8 Fix some missing void * and const in existing APIs.
Several changes here that should have been in commit 7babe66a8 but I
missed them.
2018-06-02 17:33:02 +01:00
Pavel Kryukov
e6a60d53be Add a dummy field to ssh_key structure
According to C standard, the behavior is undefined if structure contains
no members.
2018-06-01 19:37:46 +03: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
0fc2d3b455 Invent a struct type for polymorphic SSH key data.
During last week's work, I made a mistake in which I got the arguments
backwards in one of the key-blob-generating functions - mistakenly
swapped the 'void *' key instance with the 'BinarySink *' output
destination - and I didn't spot the mistake until run time, because in
C you can implicitly convert both to and from void * and so there was
no compile-time failure of type checking.

Now that I've introduced the FROMFIELD macro that downcasts a pointer
to one field of a structure to retrieve a pointer to the whole
structure, I think I might start using that more widely to indicate
this kind of polymorphic subtyping. So now all the public-key
functions in the struct ssh_signkey vtable handle their data instance
in the form of a pointer to a subfield of a new zero-sized structure
type 'ssh_key', which outside the key implementations indicates 'this
is some kind of key instance but it could be of any type'; they
downcast that pointer internally using FROMFIELD in place of the
previous ordinary C cast, and return one by returning &foo->sshk for
whatever foo they've just made up.

The sshk member is not at the beginning of the structure, which means
all those FROMFIELDs and &key->sshk are actually adding and
subtracting an offset. Of course I could have put the member at the
start anyway, but I had the idea that it's actually a feature _not_ to
have the two types start at the same address, because it means you
should notice earlier rather than later if you absentmindedly cast
from one to the other directly rather than by the approved method (in
particular, if you accidentally assign one through a void * and back
without even _noticing_ you perpetrated a cast). In particular, this
enforces that you can't sfree() the thing even once without realising
you should instead of called the right freekey function. (I found
several bugs by this method during initial testing, so I think it's
already proved its worth!)

While I'm here, I've also renamed the vtable structure ssh_signkey to
ssh_keyalg, because it was a confusing name anyway - it describes the
_algorithm_ for handling all keys of that type, not a specific key. So
ssh_keyalg is the collection of code, and ssh_key is one instance of
the data it handles.
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
43ec3397b6 Remove vestiges of attempt at MS Crypto API support.
There was a time, back when the USA was more vigorously against
cryptography, when we toyed with the idea of having a version of PuTTY
that outsourced its cryptographic primitives to the Microsoft optional
encryption API, which would effectively create a tool that acted like
PuTTY proper on a system with that API installed, but automatically
degraded to being PuTTYtel on a system without, and meanwhile (so went
the theory) it could be moved freely across national borders with
crypto restrictions, because it didn't _contain_ any of the actual
crypto.

I don't recall that we ever got it working at all. And certainly the
vestiges of it here and there in the current code are completely
unworkable - they refer to an 'mscrypto.c' that doesn't even exist,
and the ifdefs in the definitions of structures like RSAKey and
MD5Context are not matched by any corresponding ifdefs in the code. So
I ought to have got round to removing it long ago, in order to avoid
misleading anyone.
2018-05-26 09:19:38 +01:00
Simon Tatham
e27ddf6d28 Make ssh_hash and ssh_mac expose a BinarySink.
Just as I did a few commits ago with the low-level SHA_Bytes type
functions, the ssh_hash and ssh_mac abstract types now no longer have
a direct foo->bytes() update method at all. Instead, each one has a
foo->sink() function that returns a BinarySink with the same lifetime
as the hash context, and then the caller can feed data into that in
the usual way.

This lets me get rid of a couple more duplicate marshalling routines
in ssh.c: hash_string(), hash_uint32(), hash_mpint().
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
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
0e3082ee89 New centralised binary-data marshalling system.
I've finally got tired of all the code throughout PuTTY that repeats
the same logic about how to format the SSH binary primitives like
uint32, string, mpint. We've got reasonably organised code in ssh.c
that appends things like that to 'struct Packet'; something similar in
sftp.c which repeats a lot of the work; utility functions in various
places to format an mpint to feed to one or another hash function; and
no end of totally ad-hoc stuff in functions like public key blob
formatters which actually have to _count up_ the size of data
painstakingly, then malloc exactly that much and mess about with
PUT_32BIT.

It's time to bring all of that into one place, and stop repeating
myself in error-prone ways everywhere. The new marshal.h defines a
system in which I centralise all the actual marshalling functions, and
then layer a touch of C macro trickery on top to allow me to (look as
if I) pass a wide range of different types to those functions, as long
as the target type has been set up in the right way to have a write()
function.

This commit adds the new header and source file, and sets up some
general centralised types (strbuf and the various hash-function
contexts like SHA_State), but doesn't use the new calls for anything
yet.

(I've also renamed some internal functions in import.c which were
using the same names that I've just defined macros over. That won't
last long - those functions are going to go away soon, so the changed
names are strictly temporary.)
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
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
Tim Kosse
eaac8768e4 Support aes256-ctr encryption when imported OpenSSH keys.
OpenSSH 7.6 switched from aes256-cbc to aes256-ctr for encrypting
new-style private keys.
2018-04-11 22:35:40 +01:00
Pavel I. Kryukov
a27f55e819 Use correct way to detect new instructions in Clang
__clang_major__ and __clang_minor__ macros may be overriden
 in Apple and other compilers. Instead of them, we use
__has_attribute(target) to check whether Clang supports per-function
targeted build and __has_include() to check if there are intrinsic
header files
2018-03-14 20:36:31 +00:00
Pavel I. Kryukov
f51a5c9235 Add supports_sha_ni(void) function
It executes CPUID instruction to check whether
SHA extensions are supported by hosting CPU.
2018-03-12 20:17:47 +00:00
Pavel I. Kryukov
59e2334029 Add pointers to SHA1 and SHA256 implementation functions
These pointers will be required in next commits
where subroutines with new instructions are introduced.
Depending on CPUID dynamic check, pointers will refer to old
SW-only implementations or to new instructions subroutines
2018-03-12 20:17:47 +00:00
Pavel I. Kryukov
5a38b293bd Check whether compiler supports SHA-NI intrinsics
SHA intrinsics are available in Clang >=3.8, GCC >=5, and MSVC >=14,
so if supported compiler is used, COMPILER_SUPPORTS_SHA_NI macro
becomes defined
2018-03-12 20:17:47 +00:00
Simon Tatham
a3d14d77f5 One more warning fix: spurious 'const' on functions.
These must have been absent-mindedly copied from function declarations
of the form 'const type *fn(args)', where the 'const' is meaningful
and describes the data pointed to by the returned pointer, to
functions of the form 'const type fn(args)' where the 'const' is
completely pointless.
2017-02-05 12:08:13 +00:00
Simon Tatham
f0f19b6147 Add some missing 'const' in version.c's string data.
I can't believe this codebase is around 20 years old and has had
multiple giant const-fixing patches, and yet there are _still_ things
that should have been const for years and aren't.
2016-04-07 07:52:55 +01:00
Simon Tatham
0b42fed9bd Polish up the PuTTYgen user interface for ECC key types.
Jacob pointed out that a free-text field for entering a key size in
bits is all very well for key types where we actually _can_ generate a
key to a size of your choice, but less useful for key types where
there are only three (or one) legal values for the field, especially
if we don't _say_ what they are.

So I've revamped the UI a bit: now, in ECDSA mode, you get a dropdown
list selector showing the available elliptic curves (and they're even
named, rather than just given by bit count), and in ED25519 mode even
that disappears. The curve selector for ECDSA and the bits selector
for RSA/DSA are independent controls, so each one remembers its last
known value even while temporarily hidden in favour of the other.

The actual generation function still expects a bit count rather than
an actual curve or algorithm ID, so the easiest way to actually
arrange to populate the drop-down list was to have an array of bit
counts exposed by sshecc.c. That's a bit ugly, but there we go.

One small functional change: if you enter an absurdly low value into
the RSA/DSA bit count box (under 256), PuTTYgen used to give a warning
and reset it to 256. Now it resets it to the default key length of
2048, basically because I was touching that code anyway to change a
variable name and just couldn't bring myself to leave it in a state
where it intentionally chose such an utterly useless key size. Of
course this doesn't prevent generation of 256-bit keys if someone
still really wants one - it just means they don't get one selected as
the result of a typo.
2016-03-25 08:22:13 +00: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
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
42cf086b6b Add a key-length field to 'struct ssh_mac'.
The key derivation code has been assuming (though non-critically, as
it happens) that the size of the MAC output is the same as the size of
the MAC key. That isn't even a good assumption for the HMAC family,
due to HMAC-SHA1-96 and also the bug-compatible versions of HMAC-SHA1
that only use 16 bytes of key material; so now we have an explicit
key-length field separate from the MAC-length field.
2015-08-21 23:41:05 +01:00
Simon Tatham
1df12e3915 Add copy and free methods to 'struct ssh_hash'.
This permits a hash state to be cloned in the middle of being used, so
that multiple strings with the same prefix can be hashed without
having to repeat all the computation over the prefix.

Having done that, we'll also sometimes need to free a hash state that
we aren't generating actual hash output from, so we need a free method
as well.
2015-08-21 23:40:36 +01:00
Chris Staite
b0823fc5be Add the ChaCha20-Poly1305 cipher+MAC, as implemented by OpenSSH. 2015-06-07 13:50:05 +01:00
Chris Staite
5d9a9a7bdf Allow a cipher to specify encryption of the packet length.
No cipher uses this facility yet, but one shortly will.
2015-06-07 13:42:31 +01:00
Chris Staite
705f159255 Allow a cipher to override the SSH KEX's choice of MAC.
No cipher uses this facility yet, but one shortly will.
2015-06-07 13:42:19 +01:00
Simon Tatham
a209b9044e Log which elliptic curve we're using for ECDH kex.
It seems like quite an important thing to mention in the event log!
Suppose there's a bug affecting only one curve, for example? Fixed-
group Diffie-Hellman has always logged the group, but the ECDH log
message just told you the hash and not also the curve.

To implement this, I've added a 'textname' field to all elliptic
curves, whether they're used for kex or signing or both, suitable for
use in this log message and any others we might find a need for in
future.
2015-05-19 10:01:42 +01:00
Simon Tatham
c8f83979a3 Log identifying information for the other end of connections.
When anyone connects to a PuTTY tool's listening socket - whether it's
a user of a local->remote port forwarding, a connection-sharing
downstream or a client of Pageant - we'd like to log as much
information as we can find out about where the connection came from.

To that end, I've implemented a function sk_peer_info() in the socket
abstraction, which returns a freeform text string as best it can (or
NULL, if it can't get anything at all) describing the thing at the
other end of the connection. For TCP connections, this is done using
getpeername() to get an IP address and port in the obvious way; for
Unix-domain sockets, we attempt SO_PEERCRED (conditionalised on some
moderately hairy autoconfery) to get the pid and owner of the peer. I
haven't implemented anything for Windows named pipes, but I will if I
hear of anything useful.
2015-05-18 14:03:10 +01:00
Simon Tatham
89da2ddf56 Giant const-correctness patch of doom!
Having found a lot of unfixed constness issues in recent development,
I thought perhaps it was time to get proactive, so I compiled the
whole codebase with -Wwrite-strings. That turned up a huge load of
const problems, which I've fixed in this commit: the Unix build now
goes cleanly through with -Wwrite-strings, and the Windows build is as
close as I could get it (there are some lingering issues due to
occasional Windows API functions like AcquireCredentialsHandle not
having the right constness).

Notable fallout beyond the purely mechanical changing of types:
 - the stuff saved by cmdline_save_param() is now explicitly
   dupstr()ed, and freed in cmdline_run_saved.
 - I couldn't make both string arguments to cmdline_process_param()
   const, because it intentionally writes to one of them in the case
   where it's the argument to -pw (in the vain hope of being at least
   slightly friendly to 'ps'), so elsewhere I had to temporarily
   dupstr() something for the sake of passing it to that function
 - I had to invent a silly parallel version of const_cmp() so I could
   pass const string literals in to lookup functions.
 - stripslashes() in pscp.c and psftp.c has the annoying strchr nature
2015-05-15 12:47:44 +01:00
Simon Tatham
7db526c730 Clean up elliptic curve selection and naming.
The ec_name_to_curve and ec_curve_to_name functions shouldn't really
have had to exist at all: whenever any part of the PuTTY codebase
starts using sshecc.c, it's starting from an ssh_signkey or ssh_kex
pointer already found by some other means. So if we make sure not to
lose that pointer, we should never need to do any string-based lookups
to find the curve we want, and conversely, when we need to know the
name of our curve or our algorithm, we should be able to look it up as
a straightforward const char * starting from the algorithm pointer.

This commit cleans things up so that that is indeed what happens. The
ssh_signkey and ssh_kex structures defined in sshecc.c now have
'extra' fields containing pointers to all the necessary stuff;
ec_name_to_curve and ec_curve_to_name have been completely removed;
struct ec_curve has a string field giving the curve's name (but only
for those curves which _have_ a name exposed in the wire protocol,
i.e. the three NIST ones); struct ec_key keeps a pointer to the
ssh_signkey it started from, and uses that to remember the algorithm
name rather than reconstructing it from the curve. And I think I've
got rid of all the ad-hockery scattered around the code that switches
on curve->fieldBits or manually constructs curve names using stuff
like sprintf("nistp%d"); the only remaining switch on fieldBits
(necessary because that's the UI for choosing a curve in PuTTYgen) is
at least centralised into one place in sshecc.c.

One user-visible result is that the format of ed25519 host keys in the
registry has changed: there's now no curve name prefix on them,
because I think it's not really right to make up a name to use. So any
early adopters who've been using snapshot PuTTY in the last week will
be inconvenienced; sorry about that.
2015-05-15 10:15:35 +01:00
Simon Tatham
1293334ebf Provide an 'extra' pointer in ssh_signkey and ssh_kex.
This gives families of public key and kex functions (by which I mean
those sharing a set of methods) a place to store parameters that allow
the methods to vary depending on which exact algorithm is in use.

The ssh_kex structure already had a set of parameters specific to
Diffie-Hellman key exchange; I've moved those into sshdh.c and made
them part of the 'extra' structure for that family only, so that
unrelated kex methods don't have to faff about saying NULL,NULL,0,0.
(This required me to write an extra accessor function for ssh.c to ask
whether a DH method was group-exchange style or fixed-group style, but
that doesn't seem too silly.)
2015-05-15 10:12:08 +01:00
Simon Tatham
870ad6ab07 Pass the ssh_signkey structure itself to public key methods.
Not all of them, but the ones that don't get a 'void *key' parameter.
This means I can share methods between multiple ssh_signkey
structures, and still give those methods an easy way to find out which
public key method they're dealing with, by loading parameters from a
larger structure in which the ssh_signkey is the first element.

(In OO terms, I'm arranging that all static methods of my public key
classes get a pointer to the class vtable, to make up for not having a
pointer to the class instance.)

I haven't actually done anything with the new facility in this commit,
but it will shortly allow me to clean up the constant lookups by curve
name in the ECDSA code.
2015-05-15 10:12:07 +01:00
Simon Tatham
a5fc95b715 Const-correctness of name fields in struct ssh_*.
All the name strings in ssh_cipher, ssh_mac, ssh_hash, ssh_signkey
point to compile-time string literals, hence should obviously be const
char *.

Most of these const-correctness patches are just a mechanical job of
adding a 'const' in the one place you need it right now, and then
chasing the implications through the code adding further consts until
it compiles. But this one has actually shown up a bug: the 'algorithm'
output parameter in ssh2_userkey_loadpub was sometimes returning a
pointer to a string literal, and sometimes a pointer to dynamically
allocated memory, so callers were forced to either sometimes leak
memory or sometimes free a bad thing. Now it's consistently
dynamically allocated, and should be freed everywhere too.
2015-05-15 10:12:06 +01:00
Simon Tatham
79fe96155a Const-correctness in struct ssh_hash.
The 'bytes' function should take a const void * as input, not a void *.
2015-05-15 10:12:05 +01:00
Simon Tatham
8682246d33 Centralise SSH-2 key fingerprinting into sshpubk.c.
There were ad-hoc functions for fingerprinting a bare key blob in both
cmdgen.c and pageant.c, not quite doing the same thing. Also, every
SSH-2 public key algorithm in the code base included a dedicated
fingerprint() method, which is completely pointless since SSH-2 key
fingerprints are computed in an algorithm-independent way (just hash
the standard-format public key blob), so each of those methods was
just duplicating the work of the public_blob() method with a less
general output mechanism.

Now sshpubk.c centrally provides an ssh2_fingerprint_blob() function
that does all the real work, plus an ssh2_fingerprint() function that
wraps it and deals with calling public_blob() to get something to
fingerprint. And the fingerprint() method has been completely removed
from ssh_signkey and all its implementations, and good riddance.
2015-05-12 14:56:38 +01:00
Simon Tatham
eef0235a0f Centralise public-key output code into sshpubk.c.
There was a fair amount of duplication between Windows and Unix
PuTTYgen, and some confusion over writing things to FILE * and
formatting them internally into strings. I think all the public-key
output code now lives in sshpubk.c, and there's only one copy of the
code to generate each format.
2015-05-12 14:56:38 +01:00
Simon Tatham
f274b56a57 Const-correctness in the base64 functions. 2015-05-12 14:56:38 +01:00
Simon Tatham
3935cc3af1 Support loading public-key-only files in Unix PuTTYgen.
The rsakey_pubblob() and ssh2_userkey_loadpub() functions, which
expected to be given a private key file and load only the unencrypted
public half, now also cope with any of the public-only formats I know
about (SSH-1 only has one, whereas SSH-2 has the RFC 4716 format and
OpenSSH's one-line format) and return an appropriate public key blob
from each of those too.

cmdgen now supports this functionality, by permitting public key files
to be loaded and used by any operation that doesn't need the private
key: so you can convert back and forth between the SSH-2 public
formats, or list the file's fingerprint.
2015-05-12 12:19:57 +01:00
Simon Tatham
9971da40c3 Utility function: bignum_from_decimal. 2015-05-12 12:14:45 +01:00
Simon Tatham
8c4ce6d8c6 Const-correctness in key-loading functions.
The passphrase parameter should be a const char *.
2015-05-11 15:49:09 +01:00
Simon Tatham
90af5bed04 Sort out the mess with OpenSSH key file formats.
When I implemented reading and writing of the new format a couple of
weeks ago, I kept them strictly separate in the UI, so you have to ask
for the format you want when exporting. But in fact this is silly,
because not every key type can be saved in both formats, and OpenSSH
itself has the policy of using the old format for key types it can
handle, unless specifically asked to use the new one.

So I've now arranged that the key file format enum has three values
for OpenSSH: PEM, NEW and AUTO. Files being loaded are identified as
either PEM or NEW, which describe the two physical file formats. But
exporting UIs present either AUTO or NEW, where AUTO is the virtual
format meaning 'save in the old format if possible, otherwise the new
one'.
2015-05-10 13:11:43 +01:00
Chris Staite
76a4b576e5 Support public keys using the "ssh-ed25519" method.
This introduces a third system of elliptic curve representation and
arithmetic, namely Edwards form.
2015-05-09 15:14:35 +01:00
Chris Staite
541abf9258 Support ECDH key exchange using the 'curve25519' curve.
This is the kex protocol id "curve25519-sha256@libssh.org", so called
because it's over the prime field of order 2^255 - 19.

Arithmetic in this curve is done using the Montgomery representation,
rather than the Weierstrass representation. So 'struct ec_curve' has
grown a discriminant field and a union of subtypes.
2015-05-09 15:07:14 +01:00
Chris Staite
7d6bf4a6ca Provide a little-endian version of bignum_from_bytes(). 2015-05-09 15:02:50 +01:00
Simon Tatham
1f4dc6faa7 Remove the list of key algorithms in pageant.c.
The only reason those couldn't be replaced with a call to the
centralised find_pubkey_alg is because that function takes a zero-
terminated string and instead we had a (length,pointer) string. Easily
fixed; there's now a find_pubkey_alg_len(), and we call that.

This also fixes a string-matching bug in which the sense of memcmp was
reversed by mistake for ECDSA keys!
2015-05-07 19:59:07 +01:00
Simon Tatham
a53e4e2cb6 Const-correctness in x11_setup_display.
The 'display' parameter should have been a const char *. No call sites
affected.
2015-05-05 20:16:18 +01:00
Simon Tatham
bcfcb169ef Const-correctness in public-key functions.
Several of the functions in ssh2_signkey, and one or two SSH-1 key
functions too, were still taking assorted non-const buffer parameters
that had never been properly constified. Sort them all out.
2015-05-05 20:16:17 +01:00
Simon Tatham
6b30316922 Use find_pubkey_alg in openssh_read_new().
This is better than listing all the algorithm names in yet another
place that will then need updating when a new key format is added.
However, that also means I need to find a new place to put the
'npieces' value I was previously setting up differently per key type;
since that's a fundamental property of the key format, I've moved it
to a constant field in the ssh_signkey structure, and filled that
field in for all the existing key types with the values from the
replaced code in openssh_read_new().
2015-05-02 15:11:41 +01:00
Simon Tatham
79bbf37c9e Separate key-type enum values for old and new OpenSSH keys.
It's all very well for these two different formats to share a type
code as long as we're only loading them and not saving, but as soon as
we need to save one or the other, we'll need different type codes
after all.

This commit introduces the openssh_new_write() function, but for the
moment, it always returns failure.
2015-04-28 19:48:43 +01:00
Simon Tatham
d637528181 Implementation of OpenSSH's bcrypt.
This isn't the same as the standard bcrypt; it's OpenSSH's
modification that they use for their new-style key format.

In order to implement this, I've broken up blowfish_setkey() into two
subfunctions, and provided one of them with an extra optional salt
parameter, which is NULL in ordinary Blowfish but used by bcrypt.
Also, I've exposed some of sshblowf.c's internal machinery for the new
sshbcrypt.c to use.
2015-04-27 20:48:29 +01:00
Simon Tatham
a8658edb17 Paste error in comment.
SSH2_MSG_KEX_DH_GEX_REQUEST_OLD and SSH2_MSG_KEX_DH_GEX_REQUEST were
correctly _defined_ as different numbers, but the comments to the
right containing the hex representations of their values were
accidentally the same.
2015-04-27 06:54:21 +01:00
Simon Tatham
183a9ee98b Support OpenSSH encrypt-then-MAC protocol extension.
This causes the initial length field of the SSH-2 binary packet to be
unencrypted (with the knock-on effect that now the packet length not
including MAC must be congruent to 4 rather than 0 mod the cipher
block size), and then the MAC is applied over the unencrypted length
field and encrypted ciphertext (prefixed by the sequence number as
usual). At the cost of exposing some information about the packet
lengths to an attacker (but rarely anything they couldn't have
inferred from the TCP headers anyway), this closes down any
possibility of a MITM using the client as a decryption oracle, unless
they can _first_ fake a correct MAC.

ETM mode is enabled by means of selecting a different MAC identifier,
all the current ones of which are constructed by appending
"-etm@openssh.com" to the name of a MAC that already existed.

We currently prefer the original SSH-2 binary packet protocol (i.e. we
list all the ETM-mode MACs last in our KEXINIT), on the grounds that
it's better tested and more analysed, so at the moment the new mode is
only activated if a server refuses to speak anything else.
2015-04-26 23:30:32 +01:00
Simon Tatham
62a1bce7cb Support RFC 4419.
PuTTY now uses the updated version of Diffie-Hellman group exchange,
except for a few old OpenSSH versions which Darren Tucker reports only
support the old version.

FIXME: this needs further work because the Bugs config panel has now
overflowed.
2015-04-25 10:54:18 +01:00
Simon Tatham
808e414130 Merge branch 'pre-0.64' 2015-02-28 07:57:58 +00:00
Simon Tatham
174476813f Enforce acceptable range for Diffie-Hellman server value.
Florent Daigniere of Matta points out that RFC 4253 actually
_requires_ us to refuse to accept out-of-range values, though it isn't
completely clear to me why this should be a MUST on the receiving end.

Matta considers this to be a security vulnerability, on the grounds
that if a server should accidentally send an obviously useless value
such as 1 then we will fail to reject it and agree a key that an
eavesdropper could also figure out. Their id for this vulnerability is
MATTA-2015-002.
2015-02-28 07:57:35 +00:00
Simon Tatham
bb09a3936e Fix some rogue // comments.
That's what you get for changing things at the last minute...
2014-11-03 18:41:56 +00:00
Chris Staite
2bf8688355 Elliptic-curve cryptography support.
This provides support for ECDSA public keys, for both hosts and users,
and also ECDH key exchange. Supported curves are currently just the
three NIST curves required by RFC 5656.
2014-11-02 18:16:54 +00:00
Chris Staite
7d1c30cd50 Some extra bignum functions: modsub, lshift, random_in_range. 2014-11-02 18:16:54 +00:00
Chris Staite
66970c4258 Provide SHA-384 and SHA-512 as hashes usable in SSH KEX.
SHA-384 was previously not implemented at all, but is a trivial
adjustment to SHA-512 (different starting constants, and truncate the
output hash). Both are now exposed as 'ssh_hash' structures so that
key exchange methods can ask for them.
2014-11-02 18:16:54 +00:00
Simon Tatham
a2b64dca47 Factor out the DSA deterministic k generator.
It's now a separate function, which you call with an identifying
string to be hashed into the generation of x. The idea is that other
DSA-like signature algorithms can reuse the same function, with a
different id string.

As a minor refinement, we now also never return k=1.
2014-11-02 18:16:54 +00:00
Simon Tatham
bb78583ad2 Implement connection sharing between instances of PuTTY.
The basic strategy is described at the top of the new source file
sshshare.c. In very brief: an 'upstream' PuTTY opens a Unix-domain
socket or Windows named pipe, and listens for connections from other
PuTTYs wanting to run sessions on the same server. The protocol spoken
down that socket/pipe is essentially the bare ssh-connection protocol,
using a trivial binary packet protocol with no encryption, and the
upstream has to do some fiddly transformations that I've been
referring to as 'channel-number NAT' to avoid resource clashes between
the sessions it's managing.

This is quite different from OpenSSH's approach of using the Unix-
domain socket as a means of passing file descriptors around; the main
reason for that is that fd-passing is Unix-specific but this system
has to work on Windows too. However, there are additional advantages,
such as making it easy for each downstream PuTTY to run its own
independent set of port and X11 forwardings (though the method for
making the latter work is quite painful).

Sharing is off by default, but configuration is intended to be very
easy in the normal case - just tick one box in the SSH config panel
and everything else happens automatically.

[originally from svn r10083]
2013-11-17 14:05:41 +00:00
Simon Tatham
e5a3e28eec Get rid of the error-return mechanism from x11_init.
Now that it doesn't actually make a network connection because that's
deferred until after the X authorisation exchange, there's no point in
having it return an error message and write the real output through a
pointer argument. Instead, we can just have it return xconn directly
and simplify the call sites.

[originally from svn r10081]
2013-11-17 14:05:23 +00:00
Simon Tatham
94e8f97d3f Refactor the construction of X protocol greetings.
I've moved it out into a separate function, preparatory to calling it
from somewhere completely different in changes to come. Also, we now
retain the peer address sent from the SSH server in string form,
rather than translating it immediately into a numeric IP address, so
that its original form will be available later to pass on elsewhere.

[originally from svn r10080]
2013-11-17 14:05:17 +00:00
Simon Tatham
cc4fbe33bc Prepare to have multiple X11 auth cookies valid at once.
Rather than the top-level component of X forwarding being an
X11Display structure which owns some auth data, it's now a collection
of X11FakeAuth structures, each of which owns a display. The idea is
that when we receive an X connection, we wait to see which of our
available auth cookies it matches, and then connect to whatever X
display that auth cookie identifies. At present the tree will only
have one thing in it; this is all groundwork for later changes.

[originally from svn r10079]
2013-11-17 14:05:10 +00:00
Simon Tatham
01085358e4 Decouple X socket opening from x11_init().
Now we wait to open the socket to the X server until we've seen the
authorisation data. This prepares us to do something else with the
channel if we see different auth data, which will come up in
connection sharing.

[originally from svn r10078]
2013-11-17 14:05:04 +00:00
Simon Tatham
961503e449 Add missing 'const' in the des_*_xdmauth functions.
[originally from svn r10077]
2013-11-17 14:05:01 +00:00
Simon Tatham
9cbcd17651 Refactor ssh.c's APIs to x11fwd.c and portfwd.c.
The most important change is that, where previously ssh.c held the
Socket pointer for each X11 and port forwarding, and the support
modules would find their internal state structure by calling
sk_get_private_ptr on that Socket, it's now the other way round. ssh.c
now directly holds the internal state structure pointer for each
forwarding, and when the support module needs the Socket it looks it
up in a field of that. This will come in handy when I decouple socket
creation from logical forwarding setup, so that X forwardings can
delay actually opening a connection to an X server until they look at
the authentication data and see which server it has to be.

However, while I'm here, I've also taken the opportunity to clean up a
few other points, notably error message handling, and also the fact
that the same kind of state structure was used for both
connection-type and listening-type port forwardings. Now there are
separate PortForwarding and PortListener structure types, which seems
far more sensible.

[originally from svn r10074]
2013-11-17 14:04:41 +00:00
Simon Tatham
0bc76b8252 Move SSH protocol enumerations out into ssh.h.
This permits packet type codes and other magic numbers to be accessed
from modules other than ssh.c.

[originally from svn r10064]
2013-11-17 14:03:29 +00:00
Simon Tatham
8e7b0d0e4b Pass an error message through to sshfwd_unclean_close.
We have access to one at every call site, so there's really no reason
not to send it through to ssh.c to be logged.

[originally from svn r10038]
2013-09-08 07:14:56 +00:00
Simon Tatham
808df44e54 Add an assortment of missing consts I've just noticed.
[originally from svn r9972]
2013-07-27 18:35:48 +00:00
Ben Harris
8f3cc4a9bf Add support for HMAC-SHA-256 as an SSH-2 MAC algorithm ("hmac-sha2-256")
as specified in RFC 6668.  This is not so much because I think it's 
necessary, but because scrypt uses HMAC-SHA-256 and once we've got it we 
may as well use it.

Code very closely derived from the HMAC-SHA-1 code.

Tested against OpenSSH 5.9p1 Debian-5ubuntu1.

[originally from svn r9759]
2013-02-20 23:30:55 +00:00
Simon Tatham
9604c2b367 Generate keys more carefully, so that when the user asks for an n-bit
key they always get an n-bit number instead of n-1. The latter was
perfectly harmless but kept confusing users.

[originally from svn r9421]
2012-03-04 00:24:49 +00:00
Simon Tatham
49927f6c4d Introduce a function sshfwd_unclean_close(), supplied by ssh.c to
subsidiary network modules like portfwd.c. To be called when the
subsidiary module experiences a socket error: it sends an emergency
CHANNEL_CLOSE (not just outgoing CHANNEL_EOF), and immediately deletes
the local side of the channel. (I've invented a new channel type in
ssh.c called CHAN_ZOMBIE, for channels whose original local side has
already been thrown away and they're just hanging around waiting to
receive the acknowledging CHANNEL_CLOSE.)

As a result of this and the last few commits, I can now run a port
forwarding session in which a local socket error occurs on a forwarded
port, and PuTTY now handles it apparently correctly, closing both the
SSH channel and the local socket and then actually recognising that
it's OK to terminate when all _other_ channels have been closed.
Previously the channel corresponding to the duff connection would
linger around (because of net_pending_errors never being called), and
keep being selected on (hence chewing CPU), and inhibit program
termination at the end of the session (because not all channels were
closed).

[originally from svn r9364]
2011-12-08 19:15:58 +00:00
Simon Tatham
947962e0b9 Revamp of EOF handling in all network connections, pipes and other
data channels. Should comprehensively fix 'half-closed', in principle,
though it's a big and complicated change and so there's a good chance
I've made at least one mistake somewhere.

All connections should now be rigorous about propagating end-of-file
(or end-of-data-stream, or socket shutdown, or whatever) independently
in both directions, except in frontends with no mechanism for sending
explicit EOF (e.g. interactive terminal windows) or backends which are
basically always used for interactive sessions so it's unlikely that
an application would be depending on independent EOF (telnet, rlogin).

EOF should now never accidentally be sent while there's still buffered
data to go out before it. (May help fix 'portfwd-corrupt', and also I
noticed recently that the ssh main session channel can accidentally
have MSG_EOF sent before the output bufchain is clear, leading to
embarrassment when it subsequently does send the output).

[originally from svn r9279]
2011-09-13 11:44:03 +00:00
Simon Tatham
a1f3b7a358 Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.

User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).

One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.

[originally from svn r9214]
2011-07-14 18:52:21 +00:00
Jacob Nevins
74c5f7dda9 Implement zlib@openssh.com, using the rekey-after-userauth method suggested in
the wishlist entry.

[originally from svn r9120]
[this svn revision also touched putty-website,putty-wishlist]
2011-03-04 22:34:47 +00:00
Simon Tatham
fa85085640 Implement the Chinese Remainder Theorem optimisation for speeding up
RSA private key operations by making use of the fact that we know the
factors of the modulus.

[originally from svn r9095]
2011-02-18 08:25:39 +00:00
Simon Tatham
99fffd6ed3 Patch from Alejandro Sedeno, somewhat modified by me, which
reorganises the GSSAPI support so that it handles alternative
implementations of the GSS-API. In particular, this means PuTTY can
now talk to MIT Kerberos for Windows instead of being limited to
SSPI. I don't know for sure whether further tweaking will be needed
(to the UI, most likely, or to automatic selection of credentials),
but testing reports suggest it's now at least worth committing to
trunk to get it more widely tested.

[originally from svn r8952]
2010-05-19 18:22:17 +00:00
Simon Tatham
108791e15c Support importing of new-style OpenSSH private keys (encrypted by
AES rather than 3DES).

[originally from svn r8916]
2010-04-12 10:55:31 +00:00
Ben Harris
86c183f8e8 Mitigation for VU#958563: When using a CBC-mode server-to-client cipher
under SSH-2, don't risk looking at the length field of an incoming packet
until we've successfully MAC'ed the packet.

This requires a change to the MAC mechanics so that we can calculate MACs
incrementally, and output a MAC for the packet so far while still being
able to add more data to the packet later.

[originally from svn r8334]
2008-11-26 12:49:25 +00:00
Simon Tatham
ca6fc3a4da Revamp of the local X11 connection code. We now parse X display
strings more rigorously, and then we look up the local X authority
data in .Xauthority _ourself_ rather than delegating to an external
xauth program. This is (negligibly) more efficient on Unix, assuming
I haven't got it wrong in some subtle way, but its major benefit is
that we can now support X authority lookups on Windows as well
provided the user points us at an appropriate X authority file in
the standard format. A new Windows-specific config option has been
added for this purpose.

[originally from svn r8305]
2008-11-17 18:38:09 +00:00
Simon Tatham
14d825d42f OS X Leopard, it turns out, has a new and exciting strategy for
addressing X displays. Update PuTTY's display-name-to-Unix-socket-
path translation code to cope with it, thus causing X forwarding to
start working again on Leopard.

[originally from svn r8020]
2008-05-28 19:23:57 +00:00
Ben Harris
dad558a1e5 Add support for RFC 4432 RSA key exchange, the patch for which has been
lying around in my home directory for _years_.

[originally from svn r7496]
2007-04-30 22:09:26 +00:00
Jacob Nevins
cd94e3bc3c Patch from Colin Watson intended to give a clean Unix compile with GCC 4.
(Since we choose to compile with -Werror, this is particularly important.)

I haven't yet checked that the resulting source actually compiles cleanly with
GCC 4, hence not marking `gcc4-warnings' as fixed just yet.

[originally from svn r7041]
2006-12-30 23:00:14 +00:00
Jacob Nevins
078c516a45 Dimitry Andric spotted that DH gex with SHA-256 was overflowing a buffer.
Fixed, and added paranoia so that this shouldn't happen again.

[originally from svn r6606]
[this svn revision also touched putty-wishlist]
2006-03-12 19:24:05 +00:00