I noticed today that Unix Plink responds to SIGWINCH by accidentally
dying of EINTR having interrupted its main select loop, and when I
checked, there turn out to be a couple of other select loops with the
same bug.
This is a purely stylistic cleanup - no functional change intended -
after Tim Kosse's changes in commits e9a76883a and 6f871e3d2.
I think the underlying cause of the confusion whose functional effects
he was fixing there is that I have the bad habit of tending to call
variables 'ret' for two different reasons: one is because it's holding
the value returned from some subroutine I've just called, and the
other is because it's holding the value I'm preparing to return from
the routine _containing_ the variable.
The reason it's a bad habit is that I confuse the two purposes, and a
variable of one type ends up accidentally being treated as the other.
So while Tim's commits have already fixed the functional effects of
the error in this case, this change should help prevent a recurrence
because now there's no variable called 'ret' at all that's in scope
for the whole function.
random_add_noise calls SHATransform for every 64 octets of incoming noise,
yet instead of xor'ing the hashed noise into the pool it instead only xor'ed
20 octets of the raw noise in each iteration. This effectively reduced the
amount of new entropy entering the pool.
It is possible for SSH_FXP_CLOSE requests to fail. This can happen if the
server buffers writes and an error occurs flushing the data to disk while
processing the SSH_FXP_CLOSE request. If the close fails, sftp_put_file now
returns an error as well.
Due to a shadowed variable, transfer failures were not reflected in the return
code to sftp_put_file. Instead of tracking the return code, use the 'err'
variable to decide which return code to use.
Due to the return variable 'ret' being shadowed in the transfer loop, errors
in the transfer loop did not affect the final return value of sftp_get_file.
This particularly affects psftp's batch mode (without passing the -be
command-line argument), which would errorneously continue. The solution is
to simply remove the shadowing declaration.
A user points out that buf[] in sk_tcp_peer_info is only used in the
IPv6 branch of an ifdef, and is declared with a size of
INET6_ADDRSTRLEN, which won't be defined in NO_IPV6 mode. So moving
the definition inside another IPv6-only ifdef fixes the resulting
build failure.
The id member of the sftp_request structure is of type unsigned int.
This type is also used in the sftp_reqfind callback. In
sftp_find_request we thus need to pass a pointer to unsigned int to
find234. Before this commit, sftp_find_request was passing a pointer
to unsigned long to find234, which causes the lookup to fail on
big-endian platforms where sizeof(unsigned int) != sizeof(unsigned
long), e.g. ppc64.
The new font name configured by the keystrokes was missing its
"client:" or "server:" prefix, which could have led to the selection
of the wrong font in rare situations.
Each gtkfont back end now provides a routine that will return the name
of a similar font to the current one but one notch larger or smaller.
For Pango, this is just a matter of incrementing the font size field
in a standard way; for X11 server-side fonts, we have to go and do an
XListFonts query with a wildcard that requests fonts that vary only in
the size fields from the current one, and then iterate over the result
looking for the best one.
(I expect this will be more useful to Pango scalable-font users than
to X11 fonts, but it seemed a shame not to give the X11 side my best
shot while I was at it.)
Choice of hotkey: I know I'm being inconsistent with gnome-terminal's
use of Ctrl-plus and Ctrl-minus. I thought that was because I was
already using Ctrl-minus as a more convenient synonym for
Ctrl-underscore (which sends the actual control code 0x1F), but now I
actually try it, apparently I'm not. However, Ctrl-plus and Ctrl-minus
are quite horrible as a keystroke pair anyway (one has to be typed
with shift and one without!), and I feel as if the 'less' and
'greater' signs are more specific anyway, in that they specifically
indicate _size_ rather than just 'unspecified numerical value'.
There were already two places in the code (x11font_enum_fonts and
x11_guess_derived_font_name) where we retrieved an XLFD from the X
server, sawed it up ad-hoc into its '-'-separated parts and accessed
them by numeric index.
I'm about to add a third, so before I do, let's turn this into a
somewhat principled system where we get to do the decode/encode in
just one place and call all the individual fields by names that are
actually memorable.
No functional change intended by this commit.
The algorithm Windows uses to generate AppUserModelIDs "hangs on" to
removable media (CDs/DVDs) if PuTTY is launched with a CD/DVD in a drive.
Set the AppUserModelID explicitly to avoid using this algorithm.
The XDG configuration location ($XDG_CONFIG_HOME/putty, or
~/.config/putty) is now prefered over the old ~/.putty location, if the
XDG location already exists. If it doesn't exist, we try to use one of
the old locations ($HOME/.putty, [/etc/passwd home]/.putty, /.putty). If
none of the directories exist, we fall back to ~/.config/putty or
~/.putty, if the XDG_DEFAULT macro is defined or not, respectively. The
PUTTYDIR environment variable remains a definitive override of the
configuration location. This all ensures that the old location is still
used, unless the user explicitly requests otherwise.
The configuration directories are created using the make_dir_path()
function, to ensure that saving the configuration doesn't fail e.g.
because of a non-existent ~/.config directory.
Essentially 'mkdir -p' - we try to make each prefix of the pathname,
terminating on any error other than EEXIST. Semantics are similar to
make_dir_and_check_ours(): we return NULL on success or a dynamically
allocated error message string on failure.
At least on systems providing SetDefaultDllDirectories, this should
stop PuTTY from being willing to load DLLs from its containing
directory - which makes no difference when it's been properly
installed (in which case the application dir contains no DLLs anyway),
but does if it's being run from somewhere uncontrolled like a browser
downloads directory.
Preliminary testing suggests that this shouldn't break any existing
deliberate use of DLLs, including GSSAPI providers.
Copying large scrollback buffers to the clipboard can take a long time,
up to several minutes. Doubling the size of the clipboard copy buffer
when more space is needed, instead of just adding a small constant size,
significantly speeds up clipboard copies of large scrollback buffers.
From ssh2_channel_got_eof() to ssh2_msg_channel_eof(). This removes
the only SSH-2 specicifity from the former. ssh2_channel_got_eof()
can also be called from ssh2_msg_channel_close(), but that calls
ssh2_channel_check_close() already.
Nothing ever sets them to NULL, and the various paths by which the
channel types can be set to CHAN_X11 or CHAN_SOCKDATA all ensure thet
the relevant union members are non-NULL. All the removed conditionals
have been converted into assertions, just in case I'm wrong.
It's redundant with the halfopen flag and is a misuse of the channel
type field. Happily, everything that depends on CHAN_SOCKDATA_DORMANT
also checks halfopen, so removing it is trivial.
Now it disconnects if the server sends
SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE for
a channel that isn't half-open. Assertions in the SSH-2 handlers for
these messages rely on this behaviour even though it's never been
enforced before.
All but one caller was doing this unconditionally. The one conditional
call was when initialising the main channel, and in consequence PuTTY
leaked a channel structure when the server refused to open the main
channel. Now it doesn't.
The Windows implementation of get_file_posn is calling SetFilePointer
to obtain the current position in the file. However it did not
initialize the variable holding the high order 32-bit to 0. Thus,
SetFilePointer either returned -1 to indicate an error or did move the
file pointer to a different location instead of just returning the
current position. This change just initializes the variable to 0.
As a result, this bug has caused psftp's reget command to fail
resuming transfers or to create corrupt files due to setting up an
incorrect resume offset.
It now expects its standard input to be connected to the same PuTTY
its standard output is talking to, i.e. expects to be invoked as a
proxy command. It conducts the same sample key exchange as it used to,
but now reads the SSH greeting and first couple of packets back from
PuTTY and minimally checks that they're something like what it was
expecting.
(In the process, I've also fixed a mistake in the Python message code
enumeration, which caused one of those expect() calls to fail.)
This is equivalent to selecting 'Local' as the proxy type and entering
the argument string in the proxy command box, in the GUI.
I've pulled this out of all the other proxy options to promote to a
named command-line option, partly because it's the proxy option with
the most natural command-line expression in the first place (any shell
command you might want to use is already in the form of a single
string), and also because it has uses beyond end-user proxying
applications: in particular, replacing the network connection with a
local process is a convenient way to do testing in the style of
contrib/samplekex.py, avoiding the need to run a separate command to
make the test 'server' listen on a port.
DJB's spec at http://cr.yp.to/ecdh/curve25519-20060209.pdf is clear
that we should be clearing the low 3 bits of the _LSB_ of the private
key bit string, and setting bit 6 and clearing bit 7 of the _MSB_. We
were doing the opposite, due to feeding the resulting bit string to
bignum_from_bytes() rather than bignum_from_bytes_le().
This didn't cause an interoperability issue, because the two DH
exponentiations still commute, but it goes against the Curve25519
spec, in particular the care taken to fix the position of the leading
exponent bit.
The code is now consistent with the test vectors in RFC 7748 section
6.1: if you modify the EC_MONTGOMERY branch of ssh_ecdhkex_newkey() to
replace the loop on random_byte() with a memcpy that fills bytes[]
with 77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a
and then print out the resulting publicKey->x, you find that it's
(byte-reversed) the expected output value given in that RFC section,
8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a.
An opcode for this was recently published in
https://tools.ietf.org/html/draft-sgtatham-secsh-iutf8-00 .
The default setting is conditional on frontend_is_utf8(), which is
consistent with the pty back end's policy for setting the same flag
locally. Of course, users can override the setting either way in the
GUI configurer, the same as all other tty modes.
Previously only Unix front ends bothered to include it, on the basis
that only the pty backend needed it (to set IUTF8 in the pty). We're
about to need it everywhere else too.
Previously, the code that marshalled tty settings into the "pty-req"
request was iterating through the subkeys stored in ssh->conf, meaning
that if a session had been saved before we gained support for a
particular tty mode, the iteration wouldn't visit that mode at all and
hence wouldn't send even the default setting for it.
Now we iterate over the array of known mode identifiers in
ssh_ttymodes[] and look each one up in ssh->conf, rather than vice
versa. This means that when we add support for a new tty mode with a
nontrivial policy for choosing its default state, we should start
using the default handler immediately, rather than bizarrely waiting
for users to save a session after the change.
Also add an assertion to do_ssh2_transport to catch this.
This bug would be highly unlikely to manifest accidentally, but I
think you could trigger it by setting the data-based rekey threshold
very low.