Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/OPENSSH]: src/crypto/external/bsd/openssh/dist Import OpenSSH-9.0



details:   https://anonhg.NetBSD.org/src/rev/bcdbdf6848fa
branches:  OPENSSH
changeset: 365227:bcdbdf6848fa
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Apr 15 13:58:16 2022 +0000

description:
Import OpenSSH-9.0

Changes since OpenSSH 8.9
=========================

This release is focused on bug fixing.

Potentially-incompatible changes
--------------------------------

This release switches scp(1) from using the legacy scp/rcp protocol
to using the SFTP protocol by default.

Legacy scp/rcp performs wildcard expansion of remote filenames (e.g.
"scp host:* .") through the remote shell. This has the side effect of
requiring double quoting of shell meta-characters in file names
included on scp(1) command-lines, otherwise they could be interpreted
as shell commands on the remote side.

This creates one area of potential incompatibility: scp(1) when using
the SFTP protocol no longer requires this finicky and brittle quoting,
and attempts to use it may cause transfers to fail. We consider the
removal of the need for double-quoting shell characters in file names
to be a benefit and do not intend to introduce bug-compatibility for
legacy scp/rcp in scp(1) when using the SFTP protocol.

Another area of potential incompatibility relates to the use of remote
paths relative to other user's home directories, for example -
"scp host:~user/file /tmp". The SFTP protocol has no native way to
expand a ~user path. However, sftp-server(8) in OpenSSH 8.7 and later
support a protocol extension "expand-path%openssh.com@localhost" to support
this.

In case of incompatibility, the scp(1) client may be instructed to use
the legacy scp/rcp using the -O flag.

New features
------------

 * ssh(1), sshd(8): use the hybrid Streamlined NTRU Prime + x25519 key
   exchange method by default ("sntrup761x25519-sha512%openssh.com@localhost").
   The NTRU algorithm is believed to resist attacks enabled by future
   quantum computers and is paired with the X25519 ECDH key exchange
   (the previous default) as a backstop against any weaknesses in
   NTRU Prime that may be discovered in the future. The combination
   ensures that the hybrid exchange offers at least as good security
   as the status quo.

   We are making this change now (i.e. ahead of cryptographically-
   relevant quantum computers) to prevent "capture now, decrypt
   later" attacks where an adversary who can record and store SSH
   session ciphertext would be able to decrypt it once a sufficiently
   advanced quantum computer is available.

 * sftp-server(8): support the "copy-data" extension to allow server-
   side copying of files/data, following the design in
   draft-ietf-secsh-filexfer-extensions-00. bz2948

 * sftp(1): add a "cp" command to allow the sftp client to perform
   server-side file copies.

Bugfixes
--------

 * ssh(1), sshd(8): upstream: fix poll(2) spin when a channel's output
   fd closes without data in the channel buffer. bz3405 and bz3411

 * sshd(8): pack pollfd array in server listen/accept loop. Could
   cause the server to hang/spin when MaxStartups > RLIMIT_NOFILE

 * ssh-keygen(1): avoid NULL deref via the find-principals and
   check-novalidate operations. bz3409 and GHPR307 respectively.

 * scp(1): fix a memory leak in argument processing. bz3404

 * sshd(8): don't try to resolve ListenAddress directives in the sshd
   re-exec path. They are unused after re-exec and parsing errors
   (possible for example if the host's network configuration changed)
   could prevent connections from being accepted.

 * sshd(8): when refusing a public key authentication request from a
   client for using an unapproved or unsupported signature algorithm
   include the algorithm name in the log message to make debugging
   easier.

Portability
-----------

 * sshd(8): refactor platform-specific locked account check, fixing
   an incorrect free() on platforms with both libiaf and shadow
   passwords (probably only Unixware) GHPR284,

 * ssh(1), sshd(8): Fix possible integer underflow in scan_scaled(3)
   parsing of K/M/G/etc quantities. bz#3401.

 * sshd(8): provide killpg implementation (mostly for Tandem NonStop)
   GHPR301.

 * Check for missing ftruncate prototype. GHPR301

 * sshd(8): default to not using sandbox when cross compiling. On most
   systems poll(2) does not work when the number of FDs is reduced
   with setrlimit, so assume it doesn't when cross compiling and we
   can't run the test.  bz#3398.

 * sshd(8): allow ppoll_time64 in seccomp sandbox. Should fix sandbox
   violations on some (at least i386 and armhf) 32bit Linux platforms.
   bz#3396.

 * Improve detection of -fzero-call-used-regs=all support in
   configure script.

diffstat:

 crypto/external/bsd/openssh/dist/PROTOCOL       |   41 ++++-
 crypto/external/bsd/openssh/dist/auth-rhosts.c  |    3 +-
 crypto/external/bsd/openssh/dist/auth2-pubkey.c |    6 +-
 crypto/external/bsd/openssh/dist/channels.c     |  218 ++++++++++++-----------
 crypto/external/bsd/openssh/dist/channels.h     |    4 +-
 crypto/external/bsd/openssh/dist/misc.c         |   27 +-
 crypto/external/bsd/openssh/dist/monitor.c      |   11 +-
 crypto/external/bsd/openssh/dist/myproposal.h   |    4 +-
 crypto/external/bsd/openssh/dist/scp.1          |   24 +-
 crypto/external/bsd/openssh/dist/scp.c          |    6 +-
 crypto/external/bsd/openssh/dist/servconf.c     |    9 +-
 crypto/external/bsd/openssh/dist/servconf.h     |    4 +-
 crypto/external/bsd/openssh/dist/sftp-client.c  |  122 +++++++++++++-
 crypto/external/bsd/openssh/dist/sftp-client.h  |    5 +-
 crypto/external/bsd/openssh/dist/sftp-glob.c    |    8 +-
 crypto/external/bsd/openssh/dist/sftp-server.c  |   94 ++++++++++-
 crypto/external/bsd/openssh/dist/sftp.1         |   20 +-
 crypto/external/bsd/openssh/dist/sftp.c         |   20 +-
 crypto/external/bsd/openssh/dist/ssh-agent.1    |    8 +-
 crypto/external/bsd/openssh/dist/ssh-keygen.c   |    9 +-
 crypto/external/bsd/openssh/dist/ssh-keysign.8  |    6 +-
 crypto/external/bsd/openssh/dist/ssh.1          |   10 +-
 crypto/external/bsd/openssh/dist/ssh.c          |    4 +-
 crypto/external/bsd/openssh/dist/ssh_config.5   |   10 +-
 crypto/external/bsd/openssh/dist/sshd.8         |    6 +-
 crypto/external/bsd/openssh/dist/sshd.c         |   31 ++-
 crypto/external/bsd/openssh/dist/sshd_config.5  |    6 +-
 crypto/external/bsd/openssh/dist/sshsig.c       |    9 +-
 crypto/external/bsd/openssh/dist/version.h      |    4 +-
 crypto/external/bsd/openssh/dist/xmalloc.c      |    5 +-
 30 files changed, 528 insertions(+), 206 deletions(-)

diffs (truncated from 1583 to 300 lines):

diff -r 9532ca75ef8e -r bcdbdf6848fa crypto/external/bsd/openssh/dist/PROTOCOL
--- a/crypto/external/bsd/openssh/dist/PROTOCOL Wed Feb 23 19:04:25 2022 +0000
+++ b/crypto/external/bsd/openssh/dist/PROTOCOL Fri Apr 15 13:58:16 2022 +0000
@@ -492,7 +492,7 @@
        string          "fsync%openssh.com@localhost"
        string          handle
 
-One receiving this request, a server will call fsync(handle_fd) and will
+On receiving this request, a server will call fsync(handle_fd) and will
 respond with a SSH_FXP_STATUS message.
 
 This extension is advertised in the SSH_FXP_VERSION hello with version
@@ -576,6 +576,43 @@
 This extension is advertised in the SSH_FXP_VERSION hello with version
 "1".
 
+4.10. sftp: Extension request "copy-data"
+
+This request asks the server to copy data from one open file handle and
+write it to a different open file handle.  This avoids needing to transfer
+the data across the network twice (a download followed by an upload).
+
+       byte            SSH_FXP_EXTENDED
+       uint32          id
+       string          "copy-data"
+       string          read-from-handle
+       uint64          read-from-offset
+       uint64          read-data-length
+       string          write-to-handle
+       uint64          write-to-offset
+
+The server will copy read-data-length bytes starting from
+read-from-offset from the read-from-handle and write them to
+write-to-handle starting from write-to-offset, and then respond with a
+SSH_FXP_STATUS message.
+
+It's equivalent to issuing a series of SSH_FXP_READ requests on
+read-from-handle and a series of requests of SSH_FXP_WRITE on
+write-to-handle.
+
+If read-from-handle and write-to-handle are the same, the server will
+fail the request and respond with a SSH_FX_INVALID_PARAMETER message.
+
+If read-data-length is 0, then the server will read data from the
+read-from-handle until EOF is reached.
+
+This extension is advertised in the SSH_FXP_VERSION hello with version
+"1".
+
+This request is identical to the "copy-data" request documented in:
+
+https://tools.ietf.org/html/draft-ietf-secsh-filexfer-extensions-00#section-7
+
 5. Miscellaneous changes
 
 5.1 Public key format
@@ -612,4 +649,4 @@
 OpenSSH extends the usual agent protocol. These changes are documented
 in the PROTOCOL.agent file.
 
-$OpenBSD: PROTOCOL,v 1.43 2021/12/19 22:15:42 djm Exp $
+$OpenBSD: PROTOCOL,v 1.44 2022/03/31 03:05:49 djm Exp $
diff -r 9532ca75ef8e -r bcdbdf6848fa crypto/external/bsd/openssh/dist/auth-rhosts.c
--- a/crypto/external/bsd/openssh/dist/auth-rhosts.c    Wed Feb 23 19:04:25 2022 +0000
+++ b/crypto/external/bsd/openssh/dist/auth-rhosts.c    Fri Apr 15 13:58:16 2022 +0000
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-rhosts.c,v 1.55 2022/02/23 11:15:57 djm Exp $ */
+/* $OpenBSD: auth-rhosts.c,v 1.56 2022/02/23 21:21:49 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo%cs.hut.fi@localhost>
  * Copyright (c) 1995 Tatu Ylonen <ylo%cs.hut.fi@localhost>, Espoo, Finland
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
+#include <stdlib.h>
 #include <unistd.h>
 
 #include "packet.h"
diff -r 9532ca75ef8e -r bcdbdf6848fa crypto/external/bsd/openssh/dist/auth2-pubkey.c
--- a/crypto/external/bsd/openssh/dist/auth2-pubkey.c   Wed Feb 23 19:04:25 2022 +0000
+++ b/crypto/external/bsd/openssh/dist/auth2-pubkey.c   Fri Apr 15 13:58:16 2022 +0000
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkey.c,v 1.112 2021/12/19 22:12:30 djm Exp $ */
+/* $OpenBSD: auth2-pubkey.c,v 1.113 2022/02/27 01:33:59 naddy Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -163,8 +163,8 @@
                goto done;
        }
        if (match_pattern_list(pkalg, options.pubkey_accepted_algos, 0) != 1) {
-               logit_f("key type %s not in PubkeyAcceptedAlgorithms",
-                   sshkey_ssh_name(key));
+               logit_f("signature algorithm %s not in "
+                   "PubkeyAcceptedAlgorithms", pkalg);
                goto done;
        }
        if ((r = sshkey_check_cert_sigtype(key,
diff -r 9532ca75ef8e -r bcdbdf6848fa crypto/external/bsd/openssh/dist/channels.c
--- a/crypto/external/bsd/openssh/dist/channels.c       Wed Feb 23 19:04:25 2022 +0000
+++ b/crypto/external/bsd/openssh/dist/channels.c       Fri Apr 15 13:58:16 2022 +0000
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.413 2022/02/17 10:58:27 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.415 2022/03/30 21:10:25 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo%cs.hut.fi@localhost>
  * Copyright (c) 1995 Tatu Ylonen <ylo%cs.hut.fi@localhost>, Espoo, Finland
@@ -420,21 +420,25 @@
                c->io_want &= ~SSH_CHAN_IO_RFD;
                c->io_ready &= ~SSH_CHAN_IO_RFD;
                c->rfd = -1;
+               c->pfds[0] = -1;
        }
        if (*fdp == c->wfd) {
                c->io_want &= ~SSH_CHAN_IO_WFD;
                c->io_ready &= ~SSH_CHAN_IO_WFD;
                c->wfd = -1;
+               c->pfds[1] = -1;
        }
        if (*fdp == c->efd) {
                c->io_want &= ~SSH_CHAN_IO_EFD;
                c->io_ready &= ~SSH_CHAN_IO_EFD;
                c->efd = -1;
+               c->pfds[2] = -1;
        }
        if (*fdp == c->sock) {
                c->io_want &= ~SSH_CHAN_IO_SOCK;
                c->io_ready &= ~SSH_CHAN_IO_SOCK;
                c->sock = -1;
+               c->pfds[3] = -1;
        }
 
        ret = close(fd);
@@ -2433,10 +2437,13 @@
     u_int pollfd_offset, struct pollfd *pfd)
 {
 #ifdef DEBUG_CHANNEL_POLL
-       debug3_f("channel %d: rfd r%d w%d e%d s%d "
-           "pfd[%u].fd=%d want 0x%02x ev 0x%02x ready 0x%02x rev 0x%02x",
-           c->self, c->rfd, c->wfd, c->efd, c->sock, pollfd_offset, pfd->fd,
-           c->io_want, pfd->events, c->io_ready, pfd->revents);
+       debug3("%s: channel %d: %s r%d w%d e%d s%d c->pfds [ %d %d %d %d ] "
+           "io_want 0x%02x io_ready 0x%02x pfd[%u].fd=%d "
+           "pfd.ev 0x%02x pfd.rev 0x%02x", func, c->self, what,
+           c->rfd, c->wfd, c->efd, c->sock,
+           c->pfds[0], c->pfds[1], c->pfds[2], c->pfds[3],
+           c->io_want, c->io_ready,
+           pollfd_offset, pfd->fd, pfd->events, pfd->revents);
 #endif
 }
 
@@ -2445,7 +2452,7 @@
 channel_prepare_pollfd(Channel *c, u_int *next_pollfd,
     struct pollfd *pfd, u_int npfd)
 {
-       u_int p = *next_pollfd;
+       u_int ev, p = *next_pollfd;
 
        if (c == NULL)
                return;
@@ -2454,7 +2461,7 @@
                fatal_f("channel %d: bad pfd offset %u (max %u)",
                    c->self, p, npfd);
        }
-       c->pollfd_offset = -1;
+       c->pfds[0] = c->pfds[1] = c->pfds[2] = c->pfds[3] = -1;
        /*
         * prepare c->rfd
         *
@@ -2463,69 +2470,82 @@
         * IO too.
         */
        if (c->rfd != -1) {
-               if (c->pollfd_offset == -1)
-                       c->pollfd_offset = p;
-               pfd[p].fd = c->rfd;
-               pfd[p].events = 0;
+               ev = 0;
                if ((c->io_want & SSH_CHAN_IO_RFD) != 0)
-                       pfd[p].events |= POLLIN;
+                       ev |= POLLIN;
                /* rfd == wfd */
-               if (c->wfd == c->rfd &&
-                   (c->io_want & SSH_CHAN_IO_WFD) != 0)
-                       pfd[p].events |= POLLOUT;
+               if (c->wfd == c->rfd) {
+                       if ((c->io_want & SSH_CHAN_IO_WFD) != 0)
+                               ev |= POLLOUT;
+               }
                /* rfd == efd */
-               if (c->efd == c->rfd &&
-                   (c->io_want & SSH_CHAN_IO_EFD_R) != 0)
-                       pfd[p].events |= POLLIN;
-               if (c->efd == c->rfd &&
-                   (c->io_want & SSH_CHAN_IO_EFD_W) != 0)
-                       pfd[p].events |= POLLOUT;
+               if (c->efd == c->rfd) {
+                       if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0)
+                               ev |= POLLIN;
+                       if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0)
+                               ev |= POLLOUT;
+               }
                /* rfd == sock */
-               if (c->sock == c->rfd &&
-                   (c->io_want & SSH_CHAN_IO_SOCK_R) != 0)
-                       pfd[p].events |= POLLIN;
-               if (c->sock == c->rfd &&
-                   (c->io_want & SSH_CHAN_IO_SOCK_W) != 0)
-                       pfd[p].events |= POLLOUT;
-               dump_channel_poll(__func__, "rfd", c, p, &pfd[p]);
-               p++;
+               if (c->sock == c->rfd) {
+                       if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0)
+                               ev |= POLLIN;
+                       if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0)
+                               ev |= POLLOUT;
+               }
+               /* Pack a pfd entry if any event armed for this fd */
+               if (ev != 0) {
+                       c->pfds[0] = p;
+                       pfd[p].fd = c->rfd;
+                       pfd[p].events = ev;
+                       dump_channel_poll(__func__, "rfd", c, p, &pfd[p]);
+                       p++;
+               }
        }
-       /* prepare c->wfd (if not already handled above) */
+       /* prepare c->wfd if wanting IO and not already handled above */
        if (c->wfd != -1 && c->rfd != c->wfd) {
-               if (c->pollfd_offset == -1)
-                       c->pollfd_offset = p;
-               pfd[p].fd = c->wfd;
-               pfd[p].events = 0;
-               if ((c->io_want & SSH_CHAN_IO_WFD) != 0)
-                       pfd[p].events = POLLOUT;
-               dump_channel_poll(__func__, "wfd", c, p, &pfd[p]);
-               p++;
+               ev = 0;
+               if ((c->io_want & SSH_CHAN_IO_WFD))
+                       ev |= POLLOUT;
+               /* Pack a pfd entry if any event armed for this fd */
+               if (ev != 0) {
+                       c->pfds[1] = p;
+                       pfd[p].fd = c->wfd;
+                       pfd[p].events = ev;
+                       dump_channel_poll(__func__, "wfd", c, p, &pfd[p]);
+                       p++;
+               }
        }
-       /* prepare c->efd (if not already handled above) */
+       /* prepare c->efd if wanting IO and not already handled above */
        if (c->efd != -1 && c->rfd != c->efd) {
-               if (c->pollfd_offset == -1)
-                       c->pollfd_offset = p;
-               pfd[p].fd = c->efd;
-               pfd[p].events = 0;
+               ev = 0;
                if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0)
-                       pfd[p].events |= POLLIN;
+                       ev |= POLLIN;
                if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0)
-                       pfd[p].events |= POLLOUT;
-               dump_channel_poll(__func__, "efd", c, p, &pfd[p]);
-               p++;
+                       ev |= POLLOUT;
+               /* Pack a pfd entry if any event armed for this fd */
+               if (ev != 0) {
+                       c->pfds[2] = p;
+                       pfd[p].fd = c->efd;
+                       pfd[p].events = ev;
+                       dump_channel_poll(__func__, "efd", c, p, &pfd[p]);
+                       p++;
+               }
        }
-       /* prepare c->sock (if not already handled above) */
+       /* prepare c->sock if wanting IO and not already handled above */
        if (c->sock != -1 && c->rfd != c->sock) {
-               if (c->pollfd_offset == -1)
-                       c->pollfd_offset = p;
-               pfd[p].fd = c->sock;
-               pfd[p].events = 0;
+               ev = 0;
                if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0)
-                       pfd[p].events |= POLLIN;
+                       ev |= POLLIN;
                if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0)
-                       pfd[p].events |= POLLOUT;
-               dump_channel_poll(__func__, "sock", c, p, &pfd[p]);
-               p++;
+                       ev |= POLLOUT;
+               /* Pack a pfd entry if any event armed for this fd */
+               if (ev != 0) {
+                       c->pfds[3] = p;
+                       pfd[p].fd = c->sock;
+                       pfd[p].events = 0;
+                       dump_channel_poll(__func__, "sock", c, p, &pfd[p]);
+                       p++;
+               }
        }



Home | Main Index | Thread Index | Old Index