Add patches from CentOS/RHEL9.1

Related: rhbz#2117264
This commit is contained in:
Dmitry Belyavskiy 2022-08-10 15:08:21 +02:00
parent 14d7b86a50
commit 9fd6981674
18 changed files with 2204 additions and 99 deletions

View File

@ -101,22 +101,6 @@ diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c
return idx; return idx;
} }
diff -up openssh-8.5p1/compat.c.coverity openssh-8.5p1/compat.c
--- openssh-8.5p1/compat.c.coverity 2021-03-24 12:03:33.768968062 +0100
+++ openssh-8.5p1/compat.c 2021-03-24 12:03:33.783968166 +0100
@@ -191,10 +191,12 @@ compat_kex_proposal(struct ssh *ssh, cha
return p;
debug2_f("original KEX proposal: %s", p);
if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
+ /* coverity[overwrite_var : FALSE] */
if ((p = match_filter_denylist(p,
"curve25519-sha256@libssh.org")) == NULL)
fatal("match_filter_denylist failed");
if ((ssh->compat & SSH_OLD_DHGEX) != 0) {
+ /* coverity[overwrite_var : FALSE] */
if ((p = match_filter_denylist(p,
"diffie-hellman-group-exchange-sha256,"
"diffie-hellman-group-exchange-sha1")) == NULL)
diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c
--- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100 --- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100
+++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100 +++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100
@ -419,15 +403,6 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
} }
_exit(1); _exit(1);
@@ -762,6 +762,8 @@ process_put(struct sftp_conn *conn, cons
fflag || global_fflag) == -1)
err = -1;
}
+ free(abs_dst);
+ abs_dst = NULL;
}
out:
@@ -985,6 +987,7 @@ do_globbed_ls(struct sftp_conn *conn, co @@ -985,6 +987,7 @@ do_globbed_ls(struct sftp_conn *conn, co
if (lflag & LS_LONG_VIEW) { if (lflag & LS_LONG_VIEW) {
if (g.gl_statv[i] == NULL) { if (g.gl_statv[i] == NULL) {
@ -436,6 +411,30 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
continue; continue;
} }
lname = ls_file(fname, g.gl_statv[i], 1, lname = ls_file(fname, g.gl_statv[i], 1,
diff --git a/sftp-client.c b/sftp-client.c
index 9de9afa20f..ea98d9f8d0 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -2195,6 +2195,7 @@ handle_dest_replies(struct sftp_conn *to, const char *to_path, int synchronous,
(*nreqsp)--;
}
debug3_f("done: %u outstanding replies", *nreqsp);
+ sshbuf_free(msg);
}
int
diff --git a/sftp-server.c b/sftp-server.c
index 18d1949112..6380c4dd23 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1553,6 +1553,7 @@ process_extended_expand(u_int32_t id)
npath = xstrdup(path + 2);
free(path);
xasprintf(&path, "%s/%s", cwd, npath);
+ free(npath);
} else {
/* ~user expansions */
if (tilde_expand(path, pw->pw_uid, &npath) != 0) {
diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c
--- openssh-8.5p1/sk-usbhid.c.coverity 2021-03-02 11:31:47.000000000 +0100 --- openssh-8.5p1/sk-usbhid.c.coverity 2021-03-02 11:31:47.000000000 +0100
+++ openssh-8.5p1/sk-usbhid.c 2021-03-24 12:03:33.786968187 +0100 +++ openssh-8.5p1/sk-usbhid.c 2021-03-24 12:03:33.786968187 +0100
@ -505,15 +504,6 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
} }
/* /*
@@ -2474,7 +2479,7 @@ do_ssh2_kex(struct ssh *ssh)
if (options.rekey_limit || options.rekey_interval)
ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
options.rekey_interval);
-
+ /* coverity[leaked_storage : FALSE]*/
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
ssh, list_hostkey_types());
@@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh) @@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh)
if (newstr) if (newstr)

View File

@ -1,16 +1,3 @@
diff -up openssh-8.6p1/cipher-ctr.c.fips openssh-8.6p1/cipher-ctr.c
--- openssh-8.6p1/cipher-ctr.c.fips 2021-04-19 16:53:02.994577324 +0200
+++ openssh-8.6p1/cipher-ctr.c 2021-04-19 16:53:03.064577862 +0200
@@ -179,7 +179,8 @@ evp_aes_128_ctr(void)
aes_ctr.do_cipher = ssh_aes_ctr;
#ifndef SSH_OLD_EVP
aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV |
+ EVP_CIPH_FLAG_FIPS;
#endif
return (&aes_ctr);
}
diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
--- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 --- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/dh.c 2021-04-19 16:58:47.750263410 +0200 +++ openssh-8.6p1/dh.c 2021-04-19 16:58:47.750263410 +0200
@ -19,7 +6,7 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
struct dhgroup dhg; struct dhgroup dhg;
+ if (FIPS_mode()) { + if (FIPS_mode()) {
+ logit("Using arbitrary primes is not allowed in FIPS mode." + verbose("Using arbitrary primes is not allowed in FIPS mode."
+ " Falling back to known groups."); + " Falling back to known groups.");
+ return (dh_new_group_fallback(max)); + return (dh_new_group_fallback(max));
+ } + }
@ -116,8 +103,8 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
/* generate and send 'e', client DH public key */ /* generate and send 'e', client DH public key */
diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
--- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 --- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/myproposal.h 2021-04-19 16:53:03.065577869 +0200 +++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200
@@ -57,6 +57,19 @@ @@ -57,6 +57,18 @@
"rsa-sha2-512," \ "rsa-sha2-512," \
"rsa-sha2-256" "rsa-sha2-256"
@ -127,12 +114,11 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \ + "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
+ "rsa-sha2-512-cert-v01@openssh.com," \ + "rsa-sha2-512-cert-v01@openssh.com," \
+ "rsa-sha2-256-cert-v01@openssh.com," \ + "rsa-sha2-256-cert-v01@openssh.com," \
+ "ssh-rsa-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp256," \ + "ecdsa-sha2-nistp256," \
+ "ecdsa-sha2-nistp384," \ + "ecdsa-sha2-nistp384," \
+ "ecdsa-sha2-nistp521," \ + "ecdsa-sha2-nistp521," \
+ "rsa-sha2-512," \ + "rsa-sha2-512," \
+ "rsa-sha2-256," + "rsa-sha2-256"
+ +
#define KEX_SERVER_ENCRYPT \ #define KEX_SERVER_ENCRYPT \
"chacha20-poly1305@openssh.com," \ "chacha20-poly1305@openssh.com," \
@ -358,6 +344,20 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
saved_argc = ac; saved_argc = ac;
rexec_argc = ac; rexec_argc = ac;
@@ -1931,6 +1931,13 @@ main(int ac, char **av)
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
do_log2_r(r, ll, "Unable to load host key \"%s\"",
options.host_key_files[i]);
+ if (FIPS_mode() && key != NULL && (sshkey_type_plain(key->type) == KEY_ED25519_SK
+ || sshkey_type_plain(key->type) == KEY_ED25519)) {
+ logit_f("sshd: Ed25519 keys are not allowed in FIPS mode, skipping %s", options.host_key_files[i]);
+ sshkey_free(key);
+ key = NULL;
+ continue;
+ }
if (sshkey_is_sk(key) &&
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
debug("host key %s requires user presence, ignoring",
@@ -2110,6 +2113,10 @@ main(int ac, char **av) @@ -2110,6 +2113,10 @@ main(int ac, char **av)
/* Reinitialize the log (because of the fork above). */ /* Reinitialize the log (because of the fork above). */
log_init(__progname, options.log_level, options.log_facility, log_stderr); log_init(__progname, options.log_level, options.log_facility, log_stderr);
@ -407,15 +407,78 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
#include "ssh-sk.h" #include "ssh-sk.h"
#ifdef WITH_XMSS #ifdef WITH_XMSS
@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA @@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai
for (kt = keytypes; kt->type != -1; kt++) {
if (kt->name == NULL || kt->type == KEY_NULL)
continue;
+ if (FIPS_mode()) {
+ switch (kt->type) {
+ case KEY_ED25519:
+ case KEY_ED25519_SK:
+ case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
if (!include_sigonly && kt->sigonly)
continue;
if ((certs_only && !kt->cert) || (plain_only && kt->cert))
@@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c
return SSH_ERR_EC_CURVE_MISMATCH;
} }
if (!BN_set_word(f4, RSA_F4) ||
!RSA_generate_key_ex(private, bits, f4, NULL)) { + switch (type) {
+ if (FIPS_mode()) + case KEY_ED25519:
+ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); + case KEY_ED25519_SK:
+ case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
+ if (FIPS_mode()) {
+ sshkey_free(k);
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ break;
+ default:
+ break;
+ }
/* Fill in ret from parsed key */
ret->type = type;
if (sshkey_is_cert(ret)) {
@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA
goto out;
if (EVP_PKEY_keygen(ctx, &res) <= 0) {
+ if (FIPS_mode())
+ logit_f("the key length might be unsupported by FIPS mode approved key generation method");
ret = SSH_ERR_LIBCRYPTO_ERROR; ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
@@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key,
break;
case KEY_ED25519_SK:
case KEY_ED25519_SK_CERT:
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ /* Fallthrough */
case KEY_ECDSA_SK_CERT:
case KEY_ECDSA_SK:
r = sshsk_sign(sk_provider, key, sigp, lenp, data,
@@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key,
return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);
case KEY_ED25519_SK:
case KEY_ED25519_SK_CERT:
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen,
compat, detailsp);
#ifdef WITH_XMSS
diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
--- openssh-8.6p1/ssh-keygen.c.fips 2021-04-19 16:53:03.038577662 +0200 --- openssh-8.6p1/ssh-keygen.c.fips 2021-04-19 16:53:03.038577662 +0200
+++ openssh-8.6p1/ssh-keygen.c 2021-04-19 16:53:03.068577892 +0200 +++ openssh-8.6p1/ssh-keygen.c 2021-04-19 16:53:03.068577892 +0200
@ -426,7 +489,7 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
+ if (FIPS_mode()) { + if (FIPS_mode()) {
+ if (type == KEY_DSA) + if (type == KEY_DSA)
+ fatal("DSA keys are not allowed in FIPS mode"); + fatal("DSA keys are not allowed in FIPS mode");
+ if (type == KEY_ED25519) + if (type == KEY_ED25519 || type == KEY_ED25519_SK)
+ fatal("ED25519 keys are not allowed in FIPS mode"); + fatal("ED25519 keys are not allowed in FIPS mode");
+ } + }
switch (type) { switch (type) {
@ -451,3 +514,122 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
if ((fd = mkstemp(prv_tmp)) == -1) { if ((fd = mkstemp(prv_tmp)) == -1) {
error("Could not save your private key in %s: %s", error("Could not save your private key in %s: %s",
prv_tmp, strerror(errno)); prv_tmp, strerror(errno));
diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c
--- openssh-8.7p1/kexgen.c.fips3 2022-07-11 16:11:21.973519913 +0200
+++ openssh-8.7p1/kexgen.c 2022-07-11 16:25:31.172187365 +0200
@@ -31,6 +31,7 @@
#include <stdio.h>
#include <string.h>
#include <signal.h>
+#include <openssl/crypto.h>
#include "sshkey.h"
#include "kex.h"
@@ -115,10 +116,20 @@ kex_gen_client(struct ssh *ssh)
break;
#endif
case KEX_C25519_SHA256:
- r = kex_c25519_keypair(kex);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_keypair(kex);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_keypair(kex);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_keypair(kex);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
@@ -186,11 +197,21 @@ input_kex_gen_reply(int type, u_int32_t
break;
#endif
case KEX_C25519_SHA256:
- r = kex_c25519_dec(kex, server_blob, &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_dec(kex, server_blob, &shared_secret);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_dec(kex, server_blob,
- &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_dec(kex, server_blob,
+ &shared_secret);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
@@ -285,12 +306,22 @@ input_kex_gen_init(int type, u_int32_t s
break;
#endif
case KEX_C25519_SHA256:
- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
- &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
+ &shared_secret);
+ }
break;
case KEX_KEM_SNTRUP761X25519_SHA512:
- r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
- &server_pubkey, &shared_secret);
+ if (FIPS_mode()) {
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
+ r = SSH_ERR_INVALID_ARGUMENT;
+ } else {
+ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
+ &server_pubkey, &shared_secret);
+ }
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c
--- openssh-8.7p1/ssh-ed25519.c.fips3 2022-07-11 16:53:41.428343304 +0200
+++ openssh-8.7p1/ssh-ed25519.c 2022-07-11 16:56:09.284663661 +0200
@@ -24,6 +24,7 @@
#include <string.h>
#include <stdarg.h>
+#include <openssl/crypto.h>
#include "log.h"
#include "sshbuf.h"
@@ -52,6 +53,10 @@ ssh_ed25519_sign(const struct sshkey *ke
key->ed25519_sk == NULL ||
datalen >= INT_MAX - crypto_sign_ed25519_BYTES)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
smlen = slen = datalen + crypto_sign_ed25519_BYTES;
if ((sig = malloc(slen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
@@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey *
datalen >= INT_MAX - crypto_sign_ed25519_BYTES ||
signature == NULL || signaturelen == 0)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode()) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
if ((b = sshbuf_from(signature, signaturelen)) == NULL)
return SSH_ERR_ALLOC_FAIL;

View File

@ -1,13 +1,13 @@
diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 diff --color -ru a/ssh_config.5 b/ssh_config.5
--- openssh-8.7p1/ssh_config.5.crypto-policies 2021-08-30 13:29:00.174292872 +0200 --- a/ssh_config.5 2022-07-12 15:05:22.550013071 +0200
+++ openssh-8.7p1/ssh_config.5 2021-08-30 13:31:32.009548808 +0200 +++ b/ssh_config.5 2022-07-12 15:17:20.016704545 +0200
@@ -373,17 +373,13 @@ or @@ -373,17 +373,13 @@
causes no CNAMEs to be considered for canonicalization. causes no CNAMEs to be considered for canonicalization.
This is the default behaviour. This is the default behaviour.
.It Cm CASignatureAlgorithms .It Cm CASignatureAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies which algorithms are allowed for signing of certificates Specifies which algorithms are allowed for signing of certificates
@ -24,13 +24,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
If the specified list begins with a If the specified list begins with a
.Sq + .Sq +
character, then the specified algorithms will be appended to the default set character, then the specified algorithms will be appended to the default set
@@ -445,20 +441,25 @@ If the option is set to @@ -445,20 +441,25 @@
(the default), (the default),
the check will not be executed. the check will not be executed.
.It Cm Ciphers .It Cm Ciphers
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the ciphers allowed and their order of preference. Specifies the ciphers allowed and their order of preference.
@ -54,7 +54,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Pp .Pp
The supported ciphers are: The supported ciphers are:
.Bd -literal -offset indent .Bd -literal -offset indent
@@ -474,13 +475,6 @@ aes256-gcm@openssh.com @@ -474,13 +475,6 @@
chacha20-poly1305@openssh.com chacha20-poly1305@openssh.com
.Ed .Ed
.Pp .Pp
@ -68,19 +68,19 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
The list of available ciphers may also be obtained using The list of available ciphers may also be obtained using
.Qq ssh -Q cipher . .Qq ssh -Q cipher .
.It Cm ClearAllForwardings .It Cm ClearAllForwardings
@@ -874,6 +868,11 @@ command line will be passed untouched to @@ -874,6 +868,11 @@
The default is The default is
.Dq no . .Dq no .
.It Cm GSSAPIKexAlgorithms .It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
The list of key exchange algorithms that are offered for GSSAPI The list of key exchange algorithms that are offered for GSSAPI
key exchange. Possible values are key exchange. Possible values are
.Bd -literal -offset 3n .Bd -literal -offset 3n
@@ -886,10 +885,8 @@ gss-nistp256-sha256-, @@ -886,10 +885,8 @@
gss-curve25519-sha256- gss-curve25519-sha256-
.Ed .Ed
.Pp .Pp
@ -92,13 +92,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.It Cm HashKnownHosts .It Cm HashKnownHosts
Indicates that Indicates that
.Xr ssh 1 .Xr ssh 1
@@ -1219,29 +1216,25 @@ it may be zero or more of: @@ -1219,29 +1216,25 @@
and and
.Cm pam . .Cm pam .
.It Cm KexAlgorithms .It Cm KexAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the available KEX (Key Exchange) algorithms. Specifies the available KEX (Key Exchange) algorithms.
@ -107,7 +107,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Sq + .Sq +
-character, then the specified algorithms will be appended to the default set -character, then the specified algorithms will be appended to the default set
-instead of replacing them. -instead of replacing them.
+character, then the specified algorithms will be appended to the built-in +character, then the specified methods will be appended to the built-in
+openssh default set instead of replacing them. +openssh default set instead of replacing them.
If the specified list begins with a If the specified list begins with a
.Sq - .Sq -
@ -131,13 +131,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Pp .Pp
The list of available key exchange algorithms may also be obtained using The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q kex . .Qq ssh -Q kex .
@@ -1351,37 +1344,33 @@ function, and all code in the @@ -1351,37 +1344,33 @@
file. file.
This option is intended for debugging and no overrides are enabled by default. This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs .It Cm MACs
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the MAC (message authentication code) algorithms Specifies the MAC (message authentication code) algorithms
@ -178,13 +178,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
The list of available MAC algorithms may also be obtained using The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac . .Qq ssh -Q mac .
.It Cm NoHostAuthenticationForLocalhost .It Cm NoHostAuthenticationForLocalhost
@@ -1553,36 +1542,25 @@ instead of continuing to execute and pas @@ -1553,36 +1542,25 @@
The default is The default is
.Cm no . .Cm no .
.It Cm PubkeyAcceptedAlgorithms .It Cm PubkeyAcceptedAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the signature algorithms that will be used for public key Specifies the signature algorithms that will be used for public key
@ -224,16 +224,16 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Pp .Pp
The list of available signature algorithms may also be obtained using The list of available signature algorithms may also be obtained using
.Qq ssh -Q PubkeyAcceptedAlgorithms . .Qq ssh -Q PubkeyAcceptedAlgorithms .
diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 diff --color -ru a/sshd_config.5 b/sshd_config.5
--- openssh-8.7p1/sshd_config.5.crypto-policies 2021-08-30 13:29:00.157292731 +0200 --- a/sshd_config.5 2022-07-12 15:05:22.535012771 +0200
+++ openssh-8.7p1/sshd_config.5 2021-08-30 13:32:16.263918533 +0200 +++ b/sshd_config.5 2022-07-12 15:15:33.394809258 +0200
@@ -373,17 +373,13 @@ If the argument is @@ -373,17 +373,13 @@
then no banner is displayed. then no banner is displayed.
By default, no banner is displayed. By default, no banner is displayed.
.It Cm CASignatureAlgorithms .It Cm CASignatureAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies which algorithms are allowed for signing of certificates Specifies which algorithms are allowed for signing of certificates
@ -250,13 +250,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
If the specified list begins with a If the specified list begins with a
.Sq + .Sq +
character, then the specified algorithms will be appended to the default set character, then the specified algorithms will be appended to the default set
@@ -450,20 +446,25 @@ The default is @@ -450,20 +446,25 @@
indicating not to indicating not to
.Xr chroot 2 . .Xr chroot 2 .
.It Cm Ciphers .It Cm Ciphers
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the ciphers allowed. Specifies the ciphers allowed.
@ -280,7 +280,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
.Pp .Pp
The supported ciphers are: The supported ciphers are:
.Pp .Pp
@@ -490,13 +491,6 @@ aes256-gcm@openssh.com @@ -490,13 +491,6 @@
chacha20-poly1305@openssh.com chacha20-poly1305@openssh.com
.El .El
.Pp .Pp
@ -294,13 +294,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The list of available ciphers may also be obtained using The list of available ciphers may also be obtained using
.Qq ssh -Q cipher . .Qq ssh -Q cipher .
.It Cm ClientAliveCountMax .It Cm ClientAliveCountMax
@@ -685,21 +679,22 @@ For this to work @@ -685,21 +679,22 @@
.Cm GSSAPIKeyExchange .Cm GSSAPIKeyExchange
needs to be enabled in the server and also used by the client. needs to be enabled in the server and also used by the client.
.It Cm GSSAPIKexAlgorithms .It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
The list of key exchange algorithms that are accepted by GSSAPI The list of key exchange algorithms that are accepted by GSSAPI
@ -327,13 +327,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
This option only applies to connections using GSSAPI. This option only applies to connections using GSSAPI.
.It Cm HostbasedAcceptedAlgorithms .It Cm HostbasedAcceptedAlgorithms
Specifies the signature algorithms that will be accepted for hostbased Specifies the signature algorithms that will be accepted for hostbased
@@ -799,26 +794,13 @@ is specified, the location of the socket @@ -799,26 +794,13 @@
.Ev SSH_AUTH_SOCK .Ev SSH_AUTH_SOCK
environment variable. environment variable.
.It Cm HostKeyAlgorithms .It Cm HostKeyAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the host key signature algorithms Specifies the host key signature algorithms
@ -359,13 +359,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The list of available signature algorithms may also be obtained using The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms . .Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts .It Cm IgnoreRhosts
@@ -965,20 +947,25 @@ Specifies whether to look at .k5login fi @@ -965,20 +947,25 @@
The default is The default is
.Cm yes . .Cm yes .
.It Cm KexAlgorithms .It Cm KexAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the available KEX (Key Exchange) algorithms. Specifies the available KEX (Key Exchange) algorithms.
@ -374,7 +374,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
.Sq + .Sq +
-character, then the specified algorithms will be appended to the default set -character, then the specified algorithms will be appended to the default set
-instead of replacing them. -instead of replacing them.
+character, then the specified algorithms will be appended to the built-in +character, then the specified methods will be appended to the built-in
+openssh default set instead of replacing them. +openssh default set instead of replacing them.
If the specified list begins with a If the specified list begins with a
.Sq - .Sq -
@ -389,7 +389,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The supported algorithms are: The supported algorithms are:
.Pp .Pp
.Bl -item -compact -offset indent .Bl -item -compact -offset indent
@@ -1010,15 +997,6 @@ ecdh-sha2-nistp521 @@ -1010,15 +997,6 @@
sntrup761x25519-sha512@openssh.com sntrup761x25519-sha512@openssh.com
.El .El
.Pp .Pp
@ -405,13 +405,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The list of available key exchange algorithms may also be obtained using The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q KexAlgorithms . .Qq ssh -Q KexAlgorithms .
.It Cm ListenAddress .It Cm ListenAddress
@@ -1104,21 +1082,26 @@ function, and all code in the @@ -1104,21 +1082,26 @@
file. file.
This option is intended for debugging and no overrides are enabled by default. This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs .It Cm MACs
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the available MAC (message authentication code) algorithms. Specifies the available MAC (message authentication code) algorithms.
@ -436,7 +436,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
.Pp .Pp
The algorithms that contain The algorithms that contain
.Qq -etm .Qq -etm
@@ -1161,15 +1144,6 @@ umac-64-etm@openssh.com @@ -1161,15 +1144,6 @@
umac-128-etm@openssh.com umac-128-etm@openssh.com
.El .El
.Pp .Pp
@ -452,13 +452,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The list of available MAC algorithms may also be obtained using The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac . .Qq ssh -Q mac .
.It Cm Match .It Cm Match
@@ -1548,37 +1522,25 @@ or equivalent.) @@ -1548,37 +1522,25 @@
The default is The default is
.Cm yes . .Cm yes .
.It Cm PubkeyAcceptedAlgorithms .It Cm PubkeyAcceptedAlgorithms
+The default is handled system-wide by +The default is handled system-wide by
+.Xr crypto-policies 7 . +.Xr crypto-policies 7 .
+To see the defaults and how to modify this default, see manual page +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
+.Xr update-crypto-policies 8 . +.Xr update-crypto-policies 8 .
+.Pp +.Pp
Specifies the signature algorithms that will be accepted for public key Specifies the signature algorithms that will be accepted for public key

View File

@ -0,0 +1,110 @@
diff -up openssh-8.7p1/sshkey.c.evpgenrsa openssh-8.7p1/sshkey.c
--- openssh-8.7p1/sshkey.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200
+++ openssh-8.7p1/sshkey.c 2022-06-30 15:24:31.499641196 +0200
@@ -1657,7 +1657,8 @@ sshkey_cert_type(const struct sshkey *k)
static int
rsa_generate_private_key(u_int bits, RSA **rsap)
{
- RSA *private = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *res = NULL;
BIGNUM *f4 = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
@@ -1667,20 +1668,42 @@ rsa_generate_private_key(u_int bits, RSA
bits > SSHBUF_MAX_BIGNUM * 8)
return SSH_ERR_KEY_LENGTH;
*rsap = NULL;
- if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
+
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL
+ || (f4 = BN_new()) == NULL || !BN_set_word(f4, RSA_F4)) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (!BN_set_word(f4, RSA_F4) ||
- !RSA_generate_key_ex(private, bits, f4, NULL)) {
+
+ if (EVP_PKEY_keygen_init(ctx) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) {
+ ret = SSH_ERR_KEY_LENGTH;
+ goto out;
+ }
+
+ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, f4) <= 0)
+ goto out;
+
+ if (EVP_PKEY_keygen(ctx, &res) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
+ *rsap = EVP_PKEY_get1_RSA(res);
+ if (*rsap) {
+ ret = 0;
+ } else {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- *rsap = private;
- private = NULL;
- ret = 0;
out:
- RSA_free(private);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(res);
BN_free(f4);
return ret;
}
@@ -1820,7 +1820,8 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k)
static int
ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
{
- EC_KEY *private;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *res = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
if (nid == NULL || ecdsap == NULL)
@@ -1828,20 +1829,29 @@ ecdsa_generate_private_key(u_int bits, i
if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
return SSH_ERR_KEY_LENGTH;
*ecdsap = NULL;
- if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
+
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (EC_KEY_generate_key(private) != 1) {
+
+ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(*nid)) <= 0
+ || EVP_PKEY_keygen(ctx, &res) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
+ *ecdsap = EVP_PKEY_get1_EC_KEY(res);
+ if (*ecdsap) {
+ EC_KEY_set_asn1_flag(*ecdsap, OPENSSL_EC_NAMED_CURVE);
+ ret = 0;
+ } else {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
- *ecdsap = private;
- private = NULL;
- ret = 0;
out:
- EC_KEY_free(private);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(res);
return ret;
}
# endif /* OPENSSL_HAS_ECC */

View File

@ -0,0 +1,20 @@
diff --color -rup a/monitor.c b/monitor.c
--- a/monitor.c 2022-07-11 15:11:28.146863144 +0200
+++ b/monitor.c 2022-07-11 15:15:35.726655877 +0200
@@ -376,8 +376,15 @@ monitor_child_preauth(struct ssh *ssh, s
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
auth_log(ssh, authenticated, partial,
auth_method, auth_submethod);
- if (!partial && !authenticated)
+ if (!partial && !authenticated) {
+#ifdef GSSAPI
+ /* If gssapi-with-mic failed, MONITOR_REQ_GSSCHECKMIC is disabled.
+ * We have to reenable it to try again for gssapi-keyex */
+ if (strcmp(auth_method, "gssapi-with-mic") == 0 && options.gss_keyex)
+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
+#endif
authctxt->failures++;
+ }
if (authenticated || partial) {
auth2_update_session_info(authctxt,
auth_method, auth_submethod);

View File

@ -0,0 +1,151 @@
diff --color -rup a/sshconnect2.c b/sshconnect2.c
--- a/sshconnect2.c 2022-07-11 17:00:02.618575727 +0200
+++ b/sshconnect2.c 2022-07-11 17:03:05.096085690 +0200
@@ -2288,9 +2288,9 @@ userauth_hostbased(struct ssh *ssh)
if (authctxt->sensitive->keys[i] == NULL ||
authctxt->sensitive->keys[i]->type == KEY_UNSPEC)
continue;
- if (match_pattern_list(
+ if (!sshkey_match_keyname_to_sigalgs(
sshkey_ssh_name(authctxt->sensitive->keys[i]),
- authctxt->active_ktype, 0) != 1)
+ authctxt->active_ktype))
continue;
/* we take and free the key */
private = authctxt->sensitive->keys[i];
@@ -2316,7 +2316,8 @@ userauth_hostbased(struct ssh *ssh)
error_f("sshkey_fingerprint failed");
goto out;
}
- debug_f("trying hostkey %s %s", sshkey_ssh_name(private), fp);
+ debug_f("trying hostkey %s %s using sigalg %s",
+ sshkey_ssh_name(private), fp, authctxt->active_ktype);
/* figure out a name for the client host */
lname = get_local_name(ssh_packet_get_connection_in(ssh));
diff --color -rup a/sshkey.c b/sshkey.c
--- a/sshkey.c 2022-07-11 17:00:02.609575554 +0200
+++ b/sshkey.c 2022-07-11 17:12:30.905976443 +0200
@@ -252,6 +252,29 @@ sshkey_ecdsa_nid_from_name(const char *n
return -1;
}
+int
+sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs)
+{
+ int ktype;
+
+ if (sigalgs == NULL || *sigalgs == '\0' ||
+ (ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC)
+ return 0;
+ else if (ktype == KEY_RSA) {
+ return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 ||
+ match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 ||
+ match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1;
+ } else if (ktype == KEY_RSA_CERT) {
+ return match_pattern_list("ssh-rsa-cert-v01@openssh.com",
+ sigalgs, 0) == 1 ||
+ match_pattern_list("rsa-sha2-256-cert-v01@openssh.com",
+ sigalgs, 0) == 1 ||
+ match_pattern_list("rsa-sha2-512-cert-v01@openssh.com",
+ sigalgs, 0) == 1;
+ } else
+ return match_pattern_list(keyname, sigalgs, 0) == 1;
+}
+
char *
sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
{
diff --color -rup a/sshkey.h b/sshkey.h
--- a/sshkey.h 2022-07-11 17:00:02.603575438 +0200
+++ b/sshkey.h 2022-07-11 17:13:01.052556879 +0200
@@ -194,6 +194,10 @@ int sshkey_is_cert(const struct sshkey
int sshkey_is_sk(const struct sshkey *);
int sshkey_type_is_cert(int);
int sshkey_type_plain(int);
+
+/* Returns non-zero if key name match sigalgs pattern list. (handles RSA) */
+int sshkey_match_keyname_to_sigalgs(const char *, const char *);
+
int sshkey_to_certified(struct sshkey *);
int sshkey_drop_cert(struct sshkey *);
int sshkey_cert_copy(const struct sshkey *, struct sshkey *);
diff --color -rup a/ssh-keysign.c b/ssh-keysign.c
--- a/ssh-keysign.c 2021-08-20 06:03:49.000000000 +0200
+++ b/ssh-keysign.c 2022-07-11 17:00:23.306973667 +0200
@@ -62,7 +62,7 @@
extern char *__progname;
static int
-valid_request(struct passwd *pw, char *host, struct sshkey **ret,
+valid_request(struct passwd *pw, char *host, struct sshkey **ret, char **pkalgp,
u_char *data, size_t datalen)
{
struct sshbuf *b;
@@ -75,6 +75,8 @@ valid_request(struct passwd *pw, char *h
if (ret != NULL)
*ret = NULL;
+ if (pkalgp != NULL)
+ *pkalgp = NULL;
fail = 0;
if ((b = sshbuf_from(data, datalen)) == NULL)
@@ -122,8 +124,6 @@ valid_request(struct passwd *pw, char *h
fail++;
} else if (key->type != pktype)
fail++;
- free(pkalg);
- free(pkblob);
/* client host name, handle trailing dot */
if ((r = sshbuf_get_cstring(b, &p, &len)) != 0)
@@ -154,8 +154,19 @@ valid_request(struct passwd *pw, char *h
if (fail)
sshkey_free(key);
- else if (ret != NULL)
- *ret = key;
+ else {
+ if (ret != NULL) {
+ *ret = key;
+ key = NULL;
+ }
+ if (pkalgp != NULL) {
+ *pkalgp = pkalg;
+ pkalg = NULL;
+ }
+ }
+ sshkey_free(key);
+ free(pkalg);
+ free(pkblob);
return (fail ? -1 : 0);
}
@@ -170,7 +181,7 @@ main(int argc, char **argv)
struct passwd *pw;
int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd;
u_char *signature, *data, rver;
- char *host, *fp;
+ char *host, *fp, *pkalg;
size_t slen, dlen;
if (pledge("stdio rpath getpw dns id", NULL) != 0)
@@ -258,7 +269,7 @@ main(int argc, char **argv)
if ((r = sshbuf_get_string(b, &data, &dlen)) != 0)
fatal_r(r, "%s: buffer error", __progname);
- if (valid_request(pw, host, &key, data, dlen) < 0)
+ if (valid_request(pw, host, &key, &pkalg, data, dlen) < 0)
fatal("%s: not a valid request", __progname);
free(host);
@@ -279,7 +290,7 @@ main(int argc, char **argv)
}
if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen,
- NULL, NULL, NULL, 0)) != 0)
+ pkalg, NULL, NULL, 0)) != 0)
fatal_r(r, "%s: sshkey_sign failed", __progname);
free(data);

12
openssh-8.7p1-ibmca.patch Normal file
View File

@ -0,0 +1,12 @@
--- openssh-8.7p1/openbsd-compat/bsd-closefrom.c.orig 2022-04-12 15:47:03.815044607 +0200
+++ openssh-8.7p1/openbsd-compat/bsd-closefrom.c 2022-04-12 15:48:12.464963511 +0200
@@ -16,7 +16,7 @@
#include "includes.h"
-#ifndef HAVE_CLOSEFROM
+#if (!defined HAVE_CLOSEFROM) || (defined __s390__)
#include <sys/types.h>
#include <sys/param.h>

View File

@ -0,0 +1,156 @@
diff --color -rup a/compat.c b/compat.c
--- a/compat.c 2021-08-20 06:03:49.000000000 +0200
+++ b/compat.c 2022-07-14 17:39:23.770268440 +0200
@@ -157,11 +157,12 @@ compat_banner(struct ssh *ssh, const cha
debug_f("no match: %s", version);
}
+/* Always returns pointer to allocated memory, caller must free. */
char *
compat_cipher_proposal(struct ssh *ssh, char *cipher_prop)
{
if (!(ssh->compat & SSH_BUG_BIGENDIANAES))
- return cipher_prop;
+ return xstrdup(cipher_prop);
debug2_f("original cipher proposal: %s", cipher_prop);
if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL)
fatal("match_filter_denylist failed");
@@ -171,11 +172,12 @@ compat_cipher_proposal(struct ssh *ssh,
return cipher_prop;
}
+/* Always returns pointer to allocated memory, caller must free. */
char *
compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop)
{
if (!(ssh->compat & SSH_BUG_RSASIGMD5))
- return pkalg_prop;
+ return xstrdup(pkalg_prop);
debug2_f("original public key proposal: %s", pkalg_prop);
if ((pkalg_prop = match_filter_denylist(pkalg_prop, "ssh-rsa")) == NULL)
fatal("match_filter_denylist failed");
@@ -185,21 +187,26 @@ compat_pkalg_proposal(struct ssh *ssh, c
return pkalg_prop;
}
+/* Always returns pointer to allocated memory, caller must free. */
char *
compat_kex_proposal(struct ssh *ssh, char *p)
{
+ char *cp = NULL;
+
if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
- return p;
+ return xstrdup(p);
debug2_f("original KEX proposal: %s", p);
if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
if ((p = match_filter_denylist(p,
"curve25519-sha256@libssh.org")) == NULL)
fatal("match_filter_denylist failed");
if ((ssh->compat & SSH_OLD_DHGEX) != 0) {
+ cp = p;
if ((p = match_filter_denylist(p,
"diffie-hellman-group-exchange-sha256,"
"diffie-hellman-group-exchange-sha1")) == NULL)
fatal("match_filter_denylist failed");
+ free(cp);
}
debug2_f("compat KEX proposal: %s", p);
if (*p == '\0')
diff --color -rup a/sshconnect2.c b/sshconnect2.c
--- a/sshconnect2.c 2022-07-14 17:38:43.241496549 +0200
+++ b/sshconnect2.c 2022-07-14 17:39:23.772268479 +0200
@@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
{
char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
char *s, *all_key;
+ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL;
int r, use_known_hosts_order = 0;
#if defined(GSSAPI) && defined(WITH_OPENSSL)
@@ -252,10 +253,9 @@ ssh_kex2(struct ssh *ssh, char *host, st
if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL)
fatal_f("kex_names_cat");
- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, s);
+ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, s);
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
- compat_cipher_proposal(ssh, options.ciphers);
- myproposal[PROPOSAL_ENC_ALGS_STOC] =
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc =
compat_cipher_proposal(ssh, options.ciphers);
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
myproposal[PROPOSAL_COMP_ALGS_STOC] =
@@ -264,12 +264,12 @@ ssh_kex2(struct ssh *ssh, char *host, st
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
if (use_known_hosts_order) {
/* Query known_hosts and prefer algorithms that appear there */
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
compat_pkalg_proposal(ssh,
order_hostkeyalgs(host, hostaddr, port, cinfo));
} else {
/* Use specified HostkeyAlgorithms exactly */
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
}
@@ -383,6 +383,10 @@ ssh_kex2(struct ssh *ssh, char *host, st
(r = ssh_packet_write_wait(ssh)) != 0)
fatal_fr(r, "send packet");
#endif
+ /* Free only parts of proposal that were dynamically allocated here. */
+ free(prop_kex);
+ free(prop_enc);
+ free(prop_hostkey);
}
/*
diff --color -rup a/sshd.c b/sshd.c
--- a/sshd.c 2022-07-14 17:38:43.242496568 +0200
+++ b/sshd.c 2022-07-14 17:42:07.616388978 +0200
@@ -2493,14 +2493,15 @@ do_ssh2_kex(struct ssh *ssh)
{
char *myproposal[PROPOSAL_MAX] = { KEX_SERVER };
struct kex *kex;
+ char *hostkey_types = NULL;
+ char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL;
int r;
- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh,
+ myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh,
options.kex_algorithms);
- myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh,
- options.ciphers);
- myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(ssh,
- options.ciphers);
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] =
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc =
+ compat_cipher_proposal(ssh, options.ciphers);
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
@@ -2513,8 +2514,10 @@ do_ssh2_kex(struct ssh *ssh)
ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
options.rekey_interval);
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
- ssh, list_hostkey_types());
+ hostkey_types = list_hostkey_types();
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
+ compat_pkalg_proposal(ssh, hostkey_types);
+ free(hostkey_types);
#if defined(GSSAPI) && defined(WITH_OPENSSL)
{
@@ -2606,6 +2609,9 @@ do_ssh2_kex(struct ssh *ssh)
(r = ssh_packet_write_wait(ssh)) != 0)
fatal_fr(r, "send test");
#endif
+ free(prop_kex);
+ free(prop_enc);
+ free(prop_hostkey);
debug("KEX done");
}

View File

@ -0,0 +1,194 @@
diff --color -ru a/clientloop.c b/clientloop.c
--- a/clientloop.c 2022-06-29 16:35:06.677597259 +0200
+++ b/clientloop.c 2022-06-29 16:40:29.737926205 +0200
@@ -116,6 +116,9 @@
#include "ssh-gss.h"
#endif
+/* Permitted RSA signature algorithms for UpdateHostkeys proofs */
+#define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256"
+
/* import options */
extern Options options;
@@ -2110,8 +2113,10 @@
struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
size_t i, ndone;
struct sshbuf *signdata;
- int r, kexsigtype, use_kexsigtype;
+ int r, plaintype;
const u_char *sig;
+ const char *rsa_kexalg = NULL;
+ char *alg = NULL;
size_t siglen;
if (ctx->nnew == 0)
@@ -2122,9 +2127,9 @@
hostkeys_update_ctx_free(ctx);
return;
}
- kexsigtype = sshkey_type_plain(
- sshkey_type_from_name(ssh->kex->hostkey_alg));
-
+ if (sshkey_type_plain(sshkey_type_from_name(
+ ssh->kex->hostkey_alg)) == KEY_RSA)
+ rsa_kexalg = ssh->kex->hostkey_alg;
if ((signdata = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
/*
@@ -2135,6 +2140,7 @@
for (ndone = i = 0; i < ctx->nkeys; i++) {
if (ctx->keys_match[i])
continue;
+ plaintype = sshkey_type_plain(ctx->keys[i]->type);
/* Prepare data to be signed: session ID, unique string, key */
sshbuf_reset(signdata);
if ( (r = sshbuf_put_cstring(signdata,
@@ -2148,19 +2154,33 @@
error_fr(r, "parse sig");
goto out;
}
+ if ((r = sshkey_get_sigtype(sig, siglen, &alg)) != 0) {
+ error_fr(r, "server gave unintelligible signature "
+ "for %s key %zu", sshkey_type(ctx->keys[i]), i);
+ goto out;
+ }
/*
- * For RSA keys, prefer to use the signature type negotiated
- * during KEX to the default (SHA1).
+ * Special case for RSA keys: if a RSA hostkey was negotiated,
+ * then use its signature type for verification of RSA hostkey
+ * proofs. Otherwise, accept only RSA-SHA256/512 signatures.
*/
- use_kexsigtype = kexsigtype == KEY_RSA &&
- sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA;
- debug3_f("verify %s key %zu using %s sigalg",
- sshkey_type(ctx->keys[i]), i,
- use_kexsigtype ? ssh->kex->hostkey_alg : "default");
+ if (plaintype == KEY_RSA && rsa_kexalg == NULL &&
+ match_pattern_list(alg, HOSTKEY_PROOF_RSA_ALGS, 0) != 1) {
+ debug_f("server used untrusted RSA signature algorithm "
+ "%s for key %zu, disregarding", alg, i);
+ free(alg);
+ /* zap the key from the list */
+ sshkey_free(ctx->keys[i]);
+ ctx->keys[i] = NULL;
+ ndone++;
+ continue;
+ }
+ debug3_f("verify %s key %zu using sigalg %s",
+ sshkey_type(ctx->keys[i]), i, alg);
+ free(alg);
if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
sshbuf_ptr(signdata), sshbuf_len(signdata),
- use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0,
- NULL)) != 0) {
+ plaintype == KEY_RSA ? rsa_kexalg : NULL, 0, NULL)) != 0) {
error_fr(r, "server gave bad signature for %s key %zu",
sshkey_type(ctx->keys[i]), i);
goto out;
diff --color -ru a/kex.c b/kex.c
--- a/kex.c 2022-06-29 16:35:06.775599179 +0200
+++ b/kex.c 2022-06-29 16:42:00.839710940 +0200
@@ -959,6 +959,18 @@
return (1);
}
+/* returns non-zero if proposal contains any algorithm from algs */
+static int
+has_any_alg(const char *proposal, const char *algs)
+{
+ char *cp;
+
+ if ((cp = match_list(proposal, algs, NULL)) == NULL)
+ return 0;
+ free(cp);
+ return 1;
+}
+
static int
kex_choose_conf(struct ssh *ssh)
{
@@ -994,6 +1006,16 @@
free(ext);
}
+ /* Check whether client supports rsa-sha2 algorithms */
+ if (kex->server && (kex->flags & KEX_INITIAL)) {
+ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
+ "rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com"))
+ kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
+ if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
+ "rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com"))
+ kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
+ }
+
/* Algorithm Negotiation */
if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
sprop[PROPOSAL_KEX_ALGS])) != 0) {
diff --color -ru a/kex.h b/kex.h
--- a/kex.h 2022-06-29 16:35:06.766599003 +0200
+++ b/kex.h 2022-06-29 16:42:24.199168567 +0200
@@ -116,6 +116,8 @@
#define KEX_INIT_SENT 0x0001
#define KEX_INITIAL 0x0002
+#define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */
+#define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */
struct sshenc {
char *name;
diff --color -ru a/serverloop.c b/serverloop.c
--- a/serverloop.c 2021-08-20 06:03:49.000000000 +0200
+++ b/serverloop.c 2022-06-29 16:45:05.902336428 +0200
@@ -684,16 +684,18 @@
struct sshbuf *resp = NULL;
struct sshbuf *sigbuf = NULL;
struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
- int r, ndx, kexsigtype, use_kexsigtype, success = 0;
+ int r, ndx, success = 0;
const u_char *blob;
+ const char *sigalg, *kex_rsa_sigalg = NULL;
u_char *sig = 0;
size_t blen, slen;
if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
- kexsigtype = sshkey_type_plain(
- sshkey_type_from_name(ssh->kex->hostkey_alg));
+ if (sshkey_type_plain(sshkey_type_from_name(
+ ssh->kex->hostkey_alg)) == KEY_RSA)
+ kex_rsa_sigalg = ssh->kex->hostkey_alg;
while (ssh_packet_remaining(ssh) > 0) {
sshkey_free(key);
key = NULL;
@@ -726,16 +728,24 @@
* For RSA keys, prefer to use the signature type negotiated
* during KEX to the default (SHA1).
*/
- use_kexsigtype = kexsigtype == KEY_RSA &&
- sshkey_type_plain(key->type) == KEY_RSA;
+ sigalg = NULL;
+ if (sshkey_type_plain(key->type) == KEY_RSA) {
+ if (kex_rsa_sigalg != NULL)
+ sigalg = kex_rsa_sigalg;
+ else if (ssh->kex->flags & KEX_RSA_SHA2_512_SUPPORTED)
+ sigalg = "rsa-sha2-512";
+ else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
+ sigalg = "rsa-sha2-256";
+ }
+ debug3_f("sign %s key (index %d) using sigalg %s",
+ sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
if ((r = sshbuf_put_cstring(sigbuf,
"hostkeys-prove-00@openssh.com")) != 0 ||
(r = sshbuf_put_stringb(sigbuf,
ssh->kex->session_id)) != 0 ||
(r = sshkey_puts(key, sigbuf)) != 0 ||
(r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen,
- sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
- use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
+ sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 ||
(r = sshbuf_put_string(resp, sig, slen)) != 0) {
error_fr(r, "assemble signature");
goto out;

View File

@ -0,0 +1,424 @@
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 2ab222ed6..4e9437912 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -118,6 +118,10 @@ userauth_hostbased(struct ssh *ssh, const char *method)
"(null)" : key->cert->signature_type);
goto done;
}
+ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) {
+ logit("refusing %s key", sshkey_type(key));
+ goto done;
+ }
if (!authctxt->valid || authctxt->user == NULL) {
debug2_f("disabled because of invalid user");
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index daa756a01..68e7dea1f 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -172,6 +172,10 @@ userauth_pubkey(struct ssh *ssh, const char *method)
"(null)" : key->cert->signature_type);
goto done;
}
+ if ((r = sshkey_check_rsa_length(key, options.rsa_min_size)) != 0) {
+ logit("refusing %s key", sshkey_type(key));
+ goto done;
+ }
key_s = format_key(key);
if (sshkey_is_cert(key))
ca_s = format_key(key->cert->signature_key);
diff --git a/readconf.c b/readconf.c
index 5b5afa8e3..5e17abd41 100644
--- a/readconf.c
+++ b/readconf.c
@@ -160,7 +160,7 @@ typedef enum {
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
- oSecurityKeyProvider, oKnownHostsCommand,
+ oSecurityKeyProvider, oKnownHostsCommand, oRSAMinSize,
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
@@ -306,6 +306,7 @@ static struct {
{ "proxyjump", oProxyJump },
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
+ { "rsaminsize", oRSAMinSize },
{ NULL, oBadOption }
};
@@ -2162,6 +2163,10 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
*charptr = xstrdup(arg);
break;
+ case oRSAMinSize:
+ intptr = &options->rsa_min_size;
+ goto parse_int;
+
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@@ -2409,6 +2414,7 @@ initialize_options(Options * options)
options->hostbased_accepted_algos = NULL;
options->pubkey_accepted_algos = NULL;
options->known_hosts_command = NULL;
+ options->rsa_min_size = -1;
}
/*
@@ -2598,6 +2604,8 @@ fill_default_options(Options * options)
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("$SSH_SK_PROVIDER");
#endif
+ if (options->rsa_min_size == -1)
+ options->rsa_min_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
/* Expand KEX name lists */
all_cipher = cipher_alg_list(',', 0);
@@ -3287,6 +3295,7 @@ dump_client_config(Options *o, const char *host)
dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
+ dump_cfg_int(oRSAMinSize, o->rsa_min_size);
/* String options */
dump_cfg_string(oBindAddress, o->bind_address);
diff --git a/readconf.h b/readconf.h
index f647bd42a..29db353ab 100644
--- a/readconf.h
+++ b/readconf.h
@@ -176,6 +176,8 @@ typedef struct {
char *known_hosts_command;
+ int rsa_min_size; /* minimum size of RSA keys */
+
char *ignored_unknown; /* Pattern list of unknown tokens to ignore */
} Options;
diff --git a/servconf.c b/servconf.c
index f7317a5cb..362ff5b67 100644
--- a/servconf.c
+++ b/servconf.c
@@ -177,6 +177,7 @@ initialize_server_options(ServerOptions *options)
options->fingerprint_hash = -1;
options->disable_forwarding = -1;
options->expose_userauth_info = -1;
+ options->rsa_min_size = -1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@@ -416,6 +417,8 @@ fill_default_server_options(ServerOptions *options)
options->expose_userauth_info = 0;
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("internal");
+ if (options->rsa_min_size == -1)
+ options->rsa_min_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
assemble_algorithms(options);
@@ -489,6 +492,7 @@ typedef enum {
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
+ sRSAMinSize,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
@@ -632,6 +636,7 @@ static struct {
{ "rdomain", sRDomain, SSHCFG_ALL },
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
+ { "rsaminsize", sRSAMinSize, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
};
@@ -2377,6 +2382,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
*charptr = xstrdup(arg);
break;
+ case sRSAMinSize:
+ intptr = &options->rsa_min_size;
+ goto parse_int;
+
case sDeprecated:
case sIgnore:
case sUnsupported:
@@ -2549,6 +2558,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
M_CP_INTOPT(log_level);
+ M_CP_INTOPT(rsa_min_size);
/*
* The bind_mask is a mode_t that may be unsigned, so we can't use
@@ -2810,6 +2820,7 @@ dump_config(ServerOptions *o)
dump_cfg_int(sMaxSessions, o->max_sessions);
dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
+ dump_cfg_int(sRSAMinSize, o->rsa_min_size);
dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
/* formatted integer arguments */
diff --git a/servconf.h b/servconf.h
index 115db1e79..2e3486906 100644
--- a/servconf.h
+++ b/servconf.h
@@ -227,6 +227,7 @@ typedef struct {
int expose_userauth_info;
u_int64_t timing_secret;
char *sk_provider;
+ int rsa_min_size; /* minimum size of RSA keys */
} ServerOptions;
/* Information about the incoming connection as used by Match */
diff --git a/ssh.c b/ssh.c
index a926cc007..cd13fb879 100644
--- a/ssh.c
+++ b/ssh.c
@@ -500,14 +500,22 @@ resolve_canonicalize(char **hostp, int port)
}
/*
- * Check the result of hostkey loading, ignoring some errors and
- * fatal()ing for others.
+ * Check the result of hostkey loading, ignoring some errors and either
+ * discarding the key or fatal()ing for others.
*/
static void
-check_load(int r, const char *path, const char *message)
+check_load(int r, struct sshkey **k, const char *path, const char *message)
{
switch (r) {
case 0:
+ /* Check RSA keys size and discard if undersized */
+ if (k != NULL && *k != NULL &&
+ (r = sshkey_check_rsa_length(*k,
+ options.rsa_min_size)) != 0) {
+ error_r(r, "load %s \"%s\"", message, path);
+ free(*k);
+ *k = NULL;
+ }
break;
case SSH_ERR_INTERNAL_ERROR:
case SSH_ERR_ALLOC_FAIL:
@@ -1557,12 +1565,13 @@ main(int ac, char **av)
if ((o) >= sensitive_data.nkeys) \
fatal_f("pubkey out of array bounds"); \
check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \
- p, "pubkey"); \
+ &(sensitive_data.keys[o]), p, "pubkey"); \
} while (0)
#define L_CERT(p,o) do { \
if ((o) >= sensitive_data.nkeys) \
fatal_f("cert out of array bounds"); \
- check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \
+ check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \
+ &(sensitive_data.keys[o]), p, "cert"); \
} while (0)
if (options.hostbased_authentication == 1) {
@@ -2244,7 +2253,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)
filename = default_client_percent_dollar_expand(cp, cinfo);
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
- filename, "pubkey");
+ &public, filename, "pubkey");
debug("identity file %s type %d", filename,
public ? public->type : -1);
free(options.identity_files[i]);
@@ -2263,7 +2272,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)
continue;
xasprintf(&cp, "%s-cert", filename);
check_load(sshkey_load_public(cp, &public, NULL),
- filename, "pubkey");
+ &public, filename, "pubkey");
debug("identity file %s type %d", cp,
public ? public->type : -1);
if (public == NULL) {
@@ -2294,7 +2303,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
- filename, "certificate");
+ &public, filename, "certificate");
debug("certificate file %s type %d", filename,
public ? public->type : -1);
free(options.certificate_files[i]);
diff --git a/sshconnect2.c b/sshconnect2.c
index 67f8e0309..d050c1656 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -91,6 +91,10 @@ static const struct ssh_conn_info *xxx_conn_info;
static int
verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
{
+ int r;
+
+ if ((r = sshkey_check_rsa_length(hostkey, options.rsa_min_size)) != 0)
+ fatal_r(r, "Bad server host key");
if (verify_host_key(xxx_host, xxx_hostaddr, hostkey,
xxx_conn_info) == -1)
fatal("Host key verification failed.");
@@ -1747,6 +1751,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt)
close(agent_fd);
} else {
for (j = 0; j < idlist->nkeys; j++) {
+ if ((r = sshkey_check_rsa_length(idlist->keys[j],
+ options.rsa_min_size)) != 0) {
+ debug_fr(r, "ignoring %s agent key",
+ sshkey_ssh_name(idlist->keys[j]));
+ continue;
+ }
found = 0;
TAILQ_FOREACH(id, &files, next) {
/*
diff --git a/sshd.c b/sshd.c
index d26eb86ae..5f36905a1 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1746,6 +1746,13 @@ main(int ac, char **av)
fatal_r(r, "Could not demote key: \"%s\"",
options.host_key_files[i]);
}
+ if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey,
+ options.rsa_min_size)) != 0) {
+ error_fr(r, "Host key %s", options.host_key_files[i]);
+ sshkey_free(pubkey);
+ sshkey_free(key);
+ continue;
+ }
sensitive_data.host_keys[i] = key;
sensitive_data.host_pubkeys[i] = pubkey;
diff --git a/sshkey.c b/sshkey.c
index 47864e6d8..8bad6bd99 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -2319,18 +2319,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
return ret;
}
-#ifdef WITH_OPENSSL
-static int
-check_rsa_length(const RSA *rsa)
+int
+sshkey_check_rsa_length(const struct sshkey *k, int min_size)
{
+#ifdef WITH_OPENSSL
const BIGNUM *rsa_n;
+ int nbits;
- RSA_get0_key(rsa, &rsa_n, NULL, NULL);
- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+ if (k == NULL || k->rsa == NULL ||
+ (k->type != KEY_RSA && k->type != KEY_RSA_CERT))
+ return 0;
+ RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
+ nbits = BN_num_bits(rsa_n);
+ if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
+ (min_size > 0 && nbits < min_size))
return SSH_ERR_KEY_LENGTH;
+#endif /* WITH_OPENSSL */
return 0;
}
-#endif
static int
sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
@@ -2391,7 +2397,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
goto out;
}
rsa_n = rsa_e = NULL; /* transferred */
- if ((ret = check_rsa_length(key->rsa)) != 0)
+ if ((ret = sshkey_check_rsa_length(key, 0)) != 0)
goto out;
#ifdef DEBUG_PK
RSA_print_fp(stderr, key->rsa, 8);
@@ -3580,7 +3586,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
goto out;
}
rsa_p = rsa_q = NULL; /* transferred */
- if ((r = check_rsa_length(k->rsa)) != 0)
+ if ((r = sshkey_check_rsa_length(k, 0)) != 0)
goto out;
if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
goto out;
@@ -4566,7 +4572,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- if ((r = check_rsa_length(prv->rsa)) != 0)
+ if ((r = sshkey_check_rsa_length(prv, 0)) != 0)
goto out;
} else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA &&
(type == KEY_UNSPEC || type == KEY_DSA)) {
diff --git a/sshkey.h b/sshkey.h
index 125cadb64..52e879456 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -267,6 +267,7 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob,
int type, struct sshkey **pubkeyp);
+int sshkey_check_rsa_length(const struct sshkey *, int);
/* XXX should be internal, but used by ssh-keygen */
int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *);
diff --git a/ssh.1 b/ssh.1
index b4956aec..b1a40ebd 100644
--- a/ssh.1
+++ b/ssh.1
@@ -554,6 +554,7 @@ For full details of the options listed below, and their possible values, see
.It LogLevel
.It MACs
.It Match
+.It RSAMinSize
.It NoHostAuthenticationForLocalhost
.It NumberOfPasswordPrompts
.It PasswordAuthentication
diff --git a/ssh_config.5 b/ssh_config.5
index 24a46460..68771e4b 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -1322,6 +1322,10 @@ The argument to this keyword must be
or
.Cm no
(the default).
+.It Cm RSAMinSize
+Provides a minimal bits requirement for RSA keys when used for signature and
+verification but not for the key generation. The default value is 1024 and
+can't be reduced.
.It Cm NumberOfPasswordPrompts
Specifies the number of password prompts before giving up.
The argument to this keyword must be an integer.
diff --git a/sshd_config.5 b/sshd_config.5
index 867a747d..e08811ca 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1266,6 +1266,10 @@ will refuse connection attempts with a probability of rate/100 (30%)
if there are currently start (10) unauthenticated connections.
The probability increases linearly and all connection attempts
are refused if the number of unauthenticated connections reaches full (60).
+.It Cm RSAMinSize
+Provides a minimal bits requirement for RSA keys when used for signature and
+verification but not for the key generation. The default value is 1024 and
+can't be reduced.
.It Cm ModuliFile
Specifies the
.Xr moduli 5
diff --git a/sshkey.h b/sshkey.h
index 094815e0..2bb8cb90 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -286,6 +286,8 @@ int sshkey_private_serialize_maxsign(struct sshkey *key,
void sshkey_sig_details_free(struct sshkey_sig_details *);
+int ssh_set_rsa_min_bits(int minbits);
+
#ifdef SSHKEY_INTERNAL
int ssh_rsa_sign(const struct sshkey *key,
u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,

View File

@ -0,0 +1,63 @@
diff --color -rup a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh
--- a/regress/hostkey-agent.sh 2021-08-20 06:03:49.000000000 +0200
+++ b/regress/hostkey-agent.sh 2022-07-14 11:58:12.172786060 +0200
@@ -13,8 +13,12 @@ r=$?
grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig
echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig
+PUBKEY_ACCEPTED_ALGOS=`$SSH -G "example.com" | \
+ grep -i "PubkeyAcceptedAlgorithms" | cut -d ' ' -f2- | tr "," "|"`
+SSH_ACCEPTED_KEYTYPES=`echo "$SSH_KEYTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
+
trace "load hostkeys"
-for k in $SSH_KEYTYPES ; do
+for k in $SSH_ACCEPTED_KEYTYPES ; do
${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k"
(
printf 'localhost-with-alias,127.0.0.1,::1 '
@@ -31,7 +35,7 @@ cp $OBJ/known_hosts.orig $OBJ/known_host
unset SSH_AUTH_SOCK
for ps in yes; do
- for k in $SSH_KEYTYPES ; do
+ for k in $SSH_ACCEPTED_KEYTYPES ; do
verbose "key type $k privsep=$ps"
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy
diff --color -rup a/sshconnect2.c b/sshconnect2.c
--- a/sshconnect2.c 2022-07-14 10:10:07.262975710 +0200
+++ b/sshconnect2.c 2022-07-14 10:10:32.068452067 +0200
@@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
{
char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
char *s, *all_key;
+ char *hostkeyalgs = NULL, *pkalg = NULL;
char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL;
int r, use_known_hosts_order = 0;
@@ -264,14 +265,19 @@ ssh_kex2(struct ssh *ssh, char *host, st
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
if (use_known_hosts_order) {
/* Query known_hosts and prefer algorithms that appear there */
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
- compat_pkalg_proposal(ssh,
- order_hostkeyalgs(host, hostaddr, port, cinfo));
+ if ((hostkeyalgs = order_hostkeyalgs(host, hostaddr, port, cinfo)) == NULL)
+ fatal_f("order_hostkeyalgs");
+ pkalg = match_filter_allowlist(hostkeyalgs, options.pubkey_accepted_algos);
+ free(hostkeyalgs);
} else {
- /* Use specified HostkeyAlgorithms exactly */
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
- compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
+ /* Use specified HostkeyAlgorithms */
+ pkalg = match_filter_allowlist(options.hostkeyalgorithms, options.pubkey_accepted_algos);
}
+ if (pkalg == NULL)
+ fatal_f("match_filter_allowlist");
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
+ compat_pkalg_proposal(ssh, pkalg);
+ free(pkalg);
#if defined(GSSAPI) && defined(WITH_OPENSSL)
if (options.gss_keyex) {

View File

@ -0,0 +1,174 @@
diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c
--- openssh-8.7p1/scp.c.scp-sftpdirs 2022-02-07 12:31:07.407740407 +0100
+++ openssh-8.7p1/scp.c 2022-02-07 12:31:07.409740424 +0100
@@ -1324,7 +1324,7 @@ source_sftp(int argc, char *src, char *t
if (src_is_dir && iamrecursive) {
if (upload_dir(conn, src, abs_dst, pflag,
- SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) {
+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
error("failed to upload directory %s to %s",
src, abs_dst);
errs = 1;
diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c
--- openssh-8.7p1/sftp-client.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/sftp-client.c 2022-02-07 12:47:59.117516131 +0100
@@ -971,7 +971,7 @@ do_fsetstat(struct sftp_conn *conn, cons
/* Implements both the realpath and expand-path operations */
static char *
-do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
+do_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir)
{
struct sshbuf *msg;
u_int expected_id, count, id;
@@ -1012,9 +1012,38 @@ do_realpath_expand(struct sftp_conn *con
if ((r = sshbuf_get_u32(msg, &status)) != 0)
fatal_fr(r, "parse status");
- error("Couldn't canonicalize: %s", fx2txt(status));
- sshbuf_free(msg);
- return NULL;
+ if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) {
+ memset(&a, '\0', sizeof(a));
+ if ((r = do_mkdir(conn, path, &a, 0)) != 0) {
+ sshbuf_free(msg);
+ return NULL;
+ }
+
+ send_string_request(conn, id, SSH2_FXP_REALPATH,
+ path, strlen(path));
+
+ get_msg(conn, msg);
+ if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
+ (r = sshbuf_get_u32(msg, &id)) != 0)
+ fatal_fr(r, "parse");
+
+ if (id != expected_id)
+ fatal("ID mismatch (%u != %u)", id, expected_id);
+
+ if (type == SSH2_FXP_STATUS) {
+ u_int status;
+
+ if ((r = sshbuf_get_u32(msg, &status)) != 0)
+ fatal_fr(r, "parse status");
+ error("Couldn't canonicalize: %s", fx2txt(status));
+ sshbuf_free(msg);
+ return NULL;
+ }
+ } else {
+ error("Couldn't canonicalize: %s", fx2txt(status));
+ sshbuf_free(msg);
+ return NULL;
+ }
} else if (type != SSH2_FXP_NAME)
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
SSH2_FXP_NAME, type);
@@ -1039,9 +1067,9 @@ do_realpath_expand(struct sftp_conn *con
}
char *
-do_realpath(struct sftp_conn *conn, const char *path)
+do_realpath(struct sftp_conn *conn, const char *path, int create_dir)
{
- return do_realpath_expand(conn, path, 0);
+ return do_realpath_expand(conn, path, 0, create_dir);
}
int
@@ -1055,9 +1083,9 @@ do_expand_path(struct sftp_conn *conn, c
{
if (!can_expand_path(conn)) {
debug3_f("no server support, fallback to realpath");
- return do_realpath_expand(conn, path, 0);
+ return do_realpath_expand(conn, path, 0, 0);
}
- return do_realpath_expand(conn, path, 1);
+ return do_realpath_expand(conn, path, 1, 0);
}
int
@@ -1807,7 +1835,7 @@ download_dir(struct sftp_conn *conn, con
char *src_canon;
int ret;
- if ((src_canon = do_realpath(conn, src)) == NULL) {
+ if ((src_canon = do_realpath(conn, src, 0)) == NULL) {
error("Unable to canonicalize path \"%s\"", src);
return -1;
}
@@ -2115,12 +2143,12 @@ upload_dir_internal(struct sftp_conn *co
int
upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
int preserve_flag, int print_flag, int resume, int fsync_flag,
- int follow_link_flag)
+ int follow_link_flag, int create_dir)
{
char *dst_canon;
int ret;
- if ((dst_canon = do_realpath(conn, dst)) == NULL) {
+ if ((dst_canon = do_realpath(conn, dst, create_dir)) == NULL) {
error("Unable to canonicalize path \"%s\"", dst);
return -1;
}
@@ -2557,7 +2585,7 @@ crossload_dir(struct sftp_conn *from, st
char *from_path_canon;
int ret;
- if ((from_path_canon = do_realpath(from, from_path)) == NULL) {
+ if ((from_path_canon = do_realpath(from, from_path, 0)) == NULL) {
error("Unable to canonicalize path \"%s\"", from_path);
return -1;
}
diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h
--- openssh-8.7p1/sftp-client.h.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/sftp-client.h 2022-02-07 12:31:07.410740433 +0100
@@ -111,7 +111,7 @@ int do_fsetstat(struct sftp_conn *, cons
int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
/* Canonicalise 'path' - caller must free result */
-char *do_realpath(struct sftp_conn *, const char *);
+char *do_realpath(struct sftp_conn *, const char *, int);
/* Canonicalisation with tilde expansion (requires server extension) */
char *do_expand_path(struct sftp_conn *, const char *);
@@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const
* times if 'pflag' is set
*/
int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int,
- int, int);
+ int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to
diff -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c
--- openssh-8.7p1/sftp.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/sftp.c 2022-02-07 12:31:07.411740442 +0100
@@ -760,7 +760,7 @@ process_put(struct sftp_conn *conn, cons
if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
- fflag || global_fflag, 0) == -1)
+ fflag || global_fflag, 0, 0) == -1)
err = -1;
} else {
if (do_upload(conn, g.gl_pathv[i], abs_dst,
@@ -1577,7 +1577,7 @@ parse_dispatch_command(struct sftp_conn
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup(startdir);
path1 = make_absolute(path1, *pwd);
- if ((tmp = do_realpath(conn, path1)) == NULL) {
+ if ((tmp = do_realpath(conn, path1, 0)) == NULL) {
err = 1;
break;
}
@@ -2160,7 +2160,7 @@ interactive_loop(struct sftp_conn *conn,
}
#endif /* USE_LIBEDIT */
- remote_path = do_realpath(conn, ".");
+ remote_path = do_realpath(conn, ".", 0);
if (remote_path == NULL)
fatal("Need cwd");
startdir = xstrdup(remote_path);

View File

@ -0,0 +1,304 @@
diff --color -rup a/scp.c b/scp.c
--- a/scp.c 2022-07-26 14:51:40.560120817 +0200
+++ b/scp.c 2022-07-26 14:52:37.118213004 +0200
@@ -1324,12 +1324,12 @@ source_sftp(int argc, char *src, char *t
if (src_is_dir && iamrecursive) {
if (upload_dir(conn, src, abs_dst, pflag,
- SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) {
error("failed to upload directory %s to %s",
src, abs_dst);
errs = 1;
}
- } else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0) {
+ } else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) {
error("failed to upload file %s to %s", src, abs_dst);
errs = 1;
}
@@ -1566,11 +1566,11 @@ sink_sftp(int argc, char *dst, const cha
debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
- pflag, SFTP_PROGRESS_ONLY, 0, 0, 1) == -1)
+ pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1)
err = -1;
} else {
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
- pflag, 0, 0) == -1)
+ pflag, 0, 0, 1) == -1)
err = -1;
}
free(abs_dst);
diff --color -rup a/sftp.c b/sftp.c
--- a/sftp.c 2022-07-26 14:51:40.561120836 +0200
+++ b/sftp.c 2022-07-26 14:52:37.119213023 +0200
@@ -666,12 +666,12 @@ process_get(struct sftp_conn *conn, cons
if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, 1, resume,
- fflag || global_fflag, 0) == -1)
+ fflag || global_fflag, 0, 0) == -1)
err = -1;
} else {
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, resume,
- fflag || global_fflag) == -1)
+ fflag || global_fflag, 0) == -1)
err = -1;
}
free(abs_dst);
@@ -760,12 +760,12 @@ process_put(struct sftp_conn *conn, cons
if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
- fflag || global_fflag, 0, 0) == -1)
+ fflag || global_fflag, 0, 0, 0) == -1)
err = -1;
} else {
if (do_upload(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, resume,
- fflag || global_fflag) == -1)
+ fflag || global_fflag, 0) == -1)
err = -1;
}
}
diff --color -rup a/sftp-client.c b/sftp-client.c
--- a/sftp-client.c 2022-07-26 14:51:40.561120836 +0200
+++ b/sftp-client.c 2022-07-26 15:09:54.825295533 +0200
@@ -1454,7 +1454,7 @@ progress_meter_path(const char *path)
int
do_download(struct sftp_conn *conn, const char *remote_path,
const char *local_path, Attrib *a, int preserve_flag, int resume_flag,
- int fsync_flag)
+ int fsync_flag, int inplace_flag)
{
struct sshbuf *msg;
u_char *handle;
@@ -1498,8 +1498,8 @@ do_download(struct sftp_conn *conn, cons
&handle, &handle_len) != 0)
return -1;
- local_fd = open(local_path,
- O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
+ local_fd = open(local_path, O_WRONLY | O_CREAT |
+ ((resume_flag || inplace_flag) ? 0 : O_TRUNC), mode | S_IWUSR);
if (local_fd == -1) {
error("Couldn't open local file \"%s\" for writing: %s",
local_path, strerror(errno));
@@ -1661,8 +1661,11 @@ do_download(struct sftp_conn *conn, cons
/* Sanity check */
if (TAILQ_FIRST(&requests) != NULL)
fatal("Transfer complete, but requests still in queue");
- /* Truncate at highest contiguous point to avoid holes on interrupt */
- if (read_error || write_error || interrupted) {
+ /*
+ * Truncate at highest contiguous point to avoid holes on interrupt,
+ * or unconditionally if writing in place.
+ */
+ if (inplace_flag || read_error || write_error || interrupted) {
if (reordered && resume_flag) {
error("Unable to resume download of \"%s\": "
"server reordered requests", local_path);
@@ -1724,7 +1727,7 @@ do_download(struct sftp_conn *conn, cons
static int
download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
int depth, Attrib *dirattrib, int preserve_flag, int print_flag,
- int resume_flag, int fsync_flag, int follow_link_flag)
+ int resume_flag, int fsync_flag, int follow_link_flag, int inplace_flag)
{
int i, ret = 0;
SFTP_DIRENT **dir_entries;
@@ -1781,7 +1784,7 @@ download_dir_internal(struct sftp_conn *
if (download_dir_internal(conn, new_src, new_dst,
depth + 1, &(dir_entries[i]->a), preserve_flag,
print_flag, resume_flag,
- fsync_flag, follow_link_flag) == -1)
+ fsync_flag, follow_link_flag, inplace_flag) == -1)
ret = -1;
} else if (S_ISREG(dir_entries[i]->a.perm) ||
(follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) {
@@ -1793,7 +1796,8 @@ download_dir_internal(struct sftp_conn *
if (do_download(conn, new_src, new_dst,
S_ISLNK(dir_entries[i]->a.perm) ? NULL :
&(dir_entries[i]->a),
- preserve_flag, resume_flag, fsync_flag) == -1) {
+ preserve_flag, resume_flag, fsync_flag,
+ inplace_flag) == -1) {
error("Download of file %s to %s failed",
new_src, new_dst);
ret = -1;
@@ -1831,7 +1835,7 @@ download_dir_internal(struct sftp_conn *
int
download_dir(struct sftp_conn *conn, const char *src, const char *dst,
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
- int fsync_flag, int follow_link_flag)
+ int fsync_flag, int follow_link_flag, int inplace_flag)
{
char *src_canon;
int ret;
@@ -1843,26 +1847,25 @@ download_dir(struct sftp_conn *conn, con
ret = download_dir_internal(conn, src_canon, dst, 0,
dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag,
- follow_link_flag);
+ follow_link_flag, inplace_flag);
free(src_canon);
return ret;
}
int
do_upload(struct sftp_conn *conn, const char *local_path,
- const char *remote_path, int preserve_flag, int resume, int fsync_flag)
+ const char *remote_path, int preserve_flag, int resume,
+ int fsync_flag, int inplace_flag)
{
int r, local_fd;
- u_int status = SSH2_FX_OK;
- u_int id;
- u_char type;
+ u_int openmode, id, status = SSH2_FX_OK, reordered = 0;
off_t offset, progress_counter;
- u_char *handle, *data;
+ u_char type, *handle, *data;
struct sshbuf *msg;
struct stat sb;
- Attrib a, *c = NULL;
- u_int32_t startid;
- u_int32_t ackid;
+ Attrib a, t, *c = NULL;
+ u_int32_t startid, ackid;
+ u_int64_t highwater = 0;
struct request *ack = NULL;
struct requests acks;
size_t handle_len;
@@ -1913,10 +1916,15 @@ do_upload(struct sftp_conn *conn, const
}
}
+ openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT;
+ if (resume)
+ openmode |= SSH2_FXF_APPEND;
+ else if (!inplace_flag)
+ openmode |= SSH2_FXF_TRUNC;
+
/* Send open request */
- if (send_open(conn, remote_path, "dest", SSH2_FXF_WRITE|SSH2_FXF_CREAT|
- (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC),
- &a, &handle, &handle_len) != 0) {
+ if (send_open(conn, remote_path, "dest", openmode, &a,
+ &handle, &handle_len) != 0) {
close(local_fd);
return -1;
}
@@ -1999,6 +2007,12 @@ do_upload(struct sftp_conn *conn, const
ack->id, ack->len, (unsigned long long)ack->offset);
++ackid;
progress_counter += ack->len;
+ if (!reordered && ack->offset <= highwater)
+ highwater = ack->offset + ack->len;
+ else if (!reordered && ack->offset > highwater) {
+ debug3_f("server reordered ACKs");
+ reordered = 1;
+ }
free(ack);
}
offset += len;
@@ -2017,6 +2031,14 @@ do_upload(struct sftp_conn *conn, const
status = SSH2_FX_FAILURE;
}
+ if (inplace_flag || (resume && (status != SSH2_FX_OK || interrupted))) {
+ debug("truncating at %llu", (unsigned long long)highwater);
+ attrib_clear(&t);
+ t.flags = SSH2_FILEXFER_ATTR_SIZE;
+ t.size = highwater;
+ do_fsetstat(conn, handle, handle_len, &t);
+ }
+
if (close(local_fd) == -1) {
error("Couldn't close local file \"%s\": %s", local_path,
strerror(errno));
@@ -2041,7 +2063,7 @@ do_upload(struct sftp_conn *conn, const
static int
upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
int depth, int preserve_flag, int print_flag, int resume, int fsync_flag,
- int follow_link_flag)
+ int follow_link_flag, int inplace_flag)
{
int ret = 0;
DIR *dirp;
@@ -2119,12 +2141,13 @@ upload_dir_internal(struct sftp_conn *co
if (upload_dir_internal(conn, new_src, new_dst,
depth + 1, preserve_flag, print_flag, resume,
- fsync_flag, follow_link_flag) == -1)
+ fsync_flag, follow_link_flag, inplace_flag) == -1)
ret = -1;
} else if (S_ISREG(sb.st_mode) ||
(follow_link_flag && S_ISLNK(sb.st_mode))) {
if (do_upload(conn, new_src, new_dst,
- preserve_flag, resume, fsync_flag) == -1) {
+ preserve_flag, resume, fsync_flag,
+ inplace_flag) == -1) {
error("Uploading of file %s to %s failed!",
new_src, new_dst);
ret = -1;
@@ -2144,7 +2167,7 @@ upload_dir_internal(struct sftp_conn *co
int
upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
int preserve_flag, int print_flag, int resume, int fsync_flag,
- int follow_link_flag, int create_dir)
+ int follow_link_flag, int create_dir, int inplace_flag)
{
char *dst_canon;
int ret;
@@ -2155,7 +2178,7 @@ upload_dir(struct sftp_conn *conn, const
}
ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
- print_flag, resume, fsync_flag, follow_link_flag);
+ print_flag, resume, fsync_flag, follow_link_flag, inplace_flag);
free(dst_canon);
return ret;
diff --color -rup a/sftp-client.h b/sftp-client.h
--- a/sftp-client.h 2022-07-26 14:51:40.561120836 +0200
+++ b/sftp-client.h 2022-07-26 14:52:37.120213042 +0200
@@ -138,28 +138,29 @@ int do_fsync(struct sftp_conn *conn, u_c
* Download 'remote_path' to 'local_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_download(struct sftp_conn *, const char *, const char *,
- Attrib *, int, int, int);
+int do_download(struct sftp_conn *, const char *, const char *, Attrib *,
+ int, int, int, int);
/*
* Recursively download 'remote_directory' to 'local_directory'. Preserve
* times if 'pflag' is set
*/
-int download_dir(struct sftp_conn *, const char *, const char *,
- Attrib *, int, int, int, int, int);
+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
+ int, int, int, int, int, int);
/*
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_upload(struct sftp_conn *, const char *, const char *, int, int, int);
+int do_upload(struct sftp_conn *, const char *, const char *,
+ int, int, int, int);
/*
* Recursively upload 'local_directory' to 'remote_directory'. Preserve
* times if 'pflag' is set
*/
-int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int,
- int, int, int);
+int upload_dir(struct sftp_conn *, const char *, const char *,
+ int, int, int, int, int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to

View File

@ -0,0 +1,135 @@
diff -up openssh-8.7p1/scp.c.sftpdirs openssh-8.7p1/scp.c
--- openssh-8.7p1/scp.c.sftpdirs 2022-02-02 14:11:12.553447509 +0100
+++ openssh-8.7p1/scp.c 2022-02-02 14:12:56.081316414 +0100
@@ -130,6 +130,7 @@
#include "misc.h"
#include "progressmeter.h"
#include "utf8.h"
+#include "sftp.h"
#include "sftp-common.h"
#include "sftp-client.h"
@@ -1264,13 +1265,18 @@ tolocal(int argc, char **argv, enum scp_
static char *
prepare_remote_path(struct sftp_conn *conn, const char *path)
{
+ size_t nslash;
+
/* Handle ~ prefixed paths */
- if (*path != '~')
- return xstrdup(path);
if (*path == '\0' || strcmp(path, "~") == 0)
return xstrdup(".");
- if (strncmp(path, "~/", 2) == 0)
- return xstrdup(path + 2);
+ if (*path != '~')
+ return xstrdup(path);
+ if (strncmp(path, "~/", 2) == 0) {
+ if ((nslash = strspn(path + 2, "/")) == strlen(path + 2))
+ return xstrdup(".");
+ return xstrdup(path + 2 + nslash);
+ }
if (can_expand_path(conn))
return do_expand_path(conn, path);
/* No protocol extension */
@@ -1282,10 +1288,16 @@ void
source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
{
char *target = NULL, *filename = NULL, *abs_dst = NULL;
- int target_is_dir;
-
+ int src_is_dir, target_is_dir;
+ Attrib a;
+ struct stat st;
+
+ memset(&a, '\0', sizeof(a));
+ if (stat(src, &st) != 0)
+ fatal("stat local \"%s\": %s", src, strerror(errno));
+ src_is_dir = S_ISDIR(st.st_mode);
if ((filename = basename(src)) == NULL)
- fatal("basename %s: %s", src, strerror(errno));
+ fatal("basename \"%s\": %s", src, strerror(errno));
/*
* No need to glob here - the local shell already took care of
@@ -1295,8 +1307,12 @@ source_sftp(int argc, char *src, char *t
cleanup_exit(255);
target_is_dir = remote_is_dir(conn, target);
if (targetshouldbedirectory && !target_is_dir) {
- fatal("Target is not a directory, but more files selected "
- "for upload");
+ debug("target directory \"%s\" does not exist", target);
+ a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS;
+ a.perm = st.st_mode | 0700; /* ensure writable */
+ if (do_mkdir(conn, target, &a, 1) != 0)
+ cleanup_exit(255); /* error already logged */
+ target_is_dir = 1;
}
if (target_is_dir)
abs_dst = path_append(target, filename);
@@ -1306,7 +1322,7 @@ source_sftp(int argc, char *src, char *t
}
debug3_f("copying local %s to remote %s", src, abs_dst);
- if (local_is_dir(src) && iamrecursive) {
+ if (src_is_dir && iamrecursive) {
if (upload_dir(conn, src, abs_dst, pflag,
SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) {
error("failed to upload directory %s to %s",
@@ -1487,14 +1506,15 @@ sink_sftp(int argc, char *dst, const cha
char *abs_dst = NULL;
glob_t g;
char *filename, *tmp = NULL;
- int i, r, err = 0;
+ int i, r, err = 0, dst_is_dir;
+ struct stat st;
memset(&g, 0, sizeof(g));
+
/*
* Here, we need remote glob as SFTP can not depend on remote shell
* expansions
*/
-
if ((abs_src = prepare_remote_path(conn, src)) == NULL) {
err = -1;
goto out;
@@ -1510,11 +1530,24 @@ sink_sftp(int argc, char *dst, const cha
goto out;
}
- if (g.gl_matchc > 1 && !local_is_dir(dst)) {
- error("Multiple files match pattern, but destination "
- "\"%s\" is not a directory", dst);
- err = -1;
- goto out;
+ if ((r = stat(dst, &st)) != 0)
+ debug2_f("stat local \"%s\": %s", dst, strerror(errno));
+ dst_is_dir = r == 0 && S_ISDIR(st.st_mode);
+
+ if (g.gl_matchc > 1 && !dst_is_dir) {
+ if (r == 0) {
+ error("Multiple files match pattern, but destination "
+ "\"%s\" is not a directory", dst);
+ err = -1;
+ goto out;
+ }
+ debug2_f("creating destination \"%s\"", dst);
+ if (mkdir(dst, 0777) != 0) {
+ error("local mkdir \"%s\": %s", dst, strerror(errno));
+ err = -1;
+ goto out;
+ }
+ dst_is_dir = 1;
}
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
@@ -1525,7 +1558,7 @@ sink_sftp(int argc, char *dst, const cha
goto out;
}
- if (local_is_dir(dst))
+ if (dst_is_dir)
abs_dst = path_append(dst, filename);
else
abs_dst = xstrdup(dst);

View File

@ -0,0 +1,53 @@
diff --color -ru a/ssh.1 b/ssh.1
--- a/ssh.1 2022-07-12 11:47:51.307295880 +0200
+++ b/ssh.1 2022-07-12 11:50:28.793363263 +0200
@@ -493,6 +493,7 @@
.It AddressFamily
.It BatchMode
.It BindAddress
+.It BindInterface
.It CanonicalDomains
.It CanonicalizeFallbackLocal
.It CanonicalizeHostname
@@ -510,6 +511,7 @@
.It ControlPath
.It ControlPersist
.It DynamicForward
+.It EnableSSHKeysign
.It EscapeChar
.It ExitOnForwardFailure
.It FingerprintHash
@@ -538,6 +540,8 @@
.It IdentitiesOnly
.It IdentityAgent
.It IdentityFile
+.It IgnoreUnknown
+.It Include
.It IPQoS
.It KbdInteractiveAuthentication
.It KbdInteractiveDevices
@@ -546,6 +550,7 @@
.It LocalCommand
.It LocalForward
.It LogLevel
+.It LogVerbose
.It MACs
.It Match
.It RSAMinSize
@@ -566,6 +571,8 @@
.It RemoteCommand
.It RemoteForward
.It RequestTTY
+.It RevokedHostKeys
+.It SecurityKeyProvider
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
@@ -575,6 +582,7 @@
.It StreamLocalBindMask
.It StreamLocalBindUnlink
.It StrictHostKeyChecking
+.It SyslogFacility
.It TCPKeepAlive
.It Tunnel
.It TunnelDevice

View File

@ -0,0 +1,41 @@
diff -up openssh-8.8p1/regress/hostkey-agent.sh.redhat openssh-8.8p1/regress/hostkey-agent.sh
--- openssh-8.8p1/regress/hostkey-agent.sh.redhat 2022-08-10 15:54:42.084777662 +0200
+++ openssh-8.8p1/regress/hostkey-agent.sh 2022-08-10 17:01:25.651269994 +0200
@@ -36,6 +36,8 @@ unset SSH_AUTH_SOCK
for ps in yes; do
for k in $SSH_ACCEPTED_KEYTYPES ; do
+ [ "$k" == "ssh-rsa" ] && continue
+ [ "$k" == "ssh-dss" ] && continue
verbose "key type $k privsep=$ps"
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy
diff -up openssh-8.8p1/regress/hostkey-rotate.sh.redhat openssh-8.8p1/regress/hostkey-rotate.sh
--- openssh-8.8p1/regress/hostkey-rotate.sh.redhat 2022-08-10 16:57:12.720029146 +0200
+++ openssh-8.8p1/regress/hostkey-rotate.sh 2022-08-10 17:15:48.274923865 +0200
@@ -40,6 +40,8 @@ trace "prepare hostkeys"
nkeys=0
all_algs=""
for k in $SSH_HOSTKEY_TYPES; do
+ [ "$k" == "ssh-rsa" ] && continue
+ [ "$k" == "ssh-dss" ] && continue
${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k"
echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig
nkeys=`expr $nkeys + 1`
@@ -87,11 +89,15 @@ dossh -oStrictHostKeyChecking=yes -oHost
# Check that other keys learned
expect_nkeys $nkeys "learn hostkeys"
for k in $SSH_HOSTKEY_TYPES; do
+ [ "$k" == "ssh-rsa" ] && continue
+ [ "$k" == "ssh-dss" ] && continue
check_key_present $k || fail "didn't learn keytype $k"
done
# Check each key type
for k in $SSH_HOSTKEY_TYPES; do
+ [ "$k" == "ssh-rsa" ] && continue
+ [ "$k" == "ssh-dss" ] && continue
verbose "learn additional hostkeys, type=$k"
dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs
expect_nkeys $nkeys "learn hostkeys $k"

View File

@ -51,9 +51,9 @@
# Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1
%global openssh_ver 8.8p1 %global openssh_ver 8.8p1
%global openssh_rel 3 %global openssh_rel 4
%global pam_ssh_agent_ver 0.10.4 %global pam_ssh_agent_ver 0.10.4
%global pam_ssh_agent_rel 5 %global pam_ssh_agent_rel 6
Summary: An open source implementation of SSH protocol version 2 Summary: An open source implementation of SSH protocol version 2
Name: openssh Name: openssh
@ -102,6 +102,8 @@ Patch306: pam_ssh_agent_auth-0.10.2-compat.patch
# Fix NULL dereference from getpwuid() return value # Fix NULL dereference from getpwuid() return value
# https://sourceforge.net/p/pamsshagentauth/bugs/22/ # https://sourceforge.net/p/pamsshagentauth/bugs/22/
Patch307: pam_ssh_agent_auth-0.10.2-dereference.patch Patch307: pam_ssh_agent_auth-0.10.2-dereference.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2070113
Patch308: pam_ssh_agent_auth-0.10.4-rsasha2.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX)
Patch400: openssh-7.8p1-role-mls.patch Patch400: openssh-7.8p1-role-mls.patch
@ -197,6 +199,62 @@ Patch975: openssh-8.0p1-preserve-pam-errors.patch
Patch976: openssh-8.7p1-sftp-default-protocol.patch Patch976: openssh-8.7p1-sftp-default-protocol.patch
# Implement kill switch for SCP protocol # Implement kill switch for SCP protocol
Patch977: openssh-8.7p1-scp-kill-switch.patch Patch977: openssh-8.7p1-scp-kill-switch.patch
# Create non-existent directories when scp works in sftp mode and some more minor fixes
# upstream commits:
# ba61123eef9c6356d438c90c1199a57a0d7bcb0a
# 63670d4e9030bcee490d5a9cce561373ac5b3b23
# ac7c9ec894ed0825d04ef69c55babb49bab1d32e
Patch980: openssh-8.7p1-sftpscp-dir-create.patch
# Workaround for lack of sftp_realpath in older versions of RHEL
# https://bugzilla.redhat.com/show_bug.cgi?id=2038854
# https://github.com/openssh/openssh-portable/pull/299
# downstream only
Patch981: openssh-8.7p1-recursive-scp.patch
# https://github.com/djmdjm/openssh-wip/pull/13
Patch982: openssh-8.7p1-minrsabits.patch
# downstream only
Patch983: openssh-8.7p1-evpgenkey.patch
# downstream only, IBMCA tentative fix
# From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14
Patch984: openssh-8.7p1-ibmca.patch
# Minimize the use of SHA1 as a proof of possession for RSA key (#2031868)
# upstream commits:
# 291721bc7c840d113a49518f3fca70e86248b8e8
# 0fa33683223c76289470a954404047bc762be84c
Patch1000: openssh-8.7p1-minimize-sha1-use.patch
# Fix for scp clearing file when src and dest are the same (#2056884)
# upstream commits:
# 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee
Patch1001: openssh-8.7p1-scp-clears-file.patch
# Add missing options from ssh_config into ssh manpage
# upstream bug:
# https://bugzilla.mindrot.org/show_bug.cgi?id=3455
Patch1002: openssh-8.7p1-ssh-manpage.patch
# Always return allocated strings from the kex filtering so that we can free them
# upstream commits:
# 486c4dc3b83b4b67d663fb0fa62bc24138ec3946
# 6c31ba10e97b6953c4f325f526f3e846dfea647a
# 322964f8f2e9c321e77ebae1e4d2cd0ccc5c5a0b
Patch1003: openssh-8.7p1-mem-leak.patch
# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures
# upstream MR:
# https://github.com/openssh-gsskex/openssh-gsskex/pull/21
Patch1004: openssh-8.7p1-gssapi-auth.patch
# Fix host-based authentication with rsa keys
# upstream commits:
# 7aa7b096cf2bafe2777085abdeed5ce00581f641
# d9dbb5d9a0326e252d3c7bc13beb9c2434f59409
# fdb1d58d0d3888b042e5a500f6ce524486aaf782
Patch1005: openssh-8.7p1-host-based-auth.patch
# Don't propose disallowed algorithms during hostkey negotiation
# upstream MR:
# https://github.com/openssh/openssh-portable/pull/323
Patch1006: openssh-8.7p1-negotiate-supported-algs.patch
# downstream only
# we skip some ssh-rsa/ssh-dss tests to make native test suite pass
Patch1100: openssh-8.8p1-skip-some-tests.patch
License: BSD License: BSD
Requires: /sbin/nologin Requires: /sbin/nologin
@ -325,6 +383,7 @@ pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
%patch306 -p2 -b .psaa-compat %patch306 -p2 -b .psaa-compat
%patch305 -p2 -b .psaa-agent %patch305 -p2 -b .psaa-agent
%patch307 -p2 -b .psaa-deref %patch307 -p2 -b .psaa-deref
%patch308 -p2 -b .rsasha2
# Remove duplicate headers and library files # Remove duplicate headers and library files
rm -f $(cat %{SOURCE5}) rm -f $(cat %{SOURCE5})
popd popd
@ -375,11 +434,26 @@ popd
%patch975 -p1 -b .preserve-pam-errors %patch975 -p1 -b .preserve-pam-errors
%patch976 -p1 -b .sftp-by-default %patch976 -p1 -b .sftp-by-default
%patch977 -p1 -b .kill-scp %patch977 -p1 -b .kill-scp
%patch980 -p1 -b .sftpdirs
%patch981 -p1 -b .scp-sftpdirs
%patch982 -p1 -b .minrsabits
%patch983 -p1 -b .evpgenrsa
%patch984 -p1 -b .ibmca
%patch200 -p1 -b .audit %patch200 -p1 -b .audit
%patch201 -p1 -b .audit-race %patch201 -p1 -b .audit-race
%patch700 -p1 -b .fips %patch700 -p1 -b .fips
%patch1000 -p1 -b .minimize-sha1-use
%patch1001 -p1 -b .scp-clears-file
%patch1002 -p1 -b .ssh-manpage
%patch1003 -p1 -b .mem-leak
%patch1004 -p1 -b .gssapi-auth
%patch1005 -p1 -b .host-based-auth
%patch1006 -p1 -b .negotiate-supported-algs
%patch1100 -p1 -b .skipsshrsadsstests
%patch100 -p1 -b .coverity %patch100 -p1 -b .coverity
autoreconf autoreconf
@ -661,6 +735,9 @@ test -f %{sysconfig_anaconda} && \
%endif %endif
%changelog %changelog
* Wed Aug 10 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.8p1-4 + 0.10.4-6
- Port patches from CentOS (rhbz#2117264)
* Mon Aug 01 2022 Luca BRUNO <lucab@lucabruno.net> - 8.8p1-3 * Mon Aug 01 2022 Luca BRUNO <lucab@lucabruno.net> - 8.8p1-3
- Use allocated static GID for 'ssh_keys' group (rhbz#2104595) - Use allocated static GID for 'ssh_keys' group (rhbz#2104595)

View File

@ -0,0 +1,19 @@
diff -up openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.rsasha2 openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c
--- openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.rsasha2 2022-07-15 15:08:12.865585410 +0200
+++ openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c 2022-07-15 15:16:25.164282372 +0200
@@ -87,8 +87,13 @@ userauth_pubkey_from_id(const char *ruse
(r = sshbuf_put_string(b, pkblob, blen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
- if (ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) != 0)
- goto user_auth_clean_exit;
+ if (sshkey_type_plain(id->key->type) == KEY_RSA
+ && ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), "rsa-sha2-256", 0) == 0) {
+ /* Do nothing */
+ } else {
+ if (ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) != 0)
+ goto user_auth_clean_exit;
+ }
/* test for correct signature */
if (sshkey_verify(id->key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0, NULL) == 0)