From 492c50f483483540f246a37be10410d525216f1f Mon Sep 17 00:00:00 2001 From: Raven Date: Wed, 28 Feb 2024 18:36:35 +0600 Subject: [PATCH] openssh: update to 9.6p1 --- .../openssh-6.6.1p1-selinux-contexts.patch | 22 +- openssh/openssh-6.7p1-coverity.patch | 102 ---- openssh/openssh-7.2p2-x11.patch | 24 +- openssh/openssh-7.8p1-role-mls.patch | 10 +- openssh/openssh-8.7p1-minrsabits.patch | 22 +- openssh/openssh-8.7p1-recursive-scp.patch | 167 +++--- .../openssh-9.3p1-merged-openssl-evp.patch | 55 +- openssh/openssh-9.3p1-openssl-compat.patch | 40 -- ...patch => openssh-9.6p1-gssapi-keyex.patch} | 198 +++++-- ...i.patch => openssh-9.6p1-pkcs11-uri.patch} | 548 +++++++++--------- openssh/openssh.spec | 42 +- 11 files changed, 594 insertions(+), 636 deletions(-) delete mode 100644 openssh/openssh-9.3p1-openssl-compat.patch rename openssh/{openssh-9.3p1-gssapi-keyex.patch => openssh-9.6p1-gssapi-keyex.patch} (96%) rename openssh/{openssh-9.3p2-pkcs11-uri.patch => openssh-9.6p1-pkcs11-uri.patch} (88%) diff --git a/openssh/openssh-6.6.1p1-selinux-contexts.patch b/openssh/openssh-6.6.1p1-selinux-contexts.patch index fa9d591..eab724a 100644 --- a/openssh/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh/openssh-6.6.1p1-selinux-contexts.patch @@ -93,19 +93,17 @@ index 8f32464..18a2ca4 100644 #endif diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 22ea8ef..1fc963d 100644 ---- a/openbsd-compat/port-linux.c -+++ b/openbsd-compat/port-linux.c -@@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname) - strlcpy(newctx + len, newname, newlen - len); - if ((cx = index(cx + 1, ':'))) - strlcat(newctx, cx, newlen); -- debug3("%s: setting context from '%s' to '%s'", __func__, -+ debug_f("setting context from '%s' to '%s'", - oldctx, newctx); +--- a/openbsd-compat/port-linux.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/openbsd-compat/port-linux.c (date 1703108053912) +@@ -207,7 +207,7 @@ + xasprintf(&newctx, "%.*s%s%s", (int)(cx - oldctx + 1), oldctx, + newname, cx2 == NULL ? "" : cx2); + +- debug3_f("setting context from '%s' to '%s'", oldctx, newctx); ++ debug_f("setting context from '%s' to '%s'", oldctx, newctx); if (setcon(newctx) < 0) - do_log2(log_level, "%s: setcon %s from %s failed with %s", - __func__, newctx, oldctx, strerror(errno)); + do_log2_f(log_level, "setcon %s from %s failed with %s", + newctx, oldctx, strerror(errno)); diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index cb51f99..8b7cda2 100644 --- a/openbsd-compat/port-linux.h diff --git a/openssh/openssh-6.7p1-coverity.patch b/openssh/openssh-6.7p1-coverity.patch index 494f4c6..01a061b 100644 --- a/openssh/openssh-6.7p1-coverity.patch +++ b/openssh/openssh-6.7p1-coverity.patch @@ -17,17 +17,6 @@ diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c return oerrno; } /* make sure the KRB5CCNAME is set for non-standard location */ -diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c ---- openssh-8.5p1/auth-options.c.coverity 2021-03-02 11:31:47.000000000 +0100 -+++ openssh-8.5p1/auth-options.c 2021-03-24 12:03:33.782968159 +0100 -@@ -706,6 +708,7 @@ serialise_array(struct sshbuf *m, char * - return r; - } - /* success */ -+ sshbuf_free(b); - return 0; - } - 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 @@ -42,32 +31,9 @@ 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 -@@ -1209,6 +1209,7 @@ ssh_krl_from_blob(struct sshbuf *buf, st - sshkey_free(key); - sshbuf_free(copy); - sshbuf_free(sect); -+ /* coverity[leaked_storage : FALSE] */ - return r; - } - @@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); @@ -164,23 +130,6 @@ diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c return (0); error: -diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1/monitor_wrap.c.coverity 2016-12-23 16:40:26.892788689 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:40:26.900788691 +0100 -@@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, - if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || - (tmp2 = dup(pmonitor->m_recvfd)) == -1) { - error_f("cannot allocate fds for pty"); -- if (tmp1 > 0) -+ if (tmp1 >= 0) - close(tmp1); -- if (tmp2 > 0) -- close(tmp2); -+ /*DEAD CODE if (tmp2 >= 0) -+ close(tmp2);*/ - return 0; - } - close(tmp1); diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/openbsd-compat/bindresvport.c --- openssh-7.4p1/openbsd-compat/bindresvport.c.coverity 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/openbsd-compat/bindresvport.c 2016-12-23 16:40:26.901788691 +0100 @@ -234,23 +183,6 @@ diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c goto out; } free(arg2); -diff -up openssh-8.7p1/scp.c.coverity openssh-8.7p1/scp.c ---- openssh-8.7p1/scp.c.coverity 2021-08-30 16:23:35.389741329 +0200 -+++ openssh-8.7p1/scp.c 2021-08-30 16:27:04.854555296 +0200 -@@ -186,11 +186,11 @@ killchild(int signo) - { - if (do_cmd_pid > 1) { - kill(do_cmd_pid, signo ? signo : SIGTERM); -- waitpid(do_cmd_pid, NULL, 0); -+ (void) waitpid(do_cmd_pid, NULL, 0); - } - if (do_cmd_pid2 > 1) { - kill(do_cmd_pid2, signo ? signo : SIGTERM); -- waitpid(do_cmd_pid2, NULL, 0); -+ (void) waitpid(do_cmd_pid2, NULL, 0); - } - - if (signo) diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c --- openssh-7.4p1/servconf.c.coverity 2016-12-23 16:40:26.896788690 +0100 +++ openssh-7.4p1/servconf.c 2016-12-23 16:40:26.901788691 +0100 @@ -278,18 +210,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-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 -@@ -224,7 +224,7 @@ killchild(int signo) - pid = sshpid; - if (pid > 1) { - kill(pid, SIGTERM); -- waitpid(pid, NULL, 0); -+ (void) waitpid(pid, NULL, 0); - } - - _exit(1); 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 @@ -301,28 +221,6 @@ diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c return NULL; } /* validate also provider from URI */ -@@ -1220,8 +1220,8 @@ main(int ac, char **av) - sanitise_stdfd(); - - /* drop */ -- setegid(getgid()); -- setgid(getgid()); -+ (void) setegid(getgid()); -+ (void) setgid(getgid()); - - platform_disable_tracing(0); /* strict=no */ - -diff -up openssh-8.5p1/ssh.c.coverity openssh-8.5p1/ssh.c ---- openssh-8.5p1/ssh.c.coverity 2021-03-24 12:03:33.779968138 +0100 -+++ openssh-8.5p1/ssh.c 2021-03-24 12:03:33.786968187 +0100 -@@ -1746,6 +1746,7 @@ control_persist_detach(void) - close(muxserver_sock); - muxserver_sock = -1; - options.control_master = SSHCTL_MASTER_NO; -+ /* coverity[leaked_handle: FALSE]*/ - muxclient(options.control_path); - /* muxclient() doesn't return on success. */ - fatal("Failed to connect to new control master"); diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c --- openssh-7.4p1/sshd.c.coverity 2016-12-23 16:40:26.897788690 +0100 +++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100 diff --git a/openssh/openssh-7.2p2-x11.patch b/openssh/openssh-7.2p2-x11.patch index 0a19ecb..b27d7c4 100644 --- a/openssh/openssh-7.2p2-x11.patch +++ b/openssh/openssh-7.2p2-x11.patch @@ -1,21 +1,23 @@ -diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c ---- openssh-7.2p2/channels.c.x11 2016-03-09 19:04:48.000000000 +0100 -+++ openssh-7.2p2/channels.c 2016-06-03 10:42:04.775164520 +0200 -@@ -3990,21 +3990,24 @@ x11_create_display_inet(int x11_display_ +diff --git a/channels.c b/channels.c +--- a/channels.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/channels.c (date 1703026069921) +@@ -5075,11 +5075,13 @@ } - + static int -connect_local_xsocket_path(const char *pathname) +connect_local_xsocket_path(const char *pathname, int len) { int sock; struct sockaddr_un addr; - -+ if (len <= 0) -+ return -1; + ++ if (len <= 0) ++ return -1; sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock == -1) + if (sock == -1) { error("socket: %.100s", strerror(errno)); +@@ -5087,11 +5089,12 @@ + } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strlcpy(addr.sun_path, pathname, sizeof addr.sun_path); @@ -29,8 +31,8 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c - error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); return -1; } - -@@ -4012,8 +4015,18 @@ static int + +@@ -5099,8 +5102,18 @@ connect_local_xsocket(u_int dnr) { char buf[1024]; diff --git a/openssh/openssh-7.8p1-role-mls.patch b/openssh/openssh-7.8p1-role-mls.patch index 4dc460a..347766d 100644 --- a/openssh/openssh-7.8p1-role-mls.patch +++ b/openssh/openssh-7.8p1-role-mls.patch @@ -23,7 +23,7 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c if ((style = strchr(user, ':')) != NULL) *style++ = 0; -@@ -296,8 +304,15 @@ input_userauth_request(int type, u_int32 +@@ -314,8 +314,15 @@ input_userauth_request(int type, u_int32 use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; @@ -34,12 +34,12 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c + if (use_privsep) { mm_inform_authserv(service, style); +#ifdef WITH_SELINUX -+ mm_inform_authrole(role); ++ mm_inform_authrole(role); +#endif -+ } ++ } userauth_banner(ssh); - if (auth2_setup_methods_lists(authctxt) != 0) - ssh_packet_disconnect(ssh, + if ((r = kex_server_update_ext_info(ssh)) != 0) + fatal_fr(r, "kex_server_update_ext_info failed"); diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c --- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200 +++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200 diff --git a/openssh/openssh-8.7p1-minrsabits.patch b/openssh/openssh-8.7p1-minrsabits.patch index 2ed59a3..479b55d 100644 --- a/openssh/openssh-8.7p1-minrsabits.patch +++ b/openssh/openssh-8.7p1-minrsabits.patch @@ -1,23 +1,21 @@ diff --git a/readconf.c b/readconf.c -index 7f26c680..42be690b 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -320,6 +320,7 @@ static struct { +--- a/readconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/readconf.c (date 1703169891147) +@@ -326,6 +326,7 @@ { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, - { "requiredrsasize", oRequiredRSASize }, + { "requiredrsasize", oRequiredRSASize }, + { "rsaminsize", oRequiredRSASize }, /* alias */ { "enableescapecommandline", oEnableEscapeCommandline }, - - { NULL, oBadOption } + { "obscurekeystroketiming", oObscureKeystrokeTiming }, + { "channeltimeout", oChannelTimeout }, diff --git a/servconf.c b/servconf.c -index 29df0463..423772b1 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -676,6 +680,7 @@ static struct { +--- a/servconf.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/servconf.c (date 1703169891148) +@@ -691,6 +691,7 @@ { "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 }, diff --git a/openssh/openssh-8.7p1-recursive-scp.patch b/openssh/openssh-8.7p1-recursive-scp.patch index f0d9b0f..17c340e 100644 --- a/openssh/openssh-8.7p1-recursive-scp.patch +++ b/openssh/openssh-8.7p1-recursive-scp.patch @@ -1,28 +1,28 @@ -diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c ---- openssh-8.7p1/scp.c.scp-sftpdirs 2022-02-07 12:31:07.407740407 +0100 -+++ openssh-8.7p1/scp.c 2022-02-07 12:31:07.409740424 +0100 -@@ -1324,7 +1324,7 @@ source_sftp(int argc, char *src, char *t - +diff --git a/scp.c b/scp.c +--- a/scp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/scp.c (date 1703111453316) +@@ -1372,7 +1372,7 @@ + if (src_is_dir && iamrecursive) { - if (upload_dir(conn, src, abs_dst, pflag, + if (sftp_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; - } -diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c ---- openssh-8.7p1/sftp-client.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp-client.c 2022-02-07 12:47:59.117516131 +0100 -@@ -971,7 +971,7 @@ do_fsetstat(struct sftp_conn *conn, cons - + error("failed to upload directory %s to %s", src, targ); + errs = 1; + } +diff --git a/sftp-client.c b/sftp-client.c +--- a/sftp-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp-client.c (date 1703169614263) +@@ -1003,7 +1003,7 @@ + /* Implements both the realpath and expand-path operations */ static char * --do_realpath_expand(struct sftp_conn *conn, const char *path, int expand) -+do_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir) +-sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand) ++sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir) { struct sshbuf *msg; u_int expected_id, count, id; -@@ -1033,11 +1033,43 @@ do_realpath_expand(struct sftp_conn *con +@@ -1049,11 +1049,43 @@ if ((r = sshbuf_get_u32(msg, &status)) != 0 || (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0) fatal_fr(r, "parse status"); @@ -33,7 +33,7 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c - return NULL; + if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) { + memset(&a, '\0', sizeof(a)); -+ if ((r = do_mkdir(conn, path, &a, 0)) != 0) { ++ if ((r = sftp_mkdir(conn, path, &a, 0)) != 0) { + sshbuf_free(msg); + return NULL; + } @@ -71,111 +71,112 @@ diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); -@@ -1039,9 +1067,9 @@ do_realpath_expand(struct sftp_conn *con +@@ -1078,9 +1110,9 @@ } - + char * --do_realpath(struct sftp_conn *conn, const char *path) -+do_realpath(struct sftp_conn *conn, const char *path, int create_dir) +-sftp_realpath(struct sftp_conn *conn, const char *path) ++sftp_realpath(struct sftp_conn *conn, const char *path, int create_dir) { -- return do_realpath_expand(conn, path, 0); -+ return do_realpath_expand(conn, path, 0, create_dir); +- return sftp_realpath_expand(conn, path, 0); ++ return sftp_realpath_expand(conn, path, 0, create_dir); } - + int -@@ -1055,9 +1083,9 @@ do_expand_path(struct sftp_conn *conn, c +@@ -1094,9 +1126,9 @@ { - if (!can_expand_path(conn)) { + if (!sftp_can_expand_path(conn)) { debug3_f("no server support, fallback to realpath"); -- return do_realpath_expand(conn, path, 0); -+ return do_realpath_expand(conn, path, 0, 0); +- return sftp_realpath_expand(conn, path, 0); ++ return sftp_realpath_expand(conn, path, 0, 0); } -- return do_realpath_expand(conn, path, 1); -+ return do_realpath_expand(conn, path, 1, 0); +- return sftp_realpath_expand(conn, path, 1); ++ return sftp_realpath_expand(conn, path, 1, 0); } - + int -@@ -1807,7 +1835,7 @@ download_dir(struct sftp_conn *conn, con +@@ -2016,7 +2048,7 @@ char *src_canon; int ret; - -- if ((src_canon = do_realpath(conn, src)) == NULL) { -+ if ((src_canon = do_realpath(conn, src, 0)) == NULL) { - error("download \"%s\": path canonicalization failed", src); - return -1; - } -@@ -2115,12 +2143,12 @@ upload_dir_internal(struct sftp_conn *co + +- if ((src_canon = sftp_realpath(conn, src)) == NULL) { ++ if ((src_canon = sftp_realpath(conn, src, 0)) == NULL) { + error("download \"%s\": path canonicalization failed", src); + return -1; + } +@@ -2365,12 +2397,12 @@ int - upload_dir(struct sftp_conn *conn, const char *src, const char *dst, + sftp_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 inplace_flag) + int follow_link_flag, int inplace_flag, int create_dir) { char *dst_canon; int ret; - -- if ((dst_canon = do_realpath(conn, dst)) == NULL) { -+ if ((dst_canon = do_realpath(conn, dst, create_dir)) == NULL) { - error("upload \"%s\": path canonicalization failed", dst); - return -1; - } -@@ -2557,7 +2585,7 @@ crossload_dir(struct sftp_conn *from, st + +- if ((dst_canon = sftp_realpath(conn, dst)) == NULL) { ++ if ((dst_canon = sftp_realpath(conn, dst, create_dir)) == NULL) { + error("upload \"%s\": path canonicalization failed", dst); + return -1; + } +@@ -2825,7 +2857,7 @@ char *from_path_canon; int ret; - -- if ((from_path_canon = do_realpath(from, from_path)) == NULL) { -+ if ((from_path_canon = do_realpath(from, from_path, 0)) == NULL) { - error("crossload \"%s\": path canonicalization failed", - from_path); - return -1; -diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h ---- openssh-8.7p1/sftp-client.h.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp-client.h 2022-02-07 12:31:07.410740433 +0100 -@@ -111,7 +111,7 @@ int do_fsetstat(struct sftp_conn *, cons - int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); - + +- if ((from_path_canon = sftp_realpath(from, from_path)) == NULL) { ++ if ((from_path_canon = sftp_realpath(from, from_path, 0)) == NULL) { + error("crossload \"%s\": path canonicalization failed", + from_path); + return -1; +diff --git a/sftp-client.h b/sftp-client.h +--- a/sftp-client.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp-client.h (date 1703111691284) +@@ -111,7 +111,7 @@ + int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); + /* Canonicalise 'path' - caller must free result */ --char *do_realpath(struct sftp_conn *, const char *); -+char *do_realpath(struct sftp_conn *, const char *, int); - +-char *sftp_realpath(struct sftp_conn *, const char *); ++char *sftp_realpath(struct sftp_conn *, const char *, int); + /* Canonicalisation with tilde expansion (requires server extension) */ - char *do_expand_path(struct sftp_conn *, const char *); -@@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const + char *sftp_expand_path(struct sftp_conn *, const char *); +@@ -163,7 +163,7 @@ * times if 'pflag' is set */ - int upload_dir(struct sftp_conn *, const char *, const char *, + int sftp_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 -diff -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c ---- openssh-8.7p1/sftp.c.scp-sftpdirs 2021-08-20 06:03:49.000000000 +0200 -+++ openssh-8.7p1/sftp.c 2022-02-07 12:31:07.411740442 +0100 -@@ -760,7 +760,7 @@ process_put(struct sftp_conn *conn, cons - if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { - if (upload_dir(conn, g.gl_pathv[i], abs_dst, + +diff --git a/sftp.c b/sftp.c +--- a/sftp.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/sftp.c (date 1703168795365) +@@ -807,7 +807,7 @@ + (rflag || global_rflag)) { + if (sftp_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, -@@ -1577,7 +1577,7 @@ parse_dispatch_command(struct sftp_conn + if (sftp_upload(conn, g.gl_pathv[i], abs_dst, +@@ -1642,7 +1642,7 @@ if (path1 == NULL || *path1 == '\0') path1 = xstrdup(startdir); - path1 = make_absolute(path1, *pwd); -- if ((tmp = do_realpath(conn, path1)) == NULL) { -+ if ((tmp = do_realpath(conn, path1, 0)) == NULL) { + path1 = sftp_make_absolute(path1, *pwd); +- if ((tmp = sftp_realpath(conn, path1)) == NULL) { ++ if ((tmp = sftp_realpath(conn, path1, 0)) == NULL) { err = 1; break; } -@@ -2160,7 +2160,7 @@ interactive_loop(struct sftp_conn *conn, +@@ -2247,7 +2247,7 @@ } #endif /* USE_LIBEDIT */ - -- remote_path = do_realpath(conn, "."); -+ remote_path = do_realpath(conn, ".", 0); - if (remote_path == NULL) + +- if ((remote_path = sftp_realpath(conn, ".")) == NULL) ++ if ((remote_path = sftp_realpath(conn, ".", 0)) == NULL) fatal("Need cwd"); startdir = xstrdup(remote_path); + diff --git a/openssh/openssh-9.3p1-merged-openssl-evp.patch b/openssh/openssh-9.3p1-merged-openssl-evp.patch index 95d86c3..6a30485 100644 --- a/openssh/openssh-9.3p1-merged-openssl-evp.patch +++ b/openssh/openssh-9.3p1-merged-openssl-evp.patch @@ -659,15 +659,15 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x # ifdef OPENSSL_HAS_ECC # include # include -@@ -268,6 +271,10 @@ +@@ -266,6 +266,10 @@ const char *sshkey_ssh_name_plain(const struct sshkey *); - int sshkey_names_valid2(const char *, int); + int sshkey_names_valid2(const char *, int, 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 @@ @@ -695,11 +695,11 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x #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 @@ - +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +--- a/ssh-pkcs11.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/ssh-pkcs11.c (date 1703110934679) +@@ -620,8 +620,24 @@ + return (0); } + @@ -711,7 +711,7 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return 0; +} #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - + +int +is_rsa_pkcs11(RSA *rsa) +{ @@ -722,14 +722,14 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + /* remove trailing spaces. Note, that this does NOT guarantee the buffer * will be null terminated if there are no trailing spaces! */ - static void -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; + static char * +diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c +--- a/ssh-pkcs11-client.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/ssh-pkcs11-client.c (date 1703110830967) +@@ -402,8 +402,36 @@ + if (helper->nrsa == 0 && helper->nec == 0) + helper_terminate(helper); + } + +int +is_ecdsa_pkcs11(EC_KEY *ecdsa) @@ -744,8 +744,8 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + return 1; + return 0; +} - #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - + #endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ + +int +is_rsa_pkcs11(RSA *rsa) +{ @@ -762,14 +762,15 @@ diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x + /* 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 - + wrap_key(struct helper *helper, struct sshkey *k) +diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h +--- a/ssh-pkcs11.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/ssh-pkcs11.h (date 1703111023334) +@@ -38,6 +38,12 @@ + /* Only available in ssh-pkcs11-client.c so far */ + int pkcs11_make_cert(const struct sshkey *, + const struct sshkey *, struct sshkey **); ++ +#ifdef HAVE_EC_KEY_METHOD_NEW +int is_ecdsa_pkcs11(EC_KEY *ecdsa); +#endif diff --git a/openssh/openssh-9.3p1-openssl-compat.patch b/openssh/openssh-9.3p1-openssl-compat.patch deleted file mode 100644 index cf512ef..0000000 --- a/openssh/openssh-9.3p1-openssl-compat.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- 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/openssh-9.3p1-gssapi-keyex.patch b/openssh/openssh-9.6p1-gssapi-keyex.patch similarity index 96% rename from openssh/openssh-9.3p1-gssapi-keyex.patch rename to openssh/openssh-9.6p1-gssapi-keyex.patch index 68dc906..3e5ccec 100644 --- a/openssh/openssh-9.3p1-gssapi-keyex.patch +++ b/openssh/openssh-9.6p1-gssapi-keyex.patch @@ -144,8 +144,8 @@ index 9351e042..d6446c0c 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,7 +1,7 @@ - /* $OpenBSD: auth2-gss.c,v 1.33 2021/12/19 22:12:07 djm Exp $ */ - + /* $OpenBSD: auth2-gss.c,v 1.34 2023/03/31 04:22:27 djm Exp $ */ + /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. @@ -1268,7 +1268,7 @@ index ce85f043..574c7609 100644 +#endif + /* prototype */ - static int kex_choose_conf(struct ssh *); + static int kex_choose_conf(struct ssh *, uint32_t seq); static int kex_input_newkeys(int, u_int32_t, struct ssh *); @@ -115,15 +120,28 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ @@ -1488,7 +1488,7 @@ new file mode 100644 index 00000000..f6e1405e --- /dev/null +++ b/kexgssc.c -@@ -0,0 +1,600 @@ +@@ -0,0 +1,612 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1589,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; + @@ -1653,11 +1655,16 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { ++ u_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); + @@ -1944,11 +1951,16 @@ index 00000000..f6e1405e + do { + type = ssh_packet_read(ssh); + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { ++ u_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); + @@ -2094,7 +2106,7 @@ 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"); + @@ -3380,7 +3400,7 @@ index 60de6087..db5c65bc 100644 .It HashKnownHosts .It Host .It HostbasedAcceptedAlgorithms -@@ -579,6 +585,8 @@ flag), +@@ -624,6 +624,8 @@ (supported message integrity codes), .Ar kex (key exchange algorithms), @@ -3388,7 +3408,7 @@ index 60de6087..db5c65bc 100644 +(GSSAPI key exchange algorithms), .Ar key (key types), - .Ar key-cert + .Ar key-ca-sign diff --git a/ssh.c b/ssh.c index 15aee569..110cf9c1 100644 --- a/ssh.c @@ -3424,7 +3444,7 @@ index 5e8ef548..1ff999b6 100644 +# GSSAPIKeyExchange no +# GSSAPITrustDNS no # BatchMode no - # CheckHostIP yes + # CheckHostIP no # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 index 06a32d31..3f490697 100644 @@ -3903,11 +3923,69 @@ diff --git a/sshkey.c b/sshkey.c index 57995ee6..fd5b7724 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -127,6 +127,17 @@ +@@ -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 -+const struct sshkey_impl sshkey_null_impl = { ++ ++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, @@ -3915,21 +3993,21 @@ index 57995ee6..fd5b7724 100644 + /* .nid = */ 0, + /* .cert = */ 0, + /* .sigonly = */ 0, -+ /* .keybits = */ 0, -+ /* .funcs = */ NULL, ++ /* .keybits = */ 0, /* FIXME */ ++ /* .funcs = */ &sshkey_gss_funcs, +}; const struct sshkey_impl * const keyimpls[] = { &sshkey_ed25519_impl, -@@ -162,6 +179,7 @@ static const struct keytype keytypes[] = +@@ -154,6 +154,7 @@ static const struct keytype keytypes[] = { &sshkey_xmss_impl, &sshkey_xmss_cert_impl, #endif -+ &sshkey_null_impl, ++ &sshkey_gss_kex_impl, NULL }; -@@ -286,7 +304,7 @@ sshkey_alg_list(int certs_only, int plai +@@ -255,7 +256,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; @@ -3950,3 +4028,47 @@ index 71a3fddc..37a43a67 100644 KEY_UNSPEC }; +diff --git a/packet.h b/packet.h +--- a/packet.h (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/packet.h (date 1703172586447) +@@ -124,6 +124,7 @@ + int ssh_packet_send2(struct ssh *); + + int ssh_packet_read(struct ssh *); ++int ssh_packet_read_expect(struct ssh *, u_int type); + int ssh_packet_read_poll(struct ssh *); + int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); + int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); +diff --git a/packet.c b/packet.c +--- a/packet.c (revision 8241b9c0529228b4b86d88b1a6076fb9f97e4a99) ++++ b/packet.c (date 1703172586447) +@@ -1425,6 +1416,29 @@ + return type; + } + ++/* ++ * Waits until a packet has been received, verifies that its type matches ++ * that given, and gives a fatal error and exits if there is a mismatch. ++ */ ++ ++int ++ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) ++{ ++ int r; ++ u_char type; ++ ++ if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) ++ return r; ++ if (type != expected_type) { ++ if ((r = sshpkt_disconnect(ssh, ++ "Protocol error: expected packet type %d, got %d", ++ expected_type, type)) != 0) ++ return r; ++ return SSH_ERR_PROTOCOL_ERROR; ++ } ++ return 0; ++} ++ + static int + ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) + { diff --git a/openssh/openssh-9.3p2-pkcs11-uri.patch b/openssh/openssh-9.6p1-pkcs11-uri.patch similarity index 88% rename from openssh/openssh-9.3p2-pkcs11-uri.patch rename to openssh/openssh-9.6p1-pkcs11-uri.patch index ffaf98a..1e7940d 100644 --- a/openssh/openssh-9.3p2-pkcs11-uri.patch +++ b/openssh/openssh-9.6p1-pkcs11-uri.patch @@ -1,7 +1,7 @@ -diff -Naur a/configure.ac b/configure.ac ---- a/configure.ac 2023-10-20 19:13:59.336263852 +0600 -+++ b/configure.ac 2023-10-20 19:11:41.812164445 +0600 -@@ -2056,12 +2056,14 @@ +diff -up openssh-9.6p1/configure.ac.pkcs11-uri openssh-9.6p1/configure.ac +--- openssh-9.6p1/configure.ac.pkcs11-uri 2024-01-12 14:25:25.228942213 +0100 ++++ openssh-9.6p1/configure.ac 2024-01-12 14:25:25.233942336 +0100 +@@ -2066,12 +2066,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -16,7 +16,7 @@ diff -Naur a/configure.ac b/configure.ac fi ] ) -@@ -2085,6 +2087,40 @@ +@@ -2095,6 +2097,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -57,7 +57,7 @@ diff -Naur a/configure.ac b/configure.ac # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5692,6 +5728,7 @@ +@@ -5708,6 +5744,7 @@ echo " BSD Auth support echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -65,10 +65,10 @@ diff -Naur a/configure.ac b/configure.ac echo " U2F/FIDO support: $enable_sk" echo "" -diff -Naur a/Makefile.in b/Makefile.in ---- a/Makefile.in 2023-10-20 19:13:59.290264154 +0600 -+++ b/Makefile.in 2023-10-20 19:11:41.813164439 +0600 -@@ -105,7 +105,7 @@ +diff -up openssh-9.6p1/Makefile.in.pkcs11-uri openssh-9.6p1/Makefile.in +--- openssh-9.6p1/Makefile.in.pkcs11-uri 2024-01-12 14:25:25.204941622 +0100 ++++ openssh-9.6p1/Makefile.in 2024-01-12 14:25:25.233942336 +0100 +@@ -105,7 +105,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ ssh-ed25519-sk.o ssh-rsa.o dh.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ @@ -77,7 +77,7 @@ diff -Naur a/Makefile.in b/Makefile.in poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ ssh-ed25519.o digest-openssl.o digest-libc.o \ hmac.o ed25519.o hash.o \ -@@ -299,6 +299,8 @@ +@@ -299,6 +299,8 @@ clean: regressclean rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8$(EXEEXT) @@ -86,7 +86,7 @@ diff -Naur a/Makefile.in b/Makefile.in rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -336,6 +338,8 @@ +@@ -336,6 +338,8 @@ distclean: regressclean rm -f regress/unittests/sshsig/test_sshsig rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 @@ -95,7 +95,7 @@ diff -Naur a/Makefile.in b/Makefile.in rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -513,6 +517,7 @@ +@@ -513,6 +517,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshkey $(MKDIR_P) `pwd`/regress/unittests/sshsig $(MKDIR_P) `pwd`/regress/unittests/utf8 @@ -103,7 +103,7 @@ diff -Naur a/Makefile.in b/Makefile.in $(MKDIR_P) `pwd`/regress/misc/sk-dummy [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -685,6 +690,17 @@ +@@ -685,6 +690,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS) @@ -116,37 +116,24 @@ diff -Naur a/Makefile.in b/Makefile.in + $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lcrypto $(LIBS) -+ + # These all need to be compiled -fPIC, so they are treated differently. SK_DUMMY_OBJS=\ regress/misc/sk-dummy/sk-dummy.lo \ -@@ -720,7 +736,8 @@ +@@ -720,7 +735,8 @@ regress-unit-binaries: regress-prep $(RE regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ regress/unittests/sshkey/test_sshkey$(EXEEXT) \ regress/unittests/sshsig/test_sshsig$(EXEEXT) \ - regress/unittests/utf8/test_utf8$(EXEEXT) + regress/unittests/utf8/test_utf8$(EXEEXT) \ -+ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) ++ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - tests: file-tests t-exec interop-tests unit + tests: file-tests t-exec interop-tests extra-tests unit echo all tests passed -diff -Naur a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh ---- a/regress/agent-pkcs11.sh 2023-07-19 12:31:34.000000000 +0600 -+++ b/regress/agent-pkcs11.sh 2023-10-20 19:11:41.813164439 +0600 -@@ -113,7 +113,7 @@ - done - - trace "remove pkcs11 keys" -- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 -+ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -e failed: exit code $r" -diff -Naur a/regress/Makefile b/regress/Makefile ---- a/regress/Makefile 2023-07-19 12:31:34.000000000 +0600 -+++ b/regress/Makefile 2023-10-20 19:11:41.813164439 +0600 -@@ -127,7 +127,8 @@ +diff -up openssh-9.6p1/regress/Makefile.pkcs11-uri openssh-9.6p1/regress/Makefile +--- openssh-9.6p1/regress/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/regress/Makefile 2024-01-12 14:25:25.233942336 +0100 +@@ -134,7 +134,8 @@ CLEANFILES= *.core actual agent-key.* au known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ pidfile putty.rsa2 ready regress.log remote_pid \ @@ -156,7 +143,7 @@ diff -Naur a/regress/Makefile b/regress/Makefile rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ -@@ -258,8 +259,9 @@ +@@ -273,8 +274,9 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ @@ -168,9 +155,9 @@ diff -Naur a/regress/Makefile b/regress/Makefile -d ${.CURDIR}/unittests/sshkey/testdata ; \ $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ -d ${.CURDIR}/unittests/sshsig/testdata ; \ -diff -Naur a/regress/pkcs11.sh b/regress/pkcs11.sh ---- a/regress/pkcs11.sh 1970-01-01 06:00:00.000000000 +0600 -+++ b/regress/pkcs11.sh 2023-10-20 19:11:41.813164439 +0600 +diff -up openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri openssh-9.6p1/regress/pkcs11.sh +--- openssh-9.6p1/regress/pkcs11.sh.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 ++++ openssh-9.6p1/regress/pkcs11.sh 2024-01-12 14:25:25.233942336 +0100 @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -521,21 +508,20 @@ diff -Naur a/regress/pkcs11.sh b/regress/pkcs11.sh + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -\ В конце файла нет новой строки -diff -Naur a/regress/unittests/Makefile b/regress/unittests/Makefile ---- a/regress/unittests/Makefile 2023-07-19 12:31:34.000000000 +0600 -+++ b/regress/unittests/Makefile 2023-10-20 19:11:41.813164439 +0600 -@@ -2,6 +2,6 @@ +diff -up openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri openssh-9.6p1/regress/unittests/Makefile +--- openssh-9.6p1/regress/unittests/Makefile.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/regress/unittests/Makefile 2024-01-12 14:25:25.233942336 +0100 +@@ -1,6 +1,6 @@ + # $OpenBSD: Makefile,v 1.13 2023/09/24 08:14:13 claudio Exp $ - REGRESS_FAIL_EARLY?= yes SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion -SUBDIR+=authopt misc sshsig +SUBDIR+=authopt misc sshsig pkcs11 .include -diff -Naur a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c ---- a/regress/unittests/pkcs11/tests.c 1970-01-01 06:00:00.000000000 +0600 -+++ b/regress/unittests/pkcs11/tests.c 2023-10-20 19:11:41.814164432 +0600 +diff -up openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-9.6p1/regress/unittests/pkcs11/tests.c +--- openssh-9.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2024-01-12 14:25:25.233942336 +0100 ++++ openssh-9.6p1/regress/unittests/pkcs11/tests.c 2024-01-12 14:25:25.233942336 +0100 @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2017 Red Hat @@ -883,10 +869,9 @@ diff -Naur a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c + test_parse_invalid(); + test_generate_valid(); +} -\ В конце файла нет новой строки -diff -Naur a/ssh-add.c b/ssh-add.c ---- a/ssh-add.c 2023-07-19 12:31:34.000000000 +0600 -+++ b/ssh-add.c 2023-10-20 19:11:41.814164432 +0600 +diff -up openssh-9.6p1/ssh-add.c.pkcs11-uri openssh-9.6p1/ssh-add.c +--- openssh-9.6p1/ssh-add.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-add.c 2024-01-12 14:25:25.233942336 +0100 @@ -69,6 +69,7 @@ #include "ssh-sk.h" #include "sk-api.h" @@ -895,12 +880,16 @@ diff -Naur a/ssh-add.c b/ssh-add.c /* argv0 */ extern char *__progname; -@@ -230,6 +231,34 @@ +@@ -240,6 +241,38 @@ delete_all(int agent_fd, int qflag) return ret; } +#ifdef ENABLE_PKCS11 -+static int update_card(int, int, const char *, int, struct dest_constraint **, size_t, char *); ++static int ++update_card(int agent_fd, int add, const char *id, int qflag, ++ int key_only, int cert_only, ++ struct dest_constraint **dest_constraints, size_t ndest_constraints, ++ struct sshkey **certs, size_t ncerts, char *pin); + +int +update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag, @@ -922,32 +911,35 @@ diff -Naur a/ssh-add.c b/ssh-add.c + } + pkcs11_uri_cleanup(uri); + -+ return update_card(agent_fd, adding, pkcs11_uri, qflag, -+ dest_constraints, ndest_constraints, pin); ++ return update_card(agent_fd, adding, pkcs11_uri, qflag, 1, 0, ++ dest_constraints, ndest_constraints, NULL, 0, pin); +} +#endif + static int - add_file(int agent_fd, const char *filename, int key_only, int qflag, - const char *skprovider, struct dest_constraint **dest_constraints, -@@ -445,12 +474,11 @@ - - static int + add_file(int agent_fd, const char *filename, int key_only, int cert_only, + int qflag, const char *skprovider, +@@ -460,15 +489,14 @@ static int update_card(int agent_fd, int add, const char *id, int qflag, -- struct dest_constraint **dest_constraints, size_t ndest_constraints) -+ struct dest_constraint **dest_constraints, size_t ndest_constraints, char *pin) + int key_only, int cert_only, + struct dest_constraint **dest_constraints, size_t ndest_constraints, +- struct sshkey **certs, size_t ncerts) ++ struct sshkey **certs, size_t ncerts, char *pin) { - char *pin = NULL; int r, ret = -1; + if (key_only) + ncerts = 0; + - if (add) { + if (add && pin == NULL) { if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -637,6 +665,14 @@ - const char *skprovider, struct dest_constraint **dest_constraints, - size_t ndest_constraints) +@@ -656,6 +684,14 @@ do_file(int agent_fd, int deleting, int + char *file, int qflag, const char *skprovider, + struct dest_constraint **dest_constraints, size_t ndest_constraints) { +#ifdef ENABLE_PKCS11 + if (strlen(file) >= strlen(PKCS11_URI_SCHEME) && @@ -958,21 +950,21 @@ diff -Naur a/ssh-add.c b/ssh-add.c + } +#endif if (deleting) { - if (delete_file(agent_fd, file, key_only, qflag) == -1) - return -1; -@@ -963,7 +999,7 @@ - } - if (pkcs11provider != NULL) { + if (delete_file(agent_fd, file, key_only, + cert_only, qflag) == -1) +@@ -999,7 +1035,7 @@ main(int argc, char **argv) if (update_card(agent_fd, !deleting, pkcs11provider, -- qflag, dest_constraints, ndest_constraints) == -1) -+ qflag, dest_constraints, ndest_constraints, NULL) == -1) + qflag, key_only, cert_only, + dest_constraints, ndest_constraints, +- certs, ncerts) == -1) ++ certs, ncerts, NULL) == -1) ret = 1; goto done; } -diff -Naur a/ssh-agent.c b/ssh-agent.c ---- a/ssh-agent.c 2023-07-19 12:31:34.000000000 +0600 -+++ b/ssh-agent.c 2023-10-20 19:11:41.814164432 +0600 -@@ -1379,10 +1379,72 @@ +diff -up openssh-9.6p1/ssh-agent.c.pkcs11-uri openssh-9.6p1/ssh-agent.c +--- openssh-9.6p1/ssh-agent.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-agent.c 2024-01-12 14:25:25.234942360 +0100 +@@ -1549,10 +1549,72 @@ add_p11_identity(struct sshkey *key, cha } #ifdef ENABLE_PKCS11 @@ -1046,49 +1038,54 @@ diff -Naur a/ssh-agent.c b/ssh-agent.c char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; u_int seconds = 0; -@@ -1408,33 +1470,28 @@ +@@ -1581,25 +1643,18 @@ process_add_smartcard_key(SocketEntry *e "providers is disabled", provider); goto send; } - if (realpath(provider, canonical_provider) == NULL) { - verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", - provider, strerror(errno)); -- goto send; -- } -- if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { -- verbose("refusing PKCS#11 add of \"%.100s\": " -- "provider not allowed", canonical_provider); + sane_uri = sanitize_pkcs11_provider(provider); + if (sane_uri == NULL) goto send; - } +- if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { +- verbose("refusing PKCS#11 add of \"%.100s\": " +- "provider not allowed", canonical_provider); +- goto send; +- } - debug_f("add %.100s", canonical_provider); -+ if (lifetime && !death) death = monotime() + lifetime; - count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments); -+ + debug_f("add %.100s", sane_uri); + count = pkcs11_add_provider(sane_uri, pin, &keys, &comments); for (i = 0; i < count; i++) { - k = keys[i]; - if (lookup_identity(k) == NULL) { - id = xcalloc(1, sizeof(Identity)); - id->key = k; - keys[i] = NULL; /* transferred */ -- id->provider = xstrdup(canonical_provider); -+ id->provider = xstrdup(sane_uri); - if (*comments[i] != '\0') { - id->comment = comments[i]; - comments[i] = NULL; /* transferred */ - } else { -- id->comment = xstrdup(canonical_provider); -+ id->comment = xstrdup(sane_uri); - } - id->death = death; - id->confirm = confirm; -@@ -1453,6 +1510,7 @@ + if (comments[i] == NULL || comments[i][0] == '\0') { + free(comments[i]); +- comments[i] = xstrdup(canonical_provider); ++ comments[i] = xstrdup(sane_uri); + } + for (j = 0; j < ncerts; j++) { + if (!sshkey_is_cert(certs[j])) +@@ -1609,13 +1664,13 @@ process_add_smartcard_key(SocketEntry *e + if (pkcs11_make_cert(keys[i], certs[j], &k) != 0) + continue; + add_p11_identity(k, xstrdup(comments[i]), +- canonical_provider, death, confirm, ++ sane_uri, death, confirm, + dest_constraints, ndest_constraints); + success = 1; + } + if (!cert_only && lookup_identity(keys[i]) == NULL) { + add_p11_identity(keys[i], comments[i], +- canonical_provider, death, confirm, ++ sane_uri, death, confirm, + dest_constraints, ndest_constraints); + keys[i] = NULL; /* transferred */ + comments[i] = NULL; /* transferred */ +@@ -1628,6 +1683,7 @@ process_add_smartcard_key(SocketEntry *e send: free(pin); free(provider); @@ -1096,7 +1093,7 @@ diff -Naur a/ssh-agent.c b/ssh-agent.c free(keys); free(comments); free_dest_constraints(dest_constraints, ndest_constraints); -@@ -1462,7 +1520,7 @@ +@@ -1640,7 +1696,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1105,7 +1102,7 @@ diff -Naur a/ssh-agent.c b/ssh-agent.c int r, success = 0; Identity *id, *nxt; -@@ -1474,30 +1532,28 @@ +@@ -1652,30 +1708,29 @@ process_remove_smartcard_key(SocketEntry } free(pin); @@ -1123,9 +1120,8 @@ diff -Naur a/ssh-agent.c b/ssh-agent.c nxt = TAILQ_NEXT(id, next); /* Skip file--based keys */ if (id->provider == NULL) -- continue; + continue; - if (!strcmp(canonical_provider, id->provider)) { -+ + if (!strcmp(sane_uri, id->provider)) { TAILQ_REMOVE(&idtab->idlist, id, next); free_identity(id); @@ -1138,15 +1134,40 @@ diff -Naur a/ssh-agent.c b/ssh-agent.c else error_f("pkcs11_del_provider failed"); send: -- free(provider); + free(provider); + free(sane_uri); send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff -Naur a/ssh.c b/ssh.c ---- a/ssh.c 2023-10-20 19:13:59.298264101 +0600 -+++ b/ssh.c 2023-10-20 19:11:41.815164426 +0600 -@@ -840,6 +840,14 @@ +diff -up openssh-9.6p1/ssh_config.5.pkcs11-uri openssh-9.6p1/ssh_config.5 +--- openssh-9.6p1/ssh_config.5.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 ++++ openssh-9.6p1/ssh_config.5 2024-01-12 14:25:25.234942360 +0100 +@@ -1216,6 +1216,21 @@ may also be used in conjunction with + .Cm CertificateFile + in order to provide any certificate also needed for authentication with + the identity. ++.Pp ++The authentication identity can be also specified in a form of PKCS#11 URI ++starting with a string ++.Cm pkcs11: . ++There is supported a subset of the PKCS#11 URI as defined ++in RFC 7512 (implemented path arguments ++.Cm id , ++.Cm manufacturer , ++.Cm object , ++.Cm token ++and query arguments ++.Cm module-path ++and ++.Cm pin-value ++). The URI can not be in quotes. + .It Cm IgnoreUnknown + Specifies a pattern-list of unknown options to be ignored if they are + encountered in configuration parsing. +diff -up openssh-9.6p1/ssh.c.pkcs11-uri openssh-9.6p1/ssh.c +--- openssh-9.6p1/ssh.c.pkcs11-uri 2024-01-12 14:25:25.208941721 +0100 ++++ openssh-9.6p1/ssh.c 2024-01-12 14:25:25.234942360 +0100 +@@ -882,6 +882,14 @@ main(int ac, char **av) options.gss_deleg_creds = 1; break; case 'i': @@ -1161,7 +1182,7 @@ diff -Naur a/ssh.c b/ssh.c p = tilde_expand_filename(optarg, getuid()); if (stat(p, &st) == -1) fprintf(stderr, "Warning: Identity file %s " -@@ -1712,6 +1720,7 @@ +@@ -1784,6 +1792,7 @@ main(int ac, char **av) #ifdef ENABLE_PKCS11 (void)pkcs11_del_provider(options.pkcs11_provider); #endif @@ -1169,7 +1190,7 @@ diff -Naur a/ssh.c b/ssh.c skip_connect: exit_status = ssh_session2(ssh, cinfo); -@@ -2228,6 +2237,45 @@ +@@ -2307,6 +2316,45 @@ ssh_session2(struct ssh *ssh, const stru options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -1215,7 +1236,7 @@ diff -Naur a/ssh.c b/ssh.c /* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(const struct ssh_conn_info *cinfo) -@@ -2242,11 +2290,6 @@ +@@ -2321,11 +2369,6 @@ load_public_identity_files(const struct char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; @@ -1227,7 +1248,7 @@ diff -Naur a/ssh.c b/ssh.c n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); -@@ -2259,33 +2302,46 @@ +@@ -2338,33 +2381,46 @@ load_public_identity_files(const struct sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 @@ -1293,35 +1314,10 @@ diff -Naur a/ssh.c b/ssh.c filename = default_client_percent_dollar_expand(cp, cinfo); free(cp); check_load(sshkey_load_public(filename, &public, NULL), -diff -Naur a/ssh_config.5 b/ssh_config.5 ---- a/ssh_config.5 2023-10-20 19:13:59.299264095 +0600 -+++ b/ssh_config.5 2023-10-20 19:11:41.815164426 +0600 -@@ -1124,6 +1124,21 @@ - .Cm CertificateFile - in order to provide any certificate also needed for authentication with - the identity. -+.Pp -+The authentication identity can be also specified in a form of PKCS#11 URI -+starting with a string -+.Cm pkcs11: . -+There is supported a subset of the PKCS#11 URI as defined -+in RFC 7512 (implemented path arguments -+.Cm id , -+.Cm manufacturer , -+.Cm object , -+.Cm token -+and query arguments -+.Cm module-path -+and -+.Cm pin-value -+). The URI can not be in quotes. - .It Cm IgnoreUnknown - Specifies a pattern-list of unknown options to be ignored if they are - encountered in configuration parsing. -diff -Naur a/ssh-keygen.c b/ssh-keygen.c ---- a/ssh-keygen.c 2023-07-19 12:31:34.000000000 +0600 -+++ b/ssh-keygen.c 2023-10-20 19:11:41.816164419 +0600 -@@ -866,8 +866,11 @@ +diff -up openssh-9.6p1/ssh-keygen.c.pkcs11-uri openssh-9.6p1/ssh-keygen.c +--- openssh-9.6p1/ssh-keygen.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-keygen.c 2024-01-12 14:25:25.234942360 +0100 +@@ -862,8 +862,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1335,10 +1331,30 @@ diff -Naur a/ssh-keygen.c b/ssh-keygen.c } free(comments[i]); sshkey_free(keys[i]); -diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c ---- a/ssh-pkcs11.c 2023-07-19 12:31:34.000000000 +0600 -+++ b/ssh-pkcs11.c 2023-10-20 19:15:23.755711022 +0600 -@@ -55,8 +55,8 @@ +diff -up openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-client.c +--- openssh-9.6p1/ssh-pkcs11-client.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11-client.c 2024-01-12 14:25:25.234942360 +0100 +@@ -592,6 +592,8 @@ pkcs11_add_provider(char *name, char *pi + struct sshbuf *msg; + struct helper *helper; + ++ debug_f("called, name = %s", name); ++ + if ((helper = helper_by_provider(name)) == NULL && + (helper = pkcs11_start_helper(name)) == NULL) + return -1; +@@ -612,6 +614,7 @@ pkcs11_add_provider(char *name, char *pi + *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); + if (labelsp) + *labelsp = xcalloc(nkeys, sizeof(char *)); ++ debug_f("nkeys = %u", nkeys); + for (i = 0; i < nkeys; i++) { + /* XXX clean up properly instead of fatal() */ + if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || +diff -up openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11.c +--- openssh-9.6p1/ssh-pkcs11.c.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11.c 2024-01-12 14:28:09.170975480 +0100 +@@ -55,8 +55,8 @@ struct pkcs11_slotinfo { int logged_in; }; @@ -1349,7 +1365,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c void *handle; CK_FUNCTION_LIST *function_list; CK_INFO info; -@@ -65,6 +65,13 @@ +@@ -65,6 +65,13 @@ struct pkcs11_provider { struct pkcs11_slotinfo *slotinfo; int valid; int refcount; @@ -1363,7 +1379,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c TAILQ_ENTRY(pkcs11_provider) next; }; -@@ -75,6 +82,7 @@ +@@ -75,6 +82,7 @@ struct pkcs11_key { CK_ULONG slotidx; char *keyid; int keyid_len; @@ -1371,7 +1387,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c }; int pkcs11_interactive = 0; -@@ -106,26 +114,61 @@ +@@ -106,26 +114,61 @@ pkcs11_init(int interactive) * this is called when a provider gets unregistered. */ static void @@ -1400,9 +1416,6 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c - if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) + if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) error("C_Finalize failed: %lu", rv); -- p->valid = 0; -- p->function_list = NULL; -- dlclose(p->handle); + m->valid = 0; + m->function_list = NULL; + dlclose(m->handle); @@ -1441,11 +1454,13 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c + return; + pkcs11_module_unref(p->module); + p->module = NULL; -+ p->valid = 0; + p->valid = 0; +- p->function_list = NULL; +- dlclose(p->handle); } /* -@@ -137,12 +180,10 @@ +@@ -137,11 +180,9 @@ pkcs11_provider_unref(struct pkcs11_prov { debug_f("provider \"%s\" refcount %d", p->name, p->refcount); if (--p->refcount <= 0) { @@ -1454,13 +1469,12 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c free(p->name); - free(p->slotlist); - free(p->slotinfo); - free(p); + if (p->module) + pkcs11_module_unref(p->module); + free(p); } } - -@@ -159,6 +200,20 @@ +@@ -159,6 +200,20 @@ pkcs11_terminate(void) } } @@ -1481,7 +1495,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c /* lookup provider by name */ static struct pkcs11_provider * pkcs11_provider_lookup(char *provider_id) -@@ -173,19 +228,55 @@ +@@ -173,19 +228,55 @@ pkcs11_provider_lookup(char *provider_id return (NULL); } @@ -1491,7 +1505,6 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c int pkcs11_del_provider(char *provider_id) { -- struct pkcs11_provider *p; + int rv; + struct pkcs11_uri *uri; + @@ -1521,7 +1534,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c +int +pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) +{ -+ struct pkcs11_provider *p; + struct pkcs11_provider *p; + int rv = -1; + char *provider_uri = pkcs11_uri_get(uri); + @@ -1541,7 +1554,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c } static RSA_METHOD *rsa_method; -@@ -195,6 +286,56 @@ +@@ -195,6 +286,56 @@ static EC_KEY_METHOD *ec_key_method; static int ec_key_idx = 0; #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ @@ -1598,7 +1611,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c /* release a wrapped object */ static void pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, -@@ -208,6 +349,7 @@ +@@ -208,6 +349,7 @@ pkcs11_k11_free(void *parent, void *ptr, if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); @@ -1606,7 +1619,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c free(k11); } -@@ -222,8 +364,8 @@ +@@ -222,8 +364,8 @@ pkcs11_find(struct pkcs11_provider *p, C CK_RV rv; int ret = -1; @@ -1617,7 +1630,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); -@@ -260,14 +402,14 @@ +@@ -260,14 +402,14 @@ pkcs11_login_slot(struct pkcs11_provider if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH) verbose("Deferring PIN entry to reader keypad."); else { @@ -1635,7 +1648,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c (pin != NULL) ? strlen(pin) : 0); if (pin != NULL) freezero(pin, strlen(pin)); -@@ -297,13 +439,14 @@ +@@ -297,13 +439,14 @@ pkcs11_login_slot(struct pkcs11_provider static int pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) { @@ -1652,7 +1665,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c } -@@ -319,13 +462,14 @@ +@@ -319,13 +462,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs *val = 0; @@ -1670,7 +1683,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c attr.type = type; attr.pValue = &flag; -@@ -356,13 +500,14 @@ +@@ -356,13 +500,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C int always_auth = 0; int did_login = 0; @@ -1688,7 +1701,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -439,8 +584,8 @@ +@@ -439,8 +584,8 @@ pkcs11_rsa_private_encrypt(int flen, con return (-1); } @@ -1699,7 +1712,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c tlen = RSA_size(rsa); /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -484,7 +629,7 @@ +@@ -484,7 +629,7 @@ pkcs11_rsa_start_wrapper(void) /* redirect private key operations for rsa key to pkcs11 token */ static int pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1708,7 +1721,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c { struct pkcs11_key *k11; -@@ -502,6 +647,12 @@ +@@ -502,6 +647,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -1721,7 +1734,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c RSA_set_method(rsa, rsa_method); RSA_set_ex_data(rsa, rsa_idx, k11); return (0); -@@ -532,8 +683,8 @@ +@@ -532,8 +683,8 @@ ecdsa_do_sign(const unsigned char *dgst, return (NULL); } @@ -1732,7 +1745,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c siglen = ECDSA_size(ec); sig = xmalloc(siglen); -@@ -598,7 +749,7 @@ +@@ -598,7 +749,7 @@ pkcs11_ecdsa_start_wrapper(void) static int pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1741,7 +1754,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c { struct pkcs11_key *k11; -@@ -615,6 +766,11 @@ +@@ -615,6 +766,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -1750,31 +1763,21 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c + memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); + k11->label[label_attrib->ulValueLen] = 0; + } ++ EC_KEY_set_method(ec, ec_key_method); EC_KEY_set_ex_data(ec, ec_key_idx, k11); -@@ -622,7 +778,8 @@ +@@ -622,7 +779,8 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider } #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ -/* remove trailing spaces */ +/* remove trailing spaces. Note, that this does NOT guarantee the buffer + * will be null terminated if there are no trailing spaces! */ - static void + static char * rmspace(u_char *buf, size_t len) { -@@ -630,8 +787,8 @@ - - if (!len) - return; -- for (i = len - 1; i > 0; i--) -- if (i == len - 1 || buf[i] == ' ') -+ for (i = len - 1; i > 0; i--) -+ if (buf[i] == ' ') - buf[i] = '\0'; - else - break; -@@ -651,8 +808,8 @@ +@@ -654,8 +812,8 @@ pkcs11_open_session(struct pkcs11_provid CK_SESSION_HANDLE session; int login_required, ret; @@ -1785,7 +1788,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c login_required = si->token.flags & CKF_LOGIN_REQUIRED; -@@ -662,9 +819,9 @@ +@@ -665,9 +823,9 @@ pkcs11_open_session(struct pkcs11_provid error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -1797,7 +1800,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c return (-1); } if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -700,7 +857,8 @@ +@@ -703,7 +861,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -1807,7 +1810,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -714,14 +872,15 @@ +@@ -717,14 +876,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -1828,7 +1831,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -732,19 +891,19 @@ +@@ -735,19 +895,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -1852,7 +1855,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -756,8 +915,8 @@ +@@ -759,8 +919,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1863,7 +1866,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (group == NULL) { ossl_error("d2i_ECPKParameters failed"); goto fail; -@@ -768,13 +927,13 @@ +@@ -771,13 +931,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1880,7 +1883,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (octet == NULL) { ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; -@@ -791,7 +950,7 @@ +@@ -794,7 +954,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -1889,7 +1892,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -807,7 +966,7 @@ +@@ -810,7 +970,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ ec = NULL; /* now owned by key */ fail: @@ -1898,7 +1901,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c free(key_attr[i].pValue); if (ec) EC_KEY_free(ec); -@@ -824,7 +983,8 @@ +@@ -827,7 +987,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -1908,7 +1911,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -835,14 +995,15 @@ +@@ -838,14 +999,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -1929,7 +1932,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -853,19 +1014,19 @@ +@@ -856,19 +1018,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ @@ -1953,7 +1956,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -877,8 +1038,8 @@ +@@ -880,8 +1042,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr goto fail; } @@ -1964,7 +1967,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (rsa_n == NULL || rsa_e == NULL) { error("BN_bin2bn failed"); goto fail; -@@ -887,7 +1048,7 @@ +@@ -890,7 +1052,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ @@ -1973,7 +1976,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -902,7 +1063,7 @@ +@@ -905,7 +1067,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr rsa = NULL; /* now owned by key */ fail: @@ -1982,7 +1985,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c free(key_attr[i].pValue); RSA_free(rsa); -@@ -913,7 +1074,8 @@ +@@ -916,7 +1078,8 @@ static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) { @@ -1992,7 +1995,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -937,14 +1099,15 @@ +@@ -940,14 +1103,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -2013,7 +2016,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return -1; -@@ -956,18 +1119,19 @@ +@@ -959,18 +1123,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2036,7 +2039,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto out; -@@ -981,8 +1145,8 @@ +@@ -984,8 +1149,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p subject = xstrdup("invalid subject"); X509_NAME_free(x509_name); @@ -2047,7 +2050,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c error("d2i_x509 failed"); goto out; } -@@ -1002,7 +1166,7 @@ +@@ -1005,7 +1170,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2056,7 +2059,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1032,7 +1196,7 @@ +@@ -1035,7 +1200,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2065,7 +2068,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1052,7 +1216,7 @@ +@@ -1055,7 +1220,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } out: @@ -2074,7 +2077,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c free(cert_attr[i].pValue); X509_free(x509); RSA_free(rsa); -@@ -1103,11 +1267,12 @@ +@@ -1106,11 +1271,12 @@ note_key(struct pkcs11_provider *p, CK_U */ static int pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2089,13 +2092,12 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1124,10 +1289,24 @@ +@@ -1127,10 +1293,23 @@ pkcs11_fetch_certs(struct pkcs11_provide key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); - session = p->slotinfo[slotidx].session; - f = p->function_list; -+ + if (uri->id != NULL) { + key_attr[nattr].type = CKA_ID; + key_attr[nattr].pValue = uri->id; @@ -2117,7 +2119,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1208,11 +1387,12 @@ +@@ -1211,11 +1390,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2132,7 +2134,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1228,10 +1408,23 @@ +@@ -1231,10 +1411,23 @@ pkcs11_fetch_keys(struct pkcs11_provider key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2159,7 +2161,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1500,16 +1693,10 @@ +@@ -1503,16 +1696,10 @@ pkcs11_ecdsa_generate_private_key(struct } #endif /* WITH_PKCS11_KEYGEN */ @@ -2178,7 +2180,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1518,162 +1705,304 @@ +@@ -1521,162 +1708,309 @@ pkcs11_register_provider(char *provider_ CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2186,29 +2188,35 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c + struct pkcs11_module *m = NULL; - if (providerp == NULL) +- goto fail; +- *providerp = NULL; +- +- if (keyp != NULL) +- *keyp = NULL; +- if (labelsp != NULL) +- *labelsp = NULL; + /* if no provider specified, fallback to p11-kit */ + if (uri->module_path == NULL) { +#ifdef PKCS11_DEFAULT_PROVIDER + provider_module = strdup(PKCS11_DEFAULT_PROVIDER); +#else + error_f("No module path provided"); - goto fail; -- *providerp = NULL; ++ goto fail; +#endif + } else { + provider_module = strdup(uri->module_path); + } - -- if (keyp != NULL) -- *keyp = NULL; -- if (labelsp != NULL) -- *labelsp = NULL; -+ + p = xcalloc(1, sizeof(*p)); + p->name = pkcs11_uri_get(uri); - if (pkcs11_provider_lookup(provider_id) != NULL) { - debug_f("provider already registered: %s", provider_id); ++ if (lib_contains_symbol(provider_module, "C_GetFunctionList") != 0) { ++ error("provider %s is not a PKCS11 library", provider_module); + goto fail; + } +- if (lib_contains_symbol(provider_id, "C_GetFunctionList") != 0) { +- error("provider %s is not a PKCS11 library", provider_id); - goto fail; + if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL + && m->valid) { @@ -2227,6 +2235,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c + p->module = m; + m->refcount++; } ++ /* open shared pkcs11-library */ - if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { - error("dlopen %s failed: %s", provider_id, dlerror()); @@ -2239,7 +2248,6 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c - p = xcalloc(1, sizeof(*p)); - p->name = xstrdup(provider_id); - p->handle = handle; -+ + p->module->handle = handle; /* setup the pkcs11 callbacks */ if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { @@ -2264,15 +2272,13 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c + provider_module, rv); goto fail; } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); -- debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" -- " libraryDescription <%s> libraryVersion %d.%d", +- debug("provider %s: manufacturerID <%.*s> cryptokiVersion %d.%d" +- " libraryDescription <%.*s> libraryVersion %d.%d", - provider_id, -- p->info.manufacturerID, +- RMSPACE(p->info.manufacturerID), - p->info.cryptokiVersion.major, - p->info.cryptokiVersion.minor, -- p->info.libraryDescription, +- RMSPACE(p->info.libraryDescription), - p->info.libraryVersion.major, - p->info.libraryVersion.minor); - if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { @@ -2316,12 +2322,12 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c goto fail; } - p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); p->valid = 1; - nkeys = 0; - for (i = 0; i < p->nslots; i++) { - token = &p->slotinfo[i].token; - if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) -+ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); + m->valid = 1; + for (i = 0; i < m->nslots; i++) { + token = &m->slotinfo[i].token; @@ -2338,23 +2344,25 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c + token->flags = 0; continue; } - rmspace(token->label, sizeof(token->label)); - rmspace(token->manufacturerID, sizeof(token->manufacturerID)); - rmspace(token->model, sizeof(token->model)); - rmspace(token->serialNumber, sizeof(token->serialNumber)); -- debug("provider %s slot %lu: label <%s> manufacturerID <%s> " -- "model <%s> serial <%s> flags 0x%lx", + debug("provider %s slot %lu: label <%.*s> " + "manufacturerID <%.*s> model <%.*s> serial <%.*s> " + "flags 0x%lx", - provider_id, (unsigned long)i, ++ provider_module, (unsigned long)i, + RMSPACE(token->label), RMSPACE(token->manufacturerID), + RMSPACE(token->model), RMSPACE(token->serialNumber), + token->flags); + } + m->module_path = provider_module; + provider_module = NULL; + -+ /* insert unconditionally -- remove if there will be no keys later */ ++ /* now owned by caller */ ++ *providerp = p; ++ + TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); + p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; + ++ return 0; +fail: + if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize for provider %s failed: %lu", @@ -2370,7 +2378,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c + } + if (handle) + dlclose(handle); -+ return ret; ++ return (ret); +} + +/* @@ -2436,12 +2444,12 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c + debug("provider %s slot %lu: label <%.32s> manufacturerID <%.32s> " + "model <%.16s> serial <%.16s> flags 0x%lx", + provider_uri, (unsigned long)i, - token->label, token->manufacturerID, token->model, - token->serialNumber, token->flags); ++ token->label, token->manufacturerID, token->model, ++ token->serialNumber, token->flags); /* - * open session, login with pin and retrieve public - * keys (if keyp is provided) -+ * open session if not yet openend, login with pin and ++ * open session if not yet opened, login with pin and + * retrieve public keys (if keyp is provided) */ - if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || @@ -2490,8 +2498,8 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c - TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); - p->refcount++; /* add to provider list */ +- + free(provider_uri); - return (nkeys); fail: - if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) @@ -2502,8 +2510,8 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c - free(p->slotlist); - free(p->slotinfo); - free(p); -+ TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); ++ pkcs11_provider_unref(p); } - if (handle) - dlclose(handle); @@ -2561,7 +2569,7 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { -@@ -1682,7 +2011,37 @@ +@@ -1685,7 +2019,37 @@ pkcs11_add_provider(char *provider_id, c pkcs11_provider_unref(p); } if (nkeys == 0) @@ -2600,29 +2608,9 @@ diff -Naur a/ssh-pkcs11.c b/ssh-pkcs11.c return (nkeys); } -diff -Naur a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c ---- a/ssh-pkcs11-client.c 2023-07-19 12:31:34.000000000 +0600 -+++ b/ssh-pkcs11-client.c 2023-10-20 19:11:41.817164413 +0600 -@@ -323,6 +323,8 @@ - u_int nkeys, i; - struct sshbuf *msg; - -+ debug_f("called, name = %s", name); -+ - if (fd < 0 && pkcs11_start_helper() < 0) - return (-1); - -@@ -342,6 +344,7 @@ - *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); - if (labelsp) - *labelsp = xcalloc(nkeys, sizeof(char *)); -+ debug_f("nkeys = %u", nkeys); - for (i = 0; i < nkeys; i++) { - /* XXX clean up properly instead of fatal() */ - if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff -Naur a/ssh-pkcs11.h b/ssh-pkcs11.h ---- a/ssh-pkcs11.h 2023-07-19 12:31:34.000000000 +0600 -+++ b/ssh-pkcs11.h 2023-10-20 19:11:41.817164413 +0600 +diff -up openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11.h +--- openssh-9.6p1/ssh-pkcs11.h.pkcs11-uri 2023-12-18 15:59:50.000000000 +0100 ++++ openssh-9.6p1/ssh-pkcs11.h 2024-01-12 14:25:25.235942385 +0100 @@ -22,10 +22,14 @@ #define SSH_PKCS11_ERR_PIN_REQUIRED 4 #define SSH_PKCS11_ERR_PIN_LOCKED 5 @@ -2638,9 +2626,9 @@ diff -Naur a/ssh-pkcs11.h b/ssh-pkcs11.h #ifdef WITH_PKCS11_KEYGEN struct sshkey * pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, -diff -Naur a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c ---- a/ssh-pkcs11-uri.c 1970-01-01 06:00:00.000000000 +0600 -+++ b/ssh-pkcs11-uri.c 2023-10-20 19:11:41.817164413 +0600 +diff -up openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.c +--- openssh-9.6p1/ssh-pkcs11-uri.c.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 ++++ openssh-9.6p1/ssh-pkcs11-uri.c 2024-01-12 14:25:25.235942385 +0100 @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2017 Red Hat @@ -3079,11 +3067,10 @@ diff -Naur a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c +} + +#endif /* ENABLE_PKCS11 */ -\ В конце файла нет новой строки -diff -Naur a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h ---- a/ssh-pkcs11-uri.h 1970-01-01 06:00:00.000000000 +0600 -+++ b/ssh-pkcs11-uri.h 2023-10-20 19:11:41.818164406 +0600 -@@ -0,0 +1,42 @@ +diff -up openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-9.6p1/ssh-pkcs11-uri.h +--- openssh-9.6p1/ssh-pkcs11-uri.h.pkcs11-uri 2024-01-12 14:25:25.235942385 +0100 ++++ openssh-9.6p1/ssh-pkcs11-uri.h 2024-01-12 14:25:25.235942385 +0100 +@@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -3126,3 +3113,4 @@ diff -Naur a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h +int pkcs11_uri_parse(const char *, struct pkcs11_uri *); +struct pkcs11_uri *pkcs11_uri_init(); +char *pkcs11_uri_get(struct pkcs11_uri *uri); ++ diff --git a/openssh/openssh.spec b/openssh/openssh.spec index bb98d1d..351ee5a 100644 --- a/openssh/openssh.spec +++ b/openssh/openssh.spec @@ -56,10 +56,10 @@ %{?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 openssh_rel 2 +%global openssh_ver 9.6p1 +%global openssh_rel 1 %global pam_ssh_agent_ver 0.10.4 -%global pam_ssh_agent_rel 11 +%global pam_ssh_agent_rel 12 Summary: An open source implementation of SSH protocol version 2 Name: openssh @@ -164,7 +164,7 @@ Patch711: openssh-7.8p1-UsePAM-warning.patch # Reenable MONITOR_REQ_GSSCHECKMIC after gssapi-with-mic failures # upstream MR: # https://github.com/openssh-gsskex/openssh-gsskex/pull/21 -Patch800: openssh-9.3p1-gssapi-keyex.patch +Patch800: openssh-9.6p1-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) @@ -204,7 +204,7 @@ 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-9.3p2-pkcs11-uri.patch +Patch951: openssh-9.6p1-pkcs11-uri.patch # Unbreak scp between two IPv6 hosts (#1620333) Patch953: openssh-7.8p1-scp-ipv6.patch # Mention crypto-policies in manual pages (#1668325) @@ -252,9 +252,6 @@ 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 - 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 @@ -279,12 +276,12 @@ BuildRequires: systemd-rpm-macros %else BuildRequires: perl %endif -%if 0%{?fedora} || 0%{?rhel} >= 7 +%if 0%{?fedora} || 0%{?rhel} != 7 BuildRequires: gcc %else BuildRequires: devtoolset-8-gcc devtoolset-8-build %if 0%{?rhel} < 7 -BuildRequires: autoconf2.69 automake1.16 m4_next +BuildRequires: autoconf2.69 automake1.16 m4 %endif %endif BuildRequires: make @@ -430,12 +427,12 @@ popd %patch703 -p1 -b .grab-info %patch707 -p1 -b .redhat %patch711 -p1 -b .log-usepam-no -# +# %patch800 -p1 -b .gsskex %patch801 -p1 -b .force_krb %patch804 -p1 -b .ccache_name %patch805 -p1 -b .k5login -# +# %patch901 -p1 -b .kuserok %patch906 -p1 -b .fromto-remote %patch916 -p1 -b .contexts @@ -479,16 +476,10 @@ popd %patch1012 -p1 -b .evp-fips-dh %patch1013 -p1 -b .evp-fips-ecdh %patch1014 -p1 -b .nosha1hostproof -%patch1016 -p1 -b .ossl-version + %patch100 -p1 -b .coverity -%if 0%{?rhel} < 7 -. /etc/profile.d/modules.sh -module load autoconf -module load automake -module load m4 -%endif autoreconf pushd pam_ssh_agent_auth-pam_ssh_agent_auth-%{pam_ssh_agent_ver} @@ -496,18 +487,14 @@ autoreconf popd %build -%if 0%{?rhel} < 8 +%if 0%{?rhel} == 7 %enable_devtoolset8 %endif -%if 0%{?rhel} < 7 -. /etc/profile.d/modules.sh -module load autoconf -module load automake -module load m4 -%endif + %set_build_flags # the -fvisibility=hidden is needed for clean build of the pam_ssh_agent_auth # it is needed for lib(open)ssh build too since it is linked to the pam module too + CFLAGS="$CFLAGS -I%{_includedir}/openssl3 -fvisibility=hidden"; export CFLAGS %if %{pie} %ifarch s390 s390x sparc sparcv9 sparc64 @@ -869,6 +856,9 @@ fi %endif %changelog +* Wed Feb 28 2024 Raven - 9.6p2-1 +- New upstream release + * Fri Oct 20 2023 Raven - 9.3p2-1 - add pam config ported from proper rhel versions