The previous assertion failure is obviously wrong, but RFC 4253 doesn't
explicitly declare them to be a protocol error. Currently, the incoming
packet isn't logged, which might cause some confusion for log parsers.
Bug found with the help of afl-fuzz.
This protects the Unix platform sharing code in the case where no salt
file exists yet in the connection-sharing directory, in which case
make_dirname() will want to create one by using some random bytes, and
prior to this commit, would fail an assertion because the random
number generator wasn't set up.
It would be neater to just return FALSE from ssh_test_for_upstream in
that situation - if there's no salt file, then no sharing socket can
be valid anyway - but that would involve doing more violence to the
code structure than I'm currently prepared to do for a minor elegance
gain.
A user reports that in a particular situation one of the calls to
LoadLibrary from wingss.c has unwanted side effects, and points out
that this happens even when the saved session has GSSAPI disabled. So
I've evaluated as much as possible of the condition under which we
check the results of GSS library loading, and deferred the library
loading itself until after that condition says we even care about the
results.
(cherry picked from commit 9a08d9a7c1)
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.
This is the part of ssh.c's connect_to_host() which figures out the
host name and port number that logically identify the connection -
i.e. not necessarily where we physically connected to, but what we'll
use to look up the saved session cache, put in the window title bar,
and give to the connection sharing code to identify other connections
to share with.
I'm about to want to use it for another purpose, so it needs to be
moved out into a separate function.
If we've chosen the ChaCha20-Poly1305 option for a cipher, then that
forces the use of its associated MAC. In that situation, we should
avoid even _trying_ to figure out a MAC by examining the MAC string
from the server's KEXINIT, because we won't use the MAC selected by
that method anyway, so there's no point imposing the requirement on
servers to present a MAC we believe in just so we know it's there.
This was breaking interoperation with tinysshd, and is in violation of
OpenSSH's spec for the "chacha20-poly1305@openssh.com" cipher.
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.
Tim Kosse points out that we now support some combinations of crypto
primitives which break the hardwired assumption that two blocks of
hash output from the session-key derivation algorithm are sufficient
to key every cipher and MAC in the system.
So now ssh2_mkkey is given the desired key length, and performs as
many iterations as necessary.
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.
A user reports that in a particular situation one of the calls to
LoadLibrary from wingss.c has unwanted side effects, and points out
that this happens even when the saved session has GSSAPI disabled. So
I've evaluated as much as possible of the condition under which we
check the results of GSS library loading, and deferred the library
loading itself until after that condition says we even care about the
results.
If a sharing downstream disconnected while we were still in userauth
(probably by deliberate user action, since such a downstream would
have just been sitting there waiting for upstream to be ready for it)
then we could crash by attempting to count234(ssh->channels) before
the ssh->channels tree had been set up in the first place.
A simple null-pointer check fixes it. Thanks to Antti Seppanen for the
report.
I removed a vital line of code while fixing the merge conflicts when
cherry-picking 1eb578a488 as
26fe1e26c0, causing Diffie-Hellman key
exchange to be completely broken because the server's host key was
never constructed to verify the signature with. Reinstate it.
Assorted calls to ssh_pkt_getstring in handling the later parts of key
exchange (post-KEXINIT) were not checked for NULL afterwards, so that
a variety of badly formatted key exchange packets would cause a crash
rather than a sensible error message.
None of these is an exploitable vulnerability - the server can only
force a clean null-deref crash, not an access to actually interesting
memory.
Thanks to '3unnym00n' for pointing out one of these, causing me to
find all the rest of them too.
(cherry picked from commit 1eb578a488)
Conflicts:
ssh.c
Cherry-picker's notes: the main conflict arose because the original
commit also made fixes to the ECDH branch of the big key exchange if
statement, which doesn't exist on this branch. Also there was a minor
and purely textual conflict, when an error check was added right next
to a function call that had acquired an extra parameter on master.
The final main loop in do_ssh2_authconn will sometimes loop over all
currently open channels calling ssh2_try_send_and_unthrottle. If the
channel is a sharing one, however, that will reference fields of the
channel structure like 'remwindow', which were never initialised in
the first place (thanks, valgrind). Fix by excluding CHAN_SHARING
channels from that loop.
(cherry picked from commit 7366fde1d4)
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.
(cherry picked from commit c8f83979a3)
Conflicts:
pageant.c
Cherry-picker's notes: the conflict was because the original commit
also added a use of the same feature in the centralised Pageant code,
which doesn't exist on this branch. Also I had to remove 'const' from
the type of the second parameter to wrap_send_port_open(), since this
branch hasn't had the same extensive const-fixing as master.
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.
(cherry picked from commit 62a1bce7cb)
Assorted calls to ssh_pkt_getstring in handling the later parts of key
exchange (post-KEXINIT) were not checked for NULL afterwards, so that
a variety of badly formatted key exchange packets would cause a crash
rather than a sensible error message.
None of these is an exploitable vulnerability - the server can only
force a clean null-deref crash, not an access to actually interesting
memory.
Thanks to '3unnym00n' for pointing out one of these, causing me to
find all the rest of them too.
The final main loop in do_ssh2_authconn will sometimes loop over all
currently open channels calling ssh2_try_send_and_unthrottle. If the
channel is a sharing one, however, that will reference fields of the
channel structure like 'remwindow', which were never initialised in
the first place (thanks, valgrind). Fix by excluding CHAN_SHARING
channels from that loop.
I'd rather see the cipher and MAC named separately, with a hint that
the two are linked together in some way, than see the cipher called by
a name including the MAC and the MAC init message have an ugly
'<implicit>' in it.
This allows for sharing a bit of code, and it also means that
deduplication of KEXINIT algorithms can be done while working out the
list of algorithms rather than when constructing the KEXINIT packet
itself.
The general plan is that if PuTTY knows a host key for a server, it
should preferentially ask for the same type of key so that there's some
chance of actually getting the same key again. This should mean that
when a server (or PuTTY) adds a new host key type, PuTTY doesn't
gratuitously switch to that key type and then warn the user about an
unrecognised key.
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.
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.
The new code remembers the contents and meaning of the outgoing KEXINIT
and uses this to drive the algorithm negotiation, rather than trying to
reconstruct what the outgoing KEXINIT probably said. This removes the
need to maintain the KEXINIT generation and parsing code precisely in
parallel.
It also fixes a bug whereby PuTTY would have selected the wrong host key
type in cases where the server gained a host key type between rekeys.
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
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.
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.)
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.
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.
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.
Obviously PuTTY can't actually do public-key authentication itself, if
you give it a public rather than private key file. But it can still
match the supplied public key file against the list of keys in the
agent, and narrow down to that. So if for some reason you're
forwarding an agent to a machine you don't want to trust with your
_private_ key file (even encrypted), you can still use the '-i' option
to select which key from the agent to use, by uploading just the
public key file to that machine.
It's just ssh_pkt_addstring_data but using strlen to get the length of
string to add, so make that explicit by having it call
ssh_pkt_addstring_data. Good compilers should be unaffected by this
change.
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.
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 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.
I'm not actually sure why we've always had back ends notify ldisc of
changes to echo/edit settings by giving ldisc_send(ldisc,NULL,0,0) a
special meaning, instead of by having a separate dedicated notify
function with its own prototype and parameter set. Coverity's recent
observation that the two kinds of call don't even have the same
requirements on the ldisc (particularly, whether ldisc->term can be
NULL) makes me realise that it's really high time I separated the two
conceptually different operations into actually different functions.
While I'm here, I've renamed the confusing ldisc_update() function
which that special operation ends up feeding to, because it's not
actually a function applying to an ldisc - it applies to a front end.
So ldisc_send(ldisc,NULL,0,0) is now ldisc_echoedit_update(ldisc), and
that in turn figures out the current echo/edit settings before passing
them on to frontend_echoedit_update(). I think that should be clearer.
This ought to happen in ssh_do_close alongside the code that shuts
down other local listening things like port forwardings, for the same
obvious reason. In particular, we should get through this _before_ we
put up a modal dialog box telling the user what just went wrong with
the SSH connection, so that further sessions started while that box is
active don't try futilely to connect to the not-really-listening
zombie upstream.
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.
I had initially assumed that, since all of a user's per-connection
subdirectories live inside a top-level putty-connshare.$USER directory
that's not accessible to anyone else, there would be no need to
obfuscate the names of the internal directories for privacy, because
nobody would be able to look at them anyway.
Unfortunately, that's not true: 'netstat -ax' run by any user will
show up the full pathnames of Unix-domain sockets, including pathname
components that you wouldn't have had the access to go and look at
directly. So the Unix connection sharing socket names do need to be
obfuscated after all.
Since Unix doesn't have Windows's CryptProtectMemory, we have to do
this manually, by creating a file of random salt data inside the
top-level putty-connshare directory (if there isn't one there already)
and then hashing that salt with the "user@host" connection identifier
to get the socket directory name. What a pain.
[originally from svn r10222]
This option is available from the command line as '-hostkey', and is
also configurable through the GUI. When enabled, it completely
replaces all of the automated host key management: the server's host
key will be checked against the manually configured list, and the
connection will be allowed or disconnected on that basis, and the host
key store in the registry will not be either consulted or updated.
The main aim is to provide a means of automatically running Plink,
PSCP or PSFTP deep inside Windows services where HKEY_CURRENT_USER
isn't available to have stored the right host key in. But it also
permits you to specify a list of multiple host keys, which means a
second use case for the same mechanism will probably be round-robin
DNS names that select one of several servers with different host keys.
Host keys can be specified as the standard MD5 fingerprint or as an
SSH-2 base64 blob, and are canonicalised on input. (The base64 blob is
more unwieldy, especially with Windows command-line length limits, but
provides a means of specifying the _whole_ public key in case you
don't trust MD5. I haven't bothered to provide an analogous mechanism
for SSH-1, on the basis that anyone worrying about MD5 should have
stopped using SSH-1 already!)
[originally from svn r10220]
This is the same code I previously fixed for failing to check NULL
pointers coming back from ssh_pkt_getstring if the server's KEXINIT
ended early, leading to an embarrassing segfault in place of a fatal
error message. But I've now also had it pointed out to me that the
fatal error message passes the string as %s, which is inappropriate
because (being read straight out of the middle of an SSH packet) it
isn't necessarily zero-terminated!
This is still just an embarrassing segfault in place of a fatal error
message, and not exploitable as far as I can see, because the string
is passed to a dupprintf, which will either read off the end of
allocated address space and segfault non-exploitably, or else it will
find a NUL after all and carefully allocate enough space to format an
error message containing all of the previous junk. But still, how
embarrassing to have messed up the same code _twice_.
[originally from svn r10211]
We now expect that after the server has sent us CHANNEL_CLOSE, we
should not expect to see any replies to our outstanding channel
requests, and conversely after we have sent CHANNEL_CLOSE we avoid
sending any reply to channel requests from the server. This was the
consensus among implementors discussing the problem on ietf-ssh in
April 2014.
To cope with current OpenSSH's (and perhaps other servers we don't
know about yet) willingness to send request replies after
CHANNEL_CLOSE, I introduce a bug-compatibility flag which is detected
for every OpenSSH version up to and including the current 6.6 - but
not beyond, since https://bugzilla.mindrot.org/show_bug.cgi?id=1818
promises that 6.7 will also implement the new consensus behaviour.
[originally from svn r10200]
Martin Prikryl reports that it had the exact same bug as old OpenSSH
(insisting that RSA signature integers be padded with leading zero
bytes to the same length as the RSA modulus, where in fact RFC 4253
section 6.6 says it ought to have _no_ padding), but is recently
fixed. The first version string to not have the bug is reported to be
"mod_sftp/0.9.9", so here we recognise everything less than that as
requiring our existing workaround.
[originally from svn r10161]
If we search for a colon by computing ptr + host_strcspn(ptr,":"),
then the resulting pointer is always non-NULL, and the 'not found'
condition is not !p but !*p.
This typo could have caused PuTTY to overrun a string, but not in a
security-bug sense because any such string would have to have been
loaded from the configuration rather than received from a hostile
source.
[originally from svn r10123]
Both GUI PuTTY front ends have a piece of logic whereby a string is
interpreted as host:port if there's _one_ colon in it, but if there's
more than one colon then it's assumed to be an IPv6 literal with no
trailing port number. This permits the PuTTY command line to take
strings such as 'host', 'host:22' or '[::1]:22', but also cope with a
bare v6 literal such as '::1'.
This logic is also required in the two Plink front ends and in the
processing of CONF_loghost for host key indexing in ssh.c, but was
missing in all those places. Add it.
[originally from svn r10121]
I've gone through everywhere we handle host names / addresses (on
command lines, in PuTTY config, in port forwarding, in X display
names, in host key storage...) and tried to make them handle IPv6
literals sensibly, by using the host_str* functions I introduced in my
previous commit. Generally it's now OK to use a bracketed IPv6 literal
anywhere a hostname might have been valid; in a few cases where no
ambiguity exists (e.g. no :port suffix is permitted anyway)
unbracketed IPv6 literals are also acceptable.
[originally from svn r10120]
The line that resets st->pktin->length to cover only the semantic
payload of the SSH message was overwriting the modification to
st->pktin->length performed by the optional decompression step. I
didn't notice because I don't habitually enable compression.
[originally from svn r10103]
[r10070 == 9f5d51a4ac]
I've enabled gcc's format-string checking on dupprintf, by declaring
it in misc.h to have the appropriate GNU-specific attribute. This
pointed out a selection of warnings, which I've fixed.
[originally from svn r10084]
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]
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]
I don't know that this can ever be triggered in the current state of
the code, but when I start mucking around with SSH session closing in
the near future, it may be handy to have it.
[originally from svn r10076]
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]
Because the upcoming connection sharing changes are going to involve
us emitting outgoing SSH packets into our log file that we didn't
construct ourselves, we can no longer rely on metadata inserted at
packet construction time to tell us which parts of which packets have
to be blanked or omitted in the SSH packet log. Instead, we now have
functions that deal with constructing the blanks array just before
passing all kinds of packet (both SSH-1 and SSH-2, incoming and
outgoing) to logging.c; the blanks/nblanks fields in struct Packet are
therefore no longer needed.
[originally from svn r10071]
There's always been some confusion over exactly what it all means. I
haven't cleaned it up to the point of complete sensibleness, but I've
got it to a point where I can at least understand and document the
remaining non-sensibleness.
[originally from svn r10070]
It's now indexed by source hostname as well as source port (so that
separate requests for the server to listen on addr1:1234 and
addr2:1234 can be disambiguated), and also its destination host name
is dynamically allocated rather than a fixed-size buffer.
[originally from svn r10062]
Anthony Ho reports that this can occur naturally in some situation
involving Windows 8 + IE 11 and dynamic port forwarding: apparently we
get through the SOCKS negotiation, send our CHANNEL_OPEN, and then
*immediately* suffer a local WSAECONNABORTED error before the server
has sent back its OPEN_CONFIRMATION or OPEN_FAILURE. In this situation
ssh2_channel_check_close was failing to notice that the channel didn't
yet have a valid server id, and sending out a CHANNEL_CLOSE anyway
containing 32 bits of uninitialised nonsense.
We now handle this by turning our half-open CHAN_SOCKDATA_DORMANT into
a half-open CHAN_ZOMBIE, which means in turn that our handler
functions for OPEN_CONFIRMATION and OPEN_FAILURE have to recognise and
handle that case, the former by immediately initiating channel closure
once we _do_ have the channel's server id to do it with.
[originally from svn r10039]
CHAN_AGENT channels need c->u.a.message to be either NULL or valid
dynamically allocated memory, because it'll be freed by
ssh_channel_destroy. This bug triggers if an agent forwarding channel
is opened and closed without having sent any queries.
[originally from svn r10032]
We now only present the full set of host key algorithms we can handle
in the first key exchange. In subsequent rekeys, we present only the
host key algorithm that we agreed on the previous time, and then we
verify the host key by simply enforcing that it's exactly the same as
the one we saw at first and disconnecting rudely if it isn't.
[originally from svn r10027]
sitting on a pile of buffered data waiting for WINDOW_ADJUSTs, we
should throw away that buffered data, because the CHANNEL_CLOSE tells
us that we won't be receiving those WINDOW_ADJUSTs, and if we hang on
to the data and keep trying then it'll prevent ssh_channel_try_eof
from sending the CHANNEL_EOF which is a prerequisite of sending our
own CHANNEL_CLOSE.
[originally from svn r9953]
crWaitUntilV(pktin) with plain crReturnV, because those coroutines can
be called back either with a response packet from the channel request
_or_ with NULL by ssh_free meaning 'please just clean yourself up'.
[originally from svn r9927]
warnings about insecure crypto components. The latter may crReturn
(though not in any current implementation, I believe), which
invalidates pktin, which is used by the former.
[originally from svn r9921]
of the GET_32BIT macros and then used as length fields. Missing bounds
checks against zero have been added, and also I've introduced a helper
function toint() which casts from unsigned to int in such a way as to
avoid C undefined behaviour, since I'm not sure I trust compilers any
more to do the obviously sensible thing.
[originally from svn r9918]
since there is a theoretical code path (via the crReturn loop after
asking an interactive question about a host key or crypto algorithm)
on which we can leave and return to do_ssh1_login between allocating
and freeing those keys.
(In practice it shouldn't come up anyway with any of the current
implementations of the interactive question functions, not to mention
the unlikelihood of anyone non-specialist still using SSH-1, but
better safe than sorry.)
[originally from svn r9895]
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]
RFC 4245 section 7.1 specifies the meaning of the "address to bind"
parameter in a "tcpip-forward" request. "0.0.0.0" and "127.0.0.1" are
specified to be all interfaces and the loopback interface respectively
in IPv4, while "" and "localhost" are the address-family-agnostic
equivalents. Switch PuTTY to using the latter, since it doesn't seem
right to force IPv4.
There's an argument that PuTTY should provide a means of configuring the
address family used for remote forwardings like it does for local ones.
[originally from svn r9668]
First, make absolute times unsigned. This means that it's safe to
depend on their overflow behaviour (which is undefined for signed
integers). This requires a little extra care in handling comparisons,
but I think I've correctly adjusted them all.
Second, functions registered with schedule_timer() are guaranteed to be
called with precisely the time that was returned by schedule_timer().
Thus, it's only necessary to check these values for equality rather than
doing risky range checks, so do that.
The timing code still does lots that's undefined, unnecessary, or just
wrong, but this is a good start.
[originally from svn r9667]
confused if they receive a request followed by immediate EOF, since we
currently send outgoing EOF as soon as we see the incoming one - and
then, when the response comes back from the real SSH agent, we send it
along anyway as channel data in spite of having sent EOF.
To fix this, I introduce a new field for each agent channel which
counts the number of calls to ssh_agentf_callback that are currently
expected, and we don't send EOF on an agent channel until we've both
received EOF and that value drops to zero.
[originally from svn r9651]