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'.
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.
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!
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.
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().
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.
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.
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.
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.
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.
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.
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.
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.
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.
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]
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]
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]
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]
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]
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]
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]
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]
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]
'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]
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]
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]
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]
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]
(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]