diff --git a/openssh-5.9p1-ipv6man.patch b/openssh-5.9p1-ipv6man.patch new file mode 100644 index 0000000000000000000000000000000000000000..ece1a73d3dfd9f81686c88958375029859419c65 --- /dev/null +++ b/openssh-5.9p1-ipv6man.patch @@ -0,0 +1,24 @@ +diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1 +--- openssh-5.9p0/ssh.1.ipv6man 2011-08-05 22:17:32.000000000 +0200 ++++ openssh-5.9p0/ssh.1 2011-08-31 13:08:34.880024485 +0200 +@@ -1400,6 +1400,8 @@ manual page for more information. + .Nm + exits with the exit status of the remote command or with 255 + if an error occurred. ++.Sh IPV6 ++IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. + .Sh SEE ALSO + .Xr scp 1 , + .Xr sftp 1 , +diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8 +--- openssh-5.9p0/sshd.8.ipv6man 2011-08-05 22:17:32.000000000 +0200 ++++ openssh-5.9p0/sshd.8 2011-08-31 13:10:34.129039094 +0200 +@@ -940,6 +940,8 @@ concurrently for different ports, this c + started last). + The content of this file is not sensitive; it can be world-readable. + .El ++.Sh IPV6 ++IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. + .Sh SEE ALSO + .Xr scp 1 , + .Xr sftp 1 , diff --git a/openssh-6.3p1-ctr-evp-fast.patch b/openssh-6.3p1-ctr-evp-fast.patch deleted file mode 100644 index ddcb7f15ab4f6114eca22356514d7ada0ea5b47b..0000000000000000000000000000000000000000 --- a/openssh-6.3p1-ctr-evp-fast.patch +++ /dev/null @@ -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); diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 2aa14bd44e420e4e5a87f56dc6df9da1d935e5cd..529b5089993a57b47f137e1790d238de7a0fbc2d 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -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) diff --git a/openssh-6.6p1-keyperm.patch b/openssh-6.6p1-keyperm.patch deleted file mode 100644 index 5e06940b64e6f61324f772f3aef1c2ad612064cf..0000000000000000000000000000000000000000 --- a/openssh-6.6p1-keyperm.patch +++ /dev/null @@ -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 - #include -+#include - #include - #include - #include -@@ -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("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index f3231f932891964b82096d13ce17d35281653850..eaf4453222b8b3c94bb757e19ae2184fac4eaa68 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -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); diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 1923ac8c66eec84ff5d3807cd7fc9850ecb64345..1dca99cac57bacd3e56aada85ac0523eb2d96322 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -28,47 +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 -@@ -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/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 @@ -83,21 +42,6 @@ diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (sshbuf_len(buf) != 0 && -diff -up openssh-8.5p1/kexgssc.c.coverity openssh-8.5p1/kexgssc.c ---- openssh-8.5p1/kexgssc.c.coverity 2021-03-24 12:03:33.711967665 +0100 -+++ openssh-8.5p1/kexgssc.c 2021-03-24 12:03:33.783968166 +0100 -@@ -98,8 +98,10 @@ kexgss_client(struct ssh *ssh) - default: - fatal_f("Unexpected KEX type %d", kex->kex_type); - } -- if (r != 0) -+ if (r != 0) { -+ ssh_gssapi_delete_ctx(&ctxt); - return r; -+ } - - token_ptr = GSS_C_NO_BUFFER; - diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c --- openssh-8.5p1/krl.c.coverity 2021-03-02 11:31:47.000000000 +0100 +++ openssh-8.5p1/krl.c 2021-03-24 12:03:33.783968166 +0100 @@ -184,17 +128,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 @@ -330,24 +263,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 @@ -360,25 +275,6 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c } _exit(1); -@@ -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 @@ -453,32 +349,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; diff --git a/openssh-7.2p2-s390-closefrom.patch b/openssh-7.2p2-s390-closefrom.patch new file mode 100644 index 0000000000000000000000000000000000000000..363538ca937b04d160a013a45821dc86e5fd1d9e --- /dev/null +++ b/openssh-7.2p2-s390-closefrom.patch @@ -0,0 +1,52 @@ +Zseries only: Leave the hardware filedescriptors open. + +All filedescriptors above 2 are getting closed when a new +sshd process to handle a new client connection is +spawned. As the process also chroot into an empty filesystem +without any device nodes, there is no chance to reopen the +files. This patch filters out the reqired fds in the +closefrom function so these are skipped in the close loop. + +Author: Harald Freudenberger + +--- + openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +--- a/openbsd-compat/bsd-closefrom.c ++++ b/openbsd-compat/bsd-closefrom.c +@@ -82,7 +82,33 @@ closefrom(int lowfd) + fd = strtol(dent->d_name, &endp, 10); + if (dent->d_name != endp && *endp == '\0' && + fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) ++#ifdef __s390__ ++ { ++ /* ++ * the filedescriptors used to communicate with ++ * the device drivers to provide hardware support ++ * should survive. HF ++ */ ++ char fpath[PATH_MAX], lpath[PATH_MAX]; ++ len = snprintf(fpath, sizeof(fpath), "%s/%s", ++ fdpath, dent->d_name); ++ if (len > 0 && (size_t)len <= sizeof(fpath)) { ++ len = readlink(fpath, lpath, sizeof(lpath)); ++ if (len > 0) { ++ lpath[len] = 0; ++ if (strstr(lpath, "dev/z90crypt") ++ || strstr(lpath, "dev/zcrypt") ++ || strstr(lpath, "dev/prandom") ++ || strstr(lpath, "dev/shm/icastats")) ++ fd = -1; ++ } ++ } ++ if (fd >= 0) ++ (void) close((int) fd); ++ } ++#else + (void) close((int) fd); ++#endif + } + (void) closedir(dirp); + return; + diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index ad181cb57bef73b71ff1a30c86a05e954d693f9b..2b702d416c44f2ccefdc1784793654ed48b32e41 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -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 diff --git a/openssh-7.4p1-systemd.patch b/openssh-7.4p1-systemd.patch index 4f9e58a99044003969ed299391e20206d395093e..1242aac8d4647dd097be70d150f67bfd8cd2fec5 100644 --- a/openssh-7.4p1-systemd.patch +++ b/openssh-7.4p1-systemd.patch @@ -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" diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index 7217c6419144681ee08064f1d606708d1087c6b1..90640a02490027f7d3b52da4c33d39ac47718fc9 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -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 diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 2d3aae95df3c4f8a5d803973960baca3cc177f1c..748c4b608e5808f30d1775976ddf7c988d963351 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -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 @@ -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 *); diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index d1e44b00e6fbf9fcde3f0266d15e8d319fd29959..53515715d1832591153dfd3168aba7a966a6734b 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -368,14 +368,6 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c #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\"", @@ -423,10 +415,10 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c --- 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 -@@ -34,6 +34,7 @@ - #include - #include +@@ -36,6 +36,7 @@ #include + #include + #include +#include #endif @@ -440,11 +432,11 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c #ifdef WITH_XMSS @@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai - for (kt = keytypes; kt->type != -1; kt++) { - if (kt->name == NULL || kt->type == KEY_NULL) + impl = keyimpls[i]; + if (impl->name == NULL || impl->type == KEY_NULL) continue; + if (FIPS_mode()) { -+ switch (kt->type) { ++ switch (impl->type) { + case KEY_ED25519: + case KEY_ED25519_SK: + case KEY_ED25519_CERT: @@ -455,9 +447,9 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c + break; + } + } - if (!include_sigonly && kt->sigonly) + if (!include_sigonly && impl->sigonly) continue; - if ((certs_only && !kt->cert) || (plain_only && kt->cert)) + 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; } @@ -477,40 +469,31 @@ diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c + break; + } /* Fill in ret from parsed key */ - ret->type = type; - if (sshkey_is_cert(ret)) { -@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA - goto out; - - if (EVP_PKEY_keygen(ctx, &res) <= 0) { -+ if (FIPS_mode()) -+ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } + sshkey_free_contents(ret); + *ret = *k; @@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key, - break; - case KEY_ED25519_SK: - case KEY_ED25519_SK_CERT: -+ if (FIPS_mode()) { + *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 */ - case KEY_ECDSA_SK_CERT: - case KEY_ECDSA_SK: - r = sshsk_sign(sk_provider, key, sigp, lenp, data, + 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, - return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); - case KEY_ED25519_SK: - case KEY_ED25519_SK_CERT: -+ if (FIPS_mode()) { + *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; + } - return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen, - compat, detailsp); - #ifdef WITH_XMSS + 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-05-06 12:08:36.467926637 +0200 +++ openssh-8.6p1/ssh-keygen.c 2021-05-06 12:08:36.503926916 +0200 @@ -554,6 +537,26 @@ 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 + #include + #include ++#include + + #include + #include +@@ -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 @@ -663,13 +666,13 @@ diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c if ((sig = malloc(slen)) == NULL) return SSH_ERR_ALLOC_FAIL; @@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey * - datalen >= INT_MAX - crypto_sign_ed25519_BYTES || - signature == NULL || signaturelen == 0) + 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(signature, signaturelen)) == NULL) + if ((b = sshbuf_from(sig, siglen)) == NULL) return SSH_ERR_ALLOC_FAIL; diff --git a/openssh-7.7p1-anolis.patch b/openssh-7.7p1-redhat.patch similarity index 76% rename from openssh-7.7p1-anolis.patch rename to openssh-7.7p1-redhat.patch index bbd0c9ce5ae2bd648187d393681aa2309828ad32..1d77f90ccc65d86a137826d9f136c44899b083e5 100644 --- a/openssh-7.7p1-anolis.patch +++ b/openssh-7.7p1-redhat.patch @@ -1,5 +1,5 @@ -diff -up openssh/ssh_config.anolis openssh/ssh_config ---- openssh/ssh_config.anolis 2020-02-11 23:28:35.000000000 +0100 +diff -up openssh/ssh_config.redhat openssh/ssh_config +--- openssh/ssh_config.redhat 2020-02-11 23:28:35.000000000 +0100 +++ openssh/ssh_config 2020-02-13 18:13:39.180641839 +0100 @@ -43,3 +43,10 @@ # ProxyCommand ssh -q -W %h:%p gateway.example.com @@ -12,9 +12,9 @@ diff -up openssh/ssh_config.anolis openssh/ssh_config +# included below. For more information, see manual page for +# update-crypto-policies(8) and ssh_config(5). +Include /etc/ssh/ssh_config.d/*.conf -diff -up openssh/ssh_config_anolis.anolis openssh/ssh_config_anolis ---- openssh/ssh_config_anolis.anolis 2020-02-13 18:13:39.180641839 +0100 -+++ openssh/ssh_config_anolis 2020-02-13 18:13:39.180641839 +0100 +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,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 @@ -31,8 +31,8 @@ diff -up openssh/ssh_config_anolis.anolis openssh/ssh_config_anolis + +# Uncomment this if you want to use .local domain +# Host *.local -diff -up openssh/sshd_config.0.anolis openssh/sshd_config.0 ---- openssh/sshd_config.0.anolis 2020-02-12 14:30:04.000000000 +0100 +diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0 +--- openssh/sshd_config.0.redhat 2020-02-12 14:30:04.000000000 +0100 +++ openssh/sshd_config.0 2020-02-13 18:13:39.181641855 +0100 @@ -970,9 +970,9 @@ DESCRIPTION @@ -47,8 +47,8 @@ diff -up openssh/sshd_config.0.anolis openssh/sshd_config.0 TCPKeepAlive Specifies whether the system should send TCP keepalive messages -diff -up openssh/sshd_config.5.anolis openssh/sshd_config.5 ---- openssh/sshd_config.5.anolis 2020-02-11 23:28:35.000000000 +0100 +diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5 +--- openssh/sshd_config.5.redhat 2020-02-11 23:28:35.000000000 +0100 +++ openssh/sshd_config.5 2020-02-13 18:13:39.181641855 +0100 @@ -1614,7 +1614,7 @@ By default no subsystems are defined. .It Cm SyslogFacility @@ -59,8 +59,8 @@ diff -up openssh/sshd_config.5.anolis openssh/sshd_config.5 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. .It Cm TCPKeepAlive -diff -up openssh/sshd_config.anolis openssh/sshd_config ---- openssh/sshd_config.anolis 2020-02-11 23:28:35.000000000 +0100 +diff -up openssh/sshd_config.redhat openssh/sshd_config +--- openssh/sshd_config.redhat 2020-02-11 23:28:35.000000000 +0100 +++ openssh/sshd_config 2020-02-13 18:20:16.349913681 +0100 @@ -10,6 +10,14 @@ # possible, but leave them commented. Uncommented options override the @@ -77,17 +77,10 @@ diff -up openssh/sshd_config.anolis openssh/sshd_config #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 -diff -up openssh/sshd_config_anolis.anolis openssh/sshd_config_anolis ---- openssh/sshd_config_anolis.anolis 2020-02-13 18:14:02.268006439 +0100 -+++ openssh/sshd_config_anolis 2020-02-13 18:19:20.765035947 +0100 -@@ -0,0 +1,22 @@ -+# 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 -+ +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,15 @@ +SyslogFacility AUTHPRIV + +ChallengeResponseAuthentication no @@ -103,4 +96,14 @@ diff -up openssh/sshd_config_anolis.anolis openssh/sshd_config_anolis +# as it is more configurable and versatile than the built-in version. +PrintMotd no + +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 + diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index d4549f0ababcd1a8d08637d1eccf0c7b5a140fbc..86c08dba42f5cb25850dc7b5be1c70cd9c9f8ccc 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,7 @@ -diff --color -ru a/ssh_config.5 b/ssh_config.5 ---- a/ssh_config.5 2022-07-12 15:05:22.550013071 +0200 -+++ b/ssh_config.5 2022-07-12 15:17:20.016704545 +0200 -@@ -373,17 +373,13 @@ +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 @@ -24,7 +24,7 @@ diff --color -ru a/ssh_config.5 b/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 @@ +@@ -450,20 +446,25 @@ (the default), the check will not be executed. .It Cm Ciphers @@ -54,7 +54,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Pp The supported ciphers are: .Bd -literal -offset indent -@@ -474,13 +475,6 @@ +@@ -479,13 +480,6 @@ chacha20-poly1305@openssh.com .Ed .Pp @@ -68,7 +68,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClearAllForwardings -@@ -874,6 +868,11 @@ +@@ -885,6 +879,11 @@ The default is .Dq no . .It Cm GSSAPIKexAlgorithms @@ -80,7 +80,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are .Bd -literal -offset 3n -@@ -886,10 +885,8 @@ +@@ -897,10 +896,8 @@ gss-curve25519-sha256- .Ed .Pp @@ -92,7 +92,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -913,36 +910,25 @@ +@@ -919,36 +916,25 @@ but may be manually hashed using .Xr ssh-keygen 1 . .It Cm HostbasedAcceptedAlgorithms @@ -137,7 +137,25 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Pp The .Fl Q -@@ -1219,30 +1216,25 @@ +@@ -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 @@ -177,7 +195,7 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Pp The list of available key exchange algorithms may also be obtained using .Qq ssh -Q kex . -@@ -1351,37 +1344,33 @@ +@@ -1365,37 +1357,33 @@ file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -224,7 +242,7 @@ diff --color -ru a/ssh_config.5 b/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 @@ +@@ -1567,39 +1555,31 @@ The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -270,7 +288,13 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -@@ -2237,7 +2207,9 @@ for those users who do not have a config ++.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 @@ -281,10 +305,10 @@ diff --color -ru a/ssh_config.5 b/ssh_config.5 .Sh AUTHORS .An -nosplit OpenSSH is a derivative of the original and free -diff --color -ru a/sshd_config.5 b/sshd_config.5 ---- a/sshd_config.5 2022-07-12 15:05:22.535012771 +0200 -+++ b/sshd_config.5 2022-07-12 15:15:33.394809258 +0200 -@@ -373,17 +373,13 @@ +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 @@ -307,7 +331,7 @@ diff --color -ru a/sshd_config.5 b/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 @@ +@@ -525,20 +521,25 @@ indicating not to .Xr chroot 2 . .It Cm Ciphers @@ -337,7 +361,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 .Pp The supported ciphers are: .Pp -@@ -490,13 +491,6 @@ +@@ -565,13 +566,6 @@ chacha20-poly1305@openssh.com .El .Pp @@ -351,7 +375,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -685,53 +679,43 @@ +@@ -766,53 +760,43 @@ .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -424,7 +448,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q HostbasedAcceptedAlgorithms . -@@ -799,25 +794,14 @@ +@@ -879,25 +863,14 @@ .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms @@ -455,7 +479,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -965,20 +947,25 @@ +@@ -1044,20 +1017,25 @@ The default is .Cm yes . .It Cm KexAlgorithms @@ -485,7 +509,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The supported algorithms are: .Pp .Bl -item -compact -offset indent -@@ -1010,16 +997,6 @@ +@@ -1089,16 +1067,6 @@ sntrup761x25519-sha512@openssh.com .El .Pp @@ -502,7 +526,7 @@ diff --color -ru a/sshd_config.5 b/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 @@ +@@ -1184,21 +1152,26 @@ file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -533,7 +557,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 .Pp The algorithms that contain .Qq -etm -@@ -1161,15 +1144,6 @@ +@@ -1241,15 +1214,6 @@ umac-128-etm@openssh.com .El .Pp @@ -549,7 +573,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1548,36 +1522,25 @@ +@@ -1633,36 +1597,25 @@ The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms @@ -595,7 +619,7 @@ diff --color -ru a/sshd_config.5 b/sshd_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -@@ -2011,7 +1968,9 @@ This file should be writable by root onl +@@ -2131,7 +2084,9 @@ .El .Sh SEE ALSO .Xr sftp-server 8 , diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index d5dfd7ed63e4af5567c8d5ab65415b25fba928fe..0bc509fe301c99426945bf2e17014db168168cb7 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -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 \ 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 @@ -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", - NULL, + NULL, diff --git a/auth2.c b/auth2.c index 0e776224..1c217268 100644 --- a/auth2.c @@ -378,13 +388,9 @@ index ebd0dbca..1bdac6a4 100644 /* 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_poll(ssh, pfd, npfd_active); +@@ -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. */ - if (conn_in_ready) - client_process_net_input(ssh); + 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,8 +1369,8 @@ index ce85f043..574c7609 100644 +#ifdef GSSAPI + free(kex->gss_host); +#endif /* GSSAPI */ - sshbuf_free(kex->initial_sig); - sshkey_free(kex->initial_hostkey); + sshbuf_free(kex->initial_sig); + sshkey_free(kex->initial_hostkey); free(kex->failed_choice); diff --git a/kex.h b/kex.h index a5ae6ac0..fe714141 100644 @@ -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,612 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1590,8 +1589,10 @@ index 00000000..f6e1405e + default: + fatal_f("Unexpected KEX type %d", kex->kex_type); + } -+ if (r != 0) ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&ctxt); + return r; ++ } + + token_ptr = GSS_C_NO_BUFFER; + @@ -1654,11 +1655,16 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { ++ char *tmp = NULL; ++ size_t tmp_len = 0; ++ + debug("Received KEXGSS_HOSTKEY"); + if (server_host_key_blob) + fatal("Server host key received more than once"); -+ if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0) ++ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0) + fatal("Failed to read server host key: %s", ssh_err(r)); ++ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL) ++ fatal("sshbuf_from failed"); + } + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); + @@ -1945,11 +1951,16 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { ++ char *tmp = NULL; ++ size_t tmp_len = 0; ++ + debug("Received KEXGSS_HOSTKEY"); + if (server_host_key_blob) + fatal("Server host key received more than once"); -+ if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0) ++ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0) + fatal("sshpkt failed: %s", ssh_err(r)); ++ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL) ++ fatal("sshbuf_from failed"); + } + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); + @@ -2088,13 +2099,14 @@ 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 index 00000000..60bc02de --- /dev/null +++ b/kexgsss.c -@@ -0,0 +1,474 @@ +@@ -0,0 +1,482 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -2161,7 +2173,7 @@ index 00000000..60bc02de + */ + + OM_uint32 ret_flags = 0; -+ gss_buffer_desc gssbuf, recv_tok, msg_tok; ++ gss_buffer_desc gssbuf = {0, NULL}, recv_tok, msg_tok; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + Gssctxt *ctxt = NULL; + struct sshbuf *shared_secret = NULL; @@ -2201,7 +2213,7 @@ index 00000000..60bc02de + type = ssh_packet_read(ssh); + switch(type) { + case SSH2_MSG_KEXGSS_INIT: -+ if (client_pubkey != NULL) ++ if (gssbuf.value != NULL) + fatal("Received KEXGSS_INIT after initialising"); + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, + &recv_tok)) != 0 || @@ -2232,6 +2244,31 @@ index 00000000..60bc02de + goto out; + + /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ ++ ++ /* Calculate the hash early so we can free the ++ * client_pubkey, which has reference to the parent ++ * buffer state->incoming_packet ++ */ ++ hashlen = sizeof(hash); ++ if ((r = kex_gen_hash( ++ kex->hash_alg, ++ kex->client_version, ++ kex->server_version, ++ kex->peer, ++ kex->my, ++ empty, ++ client_pubkey, ++ server_pubkey, ++ shared_secret, ++ hash, &hashlen)) != 0) ++ goto out; ++ ++ gssbuf.value = hash; ++ gssbuf.length = hashlen; ++ ++ sshbuf_free(client_pubkey); ++ client_pubkey = NULL; ++ + break; + case SSH2_MSG_KEXGSS_CONTINUE: + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, @@ -2253,7 +2290,7 @@ index 00000000..60bc02de + if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) + fatal("Zero length token output when incomplete"); + -+ if (client_pubkey == NULL) ++ if (gssbuf.value == NULL) + fatal("No client public key"); + + if (maj_status & GSS_S_CONTINUE_NEEDED) { @@ -2282,23 +2319,6 @@ index 00000000..60bc02de + if (!(ret_flags & GSS_C_INTEG_FLAG)) + fatal("Integrity flag wasn't set"); + -+ hashlen = sizeof(hash); -+ if ((r = kex_gen_hash( -+ kex->hash_alg, -+ kex->client_version, -+ kex->server_version, -+ kex->peer, -+ kex->my, -+ empty, -+ client_pubkey, -+ server_pubkey, -+ shared_secret, -+ hash, &hashlen)) != 0) -+ goto out; -+ -+ gssbuf.value = hash; -+ gssbuf.length = hashlen; -+ + if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) + fatal("Couldn't get MIC"); + @@ -2612,6 +2632,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); @@ -3496,7 +3533,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 +3545,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 +3584,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 +3605,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 +3620,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 +3789,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 +3923,98 @@ diff --git a/sshkey.c b/sshkey.c index 57995ee6..fd5b7724 100644 --- a/sshkey.c +++ b/sshkey.c +@@ -127,6 +127,75 @@ static const struct keytype keytypes[] = { + extern const struct sshkey_impl sshkey_xmss_impl; + extern const struct sshkey_impl sshkey_xmss_cert_impl; + #endif ++ ++static int ssh_gss_equal(const struct sshkey *, const struct sshkey *) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_serialize_public(const struct sshkey *, struct sshbuf *, ++ enum sshkey_serialize_rep) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_deserialize_public(const char *, struct sshbuf *, ++ struct sshkey *) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_serialize_private(const struct sshkey *, struct sshbuf *, ++ enum sshkey_serialize_rep) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_deserialize_private(const char *, struct sshbuf *, ++ struct sshkey *) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_copy_public(const struct sshkey *, struct sshkey *) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static int ssh_gss_verify(const struct sshkey *, const u_char *, size_t, ++ const u_char *, size_t, const char *, u_int, ++ struct sshkey_sig_details **) ++{ ++ return SSH_ERR_FEATURE_UNSUPPORTED; ++} ++ ++static const struct sshkey_impl_funcs sshkey_gss_funcs = { ++ /* .size = */ NULL, ++ /* .alloc = */ NULL, ++ /* .cleanup = */ NULL, ++ /* .equal = */ ssh_gss_equal, ++ /* .ssh_serialize_public = */ ssh_gss_serialize_public, ++ /* .ssh_deserialize_public = */ ssh_gss_deserialize_public, ++ /* .ssh_serialize_private = */ ssh_gss_serialize_private, ++ /* .ssh_deserialize_private = */ ssh_gss_deserialize_private, ++ /* .generate = */ NULL, ++ /* .copy_public = */ ssh_gss_copy_public, ++ /* .sign = */ NULL, ++ /* .verify = */ ssh_gss_verify, ++}; ++ ++/* The struct is intentionally dummy and has no gss calls */ ++static const struct sshkey_impl sshkey_gss_kex_impl = { ++ /* .name = */ "null", ++ /* .shortname = */ "null", ++ /* .sigalg = */ NULL, ++ /* .type = */ KEY_NULL, ++ /* .nid = */ 0, ++ /* .cert = */ 0, ++ /* .sigonly = */ 0, ++ /* .keybits = */ 0, /* FIXME */ ++ /* .funcs = */ &sshkey_gss_funcs, ++}; + + const struct sshkey_impl * const keyimpls[] = { + &sshkey_ed25519_impl, @@ -154,6 +154,7 @@ static const struct keytype keytypes[] = { - # endif /* ENABLE_SK */ - # endif /* OPENSSL_HAS_ECC */ - #endif /* WITH_OPENSSL */ -+ { "null", "null", NULL, KEY_NULL, 0, 0, 0 }, - { NULL, NULL, NULL, -1, -1, 0, 0 } + &sshkey_xmss_impl, + &sshkey_xmss_cert_impl, + #endif ++ &sshkey_gss_kex_impl, + NULL }; @@ -255,7 +256,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) - const struct keytype *kt; - 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 diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index b3295a95acafe74fcc508c1f32176d7fb5d1c22e..e21e545c72012bcce90b2d721b116aa03f566d73 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -76,7 +76,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in + ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ ssh-ed25519.o digest-openssl.o digest-libc.o \ - hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ + hmac.o ed25519.o hash.o \ @@ -302,6 +302,8 @@ clean: regressclean rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) rm -f regress/unittests/utf8/*.o @@ -105,7 +105,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile @@ -677,6 +682,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT regress/unittests/test_helper/libtest_helper.a \ - -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) +UNITTESTS_TEST_PKCS11_OBJS=\ + regress/unittests/pkcs11/tests.o @@ -115,7 +115,7 @@ diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in + regress/unittests/test_helper/libtest_helper.a libssh.a + $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ + regress/unittests/test_helper/libtest_helper.a \ -+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) ++ -lssh -lopenbsd-compat -lcrypto $(LIBS) + # These all need to be compiled -fPIC, so they are treated differently. SK_DUMMY_OBJS=\ @@ -1035,7 +1035,7 @@ diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c int r, i, count = 0, success = 0, confirm = 0; u_int seconds = 0; @@ -869,33 +931,28 @@ process_add_smartcard_key(SocketEntry *e - error_f("failed to parse constraints"); + "providers is disabled", provider); goto send; } - if (realpath(provider, canonical_provider) == NULL) { @@ -2157,7 +2157,7 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1517,164 +1702,298 @@ pkcs11_register_provider(char *provider_ +@@ -1517,162 +1702,296 @@ pkcs11_register_provider(char *provider_ CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2213,10 +2213,8 @@ diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c + 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 = xcalloc(1, sizeof(*p)); - p->name = xstrdup(provider_id); - p->handle = handle; @@ -3057,3 +3055,4 @@ diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri. +struct pkcs11_uri *pkcs11_uri_init(); +char *pkcs11_uri_get(struct pkcs11_uri *uri); + + diff --git a/openssh-8.7p1-CVE-2023-25136.patch b/openssh-8.7p1-CVE-2023-25136.patch deleted file mode 100644 index ca661ee603a820570f85e521ecdec3aca16eb67f..0000000000000000000000000000000000000000 --- a/openssh-8.7p1-CVE-2023-25136.patch +++ /dev/null @@ -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; - } - diff --git a/openssh-8.7p1-evpgenkey.patch b/openssh-8.7p1-evpgenkey.patch deleted file mode 100644 index 1af9b490135551daafd4d154691001a38384b266..0000000000000000000000000000000000000000 --- a/openssh-8.7p1-evpgenkey.patch +++ /dev/null @@ -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 */ diff --git a/openssh-8.7p1-gssapi-auth.patch b/openssh-8.7p1-gssapi-auth.patch deleted file mode 100644 index 6908cadfcebce3880a56a0b8625ab90d2238c31f..0000000000000000000000000000000000000000 --- a/openssh-8.7p1-gssapi-auth.patch +++ /dev/null @@ -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); diff --git a/openssh-8.7p1-ibmca.patch b/openssh-8.7p1-ibmca.patch new file mode 100644 index 0000000000000000000000000000000000000000..88914bff1c860f1cbb2b88d5c872d5afa72c6a89 --- /dev/null +++ b/openssh-8.7p1-ibmca.patch @@ -0,0 +1,11 @@ +--- openssh-8.7p1/openbsd-compat/bsd-closefrom.c.orig 2022-04-12 15:47:03.815044607 +0200 ++++ openssh-8.7p1/openbsd-compat/bsd-closefrom.c 2022-04-12 15:48:12.464963511 +0200 +@@ -16,7 +16,7 @@ + + #include "includes.h" + +-#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) ++#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) || (defined __s390__) + + #include + #include diff --git a/openssh-8.7p1-mem-leak.patch b/openssh-8.7p1-mem-leak.patch deleted file mode 100644 index 8c9ac80679997649bdfdd348dba99a8360378b18..0000000000000000000000000000000000000000 --- a/openssh-8.7p1-mem-leak.patch +++ /dev/null @@ -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"); - } - diff --git a/openssh-8.7p1-minrsabits.patch b/openssh-8.7p1-minrsabits.patch index ad91fe779c099b20161a903f8e442641bf4f70f4..2ed59a3e099b7db9599382b6875622862541db0c 100644 --- a/openssh-8.7p1-minrsabits.patch +++ b/openssh-8.7p1-minrsabits.patch @@ -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"); \ - if (sensitive_data.keys[o] != NULL) \ - debug2("hostbased key %d: %s key from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ -@@ -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"); \ - if (sensitive_data.keys[o] != NULL) \ - debug2("hostbased key %d: %s cert from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ -@@ -2265,7 +2274,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) - /* list of keys supported by the agent */ - if ((r = get_agent_identities(ssh, &agent_fd, &idlist)) == 0) { - 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 diff --git a/openssh-8.7p1-negotiate-supported-algs.patch b/openssh-8.7p1-negotiate-supported-algs.patch index 260ddb817beac4daadf63098fc9eb4ffec2ff5b8..ee3637fa37cb1860486800adc670d7fad4abc1ed 100644 --- a/openssh-8.7p1-negotiate-supported-algs.patch +++ b/openssh-8.7p1-negotiate-supported-algs.patch @@ -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=$? +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" - ${SSHKEYGEN} -s $OBJ/agent-ca -qh -n localhost-with-alias \ - -I localhost-with-alias $OBJ/agent-key.$k.pub || \ -@@ -31,7 +35,7 @@ cp $OBJ/known_hosts.orig $OBJ/known_host + ${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k" + ${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 k in $SSH_KEYTYPES ; do +for k in $SSH_ACCEPTED_KEYTYPES ; do - verbose "key type $k" - cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy - echo "HostKeyAlgorithms $k" >> $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 + 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) diff --git a/openssh-8.7p1-nohostsha1proof.patch b/openssh-8.7p1-nohostsha1proof.patch new file mode 100644 index 0000000000000000000000000000000000000000..7fea8006d9429c8d5d397f7c6872c15dadbf6a2f --- /dev/null +++ b/openssh-8.7p1-nohostsha1proof.patch @@ -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; + } diff --git a/openssh-8.7p1-recursive-scp.patch b/openssh-8.7p1-recursive-scp.patch index 5b44d922dc1fccee34eb1f4ff8bdafc6da85de0b..f0d9b0fed4898e8536615edeffe6a122aace88fc 100644 --- a/openssh-8.7p1-recursive-scp.patch +++ b/openssh-8.7p1-recursive-scp.patch @@ -5,8 +5,8 @@ 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) { +- 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; } @@ -108,8 +108,8 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c 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; @@ -143,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 @@ -156,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, diff --git a/openssh-8.7p1-scp-clears-file.patch b/openssh-8.7p1-scp-clears-file.patch deleted file mode 100644 index 3ecff1ebd960a6ff5465fc76e688cad844c508bb..0000000000000000000000000000000000000000 --- a/openssh-8.7p1-scp-clears-file.patch +++ /dev/null @@ -1,303 +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,11 +1324,11 @@ 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, targ); - 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, targ); - 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("open local \"%s\": %s", local_path, strerror(errno)); - goto fail; -@@ -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("close local \"%s\": %s", local_path, strerror(errno)); - status = SSH2_FX_FAILURE; -@@ -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("upload \"%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 diff --git a/openssh-8.7p1-scp-kill-switch.patch b/openssh-8.7p1-scp-kill-switch.patch index 6710304c1dc676ef2e5d13a327fb6fdad52ea93e..161ab2d92842f82809c398d560937d6f4e516358 100644 --- a/openssh-8.7p1-scp-kill-switch.patch +++ b/openssh-8.7p1-scp-kill-switch.patch @@ -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 diff --git a/openssh-8.7p1-sftp-default-protocol.patch b/openssh-8.7p1-sftp-default-protocol.patch deleted file mode 100644 index 8837a7ba5ff83fe0e83d51aa30f53bc226936dce..0000000000000000000000000000000000000000 --- a/openssh-8.7p1-sftp-default-protocol.patch +++ /dev/null @@ -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 R H/Fa 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); diff --git a/openssh-8.7p1-ssh-manpage.patch b/openssh-8.7p1-ssh-manpage.patch index 04e4c0631da8ef0fa8f220cc5ecc1c928e8df778..c7f6f1e659a00bcba4a91c9e63dc2f5e0e8f2632 100644 --- a/openssh-8.7p1-ssh-manpage.patch +++ b/openssh-8.7p1-ssh-manpage.patch @@ -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 diff --git a/openssh-9.0p1-audit-log.patch b/openssh-9.0p1-audit-log.patch new file mode 100644 index 0000000000000000000000000000000000000000..fbf5094d883d0113ffa08e3702f3c7252d30763f --- /dev/null +++ b/openssh-9.0p1-audit-log.patch @@ -0,0 +1,119 @@ +diff -up openssh-9.0p1/audit-bsm.c.patch openssh-9.0p1/audit-bsm.c +--- openssh-9.0p1/audit-bsm.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit-bsm.c 2022-10-24 14:51:43.685766639 +0200 +@@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li + } + + int +-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) ++audit_keyusage(struct ssh *ssh, int host_user, char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv) + { + /* not implemented */ + } +diff -up openssh-9.0p1/audit.c.patch openssh-9.0p1/audit.c +--- openssh-9.0p1/audit.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit.c 2022-10-24 15:20:38.854548226 +0200 +@@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev) + void + audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key) + { +- char *fp; ++ char *key_fp = NULL; ++ char *issuer_fp = NULL; ++ struct sshkey_cert *cert = NULL; + +- fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); +- if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0) ++ key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); ++ if (sshkey_is_cert(key) && key->cert != NULL && key->cert->signature_key != NULL) { ++ cert = key->cert; ++ issuer_fp = sshkey_fingerprint(cert->signature_key, ++ options.fingerprint_hash, SSH_FP_DEFAULT); ++ } ++ if (audit_keyusage(ssh, host_user, key_fp, cert, issuer_fp, (*rv == 0)) == 0) + *rv = -SSH_ERR_INTERNAL_ERROR; +- free(fp); ++ if (key_fp) ++ free(key_fp); ++ if (issuer_fp) ++ free(issuer_fp); + } + + void +diff -up openssh-9.0p1/audit.h.patch openssh-9.0p1/audit.h +--- openssh-9.0p1/audit.h.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit.h 2022-10-24 14:58:20.887565518 +0200 +@@ -64,7 +64,7 @@ void audit_session_close(struct logininf + int audit_run_command(struct ssh *, const char *); + void audit_end_command(struct ssh *, int, const char *); + ssh_audit_event_t audit_classify_auth(const char *); +-int audit_keyusage(struct ssh *, int, char *, int); ++int audit_keyusage(struct ssh *, int, const char *, const struct sshkey_cert *, const char *, int); + void audit_key(struct ssh *, int, int *, const struct sshkey *); + void audit_unsupported(struct ssh *, int); + void audit_kex(struct ssh *, int, char *, char *, char *, char *); +diff -up openssh-9.0p1/audit-linux.c.patch openssh-9.0p1/audit-linux.c +--- openssh-9.0p1/audit-linux.c.patch 2022-10-24 15:02:16.544858331 +0200 ++++ openssh-9.0p1/audit-linux.c 2022-10-24 15:21:58.165303951 +0200 +@@ -137,10 +137,12 @@ fatal_report: + } + + int +-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv) ++audit_keyusage(struct ssh *ssh, int host_user, const char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv) + { + char buf[AUDIT_LOG_SIZE]; + int audit_fd, rc, saved_errno; ++ const char *rip; ++ u_int i; + + audit_fd = audit_open(); + if (audit_fd < 0) { +@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host + else + return 0; /* Must prevent login */ + } ++ rip = ssh_remote_ipaddr(ssh); + snprintf(buf, sizeof(buf), "%s_auth grantors=auth-key", host_user ? "pubkey" : "hostbased"); + rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, +- buf, audit_username(), -1, NULL, ssh_remote_ipaddr(ssh), NULL, rv); ++ buf, audit_username(), -1, NULL, rip, NULL, rv); + if ((rc < 0) && ((rc != -1) || (getuid() == 0))) + goto out; +- snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", fp); ++ snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", key_fp); + rc = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, buf, NULL, +- ssh_remote_ipaddr(ssh), NULL, rv); ++ rip, NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ ++ if (cert) { ++ char *pbuf; ++ ++ pbuf = audit_encode_nv_string("key_id", cert->key_id, 0); ++ if (pbuf == NULL) ++ goto out; ++ snprintf(buf, sizeof(buf), "cert %s cert_serial=%llu cert_issuer_alg=\"%s\" cert_issuer_fp=\"%s\"", ++ pbuf, (unsigned long long)cert->serial, sshkey_type(cert->signature_key), issuer_fp); ++ free(pbuf); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, rip, NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ ++ for (i = 0; cert->principals != NULL && i < cert->nprincipals; i++) { ++ pbuf = audit_encode_nv_string("cert_principal", cert->principals[i], 0); ++ if (pbuf == NULL) ++ goto out; ++ snprintf(buf, sizeof(buf), "principal %s", pbuf); ++ free(pbuf); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, rip, NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ } ++ } + out: + saved_errno = errno; + audit_close(audit_fd); diff --git a/openssh-9.0p1-evp-fips-dh.patch b/openssh-9.0p1-evp-fips-dh.patch new file mode 100644 index 0000000000000000000000000000000000000000..d0470d922a89c26e8fcee094700f931da56e4c5e --- /dev/null +++ b/openssh-9.0p1-evp-fips-dh.patch @@ -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 + #include + #include ++#include ++#include ++#include + + #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 ++#include ++#include ++#include ++#include + + #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 + # include + # include ++# include ++# include ++# include + # ifdef OPENSSL_HAS_ECC + # include + # 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); diff --git a/openssh-9.0p1-evp-fips-ecdh.patch b/openssh-9.0p1-evp-fips-ecdh.patch new file mode 100644 index 0000000000000000000000000000000000000000..0313c6f386d94821605a2680f854b686baa22dfe --- /dev/null +++ b/openssh-9.0p1-evp-fips-ecdh.patch @@ -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 + + #include ++#include ++#include ++#include ++#include + + #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; + } diff --git a/openssh-9.0p1.tar.gz b/openssh-9.0p1.tar.gz deleted file mode 100644 index 81cc006f4d2b24e4cd1f521fbf6afc838d6d96b9..0000000000000000000000000000000000000000 Binary files a/openssh-9.0p1.tar.gz and /dev/null differ diff --git a/openssh-9.0p1.tar.gz.asc b/openssh-9.0p1.tar.gz.asc deleted file mode 100644 index 617af2b9b54e8a672f3062f2719e027e7ba149bc..0000000000000000000000000000000000000000 --- a/openssh-9.0p1.tar.gz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmJObeQACgkQKj9BTnNg -YLqXsRAAyd18O0i9cBeMuzRY5df9rn+2iIl6FGYpwaPSXSn2t8UR9xad63G+5Wtm -Qx5zxaWnPDkrKQvja6DzU7Zc58J/N0o9IMLEfXAP4eGXsuF4NZM/SEHjqRtQovTo -26xRxbX4LryUBJ7tNCSJ81UGmNS3GfwuTroMB32WclChCMOdu1MzO8mHOrtOBB7B -nc2F4Y7x4i71RXilTAMzpnzAzktOt5O74A16NZsfa8vJPyrFVav+hv4wYx2VROGa -HDVwdvnxVqUSAQQ47bYiWequ0DYgVK4icvRsUm5FYkAfFu7H0/6s6CIKgaslkOJ8 -OodTa7u2doG/P7Seeol8eG8B9uKSHhwlKMO/24LEzs3AHSHW2bEL/n7XECXMNhWW -lFPdHpJ1ieFjEuVcNidag9XQ8zj2V6Q2jnD/dpbegHHy3yVAjYKvgK+TmxNq/EGW -+b5hMo1sHPpX0p8fHpfxKbZxxzOD+KipoDINkvqmG2f9YPdeuEJgwbyCXFt5cEC2 -S3R3K0kpkb0j8wSPPZyGaezKTeKqKtA8oD/omWf4hJg+y4G0LQUAW/0/276uUcTA -ZEzGE/KI3WSwdqAY4PvxsFxqLdp6a5s3FKQKsFXlsqEQfWaCpqMZRjmz3nskQSu/ -WF9X7yZzn/l4GNTj4E8zCcUQGrYkOzACPIMJ/nmWAMTesuB9AqI= -=Agii ------END PGP SIGNATURE----- diff --git a/openssh-8.0p1-openssl-evp.patch b/openssh-9.3p1-merged-openssl-evp.patch similarity index 40% rename from openssh-8.0p1-openssl-evp.patch rename to openssh-9.3p1-merged-openssl-evp.patch index ade0bbb2118460071a8b8347c81363cbacd21bb3..98236c5968faf5c53441cfbddc89b778d9ab9188 100644 --- a/openssh-8.0p1-openssl-evp.patch +++ b/openssh-9.3p1-merged-openssl-evp.patch @@ -1,23 +1,23 @@ -From ed7ec0cdf577ffbb0b15145340cf51596ca3eb89 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -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[] = { +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/digest.h openssh-9.3p1-patched/digest.h +--- openssh-9.3p1/digest.h 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/digest.h 2023-06-06 15:52:25.602551466 +0200 +@@ -32,6 +32,12 @@ + struct sshbuf; + struct ssh_digest_ctx; + ++#ifdef WITH_OPENSSL ++#include ++/* 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 --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/digest-openssl.c openssh-9.3p1-patched/digest-openssl.c +--- openssh-9.3p1/digest-openssl.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/digest-openssl.c 2023-06-06 15:52:25.601551454 +0200 +@@ -64,6 +64,22 @@ { -1, NULL, 0, NULL }, }; @@ -40,30 +40,21 @@ index da7ed72bc..6a21d8adb 100644 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 -+/* 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 --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-dss.c openssh-9.3p1-patched/ssh-dss.c +--- openssh-9.3p1/ssh-dss.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/ssh-dss.c 2023-06-06 15:52:25.624551743 +0200 +@@ -32,6 +32,8 @@ + #include + #include + #include ++#include ++#include -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) + #include + #include +@@ -261,11 +263,15 @@ + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { + EVP_PKEY *pkey = NULL; DSA_SIG *sig = NULL; @@ -79,7 +70,7 @@ index a23c383dc..ea45e7275 100644 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, +@@ -276,17 +282,23 @@ if (key == NULL || key->dsa == NULL || sshkey_type_plain(key->type) != KEY_DSA) return SSH_ERR_INVALID_ARGUMENT; @@ -88,9 +79,8 @@ index a23c383dc..ea45e7275 100644 - 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; ++ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) ++ return ret; + ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len, + data, datalen); + EVP_PKEY_free(pkey); @@ -109,7 +99,7 @@ index a23c383dc..ea45e7275 100644 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, +@@ -319,7 +331,7 @@ *lenp = len; ret = 0; out: @@ -118,15 +108,15 @@ index a23c383dc..ea45e7275 100644 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) +@@ -331,20 +343,20 @@ + const u_char *data, size_t dlen, const char *alg, u_int compat, + struct sshkey_sig_details **detailsp) { + EVP_PKEY *pkey = NULL; - DSA_SIG *sig = NULL; + DSA_SIG *dsig = 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); +- size_t len, hlen = ssh_digest_bytes(SSH_DIGEST_SHA1); + u_char *sigblob = NULL; + size_t len, slen; int ret = SSH_ERR_INTERNAL_ERROR; @@ -136,25 +126,25 @@ index a23c383dc..ea45e7275 100644 if (key == NULL || key->dsa == NULL || sshkey_type_plain(key->type) != KEY_DSA || - signature == NULL || signaturelen == 0) + sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; -- if (dlen == 0) +- if (hlen == 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, + if ((b = sshbuf_from(sig, siglen)) == NULL) +@@ -386,25 +398,28 @@ } sig_r = sig_s = NULL; /* transferred */ - /* sha1 the data */ -- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, +- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen, - digest, sizeof(digest))) != 0) -+ if ((slen = i2d_DSA_SIG(sig, NULL)) == 0) { ++ if ((slen = i2d_DSA_SIG(dsig, NULL)) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; - -- switch (DSA_do_verify(digest, dlen, sig, key->dsa)) { +- switch (DSA_do_verify(digest, hlen, dsig, key->dsa)) { - case 1: - ret = 0; - break; @@ -167,70 +157,197 @@ index a23c383dc..ea45e7275 100644 - default: + } + psig = sigb; -+ if ((slen = i2d_DSA_SIG(sig, &psig)) == 0) { ++ if ((slen = i2d_DSA_SIG(dsig, &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; ++ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0) + goto out; -+ } -+ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen, ++ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen, + sigb, slen); + EVP_PKEY_free(pkey); + out: - explicit_bzero(digest, sizeof(digest)); + free(sigb); - DSA_SIG_free(sig); + DSA_SIG_free(dsig); 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) +@@ -415,6 +430,65 @@ + return ret; + } + ++int ++ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey) ++{ ++ OSSL_PARAM_BLD *param_bld = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL; ++ int ret = 0; ++ ++ if (k == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ DSA_get0_pqg(k->dsa, &p, &q, &g); ++ DSA_get0_key(k->dsa, &pub, &priv); ++ ++ if (p != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (q != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (g != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (pub != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, ++ OSSL_PKEY_PARAM_PUB_KEY, ++ pub) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (priv != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, ++ OSSL_PKEY_PARAM_PRIV_KEY, ++ priv) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++out: ++ OSSL_PARAM_BLD_free(param_bld); ++ EVP_PKEY_CTX_free(ctx); ++ return ret; ++} ++ + static const struct sshkey_impl_funcs sshkey_dss_funcs = { + /* .size = */ ssh_dss_size, + /* .alloc = */ ssh_dss_alloc, +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-ecdsa.c openssh-9.3p1-patched/ssh-ecdsa.c +--- openssh-9.3p1/ssh-ecdsa.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/ssh-ecdsa.c 2023-06-06 15:52:25.626551768 +0200 +@@ -34,6 +34,8 @@ + #include + #include + #include ++#include ++#include + + #include + +@@ -44,6 +44,9 @@ + #include "digest.h" + #define SSHKEY_INTERNAL + #include "sshkey.h" ++#ifdef ENABLE_PKCS11 ++#include "ssh-pkcs11.h" ++#endif + + #include "openbsd-compat/openssl-compat.h" + +@@ -126,19 +128,29 @@ + static int + ssh_ecdsa_generate(struct sshkey *k, int bits) + { +- EC_KEY *private; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *res = NULL; + + if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) + return SSH_ERR_KEY_LENGTH; +- if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) ++ ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) + return SSH_ERR_ALLOC_FAIL; +- if (EC_KEY_generate_key(private) != 1) { +- EC_KEY_free(private); ++ ++ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(k->ecdsa_nid)) <= 0 ++ || EVP_PKEY_keygen(ctx, &res) <= 0) { ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(res); + return SSH_ERR_LIBCRYPTO_ERROR; + } +- EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); +- k->ecdsa = private; +- return 0; ++ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/ ++ k->ecdsa = EVP_PKEY_get1_EC_KEY(res); ++ if (k->ecdsa) ++ EC_KEY_set_asn1_flag(k->ecdsa, OPENSSL_EC_NAMED_CURVE); ++ ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(res); ++ return (k->ecdsa) ? 0 : SSH_ERR_LIBCRYPTO_ERROR; + } + + static int +@@ -228,11 +240,13 @@ + const u_char *data, size_t dlen, + const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { + EVP_PKEY *pkey = NULL; - ECDSA_SIG *sig = NULL; + ECDSA_SIG *esig = 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; +- size_t len, hlen; + 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, +@@ -245,18 +259,33 @@ 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) +- (hlen = 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, +- if ((ret = ssh_digest_memory(hash_alg, data, dlen, - digest, sizeof(digest))) != 0) + -+ if ((pkey = EVP_PKEY_new()) == NULL || -+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) -+ return SSH_ERR_ALLOC_FAIL; ++#ifdef ENABLE_PKCS11 ++ if (is_ecdsa_pkcs11(key->ecdsa)) { ++ if ((pkey = EVP_PKEY_new()) == NULL || ++ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) ++ return SSH_ERR_ALLOC_FAIL; ++ } else { ++#endif ++ if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0) ++ return ret; ++#ifdef ENABLE_PKCS11 ++ } ++#endif + ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, -+ datalen); ++ dlen); + EVP_PKEY_free(pkey); + if (ret < 0) { goto out; + } -- if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) { +- if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) { + psig = sigb; -+ if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) { ++ if (d2i_ECDSA_SIG(&esig, &psig, len) == NULL) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -238,7 +355,7 @@ index 599c7199d..b036796e8 100644 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, +@@ -280,7 +309,7 @@ *lenp = len; ret = 0; out: @@ -246,17 +363,17 @@ index 599c7199d..b036796e8 100644 + 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) + ECDSA_SIG_free(esig); +@@ -293,22 +322,21 @@ + const u_char *data, size_t dlen, const char *alg, u_int compat, + struct sshkey_sig_details **detailsp) { + EVP_PKEY *pkey = NULL; - ECDSA_SIG *sig = NULL; + ECDSA_SIG *esig = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL; - int hash_alg; - u_char digest[SSH_DIGEST_MAX_LENGTH]; -- size_t dlen; +- size_t hlen; + int hash_alg, len; int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL, *sigbuf = NULL; @@ -265,79 +382,489 @@ index 599c7199d..b036796e8 100644 if (key == NULL || key->ecdsa == NULL || sshkey_type_plain(key->type) != KEY_ECDSA || - signature == NULL || signaturelen == 0) + sig == NULL || siglen == 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) +- (hlen = 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, +@@ -344,28 +372,33 @@ } 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) { ++ if ((len = i2d_ECDSA_SIG(esig, 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, +- if ((ret = ssh_digest_memory(hash_alg, data, dlen, - 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)) { +- goto out; +- +- switch (ECDSA_do_verify(digest, hlen, esig, 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; ++ if ((sigb = malloc(len)) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; 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; ++ psig = sigb; ++ if ((len = i2d_ECDSA_SIG(esig, &psig)) == 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len); -+ EVP_PKEY_free(pkey); ++ if (sshbuf_len(sigbuf) != 0) { ++ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; ++ goto out; ++ } ++ ++ if (ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey) != 0) ++ goto out; ++ ret = sshkey_verify_signature(pkey, hash_alg, data, dlen, 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 @@ + ECDSA_SIG_free(esig); +@@ -375,6 +408,79 @@ + return ret; + } + ++int ++ssh_create_evp_ec(EC_KEY *k, int ecdsa_nid, EVP_PKEY **pkey) ++{ ++ OSSL_PARAM_BLD *param_bld = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ BN_CTX *bn_ctx = NULL; ++ uint8_t *pub_ser = NULL; ++ const char *group_name; ++ const EC_POINT *pub = NULL; ++ const BIGNUM *priv = NULL; ++ int ret = 0; ++ ++ if (k == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL || ++ (bn_ctx = BN_CTX_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ ++ if ((group_name = OSSL_EC_curve_nid2name(ecdsa_nid)) == NULL || ++ OSSL_PARAM_BLD_push_utf8_string(param_bld, ++ OSSL_PKEY_PARAM_GROUP_NAME, ++ group_name, ++ strlen(group_name)) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if ((pub = EC_KEY_get0_public_key(k)) != NULL) { ++ const EC_GROUP *group; ++ size_t len; ++ ++ group = EC_KEY_get0_group(k); ++ len = EC_POINT_point2oct(group, pub, ++ POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); ++ if ((pub_ser = malloc(len)) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } ++ EC_POINT_point2oct(group, ++ pub, ++ POINT_CONVERSION_UNCOMPRESSED, ++ pub_ser, ++ len, ++ bn_ctx); ++ if (OSSL_PARAM_BLD_push_octet_string(param_bld, ++ OSSL_PKEY_PARAM_PUB_KEY, ++ pub_ser, ++ len) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ } ++ if ((priv = EC_KEY_get0_private_key(k)) != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, ++ OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ ++out: ++ OSSL_PARAM_BLD_free(param_bld); ++ EVP_PKEY_CTX_free(ctx); ++ BN_CTX_free(bn_ctx); ++ free(pub_ser); ++ return ret; ++} ++ + /* NB. not static; used by ECDSA-SK */ + const struct sshkey_impl_funcs sshkey_ecdsa_funcs = { + /* .size = */ ssh_ecdsa_size, +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/sshkey.c openssh-9.3p1-patched/sshkey.c +--- openssh-9.3p1/sshkey.c 2023-06-06 15:53:36.608444190 +0200 ++++ openssh-9.3p1-patched/sshkey.c 2023-06-06 15:52:25.625551756 +0200 +@@ -34,6 +34,8 @@ + #include + #include + #include ++#include ++#include + #endif + + #include "crypto_api.h" +@@ -575,6 +577,86 @@ + } + + #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; ++ size_t len; ++ ++ if (sigp == NULL || lenp == NULL) { ++ return SSH_ERR_INVALID_ARGUMENT; ++ } ++ ++ slen = EVP_PKEY_get_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_DigestSignInit(ctx, NULL, ssh_digest_to_md(hash_alg), ++ NULL, pkey) != 1 || ++ EVP_DigestSignUpdate(ctx, data, datalen) != 1 || ++ EVP_DigestSignFinal(ctx, sig, &len) != 1) { ++ 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_DigestVerifyInit(ctx, NULL, ssh_digest_to_md(hash_alg), ++ NULL, pkey) != 1 || ++ EVP_DigestVerifyUpdate(ctx, data, datalen) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto done; ++ } ++ ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen); ++ 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) +@@ -3763,3 +3845,27 @@ + return 0; + } + #endif /* WITH_XMSS */ ++ ++#ifdef WITH_OPENSSL ++EVP_PKEY * ++sshkey_create_evp(OSSL_PARAM_BLD *param_bld, EVP_PKEY_CTX *ctx) ++{ ++ EVP_PKEY *ret = NULL; ++ OSSL_PARAM *params = NULL; ++ if (param_bld == NULL || ctx == NULL) { ++ debug2_f("param_bld or ctx is NULL"); ++ return NULL; ++ } ++ if ((params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) { ++ debug2_f("Could not build param list"); ++ return NULL; ++ } ++ if (EVP_PKEY_fromdata_init(ctx) != 1 || ++ EVP_PKEY_fromdata(ctx, &ret, EVP_PKEY_KEYPAIR, params) != 1) { ++ debug2_f("EVP_PKEY_fromdata failed"); ++ OSSL_PARAM_free(params); ++ return NULL; ++ } ++ return ret; ++} ++#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.3p1/sshkey.h openssh-9.3p1-patched/sshkey.h +--- openssh-9.3p1/sshkey.h 2023-06-06 15:53:36.608444190 +0200 ++++ openssh-9.3p1-patched/sshkey.h 2023-06-06 15:52:25.626551768 +0200 +@@ -31,6 +31,9 @@ + #ifdef WITH_OPENSSL + #include + #include ++#include ++#include ++#include + # ifdef OPENSSL_HAS_ECC + # include + # include +@@ -268,6 +271,10 @@ + 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 **); +@@ -324,6 +331,13 @@ + + void sshkey_sig_details_free(struct sshkey_sig_details *); + ++#ifdef WITH_OPENSSL ++EVP_PKEY *sshkey_create_evp(OSSL_PARAM_BLD *, EVP_PKEY_CTX *); ++int ssh_create_evp_dss(const struct sshkey *, EVP_PKEY **); ++int ssh_create_evp_rsa(const struct sshkey *, EVP_PKEY **); ++int ssh_create_evp_ec(EC_KEY *, int, EVP_PKEY **); ++#endif /* WITH_OPENSSL */ ++ + #ifdef SSHKEY_INTERNAL + int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b); + void sshkey_sk_cleanup(struct sshkey *k); +@@ -338,6 +352,10 @@ + #endif + #endif + ++#ifdef ENABLE_PKCS11 ++int pkcs11_get_ecdsa_idx(void); ++#endif ++ + #if !defined(WITH_OPENSSL) + # undef RSA + # undef DSA +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-pkcs11.c openssh-9.3p1-patched/ssh-pkcs11.c +--- openssh-9.3p1/ssh-pkcs11.c 2023-06-06 15:53:36.592443989 +0200 ++++ openssh-9.3p1-patched/ssh-pkcs11.c 2023-06-06 15:52:25.626551768 +0200 +@@ -777,8 +777,24 @@ + + return (0); + } ++ ++int ++is_ecdsa_pkcs11(EC_KEY *ecdsa) ++{ ++ if (EC_KEY_get_ex_data(ecdsa, ec_key_idx) != NULL) ++ return 1; ++ return 0; ++} + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + ++int ++is_rsa_pkcs11(RSA *rsa) ++{ ++ if (RSA_get_ex_data(rsa, rsa_idx) != NULL) ++ return 1; ++ return 0; ++} ++ + /* remove trailing spaces */ + static void + rmspace(u_char *buf, size_t len) +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-pkcs11-client.c openssh-9.3p1-patched/ssh-pkcs11-client.c +--- openssh-9.3p1/ssh-pkcs11-client.c 2023-06-06 15:53:36.591443976 +0200 ++++ openssh-9.3p1-patched/ssh-pkcs11-client.c 2023-06-06 15:52:25.626551768 +0200 +@@ -225,8 +225,36 @@ + static RSA_METHOD *helper_rsa; + #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) + static EC_KEY_METHOD *helper_ecdsa; ++ ++int ++is_ecdsa_pkcs11(EC_KEY *ecdsa) ++{ ++ const EC_KEY_METHOD *meth; ++ ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgstlen, ++ const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey) = NULL; ++ ++ meth = EC_KEY_get_method(ecdsa); ++ EC_KEY_METHOD_get_sign(meth, NULL, NULL, &sign_sig); ++ if (sign_sig == ecdsa_do_sign) ++ return 1; ++ return 0; ++} + #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + ++int ++is_rsa_pkcs11(RSA *rsa) ++{ ++ const RSA_METHOD *meth; ++ int (*priv_enc)(int flen, const unsigned char *from, ++ unsigned char *to, RSA *rsa, int padding) = NULL; ++ ++ meth = RSA_get_method(rsa); ++ priv_enc = RSA_meth_get_priv_enc(meth); ++ if (priv_enc == rsa_encrypt) ++ return 1; ++ return 0; ++} ++ + /* redirect private key crypto operations to the ssh-pkcs11-helper */ + static void + wrap_key(struct sshkey *k) +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-pkcs11.h openssh-9.3p1-patched/ssh-pkcs11.h +--- openssh-9.3p1/ssh-pkcs11.h 2023-06-06 15:53:36.592443989 +0200 ++++ openssh-9.3p1-patched/ssh-pkcs11.h 2023-06-06 15:52:25.626551768 +0200 +@@ -39,6 +39,11 @@ + u_int32_t *); + #endif + ++#ifdef HAVE_EC_KEY_METHOD_NEW ++int is_ecdsa_pkcs11(EC_KEY *ecdsa); ++#endif ++int is_rsa_pkcs11(RSA *rsa); ++ + #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) + #undef ENABLE_PKCS11 + #endif +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-rsa.c openssh-9.3p1-patched/ssh-rsa.c +--- openssh-9.3p1/ssh-rsa.c 2023-03-15 22:28:19.000000000 +0100 ++++ openssh-9.3p1-patched/ssh-rsa.c 2023-06-06 15:52:25.627551781 +0200 +@@ -23,6 +23,8 @@ + + #include + #include ++#include ++#include + + #include + #include +@@ -36,10 +36,13 @@ + #include "sshkey.h" + #include "digest.h" + #include "log.h" ++#ifdef ENABLE_PKCS11 ++#include "ssh-pkcs11.h" ++#endif #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) + static u_int + ssh_rsa_size(const struct sshkey *key) +@@ -131,27 +133,50 @@ + static int + ssh_rsa_generate(struct sshkey *k, int bits) + { +- RSA *private = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *res = NULL; + BIGNUM *f4 = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + + if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || + bits > SSHBUF_MAX_BIGNUM * 8) + return SSH_ERR_KEY_LENGTH; +- 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*/ ++ k->rsa = EVP_PKEY_get1_RSA(res); ++ if (k->rsa) { ++ ret = 0; ++ } else { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +- k->rsa = private; +- private = NULL; +- ret = 0; + out: +- RSA_free(private); ++ EVP_PKEY_CTX_free(ctx); ++ EVP_PKEY_free(res); + BN_free(f4); + return ret; + } +@@ -317,21 +342,6 @@ return -1; } @@ -359,14 +886,14 @@ index 9b14f9a9a..8ef3a6aca 100644 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) +@@ -393,11 +403,10 @@ + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { - const BIGNUM *rsa_n; - u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; - size_t slen = 0; -- u_int dlen, len; +- u_int hlen, len; - int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; + EVP_PKEY *pkey = NULL; + u_char *sig = NULL; @@ -375,10 +902,10 @@ index 9b14f9a9a..8ef3a6aca 100644 struct sshbuf *b = NULL; if (lenp != NULL) -@@ -180,33 +164,24 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, +@@ -409,33 +418,33 @@ hash_alg = SSH_DIGEST_SHA1; else - hash_alg = rsa_hash_id_from_keyname(alg_ident); + hash_alg = rsa_hash_id_from_keyname(alg); + if (key == NULL || key->rsa == NULL || hash_alg == -1 || sshkey_type_plain(key->type) != KEY_RSA) @@ -392,7 +919,7 @@ index 9b14f9a9a..8ef3a6aca 100644 - - /* hash the data */ - nid = rsa_hash_alg_nid(hash_alg); -- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) +- if ((hlen = ssh_digest_bytes(hash_alg)) == 0) - return SSH_ERR_INTERNAL_ERROR; - if ((ret = ssh_digest_memory(hash_alg, data, datalen, - digest, sizeof(digest))) != 0) @@ -402,24 +929,33 @@ index 9b14f9a9a..8ef3a6aca 100644 - 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; +- goto out; ++#ifdef ENABLE_PKCS11 ++ if (is_rsa_pkcs11(key->rsa)) { ++ if ((pkey = EVP_PKEY_new()) == NULL || ++ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) ++ return SSH_ERR_ALLOC_FAIL; ++ } else { ++#endif ++ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) ++ return ret; ++#ifdef ENABLE_PKCS11 + } +- +- if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) { +- ret = SSH_ERR_LIBCRYPTO_ERROR; ++#endif + 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, +@@ -444,6 +453,7 @@ ret = SSH_ERR_INTERNAL_ERROR; goto out; } @@ -427,7 +963,7 @@ index 9b14f9a9a..8ef3a6aca 100644 /* 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, +@@ -464,7 +474,6 @@ *lenp = len; ret = 0; out: @@ -435,20 +971,20 @@ index 9b14f9a9a..8ef3a6aca 100644 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) +@@ -476,10 +485,10 @@ + const u_char *data, size_t dlen, const char *alg, u_int compat, + struct sshkey_sig_details **detailsp) { - 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, hlen; + 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, +@@ -487,8 +496,7 @@ sshkey_type_plain(key->type) != KEY_RSA || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; @@ -458,30 +994,29 @@ index 9b14f9a9a..8ef3a6aca 100644 return SSH_ERR_KEY_LENGTH; if ((b = sshbuf_from(sig, siglen)) == NULL) -@@ -310,16 +284,15 @@ ssh_rsa_verify(const struct sshkey *key, +@@ -540,16 +548,13 @@ explicit_bzero(sigblob, diff); len = modlen; } -- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { +- if ((hlen = ssh_digest_bytes(hash_alg)) == 0) { - ret = SSH_ERR_INTERNAL_ERROR; +- goto out; +- } +- if ((ret = ssh_digest_memory(hash_alg, data, dlen, +- digest, sizeof(digest))) != 0) + -+ if ((pkey = EVP_PKEY_new()) == NULL || -+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) { -+ ret = SSH_ERR_ALLOC_FAIL; ++ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0) 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, +- ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len, - key->rsa); ++ ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey); ++ EVP_PKEY_free(pkey); ++ out: freezero(sigblob, len); free(sigtype); -@@ -328,122 +301,26 @@ ssh_rsa_verify(const struct sshkey *key, +@@ -558,125 +563,110 @@ return ret; } @@ -558,7 +1093,6 @@ index 9b14f9a9a..8ef3a6aca 100644 - return 0; -} + size_t rsasize = 0; -+ const RSA *rsa; + int ret; -static int @@ -578,8 +1112,8 @@ index 9b14f9a9a..8ef3a6aca 100644 - ret = SSH_ERR_INVALID_ARGUMENT; - goto done; - } -+ rsa = EVP_PKEY_get0_RSA(pkey); - rsasize = RSA_size(rsa); +- rsasize = RSA_size(rsa); ++ rsasize = EVP_PKEY_get_size(pkey); if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || siglen == 0 || siglen > rsasize) { ret = SSH_ERR_INVALID_ARGUMENT; @@ -613,108 +1147,90 @@ index 9b14f9a9a..8ef3a6aca 100644 - 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) ++ssh_create_evp_rsa(const struct sshkey *k, EVP_PKEY **pkey) +{ -+ EVP_MD_CTX *ctx = NULL; -+ u_char *sig = NULL; -+ int ret, slen, len; -+ -+ if (sigp == NULL || lenp == NULL) { -+ return SSH_ERR_INVALID_ARGUMENT; -+ } ++ OSSL_PARAM_BLD *param_bld = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ int ret = 0; ++ const BIGNUM *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL; ++ const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; + -+ slen = EVP_PKEY_size(pkey); -+ if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) -+ return SSH_ERR_INVALID_ARGUMENT; ++ if (k == NULL) ++ return SSH_ERR_INVALID_ARGUMENT; ++ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL || ++ (param_bld = OSSL_PARAM_BLD_new()) == NULL) { ++ ret = SSH_ERR_ALLOC_FAIL; ++ goto out; ++ } + -+ len = slen; -+ if ((sig = malloc(slen)) == NULL) { -+ return SSH_ERR_ALLOC_FAIL; -+ } ++ RSA_get0_key(k->rsa, &n, &e, &d); ++ RSA_get0_factors(k->rsa, &p, &q); ++ RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp); + -+ 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) { ++ if (n != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, n) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (e != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, e) != 1) { + 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; -+} ++ goto out; ++ } ++ if (d != NULL && ++ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, d) != 1) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } + -+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 ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) { ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } + -+ 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) { ++ /* setting this to param_build makes the creation process fail */ ++ if (p != NULL && ++ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, p) != 1) { ++ debug2_f("failed to add 'p' param"); + 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: ++ goto out; ++ } ++ if (q != NULL && ++ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, q) != 1) { ++ debug2_f("failed to add 'q' param"); + ret = SSH_ERR_LIBCRYPTO_ERROR; -+ break; -+ } ++ goto out; ++ } ++ if (dmp1 != NULL && ++ EVP_PKEY_set_bn_param(*pkey, ++ OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) != 1) { ++ debug2_f("failed to add 'dmp1' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (dmq1 != NULL && ++ EVP_PKEY_set_bn_param(*pkey, ++ OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) != 1) { ++ debug2_f("failed to add 'dmq1' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } ++ if (iqmp != NULL && ++ EVP_PKEY_set_bn_param(*pkey, ++ OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) != 1) { ++ debug2_f("failed to add 'iqmp' param"); ++ ret = SSH_ERR_LIBCRYPTO_ERROR; ++ goto out; ++ } + -+done: -+ EVP_MD_CTX_free(ctx); -+ return ret; ++out: ++ OSSL_PARAM_BLD_free(param_bld); ++ EVP_PKEY_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 **); - + static const struct sshkey_impl_funcs sshkey_rsa_funcs = { + /* .size = */ ssh_rsa_size, + /* .alloc = */ ssh_rsa_alloc, diff --git a/openssh-9.3p1-openssl-compat.patch b/openssh-9.3p1-openssl-compat.patch new file mode 100644 index 0000000000000000000000000000000000000000..cf512ef9ae8c5da648f40e1806bb1b6c89821ff4 --- /dev/null +++ b/openssh-9.3p1-openssl-compat.patch @@ -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; diff --git a/openssh-9.3p1-upstream-cve-2023-38408.patch b/openssh-9.3p1-upstream-cve-2023-38408.patch deleted file mode 100644 index 03688862c0bde28a0077d0eba536f0b8d4b22abd..0000000000000000000000000000000000000000 --- a/openssh-9.3p1-upstream-cve-2023-38408.patch +++ /dev/null @@ -1,98 +0,0 @@ -diff --git a/ssh-agent.c b/ssh-agent.c -index 618bb198..8ea831f4 100644 -diff -up openssh-9.3p1/ssh-agent.c.cve openssh-9.3p1/ssh-agent.c ---- openssh-9.3p1/ssh-agent.c.cve 2023-07-21 15:38:13.237276580 +0200 -+++ openssh-9.3p1/ssh-agent.c 2023-07-21 15:41:30.269943569 +0200 -@@ -169,6 +169,12 @@ char socket_dir[PATH_MAX]; - /* Pattern-list of allowed PKCS#11/Security key paths */ - static char *allowed_providers; - -+/* -+ * Allows PKCS11 providers or SK keys that use non-internal providers to -+ * be added over a remote connection (identified by session-bind@openssh.com). -+ */ -+static int remote_add_provider; -+ - /* locking */ - #define LOCK_SIZE 32 - #define LOCK_SALT_SIZE 16 -@@ -1228,6 +1234,12 @@ process_add_identity(SocketEntry *e) - if (strcasecmp(sk_provider, "internal") == 0) { - debug_f("internal provider"); - } else { -+ if (e->nsession_ids != 0 && !remote_add_provider) { -+ verbose("failed add of SK provider \"%.100s\": " -+ "remote addition of providers is disabled", -+ sk_provider); -+ goto out; -+ } - if (realpath(sk_provider, canonical_provider) == NULL) { - verbose("failed provider \"%.100s\": " - "realpath: %s", sk_provider, -@@ -1368,7 +1380,7 @@ no_identities(SocketEntry *e) - - #ifdef ENABLE_PKCS11 - static char * --sanitize_pkcs11_provider(const char *provider) -+sanitize_pkcs11_provider(SocketEntry *e, const char *provider) - { - struct pkcs11_uri *uri = NULL; - char *sane_uri, *module_path = NULL; /* default path */ -@@ -1399,6 +1411,11 @@ sanitize_pkcs11_provider(const char *pro - module_path = strdup(provider); /* simple path */ - - if (module_path != NULL) { /* do not validate default NULL path in URI */ -+ if (e->nsession_ids != 0 && !remote_add_provider) { -+ verbose("failed PKCS#11 add of \"%.100s\": remote addition of " -+ "providers is disabled", provider); -+ return NULL; -+ } - if (realpath(module_path, canonical_provider) == NULL) { - verbose("failed PKCS#11 provider \"%.100s\": realpath: %s", - module_path, strerror(errno)); -@@ -1455,7 +1472,7 @@ process_add_smartcard_key(SocketEntry *e - goto send; - } - -- sane_uri = sanitize_pkcs11_provider(provider); -+ sane_uri = sanitize_pkcs11_provider(e, provider); - if (sane_uri == NULL) - goto send; - -@@ -1516,7 +1533,7 @@ process_remove_smartcard_key(SocketEntry - } - free(pin); - -- sane_uri = sanitize_pkcs11_provider(provider); -+ sane_uri = sanitize_pkcs11_provider(e, provider); - if (sane_uri == NULL) - goto send; - -@@ -2108,7 +2125,9 @@ main(int ac, char **av) - break; - case 'O': - if (strcmp(optarg, "no-restrict-websafe") == 0) -- restrict_websafe = 0; -+ restrict_websafe = 0; -+ else if (strcmp(optarg, "allow-remote-pkcs11") == 0) -+ remote_add_provider = 1; - else - fatal("Unknown -O option"); - break; -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 */ diff --git a/openssh-9.3p2.tar.gz b/openssh-9.3p2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a670bd8ef9841e04c51b55d924630261ee007880 Binary files /dev/null and b/openssh-9.3p2.tar.gz differ diff --git a/openssh-9.3p2.tar.gz.asc b/openssh-9.3p2.tar.gz.asc new file mode 100644 index 0000000000000000000000000000000000000000..4c69906cd5d1f6092d81e0b9c5d1fb0cf31698cc --- /dev/null +++ b/openssh-9.3p2.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmS3g5wACgkQKj9BTnNg +YLrMYw//evjl0mlSnycb85tWASdBWQh28xQCouuqYhDhY+8kt6YpEx34r4zuXvL3 +pEN/F1ancNXwvlRPct/tF3OEQVpKHZqiRyfWuHHURSBLaGf9V1b+gQgfM4lEQNtH +8PqRj+ur8E2GMGxvxuDKPcfduCTFrjbPJ/0OCgquuEteSM6dgcClT7q5SKKpTVSa +jV0PaXeYgnaa+u+4GsH01oUteyJNmhvEa4T+fC1RDrct1DiieUQNkaw3pwMqYXA5 +8PldGatn/npNM5ZFW4uxTjbib2yJXNIEhUIzo2A00XWRG3jIArtRJwJ6ZSBahUE4 +PyasPMhJVIxIaKy5OL4s4FAd1goe2hBlPzmDhUJOhpFniLIZ9dS5AGaX4i2TjsZl +iaIwtE2VLIn3peKZPvm7SCBqyBoiPKC0BfHmVOYs8c1W5Q30jE+kCcTDrJhHl32/ +kN5khCHIg6bUc3JzFZM7Ib0tshNP5AY0pyduSEF7SPOB5Zz2E+EwkDmkrnw9FoMh +LCvSERDkBdxWD7okUdb0ARr564lShRjd2UTFZqv3Py4nVfvnP19RgCfakNg0CZ3w +VoLytn8OQ/joAx4GMWox6g5ieYqeQ2kLzXYfXObTlDIjxirFeiBYPh6Ln5oGl81/ +jx/172HqCzRDgUogtZ/BTwiLDEzTHG7YS5RDIUYkqEGkkjjj6gg= +=yVD2 +-----END PGP SIGNATURE----- diff --git a/openssh-9.6p1-CVE-2023-51385.patch b/openssh-9.6p1-CVE-2023-51385.patch deleted file mode 100644 index 8a422054f4e82e1f3f39dce1c7facc11500d35a2..0000000000000000000000000000000000000000 --- a/openssh-9.6p1-CVE-2023-51385.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 7ef3787c84b6b524501211b11a26c742f829af1a Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Mon, 18 Dec 2023 14:47:44 +0000 -Subject: [PATCH] upstream: ban user/hostnames with most shell metacharacters - -This makes ssh(1) refuse user or host names provided on the -commandline that contain most shell metacharacters. - -Some programs that invoke ssh(1) using untrusted data do not filter -metacharacters in arguments they supply. This could create -interactions with user-specified ProxyCommand and other directives -that allow shell injection attacks to occur. - -It's a mistake to invoke ssh(1) with arbitrary untrusted arguments, -but getting this stuff right can be tricky, so this should prevent -most obvious ways of creating risky situations. It however is not -and cannot be perfect: ssh(1) has no practical way of interpreting -what shell quoting rules are in use and how they interact with the -user's specified ProxyCommand. - -To allow configurations that use strange user or hostnames to -continue to work, this strictness is applied only to names coming -from the commandline. Names specified using User or Hostname -directives in ssh_config(5) are not affected. - -feedback/ok millert@ markus@ dtucker@ deraadt@ - -OpenBSD-Commit-ID: 3b487348b5964f3e77b6b4d3da4c3b439e94b2d9 ---- - ssh.c | 41 ++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 40 insertions(+), 1 deletion(-) - -diff --git a/ssh.c b/ssh.c -index 35c48e62d18..48d93ddf2a9 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -626,6 +626,41 @@ ssh_conn_info_free(struct ssh_conn_info *cinfo) - free(cinfo); - } - -+static int -+valid_hostname(const char *s) -+{ -+ size_t i; -+ -+ if (*s == '-') -+ return 0; -+ for (i = 0; s[i] != 0; i++) { -+ if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL || -+ isspace((u_char)s[i]) || iscntrl((u_char)s[i])) -+ return 0; -+ } -+ return 1; -+} -+ -+static int -+valid_ruser(const char *s) -+{ -+ size_t i; -+ -+ if (*s == '-') -+ return 0; -+ for (i = 0; s[i] != 0; i++) { -+ if (strchr("'`\";&<>|(){}", s[i]) != NULL) -+ return 0; -+ /* Disallow '-' after whitespace */ -+ if (isspace((u_char)s[i]) && s[i + 1] == '-') -+ return 0; -+ /* Disallow \ in last position */ -+ if (s[i] == '\\' && s[i + 1] == '\0') -+ return 0; -+ } -+ return 1; -+} -+ - /* - * Main program for the ssh client. - */ -@@ -1118,6 +1153,10 @@ main(int ac, char **av) - if (!host) - usage(); - -+ if (!valid_hostname(host)) -+ fatal("hostname contains invalid characters"); -+ if (options.user != NULL && !valid_ruser(options.user)) -+ fatal("remote username contains invalid characters"); - host_arg = xstrdup(host); - - /* Initialize the command to execute on remote host. */ diff --git a/openssh.spec b/openssh.spec index 8073763a2799054153589dd734f18d8339a90099..33736003c5b7d2aa1b6fc58f68b2394c7f15717d 100644 --- a/openssh.spec +++ b/openssh.spec @@ -1,117 +1,307 @@ -%define anolis_release 11 +%define anolis_release 1 + +%global WITH_SELINUX 1 + %global _hardened_build 1 -%global sysconfig_anaconda /etc/sysconfig/sshd-permitrootlogin -%bcond_without libfido2 -%bcond_without libedit -%bcond_without pam +# 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 GTK3 instead of GTK2 in gnome-ssh-askpass +%global gtk3 1 + +# Build position-independent executables (requires toolchain support)? +%global pie 1 + +# Do we want kerberos5 support (1=yes 0=no) +%global kerberos5 1 + +# Do we want libedit support +%global libedit 1 + +# Whether to build pam_ssh_agent_auth +%global pam_ssh_agent 0 + +# Reserve options to override askpass settings with: +# rpm -ba|--rebuild --define 'skip_xxx 1' +%{?skip_gnome_askpass:%global no_gnome_askpass 1} + +# 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 9.3p2 +%global pam_ssh_agent_ver 0.10.4 +%global pam_ssh_agent_rel 9 -Name: openssh -Version: 9.0p1 -Release: %{anolis_release}%{?dist} Summary: An open source implementation of SSH protocol version 2 -License: BSD -URL: http://www.openssh.com/portable.html +Name: openssh +Version: %{openssh_ver} +Release: %{anolis_release}%{?dist} +URL: http://www.openssh.com/portable.html +#URL1: https://github.com/jbeverly/pam_ssh_agent_auth/ Source0: http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz -Source1: https://github.com/jbeverly/pam_ssh_agent_auth/archive/pam_ssh_agent_auth-0.10.4.tar.gz +Source1: http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc Source2: sshd.pam -Source3: pam_ssh_agent-rmheaders -Source4: ssh-keycat.pam -Source5: sshd.sysconfig -Source6: sshd@.service -Source7: sshd.socket -Source8: sshd.service -Source9: sshd-keygen@.service -Source10: sshd-keygen -Source11: sshd-keygen.target -Source12: ssh-agent.service -Source13: ssh-agent.socket -Source14: openssh-server-systemd-sysusers.conf - -# --- patches for pam_ssh-agent --- -Patch100: pam_ssh_agent_auth-0.9.3-build.patch -Patch101: pam_ssh_agent_auth-0.10.3-seteuid.patch -Patch102: pam_ssh_agent_auth-0.9.2-visibility.patch -Patch103: pam_ssh_agent_auth-0.10.2-compat.patch -Patch104: pam_ssh_agent_auth-0.9.3-agent_structure.patch -Patch105: pam_ssh_agent_auth-0.10.2-dereference.patch -Patch106: pam_ssh_agent_auth-0.10.4-rsasha2.patch - -Patch300: openssh-7.8p1-role-mls.patch -Patch301: openssh-6.6p1-privsep-selinux.patch -Patch302: openssh-6.6p1-keycat.patch -Patch303: openssh-6.6p1-allow-ip-opts.patch -Patch304: openssh-5.8p2-sigpipe.patch -Patch305: openssh-7.2p2-x11.patch -Patch306: openssh-5.1p1-askpass-progress.patch -Patch307: openssh-4.3p2-askpass-grab-info.patch -Patch308: openssh-7.7p1-anolis.patch -Patch309: openssh-7.8p1-UsePAM-warning.patch -Patch310: openssh-6.3p1-ctr-evp-fast.patch -Patch311: openssh-8.0p1-gssapi-keyex.patch -Patch312: openssh-6.6p1-force_krb.patch -Patch313: openssh-7.7p1-gssapi-new-unique.patch -Patch314: openssh-7.2p2-k5login_directory.patch -Patch315: openssh-6.6p1-kuserok.patch -Patch316: openssh-6.4p1-fromto-remote.patch -Patch317: openssh-6.6.1p1-selinux-contexts.patch -Patch318: openssh-6.6.1p1-log-in-chroot.patch -Patch319: openssh-6.6.1p1-scp-non-existing-directory.patch -Patch320: openssh-6.6p1-GSSAPIEnablek5users.patch -Patch321: openssh-6.8p1-sshdT-output.patch -Patch322: openssh-6.7p1-sftp-force-permission.patch -Patch323: openssh-7.3p1-x11-max-displays.patch -Patch324: openssh-7.4p1-systemd.patch -Patch325: openssh-7.6p1-cleanup-selinux.patch -Patch326: openssh-7.5p1-sandbox.patch -Patch327: openssh-8.0p1-pkcs11-uri.patch -Patch328: openssh-7.8p1-scp-ipv6.patch -Patch329: openssh-8.0p1-crypto-policies.patch -Patch330: openssh-8.0p1-openssl-evp.patch -Patch331: openssh-8.0p1-openssl-kdf.patch -Patch332: openssh-8.2p1-visibility.patch -Patch333: openssh-8.2p1-x11-without-ipv6.patch -Patch334: openssh-8.0p1-keygen-strip-doseol.patch -Patch335: openssh-8.0p1-preserve-pam-errors.patch -Patch336: openssh-8.7p1-scp-kill-switch.patch -Patch337: openssh-8.7p1-recursive-scp.patch -Patch338: openssh-8.7p1-minrsabits.patch -Patch339: openssh-8.7p1-evpgenkey.patch -Patch340: openssh-7.6p1-audit.patch -Patch341: openssh-7.1p2-audit-race-condition.patch -Patch342: openssh-7.7p1-fips.patch -Patch343: openssh-8.7p1-scp-clears-file.patch -Patch344: openssh-8.7p1-ssh-manpage.patch -Patch345: openssh-8.7p1-mem-leak.patch -Patch346: openssh-8.7p1-gssapi-auth.patch -Patch347: openssh-8.7p1-negotiate-supported-algs.patch -Patch348: openssh-6.7p1-coverity.patch -Patch349: add-loongarch64-support-for-openssh.patch -Patch350: openssh-8.7p1-CVE-2023-25136.patch -Patch351: openssh-9.3p1-upstream-cve-2023-38408.patch -Patch352: openssh-9.6p1-CVE-2023-51385.patch - -BuildRequires: autoconf automake make gcc -BuildRequires: perl-interpreter perl-generators perl-podlators -BuildRequires: zlib-devel libX11-devel gtk3-devel pam-devel p11-kit-devel krb5-devel -BuildRequires: audit-libs-devel >= 2.0.5 openssl-devel >= 0.9.8j -BuildRequires: libselinux-devel >= 2.3-5 audit-libs >= 1.0.8 -BuildRequires: util-linux groff xauth -BuildRequires: systemd-devel systemd-rpm-macros -%if %{with libfido2} -BuildRequires: libfido2-devel +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 +Source6: ssh-keycat.pam +Source7: sshd.sysconfig +Source9: sshd@.service +Source10: sshd.socket +Source11: sshd.service +Source12: sshd-keygen@.service +Source13: sshd-keygen +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 + +#https://bugzilla.mindrot.org/show_bug.cgi?id=2581 +Patch100: openssh-6.7p1-coverity.patch + +#https://bugzilla.mindrot.org/show_bug.cgi?id=1402 +# https://bugzilla.redhat.com/show_bug.cgi?id=1171248 +# record pfs= field in CRYPTO_SESSION audit event +Patch200: openssh-7.6p1-audit.patch +# Audit race condition in forked child (#1310684) +Patch201: openssh-7.1p2-audit-race-condition.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2049947 +Patch202: openssh-9.0p1-audit-log.patch + +# --- pam_ssh-agent --- +# make it build reusing the openssh sources +Patch300: pam_ssh_agent_auth-0.9.3-build.patch +# check return value of seteuid() +# https://sourceforge.net/p/pamsshagentauth/bugs/23/ +Patch301: pam_ssh_agent_auth-0.10.3-seteuid.patch +# explicitly make pam callbacks visible +Patch302: pam_ssh_agent_auth-0.9.2-visibility.patch +# update to current version of agent structure +Patch305: pam_ssh_agent_auth-0.9.3-agent_structure.patch +# remove prefixes to be able to build against current openssh library +Patch306: pam_ssh_agent_auth-0.10.2-compat.patch +# Fix NULL dereference from getpwuid() return value +# https://sourceforge.net/p/pamsshagentauth/bugs/22/ +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 +#https://bugzilla.redhat.com/show_bug.cgi?id=781634 +Patch404: openssh-6.6p1-privsep-selinux.patch +#? +Patch502: openssh-6.6p1-keycat.patch + +#https://bugzilla.mindrot.org/show_bug.cgi?id=1644 +Patch601: openssh-6.6p1-allow-ip-opts.patch +#(drop?) https://bugzilla.mindrot.org/show_bug.cgi?id=1925 +Patch606: openssh-5.9p1-ipv6man.patch +#? +Patch607: openssh-5.8p2-sigpipe.patch +#https://bugzilla.mindrot.org/show_bug.cgi?id=1789 +Patch609: openssh-7.2p2-x11.patch + +#? +Patch700: openssh-7.7p1-fips.patch +#? +Patch702: openssh-5.1p1-askpass-progress.patch +#https://bugzilla.redhat.com/show_bug.cgi?id=198332 +Patch703: openssh-4.3p2-askpass-grab-info.patch +#https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX) +Patch707: openssh-7.7p1-redhat.patch +# warn users for unsupported UsePAM=no (#757545) +Patch711: openssh-7.8p1-UsePAM-warning.patch + +# GSSAPI Key Exchange (RFC 4462 + RFC 8732) +# from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master +# and +# Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures +# upstream MR: +# https://github.com/openssh-gsskex/openssh-gsskex/pull/21 +Patch800: openssh-8.0p1-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) +# CVE-2014-9278 +Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch +# Improve ccache handling in openssh (#991186, #1199363, #1566494) +# https://bugzilla.mindrot.org/show_bug.cgi?id=2775 +Patch804: openssh-7.7p1-gssapi-new-unique.patch +# Respect k5login_directory option in krk5.conf (#1328243) +Patch805: openssh-7.2p2-k5login_directory.patch + + +#https://bugzilla.mindrot.org/show_bug.cgi?id=1780 +Patch901: openssh-6.6p1-kuserok.patch +# Use tty allocation for a remote scp (#985650) +Patch906: openssh-6.4p1-fromto-remote.patch +# privsep_preauth: use SELinux context from selinux-policy (#1008580) +Patch916: openssh-6.6.1p1-selinux-contexts.patch +# log via monitor in chroots without /dev/log (#2681) +Patch918: openssh-6.6.1p1-log-in-chroot.patch +# scp file into non-existing directory (#1142223) +Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch +# apply upstream patch and make sshd -T more consistent (#1187521) +Patch922: openssh-6.8p1-sshdT-output.patch +# Add sftp option to force mode of created files (#1191055) +Patch926: openssh-6.7p1-sftp-force-permission.patch +# make s390 use /dev/ crypto devices -- ignore closefrom +Patch939: openssh-7.2p2-s390-closefrom.patch +# Move MAX_DISPLAYS to a configuration option (#1341302) +Patch944: openssh-7.3p1-x11-max-displays.patch +# Help systemd to track the running service +Patch948: openssh-7.4p1-systemd.patch +# Pass inetd flags for SELinux down to openbsd compat level +Patch949: openssh-7.6p1-cleanup-selinux.patch +# Sandbox adjustments for s390 and audit +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 +# 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) +# 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 +Patch965: openssh-8.2p1-visibility.patch +# Do not break X11 without IPv6 +Patch966: openssh-8.2p1-x11-without-ipv6.patch +# ssh-keygen printing fingerprint issue with Windows keys (#1901518) +Patch974: openssh-8.0p1-keygen-strip-doseol.patch +# sshd provides PAM an incorrect error code (#1879503) +Patch975: openssh-8.0p1-preserve-pam-errors.patch + +# Implement kill switch for SCP protocol +Patch977: openssh-8.7p1-scp-kill-switch.patch + +# Workaround for lack of sftp_realpath in older versions of RHEL +# https://bugzilla.redhat.com/show_bug.cgi?id=2038854 +# https://github.com/openssh/openssh-portable/pull/299 +# downstream only +Patch981: openssh-8.7p1-recursive-scp.patch +# https://github.com/djmdjm/openssh-wip/pull/13 +Patch982: openssh-8.7p1-minrsabits.patch +# downstream only, IBMCA tentative fix +# From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14 +Patch984: openssh-8.7p1-ibmca.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 + +# 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 + +Patch1012: openssh-9.0p1-evp-fips-dh.patch +Patch1013: openssh-9.0p1-evp-fips-ecdh.patch +Patch1014: openssh-8.7p1-nohostsha1proof.patch +# upstream b7afd8a4ecaca8afd3179b55e9db79c0ff210237 +Patch1016: openssh-9.3p1-openssl-compat.patch +# for loongarch +Patch1017: add-loongarch64-support-for-openssh.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} +BuildRequires: libX11-devel +%if %{gtk3} +BuildRequires: gtk3-devel +%else +BuildRequires: gtk3-devel %endif -%if %{with libedit} -BuildRequires: libedit-devel ncurses-devel %endif +BuildRequires: autoconf, automake, perl-interpreter, perl-generators, zlib-devel +BuildRequires: audit-libs-devel >= 2.0.5 +BuildRequires: util-linux, groff +BuildRequires: pam-devel +BuildRequires: openssl-devel >= 0.9.8j +BuildRequires: perl-podlators +BuildRequires: systemd-devel +BuildRequires: systemd-rpm-macros +BuildRequires: gcc make +BuildRequires: p11-kit-devel +BuildRequires: libfido2-devel Recommends: p11-kit - -Requires: /sbin/nologin -Requires: libselinux >= 2.3-5 audit-libs >= 1.0.8 Obsoletes: openssh-ldap < 8.3p1-4 Obsoletes: openssh-cavs < 8.4p1-5 +%if %{kerberos5} +BuildRequires: krb5-devel +%endif + +%if %{libedit} +BuildRequires: libedit-devel ncurses-devel +%endif + +%if %{WITH_SELINUX} +Requires: libselinux >= 2.3-5 +BuildRequires: libselinux-devel >= 2.3-5 +Requires: audit-libs >= 1.0.8 +BuildRequires: audit-libs >= 1.0.8 +%endif + +BuildRequires: xauth +# for tarball signature verification +BuildRequires: gnupg2 + +%package clients +Summary: An open source SSH client applications +Requires: openssh = %{EVR} +Requires: crypto-policies >= 20220824-1 + +%package server +Summary: An open source SSH server daemon +Requires: openssh = %{EVR} +Requires(pre): /usr/sbin/useradd +Requires: pam >= 1.0.1-3 +Requires: crypto-policies >= 20220824-1 +%{?systemd_requires} + +%package keycat +Summary: A mls keycat backend for openssh +Requires: openssh = %{EVR} + +%package askpass +Summary: A passphrase dialog for OpenSSH and X +Requires: openssh = %{EVR} + +%package doc +Summary: Documentation files for %{name} +Requires: openssh = %{EVR} +BuildArch: noarch + +%package sk-dummy +Summary: OpenSSH SK driver for test purposes +Requires: openssh = %{EVR} + +%package -n pam_ssh_agent_auth +Summary: PAM module for authentication with ssh-agent +Version: %{pam_ssh_agent_ver} +Release: %{pam_ssh_agent_rel}.%{anolis_release}%{?dist} +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 commands on a remote machine. SSH is intended to replace rlogin and @@ -126,59 +316,31 @@ This package includes the core files necessary for both the OpenSSH client and server. To make this package useful, you should also install openssh-clients, openssh-server, or both. -%package clients -Summary: An open source SSH client applications -Requires: openssh = %{EVR} -Requires: crypto-policies >= 20220824-1 - %description clients OpenSSH is a free version of SSH (Secure SHell), a program for logging into and executing commands on a remote machine. This package includes the clients necessary to make encrypted connections to SSH servers. -%package server -Summary: An open source SSH server daemon -Requires: openssh = %{EVR} -Requires(pre): /usr/sbin/useradd -Requires: pam >= 1.0.1-3 crypto-policies >= 20220824-1 -%{?systemd_requires} - %description server 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 secure shell daemon (sshd). The sshd daemon allows SSH clients to securely connect to your SSH server. -%package keycat -Summary: A mls keycat backend for openssh -Requires: openssh = %{EVR} - %description keycat OpenSSH mls keycat is backend for using the authorized keys in the openssh in the mls mode. -%package askpass -Summary: A passphrase dialog for OpenSSH and X -Requires: openssh = %{EVR} - %description askpass 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. -%package doc -Summary: Documentation files for %{name} -Requires: openssh = %{EVR} -BuildArch: noarch - %description doc The %{name}-doc package contains documentation files for %{name}. -%package -n pam_ssh_agent_auth -Summary: PAM module for authentication with ssh-agent -Version: 0.10.4 -Release: 7.%{anolis_release}%{?dist} -License: BSD +%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 @@ -189,19 +351,93 @@ remote ssh-agent instance. The module is most useful for su and sudo service stacks. %prep -%setup -q -a 1 - -%if %{with pam} -pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 -%autopatch -M 200 -p2 -rm -f $(cat %{SOURCE3}) +gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0} +%setup -q -a 4 + +%if %{pam_ssh_agent} +pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver} +%patch -P 300 -p2 -b .psaa-build +%patch -P 301 -p2 -b .psaa-seteuid +%patch -P 302 -p2 -b .psaa-visibility +%patch -P 306 -p2 -b .psaa-compat +%patch -P 305 -p2 -b .psaa-agent +%patch -P 307 -p2 -b .psaa-deref +%patch -P 308 -p2 -b .rsasha2 +%patch -P 309 -p1 -b .psaa-configure-c99 +# Remove duplicate headers and library files +rm -f $(cat %{SOURCE5}) popd %endif -%autopatch -m 200 -p1 +%patch -P 400 -p1 -b .role-mls +%patch -P 404 -p1 -b .privsep-selinux + +%patch -P 502 -p1 -b .keycat + +%patch -P 601 -p1 -b .ip-opts +%patch -P 606 -p1 -b .ipv6man +%patch -P 607 -p1 -b .sigpipe +%patch -P 609 -p1 -b .x11 +%patch -P 702 -p1 -b .progress +%patch -P 703 -p1 -b .grab-info +%patch -P 707 -p1 -b .redhat +%patch -P 711 -p1 -b .log-usepam-no +# +%patch -P 800 -p1 -b .gsskex +%patch -P 801 -p1 -b .force_krb +%patch -P 804 -p1 -b .ccache_name +%patch -P 805 -p1 -b .k5login +# +%patch -P 901 -p1 -b .kuserok +%patch -P 906 -p1 -b .fromto-remote +%patch -P 916 -p1 -b .contexts +%patch -P 918 -p1 -b .log-in-chroot +%patch -P 919 -p1 -b .scp +%patch -P 802 -p1 -b .GSSAPIEnablek5users +%patch -P 922 -p1 -b .sshdt +%patch -P 926 -p1 -b .sftp-force-mode +%patch -P 939 -p1 -b .s390-dev +%patch -P 944 -p1 -b .x11max +%patch -P 948 -p1 -b .systemd +%patch -P 949 -p1 -b .refactor +%patch -P 950 -p1 -b .sandbox +%patch -P 951 -p1 -b .pkcs11-uri +%patch -P 953 -p1 -b .scp-ipv6 +%patch -P 962 -p1 -b .crypto-policies +%patch -P 963 -p1 -b .openssl-evp +%patch -P 964 -p1 -b .openssl-kdf +%patch -P 965 -p1 -b .visibility +%patch -P 966 -p1 -b .x11-ipv6 +%patch -P 974 -p1 -b .keygen-strip-doseol +%patch -P 975 -p1 -b .preserve-pam-errors + +%patch -P 977 -p1 -b .kill-scp + +%patch -P 981 -p1 -b .scp-sftpdirs +%patch -P 982 -p1 -b .minrsabits +%patch -P 984 -p1 -b .ibmca + +%patch -P 200 -p1 -b .audit +%patch -P 201 -p1 -b .audit-race +%patch -P 202 -p1 -b .audit-log +%patch -P 700 -p1 -b .fips + +%patch -P 1002 -p1 -b .ssh-manpage + +%patch -P 1006 -p1 -b .negotiate-supported-algs + +%patch -P 1012 -p1 -b .evp-fips-dh +%patch -P 1013 -p1 -b .evp-fips-ecdh +%patch -P 1014 -p1 -b .nosha1hostproof +%patch -P 1016 -p1 -b .ossl-version + +%patch -P 100 -p1 -b .coverity + +#patch for loongarch +%patch -P 1017 -p1 autoreconf -pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 +pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver} autoreconf popd @@ -209,10 +445,17 @@ popd %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="$CFLAGS -fvisibility=hidden -fpic"; export CFLAGS +CFLAGS="$CFLAGS -fvisibility=hidden"; export CFLAGS +%if %{pie} +CFLAGS="$CFLAGS -fpic" SAVE_LDFLAGS="$LDFLAGS" -LDFLAGS="$LDFLAGS -pie -z relro -z now"; export LDFLAGS +LDFLAGS="$LDFLAGS -pie -z relro -z now" + +export CFLAGS +export LDFLAGS +%endif +%if %{kerberos5} if test -r /etc/profile.d/krb5-devel.sh ; then source /etc/profile.d/krb5-devel.sh fi @@ -226,6 +469,7 @@ else CPPFLAGS="-I%{_includedir}/gssapi"; export CPPFLAGS CFLAGS="$CFLAGS -I%{_includedir}/gssapi" fi +%endif %configure \ --sysconfdir=%{_sysconfdir}/ssh \ @@ -239,105 +483,157 @@ fi --with-ssl-engine \ --with-ipaddr-display \ --with-pie=no \ - --without-hardening \ + --without-hardening `# The hardening flags are configured by system` \ --with-systemd \ --with-default-pkcs11-provider=yes \ -%if %{with libfido2} - --enable-security-key \ -%else - --disable-security-key \ -%endif --with-security-key-builtin=yes \ --with-pam \ +%if %{WITH_SELINUX} --with-selinux --with-audit=linux \ --with-sandbox=seccomp_filter \ +%endif +%if %{kerberos5} --with-kerberos5${krb5_prefix:+=${krb5_prefix}} \ -%if %{with libedit} +%else + --without-kerberos5 \ +%endif +%if %{libedit} --with-libedit %else --without-libedit %endif +%if %{static_libcrypto} +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 gtk2/gtk3 building. This is necessary +# because RPM doesn't handle nested %%if statements. +%if %{gtk3} + gtk3=yes +%else + gtk3=no +%endif + +%if ! %{no_gnome_askpass} pushd contrib -CFLAGS="$CFLAGS %{?__global_ldflags}" make gnome-ssh-askpass3 -mv gnome-ssh-askpass3 gnome-ssh-askpass +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 +fi popd +%endif -%if %{with pam} -pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 +%if %{pam_ssh_agent} +pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver} LDFLAGS="$SAVE_LDFLAGS" %configure --with-selinux \ --libexecdir=/%{_libdir}/security \ --with-mantype=man \ - --without-openssl-header-check + --without-openssl-header-check `# The check is broken` %make_build popd %endif %check +#to run tests use "--with check" %if %{?_with_check:1}%{!?_with_check:0} make tests %endif %install -mkdir -p -m755 %{buildroot}%{_sysconfdir}/ssh -mkdir -p -m755 %{buildroot}%{_sysconfdir}/ssh/ssh_config.d -mkdir -p -m755 %{buildroot}%{_sysconfdir}/ssh/sshd_config.d -mkdir -p -m755 %{buildroot}%{_libexecdir}/openssh +rm -rf $RPM_BUILD_ROOT +mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh +mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh/ssh_config.d +mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh/sshd_config.d +mkdir -p -m755 $RPM_BUILD_ROOT%{_libexecdir}/openssh %make_install -install -d %{buildroot}/etc/pam.d/ -install -d %{buildroot}/etc/sysconfig/ -install -d %{buildroot}%{_libexecdir}/openssh -install -m644 %{SOURCE2} %{buildroot}/etc/pam.d/sshd -install -m644 %{SOURCE4} %{buildroot}/etc/pam.d/ssh-keycat -install -m644 %{SOURCE5} %{buildroot}/etc/sysconfig/sshd -install -m644 ssh_config_anolis %{buildroot}/etc/ssh/ssh_config.d/50-anolis.conf -install -m644 sshd_config_anolis %{buildroot}/etc/ssh/sshd_config.d/50-anolis.conf -install -d -m755 %{buildroot}/%{_unitdir} -install -m644 %{SOURCE6} %{buildroot}/%{_unitdir}/sshd@.service -install -m644 %{SOURCE7} %{buildroot}/%{_unitdir}/sshd.socket -install -m644 %{SOURCE8} %{buildroot}/%{_unitdir}/sshd.service -install -m644 %{SOURCE9} %{buildroot}/%{_unitdir}/sshd-keygen@.service -install -m644 %{SOURCE11} %{buildroot}/%{_unitdir}/sshd-keygen.target -install -d -m755 %{buildroot}/%{_userunitdir} -install -m644 %{SOURCE12} %{buildroot}/%{_userunitdir}/ssh-agent.service -install -m644 %{SOURCE13} %{buildroot}/%{_userunitdir}/ssh-agent.socket -install -m744 %{SOURCE10} %{buildroot}/%{_libexecdir}/openssh/sshd-keygen -install -m755 contrib/ssh-copy-id %{buildroot}%{_bindir}/ -install contrib/ssh-copy-id.1 %{buildroot}%{_mandir}/man1/ +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 +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 -d -m755 $RPM_BUILD_ROOT/%{_unitdir} +install -m644 %{SOURCE9} $RPM_BUILD_ROOT/%{_unitdir}/sshd@.service +install -m644 %{SOURCE10} $RPM_BUILD_ROOT/%{_unitdir}/sshd.socket +install -m644 %{SOURCE11} $RPM_BUILD_ROOT/%{_unitdir}/sshd.service +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 +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}/%{_datadir}/empty.sshd -install -p -D -m 0644 %{SOURCE14} %{buildroot}%{_sysusersdir}/openssh-server.conf +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 + +%if ! %{no_gnome_askpass} +install contrib/gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/gnome-ssh-askpass +%endif -install -m755 contrib/gnome-ssh-askpass %{buildroot}%{_libexecdir}/openssh/gnome-ssh-askpass +%if ! %{no_gnome_askpass} +ln -s gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/ssh-askpass +install -m 755 -d $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ +install -m 755 contrib/redhat/gnome-ssh-askpass.csh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ +install -m 755 contrib/redhat/gnome-ssh-askpass.sh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ +%endif -ln -s gnome-ssh-askpass %{buildroot}%{_libexecdir}/openssh/ssh-askpass -install -m 755 -d %{buildroot}%{_sysconfdir}/profile.d/ -install -m 755 contrib/redhat/gnome-ssh-askpass.csh %{buildroot}%{_sysconfdir}/profile.d/ -install -m 755 contrib/redhat/gnome-ssh-askpass.sh %{buildroot}%{_sysconfdir}/profile.d/ +%if %{no_gnome_askpass} +rm -f $RPM_BUILD_ROOT/etc/profile.d/gnome-ssh-askpass.* +%endif -perl -pi -e "s|%{buildroot}||g" %{buildroot}%{_mandir}/man*/* +perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* -%if %{with pam} -pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 +%if %{pam_ssh_agent} +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 + %generate_compatibility_deps %pre server -%sysusers_create_compat %{SOURCE14} -# We want to remove group ownership for standard host keys if they exist -test -f /etc/ssh/ssh_host_rsa_key && /usr/bin/chmod g-r /etc/ssh/ssh_host_rsa_key || : -test -f /etc/ssh/ssh_host_ecdsa_key && /usr/bin/chmod g-r /etc/ssh/ssh_host_ecdsa_key || : -test -f /etc/ssh/ssh_host_ed25519_key && /usr/bin/chmod g-r /etc/ssh/ssh_host_ed25519_key || : +%sysusers_create_compat %{SOURCE19} %post server +if [ $1 -gt 1 ]; then + # In the case of an upgrade (never true on OSTree systems) run the migration + # script for Fedora 38 to remove group ownership for host keys. + %{_libexecdir}/openssh/ssh-host-keys-migration.sh + # Prevent the systemd unit that performs the same service (useful for + # OSTree systems) from running. + touch /var/lib/.ssh-host-keys-migration +fi %systemd_post sshd.service sshd.socket +# 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} && \ @@ -360,23 +656,24 @@ test -f %{sysconfig_anaconda} && \ %systemd_user_preun ssh-agent.socket %files -%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli +%license 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(4555,root,root) %{_libexecdir}/openssh/ssh-keysign - -%attr(0644,root,root) %{_mandir}/man1/ssh-keygen.1* %attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8* -%license LICENCE %files clients -%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config -%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config.d/50-anolis.conf -%dir %attr(0755,root,root) %{_sysconfdir}/ssh/ssh_config.d/ - %attr(0755,root,root) %{_bindir}/ssh +%attr(0644,root,root) %{_mandir}/man1/ssh.1* %attr(0755,root,root) %{_bindir}/scp +%attr(0644,root,root) %{_mandir}/man1/scp.1* +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config +%dir %attr(0755,root,root) %{_sysconfdir}/ssh/ssh_config.d/ +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config.d/50-redhat.conf +%attr(0644,root,root) %{_mandir}/man5/ssh_config.5* %attr(0755,root,root) %{_bindir}/ssh-agent %attr(0755,root,root) %{_bindir}/ssh-add %attr(0755,root,root) %{_bindir}/ssh-keyscan @@ -384,68 +681,74 @@ test -f %{sysconfig_anaconda} && \ %attr(0755,root,root) %{_bindir}/ssh-copy-id %attr(0755,root,root) %{_libexecdir}/openssh/ssh-pkcs11-helper %attr(0755,root,root) %{_libexecdir}/openssh/ssh-sk-helper -%attr(0644,root,root) %{_userunitdir}/ssh-agent.service -%attr(0644,root,root) %{_userunitdir}/ssh-agent.socket - -%attr(0644,root,root) %{_mandir}/man1/ssh.1* -%attr(0644,root,root) %{_mandir}/man1/scp.1* %attr(0644,root,root) %{_mandir}/man1/ssh-agent.1* %attr(0644,root,root) %{_mandir}/man1/ssh-add.1* %attr(0644,root,root) %{_mandir}/man1/ssh-keyscan.1* %attr(0644,root,root) %{_mandir}/man1/sftp.1* %attr(0644,root,root) %{_mandir}/man1/ssh-copy-id.1* -%attr(0644,root,root) %{_mandir}/man5/ssh_config.5* %attr(0644,root,root) %{_mandir}/man8/ssh-pkcs11-helper.8* %attr(0644,root,root) %{_mandir}/man8/ssh-sk-helper.8* +%attr(0644,root,root) %{_userunitdir}/ssh-agent.service +%attr(0644,root,root) %{_userunitdir}/ssh-agent.socket %files server -%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config -%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config.d/50-anolis.conf -%attr(0644,root,root) %config(noreplace) /etc/pam.d/sshd -%attr(0640,root,root) %config(noreplace) /etc/sysconfig/sshd -%dir %attr(0700,root,root) %{_sysconfdir}/ssh/sshd_config.d/ -%attr(0644,root,root) %{_sysusersdir}/openssh-server.conf - +%dir %attr(0711,root,root) %{_datadir}/empty.sshd %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 +%dir %attr(0700,root,root) %{_sysconfdir}/ssh/sshd_config.d/ +%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 +%attr(0644,root,root) %config(noreplace) /etc/pam.d/sshd +%attr(0640,root,root) %config(noreplace) /etc/sysconfig/sshd %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 -%dir %attr(0711,root,root) %{_datadir}/empty.sshd - -%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(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 +%ghost %attr(0644,root,root) %{_localstatedir}/lib/.ssh-host-keys-migration %files keycat -%attr(0644,root,root) %config(noreplace) /etc/pam.d/ssh-keycat -%attr(0755,root,root) %{_libexecdir}/openssh/ssh-keycat %doc HOWTO.ssh-keycat +%attr(0755,root,root) %{_libexecdir}/openssh/ssh-keycat +%attr(0644,root,root) %config(noreplace) /etc/pam.d/ssh-keycat +%if ! %{no_gnome_askpass} %files askpass %attr(0644,root,root) %{_sysconfdir}/profile.d/gnome-ssh-askpass.* %attr(0755,root,root) %{_libexecdir}/openssh/gnome-ssh-askpass %attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass +%endif -%if %{with pam} +%files doc +%doc README* +%doc CREDITS ChangeLog OVERVIEW PROTOCOL* TODO + +%files sk-dummy +%attr(0755,root,root) %{_libdir}/sshtest/sk-dummy.so +%attr(0755,root,root) %{abidir}/sk-dummy.dump + +%if %{pam_ssh_agent} %files -n pam_ssh_agent_auth -%license pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/OPENSSH_LICENSE +%license pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver}/OPENSSH_LICENSE %attr(0755,root,root) %{_libdir}/security/pam_ssh_agent_auth.so %attr(0644,root,root) %{_mandir}/man8/pam_ssh_agent_auth.8* %dir %{abidir} %attr(0644,root,rooti) %{abidir}/pam_ssh_agent_auth.dump %endif -%files doc -%doc README* -%doc CREDITS ChangeLog OVERVIEW PROTOCOL* TODO - %changelog +* Fri Mar 22 2024 mgb01105731 - 9.3p2-1 +- update to 9.3p2 + * Thu Dec 28 2023 Caspar Zhang - 9.0p1-11 - Fix CVE-2023-51385 diff --git a/pam_ssh_agent-configure-c99.patch b/pam_ssh_agent-configure-c99.patch new file mode 100644 index 0000000000000000000000000000000000000000..bc40434968e8cce4d22acfd0735039bc9b06f782 --- /dev/null +++ b/pam_ssh_agent-configure-c99.patch @@ -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: + + + +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 +-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 +-int main(){exit(0);} ++#include ++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 + #include +-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 + #include ++#include + 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 + #include ++#include + 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 +-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 +-main() { char template[]="conftest.mkstemp-test"; ++#include ++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 + #include + #include + #include + #include ++#ifdef HAVE_PTY_H ++#include ++#endif + + int + main() +@@ -1543,6 +1552,7 @@ if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include ++#include + #include + #include + #include +@@ -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 + #include + #include + #include +@@ -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 + #include +-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 + #include + #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 ], + [ 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 ], + [ 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 ], + [ extern int sys_nerr; printf("%i", sys_nerr);], + [ ac_cv_libc_defines_sys_nerr="yes" ], + [ ac_cv_libc_defines_sys_nerr="no" ] diff --git a/ssh-agent.service b/ssh-agent.service index 311f91dd758864d859fb92f470ade2dae1e8a15f..812303cb4769098af2217fe55946079aeba6e8bf 100644 --- a/ssh-agent.service +++ b/ssh-agent.service @@ -10,10 +10,10 @@ Requires=ssh-agent.socket [Service] Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket ExecStartPre=/usr/bin/rm -f $SSH_AUTH_SOCK -ExecStart=/usr/bin/ssh-agent -a $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 diff --git a/ssh-host-keys-migration.service b/ssh-host-keys-migration.service new file mode 100644 index 0000000000000000000000000000000000000000..41e2c6becfdd5072f79bddde5ba54b06eeaf4c9e --- /dev/null +++ b/ssh-host-keys-migration.service @@ -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 diff --git a/ssh-host-keys-migration.sh b/ssh-host-keys-migration.sh new file mode 100644 index 0000000000000000000000000000000000000000..083326efbb646d7b18d11c583c3504c33ee0646c --- /dev/null +++ b/ssh-host-keys-migration.sh @@ -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" diff --git a/sshd.service b/sshd.service index e8afb869854ca11c713832b710733d19f7fc65ff..0cb2a263051e27f62e80b9dcae1e2323c12f72cf 100644 --- a/sshd.service +++ b/sshd.service @@ -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 diff --git a/sshd@.service b/sshd@.service index 196c555ae54f339b718c3f65858b1caa4adf6365..be6d3b90c20a2180aca5ad32705b4a6f7b5659ba 100644 --- a/sshd@.service +++ b/sshd@.service @@ -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