Source-Changes-HG archive

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

[src/trunk]: src/crypto/external/bsd/openssh/dist Import OpenSSH-9.1 (previou...



details:   https://anonhg.NetBSD.org/src/rev/c20d9271b702
branches:  trunk
changeset: 371747:c20d9271b702
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Oct 05 22:35:32 2022 +0000

description:
Import OpenSSH-9.1 (previously we were on OpenSSH-9.0)

This release is focused on bug fixing.

Security
========

This release contains fixes for three minor memory safety problems.
None are believed to be exploitable, but we report most memory safety
problems as potential security vulnerabilities out of caution.

 * ssh-keyscan(1): fix a one-byte overflow in SSH- banner processing.
   Reported by Qualys

 * ssh-keygen(1): double free() in error path of file hashing step in
   signing/verify code; GHPR333

 * ssh-keysign(8): double-free in error path introduced in openssh-8.9

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

 * The portable OpenSSH project now signs commits and release tags
   using git's recent SSH signature support. The list of developer
   signing keys is included in the repository as .git_allowed_signers
   and is cross-signed using the PGP key that is still used to sign
   release artifacts:
   https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/RELEASE_KEY.asc

 * ssh(1), sshd(8): SetEnv directives in ssh_config and sshd_config
   are now first-match-wins to match other directives. Previously
   if an environment variable was multiply specified the last set
   value would have been used. bz3438

 * ssh-keygen(8): ssh-keygen -A (generate all default host key types)
   will no longer generate DSA keys, as these are insecure and have
   not been used by default for some years.


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

 * ssh(1), sshd(8): add a RequiredRSASize directive to set a minimum
   RSA key length. Keys below this length will be ignored for user
   authentication and for host authentication in sshd(8).

   ssh(1) will terminate a connection if the server offers an RSA key
   that falls below this limit, as the SSH protocol does not include
   the ability to retry a failed key exchange.

 * sftp-server(8): add a "users-groups-by-id%openssh.com@localhost" extension
   request that allows the client to obtain user/group names that
   correspond to a set of uids/gids.

 * sftp(1): use "users-groups-by-id%openssh.com@localhost" sftp-server
   extension (when available) to fill in user/group names for
   directory listings.

 * sftp-server(8): support the "home-directory" extension request
   defined in draft-ietf-secsh-filexfer-extensions-00. This overlaps
   a bit with the existing "expand-path%openssh.com@localhost", but some other
   clients support it.

 * ssh-keygen(1), sshd(8): allow certificate validity intervals,
   sshsig verification times and authorized_keys expiry-time options
   to accept dates in the UTC time zone in addition to the default
   of interpreting them in the system time zone. YYYYMMDD and
   YYMMDDHHMM[SS] dates/times will be interpreted as UTC if suffixed
   with a 'Z' character.

   Also allow certificate validity intervals to be specified in raw
   seconds-since-epoch as hex value, e.g. -V 0x1234:0x4567890. This
   is intended for use by regress tests and other tools that call
   ssh-keygen as part of a CA workflow. bz3468

 * sftp(1): allow arguments to the sftp -D option, e.g. sftp -D
   "/usr/libexec/sftp-server -el debug3"

 * ssh-keygen(1): allow the existing -U (use agent) flag to work
   with "-Y sign" operations, where it will be interpreted to require
   that the private keys is hosted in an agent; bz3429

Bugfixes
--------

 * ssh-keygen(1): implement the "verify-required" certificate option.
   This was already documented when support for user-verified FIDO
   keys was added, but the ssh-keygen(1) code was missing.

 * ssh-agent(1): hook up the restrict_websafe command-line flag;
   previously the flag was accepted but never actually used.

 * sftp(1): improve filename tab completions: never try to complete
   names to non-existent commands, and better match the completion
   type (local or remote filename) against the argument position
   being completed.

 * ssh-keygen(1), ssh(1), ssh-agent(1): several fixes to FIDO key
   handling, especially relating to keys that request
   user-verification. These should reduce the number of unnecessary
   PIN prompts for keys that support intrinsic user verification.
   GHPR302, GHPR329

 * ssh-keygen(1): when enrolling a FIDO resident key, check if a
   credential with matching application and user ID strings already
   exists and, if so, prompt the user for confirmation before
   overwriting the credential. GHPR329

 * sshd(8): improve logging of errors when opening authorized_keys
   files. bz2042

 * ssh(1): avoid multiplexing operations that could cause SIGPIPE from
   causing the client to exit early. bz3454

 * ssh_config(5), sshd_config(5): clarify that the RekeyLimit
   directive applies to both transmitted and received data. GHPR328

 * ssh-keygen(1): avoid double fclose() in error path.

 * sshd(8): log an error if pipe() fails while accepting a
   connection. bz3447

 * ssh(1), ssh-keygen(1): fix possible NULL deref when built without
   FIDO support. bz3443

 * ssh-keyscan(1): add missing *-sk types to ssh-keyscan manpage.
   GHPR294.

 * sshd(8): ensure that authentication passwords are cleared from
   memory in error paths. GHPR286

 * ssh(1), ssh-agent(1): avoid possibility of notifier code executing
   kill(-1). GHPR286

 * ssh_config(5): note that the ProxyJump directive also accepts the
   same tokens as ProxyCommand. GHPR305.

 * scp(1): do not not ftruncate(3) files early when in sftp mode. The
   previous behaviour of unconditionally truncating the destination
   file would cause "scp ~/foo localhost:foo" and the reverse
   "scp localhost:foo ~/foo" to delete all the contents of their
   destination. bz3431

 * ssh-keygen(1): improve error message when 'ssh-keygen -Y sign' is
   unable to load a private key; bz3429

 * sftp(1), scp(1): when performing operations that glob(3) a remote
   path, ensure that the implicit working directory used to construct
   that path escapes glob(3) characters. This prevents glob characters
   from being processed in places they shouldn't, e.g. "cd /tmp/a*/",
   "get *.txt" should have the get operation treat the path "/tmp/a*"
   literally and not attempt to expand it.

 * ssh(1), sshd(8): be stricter in which characters will be accepted
   in specifying a mask length; allow only 0-9. GHPR278

 * ssh-keygen(1): avoid printing hash algorithm twice when dumping a
   KRL

 * ssh(1), sshd(8): continue running local I/O for open channels
   during SSH transport rekeying. This should make ~-escapes work in
   the client (e.g. to exit) if the connection happened to have
   stalled during a rekey event.

 * ssh(1), sshd(8): avoid potential poll() spin during rekeying

 * Further hardening for sshbuf internals: disallow "reparenting" a
   hierarchical sshbuf and zero the entire buffer if reallocation
   fails. GHPR287

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

 * ssh(1), ssh-keygen(1), sshd(8): automatically enable the built-in
   FIDO security key support if libfido2 is found and usable, unless
   --without-security-key-builtin was requested.

 * ssh(1), ssh-keygen(1), sshd(8): many fixes to make the WinHello
   FIDO device usable on Cygwin. The windows://hello FIDO device will
   be automatically used by default on this platform unless requested
   otherwise, or when probing resident FIDO credentials (an operation
   not currently supported by WinHello).

 * Portable OpenSSH: remove workarounds for obsolete and unsupported
   versions of OpenSSL libcrypto. In particular, this release removes
   fallback support for OpenSSL that lacks AES-CTR or AES-GCM.

   Those AES cipher modes were added to OpenSSL prior to the minimum
   version currently supported by OpenSSH, so this is not expected to
   impact any currently supported configurations.

 * sshd(8): fix SANDBOX_SECCOMP_FILTER_DEBUG on current Linux/glibc

 * All: resync and clean up internal CSPRNG code.

 * scp(1), sftp(1), sftp-server(8): avoid linking these programs with
   unnecessary libraries. They are no longer linked against libz and
   libcrypto. This may be of benefit to space constrained systems
   using any of those components in isolation.

 * sshd(8): add AUDIT_ARCH_PPC to supported seccomp sandbox
   architectures.

 * configure: remove special casing of crypt(). configure will no
   longer search for crypt() in libcrypto, as it was removed from
   there years ago. configure will now only search libc and libcrypt.

 * configure: refuse to use OpenSSL 3.0.4 due to potential RCE in its
   RSA implementation (CVE-2022-2274) on x86_64.

 * All: request 1.1x API compatibility for OpenSSL >=3.x; GHPR322

 * ssh(1), ssh-keygen(1), sshd(8): fix a number of missing includes
   required by the XMSS code on some platforms.

 * sshd(8): cache timezone data in capsicum sandbox.

diffstat:

 crypto/external/bsd/openssh/dist/PROTOCOL.key       |   12 +-
 crypto/external/bsd/openssh/dist/auth2-pubkeyfile.c |  500 ++++++++++++++++++++
 crypto/external/bsd/openssh/dist/sftp-usergroup.c   |  238 +++++++++
 crypto/external/bsd/openssh/dist/sftp-usergroup.h   |   25 +
 crypto/external/bsd/openssh/dist/sk-api.h           |    6 +-
 crypto/external/bsd/openssh/dist/ssh-sk-helper.8    |   23 +-
 6 files changed, 787 insertions(+), 17 deletions(-)

diffs (truncated from 904 to 300 lines):

diff -r df6d0623c839 -r c20d9271b702 crypto/external/bsd/openssh/dist/PROTOCOL.key
--- a/crypto/external/bsd/openssh/dist/PROTOCOL.key     Wed Oct 05 22:21:19 2022 +0000
+++ b/crypto/external/bsd/openssh/dist/PROTOCOL.key     Wed Oct 05 22:35:32 2022 +0000
@@ -11,7 +11,7 @@
        string  ciphername
        string  kdfname
        string  kdfoptions
-       int     number of keys N
+       uint32  number of keys N
        string  publickey1
        string  publickey2
        ...
@@ -42,11 +42,11 @@
        ...
        string  privatekeyN
        string  commentN
-       char    1
-       char    2
-       char    3
+       byte    1
+       byte    2
+       byte    3
        ...
-       char    padlen % 255
+       byte    padlen % 255
 
 where each private key is encoded using the same rules as used for
 SSH agent.
@@ -68,4 +68,4 @@
 are used with empty passphrases. The options if the KDF "none"
 are the empty string.
 
-$OpenBSD: PROTOCOL.key,v 1.2 2021/05/07 02:29:40 djm Exp $
+$OpenBSD: PROTOCOL.key,v 1.3 2022/07/01 04:45:50 djm Exp $
diff -r df6d0623c839 -r c20d9271b702 crypto/external/bsd/openssh/dist/auth2-pubkeyfile.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/external/bsd/openssh/dist/auth2-pubkeyfile.c       Wed Oct 05 22:35:32 2022 +0000
@@ -0,0 +1,500 @@
+/* $OpenBSD: auth2-pubkeyfile.c,v 1.3 2022/07/01 03:52:57 djm Exp $ */
+/*
+ * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2010 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "ssh.h"
+#include "log.h"
+#include "misc.h"
+#include "compat.h"
+#include "sshkey.h"
+#include "digest.h"
+#include "hostfile.h"
+#include "auth.h"
+#include "auth-options.h"
+#include "authfile.h"
+#include "match.h"
+#include "ssherr.h"
+
+int
+auth_authorise_keyopts(struct passwd *pw, struct sshauthopt *opts,
+    int allow_cert_authority, const char *remote_ip, const char *remote_host,
+    const char *loc)
+{
+       time_t now = time(NULL);
+       char buf[64];
+
+       /*
+        * Check keys/principals file expiry time.
+        * NB. validity interval in certificate is handled elsewhere.
+        */
+       if (opts->valid_before && now > 0 &&
+           opts->valid_before < (uint64_t)now) {
+               format_absolute_time(opts->valid_before, buf, sizeof(buf));
+               debug("%s: entry expired at %s", loc, buf);
+               auth_debug_add("%s: entry expired at %s", loc, buf);
+               return -1;
+       }
+       /* Consistency checks */
+       if (opts->cert_principals != NULL && !opts->cert_authority) {
+               debug("%s: principals on non-CA key", loc);
+               auth_debug_add("%s: principals on non-CA key", loc);
+               /* deny access */
+               return -1;
+       }
+       /* cert-authority flag isn't valid in authorized_principals files */
+       if (!allow_cert_authority && opts->cert_authority) {
+               debug("%s: cert-authority flag invalid here", loc);
+               auth_debug_add("%s: cert-authority flag invalid here", loc);
+               /* deny access */
+               return -1;
+       }
+
+       /* Perform from= checks */
+       if (opts->required_from_host_keys != NULL) {
+               switch (match_host_and_ip(remote_host, remote_ip,
+                   opts->required_from_host_keys )) {
+               case 1:
+                       /* Host name matches. */
+                       break;
+               case -1:
+               default:
+                       debug("%s: invalid from criteria", loc);
+                       auth_debug_add("%s: invalid from criteria", loc);
+                       /* FALLTHROUGH */
+               case 0:
+                       logit("%s: Authentication tried for %.100s with "
+                           "correct key but not from a permitted "
+                           "host (host=%.200s, ip=%.200s, required=%.200s).",
+                           loc, pw->pw_name, remote_host, remote_ip,
+                           opts->required_from_host_keys);
+                       auth_debug_add("%s: Your host '%.200s' is not "
+                           "permitted to use this key for login.",
+                           loc, remote_host);
+                       /* deny access */
+                       return -1;
+               }
+       }
+       /* Check source-address restriction from certificate */
+       if (opts->required_from_host_cert != NULL) {
+               switch (addr_match_cidr_list(remote_ip,
+                   opts->required_from_host_cert)) {
+               case 1:
+                       /* accepted */
+                       break;
+               case -1:
+               default:
+                       /* invalid */
+                       error("%s: Certificate source-address invalid", loc);
+                       /* FALLTHROUGH */
+               case 0:
+                       logit("%s: Authentication tried for %.100s with valid "
+                           "certificate but not from a permitted source "
+                           "address (%.200s).", loc, pw->pw_name, remote_ip);
+                       auth_debug_add("%s: Your address '%.200s' is not "
+                           "permitted to use this certificate for login.",
+                           loc, remote_ip);
+                       return -1;
+               }
+       }
+       /*
+        *
+        * XXX this is spammy. We should report remotely only for keys
+        *     that are successful in actual auth attempts, and not PK_OK
+        *     tests.
+        */
+       auth_log_authopts(loc, opts, 1);
+
+       return 0;
+}
+
+static int
+match_principals_option(const char *principal_list, struct sshkey_cert *cert)
+{
+       char *result;
+       u_int i;
+
+       /* XXX percent_expand() sequences for authorized_principals? */
+
+       for (i = 0; i < cert->nprincipals; i++) {
+               if ((result = match_list(cert->principals[i],
+                   principal_list, NULL)) != NULL) {
+                       debug3("matched principal from key options \"%.100s\"",
+                           result);
+                       free(result);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * Process a single authorized_principals format line. Returns 0 and sets
+ * authoptsp is principal is authorised, -1 otherwise. "loc" is used as a
+ * log preamble for file/line information.
+ */
+int
+auth_check_principals_line(char *cp, const struct sshkey_cert *cert,
+    const char *loc, struct sshauthopt **authoptsp)
+{
+       u_int i, found = 0;
+       char *ep, *line_opts;
+       const char *reason = NULL;
+       struct sshauthopt *opts = NULL;
+
+       if (authoptsp != NULL)
+               *authoptsp = NULL;
+
+       /* Trim trailing whitespace. */
+       ep = cp + strlen(cp) - 1;
+       while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t'))
+               *ep-- = '\0';
+
+       /*
+        * If the line has internal whitespace then assume it has
+        * key options.
+        */
+       line_opts = NULL;
+       if ((ep = strrchr(cp, ' ')) != NULL ||
+           (ep = strrchr(cp, '\t')) != NULL) {
+               for (; *ep == ' ' || *ep == '\t'; ep++)
+                       ;
+               line_opts = cp;
+               cp = ep;
+       }
+       if ((opts = sshauthopt_parse(line_opts, &reason)) == NULL) {
+               debug("%s: bad principals options: %s", loc, reason);
+               auth_debug_add("%s: bad principals options: %s", loc, reason);
+               return -1;
+       }
+       /* Check principals in cert against those on line */
+       for (i = 0; i < cert->nprincipals; i++) {
+               if (strcmp(cp, cert->principals[i]) != 0)
+                       continue;
+               debug3("%s: matched principal \"%.100s\"",
+                   loc, cert->principals[i]);
+               found = 1;
+       }
+       if (found && authoptsp != NULL) {
+               *authoptsp = opts;
+               opts = NULL;
+       }
+       sshauthopt_free(opts);
+       return found ? 0 : -1;
+}
+
+int
+auth_process_principals(FILE *f, const char *file,
+    const struct sshkey_cert *cert, struct sshauthopt **authoptsp)
+{
+       char loc[256], *line = NULL, *cp, *ep;
+       size_t linesize = 0;
+       u_long linenum = 0, nonblank = 0;
+       u_int found_principal = 0;
+
+       if (authoptsp != NULL)
+               *authoptsp = NULL;
+
+       while (getline(&line, &linesize, f) != -1) {
+               linenum++;
+               /* Always consume entire input */
+               if (found_principal)
+                       continue;
+
+               /* Skip leading whitespace. */
+               for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
+                       ;
+               /* Skip blank and comment lines. */
+               if ((ep = strchr(cp, '#')) != NULL)
+                       *ep = '\0';
+               if (!*cp || *cp == '\n')
+                       continue;
+
+               nonblank++;
+               snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum);
+               if (auth_check_principals_line(cp, cert, loc, authoptsp) == 0)
+                       found_principal = 1;
+       }
+       debug2_f("%s: processed %lu/%lu lines", file, nonblank, linenum);
+       free(line);
+       return found_principal;
+}
+
+/*
+ * Check a single line of an authorized_keys-format file. Returns 0 if key
+ * matches, -1 otherwise. Will return key/cert options via *authoptsp
+ * on success. "loc" is used as file/line location in log messages.
+ */



Home | Main Index | Thread Index | Old Index