openssh: sync with latest SRPM

This commit is contained in:
Raven 2024-02-28 17:40:12 +06:00
parent 9cef763b26
commit 4c7dfeee1b
56 changed files with 3920 additions and 3623 deletions

View File

@ -1,12 +1,14 @@
diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c
--- openssh-5.8p2/ssh-keyscan.c.sigpipe 2011-08-23 18:30:33.873025916 +0200
+++ openssh-5.8p2/ssh-keyscan.c 2011-08-23 18:32:24.574025362 +0200
@@ -715,6 +715,8 @@ main(int argc, char **argv)
@@ -715,6 +715,9 @@ main(int argc, char **argv)
if (maxfd > fdlim_get(0))
fdlim_set(maxfd);
fdcon = xcalloc(maxfd, sizeof(con));
+
+ signal(SIGPIPE, SIG_IGN);
+
read_wait_nfdset = howmany(maxfd, NFDBITS);
read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask));
read_wait = xcalloc(maxfd, sizeof(struct pollfd));
for (j = 0; j < maxfd; j++)
read_wait[j].fd = -1;

View File

@ -1,101 +0,0 @@
diff -up openssh-5.9p1/cipher-ctr.c.ctr-evp openssh-5.9p1/cipher-ctr.c
--- openssh-5.9p1/cipher-ctr.c.ctr-evp 2012-01-11 09:24:06.000000000 +0100
+++ openssh-5.9p1/cipher-ctr.c 2012-01-11 15:54:04.675956600 +0100
@@ -38,7 +38,7 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, in
struct ssh_aes_ctr_ctx
{
- AES_KEY aes_ctx;
+ EVP_CIPHER_CTX ecbctx;
u_char aes_counter[AES_BLOCK_SIZE];
};
@@ -63,21 +63,42 @@ ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char
{
struct ssh_aes_ctr_ctx *c;
size_t n = 0;
- u_char buf[AES_BLOCK_SIZE];
+ u_char ctrbuf[AES_BLOCK_SIZE*256];
+ u_char buf[AES_BLOCK_SIZE*256];
if (len == 0)
return (1);
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
return (0);
- while ((len--) > 0) {
+ for (; len > 0; len -= sizeof(u_int)) {
+ u_int r,a,b;
+
if (n == 0) {
- AES_encrypt(c->aes_counter, buf, &c->aes_ctx);
- ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
+ int outl, i, buflen;
+
+ buflen = MIN(len, sizeof(ctrbuf));
+
+ for(i = 0; i < buflen; i += AES_BLOCK_SIZE) {
+ memcpy(&ctrbuf[i], c->aes_counter, AES_BLOCK_SIZE);
+ ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
+ }
+
+ EVP_EncryptUpdate(&c->ecbctx, buf, &outl,
+ ctrbuf, buflen);
}
- *(dest++) = *(src++) ^ buf[n];
- n = (n + 1) % AES_BLOCK_SIZE;
+
+ memcpy(&a, src, sizeof(a));
+ memcpy(&b, &buf[n], sizeof(b));
+ r = a ^ b;
+ memcpy(dest, &r, sizeof(r));
+ src += sizeof(a);
+ dest += sizeof(r);
+
+ n = (n + sizeof(b)) % sizeof(buf);
}
+ memset(ctrbuf, '\0', sizeof(ctrbuf));
+ memset(buf, '\0', sizeof(buf));
return (1);
}
@@ -91,9 +112,28 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, co
c = xmalloc(sizeof(*c));
EVP_CIPHER_CTX_set_app_data(ctx, c);
}
- if (key != NULL)
- AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
- &c->aes_ctx);
+
+ EVP_CIPHER_CTX_init(&c->ecbctx);
+
+ if (key != NULL) {
+ const EVP_CIPHER *cipher;
+ switch(EVP_CIPHER_CTX_key_length(ctx)*8) {
+ case 128:
+ cipher = EVP_aes_128_ecb();
+ break;
+ case 192:
+ cipher = EVP_aes_192_ecb();
+ break;
+ case 256:
+ cipher = EVP_aes_256_ecb();
+ break;
+ default:
+ fatal("ssh_aes_ctr_init: wrong aes key length");
+ }
+ if(!EVP_EncryptInit_ex(&c->ecbctx, cipher, NULL, key, NULL))
+ fatal("ssh_aes_ctr_init: cannot initialize aes encryption");
+ EVP_CIPHER_CTX_set_padding(&c->ecbctx, 0);
+ }
if (iv != NULL)
memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
return (1);
@@ -105,6 +145,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
struct ssh_aes_ctr_ctx *c;
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+ EVP_CIPHER_CTX_cleanup(&c->ecbctx);
memset(c, 0, sizeof(*c));
free(c);
EVP_CIPHER_CTX_set_app_data(ctx, NULL);

View File

@ -207,8 +207,8 @@ diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c
-sftp_server_main(int argc, char **argv, struct passwd *user_pw)
+sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler)
{
fd_set *rset, *wset;
int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0;
int i, r, in, out, ch, skipargs = 0, log_stderr = 0;
ssize_t len, olen;
@@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv,
extern char *__progname;

View File

@ -1,7 +1,7 @@
diff -up openssh/sshd.c.ip-opts openssh/sshd.c
--- openssh/sshd.c.ip-opts 2016-07-25 13:58:48.998507834 +0200
+++ openssh/sshd.c 2016-07-25 14:01:28.346469878 +0200
@@ -1507,12 +1507,29 @@ check_ip_options(struct ssh *ssh)
@@ -1507,12 +1507,32 @@ check_ip_options(struct ssh *ssh)
if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts,
&option_size) >= 0 && option_size != 0) {
@ -21,11 +21,14 @@ diff -up openssh/sshd.c.ip-opts openssh/sshd.c
+ case 130:
+ case 133:
+ case 134:
+ i += opts[i + 1];
+ break;
+ if (i + 1 < option_size && opts[i + 1] >= 2) {
+ i += opts[i + 1];
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ /* Fail, fatally, if we detect either loose or strict
+ * source routing options. */
+ * or incorrect source routing options. */
+ text[0] = '\0';
+ for (i = 0; i < option_size; i++)
+ snprintf(text + i*3, sizeof(text) - i*3,

View File

@ -61,13 +61,13 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in
ssh-xmss.o \
@@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2)
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)
+ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o
+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
+
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS)
@@ -321,6 +325,7 @@ install-files:
$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)

View File

@ -1,31 +0,0 @@
diff -up openssh-8.2p1/authfile.c.keyperm openssh-8.2p1/authfile.c
--- openssh-8.2p1/authfile.c.keyperm 2020-02-14 01:40:54.000000000 +0100
+++ openssh-8.2p1/authfile.c 2020-02-17 11:55:12.841729758 +0100
@@ -31,6 +31,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <grp.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
@@ -101,7 +102,19 @@ sshkey_perm_ok(int fd, const char *filen
#ifdef HAVE_CYGWIN
if (check_ntsec(filename))
#endif
+
if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
+ if (st.st_mode & 040) {
+ struct group *gr;
+
+ if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid)) {
+ /* The only additional bit is read
+ * for ssh_keys group, which is fine */
+ if ((st.st_mode & 077) == 040 ) {
+ return 0;
+ }
+ }
+ }
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");

View File

@ -155,8 +155,8 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c
* because if they are on a krb5-protected filesystem, user credentials
* to access these files aren't available yet. */
- if (krb5_kuserok(krb_context, princ, name) && k5login_exists) {
+ if (ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)
+ && k5login_exists) {
+ if (k5login_exists &&
+ ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)) {
retval = 1;
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
name, (char *)client->displayname.value);

View File

@ -1,37 +1,3 @@
diff -up openssh-8.5p1/addr.c.coverity openssh-8.5p1/addr.c
--- openssh-8.5p1/addr.c.coverity 2021-03-02 11:31:47.000000000 +0100
+++ openssh-8.5p1/addr.c 2021-03-24 12:03:33.782968159 +0100
@@ -312,8 +312,10 @@ addr_pton(const char *p, struct xaddr *n
if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0)
return -1;
- if (ai == NULL || ai->ai_addr == NULL)
+ if (ai == NULL || ai->ai_addr == NULL) {
+ freeaddrinfo(ai);
return -1;
+ }
if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen,
n) == -1) {
@@ -336,12 +338,16 @@ addr_sa_pton(const char *h, const char *
if (h == NULL || getaddrinfo(h, s, &hints, &ai) != 0)
return -1;
- if (ai == NULL || ai->ai_addr == NULL)
+ if (ai == NULL || ai->ai_addr == NULL) {
+ freeaddrinfo(ai);
return -1;
+ }
if (sa != NULL) {
- if (slen < ai->ai_addrlen)
+ if (slen < ai->ai_addrlen) {
+ freeaddrinfo(ai);
return -1;
+ }
memcpy(sa, &ai->ai_addr, ai->ai_addrlen);
}
diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c
--- openssh-8.5p1/auth-krb5.c.coverity 2021-03-24 12:03:33.724967756 +0100
+++ openssh-8.5p1/auth-krb5.c 2021-03-24 12:03:33.782968159 +0100
@ -62,72 +28,6 @@ diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c
return 0;
}
diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c
--- openssh-7.4p1/channels.c.coverity 2016-12-23 16:40:26.881788686 +0100
+++ openssh-7.4p1/channels.c 2016-12-23 16:42:36.244818763 +0100
@@ -1875,7 +1875,7 @@ channel_post_connecting(struct ssh *ssh,
debug("channel %d: connection failed: %s",
c->self, strerror(err));
/* Try next address, if any */
- if ((sock = connect_next(&c->connect_ctx)) > 0) {
+ if ((sock = connect_next(&c->connect_ctx)) >= 0) {
close(c->sock);
c->sock = c->rfd = c->wfd = sock;
channel_find_maxfd(ssh->chanctxt);
@@ -3804,7 +3804,7 @@ int
channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd)
{
int r, success = 0, idx = -1;
- char *host_to_connect, *listen_host, *listen_path;
+ char *host_to_connect = NULL, *listen_host = NULL, *listen_path = NULL;
int port_to_connect, listen_port;
/* Send the forward request to the remote side. */
@@ -3832,7 +3832,6 @@ channel_request_remote_forwarding(struct
success = 1;
if (success) {
/* Record that connection to this host/port is permitted. */
- host_to_connect = listen_host = listen_path = NULL;
port_to_connect = listen_port = 0;
if (fwd->connect_path != NULL) {
host_to_connect = xstrdup(fwd->connect_path);
@@ -3853,6 +3852,9 @@ channel_request_remote_forwarding(struct
host_to_connect, port_to_connect,
listen_host, listen_path, listen_port, NULL);
}
+ free(host_to_connect);
+ free(listen_host);
+ free(listen_path);
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
--- 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
@@ -282,6 +282,7 @@ verify_host_key_dns(const char *hostname
&hostkey_digest, &hostkey_digest_len, hostkey)) {
error("Error calculating key fingerprint.");
freerrset(fingerprints);
+ free(dnskey_digest);
return -1;
}
diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c
--- openssh-8.5p1/gss-genr.c.coverity 2021-03-26 11:52:46.613942552 +0100
+++ openssh-8.5p1/gss-genr.c 2021-03-26 11:54:37.881726318 +0100
@ -243,17 +143,6 @@ diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c
return ret;
}
diff -up openssh-8.5p1/moduli.c.coverity openssh-8.5p1/moduli.c
--- openssh-8.5p1/moduli.c.coverity 2021-03-02 11:31:47.000000000 +0100
+++ openssh-8.5p1/moduli.c 2021-03-24 12:03:33.784968173 +0100
@@ -476,6 +476,7 @@ write_checkpoint(char *cpfile, u_int32_t
else
logit("failed to write to checkpoint file '%s': %s", cpfile,
strerror(errno));
+ /* coverity[leaked_storage : FALSE] */
}
static unsigned long
diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c
--- openssh-7.4p1/monitor.c.coverity 2016-12-23 16:40:26.888788688 +0100
+++ openssh-7.4p1/monitor.c 2016-12-23 16:40:26.900788691 +0100
@ -389,24 +278,6 @@ diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c
if (tun != SSH_TUNID_ANY &&
auth_opts->force_tun_device != (int)tun)
goto done;
diff -up openssh-8.5p1/session.c.coverity openssh-8.5p1/session.c
--- openssh-8.5p1/session.c.coverity 2021-03-24 12:03:33.777968124 +0100
+++ openssh-8.5p1/session.c 2021-03-24 12:03:33.786968187 +0100
@@ -1223,12 +1223,14 @@ do_setup_env(struct ssh *ssh, Session *s
/* Environment specified by admin */
for (i = 0; i < options.num_setenv; i++) {
cp = xstrdup(options.setenv[i]);
+ /* coverity[overwrite_var : FALSE] */
if ((value = strchr(cp, '=')) == NULL) {
/* shouldn't happen; vars are checked in servconf.c */
fatal("Invalid config SetEnv: %s", options.setenv[i]);
}
*value++ = '\0';
child_set_env(&env, &envsize, cp, value);
+ free(cp);
}
/* SSH_CLIENT deprecated */
diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
--- openssh-7.4p1/sftp.c.coverity 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/sftp.c 2016-12-23 16:40:26.903788691 +0100
@ -419,34 +290,6 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
}
_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
if (lflag & LS_LONG_VIEW) {
if (g.gl_statv[i] == NULL) {
error("no stat information for %s", fname);
+ free(fname);
continue;
}
lname = ls_file(fname, g.gl_statv[i], 1,
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 2021-03-24 12:03:33.786968187 +0100
@@ -1256,6 +1256,7 @@ sk_load_resident_keys(const char *pin, s
freezero(rks[i], sizeof(*rks[i]));
}
free(rks);
+ free(device);
return ret;
}
diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c
--- openssh-7.4p1/ssh-agent.c.coverity 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/ssh-agent.c 2016-12-23 16:40:26.903788691 +0100
@ -495,25 +338,6 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
return 0;
}
@@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so
explicit_bzero(rnd, sizeof(rnd));
}
}
+
+ if (fdset != NULL)
+ free(fdset);
}
/*
@@ -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)
if (newstr)
@ -540,32 +364,3 @@ diff -up openssh-8.5p1/ssh-keygen.c.coverity openssh-8.5p1/ssh-keygen.c
} else {
if (strncasecmp(cp, "key:", 4) == 0) {
cp += 4;
@@ -2879,6 +2882,7 @@ do_moduli_screen(const char *out_file, c
} else if (strncmp(opts[i], "start-line=", 11) == 0) {
start_lineno = strtoul(opts[i]+11, NULL, 10);
} else if (strncmp(opts[i], "checkpoint=", 11) == 0) {
+ free(checkpoint);
checkpoint = xstrdup(opts[i]+11);
} else if (strncmp(opts[i], "generator=", 10) == 0) {
generator_wanted = (u_int32_t)strtonum(
@@ -2920,6 +2924,9 @@ do_moduli_screen(const char *out_file, c
#else /* WITH_OPENSSL */
fatal("Moduli screening is not supported");
#endif /* WITH_OPENSSL */
+ free(checkpoint);
+ if (in != stdin)
+ fclose(in);
}
static char *
diff -up openssh-8.5p1/sshsig.c.coverity openssh-8.5p1/sshsig.c
--- openssh-8.5p1/sshsig.c.coverity 2021-03-02 11:31:47.000000000 +0100
+++ openssh-8.5p1/sshsig.c 2021-03-24 12:03:33.787968194 +0100
@@ -515,6 +515,7 @@ hash_file(int fd, const char *hashalg, s
oerrno = errno;
error_f("read: %s", strerror(errno));
ssh_digest_free(ctx);
+ ctx = NULL;
errno = oerrno;
r = SSH_ERR_SYSTEM_ERROR;
goto out;

View File

@ -10,8 +10,8 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c
+/* Minimum port number for X11 forwarding */
+#define X11_PORT_MIN 6000
/* Per-channel callback for pre/post select() actions */
typedef void chan_fn(struct ssh *, Channel *c,
/* Per-channel callback for pre/post IO actions */
typedef void chan_fn(struct ssh *, Channel *c);
@@ -4228,7 +4228,7 @@ channel_send_window_changes(void)
*/
int
@ -82,7 +82,7 @@ diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h
+++ openssh-7.4p1/channels.h 2016-12-23 15:46:32.139506636 +0100
@@ -293,7 +293,7 @@ int permitopen_port(const char *);
void channel_set_x11_refuse_time(struct ssh *, u_int);
void channel_set_x11_refuse_time(struct ssh *, time_t);
int x11_connect_display(struct ssh *);
-int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);
+int x11_create_display_inet(struct ssh *, int, int, int, int, u_int *, int **);
@ -191,8 +191,8 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5
--- openssh-7.4p1/sshd_config.5.x11max 2016-12-23 15:46:32.134506635 +0100
+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:46:32.141506636 +0100
@@ -1133,6 +1133,7 @@ Available keywords are
.Cm StreamLocalBindUnlink ,
.Cm TrustedUserCAKeys ,
.Cm UnusedConnectionTimeout ,
.Cm X11DisplayOffset ,
+.Cm X11MaxDisplays ,
.Cm X11Forwarding

View File

@ -9,8 +9,8 @@ index 2ffc369..162ce92 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4265,6 +4265,30 @@ AC_ARG_WITH([kerberos5],
AC_SUBST([GSSLIBS])
AC_SUBST([K5LIBS])
AC_SUBST([CHANNELLIBS])
+# Check whether user wants systemd support
+SYSTEMD_MSG="no"

View File

@ -21,7 +21,7 @@ index ca75cc7..6e7de31 100644
+ SC_ALLOW(__NR_flock),
+#endif
#ifdef __NR_futex
SC_ALLOW(__NR_futex),
SC_FUTEX(__NR_futex),
#endif
@@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = {
#ifdef __NR_gettimeofday

View File

@ -729,7 +729,7 @@ diff -up openssh-8.6p1/auth2.c.audit openssh-8.6p1/auth2.c
--- openssh-8.6p1/auth2.c.audit 2021-04-19 16:47:35.682061561 +0200
+++ openssh-8.6p1/auth2.c 2021-04-19 16:47:35.754062114 +0200
@@ -298,9 +298,6 @@ input_userauth_request(int type, u_int32
} else {
authctxt->valid = 0;
/* Invalid user, fake password information */
authctxt->pw = fakepw();
-#ifdef SSH_AUDIT_EVENTS
@ -802,8 +802,8 @@ diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c
+}
+
static int
match_principals_option(const char *principal_list, struct sshkey_cert *cert)
{
match_principals_file(struct passwd *pw, char *file,
struct sshkey_cert *cert, struct sshauthopt **authoptsp)
diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c
--- openssh-8.6p1/auth.c.audit 2021-04-19 16:47:35.681061553 +0200
+++ openssh-8.6p1/auth.c 2021-04-19 16:47:35.754062114 +0200
@ -820,15 +820,6 @@ diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c
diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h
--- openssh-8.6p1/auth.h.audit 2021-04-19 16:47:35.697061676 +0200
+++ openssh-8.6p1/auth.h 2021-04-19 16:47:35.754062114 +0200
@@ -193,6 +193,8 @@ struct passwd * getpwnamallow(struct ssh
char *expand_authorized_keys(const char *, struct passwd *pw);
char *authorized_principals_file(struct passwd *);
+int user_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t,
+ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
FILE *auth_openkeyfile(const char *, struct passwd *, int);
FILE *auth_openprincipals(const char *, struct passwd *, int);
@@ -212,6 +214,8 @@ struct sshkey *get_hostkey_private_by_ty
int get_hostkey_index(struct sshkey *, int, struct ssh *);
int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *,
@ -838,6 +829,15 @@ diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h
/* Key / cert options linkage to auth layer */
const struct sshauthopt *auth_options(struct ssh *);
@@ -239,6 +241,8 @@ struct passwd * getpwnamallow(struct ssh
char *, const char *, const char *, const char *, struct sshauthopt **);
int auth_check_authkeys_file(struct passwd *, FILE *, char *,
struct sshkey *, const char *, const char *, struct sshauthopt **);
+int user_key_verify(struct ssh *, const struct sshkey *, const u_char *, size_t,
+ const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
FILE *auth_openkeyfile(const char *, struct passwd *, int);
FILE *auth_openprincipals(const char *, struct passwd *, int);
diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c
--- openssh-8.6p1/cipher.c.audit 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/cipher.c 2021-04-19 16:47:35.755062122 +0200
@ -910,9 +910,9 @@ diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c
--- openssh-8.6p1/kex.c.audit 2021-04-19 16:47:35.743062030 +0200
+++ openssh-8.6p1/kex.c 2021-04-19 16:47:35.755062122 +0200
@@ -65,6 +65,7 @@
#include "ssherr.h"
#include "sshbuf.h"
#include "digest.h"
#include "xmalloc.h"
+#include "audit.h"
#ifdef GSSAPI
@ -1195,9 +1195,9 @@ diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c
- ret = sshkey_verify(key, signature, signaturelen, data, datalen,
- sigalg, ssh->compat, &sig_details);
debug3_f("%s %s signature %s%s%s", auth_method, sshkey_type(key),
debug3_f("%s %s signature using %s %s%s%s", auth_method,
sshkey_type(key), sigalg == NULL ? "default" : sigalg,
(ret == 0) ? "verified" : "unverified",
(ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : "");
@@ -1576,13 +1600,19 @@ mm_record_login(struct ssh *ssh, Session
}
@ -2006,7 +2006,7 @@ diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h
@@ -71,10 +77,12 @@ void session_unused(int);
int session_input_channel_req(struct ssh *, Channel *, const char *);
void session_close_by_pid(struct ssh *ssh, pid_t, int);
void session_close_by_channel(struct ssh *, int, void *);
void session_close_by_channel(struct ssh *, int, int, void *);
-void session_destroy_all(struct ssh *, void (*)(Session *));
+void session_destroy_all(struct ssh *, void (*)(struct ssh*, Session *));
void session_pty_cleanup2(Session *);
@ -2040,7 +2040,7 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
static char *listener_proctitle;
@@ -279,6 +280,15 @@ close_listen_socks(void)
num_listen_socks = -1;
num_listen_socks = 0;
}
+/*
@ -2049,16 +2049,16 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
+ */
+int listening_for_clients(void)
+{
+ return num_listen_socks >= 0;
+ return num_listen_socks > 0;
+}
+
static void
close_startup_pipes(void)
{
@@ -377,18 +387,45 @@ grace_alarm_handler(int sig)
}
ssh_remote_port(the_active_state));
}
-/* Destroy the host and server keys. They will no longer be needed. */
+/*
+ * Destroy the host and server keys. They will no longer be needed. Careful,
@ -2196,8 +2196,8 @@ diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c
-server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
+server_accept_loop(struct ssh *ssh, int *sock_in, int *sock_out, int *newsock, int *config_s)
{
fd_set *fdset;
int i, j, ret, maxfd;
struct pollfd *pfd = NULL;
int i, j, ret, npfd;
@@ -1204,6 +1259,7 @@ server_accept_loop(int *sock_in, int *so
if (received_sigterm) {
logit("Received signal %d; terminating.",

View File

@ -1,25 +1,20 @@
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
--- 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-05-06 12:12:10.107634472 +0200
@@ -36,6 +36,7 @@
#include <openssl/bn.h>
#include <openssl/dh.h>
+#include <openssl/fips.h>
#include "dh.h"
#include "pathnames.h"
@@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max
int best, bestcount, which, linenum;
struct dhgroup dhg;
+ 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.");
+ return (dh_new_group_fallback(max));
+ }
@ -67,8 +62,8 @@ diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
+
#endif /* WITH_OPENSSL */
diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h
--- openssh-8.6p1/dh.h.fips 2021-04-19 16:53:03.064577862 +0200
+++ openssh-8.6p1/dh.h 2021-04-19 16:59:31.951616078 +0200
--- openssh-8.6p1/dh.h.fips 2021-05-06 12:08:36.498926877 +0200
+++ openssh-8.6p1/dh.h 2021-05-06 12:11:28.393298005 +0200
@@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int);
@ -78,8 +73,16 @@ diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h
u_int dh_estimate(int);
void dh_set_moduli_file(const char *);
diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c
--- openssh-8.6p1/kex.c.fips 2021-04-19 16:53:03.058577815 +0200
+++ openssh-8.6p1/kex.c 2021-04-19 16:53:03.065577869 +0200
--- openssh-8.6p1/kex.c.fips 2021-05-06 12:08:36.489926807 +0200
+++ openssh-8.6p1/kex.c 2021-05-06 12:08:36.498926877 +0200
@@ -39,6 +39,7 @@
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
+#include <openssl/fips.h>
#include <openssl/dh.h>
# ifdef HAVE_EVP_KDF_CTX_NEW_ID
# include <openssl/kdf.h>
@@ -203,7 +203,10 @@ kex_names_valid(const char *names)
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
@ -94,12 +97,12 @@ diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c
}
diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
--- openssh-8.6p1/kexgexc.c.fips 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/kexgexc.c 2021-04-19 16:53:03.065577869 +0200
+++ openssh-8.6p1/kexgexc.c 2021-05-06 12:08:36.498926877 +0200
@@ -28,6 +28,7 @@
#ifdef WITH_OPENSSL
+#include <openssl/crypto.h>
+#include <openssl/fips.h>
#include <sys/types.h>
#include <openssl/dh.h>
@ -116,8 +119,8 @@ diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
/* generate and send 'e', client DH public key */
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 2021-04-19 16:53:03.065577869 +0200
@@ -57,6 +57,19 @@
+++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200
@@ -57,6 +57,18 @@
"rsa-sha2-512," \
"rsa-sha2-256"
@ -127,12 +130,11 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
+ "rsa-sha2-512-cert-v01@openssh.com," \
+ "rsa-sha2-256-cert-v01@openssh.com," \
+ "ssh-rsa-cert-v01@openssh.com," \
+ "ecdsa-sha2-nistp256," \
+ "ecdsa-sha2-nistp384," \
+ "ecdsa-sha2-nistp521," \
+ "rsa-sha2-512," \
+ "rsa-sha2-256,"
+ "rsa-sha2-256"
+
#define KEX_SERVER_ENCRYPT \
"chacha20-poly1305@openssh.com," \
@ -166,8 +168,16 @@ diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
#define SSH_ALLOWED_CA_SIGALGS \
"ssh-ed25519," \
diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c
--- openssh-8.6p1/readconf.c.fips 2021-04-19 16:53:02.999577362 +0200
+++ openssh-8.6p1/readconf.c 2021-04-19 16:53:03.065577869 +0200
--- openssh-8.6p1/readconf.c.fips 2021-05-06 12:08:36.428926336 +0200
+++ openssh-8.6p1/readconf.c 2021-05-06 12:08:36.499926885 +0200
@@ -39,6 +39,7 @@
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
+#include <openssl/fips.h>
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
#else
@@ -2538,11 +2538,16 @@ fill_default_options(Options * options)
all_key = sshkey_alg_list(0, 0, 1, ',');
all_sig = sshkey_alg_list(0, 1, 1, ',');
@ -191,8 +201,8 @@ diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c
do { \
if ((r = kex_assemble_names(&options->what, \
diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c
--- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-04-19 16:53:03.034577631 +0200
+++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-04-19 16:53:03.065577869 +0200
--- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-05-06 12:08:36.463926606 +0200
+++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-05-06 12:08:36.499926885 +0200
@@ -160,6 +160,9 @@ static const struct sock_filter preauth_
#ifdef __NR_open
SC_DENY(__NR_open, EACCES),
@ -204,8 +214,16 @@ diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-secco
SC_DENY(__NR_openat, EACCES),
#endif
diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c
--- openssh-8.6p1/servconf.c.fips 2021-04-19 16:53:03.027577577 +0200
+++ openssh-8.6p1/servconf.c 2021-04-19 16:53:03.066577877 +0200
--- openssh-8.6p1/servconf.c.fips 2021-05-06 12:08:36.455926545 +0200
+++ openssh-8.6p1/servconf.c 2021-05-06 12:08:36.500926893 +0200
@@ -38,6 +38,7 @@
#include <limits.h>
#include <stdarg.h>
#include <errno.h>
+#include <openssl/fips.h>
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
@@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o)
all_key = sshkey_alg_list(0, 0, 1, ',');
all_sig = sshkey_alg_list(0, 1, 1, ',');
@ -229,13 +247,13 @@ diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c
do { \
if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c
--- openssh-8.6p1/ssh.c.fips 2021-04-19 16:53:03.038577662 +0200
+++ openssh-8.6p1/ssh.c 2021-04-19 16:53:03.066577877 +0200
--- openssh-8.6p1/ssh.c.fips 2021-05-06 12:08:36.467926637 +0200
+++ openssh-8.6p1/ssh.c 2021-05-06 12:08:36.500926893 +0200
@@ -77,6 +77,7 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#endif
+#include <openssl/crypto.h>
+#include <openssl/fips.h>
#include "openbsd-compat/openssl-compat.h"
#include "openbsd-compat/sys-queue.h"
@ -251,13 +269,13 @@ diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c
if (options.sk_provider != NULL && *options.sk_provider == '$' &&
strlen(options.sk_provider) > 1) {
diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c
--- openssh-8.6p1/sshconnect2.c.fips 2021-04-19 16:53:03.055577792 +0200
+++ openssh-8.6p1/sshconnect2.c 2021-04-19 16:53:03.066577877 +0200
--- openssh-8.6p1/sshconnect2.c.fips 2021-05-06 12:08:36.485926777 +0200
+++ openssh-8.6p1/sshconnect2.c 2021-05-06 12:08:36.501926900 +0200
@@ -45,6 +45,8 @@
#include <vis.h>
#endif
+#include <openssl/crypto.h>
+#include <openssl/fips.h>
+
#include "openbsd-compat/sys-queue.h"
@ -332,10 +350,10 @@ diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c
}
#endif
diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
--- openssh-8.6p1/sshd.c.fips 2021-04-19 16:53:03.060577831 +0200
+++ openssh-8.6p1/sshd.c 2021-04-19 16:57:45.827769340 +0200
--- openssh-8.6p1/sshd.c.fips 2021-05-06 12:08:36.493926838 +0200
+++ openssh-8.6p1/sshd.c 2021-05-06 12:13:56.501492639 +0200
@@ -66,6 +66,7 @@
#include <grp.h>
#endif
#include <pwd.h>
#include <signal.h>
+#include <syslog.h>
@ -346,18 +364,24 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
#include <openssl/dh.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
+#include <openssl/crypto.h>
+#include <openssl/fips.h>
#include "openbsd-compat/openssl-compat.h"
#endif
@@ -1619,6 +1621,7 @@ main(int ac, char **av)
#endif
__progname = ssh_get_progname(av[0]);
+ OpenSSL_add_all_algorithms();
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
saved_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)
/* Reinitialize the log (because of the fork above). */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
@ -389,13 +413,13 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
if (gss && orig)
xasprintf(&newstr, "%s,%s", gss, orig);
diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
--- openssh-8.6p1/sshkey.c.fips 2021-04-19 16:53:03.061577838 +0200
+++ openssh-8.6p1/sshkey.c 2021-04-19 16:53:03.067577885 +0200
@@ -34,6 +34,7 @@
#include <openssl/evp.h>
#include <openssl/err.h>
--- openssh-8.6p1/sshkey.c.fips 2021-05-06 12:08:36.493926838 +0200
+++ openssh-8.6p1/sshkey.c 2021-05-06 12:08:36.502926908 +0200
@@ -36,6 +36,7 @@
#include <openssl/pem.h>
+#include <openssl/crypto.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
+#include <openssl/fips.h>
#endif
#include "crypto_api.h"
@ -407,18 +431,80 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
#include "ssh-sk.h"
#ifdef WITH_XMSS
@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA
}
if (!BN_set_word(f4, RSA_F4) ||
!RSA_generate_key_ex(private, bits, f4, NULL)) {
+ if (FIPS_mode())
+ logit_f("the key length might be unsupported by FIPS mode approved key generation method");
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
@@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai
impl = keyimpls[i];
if (impl->name == NULL || impl->type == KEY_NULL)
continue;
+ if (FIPS_mode()) {
+ switch (impl->type) {
+ case KEY_ED25519:
+ case KEY_ED25519_SK:
+ case KEY_ED25519_CERT:
+ case KEY_ED25519_SK_CERT:
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
if (!include_sigonly && impl->sigonly)
continue;
if ((certs_only && !impl->cert) || (plain_only && impl->cert))
@@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c
return SSH_ERR_EC_CURVE_MISMATCH;
}
+ switch (type) {
+ case KEY_ED25519:
+ 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 */
sshkey_free_contents(ret);
*ret = *k;
@@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key,
*lenp = 0;
if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ /* Fallthrough */
if ((impl = sshkey_impl_from_key(key)) == NULL)
return SSH_ERR_KEY_TYPE_UNKNOWN;
if ((r = sshkey_unshield_private(key)) != 0)
@@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key,
*detailsp = NULL;
if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
if ((impl = sshkey_impl_from_key(key)) == NULL)
return SSH_ERR_KEY_TYPE_UNKNOWN;
return impl->funcs->verify(key, sig, siglen, data, dlen,
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 2021-04-19 16:53:03.068577892 +0200
--- openssh-8.6p1/ssh-keygen.c.fips 2021-05-06 12:08:36.467926637 +0200
+++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200
@@ -20,6 +20,7 @@
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
+#include <openssl/fips.h>
#include <openssl/pem.h>
#include "openbsd-compat/openssl-compat.h"
#endif
@@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na
#endif
}
@ -426,7 +512,7 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
+ if (FIPS_mode()) {
+ if (type == KEY_DSA)
+ 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");
+ }
switch (type) {
@ -451,3 +537,142 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
if ((fd = mkstemp(prv_tmp)) == -1) {
error("Could not save your private key in %s: %s",
prv_tmp, strerror(errno));
diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c
--- openssh-9.3p1/ssh-rsa.c.evpgenrsa 2022-06-30 15:14:58.200518353 +0200
+++ openssh-9.3p1/ssh-rsa.c 2022-06-30 15:24:31.499641196 +0200
@@ -33,6 +33,7 @@
#include <openssl/err.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
+#include <openssl/fips.h>
#include <stdarg.h>
#include <string.h>
@@ -1705,6 +1707,8 @@ ssh_rsa_generate(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;
goto out;
}
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/fips.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/fips.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 *
dlen >= INT_MAX - crypto_sign_ed25519_BYTES ||
sig == NULL || siglen == 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(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;

View File

@ -15,7 +15,7 @@ diff -up openssh/ssh_config.redhat openssh/ssh_config
diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat
--- openssh/ssh_config_redhat.redhat 2020-02-13 18:13:39.180641839 +0100
+++ openssh/ssh_config_redhat 2020-02-13 18:13:39.180641839 +0100
@@ -0,0 +1,21 @@
@@ -0,0 +1,15 @@
+# The options here are in the "Match final block" to be applied as the last
+# options and could be potentially overwritten by the user configuration
+Match final all
@ -29,12 +29,6 @@ diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat
+# mode correctly we set this to yes.
+ ForwardX11Trusted yes
+
+# Send locale-related environment variables
+ SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+ SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+ SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
+ SendEnv XMODIFIERS
+
+# Uncomment this if you want to use .local domain
+# Host *.local
diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0
@ -86,14 +80,7 @@ diff -up openssh/sshd_config.redhat openssh/sshd_config
diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat
--- openssh/sshd_config_redhat.redhat 2020-02-13 18:14:02.268006439 +0100
+++ openssh/sshd_config_redhat 2020-02-13 18:19:20.765035947 +0100
@@ -0,0 +1,28 @@
+# This system is following system-wide crypto policy. The changes to
+# crypto properties (Ciphers, MACs, ...) will not have any effect in
+# this or following included files. To override some configuration option,
+# write it before this block or include it before this file.
+# Please, see manual pages for update-crypto-policies(8) and sshd_config(5).
+Include /etc/crypto-policies/back-ends/opensshserver.config
+
@@ -0,0 +1,15 @@
+SyslogFacility AUTHPRIV
+
+ChallengeResponseAuthentication no
@ -109,9 +96,14 @@ diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat
+# as it is more configurable and versatile than the built-in version.
+PrintMotd no
+
+# Accept locale-related environment variables
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
+AcceptEnv XMODIFIERS
diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat
--- openssh/sshd_config_redhat_cp.redhat 2020-02-13 18:14:02.268006439 +0100
+++ openssh/sshd_config_redhat_cp 2020-02-13 18:19:20.765035947 +0100
@@ -0,0 +1,7 @@
+# This system is following system-wide crypto policy. The changes to
+# crypto properties (Ciphers, MACs, ...) will not have any effect in
+# this or following included files. To override some configuration option,
+# write it before this block or include it before this file.
+# Please, see manual pages for update-crypto-policies(8) and sshd_config(5).
+Include /etc/crypto-policies/back-ends/opensshserver.config
+

View File

@ -3,7 +3,7 @@ diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c
+++ openssh-8.6p1/sshd.c 2021-04-19 14:03:21.140920974 +0200
@@ -1749,6 +1749,10 @@ main(int ac, char **av)
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
cfg, &includes, NULL);
cfg, &includes, NULL, rexeced_flag);
+ /* 'UsePAM no' is not supported in Fedora */
+ if (! options.use_pam)

View File

@ -93,7 +93,7 @@ diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c
(r = sshbuf_put_cstring(b, authctxt->user)) != 0 ||
+#endif
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
(r = sshbuf_put_cstring(b, "hostbased")) != 0 ||
(r = sshbuf_put_cstring(b, method)) != 0 ||
(r = sshbuf_put_string(b, pkalg, alen)) != 0 ||
diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c
--- openssh/auth2-pubkey.c.role-mls 2018-08-22 11:14:56.816430924 +0200
@ -240,14 +240,14 @@ diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c
mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
{
@@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh,
{
struct sshbuf *b;
struct sshkey *hostkey = NULL;
const u_char *p;
- char *userstyle, *cp;
+ char *userstyle, *s, *cp;
size_t len;
u_char type;
int r, fail = 0;
int hostbound = 0, r, fail = 0;
@@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh,
fail++;
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)

View File

@ -1,13 +1,13 @@
diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
--- openssh-8.7p1/ssh_config.5.crypto-policies 2021-08-30 13:29:00.174292872 +0200
+++ openssh-8.7p1/ssh_config.5 2021-08-30 13:31:32.009548808 +0200
@@ -373,17 +373,13 @@ or
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh_config.5 openssh-9.3p1-patched/ssh_config.5
--- openssh-9.3p1/ssh_config.5 2023-06-07 10:26:48.284590156 +0200
+++ openssh-9.3p1-patched/ssh_config.5 2023-06-07 10:26:00.623052194 +0200
@@ -378,17 +378,13 @@
causes no CNAMEs to be considered for canonicalization.
This is the default behaviour.
.It Cm CASignatureAlgorithms
+The default is handled system-wide by
+.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 .
+.Pp
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
.Sq +
character, then the specified algorithms will be appended to the default set
@@ -445,20 +441,25 @@ If the option is set to
@@ -450,20 +446,25 @@
(the default),
the check will not be executed.
.It Cm Ciphers
+The default is handled system-wide by
+.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 .
+.Pp
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
The supported ciphers are:
.Bd -literal -offset indent
@@ -474,13 +475,6 @@ aes256-gcm@openssh.com
@@ -479,13 +480,6 @@
chacha20-poly1305@openssh.com
.Ed
.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
.Qq ssh -Q cipher .
.It Cm ClearAllForwardings
@@ -874,6 +868,11 @@ command line will be passed untouched to
@@ -885,6 +879,11 @@
The default is
.Dq no .
.It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by
+.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 .
+.Pp
The list of key exchange algorithms that are offered for GSSAPI
key exchange. Possible values are
.Bd -literal -offset 3n
@@ -886,10 +885,8 @@ gss-nistp256-sha256-,
@@ -897,10 +896,8 @@
gss-curve25519-sha256-
.Ed
.Pp
@ -92,13 +92,76 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.It Cm HashKnownHosts
Indicates that
.Xr ssh 1
@@ -1219,29 +1216,25 @@ it may be zero or more of:
@@ -919,36 +916,25 @@
but may be manually hashed using
.Xr ssh-keygen 1 .
.It Cm HostbasedAcceptedAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 .
+.Pp
Specifies the signature algorithms that will be used for hostbased
authentication as a comma-separated list of patterns.
Alternately if the specified list begins with a
.Sq +
character, then the specified signature algorithms will be appended
-to the default set instead of replacing them.
+to the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified signature algorithms (including wildcards)
-will be removed from the default set instead of replacing them.
+will be removed from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified signature algorithms will be placed
-at the head of the default set.
-The default for this option is:
-.Bd -literal -offset 3n
-ssh-ed25519-cert-v01@openssh.com,
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-ed25519,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256
-.Ed
+at the head of the built-in openssh default set.
.Pp
The
.Fl Q
@@ -1001,6 +987,17 @@
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
+.Pp
+The proposed
+.Cm HostKeyAlgorithms
+during KEX are limited to the set of algorithms that is defined in
+.Cm PubkeyAcceptedAlgorithms
+and therefore they are indirectly affected by system-wide
+.Xr crypto_policies 7 .
+.Xr crypto_policies 7 can not handle the list of host key algorithms directly as doing so
+would break the order given by the
+.Pa known_hosts
+file.
.It Cm HostKeyAlias
Specifies an alias that should be used instead of the
real host name when looking up or saving the host key
@@ -1232,30 +1229,25 @@
and
.Cm pam .
.It Cm KexAlgorithms
+The default is handled system-wide by
+.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 .
+.Pp
Specifies the available KEX (Key Exchange) algorithms.
@ -107,7 +170,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Sq +
-character, then the specified algorithms will be appended to the default set
-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.
If the specified list begins with a
.Sq -
@ -120,6 +183,7 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
-default set.
-The default is:
-.Bd -literal -offset indent
-sntrup761x25519-sha512@openssh.com,
-curve25519-sha256,curve25519-sha256@libssh.org,
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
-diffie-hellman-group-exchange-sha256,
@ -131,13 +195,13 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Pp
The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q kex .
@@ -1351,37 +1344,33 @@ function, and all code in the
@@ -1365,37 +1357,33 @@
file.
This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
+The default is handled system-wide by
+.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 .
+.Pp
Specifies the MAC (message authentication code) algorithms
@ -178,13 +242,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
.Qq ssh -Q mac .
.It Cm NoHostAuthenticationForLocalhost
@@ -1553,36 +1542,25 @@ instead of continuing to execute and pas
@@ -1567,39 +1555,31 @@
The default is
.Cm no .
.It Cm PubkeyAcceptedAlgorithms
+The default is handled system-wide by
+.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 .
+.Pp
Specifies the signature algorithms that will be used for public key
@ -224,16 +288,33 @@ diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q PubkeyAcceptedAlgorithms .
diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
--- openssh-8.7p1/sshd_config.5.crypto-policies 2021-08-30 13:29:00.157292731 +0200
+++ openssh-8.7p1/sshd_config.5 2021-08-30 13:32:16.263918533 +0200
@@ -373,17 +373,13 @@ If the argument is
+.Pp
+This option affects also
+.Cm HostKeyAlgorithms
.It Cm PubkeyAuthentication
Specifies whether to try public key authentication.
The argument to this keyword must be
@@ -2265,7 +2245,9 @@
This file must be world-readable.
.El
.Sh SEE ALSO
-.Xr ssh 1
+.Xr ssh 1 ,
+.Xr crypto-policies 7 ,
+.Xr update-crypto-policies 8
.Sh AUTHORS
.An -nosplit
OpenSSH is a derivative of the original and free
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshd_config.5 openssh-9.3p1-patched/sshd_config.5
--- openssh-9.3p1/sshd_config.5 2023-06-07 10:26:48.277590077 +0200
+++ openssh-9.3p1-patched/sshd_config.5 2023-06-07 10:26:00.592051845 +0200
@@ -379,17 +379,13 @@
then no banner is displayed.
By default, no banner is displayed.
.It Cm CASignatureAlgorithms
+The default is handled system-wide by
+.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 .
+.Pp
Specifies which algorithms are allowed for signing of certificates
@ -250,13 +331,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
If the specified list begins with a
.Sq +
character, then the specified algorithms will be appended to the default set
@@ -450,20 +446,25 @@ The default is
@@ -525,20 +521,25 @@
indicating not to
.Xr chroot 2 .
.It Cm Ciphers
+The default is handled system-wide by
+.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 .
+.Pp
Specifies the ciphers allowed.
@ -280,7 +361,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
.Pp
The supported ciphers are:
.Pp
@@ -490,13 +491,6 @@ aes256-gcm@openssh.com
@@ -565,13 +566,6 @@
chacha20-poly1305@openssh.com
.El
.Pp
@ -294,13 +375,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
.Qq ssh -Q cipher .
.It Cm ClientAliveCountMax
@@ -685,21 +679,22 @@ For this to work
@@ -766,53 +760,43 @@
.Cm GSSAPIKeyExchange
needs to be enabled in the server and also used by the client.
.It Cm GSSAPIKexAlgorithms
+The default is handled system-wide by
+.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 .
+.Pp
The list of key exchange algorithms that are accepted by GSSAPI
@ -326,18 +407,27 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
-gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
This option only applies to connections using GSSAPI.
.It Cm HostbasedAcceptedAlgorithms
Specifies the signature algorithms that will be accepted for hostbased
@@ -799,26 +794,13 @@ is specified, the location of the socket
.Ev SSH_AUTH_SOCK
environment variable.
.It Cm HostKeyAlgorithms
+The default is handled system-wide by
+.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 .
+.Pp
Specifies the host key signature algorithms
that the server offers.
Specifies the signature algorithms that will be accepted for hostbased
authentication as a list of comma-separated patterns.
Alternately if the specified list begins with a
.Sq +
character, then the specified signature algorithms will be appended to
-the default set instead of replacing them.
+the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified signature algorithms (including wildcards)
-will be removed from the default set instead of replacing them.
+will be removed from the built-in openssh default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified signature algorithms will be placed at
-the head of the default set.
-The default for this option is:
-.Bd -literal -offset 3n
-ssh-ed25519-cert-v01@openssh.com,
@ -348,24 +438,54 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-rsa-cert-v01@openssh.com,
-ssh-ed25519,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256,ssh-rsa
-rsa-sha2-512,rsa-sha2-256
-.Ed
+the head of the built-in openssh default set.
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostbasedAcceptedAlgorithms .
@@ -879,25 +863,14 @@
.Ev SSH_AUTH_SOCK
environment variable.
.It Cm HostKeyAlgorithms
+The default is handled system-wide by
+.Xr crypto-policies 7 .
+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 .
+.Pp
Specifies the host key signature algorithms
that the server offers.
The default for this option is:
-.Bd -literal -offset 3n
-ssh-ed25519-cert-v01@openssh.com,
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
-sk-ssh-ed25519-cert-v01@openssh.com,
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-ed25519,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256
-.Ed
-.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts
@@ -965,20 +947,25 @@ Specifies whether to look at .k5login fi
@@ -1044,20 +1017,25 @@
The default is
.Cm yes .
.It Cm KexAlgorithms
+The default is handled system-wide by
+.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 .
+.Pp
Specifies the available KEX (Key Exchange) algorithms.
@ -374,7 +494,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
.Sq +
-character, then the specified algorithms will be appended to the default set
-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.
If the specified list begins with a
.Sq -
@ -389,12 +509,13 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
The supported algorithms are:
.Pp
.Bl -item -compact -offset indent
@@ -1010,15 +997,6 @@ ecdh-sha2-nistp521
@@ -1089,16 +1067,6 @@
sntrup761x25519-sha512@openssh.com
.El
.Pp
-The default is:
-.Bd -literal -offset indent
-sntrup761x25519-sha512@openssh.com,
-curve25519-sha256,curve25519-sha256@libssh.org,
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
-diffie-hellman-group-exchange-sha256,
@ -405,13 +526,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
.Qq ssh -Q KexAlgorithms .
.It Cm ListenAddress
@@ -1104,21 +1082,26 @@ function, and all code in the
@@ -1184,21 +1152,26 @@
file.
This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
+The default is handled system-wide by
+.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 .
+.Pp
Specifies the available MAC (message authentication code) algorithms.
@ -436,7 +557,7 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
.Pp
The algorithms that contain
.Qq -etm
@@ -1161,15 +1144,6 @@ umac-64-etm@openssh.com
@@ -1241,15 +1214,6 @@
umac-128-etm@openssh.com
.El
.Pp
@ -452,13 +573,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
.Qq ssh -Q mac .
.It Cm Match
@@ -1548,37 +1522,25 @@ or equivalent.)
@@ -1633,36 +1597,25 @@
The default is
.Cm yes .
.It Cm PubkeyAcceptedAlgorithms
+The default is handled system-wide by
+.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 .
+.Pp
Specifies the signature algorithms that will be accepted for public key
@ -488,14 +609,24 @@ diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
-rsa-sha2-512-cert-v01@openssh.com,
-rsa-sha2-256-cert-v01@openssh.com,
-ssh-rsa-cert-v01@openssh.com,
-ssh-ed25519,
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
-sk-ssh-ed25519@openssh.com,
-sk-ecdsa-sha2-nistp256@openssh.com,
-rsa-sha2-512,rsa-sha2-256,ssh-rsa
-rsa-sha2-512,rsa-sha2-256
-.Ed
+built-in openssh default set.
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q PubkeyAcceptedAlgorithms .
@@ -2131,7 +2084,9 @@
.El
.Sh SEE ALSO
.Xr sftp-server 8 ,
-.Xr sshd 8
+.Xr sshd 8 ,
+.Xr crypto-policies 7 ,
+.Xr update-crypto-policies 8
.Sh AUTHORS
.An -nosplit
OpenSSH is a derivative of the original and free

View File

@ -1,720 +0,0 @@
From ed7ec0cdf577ffbb0b15145340cf51596ca3eb89 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 14 May 2019 10:45:45 +0200
Subject: [PATCH] Use high-level OpenSSL API for signatures
---
digest-openssl.c | 16 ++++
digest.h | 6 ++
ssh-dss.c | 65 ++++++++++------
ssh-ecdsa.c | 69 ++++++++++-------
ssh-rsa.c | 193 +++++++++--------------------------------------
sshkey.c | 77 +++++++++++++++++++
sshkey.h | 4 +
7 files changed, 221 insertions(+), 209 deletions(-)
diff --git a/digest-openssl.c b/digest-openssl.c
index da7ed72bc..6a21d8adb 100644
--- a/digest-openssl.c
+++ b/digest-openssl.c
@@ -63,6 +63,22 @@ const struct ssh_digest digests[] = {
{ -1, NULL, 0, NULL },
};
+const EVP_MD *
+ssh_digest_to_md(int digest_type)
+{
+ switch (digest_type) {
+ case SSH_DIGEST_SHA1:
+ return EVP_sha1();
+ case SSH_DIGEST_SHA256:
+ return EVP_sha256();
+ case SSH_DIGEST_SHA384:
+ return EVP_sha384();
+ case SSH_DIGEST_SHA512:
+ return EVP_sha512();
+ }
+ return NULL;
+}
+
static const struct ssh_digest *
ssh_digest_by_alg(int alg)
{
diff --git a/digest.h b/digest.h
index 274574d0e..c7ceeb36f 100644
--- a/digest.h
+++ b/digest.h
@@ -32,6 +32,12 @@
struct sshbuf;
struct ssh_digest_ctx;
+#ifdef WITH_OPENSSL
+#include <openssl/evp.h>
+/* Converts internal digest representation to the OpenSSL one */
+const EVP_MD *ssh_digest_to_md(int digest_type);
+#endif
+
/* Looks up a digest algorithm by name */
int ssh_digest_alg_by_name(const char *name);
diff --git a/ssh-dss.c b/ssh-dss.c
index a23c383dc..ea45e7275 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -52,11 +52,15 @@ int
ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
{
+ EVP_PKEY *pkey = NULL;
DSA_SIG *sig = NULL;
const BIGNUM *sig_r, *sig_s;
- u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
- size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
+ u_char sigblob[SIGBLOB_LEN];
+ size_t rlen, slen;
+ int len;
struct sshbuf *b = NULL;
+ u_char *sigb = NULL;
+ const u_char *psig = NULL;
int ret = SSH_ERR_INVALID_ARGUMENT;
if (lenp != NULL)
@@ -67,17 +71,24 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
if (key == NULL || key->dsa == NULL ||
sshkey_type_plain(key->type) != KEY_DSA)
return SSH_ERR_INVALID_ARGUMENT;
- if (dlen == 0)
- return SSH_ERR_INTERNAL_ERROR;
- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
- digest, sizeof(digest))) != 0)
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_DSA(pkey, key->dsa) != 1)
+ return SSH_ERR_ALLOC_FAIL;
+ ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len,
+ data, datalen);
+ EVP_PKEY_free(pkey);
+ if (ret < 0) {
goto out;
+ }
- if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
+ psig = sigb;
+ if ((sig = d2i_DSA_SIG(NULL, &psig, len)) == NULL) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ free(sigb);
+ sigb = NULL;
DSA_SIG_get0(sig, &sig_r, &sig_s);
rlen = BN_num_bytes(sig_r);
@@ -110,7 +121,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
*lenp = len;
ret = 0;
out:
- explicit_bzero(digest, sizeof(digest));
+ free(sigb);
DSA_SIG_free(sig);
sshbuf_free(b);
return ret;
@@ -121,20 +132,20 @@ ssh_dss_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat)
{
+ EVP_PKEY *pkey = NULL;
DSA_SIG *sig = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL;
- u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
- size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
+ u_char *sigblob = NULL;
+ size_t len, slen;
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL;
char *ktype = NULL;
+ u_char *sigb = NULL, *psig = NULL;
if (key == NULL || key->dsa == NULL ||
sshkey_type_plain(key->type) != KEY_DSA ||
signature == NULL || signaturelen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- if (dlen == 0)
- return SSH_ERR_INTERNAL_ERROR;
/* fetch signature */
if ((b = sshbuf_from(signature, signaturelen)) == NULL)
@@ -176,25 +187,31 @@ ssh_dss_verify(const struct sshkey *key,
}
sig_r = sig_s = NULL; /* transferred */
- /* sha1 the data */
- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
- digest, sizeof(digest))) != 0)
+ if ((slen = i2d_DSA_SIG(sig, NULL)) == 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
-
- switch (DSA_do_verify(digest, dlen, sig, key->dsa)) {
- case 1:
- ret = 0;
- break;
- case 0:
- ret = SSH_ERR_SIGNATURE_INVALID;
+ }
+ if ((sigb = malloc(slen)) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
goto out;
- default:
+ }
+ psig = sigb;
+ if ((slen = i2d_DSA_SIG(sig, &psig)) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen,
+ sigb, slen);
+ EVP_PKEY_free(pkey);
+
out:
- explicit_bzero(digest, sizeof(digest));
+ free(sigb);
DSA_SIG_free(sig);
BN_clear_free(sig_r);
BN_clear_free(sig_s);
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 599c7199d..b036796e8 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -50,11 +50,13 @@ int
ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
{
+ EVP_PKEY *pkey = NULL;
ECDSA_SIG *sig = NULL;
+ unsigned char *sigb = NULL;
+ const unsigned char *psig;
const BIGNUM *sig_r, *sig_s;
int hash_alg;
- u_char digest[SSH_DIGEST_MAX_LENGTH];
- size_t len, dlen;
+ int len;
struct sshbuf *b = NULL, *bb = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
@@ -67,18 +69,24 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
sshkey_type_plain(key->type) != KEY_ECDSA)
return SSH_ERR_INVALID_ARGUMENT;
- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
- (dlen = ssh_digest_bytes(hash_alg)) == 0)
+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
return SSH_ERR_INTERNAL_ERROR;
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
- digest, sizeof(digest))) != 0)
+
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
+ return SSH_ERR_ALLOC_FAIL;
+ ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data,
+ datalen);
+ EVP_PKEY_free(pkey);
+ if (ret < 0) {
goto out;
+ }
- if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {
+ psig = sigb;
+ if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
-
if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
@@ -102,7 +110,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
*lenp = len;
ret = 0;
out:
- explicit_bzero(digest, sizeof(digest));
+ free(sigb);
sshbuf_free(b);
sshbuf_free(bb);
ECDSA_SIG_free(sig);
@@ -115,22 +123,21 @@ ssh_ecdsa_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat)
{
+ EVP_PKEY *pkey = NULL;
ECDSA_SIG *sig = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL;
- int hash_alg;
- u_char digest[SSH_DIGEST_MAX_LENGTH];
- size_t dlen;
+ int hash_alg, len;
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL, *sigbuf = NULL;
char *ktype = NULL;
+ unsigned char *sigb = NULL, *psig = NULL;
if (key == NULL || key->ecdsa == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA ||
signature == NULL || signaturelen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
- (dlen = ssh_digest_bytes(hash_alg)) == 0)
+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
return SSH_ERR_INTERNAL_ERROR;
/* fetch signature */
@@ -166,28 +173,36 @@ ssh_ecdsa_verify(const struct sshkey *key,
}
sig_r = sig_s = NULL; /* transferred */
- if (sshbuf_len(sigbuf) != 0) {
- ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
+ /* Figure out the length */
+ if ((len = i2d_ECDSA_SIG(sig, NULL)) == 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((sigb = malloc(len)) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
- digest, sizeof(digest))) != 0)
+ psig = sigb;
+ if ((len = i2d_ECDSA_SIG(sig, &psig)) == 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
+ }
- switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
- case 1:
- ret = 0;
- break;
- case 0:
- ret = SSH_ERR_SIGNATURE_INVALID;
+ if (sshbuf_len(sigbuf) != 0) {
+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
- default:
- ret = SSH_ERR_LIBCRYPTO_ERROR;
+ }
+
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) {
+ ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len);
+ EVP_PKEY_free(pkey);
out:
- explicit_bzero(digest, sizeof(digest));
+ free(sigb);
sshbuf_free(sigbuf);
sshbuf_free(b);
ECDSA_SIG_free(sig);
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 9b14f9a9a..8ef3a6aca 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -37,7 +37,7 @@
#include "openbsd-compat/openssl-compat.h"
-static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
+static int openssh_RSA_verify(int, const u_char *, size_t, u_char *, size_t, EVP_PKEY *);
static const char *
rsa_hash_alg_ident(int hash_alg)
@@ -90,21 +90,6 @@ rsa_hash_id_from_keyname(const char *alg)
return -1;
}
-static int
-rsa_hash_alg_nid(int type)
-{
- switch (type) {
- case SSH_DIGEST_SHA1:
- return NID_sha1;
- case SSH_DIGEST_SHA256:
- return NID_sha256;
- case SSH_DIGEST_SHA512:
- return NID_sha512;
- default:
- return -1;
- }
-}
-
int
ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
{
@@ -164,11 +149,10 @@ int
ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, const char *alg_ident)
{
- const BIGNUM *rsa_n;
- u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
- size_t slen = 0;
- u_int dlen, len;
- int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
+ EVP_PKEY *pkey = NULL;
+ u_char *sig = NULL;
+ int len, slen = 0;
+ int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL;
if (lenp != NULL)
@@ -180,33 +164,24 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
hash_alg = SSH_DIGEST_SHA1;
else
hash_alg = rsa_hash_id_from_keyname(alg_ident);
+
if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
sshkey_type_plain(key->type) != KEY_RSA)
return SSH_ERR_INVALID_ARGUMENT;
- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
- return SSH_ERR_KEY_LENGTH;
slen = RSA_size(key->rsa);
- if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
- return SSH_ERR_INVALID_ARGUMENT;
-
- /* hash the data */
- nid = rsa_hash_alg_nid(hash_alg);
- if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
- return SSH_ERR_INTERNAL_ERROR;
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
- digest, sizeof(digest))) != 0)
- goto out;
+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+ return SSH_ERR_KEY_LENGTH;
- if ((sig = malloc(slen)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
+ return SSH_ERR_ALLOC_FAIL;
+ ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data,
+ datalen);
+ EVP_PKEY_free(pkey);
+ if (ret < 0) {
goto out;
}
- if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
if (len < slen) {
size_t diff = slen - len;
memmove(sig + diff, sig, len);
@@ -215,6 +190,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
ret = SSH_ERR_INTERNAL_ERROR;
goto out;
}
+
/* encode signature */
if ((b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
@@ -235,7 +211,6 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
*lenp = len;
ret = 0;
out:
- explicit_bzero(digest, sizeof(digest));
freezero(sig, slen);
sshbuf_free(b);
return ret;
@@ -246,10 +221,10 @@ ssh_rsa_verify(const struct sshkey *key,
const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
const char *alg)
{
- const BIGNUM *rsa_n;
+ EVP_PKEY *pkey = NULL;
char *sigtype = NULL;
int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
- size_t len = 0, diff, modlen, dlen;
+ size_t len = 0, diff, modlen;
struct sshbuf *b = NULL;
u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
@@ -257,8 +232,7 @@ ssh_rsa_verify(const struct sshkey *key,
sshkey_type_plain(key->type) != KEY_RSA ||
sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_KEY_LENGTH;
if ((b = sshbuf_from(sig, siglen)) == NULL)
@@ -310,16 +284,15 @@ ssh_rsa_verify(const struct sshkey *key,
explicit_bzero(sigblob, diff);
len = modlen;
}
- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
- ret = SSH_ERR_INTERNAL_ERROR;
+
+ if ((pkey = EVP_PKEY_new()) == NULL ||
+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) {
+ ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
- digest, sizeof(digest))) != 0)
- goto out;
+ ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey);
+ EVP_PKEY_free(pkey);
- ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
- key->rsa);
out:
freezero(sigblob, len);
free(sigtype);
@@ -328,122 +301,26 @@ ssh_rsa_verify(const struct sshkey *key,
return ret;
}
-/*
- * See:
- * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
- * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
- */
-
-/*
- * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
- * oiw(14) secsig(3) algorithms(2) 26 }
- */
-static const u_char id_sha1[] = {
- 0x30, 0x21, /* type Sequence, length 0x21 (33) */
- 0x30, 0x09, /* type Sequence, length 0x09 */
- 0x06, 0x05, /* type OID, length 0x05 */
- 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
- 0x05, 0x00, /* NULL */
- 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
-};
-
-/*
- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
- * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
- * id-sha256(1) }
- */
-static const u_char id_sha256[] = {
- 0x30, 0x31, /* type Sequence, length 0x31 (49) */
- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
- 0x06, 0x09, /* type OID, length 0x09 */
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
- 0x05, 0x00, /* NULL */
- 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */
-};
-
-/*
- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
- * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
- * id-sha256(3) }
- */
-static const u_char id_sha512[] = {
- 0x30, 0x51, /* type Sequence, length 0x51 (81) */
- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
- 0x06, 0x09, /* type OID, length 0x09 */
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
- 0x05, 0x00, /* NULL */
- 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */
-};
-
static int
-rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
+openssh_RSA_verify(int hash_alg, const u_char *data, size_t datalen,
+ u_char *sigbuf, size_t siglen, EVP_PKEY *pkey)
{
- switch (hash_alg) {
- case SSH_DIGEST_SHA1:
- *oidp = id_sha1;
- *oidlenp = sizeof(id_sha1);
- break;
- case SSH_DIGEST_SHA256:
- *oidp = id_sha256;
- *oidlenp = sizeof(id_sha256);
- break;
- case SSH_DIGEST_SHA512:
- *oidp = id_sha512;
- *oidlenp = sizeof(id_sha512);
- break;
- default:
- return SSH_ERR_INVALID_ARGUMENT;
- }
- return 0;
-}
+ size_t rsasize = 0;
+ const RSA *rsa;
+ int ret;
-static int
-openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
- u_char *sigbuf, size_t siglen, RSA *rsa)
-{
- size_t rsasize = 0, oidlen = 0, hlen = 0;
- int ret, len, oidmatch, hashmatch;
- const u_char *oid = NULL;
- u_char *decrypted = NULL;
-
- if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
- return ret;
- ret = SSH_ERR_INTERNAL_ERROR;
- hlen = ssh_digest_bytes(hash_alg);
- if (hashlen != hlen) {
- ret = SSH_ERR_INVALID_ARGUMENT;
- goto done;
- }
+ rsa = EVP_PKEY_get0_RSA(pkey);
rsasize = RSA_size(rsa);
if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
siglen == 0 || siglen > rsasize) {
ret = SSH_ERR_INVALID_ARGUMENT;
goto done;
}
- if ((decrypted = malloc(rsasize)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto done;
- }
- if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
- RSA_PKCS1_PADDING)) < 0) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto done;
- }
- if (len < 0 || (size_t)len != hlen + oidlen) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto done;
- }
- oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
- hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
- if (!oidmatch || !hashmatch) {
- ret = SSH_ERR_SIGNATURE_INVALID;
- goto done;
- }
- ret = 0;
+
+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen,
+ sigbuf, siglen);
+
done:
- freezero(decrypted, rsasize);
return ret;
}
#endif /* WITH_OPENSSL */
diff --git a/sshkey.c b/sshkey.c
index ad1957762..b95ed0b10 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -358,6 +358,83 @@ sshkey_type_plain(int type)
}
#ifdef WITH_OPENSSL
+int
+sshkey_calculate_signature(EVP_PKEY *pkey, int hash_alg, u_char **sigp,
+ int *lenp, const u_char *data, size_t datalen)
+{
+ EVP_MD_CTX *ctx = NULL;
+ u_char *sig = NULL;
+ int ret, slen, len;
+
+ if (sigp == NULL || lenp == NULL) {
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+
+ slen = EVP_PKEY_size(pkey);
+ if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
+ return SSH_ERR_INVALID_ARGUMENT;
+
+ len = slen;
+ if ((sig = malloc(slen)) == NULL) {
+ return SSH_ERR_ALLOC_FAIL;
+ }
+
+ if ((ctx = EVP_MD_CTX_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto error;
+ }
+ if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
+ EVP_SignUpdate(ctx, data, datalen) <= 0 ||
+ EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto error;
+ }
+
+ *sigp = sig;
+ *lenp = len;
+ /* Now owned by the caller */
+ sig = NULL;
+ ret = 0;
+
+error:
+ EVP_MD_CTX_free(ctx);
+ free(sig);
+ return ret;
+}
+
+int
+sshkey_verify_signature(EVP_PKEY *pkey, int hash_alg, const u_char *data,
+ size_t datalen, u_char *sigbuf, int siglen)
+{
+ EVP_MD_CTX *ctx = NULL;
+ int ret;
+
+ if ((ctx = EVP_MD_CTX_new()) == NULL) {
+ return SSH_ERR_ALLOC_FAIL;
+ }
+ if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
+ EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto done;
+ }
+ ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
+ switch (ret) {
+ case 1:
+ ret = 0;
+ break;
+ case 0:
+ ret = SSH_ERR_SIGNATURE_INVALID;
+ break;
+ default:
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ break;
+ }
+
+done:
+ EVP_MD_CTX_free(ctx);
+ return ret;
+}
+
/* XXX: these are really begging for a table-driven approach */
int
sshkey_curve_name_to_nid(const char *name)
diff --git a/sshkey.h b/sshkey.h
index a91e60436..270901a87 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -179,6 +179,10 @@ const char *sshkey_ssh_name(const struct sshkey *);
const char *sshkey_ssh_name_plain(const struct sshkey *);
int sshkey_names_valid2(const char *, int);
char *sshkey_alg_list(int, int, int, char);
+int sshkey_calculate_signature(EVP_PKEY*, int, u_char **,
+ int *, const u_char *, size_t);
+int sshkey_verify_signature(EVP_PKEY *, int, const u_char *,
+ size_t, u_char *, int);
int sshkey_from_blob(const u_char *, size_t, struct sshkey **);
int sshkey_fromb(struct sshbuf *, struct sshkey **);

View File

@ -1,38 +0,0 @@
diff --git a/compat.c b/compat.c
index 46dfe3a9c2e..478a9403eea 100644
--- a/compat.c
+++ b/compat.c
@@ -190,26 +190,26 @@ compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop)
char *
compat_kex_proposal(struct ssh *ssh, char *p)
{
- char *cp = NULL;
+ char *cp = NULL, *cp2 = NULL;
if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
return xstrdup(p);
debug2_f("original KEX proposal: %s", p);
if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
- if ((p = match_filter_denylist(p,
+ if ((cp = 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,
+ if ((cp2 = match_filter_denylist(cp ? cp : p,
"diffie-hellman-group-exchange-sha256,"
"diffie-hellman-group-exchange-sha1")) == NULL)
fatal("match_filter_denylist failed");
free(cp);
+ cp = cp2;
}
- debug2_f("compat KEX proposal: %s", p);
- if (*p == '\0')
+ if (cp == NULL || *cp == '\0')
fatal("No supported key exchange algorithms found");
- return p;
+ debug2_f("compat KEX proposal: %s", cp);
+ return cp;
}

View File

@ -1,110 +0,0 @@
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

@ -1,20 +0,0 @@
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

@ -1,151 +0,0 @@
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);

View File

@ -4,9 +4,8 @@
#include "includes.h"
-#ifndef HAVE_CLOSEFROM
+#if (!defined HAVE_CLOSEFROM) || (defined __s390__)
-#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM)
+#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) || (defined __s390__)
#include <sys/types.h>
#include <sys/param.h>
#include <unistd.h>

View File

@ -1,156 +0,0 @@
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

@ -1,207 +0,0 @@
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 --git a/hostfile.c b/hostfile.c
index a035b381..bd49e3ac 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -642,7 +642,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
/* Re-add the requested keys */
want = HKF_MATCH_HOST | (ip == NULL ? 0 : HKF_MATCH_IP);
for (i = 0; i < nkeys; i++) {
- if ((want & ctx.match_keys[i]) == want)
+ if (keys[i] == NULL || (want & ctx.match_keys[i]) == want)
continue;
if ((fp = sshkey_fingerprint(keys[i], hash_alg,
SSH_FP_DEFAULT)) == NULL) {
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

@ -1,446 +1,24 @@
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 36b9d2f5..6b517db4 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -119,6 +119,11 @@ userauth_hostbased(struct ssh *ssh, const char *method)
"(null)" : key->cert->signature_type);
goto done;
}
+ if ((r = sshkey_check_rsa_length(key,
+ options.required_rsa_size)) != 0) {
+ logit_r(r, "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 962fd342..5d59febc 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -175,6 +175,11 @@ userauth_pubkey(struct ssh *ssh, const char *method)
"(null)" : key->cert->signature_type);
goto done;
}
+ if ((r = sshkey_check_rsa_length(key,
+ options.required_rsa_size)) != 0) {
+ logit_r(r, "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 7f26c680..42be690b 100644
--- a/readconf.c
+++ b/readconf.c
@@ -174,7 +174,7 @@ typedef enum {
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
- oSecurityKeyProvider, oKnownHostsCommand,
+ oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize,
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
@@ -320,6 +320,8 @@ static struct {
{ "proxyjump", oProxyJump },
@@ -320,6 +320,7 @@ static struct {
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
+ { "requiredrsasize", oRequiredRSASize },
{ "requiredrsasize", oRequiredRSASize },
+ { "rsaminsize", oRequiredRSASize }, /* alias */
{ "enableescapecommandline", oEnableEscapeCommandline },
{ NULL, oBadOption }
};
@@ -2176,6 +2177,10 @@ parse_pubkey_algos:
*charptr = xstrdup(arg);
break;
+ case oRequiredRSASize:
+ intptr = &options->required_rsa_size;
+ goto parse_int;
+
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@@ -2423,6 +2428,7 @@ initialize_options(Options * options)
options->hostbased_accepted_algos = NULL;
options->pubkey_accepted_algos = NULL;
options->known_hosts_command = NULL;
+ options->required_rsa_size = -1;
}
/*
@@ -2619,6 +2625,8 @@ fill_default_options(Options * options)
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("$SSH_SK_PROVIDER");
#endif
+ if (options->required_rsa_size == -1)
+ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
/* Expand KEX name lists */
all_cipher = cipher_alg_list(',', 0);
@@ -3308,6 +3316,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(oRequiredRSASize, o->required_rsa_size);
/* String options */
dump_cfg_string(oBindAddress, o->bind_address);
diff --git a/readconf.h b/readconf.h
index f647bd42..ffb5ec4f 100644
--- a/readconf.h
+++ b/readconf.h
@@ -176,6 +176,8 @@ typedef struct {
char *known_hosts_command;
+ int required_rsa_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 29df0463..423772b1 100644
--- a/servconf.c
+++ b/servconf.c
@@ -195,6 +195,7 @@ initialize_server_options(ServerOptions *options)
options->fingerprint_hash = -1;
options->disable_forwarding = -1;
options->expose_userauth_info = -1;
+ options->required_rsa_size = -1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@@ -441,6 +442,8 @@ fill_default_server_options(ServerOptions *options)
options->expose_userauth_info = 0;
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("internal");
+ if (options->required_rsa_size == -1)
+ options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
assemble_algorithms(options);
@@ -517,6 +520,7 @@ typedef enum {
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
+ sRequiredRSASize,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
@@ -676,6 +680,8 @@ static struct {
{ "rdomain", sRDomain, SSHCFG_ALL },
@@ -676,6 +680,7 @@ static struct {
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
+ { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
+ { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */
{ "channeltimeout", sChannelTimeout, SSHCFG_ALL },
{ "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
};
@@ -2438,6 +2443,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
*charptr = xstrdup(arg);
break;
+ case sRequiredRSASize:
+ intptr = &options->required_rsa_size;
+ goto parse_int;
+
case sDeprecated:
case sIgnore:
case sUnsupported:
@@ -2610,6 +2619,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(required_rsa_size);
/*
* The bind_mask is a mode_t that may be unsigned, so we can't use
@@ -2874,6 +2884,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(sRequiredRSASize, o->required_rsa_size);
dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
/* formatted integer arguments */
diff --git a/servconf.h b/servconf.h
index 8a04463e..9346155c 100644
--- a/servconf.h
+++ b/servconf.h
@@ -229,6 +229,7 @@ typedef struct {
int expose_userauth_info;
u_int64_t timing_secret;
char *sk_provider;
+ int required_rsa_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 559bf2af..25be53d5 100644
--- a/ssh.c
+++ b/ssh.c
@@ -516,14 +516,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.required_rsa_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:
@@ -1578,7 +1586,7 @@ 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) \
@@ -1586,7 +1594,8 @@ main(int ac, char **av)
#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]);
@@ -2284,7 +2293,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) {
@@ -2315,7 +2324,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 f9bd19ea..58fe98db 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -96,6 +96,11 @@ 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.required_rsa_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.");
@@ -1606,6 +1611,13 @@ load_identity_file(Identity *id)
private = NULL;
quit = 1;
}
+ if (!quit && (r = sshkey_check_rsa_length(private,
+ options.required_rsa_size)) != 0) {
+ debug_fr(r, "Skipping key %s", id->filename);
+ sshkey_free(private);
+ private = NULL;
+ quit = 1;
+ }
if (!quit && private != NULL && id->agent_fd == -1 &&
!(id->key && id->isprivate))
maybe_add_key_to_agent(id->filename, private, comment,
@@ -1752,6 +1764,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.required_rsa_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 17eee9d8..395ef493 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1870,6 +1870,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.required_rsa_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 ed2b5dff..77093235 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -2365,18 +2365,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,
@@ -2439,7 +2445,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);
@@ -3642,7 +3648,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;
@@ -4644,7 +4650,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 094815e0..be254e6b 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -273,6 +273,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..e255b9b9 100644
--- a/ssh.1
+++ b/ssh.1
@@ -571,6 +571,7 @@ For full details of the options listed below, and their possible values, see
.It RemoteCommand
.It RemoteForward
.It RequestTTY
+.It RequiredRSASize
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
diff --git a/ssh_config.5 b/ssh_config.5
index 24a46460..d1ede18e 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -1634,6 +1634,17 @@ and
.Fl T
flags for
.Xr ssh 1 .
+.It Cm RequiredRSASize
+Specifies the minimum RSA key size (in bits) that
+.Xr ssh 1
+will accept.
+User authentication keys smaller than this limit will be ignored.
+Servers that present host keys smaller than this limit will cause the
+connection to be terminated.
+The default is
+.Cm 1024
+bits.
+Note that this limit may only be raised from the default.
.It Cm RevokedHostKeys
Specifies revoked host public keys.
Keys listed in this file will be refused for host authentication.
diff --git a/sshd_config.5 b/sshd_config.5
index 867a747d..f5a06637 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -1596,6 +1596,16 @@ is
.Cm default none ,
which means that rekeying is performed after the cipher's default amount
of data has been sent or received and no time based rekeying is done.
+.It Cm RequiredRSASize
+Specifies the minimum RSA key size (in bits) that
+.Xr sshd 8
+will accept.
+User and host-based authentication keys smaller than this limit will be
+refused.
+The default is
+.Cm 1024
+bits.
+Note that this limit may only be raised from the default.
.It Cm RevokedKeys
Specifies revoked public keys file, or
.Cm none

View File

@ -1,63 +1,117 @@
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
diff -up openssh-9.3p1/regress/hostkey-agent.sh.xxx openssh-9.3p1/regress/hostkey-agent.sh
--- openssh-9.3p1/regress/hostkey-agent.sh.xxx 2023-05-29 18:15:56.311236887 +0200
+++ openssh-9.3p1/regress/hostkey-agent.sh 2023-05-29 18:16:07.598503551 +0200
@@ -17,8 +17,21 @@ trace "make CA key"
${SSHKEYGEN} -qt ed25519 -f $OBJ/agent-ca -N '' || fatal "ssh-keygen CA"
+PUBKEY_ACCEPTED_ALGOS=`$SSH -G "example.com" | \
+ grep -i "PubkeyAcceptedAlgorithms" | cut -d ' ' -f2- | tr "," "|"`
+SSH_ACCEPTED_KEYTYPES=`echo "$SSH_KEYTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
+echo $PUBKEY_ACCEPTED_ALGOS | grep "rsa"
+r=$?
+if [ $r == 0 ]; then
+echo $SSH_ACCEPTED_KEYTYPES | grep "rsa"
+r=$?
+if [ $r -ne 0 ]; then
+SSH_ACCEPTED_KEYTYPES="$SSH_ACCEPTED_KEYTYPES ssh-rsa"
+fi
+fi
+
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
${SSHKEYGEN} -s $OBJ/agent-ca -qh -n localhost-with-alias \
-I localhost-with-alias $OBJ/agent-key.$k.pub || \
@@ -32,12 +48,16 @@ rm $OBJ/agent-ca # Don't need CA private
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
-for k in $SSH_KEYTYPES ; do
+for k in $SSH_ACCEPTED_KEYTYPES ; do
verbose "key type $k"
+ hka=$k
+ if [ $k = "ssh-rsa" ]; then
+ hka="rsa-sha2-512"
+ fi
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
- echo "HostKeyAlgorithms $k" >> $OBJ/sshd_proxy
+ echo "HostKeyAlgorithms $hka" >> $OBJ/sshd_proxy
echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy
- opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy"
+ opts="-oHostKeyAlgorithms=$hka -F $OBJ/ssh_proxy"
( printf 'localhost-with-alias,127.0.0.1,::1 ' ;
cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts
SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`
@@ -50,15 +70,16 @@ for k in $SSH_KEYTYPES ; do
done
SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com'`
+SSH_ACCEPTED_CERTTYPES=`echo "$SSH_CERTTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
# Prepare sshd_proxy for certificates.
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
HOSTKEYALGS=""
-for k in $SSH_CERTTYPES ; do
+for k in $SSH_ACCEPTED_CERTTYPES ; do
test -z "$HOSTKEYALGS" || HOSTKEYALGS="${HOSTKEYALGS},"
HOSTKEYALGS="${HOSTKEYALGS}${k}"
done
-for k in $SSH_KEYTYPES ; do
+for k in $SSH_ACCEPTED_KEYTYPES ; do
echo "Hostkey $OBJ/agent-key.${k}.pub" >> $OBJ/sshd_proxy
echo "HostCertificate $OBJ/agent-key.${k}-cert.pub" >> $OBJ/sshd_proxy
test -f $OBJ/agent-key.${k}.pub || fatal "no $k key"
@@ -70,7 +93,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >>
( printf '@cert-authority localhost-with-alias ' ;
cat $OBJ/agent-ca.pub) > $OBJ/known_hosts
-for k in $SSH_CERTTYPES ; do
+for k in $SSH_ACCEPTED_CERTTYPES ; do
verbose "cert type $k"
opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy"
SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`
diff -up openssh-9.3p1/sshconnect2.c.xxx openssh-9.3p1/sshconnect2.c
--- openssh-9.3p1/sshconnect2.c.xxx 2023-04-26 17:37:35.100827792 +0200
+++ openssh-9.3p1/sshconnect2.c 2023-04-26 17:50:31.860748877 +0200
@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
const struct ssh_conn_info *cinfo)
{
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;
char *myproposal[PROPOSAL_MAX];
- char *s, *all_key, *hkalgs = NULL;
+ char *s, *all_key, *hkalgs = NULL, *filtered_algs = 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)
@@ -260,9 +260,21 @@ ssh_kex2(struct ssh *ssh, char *host, st
if (use_known_hosts_order)
hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);
+ filtered_algs = hkalgs ? match_filter_allowlist(hkalgs, options.pubkey_accepted_algos)
+ : match_filter_allowlist(options.hostkeyalgorithms,
+ options.pubkey_accepted_algos);
+ if (filtered_algs == NULL) {
+ if (hkalgs)
+ fatal_f("No match between algorithms for %s (host %s) and pubkey accepted algorithms %s",
+ hkalgs, host, options.pubkey_accepted_algos);
+ else
+ fatal_f("No match between host key algorithms %s and pubkey accepted algorithms %s",
+ options.hostkeyalgorithms, options.pubkey_accepted_algos);
+ }
+
kex_proposal_populate_entries(ssh, myproposal, s, options.ciphers,
options.macs, compression_alg_list(options.compression),
- hkalgs ? hkalgs : options.hostkeyalgorithms);
+ filtered_algs);
#if defined(GSSAPI) && defined(WITH_OPENSSL)
if (options.gss_keyex) {
@@ -303,6 +315,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
#endif
free(hkalgs);
+ free(filtered_algs);
/* start key exchange */
if ((r = kex_setup(ssh, myproposal)) != 0)

View File

@ -0,0 +1,402 @@
diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c
--- openssh-8.7p1/compat.c.sshrsacheck 2023-01-12 13:29:06.338710923 +0100
+++ openssh-8.7p1/compat.c 2023-01-12 13:29:06.357711165 +0100
@@ -43,6 +43,7 @@ void
compat_banner(struct ssh *ssh, const char *version)
{
int i;
+ int forbid_ssh_rsa = 0;
static struct {
char *pat;
int bugs;
@@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha
};
/* process table, return first match */
+ forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA);
ssh->compat = 0;
for (i = 0; check[i].pat; i++) {
if (match_pattern_list(version, check[i].pat, 0) == 1) {
debug_f("match: %s pat %s compat 0x%08x",
version, check[i].pat, check[i].bugs);
ssh->compat = check[i].bugs;
+ if (forbid_ssh_rsa)
+ ssh->compat |= SSH_RH_RSASIGSHA;
return;
}
}
debug_f("no match: %s", version);
+ if (forbid_ssh_rsa)
+ ssh->compat |= SSH_RH_RSASIGSHA;
}
/* Always returns pointer to allocated memory, caller must free. */
diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h
--- openssh-8.7p1/compat.h.sshrsacheck 2021-08-20 06:03:49.000000000 +0200
+++ openssh-8.7p1/compat.h 2023-01-12 13:29:06.358711178 +0100
@@ -30,7 +30,7 @@
#define SSH_BUG_UTF8TTYMODE 0x00000001
#define SSH_BUG_SIGTYPE 0x00000002
#define SSH_BUG_SIGTYPE74 0x00000004
-/* #define unused 0x00000008 */
+#define SSH_RH_RSASIGSHA 0x00000008
#define SSH_OLD_SESSIONID 0x00000010
/* #define unused 0x00000020 */
#define SSH_BUG_DEBUG 0x00000040
diff -up openssh-8.7p1/monitor.c.sshrsacheck openssh-8.7p1/monitor.c
--- openssh-8.7p1/monitor.c.sshrsacheck 2023-01-20 13:07:54.279676981 +0100
+++ openssh-8.7p1/monitor.c 2023-01-20 15:01:07.007821379 +0100
@@ -660,11 +660,12 @@ mm_answer_sign(struct ssh *ssh, int sock
struct sshkey *key;
struct sshbuf *sigbuf = NULL;
u_char *p = NULL, *signature = NULL;
- char *alg = NULL;
+ char *alg = NULL, *effective_alg;
size_t datlen, siglen, alglen;
int r, is_proof = 0;
u_int keyid, compat;
const char proof_req[] = "hostkeys-prove-00@openssh.com";
+ const char safe_rsa[] = "rsa-sha2-256";
debug3_f("entering");
@@ -719,18 +720,30 @@ mm_answer_sign(struct ssh *ssh, int sock
}
if ((key = get_hostkey_by_index(keyid)) != NULL) {
- if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
+ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
+ && (sshkey_type_plain(key->type) == KEY_RSA)) {
+ effective_alg = safe_rsa;
+ } else {
+ effective_alg = alg;
+ }
+ if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, effective_alg,
options.sk_provider, NULL, compat)) != 0)
fatal_fr(r, "sign");
} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
auth_sock > 0) {
+ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
+ && (sshkey_type_plain(key->type) == KEY_RSA)) {
+ effective_alg = safe_rsa;
+ } else {
+ effective_alg = alg;
+ }
if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
- p, datlen, alg, compat)) != 0)
+ p, datlen, effective_alg, compat)) != 0)
fatal_fr(r, "agent sign");
} else
fatal_f("no hostkey from index %d", keyid);
- debug3_f("%s %s signature len=%zu", alg,
+ debug3_f("%s (effective: %s) %s signature len=%zu", alg, effective_alg,
is_proof ? "hostkey proof" : "KEX", siglen);
sshbuf_reset(m);
diff -up openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck openssh-8.7p1/regress/cert-userkey.sh
--- openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck 2023-01-25 14:26:52.885963113 +0100
+++ openssh-8.7p1/regress/cert-userkey.sh 2023-01-25 14:27:25.757219800 +0100
@@ -7,7 +7,8 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
-PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
+#ssh-dss keys are incompatible with DEFAULT crypto policy
+PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss' | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
EXTRA_TYPES=""
rsa=""
diff -up openssh-8.7p1/regress/Makefile.sshrsacheck openssh-8.7p1/regress/Makefile
--- openssh-8.7p1/regress/Makefile.sshrsacheck 2023-01-20 13:07:54.169676051 +0100
+++ openssh-8.7p1/regress/Makefile 2023-01-20 13:07:54.290677074 +0100
@@ -2,7 +2,8 @@
tests: prep file-tests t-exec unit
-REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12
+#ssh-dss tests will not pass on DEFAULT crypto-policy because of SHA1, skipping
+REGRESS_TARGETS= t1 t2 t3 t4 t5 t7 t8 t9 t10 t11 t12
# File based tests
file-tests: $(REGRESS_TARGETS)
diff -up openssh-8.7p1/regress/test-exec.sh.sshrsacheck openssh-8.7p1/regress/test-exec.sh
--- openssh-8.7p1/regress/test-exec.sh.sshrsacheck 2023-01-25 14:24:54.778040819 +0100
+++ openssh-8.7p1/regress/test-exec.sh 2023-01-25 14:26:39.500858590 +0100
@@ -581,8 +581,9 @@ maybe_filter_sk() {
fi
}
-SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk`
-SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk`
+#ssh-dss keys are incompatible with DEFAULT crypto policy
+SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'`
+SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'`
for t in ${SSH_KEYTYPES}; do
# generate user key
diff -up openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck openssh-8.7p1/regress/unittests/kex/test_kex.c
--- openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck 2023-01-26 13:34:52.645743677 +0100
+++ openssh-8.7p1/regress/unittests/kex/test_kex.c 2023-01-26 13:36:56.220745823 +0100
@@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype,
memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
if (kex != NULL)
kex_params.proposal[PROPOSAL_KEX_ALGS] = kex;
- keyname = strdup(sshkey_ssh_name(private));
+ keyname = (strcmp(sshkey_ssh_name(private), "ssh-rsa")) ?
+ strdup(sshkey_ssh_name(private)) : strdup("rsa-sha2-256");
ASSERT_PTR_NE(keyname, NULL);
kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname;
ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0);
@@ -180,7 +181,7 @@ do_kex(char *kex)
{
#ifdef WITH_OPENSSL
do_kex_with_key(kex, KEY_RSA, 2048);
- do_kex_with_key(kex, KEY_DSA, 1024);
+ /* do_kex_with_key(kex, KEY_DSA, 1024); */
#ifdef OPENSSL_HAS_ECC
do_kex_with_key(kex, KEY_ECDSA, 256);
#endif /* OPENSSL_HAS_ECC */
diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_file.c
--- openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck 2023-01-26 12:04:55.946343408 +0100
+++ openssh-8.7p1/regress/unittests/sshkey/test_file.c 2023-01-26 12:06:35.235164432 +0100
@@ -110,6 +110,7 @@ sshkey_file_tests(void)
sshkey_free(k2);
TEST_DONE();
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("load RSA cert with SHA1 signature");
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha1"), &k2), 0);
ASSERT_PTR_NE(k2, NULL);
@@ -117,7 +118,7 @@ sshkey_file_tests(void)
ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
ASSERT_STRING_EQ(k2->cert->signature_type, "ssh-rsa");
sshkey_free(k2);
- TEST_DONE();
+ TEST_DONE(); */
TEST_START("load RSA cert with SHA512 signature");
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha512"), &k2), 0);
diff -up openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c
--- openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck 2023-01-26 12:10:37.533168013 +0100
+++ openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c 2023-01-26 12:15:35.637631860 +0100
@@ -333,13 +333,14 @@ sshkey_fuzz_tests(void)
TEST_DONE();
#ifdef WITH_OPENSSL
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("fuzz RSA sig");
buf = load_file("rsa_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
sshbuf_free(buf);
sig_fuzz(k1, "ssh-rsa");
sshkey_free(k1);
- TEST_DONE();
+ TEST_DONE();*/
TEST_START("fuzz RSA SHA256 sig");
buf = load_file("rsa_1");
@@ -357,6 +358,7 @@ sshkey_fuzz_tests(void)
sshkey_free(k1);
TEST_DONE();
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("fuzz DSA sig");
buf = load_file("dsa_1");
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
@@ -364,6 +366,7 @@ sshkey_fuzz_tests(void)
sig_fuzz(k1, NULL);
sshkey_free(k1);
TEST_DONE();
+ */
#ifdef OPENSSL_HAS_ECC
TEST_START("fuzz ECDSA sig");
diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c
--- openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck 2023-01-26 11:02:52.339413463 +0100
+++ openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c 2023-01-26 11:58:42.324253896 +0100
@@ -60,6 +60,9 @@ build_cert(struct sshbuf *b, struct sshk
u_char *sigblob;
size_t siglen;
+ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
+ int expected = (sig_alg == NULL || strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
+
ca_buf = sshbuf_new();
ASSERT_PTR_NE(ca_buf, NULL);
ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0);
@@ -101,8 +104,9 @@ build_cert(struct sshbuf *b, struct sshk
ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
- sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0);
- ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
+ sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), expected);
+ if (expected == 0)
+ ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
free(sigblob);
sshbuf_free(ca_buf);
@@ -119,16 +123,22 @@ signature_test(struct sshkey *k, struct
{
size_t len;
u_char *sig;
+ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
+ int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
+ if (k && (sshkey_type_plain(k->type) == KEY_DSA || sshkey_type_plain(k->type) == KEY_DSA_CERT))
+ expected = SSH_ERR_LIBCRYPTO_ERROR;
ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg,
- NULL, NULL, 0), 0);
- ASSERT_SIZE_T_GT(len, 8);
- ASSERT_PTR_NE(sig, NULL);
- ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
- ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
- /* Fuzz test is more comprehensive, this is just a smoke test */
- sig[len - 5] ^= 0x10;
- ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ NULL, NULL, 0), expected);
+ if (expected == 0) {
+ ASSERT_SIZE_T_GT(len, 8);
+ ASSERT_PTR_NE(sig, NULL);
+ ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
+ /* Fuzz test is more comprehensive, this is just a smoke test */
+ sig[len - 5] ^= 0x10;
+ ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
+ }
free(sig);
}
@@ -514,7 +524,7 @@ sshkey_tests(void)
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
NULL), 0);
k3 = get_private("rsa_1");
- build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL);
+ build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, "rsa-sha2-256");
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
ASSERT_PTR_EQ(k4, NULL);
diff -up openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck openssh-8.7p1/regress/unittests/sshsig/tests.c
--- openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck 2023-01-26 12:19:23.659513651 +0100
+++ openssh-8.7p1/regress/unittests/sshsig/tests.c 2023-01-26 12:20:28.021044803 +0100
@@ -102,9 +102,11 @@ tests(void)
check_sig("rsa.pub", "rsa.sig", msg, namespace);
TEST_DONE();
+ /* Skip this test, SHA1 signatures are not supported
TEST_START("check DSA signature");
check_sig("dsa.pub", "dsa.sig", msg, namespace);
TEST_DONE();
+ */
#ifdef OPENSSL_HAS_ECC
TEST_START("check ECDSA signature");
diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c
--- openssh-8.7p1/serverloop.c.sshrsacheck 2023-01-12 14:57:08.118400073 +0100
+++ openssh-8.7p1/serverloop.c 2023-01-12 14:59:17.330470518 +0100
@@ -80,6 +80,7 @@
#include "auth-options.h"
#include "serverloop.h"
#include "ssherr.h"
+#include "compat.h"
extern ServerOptions options;
@@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh *
else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
sigalg = "rsa-sha2-256";
}
+ if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) {
+ sigalg = "rsa-sha2-512";
+ debug3_f("SHA1 signature is not supported, falling back to %s", sigalg);
+ }
debug3_f("sign %s key (index %d) using sigalg %s",
sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
if ((r = sshbuf_put_cstring(sigbuf,
diff -up openssh-8.7p1/sshconnect2.c.sshrsacheck openssh-8.7p1/sshconnect2.c
--- openssh-8.7p1/sshconnect2.c.sshrsacheck 2023-01-25 15:33:29.140353651 +0100
+++ openssh-8.7p1/sshconnect2.c 2023-01-25 15:59:34.225364883 +0100
@@ -1461,6 +1464,14 @@ identity_sign(struct identity *id, u_cha
retried = 1;
goto retry_pin;
}
+ if ((r == SSH_ERR_LIBCRYPTO_ERROR) && strcmp("ssh-rsa", alg)) {
+ char rsa_safe_alg[] = "rsa-sha2-512";
+ debug3_f("trying to fallback to algorithm %s", rsa_safe_alg);
+
+ if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen,
+ rsa_safe_alg, options.sk_provider, pin, compat)) != 0)
+ debug_fr(r, "sshkey_sign - RSA fallback");
+ }
goto out;
}
diff -up openssh-8.7p1/sshd.c.sshrsacheck openssh-8.7p1/sshd.c
--- openssh-8.7p1/sshd.c.sshrsacheck 2023-01-12 13:29:06.355711140 +0100
+++ openssh-8.7p1/sshd.c 2023-01-12 13:29:06.358711178 +0100
@@ -1640,6 +1651,7 @@ main(int ac, char **av)
Authctxt *authctxt;
struct connection_info *connection_info = NULL;
sigset_t sigmask;
+ int forbid_ssh_rsa = 0;
#ifdef HAVE_SECUREWARE
(void)set_auth_parameters(ac, av);
@@ -1938,6 +1950,33 @@ main(int ac, char **av)
key = NULL;
continue;
}
+ if (key && (sshkey_type_plain(key->type) == KEY_RSA || sshkey_type_plain(key->type) == KEY_RSA_CERT)) {
+ size_t sign_size = 0;
+ u_char *tmp = NULL;
+ u_char data[] = "Test SHA1 vector";
+ int res;
+
+ res = sshkey_sign(key, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
+ free(tmp);
+ if (res == SSH_ERR_LIBCRYPTO_ERROR) {
+ verbose_f("sshd: SHA1 in signatures is disabled for RSA keys");
+ forbid_ssh_rsa = 1;
+ }
+ }
+ if (key && (sshkey_type_plain(key->type) == KEY_DSA || sshkey_type_plain(key->type) == KEY_DSA_CERT)) {
+ size_t sign_size = 0;
+ u_char *tmp = NULL;
+ u_char data[] = "Test SHA1 vector";
+ int res;
+
+ res = sshkey_sign(key, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
+ free(tmp);
+ if (res == SSH_ERR_LIBCRYPTO_ERROR) {
+ logit_f("sshd: ssh-dss is disabled, skipping key file %s", options.host_key_files[i]);
+ key = NULL;
+ continue;
+ }
+ }
if (sshkey_is_sk(key) &&
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
debug("host key %s requires user presence, ignoring",
@@ -2275,6 +2306,9 @@ main(int ac, char **av)
check_ip_options(ssh);
+ if (forbid_ssh_rsa)
+ ssh->compat |= SSH_RH_RSASIGSHA;
+
/* Prepare the channels layer */
channel_init_channels(ssh);
channel_set_af(ssh, options.address_family);
diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c
--- openssh-8.7p1/ssh-rsa.c.sshrsacheck 2023-01-20 13:07:54.180676144 +0100
+++ openssh-8.7p1/ssh-rsa.c 2023-01-20 13:07:54.290677074 +0100
@@ -254,7 +254,8 @@ ssh_rsa_verify(const struct sshkey *key,
ret = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
- if (hash_alg != want_alg) {
+ if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) {
+ debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg);
ret = SSH_ERR_SIGNATURE_INVALID;
goto out;
}

View File

@ -5,11 +5,11 @@ diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c
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;
- 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, targ);
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
@ -22,11 +22,13 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c
{
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)
@@ -1033,11 +1033,43 @@ do_realpath_expand(struct sftp_conn *con
if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
(r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
fatal_fr(r, "parse status");
- error("Couldn't canonicalize: %s", fx2txt(status));
- error("%s %s: %s", expand ? "expand" : "realpath",
- path, *errmsg == '\0' ? fx2txt(status) : errmsg);
- free(errmsg);
- sshbuf_free(msg);
- return NULL;
+ if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) {
@ -35,29 +37,34 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c
+ sshbuf_free(msg);
+ return NULL;
+ }
+
+ debug2("Sending SSH2_FXP_REALPATH \"%s\" - create dir", path);
+ 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)
+ (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;
+ free(errmsg);
+
+ if ((r = sshbuf_get_u32(msg, &status)) != 0)
+ if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
+ (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
+ fatal_fr(r, "parse status");
+ error("Couldn't canonicalize: %s", fx2txt(status));
+ error("%s %s: %s", expand ? "expand" : "realpath",
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+ free(errmsg);
+ sshbuf_free(msg);
+ return NULL;
+ }
+ } else {
+ error("Couldn't canonicalize: %s", fx2txt(status));
+ error("%s %s: %s", expand ? "expand" : "realpath",
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+ free(errmsg);
+ sshbuf_free(msg);
+ return NULL;
+ }
@ -94,33 +101,33 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c
- 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;
}
error("download \"%s\": path canonicalization failed", 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)
- int follow_link_flag, int inplace_flag)
+ int follow_link_flag, int inplace_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;
}
error("upload \"%s\": path canonicalization failed", 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;
}
error("crossload \"%s\": path canonicalization failed",
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
@ -136,9 +143,9 @@ diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h
@@ -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);
int upload_dir(struct sftp_conn *, const char *, const char *,
- int, int, int, int, int, int);
+ int, int, int, int, int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to
@ -149,8 +156,8 @@ diff -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c
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)
- 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,

View File

@ -1,304 +0,0 @@
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

@ -13,8 +13,8 @@ diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1
--- openssh-8.7p1/scp.1.kill-scp 2021-09-16 12:09:02.646714578 +0200
+++ openssh-8.7p1/scp.1 2021-09-16 12:26:49.978628226 +0200
@@ -278,6 +278,13 @@ to print debugging messages about their
This is helpful in
debugging connection, authentication, and configuration problems.
By default a 32KB buffer is used.
.El
.El
+.Pp
+Usage of SCP protocol can be blocked by creating a world-readable

View File

@ -1,87 +0,0 @@
diff --git a/scp.1 b/scp.1
index 68aac04b..a96e95ad 100644
--- a/scp.1
+++ b/scp.1
@@ -18,7 +18,7 @@
.Nd OpenSSH secure file copy
.Sh SYNOPSIS
.Nm scp
-.Op Fl 346ABCOpqRrsTv
+.Op Fl 346ABCOpqRrTv
.Op Fl c Ar cipher
.Op Fl D Ar sftp_server_path
.Op Fl F Ar ssh_config
@@ -79,7 +76,9 @@ The options are as follows:
Copies between two remote hosts are transferred through the local host.
Without this option the data is copied directly between the two remote
hosts.
-Note that, when using the original SCP protocol (the default), this option
+Note that, when using the original SCP protocol (via the
+.Fl O
+flag), this option
selects batch mode for the second host as
.Nm
cannot ask for passwords or passphrases for both hosts.
@@ -146,7 +145,6 @@ Limits the used bandwidth, specified in Kbit/s.
wildcard patterns and for expanding paths with a
.Sq ~
prefix for older SFTP servers.
-This mode is the default.
.It Fl o Ar ssh_option
Can be used to pass options to
.Nm ssh
@@ -258,8 +258,6 @@ to use for the encrypted connection.
The program must understand
.Xr ssh 1
options.
-.It Fl s
-Use the SFTP protocol for transfers rather than the original scp protocol.
.It Fl T
Disable strict filename checking.
By default when copying files from a remote host to a local directory
@@ -299,11 +289,23 @@ debugging connection, authentication, and configuration problems.
.Xr ssh_config 5 ,
.Xr sftp-server 8 ,
.Xr sshd 8
+.Sh CAVEATS
+The original scp protocol (selected by the
+.Fl O
+flag) requires execution of the remote user's shell to perform
+.Xr glob 3
+pattern matching.
+This requires careful quoting of any characters that have special meaning to
+the remote shell, such as quote characters.
.Sh HISTORY
.Nm
is based on the rcp program in
.Bx
source code from the Regents of the University of California.
+.Pp
+Since OpenSSH 8.8 (8.7 in Red Hat/Fedora builds),
+.Nm
+has use the SFTP protocol for transfers by default.
.Sh AUTHORS
.An Timo Rinne Aq Mt tri@iki.fi
.An Tatu Ylonen Aq Mt ylo@cs.hut.fi
diff --git a/scp.c b/scp.c
index e039350c..c7cf7529 100644
--- a/scp.c
+++ b/scp.c
@@ -448,7 +448,7 @@ main(int argc, char **argv)
const char *errstr;
extern char *optarg;
extern int optind;
- enum scp_mode_e mode = MODE_SCP;
+ enum scp_mode_e mode = MODE_SFTP;
char *sftp_direct = NULL;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
@@ -1983,7 +1983,7 @@ void
usage(void)
{
(void) fprintf(stderr,
- "usage: scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n"
+ "usage: scp [-346ABCOpqRrTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n"
" [-i identity_file] [-J destination] [-l limit]\n"
" [-o ssh_option] [-P port] [-S program] source ... target\n");
exit(1);

View File

@ -1,135 +0,0 @@
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

@ -14,9 +14,9 @@ diff --color -ru a/ssh.1 b/ssh.1
.It ControlPersist
.It DynamicForward
+.It EnableSSHKeysign
.It EnableEscapeCommandline
.It EscapeChar
.It ExitOnForwardFailure
.It FingerprintHash
@@ -538,6 +540,8 @@
.It IdentitiesOnly
.It IdentityAgent

View File

@ -1,41 +0,0 @@
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

@ -0,0 +1,292 @@
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/dh.c openssh-9.0p1-patched/dh.c
--- openssh-9.0p1/dh.c 2023-05-25 09:24:28.730868316 +0200
+++ openssh-9.0p1-patched/dh.c 2023-05-25 09:23:44.841379532 +0200
@@ -37,6 +37,9 @@
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/fips.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include "dh.h"
#include "pathnames.h"
@@ -290,10 +293,15 @@
int
dh_gen_key(DH *dh, int need)
{
- int pbits;
- const BIGNUM *dh_p, *pub_key;
+ const BIGNUM *dh_p, *dh_g;
+ BIGNUM *pub_key = NULL, *priv_key = NULL;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+ int pbits, r = 0;
- DH_get0_pqg(dh, &dh_p, NULL, NULL);
+ DH_get0_pqg(dh, &dh_p, NULL, &dh_g);
if (need < 0 || dh_p == NULL ||
(pbits = BN_num_bits(dh_p)) <= 0 ||
@@ -301,19 +309,85 @@
return SSH_ERR_INVALID_ARGUMENT;
if (need < 256)
need = 256;
+
+ if ((param_bld = OSSL_PARAM_BLD_new()) == NULL ||
+ (ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL) {
+ OSSL_PARAM_BLD_free(param_bld);
+ return SSH_ERR_ALLOC_FAIL;
+ }
+
+ if (OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_FFC_P, dh_p) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_FFC_G, dh_g) != 1) {
+ error_f("Could not set p,q,g parameters");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
/*
* Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
* so double requested need here.
*/
- if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
- return SSH_ERR_LIBCRYPTO_ERROR;
-
- if (DH_generate_key(dh) == 0)
- return SSH_ERR_LIBCRYPTO_ERROR;
- DH_get0_key(dh, &pub_key, NULL);
- if (!dh_pub_is_valid(dh, pub_key))
- return SSH_ERR_INVALID_FORMAT;
- return 0;
+ if (OSSL_PARAM_BLD_push_int(param_bld,
+ OSSL_PKEY_PARAM_DH_PRIV_LEN,
+ MINIMUM(need * 2, pbits - 1)) != 1 ||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_fromdata_init(ctx) != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_fromdata(ctx, &pkey,
+ EVP_PKEY_KEY_PARAMETERS, params) != 1) {
+ error_f("Failed key generation");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* reuse context for key generation */
+ EVP_PKEY_CTX_free(ctx);
+ ctx = NULL;
+
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
+ EVP_PKEY_keygen_init(ctx) != 1) {
+ error_f("Could not create or init context");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_generate(ctx, &pkey) != 1) {
+ error_f("Could not generate keys");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_public_check(ctx) != 1) {
+ error_f("The public key is incorrect");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
+ &pub_key) != 1 ||
+ EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
+ &priv_key) != 1 ||
+ DH_set0_key(dh, pub_key, priv_key) != 1) {
+ error_f("Could not set pub/priv keys to DH struct");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+
+ /* transferred */
+ pub_key = NULL;
+ priv_key = NULL;
+out:
+ OSSL_PARAM_free(params);
+ OSSL_PARAM_BLD_free(param_bld);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
+ BN_clear_free(pub_key);
+ BN_clear_free(priv_key);
+ return r;
}
DH *
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.c openssh-9.0p1-patched/kex.c
--- openssh-9.0p1/kex.c 2023-05-25 09:24:28.731868327 +0200
+++ openssh-9.0p1-patched/kex.c 2023-05-25 09:23:44.841379532 +0200
@@ -1623,3 +1623,47 @@
return r;
}
+#ifdef WITH_OPENSSL
+/*
+ * Creates an EVP_PKEY from the given parameters and keys.
+ * The private key can be omitted.
+ */
+int
+kex_create_evp_dh(EVP_PKEY **pkey, const BIGNUM *p, const BIGNUM *q,
+ const BIGNUM *g, const BIGNUM *pub, const BIGNUM *priv)
+{
+ OSSL_PARAM_BLD *param_bld = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ int r = 0;
+
+ /* create EVP_PKEY-DH key */
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
+ error_f("EVP_PKEY_CTX or PARAM_BLD init failed");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1 ||
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_PUB_KEY, pub) != 1) {
+ error_f("Failed pushing params to OSSL_PARAM_BLD");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (priv != NULL &&
+ OSSL_PARAM_BLD_push_BN(param_bld,
+ OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
+ error_f("Failed pushing private key to OSSL_PARAM_BLD");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL)
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+out:
+ OSSL_PARAM_BLD_free(param_bld);
+ EVP_PKEY_CTX_free(ctx);
+ return r;
+}
+#endif /* WITH_OPENSSL */
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kexdh.c openssh-9.0p1-patched/kexdh.c
--- openssh-9.0p1/kexdh.c 2023-05-25 09:24:28.674867692 +0200
+++ openssh-9.0p1-patched/kexdh.c 2023-05-25 09:25:28.494533889 +0200
@@ -35,6 +35,10 @@
#include "openbsd-compat/openssl-compat.h"
#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include "sshkey.h"
#include "kex.h"
@@ -83,9 +87,12 @@
kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out)
{
BIGNUM *shared_secret = NULL;
+ const BIGNUM *pub, *priv, *p, *q, *g;
+ EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
u_char *kbuf = NULL;
size_t klen = 0;
- int kout, r;
+ int kout, r = 0;
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_pub= ");
@@ -100,24 +107,59 @@
r = SSH_ERR_MESSAGE_INCOMPLETE;
goto out;
}
- klen = DH_size(kex->dh);
+
+ DH_get0_key(kex->dh, &pub, &priv);
+ DH_get0_pqg(kex->dh, &p, &q, &g);
+ /* import key */
+ r = kex_create_evp_dh(&pkey, p, q, g, pub, priv);
+ if (r != 0) {
+ error_f("Could not create EVP_PKEY for dh");
+ ERR_print_errors_fp(stderr);
+ goto out;
+ }
+ /* import peer key
+ * the parameters should be the same as with pkey
+ */
+ r = kex_create_evp_dh(&dh_pkey, p, q, g, dh_pub, NULL);
+ if (r != 0) {
+ error_f("Could not import peer key for dh");
+ ERR_print_errors_fp(stderr);
+ goto out;
+ }
+
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL) {
+ error_f("Could not init EVP_PKEY_CTX for dh");
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (EVP_PKEY_derive_init(ctx) != 1 ||
+ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
+ EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
+ error_f("Could not get key size");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
if ((kbuf = malloc(klen)) == NULL ||
(shared_secret = BN_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((kout = DH_compute_key(kbuf, dh_pub, kex->dh)) < 0 ||
- BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
+ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1 ||
+ BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
+ error_f("Could not derive key");
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
#ifdef DEBUG_KEXDH
- dump_digest("shared secret", kbuf, kout);
+ dump_digest("shared secret", kbuf, klen);
#endif
r = sshbuf_put_bignum2(out, shared_secret);
out:
freezero(kbuf, klen);
BN_clear_free(shared_secret);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(dh_pkey);
+ EVP_PKEY_CTX_free(ctx);
return r;
}
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/kex.h openssh-9.0p1-patched/kex.h
--- openssh-9.0p1/kex.h 2023-05-25 09:24:28.725868260 +0200
+++ openssh-9.0p1-patched/kex.h 2023-05-25 09:23:44.841379532 +0200
@@ -33,6 +33,9 @@
# include <openssl/bn.h>
# include <openssl/dh.h>
# include <openssl/ecdsa.h>
+# include <openssl/evp.h>
+# include <openssl/core_names.h>
+# include <openssl/param_build.h>
# ifdef OPENSSL_HAS_ECC
# include <openssl/ec.h>
# else /* OPENSSL_HAS_ECC */
@@ -283,6 +286,8 @@
const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int)
__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
+int kex_create_evp_dh(EVP_PKEY **, const BIGNUM *, const BIGNUM *,
+ const BIGNUM *, const BIGNUM *, const BIGNUM *);
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
void dump_digest(const char *, const u_char *, int);

View File

@ -0,0 +1,207 @@
diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../openssh-8.7p1/kexecdh.c ./kexecdh.c
--- ../openssh-8.7p1/kexecdh.c 2021-08-20 06:03:49.000000000 +0200
+++ ./kexecdh.c 2023-04-13 14:30:14.882449593 +0200
@@ -35,17 +35,57 @@
#include <signal.h>
#include <openssl/ecdh.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
+#include <openssl/err.h>
#include "sshkey.h"
#include "kex.h"
#include "sshbuf.h"
#include "digest.h"
#include "ssherr.h"
+#include "log.h"
static int
kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key,
const EC_GROUP *, struct sshbuf **);
+static EC_KEY *
+generate_ec_keys(int ec_nid)
+{
+ EC_KEY *client_key = NULL;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+ const char *group_name;
+
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL)
+ goto out;
+ if ((group_name = OSSL_EC_curve_nid2name(ec_nid)) == NULL ||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ error_f("Could not create OSSL_PARAM");
+ goto out;
+ }
+ if (EVP_PKEY_keygen_init(ctx) != 1 ||
+ EVP_PKEY_CTX_set_params(ctx, params) != 1 ||
+ EVP_PKEY_generate(ctx, &pkey) != 1 ||
+ (client_key = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
+ error_f("Could not generate ec keys");
+ goto out;
+ }
+out:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_BLD_free(param_bld);
+ OSSL_PARAM_free(params);
+ return client_key;
+}
+
int
kex_ecdh_keypair(struct kex *kex)
{
@@ -55,11 +95,7 @@
struct sshbuf *buf = NULL;
int r;
- if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_generate_key(client_key) != 1) {
+ if ((client_key = generate_ec_keys(kex->ec_nid)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -101,11 +137,7 @@
*server_blobp = NULL;
*shared_secretp = NULL;
- if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_generate_key(server_key) != 1) {
+ if ((server_key = generate_ec_keys(kex->ec_nid)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
@@ -140,11 +172,21 @@
{
struct sshbuf *buf = NULL;
BIGNUM *shared_secret = NULL;
- EC_POINT *dh_pub = NULL;
- u_char *kbuf = NULL;
- size_t klen = 0;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
+ OSSL_PARAM_BLD *param_bld = NULL;
+ OSSL_PARAM *params = NULL;
+ u_char *kbuf = NULL, *pub = NULL;
+ size_t klen = 0, publen;
+ const char *group_name;
int r;
+ /* import EC_KEY to EVP_PKEY */
+ if ((r = ssh_create_evp_ec(key, kex->ec_nid, &pkey)) != 0) {
+ error_f("Could not create EVP_PKEY");
+ goto out;
+ }
+
*shared_secretp = NULL;
if ((buf = sshbuf_new()) == NULL) {
@@ -153,45 +195,82 @@
}
if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0)
goto out;
- if ((dh_pub = EC_POINT_new(group)) == NULL) {
+
+ /* the public key is in the buffer in octet string UNCOMPRESSED
+ * format. See sshbuf_put_ec */
+ if ((r = sshbuf_get_string(buf, &pub, &publen)) != 0)
+ goto out;
+ sshbuf_reset(buf);
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_get_ec(buf, dh_pub, group)) != 0) {
+ if ((group_name = OSSL_EC_curve_nid2name(kex->ec_nid)) == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (OSSL_PARAM_BLD_push_octet_string(param_bld,
+ OSSL_PKEY_PARAM_PUB_KEY, pub, publen) != 1 ||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
+ error_f("Failed to set params for dh_pkey");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if (EVP_PKEY_fromdata_init(ctx) != 1 ||
+ EVP_PKEY_fromdata(ctx, &dh_pkey,
+ EVP_PKEY_PUBLIC_KEY, params) != 1 ||
+ EVP_PKEY_public_check(ctx) != 1) {
+ error_f("Peer public key import failed");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- sshbuf_reset(buf);
#ifdef DEBUG_KEXECDH
fputs("public key:\n", stderr);
- sshkey_dump_ec_point(group, dh_pub);
+ EVP_PKEY_print_public_fp(stderr, dh_pkey, 0, NULL);
#endif
- if (sshkey_ec_validate_public(group, dh_pub) != 0) {
- r = SSH_ERR_MESSAGE_INCOMPLETE;
+ EVP_PKEY_CTX_free(ctx);
+ ctx = NULL;
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
+ EVP_PKEY_derive_init(ctx) != 1 ||
+ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
+ EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
+ error_f("Failed to get derive information");
+ r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- klen = (EC_GROUP_get_degree(group) + 7) / 8;
- if ((kbuf = malloc(klen)) == NULL ||
- (shared_secret = BN_new()) == NULL) {
+ if ((kbuf = malloc(klen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen ||
- BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
+ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
#ifdef DEBUG_KEXECDH
dump_digest("shared secret", kbuf, klen);
#endif
+ if ((shared_secret = BN_new()) == NULL ||
+ (BN_bin2bn(kbuf, klen, shared_secret) == NULL)) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0)
goto out;
*shared_secretp = buf;
buf = NULL;
out:
- EC_POINT_clear_free(dh_pub);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(dh_pkey);
+ OSSL_PARAM_BLD_free(param_bld);
+ OSSL_PARAM_free(params);
BN_clear_free(shared_secret);
freezero(kbuf, klen);
+ freezero(pub, publen);
sshbuf_free(buf);
return r;
}

View File

@ -12,13 +12,22 @@ index e7549470..b68c1710 100644
@@ -125,7 +126,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
auth2-none.o auth2-passwd.o auth2-pubkey.o \
auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \
monitor.o monitor_wrap.o auth-krb5.o \
- auth2-gss.o gss-serv.o gss-serv-krb5.o \
+ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \
loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
loginrec.o auth-pam.o auth-shadow.o auth-sia.o \
srclimit.o sftp-server.o sftp-common.o \
sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
@@ -523,7 +523,7 @@ regress-prep:
ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile
REGRESSLIBS=libssh.a $(LIBCOMPAT)
-TESTLIBS=$(LIBS) $(CHANNELLIBS)
+TESTLIBS=$(LIBS) $(CHANNELLIBS) $(GSSLIBS)
regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \
diff -up a/auth.c.gsskex b/auth.c
--- a/auth.c.gsskex 2021-08-20 06:03:49.000000000 +0200
+++ b/auth.c 2021-08-27 12:41:51.262788953 +0200
@ -135,7 +144,7 @@ index 9351e042..d6446c0c 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -1,7 +1,7 @@
/* $OpenBSD: auth2-gss.c,v 1.32 2021/01/27 10:15:08 djm Exp $ */
/* $OpenBSD: auth2-gss.c,v 1.33 2021/12/19 22:12:07 djm Exp $ */
/*
- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@ -151,7 +160,7 @@ index 9351e042..d6446c0c 100644
+ * The 'gssapi_keyex' userauth mechanism.
+ */
+static int
+userauth_gsskeyex(struct ssh *ssh)
+userauth_gsskeyex(struct ssh *ssh, const char *method)
+{
+ Authctxt *authctxt = ssh->authctxt;
+ int r, authenticated = 0;
@ -212,19 +221,20 @@ index 9351e042..d6446c0c 100644
else
logit("GSSAPI MIC check failed");
@@ -326,6 +370,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
@@ -326,6 +370,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
return 0;
}
+Authmethod method_gsskeyex = {
+ "gssapi-keyex",
+ NULL,
+ userauth_gsskeyex,
+ &options.gss_authentication
+};
+
Authmethod method_gssapi = {
"gssapi-with-mic",
userauth_gssapi,
NULL,
diff --git a/auth2.c b/auth2.c
index 0e776224..1c217268 100644
--- a/auth2.c
@ -375,16 +385,12 @@ index ebd0dbca..1bdac6a4 100644
+#include "ssh-gss.h"
+#endif
+
/* import options */
extern Options options;
/* Permitted RSA signature algorithms for UpdateHostkeys proofs */
#define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256"
@@ -1379,9 +1383,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
break;
/* Do channel operations unless rekeying in progress. */
- if (!ssh_packet_is_rekeying(ssh))
+ if (!ssh_packet_is_rekeying(ssh)) {
channel_after_select(ssh, readset, writeset);
@@ -1379,6 +1383,14 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
/* Do channel operations. */
channel_after_poll(ssh, pfd, npfd_active);
+#ifdef GSSAPI
+ if (options.gss_renewal_rekey &&
@ -393,11 +399,10 @@ index ebd0dbca..1bdac6a4 100644
+ need_rekeying = 1;
+ }
+#endif
+ }
+
/* Buffer input from the connection. */
client_process_net_input(ssh, readset);
if (conn_in_ready)
client_process_net_input(ssh);
diff --git a/configure.ac b/configure.ac
index b689db4b..efafb6bd 100644
--- a/configure.ac
@ -1254,15 +1259,9 @@ diff --git a/kex.c b/kex.c
index ce85f043..574c7609 100644
--- a/kex.c
+++ b/kex.c
@@ -57,11 +57,16 @@
#include "misc.h"
#include "dispatch.h"
#include "monitor.h"
+#include "xmalloc.h"
#include "ssherr.h"
#include "sshbuf.h"
@@ -57,6 +57,10 @@
#include "digest.h"
#include "xmalloc.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
@ -1360,9 +1359,9 @@ index ce85f043..574c7609 100644
+ return 1;
+}
+
/* put algorithm proposal into buffer */
int
kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
/*
* Fill out a proposal array with dynamically allocated values, which may
* be modified as required for compatibility reasons.
@@ -698,6 +755,9 @@ kex_free(struct kex *kex)
sshbuf_free(kex->server_version);
sshbuf_free(kex->client_pub);
@ -1370,9 +1369,9 @@ index ce85f043..574c7609 100644
+#ifdef GSSAPI
+ free(kex->gss_host);
+#endif /* GSSAPI */
sshbuf_free(kex->initial_sig);
sshkey_free(kex->initial_hostkey);
free(kex->failed_choice);
free(kex->hostkey_alg);
free(kex->name);
diff --git a/kex.h b/kex.h
index a5ae6ac0..fe714141 100644
--- a/kex.h
@ -1414,9 +1413,9 @@ index a5ae6ac0..fe714141 100644
char *kex_names_cat(const char *, const char *);
int kex_assemble_names(char **, const char *, const char *);
+int kex_gss_names_valid(const char *);
int kex_exchange_identification(struct ssh *, int, const char *);
void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX],
const char *, const char *, const char *, const char *, const char *);
void kex_proposal_free_entries(char *prop[PROPOSAL_MAX]);
@@ -202,6 +219,12 @@ int kexgex_client(struct ssh *);
int kexgex_server(struct ssh *);
int kex_gen_client(struct ssh *);
@ -1489,7 +1488,7 @@ new file mode 100644
index 00000000..f6e1405e
--- /dev/null
+++ b/kexgssc.c
@@ -0,0 +1,599 @@
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
+ *
@ -2088,6 +2087,7 @@ index 00000000..f6e1405e
+ sshbuf_free(server_host_key_blob);
+ return r;
+}
+
+#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */
diff --git a/kexgsss.c b/kexgsss.c
new file mode 100644
@ -2612,6 +2612,23 @@ index 2ce89fe9..ebf76c7f 100644
/* The first few requests do not require asynchronous access */
while (!authenticated) {
@@ -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);
@@ -406,6 +419,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor)
monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
@ -3011,7 +3028,7 @@ diff -up a/readconf.c.gsskex b/readconf.c
options->kbd_interactive_authentication = -1;
options->kbd_interactive_devices = NULL;
@@ -2463,8 +2516,18 @@ fill_default_options(Options * options)
options->pubkey_authentication = 1;
options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL;
if (options->gss_authentication == -1)
options->gss_authentication = 0;
+ if (options->gss_keyex == -1)
@ -3496,7 +3513,7 @@ index af00fb30..03bc87eb 100644
/*
@@ -163,6 +161,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
char *s, *all_key;
char *s, *all_key, *hkalgs = NULL;
int r, use_known_hosts_order = 0;
+#if defined(GSSAPI) && defined(WITH_OPENSSL)
@ -3508,9 +3525,10 @@ index af00fb30..03bc87eb 100644
xxx_hostaddr = hostaddr;
xxx_conn_info = cinfo;
@@ -206,6 +209,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
}
kex_proposal_populate_entries(ssh, myproposal, s, options.ciphers,
options.macs, compression_alg_list(options.compression),
hkalgs ? hkalgs : options.hostkeyalgorithms);
+
+#if defined(GSSAPI) && defined(WITH_OPENSSL)
+ if (options.gss_keyex) {
+ /* Add the GSSAPI mechanisms currently supported on this
@ -3546,11 +3564,10 @@ index af00fb30..03bc87eb 100644
+ }
+ }
+#endif
+
if (options.rekey_limit || options.rekey_interval)
ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
options.rekey_interval);
@@ -224,16 +256,46 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
free(hkalgs);
@@ -224,17 +256,47 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
# ifdef OPENSSL_HAS_ECC
ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;
# endif
@ -3568,7 +3585,7 @@ index af00fb30..03bc87eb 100644
+# endif
+#endif /* WITH_OPENSSL */
ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
ssh->kex->verify_host_key=&verify_host_key_callback;
+#if defined(GSSAPI) && defined(WITH_OPENSSL)
@ -3583,6 +3600,7 @@ index af00fb30..03bc87eb 100644
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done);
/* remove ext-info from the KEX proposals for rekeying */
free(myproposal[PROPOSAL_KEX_ALGS]);
myproposal[PROPOSAL_KEX_ALGS] =
compat_kex_proposal(ssh, options.kex_algorithms);
+#if defined(GSSAPI) && defined(WITH_OPENSSL)
@ -3751,8 +3769,8 @@ index 60b2aaf7..d92f03aa 100644
exit(1);
}
@@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh)
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
ssh, list_hostkey_types());
free(hkalgs);
+#if defined(GSSAPI) && defined(WITH_OPENSSL)
+ {
@ -3885,22 +3903,40 @@ diff --git a/sshkey.c b/sshkey.c
index 57995ee6..fd5b7724 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -154,6 +154,7 @@ static const struct keytype keytypes[] = {
KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 },
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
+ { "null", "null", NULL, KEY_NULL, 0, 0, 0 },
{ NULL, NULL, NULL, -1, -1, 0, 0 }
@@ -127,6 +127,17 @@
extern const struct sshkey_impl sshkey_xmss_impl;
extern const struct sshkey_impl sshkey_xmss_cert_impl;
#endif
+const struct sshkey_impl sshkey_null_impl = {
+ /* .name = */ "null",
+ /* .shortname = */ "null",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_NULL,
+ /* .nid = */ 0,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ NULL,
+};
const struct sshkey_impl * const keyimpls[] = {
&sshkey_ed25519_impl,
@@ -162,6 +179,7 @@ static const struct keytype keytypes[] =
&sshkey_xmss_impl,
&sshkey_xmss_cert_impl,
#endif
+ &sshkey_null_impl,
NULL
};
@@ -255,7 +256,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
const struct keytype *kt;
@@ -286,7 +304,7 @@ sshkey_alg_list(int certs_only, int plai
for (kt = keytypes; kt->type != -1; kt++) {
- if (kt->name == NULL)
+ if (kt->name == NULL || kt->type == KEY_NULL)
for (i = 0; keyimpls[i] != NULL; i++) {
impl = keyimpls[i];
- if (impl->name == NULL)
+ if (impl->name == NULL || impl->type == KEY_NULL)
continue;
if (!include_sigonly && kt->sigonly)
if (!include_sigonly && impl->sigonly)
continue;
diff --git a/sshkey.h b/sshkey.h
index 71a3fddc..37a43a67 100644

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
--- openssh-9.3p1/openbsd-compat/openssl-compat.c 2023-03-15 22:28:19.000000000 +0100
+++ /home/dbelyavs/work/upstream/openssh-portable/openbsd-compat/openssl-compat.c 2023-05-25 14:19:42.870841944 +0200
@@ -33,10 +33,10 @@
/*
* OpenSSL version numbers: MNNFFPPS: major minor fix patch status
- * We match major, minor, fix and status (not patch) for <1.0.0.
- * After that, we acceptable compatible fix versions (so we
- * allow 1.0.1 to work with 1.0.0). Going backwards is only allowed
- * within a patch series.
+ * Versions >=3 require only major versions to match.
+ * For versions <3, we accept compatible fix versions (so we allow 1.0.1
+ * to work with 1.0.0). Going backwards is only allowed within a patch series.
+ * See https://www.openssl.org/policies/releasestrat.html
*/
int
@@ -48,15 +48,17 @@
if (headerver == libver)
return 1;
- /* for versions < 1.0.0, major,minor,fix,status must match */
- if (headerver < 0x1000000f) {
- mask = 0xfffff00fL; /* major,minor,fix,status */
+ /*
+ * For versions >= 3.0, only the major and status must match.
+ */
+ if (headerver >= 0x3000000f) {
+ mask = 0xf000000fL; /* major,status */
return (headerver & mask) == (libver & mask);
}
/*
- * For versions >= 1.0.0, major,minor,status must match and library
- * fix version must be equal to or newer than the header.
+ * For versions >= 1.0.0, but <3, major,minor,status must match and
+ * library fix version must be equal to or newer than the header.
*/
mask = 0xfff0000fL; /* major,minor,status */
hfix = (headerver & 0x000ff000) >> 12;

View File

@ -1,17 +0,0 @@
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index 6be647ec..ebddf6c3 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -1537,10 +1537,8 @@ pkcs11_register_provider(char *provider_id, char *pin,
error("dlopen %s failed: %s", provider_module, dlerror());
goto fail;
}
- if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) {
- error("dlsym(C_GetFunctionList) failed: %s", dlerror());
- goto fail;
- }
+ if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL)
+ fatal("dlsym(C_GetFunctionList) failed: %s", dlerror());
p->module->handle = handle;
/* setup the pkcs11 callbacks */

View File

@ -0,0 +1,2 @@
#Type Name ID GECOS Home directory Shell
u sshd 74 "Privilege-separated SSH" /usr/share/empty.sshd -

20
openssh/openssh.pam Normal file
View File

@ -0,0 +1,20 @@
#%PAM-1.0
auth required pam_sepermit.so
auth substack password-auth
auth include postlogin
# Used with polkit to reauthorize users in remote sessions
-auth optional pam_reauthorize.so prepare
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
# Used with polkit to reauthorize users in remote sessions
-session optional pam_reauthorize.so prepare

View File

@ -1,8 +1,8 @@
%bcond_with systemd
%bcond_with X11
%bcond_with seccomp_filter
# Do we want SELinux & Audit
%if 0%{?rhel} < 7
%global noselinux 1
%endif
%if 0%{?!noselinux:1}
%global WITH_SELINUX 1
%else
@ -11,18 +11,14 @@
%global _hardened_build 1
# OpenSSH privilege separation requires a user & group ID
%global sshd_uid 74
%global sshd_gid 74
# Do we want to disable building of gnome-askpass? (1=yes 0=no)
%global no_gnome_askpass 0
# Do we want to link against a static libcrypto? (1=yes 0=no)
%global static_libcrypto 0
# Use GTK2 instead of GNOME in gnome-ssh-askpass
%global gtk2 1
# Use GTK2 in gnome-ssh-askpass
%global gtk3 0
# Build position-independent executables (requires toolchain support)?
%global pie 1
@ -33,9 +29,6 @@
# Do we want libedit support
%global libedit 1
# Do we want NSS tokens support
%define nss 1
# Whether to build pam_ssh_agent_auth
%if 0%{?!nopam:1}
%global pam_ssh_agent 1
@ -43,24 +36,30 @@
%global pam_ssh_agent 0
%endif
%if 0%{?fedora} || 0%{?rhel} >= 8
%global _emptydir %{_datadir}/empty.sshd
%else
%global _emptydir %{_localstatedir}/empty/sshd
%endif
# Reserve options to override askpass settings with:
# rpm -ba|--rebuild --define 'skip_xxx 1'
%{?skip_gnome_askpass:%global no_gnome_askpass 1}
# Add option to build without GTK2 for older platforms with only GTK+.
# Red Hat Linux <= 7.2 and Red Hat Advanced Server 2.1 are examples.
# rpm -ba|--rebuild --define 'no_gtk2 1'
%{?no_gtk2:%global gtk2 0}
# rpm -ba|--rebuild --define 'no_gtk3 1'
%{?no_gtk3:%global gtk3 0}
# Options for static OpenSSL link:
# rpm -ba|--rebuild --define "static_openssl 1"
%{?static_openssl:%global static_libcrypto 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_rel 8
%global openssh_ver 9.3p2
%global openssh_rel 2
%global pam_ssh_agent_ver 0.10.4
%global pam_ssh_agent_rel 8
%global pam_ssh_agent_rel 11
Summary: An open source implementation of SSH protocol version 2
Name: openssh
@ -70,7 +69,15 @@ URL: http://www.openssh.com/portable.html
#URL1: https://github.com/jbeverly/pam_ssh_agent_auth/
Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
Source1: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc
%if 0%{?rhel} >= 8
Source2: sshd.pam
%else
%if 0%{?rhel} == 7
Source2: sshd.pam.el7
%else
Source2: sshd.pam.el6
%endif
%endif
Source3: gpgkey-736060BA.gpg
Source4: https://github.com/jbeverly/pam_ssh_agent_auth/archive/pam_ssh_agent_auth-%{pam_ssh_agent_ver}.tar.gz
Source5: pam_ssh_agent-rmheaders
@ -81,12 +88,17 @@ Source10: sshd.socket
Source11: sshd.service
Source12: sshd-keygen@.service
Source13: sshd-keygen
Source14: sshd.init
Source15: sshd-keygen.target
Source16: ssh-agent.service
Source17: ssh-agent.socket
Source19: openssh-server-systemd-sysusers.conf
Source20: ssh-host-keys-migration.sh
Source21: ssh-host-keys-migration.service
Source20: openssh.ssh_config
Source21: openssh.sshd_config
Source22: openssh.pam
Source23: openssh.ssh_config
Source24: openssh.sshd_config
Source25: sshd.init
#https://bugzilla.mindrot.org/show_bug.cgi?id=2581
Patch100: openssh-6.7p1-coverity.patch
@ -117,6 +129,7 @@ Patch306: pam_ssh_agent_auth-0.10.2-compat.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
Patch309: pam_ssh_agent-configure-c99.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX)
Patch400: openssh-7.8p1-role-mls.patch
@ -127,8 +140,6 @@ Patch502: openssh-6.6p1-keycat.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1644
Patch601: openssh-6.6p1-allow-ip-opts.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1893 (WONTFIX)
Patch604: openssh-6.6p1-keyperm.patch
#(drop?) https://bugzilla.mindrot.org/show_bug.cgi?id=1925
Patch606: openssh-5.9p1-ipv6man.patch
#?
@ -146,12 +157,14 @@ Patch703: openssh-4.3p2-askpass-grab-info.patch
Patch707: openssh-7.7p1-redhat.patch
# warn users for unsupported UsePAM=no (#757545)
Patch711: openssh-7.8p1-UsePAM-warning.patch
# make aes-ctr ciphers use EVP engines such as AES-NI from OpenSSL
Patch712: openssh-6.3p1-ctr-evp-fast.patch
# GSSAPI Key Exchange (RFC 4462 + RFC 8732)
# from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master
Patch800: openssh-8.0p1-gssapi-keyex.patch
# and
# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures
# upstream MR:
# https://github.com/openssh-gsskex/openssh-gsskex/pull/21
Patch800: openssh-9.3p1-gssapi-keyex.patch
#http://www.mail-archive.com/kerberos@mit.edu/msg17591.html
Patch801: openssh-6.6p1-force_krb.patch
# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843)
@ -191,13 +204,15 @@ Patch950: openssh-7.5p1-sandbox.patch
# PKCS#11 URIs (upstream #2817, 2nd iteration)
# https://github.com/Jakuje/openssh-portable/commits/jjelen-pkcs11
# git show > ~/devel/fedora/openssh/openssh-8.0p1-pkcs11-uri.patch
Patch951: openssh-8.0p1-pkcs11-uri.patch
Patch951: openssh-9.3p2-pkcs11-uri.patch
# Unbreak scp between two IPv6 hosts (#1620333)
Patch953: openssh-7.8p1-scp-ipv6.patch
# Mention crypto-policies in manual pages (#1668325)
# clarify rhbz#2068423 on the man page of ssh_config
Patch962: openssh-8.0p1-crypto-policies.patch
# Use OpenSSL high-level API to produce and verify signatures (#1707485)
Patch963: openssh-8.0p1-openssl-evp.patch
# TODO fix the comment above ^
Patch963: openssh-9.3p1-merged-openssl-evp.patch
# Use OpenSSL KDF (#1631761)
Patch964: openssh-8.0p1-openssl-kdf.patch
# sk-dummy.so built with -fvisibility=hidden does not work
@ -208,16 +223,10 @@ Patch966: openssh-8.2p1-x11-without-ipv6.patch
Patch974: openssh-8.0p1-keygen-strip-doseol.patch
# sshd provides PAM an incorrect error code (#1879503)
Patch975: openssh-8.0p1-preserve-pam-errors.patch
# Use SFTP protocol by default for scp command
Patch976: openssh-8.7p1-sftp-default-protocol.patch
# Implement kill switch for SCP protocol
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
@ -225,62 +234,36 @@ Patch980: openssh-8.7p1-sftpscp-dir-create.patch
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
# CVE-2023-25136
Patch1007: openssh-8.7p1-CVE-2023-25136.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
Patch1015: openssh-9.3p1-upstream-cve-2023-38408.patch
Patch1012: openssh-9.0p1-evp-fips-dh.patch
Patch1013: openssh-9.0p1-evp-fips-ecdh.patch
Patch1014: openssh-8.7p1-nohostsha1proof.patch
License: BSD
# upstream b7afd8a4ecaca8afd3179b55e9db79c0ff210237
Patch1016: openssh-9.3p1-openssl-compat.patch
License: BSD-3-Clause AND BSD-2-Clause AND ISC AND SSH-OpenSSH AND ssh-keyscan AND sprintf AND LicenseRef-Fedora-Public-Domain AND X11-distribute-modifications-variant
Requires: /sbin/nologin
%if ! %{no_gnome_askpass}
%if %{gtk2}
BuildRequires: gtk2-devel
BuildRequires: libX11-devel
%if %{gtk3}
BuildRequires: gtk3-devel
%else
BuildRequires: gnome-libs-devel
BuildRequires: gtk2-devel
%endif
%endif
@ -288,25 +271,26 @@ BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel
BuildRequires: audit-libs-devel >= 2.0.5
BuildRequires: util-linux, groff
BuildRequires: pam-devel
BuildRequires: openssl3-devel
%if 0%{?rhel} < 7
BuildRequires: perl
%else
BuildRequires: openssl3-devel >= 0.9.8j
%if 0%{?fedora} || 0%{?rhel} >= 7
BuildRequires: perl-podlators
%endif
%if %{with systemd}
BuildRequires: systemd-devel
BuildRequires: systemd-rpm-macros
%else
BuildRequires: perl
%endif
%if 0%{?fedora} || 0%{?rhel} >= 7
BuildRequires: gcc
%else
BuildRequires: devtoolset-8-gcc devtoolset-8-build
%if 0%{?rhel} < 7
BuildRequires: autoconf2.69 automake1.16 m4_next
%endif
%endif
BuildRequires: make
%if 0%{?rhel} <= 6
BuildRequires: devtoolset-8-gcc devtoolset-8-gcc-c++ devtoolset-8-build
BuildRequires: autoconf automake1.16 m4
%else
BuildRequires: gcc
%endif
BuildRequires: p11-kit-devel
BuildRequires: libfido2-devel
Requires: p11-kit
Obsoletes: openssh-ldap < 8.3p1-4
Obsoletes: openssh-cavs < 8.4p1-5
@ -318,26 +302,23 @@ BuildRequires: krb5-devel
BuildRequires: libedit-devel ncurses-devel
%endif
%if %{nss}
BuildRequires: nss-devel
%endif
%if %{WITH_SELINUX}
Requires: libselinux
BuildRequires: libselinux-devel
Requires: audit-libs >= 1.0.8
BuildRequires: audit-libs >= 1.0.8
BuildRequires: pkgconfig(libseccomp)
%endif
BuildRequires: xauth
# for tarball signature verification
BuildRequires: gnupg2
Requires: openssh-clients = %{version}-%{release}
%package clients
Summary: An open source SSH client applications
%if 0%{?fedora} || 0%{?rhel} >= 8
Requires: crypto-policies >= 20200610-1
Requires: openssh = %{version}-%{release}
%if 0%{?rhel} >= 8
Requires: crypto-policies >= 20220824-1
%endif
%package server
@ -345,21 +326,15 @@ Summary: An open source SSH server daemon
Requires: openssh = %{version}-%{release}
Requires(pre): /usr/sbin/useradd
Requires: pam >= 1.0.1-3
%if 0%{?fedora} || 0%{?rhel} >= 8
Requires: crypto-policies >= 20200610-1
%if 0%{?rhel} >= 8
Requires: crypto-policies >= 20220824-1
%endif
%if %{without systemd}
Requires(post): chkconfig >= 0.9, /sbin/service
%else
%if 0%{?fedora} || 0%{?rhel} >= 7
%{?systemd_requires}
%package server-sysvinit
Summary: The SysV initscript to manage the OpenSSH server.
Group: System Environment/Daemons
Requires: %{name}-server%{?_isa} = %{version}-%{release}
%else
Requires(post): chkconfig >= 0.9, /sbin/service
%endif
%package keycat
Summary: A mls keycat backend for openssh
Requires: openssh = %{version}-%{release}
@ -368,11 +343,15 @@ Requires: openssh = %{version}-%{release}
Summary: A passphrase dialog for OpenSSH and X
Requires: openssh = %{version}-%{release}
%package sk-dummy
Summary: OpenSSH SK driver for test purposes
Requires: openssh = %{version}-%{release}
%package -n pam_ssh_agent_auth
Summary: PAM module for authentication with ssh-agent
Version: %{pam_ssh_agent_ver}
Release: %{pam_ssh_agent_rel}.%{openssh_rel}%{?dist}
License: BSD
License: BSD-3-Clause AND BSD-2-Clause AND ISC AND SSH-OpenSSH AND ssh-keyscan AND sprintf AND LicenseRef-Fedora-Public-Domain AND X11-distribute-modifications-variant AND OpenSSL
%description
SSH (Secure SHell) is a program for logging into and executing
@ -399,17 +378,6 @@ into and executing commands on a remote machine. This package contains
the secure shell daemon (sshd). The sshd daemon allows SSH clients to
securely connect to your SSH server.
%if %{with systemd}
%description server-sysvinit
OpenSSH is a free version of SSH (Secure SHell), a program for logging
into and executing commands on a remote machine. This package contains
the SysV init script to manage the OpenSSH server when running a legacy
SysV-compatible init system.
It is not required when the init system used is systemd.
%endif
%description keycat
OpenSSH mls keycat is backend for using the authorized keys in the
openssh in the mls mode.
@ -419,6 +387,9 @@ OpenSSH is a free version of SSH (Secure SHell), a program for logging
into and executing commands on a remote machine. This package contains
an X11 passphrase dialog for OpenSSH.
%description sk-dummy
This package contains a test SK driver used for OpenSSH test purposes
%description -n pam_ssh_agent_auth
This package contains a PAM module which can be used to authenticate
users using ssh keys stored in a ssh-agent. Through the use of the
@ -439,6 +410,8 @@ pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
%patch306 -p2 -b .psaa-compat
%patch305 -p2 -b .psaa-agent
%patch307 -p2 -b .psaa-deref
%patch308 -p2 -b .rsasha2
%patch309 -p1 -b .psaa-configure-c99
# Remove duplicate headers and library files
rm -f $(cat %{SOURCE5})
popd
@ -450,7 +423,6 @@ popd
%patch502 -p1 -b .keycat
%patch601 -p1 -b .ip-opts
%patch604 -p1 -b .keyperm
%patch606 -p1 -b .ipv6man
%patch607 -p1 -b .sigpipe
%patch609 -p1 -b .x11
@ -458,7 +430,6 @@ popd
%patch703 -p1 -b .grab-info
%patch707 -p1 -b .redhat
%patch711 -p1 -b .log-usepam-no
%patch712 -p1 -b .evp-ctr
#
%patch800 -p1 -b .gsskex
%patch801 -p1 -b .force_krb
@ -480,42 +451,38 @@ popd
%patch950 -p1 -b .sandbox
%patch951 -p1 -b .pkcs11-uri
%patch953 -p1 -b .scp-ipv6
%if 0%{?fedora} || 0%{?rhel} >= 8
%if 0%{?rhel} >= 8
%patch962 -p1 -b .crypto-policies
%if ! 0%{?rhel} == 8
%endif
%patch963 -p1 -b .openssl-evp
%endif
%endif
%patch964 -p1 -b .openssl-kdf
%patch965 -p1 -b .visibility
%patch966 -p1 -b .x11-ipv6
%patch974 -p1 -b .keygen-strip-doseol
%patch975 -p1 -b .preserve-pam-errors
%patch976 -p1 -b .sftp-by-default
%patch977 -p1 -b .kill-scp
%patch981 -p1 -b .scp-sftpdirs
%patch982 -p1 -b .minrsabits
%patch984 -p1 -b .ibmca
%patch200 -p1 -b .audit
%patch201 -p1 -b .audit-race
#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
%patch1007 -p1 -b .cve-2023-25136
%patch202 -p1 -b .audit-log
%patch700 -p1 -b .fips
%patch1100 -p1 -b .skipsshrsadsstests
%patch1002 -p1 -b .ssh-manpage
%patch1006 -p1 -b .negotiate-supported-algs
%patch1012 -p1 -b .evp-fips-dh
%patch1013 -p1 -b .evp-fips-ecdh
%patch1014 -p1 -b .nosha1hostproof
%patch1016 -p1 -b .ossl-version
%patch100 -p1 -b .coverity
%patch1015 -p1 -b .cve-2023-38408
%build
%if 0%{?rhel} < 8
%enable_devtoolset8
%endif
%if 0%{?rhel} < 7
. /etc/profile.d/modules.sh
module load autoconf
@ -528,17 +495,32 @@ pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
autoreconf
popd
%build
%if 0%{?rhel} < 8
%enable_devtoolset8
%endif
%if 0%{?rhel} < 7
. /etc/profile.d/modules.sh
module load autoconf
module load automake
module load m4
%endif
%set_build_flags
# the -fvisibility=hidden is needed for clean build of the pam_ssh_agent_auth
# it is needed for lib(open)ssh build too since it is linked to the pam module too
CFLAGS="$RPM_OPT_FLAGS -I%{_includedir}/openssl3 -fvisibility=hidden"; export CFLAGS
CFLAGS="$CFLAGS -I%{_includedir}/openssl3 -fvisibility=hidden"; export CFLAGS
%if %{pie}
%ifarch s390 s390x sparc sparcv9 sparc64
CFLAGS="$CFLAGS -fPIC"
%else
CFLAGS="$CFLAGS -fpic"
%endif
SAVE_LDFLAGS="$LDFLAGS -lrt"
LDFLAGS="$LDFLAGS -lrt -pie -z relro -z now"
SAVE_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -pie -z relro -z now"
%if 0%{?rhel} < 7
LDFLAGS="$LDFLAGS -lrt"
%endif
export CFLAGS
export LDFLAGS
@ -564,33 +546,30 @@ fi
--sysconfdir=%{_sysconfdir}/ssh \
--libexecdir=%{_libexecdir}/openssh \
--datadir=%{_datadir}/openssh \
--enable-vendor-patchlevel="RHEL10-%{openssh_ver}-%{openssh_rel}" \
%if 0%{?fedora} || 0%{?rhel} >= 7
--with-default-path=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin \
--with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \
%else
--with-default-path=/usr/local/bin:/bin:/usr/bin \
--with-superuser-path=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin \
--with-privsep-path=%{_var}/empty/sshd \
--enable-vendor-patchlevel="RHEL9-%{openssh_ver}-%{openssh_rel}" \
%endif
--with-privsep-path=%{_emptydir} \
--disable-strip \
--with-tcp-wrappers \
--without-zlib-version-check \
--with-ssl-engine \
--with-ipaddr-display \
--with-pie=no \
--without-hardening `# The hardening flags are configured by system` \
%if %{nss}
--with-nss \
%endif
%if %{with systemd}
%if 0%{?fedora} || 0%{?rhel} >= 7
--with-systemd \
%endif
--with-default-pkcs11-provider=yes \
--with-security-key-builtin=yes \
--with-pam \
%if %{WITH_SELINUX}
--with-selinux --with-audit=linux \
%if %{with seccomp_filter}
--with-sandbox=seccomp_filter \
%else
--with-sandbox=rlimit \
%endif
--with-selinux --with-audit=linux \
--with-sandbox=seccomp_filter \
%endif
%if %{kerberos5}
--with-kerberos5${krb5_prefix:+=${krb5_prefix}} \
@ -608,32 +587,38 @@ perl -pi -e "s|-lcrypto|%{_libdir}/libcrypto.a|g" Makefile
%endif
%make_build
make regress/misc/sk-dummy/sk-dummy.so
# Define a variable to toggle gnome1/gtk2 building. This is necessary
# Define a variable to toggle gtk2/gtk3 building. This is necessary
# because RPM doesn't handle nested %%if statements.
%if %{gtk2}
gtk2=yes
%if %{gtk3}
gtk3=yes
%else
gtk2=no
gtk3=no
%endif
%if ! %{no_gnome_askpass}
pushd contrib
if [ $gtk2 = yes ] ; then
if [ $gtk3 = yes ] ; then
CFLAGS="$CFLAGS %{?__global_ldflags}" \
make gnome-ssh-askpass3
mv gnome-ssh-askpass3 gnome-ssh-askpass
else
CFLAGS="$CFLAGS %{?__global_ldflags}" \
make gnome-ssh-askpass2
mv gnome-ssh-askpass2 gnome-ssh-askpass
else
CFLAGS="$CFLAGS %{?__global_ldflags}"
make gnome-ssh-askpass1
mv gnome-ssh-askpass1 gnome-ssh-askpass
fi
popd
%endif
%if %{pam_ssh_agent}
pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
LDFLAGS="$SAVE_LDFLAGS"
LDFLAGS="$SAVE_LDFLAGS -ldl"
%if 0%{?rhel} < 7
LDFLAGS="$LDFLAGS -lrt"
%endif
%configure --with-selinux \
--libexecdir=/%{_libdir}/security \
--with-mantype=man \
@ -651,29 +636,29 @@ make tests
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh
%if 0%{?fedora} || 0%{?rhel} >= 8
mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh/ssh_config.d
mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh/sshd_config.d
%endif
mkdir -p -m755 $RPM_BUILD_ROOT%{_libexecdir}/openssh
%make_install
install -d $RPM_BUILD_ROOT/etc/pam.d/
install -d $RPM_BUILD_ROOT/etc/sysconfig/
install -d $RPM_BUILD_ROOT%{_libexecdir}/openssh
install -m644 %{SOURCE2} $RPM_BUILD_ROOT/etc/pam.d/sshd
install -m644 %{SOURCE6} $RPM_BUILD_ROOT/etc/pam.d/ssh-keycat
install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/sysconfig/sshd
%if 0%{?fedora} || 0%{?rhel} >= 8
install -m644 ssh_config_redhat $RPM_BUILD_ROOT/etc/ssh/ssh_config.d/50-redhat.conf
install -m644 sshd_config_redhat $RPM_BUILD_ROOT/etc/ssh/sshd_config.d/50-redhat.conf
install -m644 ssh_config_redhat $RPM_BUILD_ROOT%{_sysconfdir}/ssh/ssh_config.d/50-redhat.conf
install -m644 sshd_config_redhat_cp $RPM_BUILD_ROOT%{_sysconfdir}/ssh/sshd_config.d/40-redhat-crypto-policies.conf
install -m644 sshd_config_redhat $RPM_BUILD_ROOT%{_sysconfdir}/ssh/sshd_config.d/50-redhat.conf
install -m644 %{SOURCE2} $RPM_BUILD_ROOT/etc/pam.d/sshd
%else
install -m 644 %{SOURCE20} $RPM_BUILD_ROOT%{_sysconfdir}/ssh/ssh_config
install -m 644 %{SOURCE21} $RPM_BUILD_ROOT%{_sysconfdir}/ssh/sshd_config
install -m 644 %{SOURCE23} $RPM_BUILD_ROOT%{_sysconfdir}/ssh/ssh_config
install -m 644 %{SOURCE24} $RPM_BUILD_ROOT%{_sysconfdir}/ssh/sshd_config
%endif
install -m 644 %{SOURCE2} $RPM_BUILD_ROOT/etc/pam.d/sshd
install -m644 %{SOURCE6} $RPM_BUILD_ROOT/etc/pam.d/ssh-keycat
install -d $RPM_BUILD_ROOT/etc/rc.d/init.d
install -m755 %{SOURCE14} $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd
%if %{with systemd}
install -m755 contrib/ssh-copy-id $RPM_BUILD_ROOT%{_bindir}/
install contrib/ssh-copy-id.1 $RPM_BUILD_ROOT%{_mandir}/man1/
%if 0%{?rhel} >= 7
install -d -m755 $RPM_BUILD_ROOT/%{_unitdir}
install -m644 %{SOURCE9} $RPM_BUILD_ROOT/%{_unitdir}/sshd@.service
install -m644 %{SOURCE10} $RPM_BUILD_ROOT/%{_unitdir}/sshd.socket
@ -682,11 +667,21 @@ install -m644 %{SOURCE12} $RPM_BUILD_ROOT/%{_unitdir}/sshd-keygen@.service
install -m644 %{SOURCE15} $RPM_BUILD_ROOT/%{_unitdir}/sshd-keygen.target
install -d -m755 $RPM_BUILD_ROOT/%{_userunitdir}
install -m644 %{SOURCE16} $RPM_BUILD_ROOT/%{_userunitdir}/ssh-agent.service
%endif
install -m644 %{SOURCE17} $RPM_BUILD_ROOT/%{_userunitdir}/ssh-agent.socket
install -m744 %{SOURCE13} $RPM_BUILD_ROOT/%{_libexecdir}/openssh/sshd-keygen
install -m755 contrib/ssh-copy-id $RPM_BUILD_ROOT%{_bindir}/
install contrib/ssh-copy-id.1 $RPM_BUILD_ROOT%{_mandir}/man1/
install -d -m711 ${RPM_BUILD_ROOT}/%{_var}/empty/sshd
install -d -m711 ${RPM_BUILD_ROOT}/%{_emptydir}
install -p -D -m 0644 %{SOURCE19} %{buildroot}%{_sysusersdir}/openssh-server.conf
# Migration service/script for Fedora 38 change to remove group ownership for standard host keys
# See https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
install -m744 %{SOURCE20} $RPM_BUILD_ROOT/%{_libexecdir}/openssh/ssh-host-keys-migration.sh
# Pulled-in via a `Wants=` in `sshd.service` & `sshd@.service`
install -m644 %{SOURCE21} $RPM_BUILD_ROOT/%{_unitdir}/ssh-host-keys-migration.service
install -d $RPM_BUILD_ROOT/%{_localstatedir}/lib
touch $RPM_BUILD_ROOT/%{_localstatedir}/lib/.ssh-host-keys-migration
%else
install -d $RPM_BUILD_ROOT/etc/rc.d/init.d
install -m755 %{SOURCE25} $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd
%endif
%if ! %{no_gnome_askpass}
install contrib/gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/gnome-ssh-askpass
@ -710,6 +705,10 @@ pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}
%make_install
popd
%endif
install -m 755 -d $RPM_BUILD_ROOT%{_libdir}/sshtest/
install -m 755 regress/misc/sk-dummy/sk-dummy.so $RPM_BUILD_ROOT%{_libdir}/sshtest
%pre
getent group ssh_keys >/dev/null || groupadd -r ssh_keys || :
@ -717,48 +716,68 @@ getent group ssh_keys >/dev/null || groupadd -r ssh_keys || :
getent group sshd >/dev/null || groupadd -g %{sshd_uid} -r sshd || :
getent passwd sshd >/dev/null || \
useradd -c "Privilege-separated SSH" -u %{sshd_uid} -g sshd \
-s /sbin/nologin -r -d %{_var}/empty/sshd sshd 2> /dev/null || :
-s /sbin/nologin -r -d %{_emptydir} sshd 2> /dev/null || :
%if %{with systemd}
%post server
%if 0%{?fedora} || 0%{?rhel} >= 7
%systemd_post sshd.service sshd.socket
%preun server
%systemd_preun sshd.service sshd.socket
%postun server
%systemd_postun_with_restart sshd.service
%post clients
%systemd_user_post ssh-agent.service
%preun clients
%systemd_user_preun ssh-agent.service
%else
%post server
/sbin/chkconfig --add sshd
%else
%postun server
/sbin/service sshd condrestart > /dev/null 2>&1 || :
%endif
%if 0%{?fedora} || 0%{?rhel} >= 8
# Migration scriptlet for Fedora 31 and 32 installations to sshd_config
# drop-in directory (in F32+).
# Do this only if the file generated by anaconda exists, contains our config
# directive and sshd_config contains include directive as shipped in our package
%global sysconfig_anaconda /etc/sysconfig/sshd-permitrootlogin
test -f %{sysconfig_anaconda} && \
test ! -f /etc/ssh/sshd_config.d/01-permitrootlogin.conf && \
grep -q '^PERMITROOTLOGIN="-oPermitRootLogin=yes"' %{sysconfig_anaconda} && \
grep -q '^Include /etc/ssh/sshd_config.d/\*.conf' /etc/ssh/sshd_config && \
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config.d/25-permitrootlogin.conf && \
rm %{sysconfig_anaconda} || :
%endif
%preun server
%if 0%{?fedora} || 0%{?rhel} >= 7
%systemd_preun sshd.service sshd.socket
%else
if [ "$1" = 0 ]
then
/sbin/service sshd stop > /dev/null 2>&1 || :
/sbin/chkconfig --del sshd
fi
%endif
%postun server
%if 0%{?fedora} || 0%{?rhel} >= 7
%systemd_postun_with_restart sshd.service
%else
/sbin/service sshd condrestart > /dev/null 2>&1 || :
%endif
%post clients
%if 0%{?fedora} || 0%{?rhel} >= 7
%systemd_user_post ssh-agent.service
%systemd_user_post ssh-agent.socket
%endif
%preun clients
%if 0%{?fedora} || 0%{?rhel} >= 7
%systemd_user_preun ssh-agent.service
%systemd_user_preun ssh-agent.socket
%endif
%files
%doc LICENCE
%doc CREDITS ChangeLog OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns TODO
%doc CREDITS ChangeLog OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns TODO LICENCE
%attr(0755,root,root) %dir %{_sysconfdir}/ssh
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli
%attr(0755,root,root) %{_bindir}/ssh-keygen
%attr(0644,root,root) %{_mandir}/man1/ssh-keygen.1*
%attr(0755,root,root) %dir %{_libexecdir}/openssh
%attr(2555,root,ssh_keys) %{_libexecdir}/openssh/ssh-keysign
%attr(4555,root,root) %{_libexecdir}/openssh/ssh-keysign
%attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8*
%files clients
@ -767,8 +786,8 @@ fi
%attr(0755,root,root) %{_bindir}/scp
%attr(0644,root,root) %{_mandir}/man1/scp.1*
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config
%if 0%{?fedora} || 0%{?rhel} >= 8
%dir %attr(0755,root,root) %{_sysconfdir}/ssh/ssh_config.d/
%if 0%{?fedora} || 0%{?rhel} >= 8
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config.d/50-redhat.conf
%endif
%attr(0644,root,root) %{_mandir}/man5/ssh_config.5*
@ -786,38 +805,40 @@ fi
%attr(0644,root,root) %{_mandir}/man1/ssh-copy-id.1*
%attr(0644,root,root) %{_mandir}/man8/ssh-pkcs11-helper.8*
%attr(0644,root,root) %{_mandir}/man8/ssh-sk-helper.8*
%if %{with systemd}
%if 0%{?fedora} || 0%{?rhel} >= 7
%attr(0644,root,root) %{_userunitdir}/ssh-agent.service
%attr(0644,root,root) %{_userunitdir}/ssh-agent.socket
%endif
%files server
%dir %attr(0711,root,root) %{_var}/empty/sshd
%dir %attr(0711,root,root) %{_emptydir}
%attr(0755,root,root) %{_sbindir}/sshd
%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-keygen
%attr(0644,root,root) %{_mandir}/man5/sshd_config.5*
%attr(0644,root,root) %{_mandir}/man5/moduli.5*
%attr(0644,root,root) %{_mandir}/man8/sshd.8*
%attr(0644,root,root) %{_mandir}/man8/sftp-server.8*
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config
%if 0%{?fedora} || 0%{?rhel} >= 8
%dir %attr(0700,root,root) %{_sysconfdir}/ssh/sshd_config.d/
%if 0%{?fedora} || 0%{?rhel} >= 8
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config.d/40-redhat-crypto-policies.conf
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config.d/50-redhat.conf
%endif
%attr(0644,root,root) %config(noreplace) /etc/pam.d/sshd
%attr(0640,root,root) %config(noreplace) /etc/sysconfig/sshd
%if %{without systemd}
%attr(0755,root,root) /etc/rc.d/init.d/sshd
%else
%if 0%{?fedora} || 0%{?rhel} >= 7
%attr(0644,root,root) %{_unitdir}/sshd.service
%attr(0644,root,root) %{_unitdir}/sshd@.service
%attr(0644,root,root) %{_unitdir}/sshd.socket
%attr(0644,root,root) %{_unitdir}/sshd-keygen@.service
%attr(0644,root,root) %{_unitdir}/sshd-keygen.target
%files server-sysvinit
%defattr(-,root,root)
%attr(0644,root,root) %{_sysusersdir}/openssh-server.conf
%attr(0644,root,root) %{_unitdir}/ssh-host-keys-migration.service
%attr(0744,root,root) %{_libexecdir}/openssh/ssh-host-keys-migration.sh
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-keygen
%ghost %attr(0644,root,root) %{_localstatedir}/lib/.ssh-host-keys-migration
%else
%attr(0755,root,root) /etc/rc.d/init.d/sshd
%endif
@ -833,19 +854,29 @@ fi
%attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass
%endif
%files sk-dummy
%attr(0755,root,root) %{_libdir}/sshtest/sk-dummy.so
%if %{pam_ssh_agent}
%files -n pam_ssh_agent_auth
%if 0%{?fedora} || 0%{?rhel} >= 8
%license pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}/OPENSSH_LICENSE
%else
%doc pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}/OPENSSH_LICENSE
%endif
%attr(0755,root,root) %{_libdir}/security/pam_ssh_agent_auth.so
%attr(0644,root,root) %{_mandir}/man8/pam_ssh_agent_auth.8*
%endif
%changelog
* Fri Oct 6 2023 Raven <raven@sysadmins.ws> - 8.8p1-8
- Use /var/empty/sshd instead of /usr/share/emty.sshd
* Fri Oct 20 2023 Raven <raven@sysadmins.ws> - 9.3p2-1
- add pam config ported from proper rhel versions
* Fri Oct 6 2023 Raven <raven@sysadmins.ws> - 8.8p1-6
- add /bin and /sbin to PATH
* Fri Oct 20 2023 Raven <raven@sysadmins.ws> - 9.3p2-1
- New upstream release
* Thu Oct 19 2023 Raven <raven@sysadmins.ws> - 9.3p1-1
- New upstream release
* Tue Apr 12 2022 Raven <raven@sysadmins.ws> - 8.8p1-4
- import ciphers and keyring settings from crypto-policies
@ -860,59 +891,37 @@ fi
* Tue Apr 12 2022 Raven <raven@sysadmins.ws> - 8.8p1-1
- New upstream release
* Mon Oct 25 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-4
- Fix memory leaks introduced in OpenSSH 8.7
Related: rhbz#2001002
* Wed Sep 29 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-3
- CVE-2021-41617 fix (#2008292)
* Tue Oct 19 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-3
- Disable locale forwarding in default configurations
Related: rhbz#2002734
* Thu Sep 16 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-2
- Use SFTP protocol for scp by default (#2004956)
* Fri Oct 01 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-2
- Upstream fix for CVE-2021-41617
Related: rhbz#2008886
* Tue Sep 14 2021 Sahana Prasad <sahana@redhat.com> - 8.7p1-1.1
- Rebuilt with OpenSSL 3.0.0
* Fri Sep 24 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-1 + 0.10.4-4
- New upstream release
- Switch to SFTP protocol in scp utility by default
- Enable SCP protocol kill switch
Related: rhbz#2001002
* Wed Sep 01 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.7p1-1 + 0.10.4-4
- New upstream release (#1995893)
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 8.6p1-7.1
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 8.6p1-5.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Wed Jul 28 2021 Florian Weimer <fweimer@redhat.com> - 8.6p1-7
- Rebuild to pick up OpenSSL 3.0 Beta ABI (#1984097)
* Mon Jun 21 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.6p1-5
- restore the blocking mode on standard output (#1942901) - upstream
* Mon Jun 21 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.6p1-6
- rebuilt
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 8.6p1-5.1
- Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065
* Thu Jun 03 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.6p1-5
- Remove recommendation of p11-kit (#1947904)
* Tue Jun 01 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.6p1-4
- rebuilt
* Tue May 25 2021 Timm Bäder <tbaeder@redhat.com> - 8.6p1-4
- Use %%set_build_flags to set all builds flags
* Fri May 21 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.6p1-3
- Hostbased ssh authentication fails if session ID contains a '/' (#1963058)
- Hostbased ssh authentication fails if session ID contains a '/' (#1963059)
* Mon May 10 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.6p1-2
- rebuilt
- restore the blocking mode on standard output (#1942901)
* Thu May 06 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.6p1-1 + 0.10.4-3
- New upstream release (#1952957)
- GSS KEX broken beginning with (GSI-)OpenSSH 8.0p1 (#1957306)
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 8.5p1-3.1
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Apr 13 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.5p1-3
- Coverity fixes for 8.5p1 (#1938831)
* Mon Apr 19 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 8.6p1-1 + 0.10.4-3
- New upstream release (#1950819)
- ssh-keygen printing fingerprint issue with Windows keys (#1901518)
- sshd provides PAM an incorrect error code (#1879503)
* Tue Mar 09 2021 Rex Dieter <rdieter@fedoraproject.org> - 8.5p1-2
- ssh-agent.serivce is user unit (#1761817#27)

View File

@ -3,7 +3,7 @@
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin:/bin
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
@ -36,14 +36,13 @@ CASignatureAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp52
# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
PermitRootLogin yes
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
@ -73,7 +72,6 @@ AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no
# Kerberos options
@ -110,7 +108,7 @@ X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no

View File

@ -0,0 +1,249 @@
configure.ac: Improve C99 compatibility
Future compilers will not support implicit declarations and implicit
ints by default. This means that configure probes which rely on them
will fail unconditionally, without actually testing anything.
The changes mostly mirror what has been implemented in the openssh
repository, but had to be adapted somewhat because of drift between
the two versions of configure.ac.
Sam James has submitted similar fixes upstream:
<https://github.com/jbeverly/pam_ssh_agent_auth/pull/41>
diff --git a/configure.ac b/configure.ac
index 6496679..d927b62 100644
--- a/configure.ac
+++ b/configure.ac
@@ -500,10 +500,10 @@ int main(void) { exit(0); }
AC_DEFINE(HAVE_BUNDLE, 1, [Define if your system uses bundles instead of ELF shared objects])
AC_MSG_CHECKING(if we have working getaddrinfo)
AC_TRY_RUN([#include <mach-o/dyld.h>
-main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
- exit(0);
+int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
+ return 0;
else
- exit(1);
+ return 1;
}], [AC_MSG_RESULT(working)],
[AC_MSG_RESULT(buggy)
AC_DEFINE(BROKEN_GETADDRINFO, 1, [getaddrinfo is broken (if present)])],
@@ -917,8 +917,8 @@ AC_SUBST(LDFLAGS_SHARED)
AC_MSG_CHECKING(compiler and flags for sanity)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([
-#include <stdio.h>
-int main(){exit(0);}
+#include <stdlib.h>
+int main(void){exit(0);}
])],
[ AC_MSG_RESULT(yes) ],
[
@@ -951,9 +951,9 @@ int main(int argc, char **argv) {
strncpy(buf,"/etc", 32);
s = dirname(buf);
if (!s || strncmp(s, "/", 32) != 0) {
- exit(1);
+ return 1;
} else {
- exit(0);
+ return 0;
}
}
]])],
@@ -1102,7 +1102,7 @@ AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <sys/types.h>
#include <dirent.h>
-int main(void){struct dirent d;exit(sizeof(d.d_name)<=sizeof(char));}
+int main(void){struct dirent d;return sizeof(d.d_name)<=sizeof(char);}
]])],
[AC_MSG_RESULT(yes)],
[
@@ -1327,8 +1327,10 @@ AC_CHECK_FUNCS(setresuid, [
AC_MSG_CHECKING(if setresuid seems to work)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
+#define _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
+#include <unistd.h>
int main(){errno=0; setresuid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
]])],
[AC_MSG_RESULT(yes)],
@@ -1344,8 +1346,10 @@ AC_CHECK_FUNCS(setresgid, [
AC_MSG_CHECKING(if setresgid seems to work)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
+#define _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
+#include <unistd.h>
int main(){errno=0; setresgid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
]])],
[AC_MSG_RESULT(yes)],
@@ -1384,7 +1388,7 @@ if test "x$ac_cv_func_snprintf" = "xyes" ; then
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <stdio.h>
-int main(void){char b[5];snprintf(b,5,"123456789");exit(b[4]!='\0');}
+int main(void){char b[5];snprintf(b,5,"123456789");return b[4]!='\0';}
]])],
[AC_MSG_RESULT(yes)],
[
@@ -1418,7 +1422,7 @@ int x_snprintf(char *str,size_t count,const char *fmt,...)
int main(void)
{
char x[1];
- exit(x_snprintf(x, 1, "%s %d", "hello", 12345) == 11 ? 0 : 1);
+ return x_snprintf(x, 1, "%s %d", "hello", 12345) == 11 ? 0 : 1;
} ]])],
[AC_MSG_RESULT(yes)],
[
@@ -1467,7 +1471,8 @@ AC_MSG_CHECKING([for (overly) strict mkstemp])
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <stdlib.h>
-main() { char template[]="conftest.mkstemp-test";
+#include <unistd.h>
+int main(void) { char template[]="conftest.mkstemp-test";
if (mkstemp(template) == -1)
exit(1);
unlink(template); exit(0);
@@ -1492,10 +1497,14 @@ if test ! -z "$check_for_openpty_ctty_bug"; then
AC_MSG_CHECKING(if openpty correctly handles controlling tty)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
+#include <stdlib.h>
#include <stdio.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
+#ifdef HAVE_PTY_H
+#include <pty.h>
+#endif
int
main()
@@ -1543,6 +1552,7 @@ if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <stdio.h>
+#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
@@ -1748,6 +1758,7 @@ AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL, 1,
AC_MSG_CHECKING([OpenSSL header version])
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/opensslv.h>
@@ -1794,12 +1805,12 @@ int main(void) {
fd = fopen(DATA,"w");
if(fd == NULL)
- exit(1);
+ return 1;
if ((rc = fprintf(fd ,"%x (%s)\n", SSLeay(), SSLeay_version(SSLEAY_VERSION))) <0)
- exit(1);
+ return 1;
- exit(0);
+ return 0;
}
]])],
[
@@ -1829,7 +1840,7 @@ AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <string.h>
#include <openssl/opensslv.h>
-int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); }
+int main(void) { return SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1; }
]])],
[
AC_MSG_RESULT(yes)
@@ -2598,7 +2609,7 @@ dnl test snprintf (broken on SCO w/gcc)
#include <stdio.h>
#include <string.h>
#ifdef HAVE_SNPRINTF
-main()
+int main(void)
{
char buf[50];
char expected_out[50];
@@ -2611,11 +2622,11 @@ main()
strcpy(expected_out, "9223372036854775807");
snprintf(buf, mazsize, "%lld", num);
if(strcmp(buf, expected_out) != 0)
- exit(1);
- exit(0);
+ return 1;
+ return 0;
}
#else
-main() { exit(0); }
+int main(void) { return 0; }
#endif
]])], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ],
AC_MSG_WARN([cross compiling: Assuming working snprintf()])
@@ -2746,11 +2757,11 @@ AC_CACHE_CHECK([for msg_accrights field in struct msghdr],
int main() {
#ifdef msg_accrights
#error "msg_accrights is a macro"
-exit(1);
+return 1;
#endif
struct msghdr m;
m.msg_accrights = 0;
-exit(0);
+return 0;
}
])],
[ ac_cv_have_accrights_in_msghdr="yes" ],
@@ -2773,11 +2784,11 @@ AC_CACHE_CHECK([for msg_control field in struct msghdr],
int main() {
#ifdef msg_control
#error "msg_control is a macro"
-exit(1);
+return 1;
#endif
struct msghdr m;
m.msg_control = 0;
-exit(0);
+return 0;
}
])],
[ ac_cv_have_control_in_msghdr="yes" ],
@@ -2791,7 +2802,7 @@ if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then
fi
AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [
- AC_TRY_LINK([],
+ AC_TRY_LINK([#include <stdio.h>],
[ extern char *__progname; printf("%s", __progname); ],
[ ac_cv_libc_defines___progname="yes" ],
[ ac_cv_libc_defines___progname="no" ]
@@ -2871,7 +2882,7 @@ if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then
fi
AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [
- AC_TRY_LINK([],
+ AC_TRY_LINK([#include <stdio.h>],
[ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);],
[ ac_cv_libc_defines_sys_errlist="yes" ],
[ ac_cv_libc_defines_sys_errlist="no" ]
@@ -2884,7 +2895,7 @@ fi
AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [
- AC_TRY_LINK([],
+ AC_TRY_LINK([#include <stdio.h>],
[ extern int sys_nerr; printf("%i", sys_nerr);],
[ ac_cv_libc_defines_sys_nerr="yes" ],
[ ac_cv_libc_defines_sys_nerr="no" ]

View File

@ -5,10 +5,15 @@
ConditionEnvironment=!SSH_AGENT_PID
Description=OpenSSH key agent
Documentation=man:ssh-agent(1) man:ssh-add(1) man:ssh(1)
Requires=ssh-agent.socket
[Service]
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK
ExecStartPre=/usr/bin/rm -f $SSH_AUTH_SOCK
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
PassEnvironment=SSH_AGENT_PID
SuccessExitStatus=2
Type=forking
Type=simple
[Install]
Also=ssh-agent.socket

14
openssh/ssh-agent.socket Normal file
View File

@ -0,0 +1,14 @@
[Unit]
Description=OpenSSH key agent
Documentation=man:ssh-agent(1) man:ssh-add(1) man:ssh(1)
[Socket]
ListenStream=%t/ssh-agent.socket
Service=ssh-agent.service
Priority=6
Backlog=5
SocketMode=0600
DirectoryMode=0700
[Install]
WantedBy=sockets.target

View File

@ -0,0 +1,15 @@
[Unit]
Description=Update OpenSSH host key permissions
Documentation=https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
Before=sshd.service
After=ssh-keygen.target
ConditionPathExists=!/var/lib/.ssh-host-keys-migration
[Service]
Type=oneshot
ExecStart=-/usr/libexec/openssh/ssh-host-keys-migration.sh
ExecStart=touch /var/lib/.ssh-host-keys-migration
RemainAfterExit=yes
[Install]
WantedBy=sshd.service

View File

@ -0,0 +1,36 @@
#!/usr/bin/bash
set -eu -o pipefail
# Detect existing non-conforming host keys and perform the permissions migration
# https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
#
# Example output looks like:
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Permissions 0640 for '/etc/ssh/ssh_host_rsa_key' are too open.
# It is required that your private key files are NOT accessible by others.
# This private key will be ignored.
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Permissions 0640 for '/etc/ssh/ssh_host_ecdsa_key' are too open.
# It is required that your private key files are NOT accessible by others.
# This private key will be ignored.
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Permissions 0640 for '/etc/ssh/ssh_host_ed25519_key' are too open.
# It is required that your private key files are NOT accessible by others.
# This private key will be ignored.
# sshd: no hostkeys available -- exiting.
#
output="$(sshd -T 2>&1 || true)" # expected to fail
while read line; do
if [[ $line =~ ^Permissions\ [0-9]+\ for\ \'(.*)\'\ are\ too\ open. ]]; then
keyfile=${BASH_REMATCH[1]}
echo $line
echo -e "\t-> changing permissions on $keyfile"
chmod --verbose g-r $keyfile
chown --verbose root:root $keyfile
fi
done <<< "$output"

View File

@ -30,8 +30,7 @@ if ! $KEYGEN -q -t $KEYTYPE -f $KEY -C '' -N '' >&/dev/null; then
fi
# sanitize permissions
/usr/bin/chgrp ssh_keys $KEY
/usr/bin/chmod 640 $KEY
/usr/bin/chmod 600 $KEY
/usr/bin/chmod 644 $KEY.pub
if [[ -x /usr/sbin/restorecon ]]; then
/usr/sbin/restorecon $KEY{,.pub}

View File

@ -3,6 +3,9 @@ Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target
# Migration for Fedora 38 change to remove group ownership for standard host keys
# See https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
Wants=ssh-host-keys-migration.service
[Service]
Type=notify

View File

@ -1,16 +1,7 @@
# Configuration file for the sshd service.
# The server keys are automatically generated if they ommited
# to change the automatic creation uncomment the approprite
# line.
# AUTOCREATE_SERVER_KEYS=RSAONLY
# AUTOCREATE_SERVER_KEYS=NO
AUTOCREATE_SERVER_KEYS=YES
# Do not change this option unless you have hardware random
# generator and you REALLY know what you are doing/
export SSH_USE_STRONG_RNG=0
# export SSH_USE_STRONG_RNG=1
# The server keys are automatically generated if they are missing.
# To change the automatic creation, adjust sshd.service options for
# example using systemctl enable sshd-keygen@dsa.service to allow creation
# of DSA key or systemctl mask sshd-keygen@rsa.service to disable RSA key
# creation.

View File

@ -3,6 +3,9 @@ Description=OpenSSH per-connection server daemon
Documentation=man:sshd(8) man:sshd_config(5)
Wants=sshd-keygen.target
After=sshd-keygen.target
# Migration for Fedora 38 change to remove group ownership for standard host keys
# See https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
Wants=ssh-host-keys-migration.service
[Service]
EnvironmentFile=-/etc/sysconfig/sshd