From 9dff9c0419407a37c6eea821b1bd5ef8dcf92096 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 6 May 2021 14:51:30 +0200 Subject: [PATCH] Rebase from openssh 8.5p1 to 8.6p1 Resolves: rhbz#1952957 --- .gitignore | 2 + openssh-4.3p2-askpass-grab-info.patch | 29 +- openssh-5.1p1-askpass-progress.patch | 2 +- openssh-6.6.1p1-log-in-chroot.patch | 100 +- openssh-7.6p1-audit.patch | 334 ++- openssh-7.7p1-fips.patch | 183 +- openssh-7.7p1-gssapi-new-unique.patch | 242 +- openssh-7.8p1-UsePAM-warning.patch | 22 +- openssh-8.0p1-crypto-policies.patch | 58 +- openssh-8.0p1-keygen-strip-doseol.patch | 12 + openssh-8.0p1-pkcs11-uri.patch | 3174 +++++++++++------------ openssh-8.0p1-preserve-pam-errors.patch | 44 + openssh.spec | 19 +- sources | 4 +- 14 files changed, 2106 insertions(+), 2119 deletions(-) create mode 100644 openssh-8.0p1-keygen-strip-doseol.patch create mode 100644 openssh-8.0p1-preserve-pam-errors.patch diff --git a/.gitignore b/.gitignore index 508d80d..a250550 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ pam_ssh_agent_auth-0.9.2.tar.bz2 /openssh-8.5p1.tar.gz /openssh-8.5p1.tar.gz.asc /gpgkey-736060BA.gpg +/openssh-8.6p1.tar.gz +/openssh-8.6p1.tar.gz.asc diff --git a/openssh-4.3p2-askpass-grab-info.patch b/openssh-4.3p2-askpass-grab-info.patch index e9a0b0d..120ed1b 100644 --- a/openssh-4.3p2-askpass-grab-info.patch +++ b/openssh-4.3p2-askpass-grab-info.patch @@ -1,19 +1,18 @@ -diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-7.4p1/contrib/gnome-ssh-askpass2.c ---- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info 2016-12-23 13:31:22.645213115 +0100 -+++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c 2016-12-23 13:31:40.997216691 +0100 -@@ -65,9 +65,12 @@ report_failed_grab (GtkWidget *parent_wi +diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/contrib/gnome-ssh-askpass2.c +--- openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info 2021-04-19 13:57:11.720113536 +0200 ++++ openssh-8.6p1/contrib/gnome-ssh-askpass2.c 2021-04-19 13:59:29.842163204 +0200 +@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_wi + err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, -- "Could not grab %s. " -- "A malicious client may be eavesdropping " -- "on your session.", what); -+ "SSH password dialog could not grab the %s input.\n" -+ "This might be caused by application such as screensaver, " -+ "however it could also mean that someone may be eavesdropping " -+ "on your session.\n" -+ "Either close the application which grabs the %s or " -+ "log out and log in again to prevent this from happening.", what, what); + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, +- "Could not grab %s. A malicious client may be eavesdropping " +- "on your session.", what); ++ "SSH password dialog could not grab the %s input.\n" ++ "This might be caused by application such as screensaver, " ++ "however it could also mean that someone may be eavesdropping " ++ "on your session.\n" ++ "Either close the application which grabs the %s or " ++ "log out and log in again to prevent this from happening.", what, what); gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); gtk_dialog_run(GTK_DIALOG(err)); diff --git a/openssh-5.1p1-askpass-progress.patch b/openssh-5.1p1-askpass-progress.patch index e0ecb80..ff609da 100644 --- a/openssh-5.1p1-askpass-progress.patch +++ b/openssh-5.1p1-askpass-progress.patch @@ -60,7 +60,7 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr if (prompt_type == PROMPT_ENTRY) { @@ -130,6 +145,22 @@ passphrase_dialog(char *message) g_signal_connect(G_OBJECT(entry), "key_press_event", - G_CALLBACK(check_none), dialog); + G_CALLBACK(check_none), dialog); } + + hbox = gtk_hbox_new(FALSE, 0); diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 664e11a..bf3293f 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c ---- openssh-7.4p1/log.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/log.c 2016-12-23 15:14:33.330168088 +0100 -@@ -250,6 +250,11 @@ debug3(const char *fmt,...) +diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c +--- openssh-8.6p1/log.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/log.c 2021-05-06 11:32:25.179006811 +0200 +@@ -194,6 +194,11 @@ void log_init(const char *av0, LogLevel level, SyslogFacility facility, int on_stderr) { @@ -13,7 +13,7 @@ diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif -@@ -273,8 +278,10 @@ log_init(char *av0, LogLevel level, Sysl +@@ -206,8 +211,10 @@ log_init(const char *av0, LogLevel level exit(1); } @@ -26,21 +26,21 @@ diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c log_on_stderr = on_stderr; if (on_stderr) -diff -up openssh-7.4p1/log.h.log-in-chroot openssh-7.4p1/log.h ---- openssh-7.4p1/log.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/log.h 2016-12-23 15:14:33.330168088 +0100 -@@ -49,6 +49,7 @@ typedef enum { - const char *, void *); +diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h +--- openssh-8.6p1/log.h.log-in-chroot 2021-05-06 11:32:25.179006811 +0200 ++++ openssh-8.6p1/log.h 2021-05-06 11:34:22.349925757 +0200 +@@ -52,6 +52,7 @@ typedef enum { + typedef void (log_handler_fn)(LogLevel, int, const char *, void *); void log_init(const char *, LogLevel, SyslogFacility, int); +void log_init_handler(const char *, LogLevel, SyslogFacility, int, int); LogLevel log_level_get(void); int log_change_level(LogLevel); int log_is_on_stderr(void); -diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.log-in-chroot 2016-12-23 15:14:33.311168085 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 15:16:42.154193100 +0100 -@@ -307,6 +307,8 @@ monitor_child_preauth(Authctxt *_authctx +diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c +--- openssh-8.6p1/monitor.c.log-in-chroot 2021-05-06 11:32:25.153006607 +0200 ++++ openssh-8.6p1/monitor.c 2021-05-06 11:33:37.671575348 +0200 +@@ -297,6 +297,8 @@ monitor_child_preauth(struct ssh *ssh, s close(pmonitor->m_log_sendfd); pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; @@ -49,7 +49,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c authctxt = (Authctxt *)ssh->authctxt; memset(authctxt, 0, sizeof(*authctxt)); ssh->authctxt = authctxt; -@@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p +@@ -408,6 +410,8 @@ monitor_child_postauth(struct ssh *ssh, close(pmonitor->m_recvfd); pmonitor->m_recvfd = -1; @@ -58,16 +58,16 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c monitor_set_child_handler(pmonitor->m_pid); ssh_signal(SIGHUP, &monitor_child_handler); ssh_signal(SIGTERM, &monitor_child_handler); -@@ -472,7 +476,7 @@ monitor_read_log(struct monitor *pmonito +@@ -480,7 +484,7 @@ monitor_read_log(struct monitor *pmonito /* Log it */ if (log_level_name(level) == NULL) fatal_f("invalid log level %u (corrupted message?)", level); -- sshlog(file, func, line, 0, level, NULL, "%s [preauth]", msg); -+ sshlog(file, func, line, 0, level, NULL, "%s [%s]", msg, pmonitor->m_state); +- sshlogdirect(level, forced, "%s [preauth]", msg); ++ sshlogdirect(level, forced, "%s [%s]", msg, pmonitor->m_state); sshbuf_free(logmsg); - free(file); -@@ -1719,13 +1723,28 @@ monitor_init(void) + free(msg); +@@ -1868,13 +1872,28 @@ monitor_init(void) mon = xcalloc(1, sizeof(*mon)); monitor_openfds(mon, 1); @@ -98,10 +98,10 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c } #ifdef GSSAPI -diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h ---- openssh-7.4p1/monitor.h.log-in-chroot 2016-12-23 15:14:33.330168088 +0100 -+++ openssh-7.4p1/monitor.h 2016-12-23 15:16:28.372190424 +0100 -@@ -83,10 +83,11 @@ struct monitor { +diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h +--- openssh-8.6p1/monitor.h.log-in-chroot 2021-05-06 11:32:25.153006607 +0200 ++++ openssh-8.6p1/monitor.h 2021-05-06 11:32:25.180006819 +0200 +@@ -80,10 +80,11 @@ struct monitor { int m_log_sendfd; struct kex **m_pkex; pid_t m_pid; @@ -114,9 +114,9 @@ diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h struct Authctxt; void monitor_child_preauth(struct ssh *, struct monitor *); -diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.log-in-chroot 2016-12-23 15:14:33.319168086 +0100 -+++ openssh-7.4p1/session.c 2016-12-23 15:18:18.742211853 +0100 +diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.log-in-chroot 2021-05-06 11:32:25.166006709 +0200 ++++ openssh-8.6p1/session.c 2021-05-06 11:32:25.181006827 +0200 @@ -160,6 +160,7 @@ login_cap_t *lc; static int is_child = 0; @@ -125,7 +125,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c /* File containing userauth info, if ExposeAuthInfo set */ static char *auth_info_file = NULL; -@@ -619,6 +620,7 @@ do_exec(Session *s, const char *command) +@@ -661,6 +662,7 @@ do_exec(struct ssh *ssh, Session *s, con int ret; const char *forced = NULL, *tty = NULL; char session_type[1024]; @@ -133,7 +133,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c if (options.adm_forced_command) { original_command = command; -@@ -676,6 +678,10 @@ do_exec(Session *s, const char *command) +@@ -720,6 +722,10 @@ do_exec(struct ssh *ssh, Session *s, con tty += 5; } @@ -144,7 +144,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", -@@ -1486,14 +1492,6 @@ child_close_fds(void) +@@ -1524,14 +1530,6 @@ child_close_fds(struct ssh *ssh) /* Stop directing logs to a high-numbered fd before we close it */ log_redirect_stderr_to(NULL); @@ -159,7 +159,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c } /* -@@ -1629,8 +1627,6 @@ do_child(Session *s, const char *command +@@ -1665,8 +1663,6 @@ do_child(struct ssh *ssh, Session *s, co exit(1); } @@ -168,7 +168,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c do_rc_files(ssh, s, shell); /* restore SIGPIPE for child */ -@@ -1653,9 +1649,17 @@ do_child(Session *s, const char *command +@@ -1691,9 +1687,17 @@ do_child(struct ssh *ssh, Session *s, co argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -187,9 +187,9 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c fflush(NULL); /* Get the last component of the shell name. */ -diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h ---- openssh-7.4p1/sftp.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sftp.h 2016-12-23 15:14:33.331168088 +0100 +diff -up openssh-8.6p1/sftp.h.log-in-chroot openssh-8.6p1/sftp.h +--- openssh-8.6p1/sftp.h.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp.h 2021-05-06 11:32:25.181006827 +0200 @@ -97,5 +97,5 @@ struct passwd; @@ -197,10 +197,10 @@ diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h -int sftp_server_main(int, char **, struct passwd *); +int sftp_server_main(int, char **, struct passwd *, int); void sftp_server_cleanup_exit(int) __attribute__((noreturn)); -diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c ---- openssh-7.4p1/sftp-server.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sftp-server.c 2016-12-23 15:14:33.331168088 +0100 -@@ -1497,7 +1497,7 @@ sftp_server_usage(void) +diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c +--- openssh-8.6p1/sftp-server.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp-server.c 2021-05-06 11:32:25.181006827 +0200 +@@ -1644,7 +1644,7 @@ sftp_server_usage(void) } int @@ -209,7 +209,7 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c { fd_set *rset, *wset; int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; -@@ -1511,7 +1511,7 @@ sftp_server_main(int argc, char **argv, +@@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv, extern char *__progname; __progname = ssh_get_progname(argv[0]); @@ -218,7 +218,7 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c pw = pwcopy(user_pw); -@@ -1582,7 +1582,7 @@ sftp_server_main(int argc, char **argv, +@@ -1730,7 +1730,7 @@ sftp_server_main(int argc, char **argv, } } @@ -227,20 +227,20 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c /* * On platforms where we can, avoid making /proc/self/{mem,maps} -diff -up openssh-7.4p1/sftp-server-main.c.log-in-chroot openssh-7.4p1/sftp-server-main.c ---- openssh-7.4p1/sftp-server-main.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sftp-server-main.c 2016-12-23 15:14:33.331168088 +0100 -@@ -49,5 +49,5 @@ main(int argc, char **argv) +diff -up openssh-8.6p1/sftp-server-main.c.log-in-chroot openssh-8.6p1/sftp-server-main.c +--- openssh-8.6p1/sftp-server-main.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp-server-main.c 2021-05-06 11:32:25.181006827 +0200 +@@ -50,5 +50,5 @@ main(int argc, char **argv) return 1; } - return (sftp_server_main(argc, argv, user_pw)); + return (sftp_server_main(argc, argv, user_pw, 0)); } -diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.log-in-chroot 2016-12-23 15:14:33.328168088 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 15:14:33.332168088 +0100 -@@ -650,7 +650,7 @@ privsep_postauth(Authctxt *authctxt) +diff -up openssh-8.6p1/sshd.c.log-in-chroot openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.log-in-chroot 2021-05-06 11:32:25.177006795 +0200 ++++ openssh-8.6p1/sshd.c 2021-05-06 11:32:25.182006834 +0200 +@@ -559,7 +559,7 @@ privsep_postauth(struct ssh *ssh, Authct } /* New socket pair */ @@ -249,7 +249,7 @@ diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) -@@ -668,6 +668,11 @@ privsep_postauth(Authctxt *authctxt) +@@ -578,6 +578,11 @@ privsep_postauth(struct ssh *ssh, Authct close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 85d0650..f37ac2b 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1,7 +1,7 @@ -diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c ---- openssh/audit-bsm.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit-bsm.c 2019-04-03 17:02:20.713886041 +0200 -@@ -372,13 +372,26 @@ audit_connection_from(const char *host, +diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c +--- openssh-8.6p1/audit-bsm.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit-bsm.c 2021-05-06 12:05:27.376464524 +0200 +@@ -373,13 +373,26 @@ audit_connection_from(const char *host, #endif } @@ -29,7 +29,7 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c audit_session_open(struct logininfo *li) { /* not implemented */ -@@ -390,6 +403,12 @@ audit_session_close(struct logininfo *li +@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li /* not implemented */ } @@ -42,7 +42,7 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c void audit_event(struct ssh *ssh, ssh_audit_event_t event) { -@@ -451,4 +470,28 @@ audit_event(struct ssh *ssh, ssh_audit_e +@@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_e debug("%s: unhandled event %d", __func__, event); } } @@ -71,9 +71,9 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh/audit.c.audit openssh/audit.c ---- openssh/audit.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit.c 2019-04-03 17:02:20.713886041 +0200 +diff -up openssh-8.6p1/audit.c.audit openssh-8.6p1/audit.c +--- openssh-8.6p1/audit.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit.c 2021-05-06 12:05:27.376464524 +0200 @@ -34,6 +34,12 @@ #include "log.h" #include "hostfile.h" @@ -251,9 +251,9 @@ diff -up openssh/audit.c.audit openssh/audit.c } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/audit.h.audit openssh/audit.h ---- openssh/audit.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit.h 2019-04-03 17:02:20.713886041 +0200 +diff -up openssh-8.6p1/audit.h.audit openssh-8.6p1/audit.h +--- openssh-8.6p1/audit.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit.h 2021-05-06 12:05:27.376464524 +0200 @@ -26,6 +26,7 @@ # define _SSH_AUDIT_H @@ -296,9 +296,9 @@ diff -up openssh/audit.h.audit openssh/audit.h +void audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); #endif /* _SSH_AUDIT_H */ -diff -up openssh/audit-linux.c.audit openssh/audit-linux.c ---- openssh/audit-linux.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit-linux.c 2019-04-03 17:02:20.713886041 +0200 +diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c +--- openssh-8.6p1/audit-linux.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit-linux.c 2021-05-06 12:05:27.377464532 +0200 @@ -33,27 +33,40 @@ #include "log.h" @@ -669,9 +669,9 @@ diff -up openssh/audit-linux.c.audit openssh/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh/auditstub.c.audit openssh/auditstub.c ---- openssh/auditstub.c.audit 2019-04-03 17:02:20.714886050 +0200 -+++ openssh/auditstub.c 2019-04-03 17:02:20.714886050 +0200 +diff -up openssh-8.6p1/auditstub.c.audit openssh-8.6p1/auditstub.c +--- openssh-8.6p1/auditstub.c.audit 2021-05-06 12:05:27.377464532 +0200 ++++ openssh-8.6p1/auditstub.c 2021-05-06 12:05:27.377464532 +0200 @@ -0,0 +1,52 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -725,10 +725,10 @@ diff -up openssh/auditstub.c.audit openssh/auditstub.c +audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh/auth2.c.audit openssh/auth2.c ---- openssh/auth2.c.audit 2019-04-03 17:02:20.651885453 +0200 -+++ openssh/auth2.c 2019-04-03 17:02:20.714886050 +0200 -@@ -303,9 +303,6 @@ input_userauth_request(int type, u_int32 +diff -up openssh-8.6p1/auth2.c.audit openssh-8.6p1/auth2.c +--- openssh-8.6p1/auth2.c.audit 2021-05-06 12:05:27.305463975 +0200 ++++ openssh-8.6p1/auth2.c 2021-05-06 12:05:27.377464532 +0200 +@@ -298,9 +298,6 @@ input_userauth_request(int type, u_int32 } else { /* Invalid user, fake password information */ authctxt->pw = fakepw(); @@ -738,9 +738,9 @@ diff -up openssh/auth2.c.audit openssh/auth2.c } #ifdef USE_PAM if (options.use_pam) -diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c ---- openssh/auth2-hostbased.c.audit 2019-04-03 17:02:20.612885083 +0200 -+++ openssh/auth2-hostbased.c 2019-04-03 17:02:20.714886050 +0200 +diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c +--- openssh-8.6p1/auth2-hostbased.c.audit 2021-05-06 12:05:27.283463805 +0200 ++++ openssh-8.6p1/auth2-hostbased.c 2021-05-06 12:05:27.377464532 +0200 @@ -158,7 +158,7 @@ userauth_hostbased(struct ssh *ssh) authenticated = 0; if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser, @@ -771,10 +771,10 @@ diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, -diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.audit 2019-04-03 17:02:20.691885832 +0200 -+++ openssh/auth2-pubkey.c 2019-04-03 17:02:20.714886050 +0200 -@@ -219,7 +219,7 @@ userauth_pubkey(struct ssh *ssh) +diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c +--- openssh-8.6p1/auth2-pubkey.c.audit 2021-05-06 12:05:27.344464277 +0200 ++++ openssh-8.6p1/auth2-pubkey.c 2021-05-06 12:05:27.378464540 +0200 +@@ -213,7 +213,7 @@ userauth_pubkey(struct ssh *ssh) /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) && @@ -783,7 +783,7 @@ diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, ssh->compat, &sig_details)) == 0) { -@@ -278,6 +278,20 @@ done: +@@ -305,6 +305,20 @@ done: return authenticated; } @@ -804,10 +804,10 @@ diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c static int match_principals_option(const char *principal_list, struct sshkey_cert *cert) { -diff -up openssh/auth.c.audit openssh/auth.c ---- openssh/auth.c.audit 2019-04-03 17:02:20.691885832 +0200 -+++ openssh/auth.c 2019-04-03 17:02:20.714886050 +0200 -@@ -366,7 +366,7 @@ auth_log(struct ssh *ssh, int authentica +diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c +--- openssh-8.6p1/auth.c.audit 2021-05-06 12:05:27.304463967 +0200 ++++ openssh-8.6p1/auth.c 2021-05-06 12:05:27.378464540 +0200 +@@ -367,7 +367,7 @@ auth_log(struct ssh *ssh, int authentica # endif #endif #ifdef SSH_AUDIT_EVENTS @@ -816,7 +816,7 @@ diff -up openssh/auth.c.audit openssh/auth.c audit_event(ssh, audit_classify_auth(method)); #endif } -@@ -592,9 +592,6 @@ getpwnamallow(struct ssh *ssh, const cha +@@ -597,9 +597,6 @@ getpwnamallow(struct ssh *ssh, const cha record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif @@ -826,10 +826,10 @@ diff -up openssh/auth.c.audit openssh/auth.c return (NULL); } if (!allowed_user(ssh, pw)) -diff -up openssh/auth.h.audit openssh/auth.h ---- openssh/auth.h.audit 2019-04-03 17:02:20.692885842 +0200 -+++ openssh/auth.h 2019-04-03 17:02:20.714886050 +0200 -@@ -195,6 +195,8 @@ struct passwd * getpwnamallow(struct ssh +diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h +--- openssh-8.6p1/auth.h.audit 2021-05-06 12:05:27.318464076 +0200 ++++ openssh-8.6p1/auth.h 2021-05-06 12:05:27.378464540 +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 *); @@ -838,7 +838,7 @@ diff -up openssh/auth.h.audit openssh/auth.h FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -214,6 +216,8 @@ struct sshkey *get_hostkey_private_by_ty +@@ -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 *, u_char **, size_t *, const u_char *, size_t, const char *); @@ -847,10 +847,10 @@ diff -up openssh/auth.h.audit openssh/auth.h /* Key / cert options linkage to auth layer */ const struct sshauthopt *auth_options(struct ssh *); -diff -up openssh/cipher.c.audit openssh/cipher.c ---- openssh/cipher.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/cipher.c 2019-04-03 17:02:20.714886050 +0200 -@@ -61,25 +61,6 @@ struct sshcipher_ctx { +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-05-06 12:05:27.378464540 +0200 +@@ -64,25 +64,6 @@ struct sshcipher_ctx { const struct sshcipher *cipher; }; @@ -876,7 +876,7 @@ diff -up openssh/cipher.c.audit openssh/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES -@@ -410,7 +391,7 @@ cipher_get_length(struct sshcipher_ctx * +@@ -422,7 +403,7 @@ cipher_get_length(struct sshcipher_ctx * void cipher_free(struct sshcipher_ctx *cc) { @@ -885,10 +885,10 @@ diff -up openssh/cipher.c.audit openssh/cipher.c return; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { chachapoly_free(cc->cp_ctx); -diff -up openssh/cipher.h.audit openssh/cipher.h ---- openssh/cipher.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/cipher.h 2019-04-03 17:02:20.714886050 +0200 -@@ -45,7 +45,25 @@ +diff -up openssh-8.6p1/cipher.h.audit openssh-8.6p1/cipher.h +--- openssh-8.6p1/cipher.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/cipher.h 2021-05-06 12:05:27.378464540 +0200 +@@ -47,7 +47,25 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -915,10 +915,10 @@ diff -up openssh/cipher.h.audit openssh/cipher.h struct sshcipher_ctx; const struct sshcipher *cipher_by_name(const char *); -diff -up openssh/kex.c.audit openssh/kex.c ---- openssh/kex.c.audit 2019-04-03 17:02:20.652885462 +0200 -+++ openssh/kex.c 2019-04-03 17:02:20.715886060 +0200 -@@ -60,6 +60,7 @@ +diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c +--- openssh-8.6p1/kex.c.audit 2021-05-06 12:05:27.368464462 +0200 ++++ openssh-8.6p1/kex.c 2021-05-06 12:05:27.379464547 +0200 +@@ -65,6 +65,7 @@ #include "ssherr.h" #include "sshbuf.h" #include "digest.h" @@ -926,7 +926,7 @@ diff -up openssh/kex.c.audit openssh/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -758,12 +759,16 @@ kex_start_rekex(struct ssh *ssh) +@@ -816,12 +817,16 @@ kex_start_rekex(struct ssh *ssh) } static int @@ -945,7 +945,7 @@ diff -up openssh/kex.c.audit openssh/kex.c if ((enc->cipher = cipher_by_name(name)) == NULL) { error_f("unsupported cipher %s", name); free(name); -@@ -783,8 +788,12 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -842,8 +847,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -959,7 +959,7 @@ diff -up openssh/kex.c.audit openssh/kex.c if (mac_setup(mac, name) < 0) { error_f("unsupported MAC %s", name); free(name); -@@ -796,12 +805,16 @@ choose_mac(struct ssh *ssh, struct sshma +@@ -856,12 +865,16 @@ choose_mac(struct ssh *ssh, struct sshma } static int @@ -978,7 +978,7 @@ diff -up openssh/kex.c.audit openssh/kex.c #ifdef WITH_ZLIB if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; -@@ -933,7 +946,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1002,7 +1015,7 @@ kex_choose_conf(struct ssh *ssh) nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; @@ -987,7 +987,7 @@ diff -up openssh/kex.c.audit openssh/kex.c sprop[nenc])) != 0) { kex->failed_choice = peer[nenc]; peer[nenc] = NULL; -@@ -948,7 +961,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1017,7 +1030,7 @@ kex_choose_conf(struct ssh *ssh) peer[nmac] = NULL; goto out; } @@ -996,7 +996,7 @@ diff -up openssh/kex.c.audit openssh/kex.c sprop[ncomp])) != 0) { kex->failed_choice = peer[ncomp]; peer[ncomp] = NULL; -@@ -971,6 +984,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -1040,6 +1053,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); @@ -1007,7 +1007,7 @@ diff -up openssh/kex.c.audit openssh/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -1129,6 +1146,36 @@ dump_digest(const char *msg, const u_cha +@@ -1297,6 +1314,36 @@ dump_digest(const char *msg, const u_cha } #endif @@ -1044,9 +1044,9 @@ diff -up openssh/kex.c.audit openssh/kex.c /* * Send a plaintext error message to the peer, suffixed by \r\n. * Only used during banner exchange, and there only for the server. -diff -up openssh/kex.h.audit openssh/kex.h ---- openssh/kex.h.audit 2019-04-03 17:02:20.652885462 +0200 -+++ openssh/kex.h 2019-04-03 17:02:20.715886060 +0200 +diff -up openssh-8.6p1/kex.h.audit openssh-8.6p1/kex.h +--- openssh-8.6p1/kex.h.audit 2021-05-06 12:05:27.306463983 +0200 ++++ openssh-8.6p1/kex.h 2021-05-06 12:05:27.379464547 +0200 @@ -226,6 +226,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1056,10 +1056,10 @@ diff -up openssh/kex.h.audit openssh/kex.h int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **); -diff -up openssh/mac.c.audit openssh/mac.c ---- openssh/mac.c.audit 2019-04-03 17:02:20.652885462 +0200 -+++ openssh/mac.c 2019-04-03 17:02:20.715886060 +0200 -@@ -243,6 +243,20 @@ mac_clear(struct sshmac *mac) +diff -up openssh-8.6p1/mac.c.audit openssh-8.6p1/mac.c +--- openssh-8.6p1/mac.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/mac.c 2021-05-06 12:05:27.379464547 +0200 +@@ -239,6 +239,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1080,9 +1080,9 @@ diff -up openssh/mac.c.audit openssh/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh/mac.h.audit openssh/mac.h ---- openssh/mac.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/mac.h 2019-04-03 17:02:20.715886060 +0200 +diff -up openssh-8.6p1/mac.h.audit openssh-8.6p1/mac.h +--- openssh-8.6p1/mac.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/mac.h 2021-05-06 12:05:27.379464547 +0200 @@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, const u_char *, size_t); @@ -1090,21 +1090,21 @@ diff -up openssh/mac.h.audit openssh/mac.h +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh/Makefile.in.audit openssh/Makefile.in ---- openssh/Makefile.in.audit 2019-04-03 17:02:20.705885965 +0200 -+++ openssh/Makefile.in 2019-04-03 17:02:20.715886060 +0200 -@@ -109,7 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +diff -up openssh-8.6p1/Makefile.in.audit openssh-8.6p1/Makefile.in +--- openssh-8.6p1/Makefile.in.audit 2021-05-06 12:05:27.352464339 +0200 ++++ openssh-8.6p1/Makefile.in 2021-05-06 12:05:27.380464555 +0200 +@@ -112,7 +112,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kexsntrup761x25519.o sntrup761.o kexgen.o \ kexgssc.o \ - sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o + sshbuf-io.o auditstub.o SKOBJS= ssh-sk-client.o -diff -up openssh/monitor.c.audit openssh/monitor.c ---- openssh/monitor.c.audit 2019-04-03 17:02:20.674885671 +0200 -+++ openssh/monitor.c 2019-04-03 17:03:17.201421405 +0200 +diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c +--- openssh-8.6p1/monitor.c.audit 2021-05-06 12:05:27.326464138 +0200 ++++ openssh-8.6p1/monitor.c 2021-05-06 12:05:27.380464555 +0200 @@ -93,6 +93,7 @@ #include "compat.h" #include "ssh2.h" @@ -1113,7 +1113,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c #include "match.h" #include "ssherr.h" #include "sk-api.h" -@@ -107,6 +108,8 @@ extern u_char session_id[]; +@@ -107,6 +108,8 @@ extern u_int utmp_len; extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ @@ -1157,7 +1157,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c #endif {0, 0, NULL} }; -@@ -1445,8 +1462,10 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1444,8 +1461,10 @@ mm_answer_keyverify(struct ssh *ssh, int int r, ret, req_presence = 0, req_verify = 0, valid_data = 0; int encoded_ret; struct sshkey_sig_details *sig_details = NULL; @@ -1169,7 +1169,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c (r = sshbuf_get_string_direct(m, &signature, &signaturelen)) != 0 || (r = sshbuf_get_string_direct(m, &data, &datalen)) != 0 || (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) -@@ -1455,6 +1474,8 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1454,6 +1473,8 @@ mm_answer_keyverify(struct ssh *ssh, int if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) fatal_f("bad key, not previously allowed"); @@ -1178,7 +1178,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1470,27 +1491,30 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1469,14 +1490,19 @@ mm_answer_keyverify(struct ssh *ssh, int case MM_USERKEY: valid_data = monitor_valid_userblob(ssh, data, datalen); auth_method = "publickey"; @@ -1198,11 +1198,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c break; } if (!valid_data) - fatal_f("bad %s signature data blob", - key_blobtype == MM_USERKEY ? "userkey" : - (key_blobtype == MM_HOSTKEY ? "hostkey" : "unknown")); - - if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, +@@ -1488,8 +1514,6 @@ mm_answer_keyverify(struct ssh *ssh, int SSH_FP_DEFAULT)) == NULL) fatal_f("sshkey_fingerprint failed"); @@ -1211,7 +1207,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c debug3_f("%s %p signature %s%s%s", auth_method, key, (ret == 0) ? "verified" : "unverified", (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); -@@ -1536,13 +1560,19 @@ mm_record_login(struct ssh *ssh, Session +@@ -1576,13 +1600,19 @@ mm_record_login(struct ssh *ssh, Session } static void @@ -1232,7 +1228,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c session_unused(s->self); } -@@ -1609,7 +1639,7 @@ mm_answer_pty(struct ssh *ssh, int sock, +@@ -1649,7 +1679,7 @@ mm_answer_pty(struct ssh *ssh, int sock, error: if (s != NULL) @@ -1241,7 +1237,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c if ((r = sshbuf_put_u32(m, 0)) != 0) fatal_fr(r, "assemble 0"); mm_request_send(sock, MONITOR_ANS_PTY, m); -@@ -1628,7 +1658,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, i +@@ -1668,7 +1698,7 @@ mm_answer_pty_cleanup(struct ssh *ssh, i if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) fatal_fr(r, "parse tty"); if ((s = session_by_tty(tty)) != NULL) @@ -1250,7 +1246,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c sshbuf_reset(m); free(tty); return (0); -@@ -1650,6 +1680,8 @@ mm_answer_term(struct ssh *ssh, int sock +@@ -1690,6 +1720,8 @@ mm_answer_term(struct ssh *ssh, int sock sshpam_cleanup(); #endif @@ -1259,7 +1255,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1696,12 +1728,47 @@ mm_answer_audit_command(struct ssh *ssh, +@@ -1736,12 +1768,47 @@ mm_answer_audit_command(struct ssh *ssh, { char *cmd; int r; @@ -1308,7 +1304,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c free(cmd); return (0); } -@@ -1767,6 +1834,7 @@ monitor_apply_keystate(struct ssh *ssh, +@@ -1813,6 +1880,7 @@ monitor_apply_keystate(struct ssh *ssh, void mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { @@ -1316,7 +1312,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c debug3_f("Waiting for new keys"); if ((child_state = sshbuf_new()) == NULL) -@@ -1774,6 +1842,19 @@ mm_get_keystate(struct ssh *ssh, struct +@@ -1820,6 +1888,19 @@ mm_get_keystate(struct ssh *ssh, struct mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); debug3_f("GOT new keys"); @@ -1336,7 +1332,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c } -@@ -2066,3 +2147,102 @@ mm_answer_gss_updatecreds(struct ssh *ss +@@ -2111,3 +2192,102 @@ mm_answer_gss_updatecreds(struct ssh *ss #endif /* GSSAPI */ @@ -1439,9 +1435,9 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/monitor.h.audit openssh/monitor.h ---- openssh/monitor.h.audit 2019-04-03 17:02:20.674885671 +0200 -+++ openssh/monitor.h 2019-04-03 17:02:20.715886060 +0200 +diff -up openssh-8.6p1/monitor.h.audit openssh-8.6p1/monitor.h +--- openssh-8.6p1/monitor.h.audit 2021-05-06 12:05:27.326464138 +0200 ++++ openssh-8.6p1/monitor.h 2021-05-06 12:05:27.380464555 +0200 @@ -65,7 +65,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1457,10 +1453,10 @@ diff -up openssh/monitor.h.audit openssh/monitor.h MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, -diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.audit 2019-04-03 17:02:20.653885472 +0200 -+++ openssh/monitor_wrap.c 2019-04-03 17:02:20.716886069 +0200 -@@ -513,7 +513,7 @@ mm_key_allowed(enum mm_keytype type, con +diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c +--- openssh-8.6p1/monitor_wrap.c.audit 2021-05-06 12:05:27.307463991 +0200 ++++ openssh-8.6p1/monitor_wrap.c 2021-05-06 12:05:27.381464563 +0200 +@@ -520,7 +520,7 @@ mm_key_allowed(enum mm_keytype type, con */ int @@ -1469,7 +1465,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c const u_char *data, size_t datalen, const char *sigalg, u_int compat, struct sshkey_sig_details **sig_detailsp) { -@@ -525,7 +525,8 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -536,7 +536,8 @@ mm_sshkey_verify(const struct sshkey *ke *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -1479,7 +1475,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c (r = sshbuf_put_string(m, sig, siglen)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0) -@@ -547,6 +548,22 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -569,6 +570,22 @@ mm_sshkey_verify(const struct sshkey *ke return 0; } @@ -1502,7 +1498,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c void mm_send_keystate(struct ssh *ssh, struct monitor *monitor) { -@@ -900,11 +915,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi +@@ -921,11 +938,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi sshbuf_free(m); } @@ -1517,7 +1513,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -914,6 +930,30 @@ mm_audit_run_command(const char *command +@@ -935,6 +953,30 @@ mm_audit_run_command(const char *command fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); @@ -1548,7 +1544,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c sshbuf_free(m); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1074,3 +1114,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1095,3 +1137,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc } #endif /* GSSAPI */ @@ -1632,10 +1628,10 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + sshbuf_free(m); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.audit 2019-04-03 17:02:20.653885472 +0200 -+++ openssh/monitor_wrap.h 2019-04-03 17:02:20.716886069 +0200 -@@ -57,7 +57,9 @@ int mm_user_key_allowed(struct ssh *, st +diff -up openssh-8.6p1/monitor_wrap.h.audit openssh-8.6p1/monitor_wrap.h +--- openssh-8.6p1/monitor_wrap.h.audit 2021-05-06 12:05:27.307463991 +0200 ++++ openssh-8.6p1/monitor_wrap.h 2021-05-06 12:05:27.381464563 +0200 +@@ -61,7 +61,9 @@ int mm_user_key_allowed(struct ssh *, st struct sshauthopt **); int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, const char *, struct sshkey *); @@ -1646,7 +1642,7 @@ diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); #ifdef GSSAPI -@@ -82,7 +84,12 @@ void mm_sshpam_free_ctx(void *); +@@ -86,7 +88,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(struct ssh *, ssh_audit_event_t); @@ -1660,10 +1656,10 @@ diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h #endif struct Session; -diff -up openssh/packet.c.audit openssh/packet.c ---- openssh/packet.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/packet.c 2019-04-03 17:02:20.716886069 +0200 -@@ -77,6 +77,7 @@ +diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c +--- openssh-8.6p1/packet.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/packet.c 2021-05-06 12:07:38.535478683 +0200 +@@ -81,6 +81,7 @@ #endif #include "xmalloc.h" @@ -1671,7 +1667,7 @@ diff -up openssh/packet.c.audit openssh/packet.c #include "compat.h" #include "ssh2.h" #include "cipher.h" -@@ -510,6 +511,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1685,7 +1681,7 @@ diff -up openssh/packet.c.audit openssh/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -587,22 +595,19 @@ ssh_packet_close_internal(struct ssh *ss +@@ -583,22 +591,19 @@ ssh_packet_close_internal(struct ssh *ss { struct session_state *state = ssh->state; u_int mode; @@ -1713,7 +1709,7 @@ diff -up openssh/packet.c.audit openssh/packet.c for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; -@@ -636,8 +641,18 @@ ssh_packet_close_internal(struct ssh *ss +@@ -634,8 +639,18 @@ ssh_packet_close_internal(struct ssh *ss #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); @@ -1732,15 +1728,15 @@ diff -up openssh/packet.c.audit openssh/packet.c free(ssh->local_ipaddr); ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); -@@ -864,6 +879,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod - (unsigned long long)state->p_send.bytes, - (unsigned long long)state->p_send.blocks); +@@ -892,6 +907,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod + (unsigned long long)state->p_send.bytes, + (unsigned long long)state->p_send.blocks); kex_free_newkeys(state->newkeys[mode]); + audit_session_key_free(ssh, mode); state->newkeys[mode] = NULL; } /* note that both bytes and the seqnr are not reset */ -@@ -2167,6 +2183,72 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2173,6 +2189,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1813,18 +1809,18 @@ diff -up openssh/packet.c.audit openssh/packet.c /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh/packet.h.audit openssh/packet.h ---- openssh/packet.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/packet.h 2019-04-03 17:02:20.716886069 +0200 -@@ -217,4 +217,5 @@ const u_char *sshpkt_ptr(struct ssh *, s +diff -up openssh-8.6p1/packet.h.audit openssh-8.6p1/packet.h +--- openssh-8.6p1/packet.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/packet.h 2021-05-06 12:05:27.382464571 +0200 +@@ -218,4 +218,5 @@ const u_char *sshpkt_ptr(struct ssh *, s # undef EC_POINT #endif +void packet_destroy_all(struct ssh *, int, int); #endif /* PACKET_H */ -diff -up openssh/session.c.audit openssh/session.c ---- openssh/session.c.audit 2019-04-03 17:02:20.712886031 +0200 -+++ openssh/session.c 2019-04-03 17:02:20.716886069 +0200 +diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.audit 2021-05-06 12:05:27.340464246 +0200 ++++ openssh-8.6p1/session.c 2021-05-06 12:05:27.383464578 +0200 @@ -136,7 +136,7 @@ extern char *__progname; extern int debug_flag; extern u_int utmp_len; @@ -1834,7 +1830,7 @@ diff -up openssh/session.c.audit openssh/session.c extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; extern char *tun_fwd_ifnames; /* serverloop.c */ -@@ -648,6 +648,14 @@ do_exec_pty(struct ssh *ssh, Session *s, +@@ -644,6 +644,14 @@ do_exec_pty(struct ssh *ssh, Session *s, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1849,7 +1845,7 @@ diff -up openssh/session.c.audit openssh/session.c /* Enter interactive session. */ s->ptymaster = ptymaster; ssh_packet_set_interactive(ssh, 1, -@@ -740,15 +748,19 @@ do_exec(struct ssh *ssh, Session *s, con +@@ -736,15 +744,19 @@ do_exec(struct ssh *ssh, Session *s, con s->self); #ifdef SSH_AUDIT_EVENTS @@ -1871,7 +1867,7 @@ diff -up openssh/session.c.audit openssh/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -1556,8 +1568,11 @@ do_child(struct ssh *ssh, Session *s, co +@@ -1550,8 +1562,11 @@ do_child(struct ssh *ssh, Session *s, co sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); /* remove hostkey from the child's memory */ @@ -1884,7 +1880,7 @@ diff -up openssh/session.c.audit openssh/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1769,6 +1784,9 @@ session_unused(int id) +@@ -1763,6 +1778,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1894,7 +1890,7 @@ diff -up openssh/session.c.audit openssh/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1851,6 +1869,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1843,6 +1861,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1914,7 +1910,7 @@ diff -up openssh/session.c.audit openssh/session.c session_by_tty(char *tty) { int i; -@@ -2461,6 +2492,32 @@ session_exit_message(struct ssh *ssh, Se +@@ -2450,6 +2481,32 @@ session_exit_message(struct ssh *ssh, Se chan_write_failed(ssh, c); } @@ -1947,7 +1943,7 @@ diff -up openssh/session.c.audit openssh/session.c void session_close(struct ssh *ssh, Session *s) { -@@ -2474,6 +2531,10 @@ session_close(struct ssh *ssh, Session * +@@ -2463,6 +2520,10 @@ session_close(struct ssh *ssh, Session * if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1958,7 +1954,7 @@ diff -up openssh/session.c.audit openssh/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2549,14 +2610,14 @@ session_close_by_channel(struct ssh *ssh +@@ -2537,14 +2598,14 @@ session_close_by_channel(struct ssh *ssh } void @@ -1975,7 +1971,7 @@ diff -up openssh/session.c.audit openssh/session.c else session_close(ssh, s); } -@@ -2683,6 +2744,15 @@ do_authenticated2(struct ssh *ssh, Authc +@@ -2671,6 +2732,15 @@ do_authenticated2(struct ssh *ssh, Authc server_loop2(ssh, authctxt); } @@ -1991,7 +1987,7 @@ diff -up openssh/session.c.audit openssh/session.c void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2746,7 +2816,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au +@@ -2734,7 +2804,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) @@ -2000,9 +1996,9 @@ diff -up openssh/session.c.audit openssh/session.c } /* Return a name for the remote host that fits inside utmp_size */ -diff -up openssh/session.h.audit openssh/session.h ---- openssh/session.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/session.h 2019-04-03 17:02:20.717886079 +0200 +diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h +--- openssh-8.6p1/session.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/session.h 2021-05-06 12:05:27.384464586 +0200 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2030,9 +2026,9 @@ diff -up openssh/session.h.audit openssh/session.h Session *session_by_tty(char *); void session_close(struct ssh *, Session *); void do_setusercontext(struct passwd *); -diff -up openssh/sshd.c.audit openssh/sshd.c ---- openssh/sshd.c.audit 2019-04-03 17:02:20.692885842 +0200 -+++ openssh/sshd.c 2019-04-03 17:02:20.717886079 +0200 +diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.audit 2021-05-06 12:05:27.346464292 +0200 ++++ openssh-8.6p1/sshd.c 2021-05-06 12:05:27.385464594 +0200 @@ -122,6 +122,7 @@ #include "ssh-gss.h" #endif @@ -2041,7 +2037,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c #include "ssh-sandbox.h" #include "auth-options.h" #include "version.h" -@@ -261,8 +262,8 @@ struct sshbuf *loginmsg; +@@ -260,8 +261,8 @@ struct sshbuf *loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -2052,7 +2048,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c static void do_ssh2_kex(struct ssh *); static char *listener_proctitle; -@@ -278,6 +279,15 @@ close_listen_socks(void) +@@ -279,6 +280,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2068,7 +2064,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c static void close_startup_pipes(void) { -@@ -380,18 +390,45 @@ grace_alarm_handler(int sig) +@@ -377,18 +387,45 @@ grace_alarm_handler(int sig) ssh_remote_port(the_active_state)); } @@ -2117,7 +2113,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -400,20 +437,38 @@ destroy_sensitive_data(void) +@@ -397,20 +434,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2157,7 +2153,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c } /* Certs do not need demotion */ } -@@ -442,7 +497,7 @@ reseed_prngs(void) +@@ -438,7 +493,7 @@ reseed_prngs(void) } static void @@ -2166,7 +2162,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c { gid_t gidset[1]; -@@ -457,7 +512,7 @@ privsep_preauth_child(void) +@@ -453,7 +508,7 @@ privsep_preauth_child(void) reseed_prngs(); /* Demote the private keys to public keys. */ @@ -2175,7 +2171,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c #ifdef WITH_SELINUX sshd_selinux_change_privsep_preauth_context(); -@@ -496,7 +551,7 @@ privsep_preauth(struct ssh *ssh) +@@ -492,7 +547,7 @@ privsep_preauth(struct ssh *ssh) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2184,7 +2180,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -542,7 +597,7 @@ privsep_preauth(struct ssh *ssh) +@@ -537,7 +592,7 @@ privsep_preauth(struct ssh *ssh) /* Arrange for logging to be sent to the monitor */ set_log_handler(mm_log_handler, pmonitor); @@ -2193,7 +2189,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c setproctitle("%s", "[net]"); if (box != NULL) ssh_sandbox_child(box); -@@ -594,7 +649,7 @@ privsep_postauth(struct ssh *ssh, Authct +@@ -589,7 +644,7 @@ privsep_postauth(struct ssh *ssh, Authct set_log_handler(mm_log_handler, pmonitor); /* Demote the private keys to public keys. */ @@ -2202,7 +2198,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c reseed_prngs(); -@@ -1057,7 +1112,7 @@ server_listen(void) +@@ -1143,7 +1198,7 @@ server_listen(void) * from this function are in a forked subprocess. */ static void @@ -2211,7 +2207,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c { fd_set *fdset; int i, j, ret, maxfd; -@@ -1112,6 +1167,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1204,6 +1259,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2219,7 +2215,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -1978,7 +2034,7 @@ main(int ac, char **av) +@@ -2098,7 +2154,7 @@ main(int ac, char **av) #endif /* Accept a connection and return in a forked child */ @@ -2228,7 +2224,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c &newsock, config_s); } -@@ -2222,6 +2278,9 @@ main(int ac, char **av) +@@ -2333,6 +2389,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ @@ -2238,7 +2234,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c ssh_packet_get_bytes(ssh, &ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2401,6 +2460,15 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2513,6 +2572,15 @@ do_ssh2_kex(struct ssh *ssh) void cleanup_exit(int i) { @@ -2254,7 +2250,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c if (the_active_state != NULL && the_authctxt != NULL) { do_cleanup(the_active_state, the_authctxt); if (use_privsep && privsep_is_preauth && -@@ -2414,9 +2482,16 @@ cleanup_exit(int i) +@@ -2525,9 +2593,16 @@ cleanup_exit(int i) } } } @@ -2272,10 +2268,10 @@ diff -up openssh/sshd.c.audit openssh/sshd.c audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh/sshkey.c.audit openssh/sshkey.c ---- openssh/sshkey.c.audit 2019-04-03 17:02:20.657885510 +0200 -+++ openssh/sshkey.c 2019-04-03 17:02:20.718886088 +0200 -@@ -331,6 +331,38 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh-8.6p1/sshkey.c.audit openssh-8.6p1/sshkey.c +--- openssh-8.6p1/sshkey.c.audit 2021-05-06 12:05:27.364464431 +0200 ++++ openssh-8.6p1/sshkey.c 2021-05-06 12:05:27.386464602 +0200 +@@ -371,6 +371,38 @@ sshkey_type_is_valid_ca(int type) } int @@ -2314,10 +2310,10 @@ diff -up openssh/sshkey.c.audit openssh/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh/sshkey.h.audit openssh/sshkey.h ---- openssh/sshkey.h.audit 2019-04-03 17:02:20.657885510 +0200 -+++ openssh/sshkey.h 2019-04-03 17:02:20.718886088 +0200 -@@ -148,6 +148,7 @@ u_int sshkey_size(const struct sshkey +diff -up openssh-8.6p1/sshkey.h.audit openssh-8.6p1/sshkey.h +--- openssh-8.6p1/sshkey.h.audit 2021-05-06 12:05:27.365464439 +0200 ++++ openssh-8.6p1/sshkey.h 2021-05-06 12:05:27.386464602 +0200 +@@ -189,6 +189,7 @@ int sshkey_shield_private(struct sshke int sshkey_unshield_private(struct sshkey *); int sshkey_type_from_name(const char *); diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index f199fb2..6e72d04 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,6 +1,6 @@ -diff -up openssh-8.0p1/cipher-ctr.c.fips openssh-8.0p1/cipher-ctr.c ---- openssh-8.0p1/cipher-ctr.c.fips 2019-07-23 14:55:45.326525641 +0200 -+++ openssh-8.0p1/cipher-ctr.c 2019-07-23 14:55:45.401526401 +0200 +diff -up openssh-8.6p1/cipher-ctr.c.fips openssh-8.6p1/cipher-ctr.c +--- openssh-8.6p1/cipher-ctr.c.fips 2021-05-06 12:08:36.423926297 +0200 ++++ openssh-8.6p1/cipher-ctr.c 2021-05-06 12:08:36.497926869 +0200 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -11,10 +11,10 @@ diff -up openssh-8.0p1/cipher-ctr.c.fips openssh-8.0p1/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh-8.0p1/dh.c.fips openssh-8.0p1/dh.c ---- openssh-8.0p1/dh.c.fips 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/dh.c 2019-07-23 14:55:45.401526401 +0200 -@@ -152,6 +152,12 @@ choose_dh(int min, int wantbits, int max +diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c +--- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/dh.c 2021-05-06 12:12:10.107634472 +0200 +@@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max int best, bestcount, which, linenum; struct dhgroup dhg; @@ -24,10 +24,10 @@ diff -up openssh-8.0p1/dh.c.fips openssh-8.0p1/dh.c + return (dh_new_group_fallback(max)); + } + - if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) { + if ((f = fopen(get_moduli_filename(), "r")) == NULL) { logit("WARNING: could not open %s (%s), using fixed modulus", - _PATH_DH_MODULI, strerror(errno)); -@@ -489,4 +495,38 @@ dh_estimate(int bits) + get_moduli_filename(), strerror(errno)); +@@ -502,4 +508,38 @@ dh_estimate(int bits) return 8192; } @@ -66,21 +66,21 @@ diff -up openssh-8.0p1/dh.c.fips openssh-8.0p1/dh.c +} + #endif /* WITH_OPENSSL */ -diff -up openssh-8.0p1/dh.h.fips openssh-8.0p1/dh.h ---- openssh-8.0p1/dh.h.fips 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/dh.h 2019-07-23 14:55:45.401526401 +0200 -@@ -43,6 +43,7 @@ DH *dh_new_group_fallback(int); +diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h +--- openssh-8.6p1/dh.h.fips 2021-05-06 12:08:36.498926877 +0200 ++++ openssh-8.6p1/dh.h 2021-05-06 12:11:28.393298005 +0200 +@@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); int dh_gen_key(DH *, int); int dh_pub_is_valid(const DH *, const BIGNUM *); +int dh_is_known_group(const DH *); u_int dh_estimate(int); - -diff -up openssh-8.0p1/kex.c.fips openssh-8.0p1/kex.c ---- openssh-8.0p1/kex.c.fips 2019-07-23 14:55:45.395526340 +0200 -+++ openssh-8.0p1/kex.c 2019-07-23 14:55:45.402526411 +0200 -@@ -199,7 +199,10 @@ kex_names_valid(const char *names) + void dh_set_moduli_file(const char *); +diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c +--- openssh-8.6p1/kex.c.fips 2021-05-06 12:08:36.489926807 +0200 ++++ openssh-8.6p1/kex.c 2021-05-06 12:08:36.498926877 +0200 +@@ -203,7 +203,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -92,9 +92,9 @@ diff -up openssh-8.0p1/kex.c.fips openssh-8.0p1/kex.c free(s); return 0; } -diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c ---- openssh-8.0p1/kexgexc.c.fips 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/kexgexc.c 2019-07-23 14:55:45.402526411 +0200 +diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c +--- openssh-8.6p1/kexgexc.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/kexgexc.c 2021-05-06 12:08:36.498926877 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -103,7 +103,7 @@ diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c #include #include -@@ -113,6 +114,10 @@ input_kex_dh_gex_group(int type, u_int32 +@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32 r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -114,10 +114,10 @@ diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ -diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h ---- openssh-8.0p1/myproposal.h.fips 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/myproposal.h 2019-07-23 14:55:45.402526411 +0200 -@@ -111,6 +111,20 @@ +diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h +--- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/myproposal.h 2021-05-06 12:08:36.498926877 +0200 +@@ -57,6 +57,20 @@ "rsa-sha2-256," \ "ssh-rsa" @@ -138,7 +138,7 @@ diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ "aes128-ctr,aes192-ctr,aes256-ctr," \ -@@ -134,6 +142,27 @@ +@@ -78,6 +92,27 @@ #define KEX_CLIENT_MAC KEX_SERVER_MAC @@ -166,10 +166,10 @@ diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h /* Not a KEX value, but here so all the algorithm defaults are together */ #define SSH_ALLOWED_CA_SIGALGS \ "ssh-ed25519," \ -diff -up openssh-8.0p1/readconf.c.fips openssh-8.0p1/readconf.c ---- openssh-8.0p1/readconf.c.fips 2019-07-23 14:55:45.334525723 +0200 -+++ openssh-8.0p1/readconf.c 2019-07-23 14:55:45.402526411 +0200 -@@ -2179,11 +2179,16 @@ fill_default_options(Options * options) +diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c +--- openssh-8.6p1/readconf.c.fips 2021-05-06 12:08:36.428926336 +0200 ++++ openssh-8.6p1/readconf.c 2021-05-06 12:08:36.499926885 +0200 +@@ -2538,11 +2538,16 @@ fill_default_options(Options * options) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); /* remove unsupported algos from default lists */ @@ -191,10 +191,10 @@ diff -up openssh-8.0p1/readconf.c.fips openssh-8.0p1/readconf.c #define ASSEMBLE(what, defaults, all) \ do { \ if ((r = kex_assemble_names(&options->what, \ -diff -up openssh-8.0p1/sandbox-seccomp-filter.c.fips openssh-8.0p1/sandbox-seccomp-filter.c ---- openssh-8.0p1/sandbox-seccomp-filter.c.fips 2019-07-23 14:55:45.373526117 +0200 -+++ openssh-8.0p1/sandbox-seccomp-filter.c 2019-07-23 14:55:45.402526411 +0200 -@@ -137,6 +137,9 @@ static const struct sock_filter preauth_ +diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c +--- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-05-06 12:08:36.463926606 +0200 ++++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-05-06 12:08:36.499926885 +0200 +@@ -160,6 +160,9 @@ static const struct sock_filter preauth_ #ifdef __NR_open SC_DENY(__NR_open, EACCES), #endif @@ -204,10 +204,10 @@ diff -up openssh-8.0p1/sandbox-seccomp-filter.c.fips openssh-8.0p1/sandbox-secco #ifdef __NR_openat SC_DENY(__NR_openat, EACCES), #endif -diff -up openssh-8.0p1/servconf.c.fips openssh-8.0p1/servconf.c ---- openssh-8.0p1/servconf.c.fips 2019-07-23 14:55:45.361525996 +0200 -+++ openssh-8.0p1/servconf.c 2019-07-23 14:55:45.403526421 +0200 -@@ -208,11 +208,16 @@ assemble_algorithms(ServerOptions *o) +diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c +--- openssh-8.6p1/servconf.c.fips 2021-05-06 12:08:36.455926545 +0200 ++++ openssh-8.6p1/servconf.c 2021-05-06 12:08:36.500926893 +0200 +@@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); /* remove unsupported algos from default lists */ @@ -229,10 +229,10 @@ diff -up openssh-8.0p1/servconf.c.fips openssh-8.0p1/servconf.c #define ASSEMBLE(what, defaults, all) \ do { \ if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ -diff -up openssh-8.0p1/ssh.c.fips openssh-8.0p1/ssh.c ---- openssh-8.0p1/ssh.c.fips 2019-07-23 14:55:45.378526168 +0200 -+++ openssh-8.0p1/ssh.c 2019-07-23 14:55:45.403526421 +0200 -@@ -76,6 +76,7 @@ +diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c +--- openssh-8.6p1/ssh.c.fips 2021-05-06 12:08:36.467926637 +0200 ++++ openssh-8.6p1/ssh.c 2021-05-06 12:08:36.500926893 +0200 +@@ -77,6 +77,7 @@ #include #include #endif @@ -240,21 +240,21 @@ diff -up openssh-8.0p1/ssh.c.fips openssh-8.0p1/ssh.c #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -614,6 +626,10 @@ main(int ac, char **av) - dump_client_config(&options, host); +@@ -1516,6 +1517,10 @@ main(int ac, char **av) exit(0); } -+ + + if (FIPS_mode()) { + debug("FIPS mode initialized"); + } - ++ /* Expand SecurityKeyProvider if it refers to an environment variable */ if (options.sk_provider != NULL && *options.sk_provider == '$' && -diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c ---- openssh-8.0p1/sshconnect2.c.fips 2019-07-23 14:55:45.336525743 +0200 -+++ openssh-8.0p1/sshconnect2.c 2019-07-23 14:55:45.403526421 +0200 -@@ -44,6 +44,8 @@ + strlen(options.sk_provider) > 1) { +diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c +--- openssh-8.6p1/sshconnect2.c.fips 2021-05-06 12:08:36.485926777 +0200 ++++ openssh-8.6p1/sshconnect2.c 2021-05-06 12:08:36.501926900 +0200 +@@ -45,6 +45,8 @@ #include #endif @@ -263,7 +263,7 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -198,36 +203,41 @@ ssh_kex2(struct ssh *ssh, char *host, st +@@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { @@ -279,24 +279,6 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c - * and can not use DNS on that socket */ - if (strcmp(gss_host, "UNKNOWN") == 0) { - free(gss_host); -- gss_host = xstrdup(host); -- } -- } else { -- gss_host = xstrdup(host); -- } -- -- gss = ssh_gssapi_client_mechanisms(gss_host, -- options.gss_client_identity, options.gss_kex_algorithms); -- if (gss) { -- debug("Offering GSSAPI proposal: %s", gss); -- xasprintf(&myproposal[PROPOSAL_KEX_ALGS], -- "%s,%s", gss, orig); -- -- /* If we've got GSSAPI algorithms, then we also support the -- * 'null' hostkey, as a last resort */ -- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; -- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], -- "%s,null", orig); + if (FIPS_mode()) { + logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); + options.gss_keyex = 0; @@ -316,9 +298,24 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c + gss_host = xstrdup(host); + } + } else { -+ gss_host = xstrdup(host); -+ } -+ + gss_host = xstrdup(host); + } +- } else { +- gss_host = xstrdup(host); +- } + +- gss = ssh_gssapi_client_mechanisms(gss_host, +- options.gss_client_identity, options.gss_kex_algorithms); +- if (gss) { +- debug("Offering GSSAPI proposal: %s", gss); +- xasprintf(&myproposal[PROPOSAL_KEX_ALGS], +- "%s,%s", gss, orig); +- +- /* If we've got GSSAPI algorithms, then we also support the +- * 'null' hostkey, as a last resort */ +- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; +- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], +- "%s,null", orig); + gss = ssh_gssapi_client_mechanisms(gss_host, + options.gss_client_identity, options.gss_kex_algorithms); + if (gss) { @@ -335,9 +332,9 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c } } #endif -diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c ---- openssh-8.0p1/sshd.c.fips 2019-07-23 14:55:45.398526371 +0200 -+++ openssh-8.0p1/sshd.c 2019-07-23 14:55:45.403526421 +0200 +diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.fips 2021-05-06 12:08:36.493926838 +0200 ++++ openssh-8.6p1/sshd.c 2021-05-06 12:13:56.501492639 +0200 @@ -66,6 +66,7 @@ #include #include @@ -354,7 +351,7 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c #include "openbsd-compat/openssl-compat.h" #endif -@@ -1529,6 +1532,7 @@ main(int ac, char **av) +@@ -1619,6 +1621,7 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -362,7 +359,7 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1992,6 +2007,10 @@ main(int ac, char **av) +@@ -2110,6 +2113,10 @@ main(int ac, char **av) /* Reinitialize the log (because of the fork above). */ log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -370,10 +367,10 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c + debug("FIPS mode initialized"); + } + - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ - if (chdir("/") == -1) -@@ -2382,10 +2401,14 @@ do_ssh2_kex(struct ssh *ssh) + /* + * Chdir to the root directory so that the current disk can be + * unmounted if desired. +@@ -2494,10 +2501,14 @@ do_ssh2_kex(struct ssh *ssh) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -392,9 +389,9 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c ---- openssh-8.0p1/sshkey.c.fips 2019-07-23 14:55:45.398526371 +0200 -+++ openssh-8.0p1/sshkey.c 2019-07-23 14:55:45.404526431 +0200 +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 @@ -411,7 +408,7 @@ diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c #include "ssh-sk.h" #ifdef WITH_XMSS -@@ -1591,6 +1593,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { @@ -420,10 +417,10 @@ diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } -diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c ---- openssh-8.0p1/ssh-keygen.c.fips 2019-07-23 14:55:45.391526300 +0200 -+++ openssh-8.0p1/ssh-keygen.c 2019-07-23 14:57:54.118830056 +0200 -@@ -199,6 +199,12 @@ type_bits_valid(int type, const char *na +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 +@@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na #endif } #ifdef WITH_OPENSSL @@ -436,7 +433,7 @@ diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c switch (type) { case KEY_DSA: if (*bitsp != 1024) -@@ -1029,9 +1035,17 @@ do_gen_all_hostkeys(struct passwd *pw) +@@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw) first = 1; printf("%s: generating new host keys: ", __progname); } @@ -454,4 +451,4 @@ diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c - type = sshkey_type_from_name(key_types[i].key_type); if ((fd = mkstemp(prv_tmp)) == -1) { error("Could not save your private key in %s: %s", - prv_tmp, strerror(errno)); + prv_tmp, strerror(errno)); diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 3b9ef3a..151796b 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -1,7 +1,26 @@ -diff --git a/auth-krb5.c b/auth-krb5.c -index a5a81ed2..63f877f2 100644 ---- a/auth-krb5.c -+++ b/auth-krb5.c +diff -up openssh-8.6p1/auth.h.ccache_name openssh-8.6p1/auth.h +--- openssh-8.6p1/auth.h.ccache_name 2021-05-06 11:15:36.345143341 +0200 ++++ openssh-8.6p1/auth.h 2021-05-06 11:15:36.387143654 +0200 +@@ -83,6 +83,7 @@ struct Authctxt { + krb5_principal krb5_user; + char *krb5_ticket_file; + char *krb5_ccname; ++ int krb5_set_env; + #endif + struct sshbuf *loginmsg; + +@@ -231,7 +232,7 @@ struct passwd *fakepw(void); + int sys_auth_passwd(struct ssh *, const char *); + + #if defined(KRB5) && !defined(HEIMDAL) +-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); ++krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); + #endif + + #endif /* AUTH_H */ +diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c +--- openssh-8.6p1/auth-krb5.c.ccache_name 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/auth-krb5.c 2021-05-06 11:28:40.195242317 +0200 @@ -51,6 +51,7 @@ #include #include @@ -10,7 +29,7 @@ index a5a81ed2..63f877f2 100644 extern ServerOptions options; -@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c #endif krb5_error_code problem; krb5_ccache ccache = NULL; @@ -19,24 +38,18 @@ index a5a81ed2..63f877f2 100644 char *client, *platform_client; const char *errmsg; -@@ -163,7 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, c goto out; } -- problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache); +- problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, +- &authctxt->krb5_fwd_ccache); + problem = ssh_krb5_cc_new_unique(authctxt->krb5_ctx, + &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env); if (problem) goto out; -@@ -172,21 +174,20 @@ auth_krb5_password(Authctxt *authctxt, const char *password) - if (problem) - goto out; - -- problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, -+ problem = krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, - &creds); - if (problem) +@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, c goto out; #endif @@ -57,7 +70,7 @@ index a5a81ed2..63f877f2 100644 do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); #endif -@@ -222,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, c void krb5_cleanup_proc(Authctxt *authctxt) { @@ -113,7 +126,7 @@ index a5a81ed2..63f877f2 100644 if (authctxt->krb5_user) { krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); authctxt->krb5_user = NULL; -@@ -237,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt) +@@ -238,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt) } } @@ -198,10 +211,7 @@ index a5a81ed2..63f877f2 100644 + return -1; +} + - krb5_error_code --ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { -- int tmpfd, ret, oerrno; -- char ccname[40]; ++krb5_error_code +ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { + profile_t p; + int ret = 0; @@ -222,7 +232,10 @@ index a5a81ed2..63f877f2 100644 + return ret; +} + -+krb5_error_code + krb5_error_code +-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { +- int tmpfd, ret, oerrno; +- char ccname[40]; +ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) { + int tmpfd, ret, oerrno, type_len; + char *ccname = NULL; @@ -324,30 +337,41 @@ index a5a81ed2..63f877f2 100644 } #endif /* !HEIMDAL */ #endif /* KRB5 */ -diff --git a/auth.h b/auth.h -index 29491df9..fdab5040 100644 ---- a/auth.h -+++ b/auth.h -@@ -82,6 +82,7 @@ struct Authctxt { - krb5_principal krb5_user; - char *krb5_ticket_file; - char *krb5_ccname; -+ int krb5_set_env; - #endif - struct sshbuf *loginmsg; +diff -up openssh-8.6p1/gss-serv.c.ccache_name openssh-8.6p1/gss-serv.c +--- openssh-8.6p1/gss-serv.c.ccache_name 2021-05-06 11:15:36.374143558 +0200 ++++ openssh-8.6p1/gss-serv.c 2021-05-06 11:15:36.387143654 +0200 +@@ -413,13 +413,15 @@ ssh_gssapi_cleanup_creds(void) + } -@@ -238,7 +239,7 @@ int sys_auth_passwd(struct ssh *, const char *); - int sys_auth_passwd(struct ssh *, const char *); + /* As user */ +-void ++int + ssh_gssapi_storecreds(void) + { + if (gssapi_client.mech && gssapi_client.mech->storecreds) { +- (*gssapi_client.mech->storecreds)(&gssapi_client); ++ return (*gssapi_client.mech->storecreds)(&gssapi_client); + } else + debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); ++ ++ return 0; + } - #if defined(KRB5) && !defined(HEIMDAL) --krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); -+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); + /* This allows GSSAPI methods to do things to the child's environment based +@@ -499,9 +501,7 @@ ssh_gssapi_rekey_creds(void) { + char *envstr; #endif - #endif /* AUTH_H */ -diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c ---- openssh-7.9p1/gss-serv-krb5.c.ccache_name 2019-03-01 15:17:42.708611802 +0100 -+++ openssh-7.9p1/gss-serv-krb5.c 2019-03-01 15:17:42.713611844 +0100 +- if (gssapi_client.store.filename == NULL && +- gssapi_client.store.envval == NULL && +- gssapi_client.store.envvar == NULL) ++ if (gssapi_client.store.envval == NULL) + return; + + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); +diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c +--- openssh-8.6p1/gss-serv-krb5.c.ccache_name 2021-05-06 11:15:36.384143632 +0200 ++++ openssh-8.6p1/gss-serv-krb5.c 2021-05-06 11:15:36.387143654 +0200 @@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ @@ -450,7 +474,7 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c do_pam_putenv(client->store.envvar, client->store.envval); #endif -@@ -361,7 +355,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl client->store.data = krb_context; @@ -459,43 +483,10 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c } int -diff --git a/gss-serv.c b/gss-serv.c -index 6cae720e..16e55cbc 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -320,13 +320,15 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) - } - - /* As user */ --void -+int - ssh_gssapi_storecreds(void) - { - if (gssapi_client.mech && gssapi_client.mech->storecreds) { -- (*gssapi_client.mech->storecreds)(&gssapi_client); -+ return (*gssapi_client.mech->storecreds)(&gssapi_client); - } else - debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -+ -+ return 0; - } - - /* This allows GSSAPI methods to do things to the child's environment based -@@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() { - char *envstr; - #endif - -- if (gssapi_client.store.filename == NULL && -- gssapi_client.store.envval == NULL && -- gssapi_client.store.envvar == NULL) -+ if (gssapi_client.store.envval == NULL) - return; - - ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); -diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c ---- openssh-7.9p1/servconf.c.ccache_name 2019-03-01 15:17:42.704611768 +0100 -+++ openssh-7.9p1/servconf.c 2019-03-01 15:17:42.713611844 +0100 -@@ -123,6 +123,7 @@ initialize_server_options(ServerOptions +diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c +--- openssh-8.6p1/servconf.c.ccache_name 2021-05-06 11:15:36.377143580 +0200 ++++ openssh-8.6p1/servconf.c 2021-05-06 11:15:36.388143662 +0200 +@@ -136,6 +136,7 @@ initialize_server_options(ServerOptions options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -503,7 +494,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c options->gss_authentication=-1; options->gss_keyex = -1; options->gss_cleanup_creds = -1; -@@ -315,6 +316,8 @@ fill_default_server_options(ServerOptions *options) +@@ -359,6 +360,8 @@ fill_default_server_options(ServerOption options->kerberos_ticket_cleanup = 1; if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; @@ -512,7 +503,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_keyex == -1) -@@ -447,7 +450,8 @@ typedef enum { +@@ -506,7 +509,8 @@ typedef enum { sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, @@ -522,7 +513,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, -@@ -526,11 +530,13 @@ static struct { +@@ -593,11 +597,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -536,7 +527,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1437,6 +1443,10 @@ process_server_config_line(ServerOptions *options, char *line, +@@ -1573,6 +1579,10 @@ process_server_config_line_depth(ServerO intptr = &options->kerberos_get_afs_token; goto parse_flag; @@ -547,7 +538,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c case sGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; -@@ -2507,6 +2517,7 @@ dump_config(ServerOptions *o) +@@ -2891,6 +2901,7 @@ dump_config(ServerOptions *o) # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif @@ -555,11 +546,10 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); -diff --git a/servconf.h b/servconf.h -index db8362c6..4fa42d64 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -123,6 +123,8 @@ typedef struct { +diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h +--- openssh-8.6p1/servconf.h.ccache_name 2021-05-06 11:15:36.377143580 +0200 ++++ openssh-8.6p1/servconf.h 2021-05-06 11:15:36.397143729 +0200 +@@ -140,6 +140,8 @@ typedef struct { * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -568,11 +558,10 @@ index db8362c6..4fa42d64 100644 int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -diff --git a/session.c b/session.c -index 85df6a27..480a5ead 100644 ---- a/session.c -+++ b/session.c -@@ -1033,7 +1033,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.ccache_name 2021-05-06 11:15:36.384143632 +0200 ++++ openssh-8.6p1/session.c 2021-05-06 11:15:36.397143729 +0200 +@@ -1038,7 +1038,8 @@ do_setup_env(struct ssh *ssh, Session *s /* Allow any GSSAPI methods that we've used to alter * the child's environment as they see fit */ @@ -582,7 +571,7 @@ index 85df6a27..480a5ead 100644 #endif /* Set basic environment. */ -@@ -1105,7 +1106,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +@@ -1114,7 +1115,7 @@ do_setup_env(struct ssh *ssh, Session *s } #endif #ifdef KRB5 @@ -591,33 +580,10 @@ index 85df6a27..480a5ead 100644 child_set_env(&env, &envsize, "KRB5CCNAME", s->authctxt->krb5_ccname); #endif -diff --git a/ssh-gss.h b/ssh-gss.h -index 6593e422..245178af 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -83,7 +82,7 @@ typedef struct ssh_gssapi_mech_struct { - int (*dochild) (ssh_gssapi_client *); - int (*userok) (ssh_gssapi_client *, char *); - int (*localname) (ssh_gssapi_client *, char **); -- void (*storecreds) (ssh_gssapi_client *); -+ int (*storecreds) (ssh_gssapi_client *); - int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); - } ssh_gssapi_mech; - -@@ -127,7 +126,7 @@ int ssh_gssapi_userok(char *name); - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); --void ssh_gssapi_storecreds(void); -+int ssh_gssapi_storecreds(void); - const char *ssh_gssapi_displayname(void); - - char *ssh_gssapi_server_mechanisms(void); -diff --git a/sshd.c b/sshd.c -index edbe815c..89514e8a 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2162,7 +2162,7 @@ main(int ac, char **av) +diff -up openssh-8.6p1/sshd.c.ccache_name openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.ccache_name 2021-05-06 11:15:36.380143602 +0200 ++++ openssh-8.6p1/sshd.c 2021-05-06 11:15:36.398143736 +0200 +@@ -2284,7 +2284,7 @@ main(int ac, char **av) #ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(authctxt->pw); @@ -626,11 +592,10 @@ index edbe815c..89514e8a 100644 restore_uid(); } #endif -diff --git a/sshd_config.5 b/sshd_config.5 -index c0683d4a..2349f477 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -860,6 +860,14 @@ Specifies whether to automatically destroy the user's ticket cache +diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5 +--- openssh-8.6p1/sshd_config.5.ccache_name 2021-05-06 11:15:36.380143602 +0200 ++++ openssh-8.6p1/sshd_config.5 2021-05-06 11:15:36.398143736 +0200 +@@ -939,6 +939,14 @@ Specifies whether to automatically destr file on logout. The default is .Cm yes . @@ -645,3 +610,24 @@ index c0683d4a..2349f477 100644 .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. +diff -up openssh-8.6p1/ssh-gss.h.ccache_name openssh-8.6p1/ssh-gss.h +--- openssh-8.6p1/ssh-gss.h.ccache_name 2021-05-06 11:15:36.384143632 +0200 ++++ openssh-8.6p1/ssh-gss.h 2021-05-06 11:15:36.398143736 +0200 +@@ -114,7 +114,7 @@ typedef struct ssh_gssapi_mech_struct { + int (*dochild) (ssh_gssapi_client *); + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); +- void (*storecreds) (ssh_gssapi_client *); ++ int (*storecreds) (ssh_gssapi_client *); + int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + +@@ -175,7 +175,7 @@ int ssh_gssapi_userok(char *name, struct + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); +-void ssh_gssapi_storecreds(void); ++int ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); + + char *ssh_gssapi_server_mechanisms(void); diff --git a/openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch index d4c53db..519ee29 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -1,7 +1,7 @@ -diff --git a/sshd.c b/sshd.c ---- a/sshd.c -+++ b/sshd.c -@@ -1701,6 +1701,10 @@ main(int ac, char **av) +diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.log-usepam-no 2021-04-19 14:00:45.099735129 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 14:03:21.140920974 +0200 +@@ -1749,6 +1749,10 @@ main(int ac, char **av) parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, cfg, &includes, NULL); @@ -9,13 +9,13 @@ diff --git a/sshd.c b/sshd.c + if (! options.use_pam) + logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems."); + - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); - -diff --git a/sshd_config b/sshd_config ---- a/sshd_config -+++ b/sshd_config -@@ -101,6 +101,8 @@ GSSAPICleanupCredentials no + #ifdef WITH_OPENSSL + if (options.moduli_file != NULL) + dh_set_moduli_file(options.moduli_file); +diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config +--- openssh-8.6p1/sshd_config.log-usepam-no 2021-04-19 14:00:45.098735121 +0200 ++++ openssh-8.6p1/sshd_config 2021-04-19 14:00:45.099735129 +0200 +@@ -87,6 +87,8 @@ AuthorizedKeysFile .ssh/authorized_keys # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication # and ChallengeResponseAuthentication to 'no'. diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 813b7ac..4baa024 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,7 +1,7 @@ -diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 ---- openssh-8.2p1/ssh_config.5.crypto-policies 2020-03-26 14:40:44.546775605 +0100 -+++ openssh-8.2p1/ssh_config.5 2020-03-26 14:52:20.700649727 +0100 -@@ -359,14 +359,13 @@ or +diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5 +--- openssh-8.6p1/ssh_config.5.crypto-policies 2021-04-19 15:18:32.071920379 +0200 ++++ openssh-8.6p1/ssh_config.5 2021-04-19 15:21:18.400179265 +0200 +@@ -368,15 +368,13 @@ or .Qq *.c.example.com domains. .It Cm CASignatureAlgorithms @@ -14,14 +14,15 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 by certificate authorities (CAs). -The default is: -.Bd -literal -offset indent --ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384, --ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com, +-rsa-sha2-512,rsa-sha2-256 -.Ed -.Pp .Xr ssh 1 will not accept host certificates signed using algorithms other than those specified. -@@ -424,20 +424,25 @@ If the option is set to +@@ -436,20 +434,25 @@ If the option is set to (the default), the check will not be executed. .It Cm Ciphers @@ -51,7 +52,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 .Pp The supported ciphers are: .Bd -literal -offset indent -@@ -453,13 +458,6 @@ aes256-gcm@openssh.com +@@ -465,13 +468,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .Ed .Pp @@ -65,7 +66,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClearAllForwardings -@@ -812,6 +810,11 @@ command line will be passed untouched to +@@ -826,6 +822,11 @@ command line will be passed untouched to The default is .Dq no . .It Cm GSSAPIKexAlgorithms @@ -77,7 +78,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 The list of key exchange algorithms that are offered for GSSAPI key exchange. Possible values are .Bd -literal -offset 3n -@@ -824,10 +827,8 @@ gss-nistp256-sha256-, +@@ -838,10 +839,8 @@ gss-nistp256-sha256-, gss-curve25519-sha256- .Ed .Pp @@ -89,7 +90,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -@@ -1149,29 +1150,25 @@ it may be zero or more of: +@@ -1169,29 +1168,25 @@ it may be zero or more of: and .Cm pam . .It Cm KexAlgorithms @@ -128,7 +129,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 .Pp The list of available key exchange algorithms may also be obtained using .Qq ssh -Q kex . -@@ -1231,37 +1228,33 @@ The default is INFO. +@@ -1301,37 +1296,33 @@ function, and all code in the file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -175,7 +176,7 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm NoHostAuthenticationForLocalhost -@@ -1394,37 +1387,25 @@ instead of continuing to execute and pas +@@ -1503,37 +1494,25 @@ instead of continuing to execute and pas The default is .Cm no . .It Cm PubkeyAcceptedAlgorithms @@ -222,10 +223,10 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 .Pp The list of available signature algorithms may also be obtained using .Qq ssh -Q PubkeyAcceptedAlgorithms . -diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 ---- openssh-8.2p1/sshd_config.5.crypto-policies 2020-03-26 14:40:44.530775355 +0100 -+++ openssh-8.2p1/sshd_config.5 2020-03-26 14:48:56.732468099 +0100 -@@ -375,14 +375,13 @@ If the argument is +diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5 +--- openssh-8.6p1/sshd_config.5.crypto-policies 2021-04-19 15:18:32.062920311 +0200 ++++ openssh-8.6p1/sshd_config.5 2021-04-19 15:20:42.591908243 +0200 +@@ -373,15 +373,13 @@ If the argument is then no banner is displayed. By default, no banner is displayed. .It Cm CASignatureAlgorithms @@ -238,14 +239,15 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 by certificate authorities (CAs). -The default is: -.Bd -literal -offset indent --ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384, --ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com, +-rsa-sha2-512,rsa-sha2-256 -.Ed -.Pp Certificates signed using other algorithms will not be accepted for public key or host-based authentication. .It Cm ChallengeResponseAuthentication -@@ -446,20 +446,25 @@ The default is +@@ -445,20 +443,25 @@ The default is indicating not to .Xr chroot 2 . .It Cm Ciphers @@ -275,7 +277,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 .Pp The supported ciphers are: .Pp -@@ -486,13 +491,6 @@ aes256-gcm@openssh.com +@@ -485,13 +488,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .El .Pp @@ -289,7 +291,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The list of available ciphers may also be obtained using .Qq ssh -Q cipher . .It Cm ClientAliveCountMax -@@ -681,21 +679,22 @@ For this to work +@@ -680,21 +676,22 @@ For this to work .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -322,7 +324,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 This option only applies to connections using GSSAPI. .It Cm HostbasedAcceptedAlgorithms Specifies the signature algorithms that will be accepted for hostbased -@@ -793,26 +793,13 @@ is specified, the location of the socket +@@ -794,26 +791,13 @@ is specified, the location of the socket .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms @@ -354,7 +356,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The list of available signature algorithms may also be obtained using .Qq ssh -Q HostKeyAlgorithms . .It Cm IgnoreRhosts -@@ -943,20 +931,25 @@ Specifies whether to look at .k5login fi +@@ -958,20 +942,25 @@ Specifies whether to look at .k5login fi The default is .Cm yes . .It Cm KexAlgorithms @@ -384,7 +386,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The supported algorithms are: .Pp .Bl -item -compact -offset indent -@@ -988,15 +981,6 @@ ecdh-sha2-nistp521 +@@ -1003,15 +992,6 @@ ecdh-sha2-nistp521 sntrup761x25519-sha512@openssh.com .El .Pp @@ -400,7 +402,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The list of available key exchange algorithms may also be obtained using .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress -@@ -1065,21 +1049,26 @@ DEBUG and DEBUG1 are equivalent. +@@ -1097,21 +1077,26 @@ function, and all code in the file. This option is intended for debugging and no overrides are enabled by default. .It Cm MACs @@ -431,7 +433,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 .Pp The algorithms that contain .Qq -etm -@@ -1122,15 +1111,6 @@ umac-64-etm@openssh.com +@@ -1154,15 +1139,6 @@ umac-64-etm@openssh.com umac-128-etm@openssh.com .El .Pp @@ -447,7 +449,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . .It Cm Match -@@ -1480,37 +1460,25 @@ or equivalent.) +@@ -1541,37 +1517,25 @@ or equivalent.) The default is .Cm yes . .It Cm PubkeyAcceptedAlgorithms diff --git a/openssh-8.0p1-keygen-strip-doseol.patch b/openssh-8.0p1-keygen-strip-doseol.patch new file mode 100644 index 0000000..3117a7a --- /dev/null +++ b/openssh-8.0p1-keygen-strip-doseol.patch @@ -0,0 +1,12 @@ +diff -up openssh-8.0p1/ssh-keygen.c.strip-doseol openssh-8.0p1/ssh-keygen.c +--- openssh-8.0p1/ssh-keygen.c.strip-doseol 2021-03-18 17:41:34.472404994 +0100 ++++ openssh-8.0p1/ssh-keygen.c 2021-03-18 17:41:55.255538761 +0100 +@@ -901,7 +901,7 @@ do_fingerprint(struct passwd *pw) + while (getline(&line, &linesize, f) != -1) { + lnum++; + cp = line; +- cp[strcspn(cp, "\n")] = '\0'; ++ cp[strcspn(cp, "\r\n")] = '\0'; + /* Trim leading space and comments */ + cp = line + strspn(line, " \t"); + if (*cp == '#' || *cp == '\0') diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 748ab48..000df67 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,112 +1,7 @@ -commit ed3eaf7d68c083b6015ca3425b75932999dafaad -Author: Jakub Jelen -Date: Wed Apr 24 17:23:21 2019 +0200 - - PKCS#11 URI from Fedora - - * Print PKCS#11 URIs from ssh-keygen - * Accept PKCS#11 URIs in -i argument to ssh - * Allow PKCS#11 URI specification in ssh_config - * Fallback to p11-kit-proxy - * PKCS#11 URI support for ssh-add and ssh-agent - * internal representation is URI - * Allow to specify pin-value in URI to avoid interactive prompts - - Currently recognized and used parts of PKCS#11 URI: - * path (optional) - * token - * id - * manufacturer - * (library-manufacturer) - * query (optional) - * module-path - * pin-value - - Unit test for PKCS#11 URIs - - * test PKCS#11 URI parser, generator - * test percent_encodeer and decoder - - Regression tests for PKCS#11 URI support - - * soft-pkcs11.so from people.su.se/~lha/soft-pkcs11 - * Return correct CKR for unknown attributes - * Adjust and build it with regress tests (allowing agent-pkcs11 test) - * Test PKCS#11 URIs support with soft-pkcs11 - * Direct usage from commandline (URI, provider and combination) - * Usage from configuration files - * Usage in ssh-agent (add, sign, remove) - * Make sure it is built with correct paths - -diff --git a/Makefile.in b/Makefile.in -index e7549470..4511f82a 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -102,7 +102,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 \ -- ssh-pkcs11.o smult_curve25519_ref.o \ -+ 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 \ -@@ -289,6 +289,8 @@ clean: regressclean - rm -f regress/unittests/match/test_match$(EXEEXT) - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8$(EXEEXT) -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) - rm -f regress/misc/sk-dummy/*.o - rm -f regress/misc/sk-dummy/*.lo - rm -f regress/misc/sk-dummy/sk-dummy.so -@@ -322,6 +324,8 @@ distclean: regressclean - rm -f regress/unittests/match/test_match - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8 -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11 - (cd openbsd-compat && $(MAKE) distclean) - if test -d pkg ; then \ - rm -fr pkg ; \ -@@ -490,6 +494,7 @@ regress-prep: - $(MKDIR_P) `pwd`/regress/unittests/kex - $(MKDIR_P) `pwd`/regress/unittests/match - $(MKDIR_P) `pwd`/regress/unittests/utf8 -+ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 - $(MKDIR_P) `pwd`/regress/misc/sk-dummy - [ -f `pwd`/regress/Makefile ] || \ - ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -617,6 +622,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ - regress/unittests/test_helper/libtest_helper.a \ - -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) - -+UNITTESTS_TEST_PKCS11_OBJS=\ -+ regress/unittests/pkcs11/tests.o -+ -+regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ -+ ${UNITTESTS_TEST_PKCS11_OBJS} \ -+ 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) -+ - # These all need to be compiled -fPIC, so they are treated differently. - SK_DUMMY_OBJS=\ - regress/misc/sk-dummy/sk-dummy.lo \ -@@ -655,6 +670,7 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ - regress/unittests/kex/test_kex$(EXEEXT) \ - regress/unittests/match/test_match$(EXEEXT) \ - regress/unittests/utf8/test_utf8$(EXEEXT) \ -+ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ - - tests: file-tests t-exec interop-tests unit - echo all tests passed -diff --git a/configure.ac b/configure.ac -index b689db4b..98d3ce4f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1911,12 +1911,14 @@ AC_LINK_IFELSE( +diff -up openssh-8.6p1/configure.ac.pkcs11-uri openssh-8.6p1/configure.ac +--- openssh-8.6p1/configure.ac.pkcs11-uri 2021-05-06 11:35:55.101653187 +0200 ++++ openssh-8.6p1/configure.ac 2021-05-06 11:35:55.111653265 +0200 +@@ -1974,12 +1974,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -121,7 +16,7 @@ index b689db4b..98d3ce4f 100644 fi ] ) -@@ -1945,6 +1947,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2008,6 +2010,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -162,7 +57,7 @@ index b689db4b..98d3ce4f 100644 # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5401,6 +5437,7 @@ echo " BSD Auth support: $BSD_AUTH_MSG" +@@ -5564,6 +5600,7 @@ echo " BSD Auth support echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -170,32 +65,72 @@ index b689db4b..98d3ce4f 100644 echo " U2F/FIDO support: $enable_sk" echo "" -diff --git a/regress/Makefile b/regress/Makefile -index 774c10d4..6bf3b627 100644 ---- a/regress/Makefile -+++ b/regress/Makefile -@@ -116,7 +116,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ - known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ - modpipe netcat no_identity_config \ - pidfile putty.rsa2 ready regress.log remote_pid \ -- revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa_ssh2_cr.prv \ -+ revoked-* rsa rsa-agent rsa-agent.pub rsa-agent-cert.pub \ -+ rsa.pub rsa_ssh2_cr.prv pkcs11*.crt pkcs11*.key pkcs11.info \ - 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 \ -@@ -246,6 +247,7 @@ unit: - V="" ; \ - test "x${USE_VALGRIND}" = "x" || \ - V=${.CURDIR}/valgrind-unit.sh ; \ -+ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ - $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ - $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ - -d ${.CURDIR}/unittests/sshkey/testdata ; \ -diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh -index fbbaea51..5d75d69f 100644 ---- a/regress/agent-pkcs11.sh -+++ b/regress/agent-pkcs11.sh +diff -up openssh-8.6p1/Makefile.in.pkcs11-uri openssh-8.6p1/Makefile.in +--- openssh-8.6p1/Makefile.in.pkcs11-uri 2021-05-06 11:35:55.054652818 +0200 ++++ openssh-8.6p1/Makefile.in 2021-05-06 11:58:16.895135904 +0200 +@@ -103,7 +103,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 \ +- ssh-pkcs11.o smult_curve25519_ref.o \ ++ 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 \ +@@ -300,6 +300,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) ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) + rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/sk-dummy/sk-dummy.so +@@ -337,6 +339,8 @@ distclean: regressclean + rm -f regress/unittests/sshsig/test_sshsig + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8 ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11 + (cd openbsd-compat && $(MAKE) distclean) + if test -d pkg ; then \ + rm -fr pkg ; \ +@@ -511,6 +515,7 @@ regress-prep: + $(MKDIR_P) `pwd`/regress/unittests/sshkey + $(MKDIR_P) `pwd`/regress/unittests/sshsig + $(MKDIR_P) `pwd`/regress/unittests/utf8 ++ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 + $(MKDIR_P) `pwd`/regress/misc/sk-dummy + [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile +@@ -674,6 +679,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ++UNITTESTS_TEST_PKCS11_OBJS=\ ++ regress/unittests/pkcs11/tests.o ++ ++regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} \ ++ 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) ++ + # These all need to be compiled -fPIC, so they are treated differently. + SK_DUMMY_OBJS=\ + regress/misc/sk-dummy/sk-dummy.lo \ +@@ -709,6 +724,7 @@ regress-unit-binaries: regress-prep $(RE + regress/unittests/sshkey/test_sshkey$(EXEEXT) \ + regress/unittests/sshsig/test_sshsig$(EXEEXT) \ + regress/unittests/utf8/test_utf8$(EXEEXT) \ ++ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ + + tests: file-tests t-exec interop-tests unit + echo all tests passed +diff -up openssh-8.6p1/regress/agent-pkcs11.sh.pkcs11-uri openssh-8.6p1/regress/agent-pkcs11.sh +--- openssh-8.6p1/regress/agent-pkcs11.sh.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/regress/agent-pkcs11.sh 2021-05-06 11:35:55.112653273 +0200 @@ -113,7 +113,7 @@ else done @@ -205,11 +140,30 @@ index fbbaea51..5d75d69f 100644 r=$? if [ $r -ne 0 ]; then fail "ssh-add -e failed: exit code $r" -diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh -new file mode 100644 -index 00000000..a91aee94 ---- /dev/null -+++ b/regress/pkcs11.sh +diff -up openssh-8.6p1/regress/Makefile.pkcs11-uri openssh-8.6p1/regress/Makefile +--- openssh-8.6p1/regress/Makefile.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/regress/Makefile 2021-05-06 11:59:24.465658383 +0200 +@@ -119,7 +119,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 \ +- revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa_ssh2_cr.prv \ ++ revoked-* rsa rsa-agent rsa-agent.pub rsa-agent-cert.pub \ ++ rsa.pub rsa_ssh2_cr.prv pkcs11*.crt pkcs11*.key pkcs11.info \ + 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 \ +@@ -249,6 +250,7 @@ unit: + V="" ; \ + test "x${USE_VALGRIND}" = "x" || \ + V=${.CURDIR}/valgrind-unit.sh ; \ ++ $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ + $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ + $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ + -d ${.CURDIR}/unittests/sshkey/testdata ; \ +diff -up openssh-8.6p1/regress/pkcs11.sh.pkcs11-uri openssh-8.6p1/regress/pkcs11.sh +--- openssh-8.6p1/regress/pkcs11.sh.pkcs11-uri 2021-05-06 11:35:55.112653273 +0200 ++++ openssh-8.6p1/regress/pkcs11.sh 2021-05-06 11:35:55.112653273 +0200 @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -560,10 +514,9 @@ index 00000000..a91aee94 + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile -index 4e56e110..2690ebeb 100644 ---- a/regress/unittests/Makefile -+++ b/regress/unittests/Makefile +diff -up openssh-8.6p1/regress/unittests/Makefile.pkcs11-uri openssh-8.6p1/regress/unittests/Makefile +--- openssh-8.6p1/regress/unittests/Makefile.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/regress/unittests/Makefile 2021-05-06 11:35:55.112653273 +0200 @@ -2,6 +2,6 @@ REGRESS_FAIL_EARLY?= yes @@ -572,11 +525,9 @@ index 4e56e110..2690ebeb 100644 +SUBDIR+=authopt misc sshsig pkcs11 .include -diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c -new file mode 100644 -index 00000000..b637cb13 ---- /dev/null -+++ b/regress/unittests/pkcs11/tests.c +diff -up openssh-8.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.6p1/regress/unittests/pkcs11/tests.c +--- openssh-8.6p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-05-06 11:35:55.112653273 +0200 ++++ openssh-8.6p1/regress/unittests/pkcs11/tests.c 2021-05-06 11:35:55.112653273 +0200 @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2017 Red Hat @@ -915,11 +866,10 @@ index 00000000..b637cb13 + test_parse_invalid(); + test_generate_valid(); +} -diff --git a/ssh-add.c b/ssh-add.c -index 8057eb1f..0c470e32 100644 ---- a/ssh-add.c -+++ b/ssh-add.c -@@ -67,6 +67,7 @@ +diff -up openssh-8.6p1/ssh-add.c.pkcs11-uri openssh-8.6p1/ssh-add.c +--- openssh-8.6p1/ssh-add.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-add.c 2021-05-06 11:35:55.112653273 +0200 +@@ -68,6 +68,7 @@ #include "digest.h" #include "ssh-sk.h" #include "sk-api.h" @@ -927,7 +877,7 @@ index 8057eb1f..0c470e32 100644 /* argv0 */ extern char *__progname; -@@ -193,6 +194,32 @@ delete_all(int agent_fd, int qflag) +@@ -229,6 +230,32 @@ delete_all(int agent_fd, int qflag) return ret; } @@ -960,7 +910,7 @@ index 8057eb1f..0c470e32 100644 static int add_file(int agent_fd, const char *filename, int key_only, int qflag, const char *skprovider) -@@ -402,12 +429,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag, +@@ -445,12 +472,11 @@ add_file(int agent_fd, const char *filen } static int @@ -975,7 +925,7 @@ index 8057eb1f..0c470e32 100644 if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -591,6 +617,13 @@ static int +@@ -630,6 +656,13 @@ static int do_file(int agent_fd, int deleting, int key_only, char *file, int qflag, const char *skprovider) { @@ -989,7 +939,7 @@ index 8057eb1f..0c470e32 100644 if (deleting) { if (delete_file(agent_fd, file, key_only, qflag) == -1) return -1; -@@ -773,7 +806,7 @@ main(int argc, char **argv) +@@ -813,7 +846,7 @@ main(int argc, char **argv) } if (pkcs11provider != NULL) { if (update_card(agent_fd, !deleting, pkcs11provider, @@ -998,11 +948,10 @@ index 8057eb1f..0c470e32 100644 ret = 1; goto done; } -diff --git a/ssh-agent.c b/ssh-agent.c -index 7eb6f0dc..27d8e4af 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -641,10 +641,72 @@ no_identities(SocketEntry *e) +diff -up openssh-8.6p1/ssh-agent.c.pkcs11-uri openssh-8.6p1/ssh-agent.c +--- openssh-8.6p1/ssh-agent.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-agent.c 2021-05-06 11:35:55.113653281 +0200 +@@ -847,10 +847,72 @@ no_identities(SocketEntry *e) } #ifdef ENABLE_PKCS11 @@ -1076,7 +1025,7 @@ index 7eb6f0dc..27d8e4af 100644 char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; u_int seconds = 0; -@@ -681,33 +743,28 @@ process_add_smartcard_key(SocketEntry *e) +@@ -869,33 +931,28 @@ process_add_smartcard_key(SocketEntry *e error_f("failed to parse constraints"); goto send; } @@ -1118,7 +1067,7 @@ index 7eb6f0dc..27d8e4af 100644 } id->death = death; id->confirm = confirm; -@@ -721,6 +778,7 @@ process_add_smartcard_key(SocketEntry *e) +@@ -910,6 +967,7 @@ process_add_smartcard_key(SocketEntry *e send: free(pin); free(provider); @@ -1126,7 +1075,7 @@ index 7eb6f0dc..27d8e4af 100644 free(keys); free(comments); send_status(e, success); -@@ -729,7 +787,7 @@ send: +@@ -918,7 +976,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1135,7 +1084,7 @@ index 7eb6f0dc..27d8e4af 100644 int r, success = 0; Identity *id, *nxt; -@@ -740,30 +798,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -930,30 +988,29 @@ process_remove_smartcard_key(SocketEntry } free(pin); @@ -1172,11 +1121,185 @@ index 7eb6f0dc..27d8e4af 100644 send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 0d6ed1ff..182f4f2b 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -855,8 +855,11 @@ do_download(struct passwd *pw) +diff -up openssh-8.6p1/ssh_config.5.pkcs11-uri openssh-8.6p1/ssh_config.5 +--- openssh-8.6p1/ssh_config.5.pkcs11-uri 2021-05-06 11:35:55.061652873 +0200 ++++ openssh-8.6p1/ssh_config.5 2021-05-06 11:35:55.116653304 +0200 +@@ -1063,6 +1063,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-8.6p1/ssh.c.pkcs11-uri openssh-8.6p1/ssh.c +--- openssh-8.6p1/ssh.c.pkcs11-uri 2021-05-06 11:35:55.060652865 +0200 ++++ openssh-8.6p1/ssh.c 2021-05-06 12:00:07.129988275 +0200 +@@ -843,6 +843,14 @@ main(int ac, char **av) + options.gss_deleg_creds = 1; + break; + case 'i': ++#ifdef ENABLE_PKCS11 ++ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(optarg, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ add_identity_file(&options, NULL, optarg, 1); ++ break; ++ } ++#endif + p = tilde_expand_filename(optarg, getuid()); + if (stat(p, &st) == -1) + fprintf(stderr, "Warning: Identity file %s " +@@ -1695,6 +1703,7 @@ main(int ac, char **av) + #ifdef ENABLE_PKCS11 + (void)pkcs11_del_provider(options.pkcs11_provider); + #endif ++ pkcs11_terminate(); + + skip_connect: + exit_status = ssh_session2(ssh, cinfo); +@@ -2211,6 +2220,45 @@ ssh_session2(struct ssh *ssh, const stru + options.escape_char : SSH_ESCAPECHAR_NONE, id); + } + ++#ifdef ENABLE_PKCS11 ++static void ++load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], ++ struct sshkey *identity_keys[], int *n_ids) ++{ ++ int nkeys, i; ++ struct sshkey **keys; ++ struct pkcs11_uri *uri; ++ ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++ ++ /* we need to merge URI and provider together */ ++ if (options.pkcs11_provider != NULL && uri->module_path == NULL) ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && ++ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { ++ for (i = 0; i < nkeys; i++) { ++ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { ++ sshkey_free(keys[i]); ++ continue; ++ } ++ identity_keys[*n_ids] = keys[i]; ++ identity_files[*n_ids] = pkcs11_uri_get(uri); ++ (*n_ids)++; ++ } ++ free(keys); ++ } ++ ++ pkcs11_uri_cleanup(uri); ++} ++#endif /* ENABLE_PKCS11 */ ++ + /* Loads all IdentityFile and CertificateFile keys */ + static void + load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2225,11 +2273,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]; +-#ifdef ENABLE_PKCS11 +- struct sshkey **keys = NULL; +- char **comments = NULL; +- int nkeys; +-#endif /* PKCS11 */ + + n_ids = n_certs = 0; + memset(identity_files, 0, sizeof(identity_files)); +@@ -2242,33 +2285,46 @@ load_public_identity_files(const struct + sizeof(certificate_file_userprovided)); + + #ifdef ENABLE_PKCS11 +- if (options.pkcs11_provider != NULL && +- options.num_identity_files < SSH_MAX_IDENTITY_FILES && +- (pkcs11_init(!options.batch_mode) == 0) && +- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, +- &keys, &comments)) > 0) { +- for (i = 0; i < nkeys; i++) { +- if (n_ids >= SSH_MAX_IDENTITY_FILES) { +- sshkey_free(keys[i]); +- free(comments[i]); +- continue; +- } +- identity_keys[n_ids] = keys[i]; +- identity_files[n_ids] = comments[i]; /* transferred */ +- n_ids++; +- } +- free(keys); +- free(comments); ++ /* handle fallback from PKCS11Provider option */ ++ pkcs11_init(!options.batch_mode); ++ ++ if (options.pkcs11_provider != NULL) { ++ struct pkcs11_uri *uri; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ /* Construct simple PKCS#11 URI to simplify access */ ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ /* Add it as any other IdentityFile */ ++ cp = pkcs11_uri_get(uri); ++ add_identity_file(&options, NULL, cp, 1); ++ free(cp); ++ ++ pkcs11_uri_cleanup(uri); + } + #endif /* ENABLE_PKCS11 */ + for (i = 0; i < options.num_identity_files; i++) { ++ char *name = options.identity_files[i]; + if (n_ids >= SSH_MAX_IDENTITY_FILES || +- strcasecmp(options.identity_files[i], "none") == 0) { ++ strcasecmp(name, "none") == 0) { + free(options.identity_files[i]); + options.identity_files[i] = NULL; + continue; + } +- cp = tilde_expand_filename(options.identity_files[i], getuid()); ++#ifdef ENABLE_PKCS11 ++ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(name, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ load_pkcs11_identity(name, identity_files, ++ identity_keys, &n_ids); ++ free(options.identity_files[i]); ++ continue; ++ } ++#endif /* ENABLE_PKCS11 */ ++ cp = tilde_expand_filename(name, getuid()); + filename = default_client_percent_dollar_expand(cp, cinfo); + free(cp); + check_load(sshkey_load_public(filename, &public, NULL), +diff -up openssh-8.6p1/ssh-keygen.c.pkcs11-uri openssh-8.6p1/ssh-keygen.c +--- openssh-8.6p1/ssh-keygen.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-keygen.c 2021-05-06 11:35:55.114653289 +0200 +@@ -860,8 +860,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1190,11 +1313,10 @@ index 0d6ed1ff..182f4f2b 100644 } free(comments[i]); sshkey_free(keys[i]); -diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c -index 8a0ffef5..ead8a562 100644 ---- a/ssh-pkcs11-client.c -+++ b/ssh-pkcs11-client.c -@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, +diff -up openssh-8.6p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11-client.c +--- openssh-8.6p1/ssh-pkcs11-client.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-pkcs11-client.c 2021-05-06 11:35:55.114653289 +0200 +@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pi u_int nkeys, i; struct sshbuf *msg; @@ -1203,7 +1325,7 @@ index 8a0ffef5..ead8a562 100644 if (fd < 0 && pkcs11_start_helper() < 0) return (-1); -@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, +@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pi *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); @@ -1211,11 +1333,1258 @@ index 8a0ffef5..ead8a562 100644 for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c -new file mode 100644 -index 00000000..e1a7b4e0 ---- /dev/null -+++ b/ssh-pkcs11-uri.c +diff -up openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11.c +--- openssh-8.6p1/ssh-pkcs11.c.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-pkcs11.c 2021-05-06 11:35:55.115653297 +0200 +@@ -55,8 +55,8 @@ struct pkcs11_slotinfo { + int logged_in; + }; + +-struct pkcs11_provider { +- char *name; ++struct pkcs11_module { ++ char *module_path; + void *handle; + CK_FUNCTION_LIST *function_list; + CK_INFO info; +@@ -65,6 +65,13 @@ struct pkcs11_provider { + struct pkcs11_slotinfo *slotinfo; + int valid; + int refcount; ++}; ++ ++struct pkcs11_provider { ++ char *name; ++ struct pkcs11_module *module; /* can be shared between various providers */ ++ int refcount; ++ int valid; + TAILQ_ENTRY(pkcs11_provider) next; + }; + +@@ -75,6 +82,7 @@ struct pkcs11_key { + CK_ULONG slotidx; + char *keyid; + int keyid_len; ++ char *label; + }; + + int pkcs11_interactive = 0; +@@ -106,26 +114,61 @@ pkcs11_init(int interactive) + * this is called when a provider gets unregistered. + */ + static void +-pkcs11_provider_finalize(struct pkcs11_provider *p) ++pkcs11_module_finalize(struct pkcs11_module *m) + { + CK_RV rv; + CK_ULONG i; + +- debug("pkcs11_provider_finalize: %p refcount %d valid %d", +- p, p->refcount, p->valid); +- if (!p->valid) ++ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); ++ if (!m->valid) + return; +- for (i = 0; i < p->nslots; i++) { +- if (p->slotinfo[i].session && +- (rv = p->function_list->C_CloseSession( +- p->slotinfo[i].session)) != CKR_OK) ++ for (i = 0; i < m->nslots; i++) { ++ if (m->slotinfo[i].session && ++ (rv = m->function_list->C_CloseSession( ++ m->slotinfo[i].session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + } +- 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); ++ m->valid = 0; ++ m->function_list = NULL; ++ dlclose(m->handle); ++} ++ ++/* ++ * remove a reference to the pkcs11 module. ++ * called when a provider is unregistered. ++ */ ++static void ++pkcs11_module_unref(struct pkcs11_module *m) ++{ ++ debug_f("%p refcount %d", m, m->refcount); ++ if (--m->refcount <= 0) { ++ pkcs11_module_finalize(m); ++ if (m->valid) ++ error_f("%p still valid", m); ++ free(m->slotlist); ++ free(m->slotinfo); ++ free(m->module_path); ++ free(m); ++ } ++} ++ ++/* ++ * finalize a provider shared libarary, it's no longer usable. ++ * however, there might still be keys referencing this provider, ++ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). ++ * this is called when a provider gets unregistered. ++ */ ++static void ++pkcs11_provider_finalize(struct pkcs11_provider *p) ++{ ++ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); ++ if (!p->valid) ++ return; ++ pkcs11_module_unref(p->module); ++ p->module = NULL; + p->valid = 0; +- p->function_list = NULL; +- dlclose(p->handle); + } + + /* +@@ -135,13 +178,11 @@ pkcs11_provider_finalize(struct pkcs11_p + static void + pkcs11_provider_unref(struct pkcs11_provider *p) + { +- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); ++ debug_f("%p refcount %d", p, p->refcount); + if (--p->refcount <= 0) { +- if (p->valid) +- error("pkcs11_provider_unref: %p still valid", p); + free(p->name); +- free(p->slotlist); +- free(p->slotinfo); ++ if (p->module) ++ pkcs11_module_unref(p->module); + free(p); + } + } +@@ -159,6 +200,20 @@ pkcs11_terminate(void) + } + } + ++/* lookup provider by module path */ ++static struct pkcs11_module * ++pkcs11_provider_lookup_module(char *module_path) ++{ ++ struct pkcs11_provider *p; ++ ++ TAILQ_FOREACH(p, &pkcs11_providers, next) { ++ debug("check %p %s (%s)", p, p->name, p->module->module_path); ++ if (!strcmp(module_path, p->module->module_path)) ++ return (p->module); ++ } ++ return (NULL); ++} ++ + /* lookup provider by name */ + static struct pkcs11_provider * + pkcs11_provider_lookup(char *provider_id) +@@ -173,19 +228,55 @@ pkcs11_provider_lookup(char *provider_id + return (NULL); + } + ++int pkcs11_del_provider_by_uri(struct pkcs11_uri *); ++ + /* unregister provider by name */ + int + pkcs11_del_provider(char *provider_id) + { ++ int rv; ++ struct pkcs11_uri *uri; ++ ++ debug_f("called, provider_id = %s", provider_id); ++ ++ if (provider_id == NULL) ++ return 0; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ rv = pkcs11_del_provider_by_uri(uri); ++ pkcs11_uri_cleanup(uri); ++ return rv; ++} ++ ++/* unregister provider by PKCS#11 URI */ ++int ++pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) ++{ + struct pkcs11_provider *p; ++ int rv = -1; ++ char *provider_uri = pkcs11_uri_get(uri); + +- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { ++ debug3_f("called with provider %s", provider_uri); ++ ++ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); +- return (0); ++ rv = 0; + } +- return (-1); ++ free(provider_uri); ++ return rv; + } + + static RSA_METHOD *rsa_method; +@@ -195,6 +283,55 @@ static EC_KEY_METHOD *ec_key_method; + static int ec_key_idx = 0; + #endif + ++/* ++ * This can't be in the ssh-pkcs11-uri, becase we can not depend on ++ * PKCS#11 structures in ssh-agent (using client-helper communication) ++ */ ++int ++pkcs11_uri_write(const struct sshkey *key, FILE *f) ++{ ++ char *p = NULL; ++ struct pkcs11_uri uri; ++ struct pkcs11_key *k11; ++ ++ /* sanity - is it a RSA key with associated app_data? */ ++ switch (key->type) { ++ case KEY_RSA: ++ k11 = RSA_get_ex_data(key->rsa, rsa_idx); ++ break; ++#ifdef HAVE_EC_KEY_METHOD_NEW ++ case KEY_ECDSA: ++ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); ++ break; ++#endif ++ default: ++ error("Unknown key type %d", key->type); ++ return -1; ++ } ++ if (k11 == NULL) { ++ error("Failed to get ex_data for key type %d", key->type); ++ return (-1); ++ } ++ ++ /* omit type -- we are looking for private-public or private-certificate pairs */ ++ uri.id = k11->keyid; ++ uri.id_len = k11->keyid_len; ++ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; ++ uri.object = k11->label; ++ uri.module_path = k11->provider->module->module_path; ++ uri.lib_manuf = k11->provider->module->info.manufacturerID; ++ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; ++ ++ p = pkcs11_uri_get(&uri); ++ /* do not cleanup -- we do not allocate here, only reference */ ++ if (p == NULL) ++ return -1; ++ ++ fprintf(f, " %s", p); ++ free(p); ++ return 0; ++} ++ + /* release a wrapped object */ + static void + pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, +@@ -208,6 +345,7 @@ pkcs11_k11_free(void *parent, void *ptr, + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); ++ free(k11->label); + free(k11); + } + +@@ -222,8 +360,8 @@ pkcs11_find(struct pkcs11_provider *p, C + CK_RV rv; + int ret = -1; + +- f = p->function_list; +- session = p->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ session = p->module->slotinfo[slotidx].session; + if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { + error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); + return (-1); +@@ -262,12 +400,12 @@ pkcs11_login_slot(struct pkcs11_provider + else { + snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", + si->token.label); +- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { ++ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { + debug_f("no pin specified"); + return (-1); /* bail out */ + } + } +- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, ++ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, + (pin != NULL) ? strlen(pin) : 0); + if (pin != NULL) + freezero(pin, strlen(pin)); +@@ -297,13 +435,14 @@ pkcs11_login_slot(struct pkcs11_provider + static int + pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) + { +- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { ++ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || ++ k11->provider->module == NULL || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + + return pkcs11_login_slot(k11->provider, +- &k11->provider->slotinfo[k11->slotidx], type); ++ &k11->provider->module->slotinfo[k11->slotidx], type); + } + + +@@ -319,13 +458,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs + + *val = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + attr.type = type; + attr.pValue = &flag; +@@ -356,13 +496,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C + int always_auth = 0; + int did_login = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { + if (pkcs11_login(k11, CKU_USER) < 0) { +@@ -439,8 +580,8 @@ pkcs11_rsa_private_encrypt(int flen, con + return (-1); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + tlen = RSA_size(rsa); + + /* XXX handle CKR_BUFFER_TOO_SMALL */ +@@ -484,7 +625,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, +- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) + { + struct pkcs11_key *k11; + +@@ -502,6 +643,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } + ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); ++ k11->label[label_attrib->ulValueLen] = 0; ++ } ++ + RSA_set_method(rsa, rsa_method); + RSA_set_ex_data(rsa, rsa_idx, k11); + return (0); +@@ -532,8 +679,8 @@ ecdsa_do_sign(const unsigned char *dgst, + return (NULL); + } + +- f = k11->provider->function_list; +- si = &k11->provider->slotinfo[k11->slotidx]; ++ f = k11->provider->module->function_list; ++ si = &k11->provider->module->slotinfo[k11->slotidx]; + + siglen = ECDSA_size(ec); + sig = xmalloc(siglen); +@@ -598,7 +745,7 @@ pkcs11_ecdsa_start_wrapper(void) + + static int + pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) ++ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ec) + { + struct pkcs11_key *k11; + +@@ -614,6 +761,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + ++ if (label_attrib->ulValueLen > 0 ) { ++ k11->label = xmalloc(label_attrib->ulValueLen+1); ++ 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); + +@@ -650,8 +803,8 @@ pkcs11_open_session(struct pkcs11_provid + CK_SESSION_HANDLE session; + int login_required, ret; + +- f = p->function_list; +- si = &p->slotinfo[slotidx]; ++ f = p->module->function_list; ++ si = &p->module->slotinfo[slotidx]; + + login_required = si->token.flags & CKF_LOGIN_REQUIRED; + +@@ -661,9 +814,9 @@ pkcs11_open_session(struct pkcs11_provid + error("pin required"); + return (-SSH_PKCS11_ERR_PIN_REQUIRED); + } +- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| ++ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| + CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { +- error("C_OpenSession failed: %lu", rv); ++ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); + return (-1); + } + if (login_required && pin != NULL && strlen(pin) != 0) { +@@ -699,7 +852,8 @@ static struct sshkey * + pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE key_attr[3]; ++ CK_ATTRIBUTE key_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -713,14 +867,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_EC_POINT; +- key_attr[2].type = CKA_EC_PARAMS; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_EC_POINT; ++ key_attr[3].type = CKA_EC_PARAMS; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -731,19 +886,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ if (key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + + /* retrieve ID, public point and curve parameters of EC key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; +@@ -755,8 +910,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + goto fail; + } + +- attrp = key_attr[2].pValue; +- group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); ++ attrp = key_attr[3].pValue; ++ group = d2i_ECPKParameters(NULL, &attrp, key_attr[3].ulValueLen); + if (group == NULL) { + ossl_error("d2i_ECPKParameters failed"); + goto fail; +@@ -767,13 +922,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + goto fail; + } + +- if (key_attr[1].ulValueLen <= 2) { ++ if (key_attr[2].ulValueLen <= 2) { + error("CKA_EC_POINT too small"); + goto fail; + } + +- attrp = key_attr[1].pValue; +- octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); ++ attrp = key_attr[2].pValue; ++ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[2].ulValueLen); + if (octet == NULL) { + ossl_error("d2i_ASN1_OCTET_STRING failed"); + goto fail; +@@ -790,7 +945,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + goto fail; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -806,7 +961,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + ec = NULL; /* now owned by key */ + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + if (ec) + EC_KEY_free(ec); +@@ -823,7 +978,8 @@ static struct sshkey * + pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) + { +- CK_ATTRIBUTE key_attr[3]; ++ CK_ATTRIBUTE key_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -834,14 +990,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; +- key_attr[1].type = CKA_MODULUS; +- key_attr[2].type = CKA_PUBLIC_EXPONENT; ++ key_attr[1].type = CKA_LABEL; ++ key_attr[2].type = CKA_MODULUS; ++ key_attr[3].type = CKA_PUBLIC_EXPONENT; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); +@@ -852,19 +1009,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ +- if (key_attr[1].ulValueLen == 0 || +- key_attr[2].ulValueLen == 0) { ++ if (key_attr[2].ulValueLen == 0 || ++ key_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + + /* retrieve ID, modulus and public exponent of RSA key */ +- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; +@@ -876,8 +1033,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + goto fail; + } + +- rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); +- rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_n = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); ++ rsa_e = BN_bin2bn(key_attr[3].pValue, key_attr[3].ulValueLen, NULL); + if (rsa_n == NULL || rsa_e == NULL) { + error("BN_bin2bn failed"); + goto fail; +@@ -886,7 +1043,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + fatal_f("set key"); + rsa_n = rsa_e = NULL; /* transferred */ + +- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) + goto fail; + + key = sshkey_new(KEY_UNSPEC); +@@ -901,7 +1058,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + rsa = NULL; /* now owned by key */ + + fail: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(key_attr[i].pValue); + RSA_free(rsa); + +@@ -912,7 +1069,8 @@ static int + pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) + { +- CK_ATTRIBUTE cert_attr[3]; ++ CK_ATTRIBUTE cert_attr[4]; ++ int nattr = 4; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -936,14 +1094,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + + memset(&cert_attr, 0, sizeof(cert_attr)); + cert_attr[0].type = CKA_ID; +- cert_attr[1].type = CKA_SUBJECT; +- cert_attr[2].type = CKA_VALUE; ++ cert_attr[1].type = CKA_LABEL; ++ cert_attr[2].type = CKA_SUBJECT; ++ cert_attr[3].type = CKA_VALUE; + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + + /* figure out size of the attributes */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return -1; +@@ -955,18 +1114,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + * XXX assumes CKA_ID is always first. + */ + if (cert_attr[1].ulValueLen == 0 || +- cert_attr[2].ulValueLen == 0) { ++ cert_attr[2].ulValueLen == 0 || ++ cert_attr[3].ulValueLen == 0) { + error("invalid attribute length"); + return -1; + } + + /* allocate buffers for attributes */ +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + if (cert_attr[i].ulValueLen > 0) + cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); + + /* retrieve ID, subject and value of certificate */ +- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); ++ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto out; +@@ -980,8 +1140,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + subject = xstrdup("invalid subject"); + X509_NAME_free(x509_name); + +- cp = cert_attr[2].pValue; +- if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { ++ cp = cert_attr[3].pValue; ++ if ((x509 = d2i_X509(NULL, &cp, cert_attr[3].ulValueLen)) == NULL) { + error("d2i_x509 failed"); + goto out; + } +@@ -1001,7 +1161,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + goto out; + } + +- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1031,7 +1191,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + goto out; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1051,7 +1211,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + goto out; + } + out: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(cert_attr[i].pValue); + X509_free(x509); + RSA_free(rsa); +@@ -1102,11 +1262,12 @@ note_key(struct pkcs11_provider *p, CK_U + */ + static int + pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[1]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1123,10 +1284,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; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } ++ ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1207,11 +1381,12 @@ fail: + */ + static int + pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[2]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1227,10 +1402,23 @@ pkcs11_fetch_keys(struct pkcs11_provider + 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; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } ++ ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1499,16 +1687,10 @@ pkcs11_ecdsa_generate_private_key(struct + } + #endif /* WITH_PKCS11_KEYGEN */ + +-/* +- * register a new provider, fails if provider already exists. if +- * keyp is provided, fetch keys. +- */ + static int +-pkcs11_register_provider(char *provider_id, char *pin, +- struct sshkey ***keyp, char ***labelsp, +- struct pkcs11_provider **providerp, CK_ULONG user) ++pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) + { +- int nkeys, need_finalize = 0; ++ int need_finalize = 0; + int ret = -1; + struct pkcs11_provider *p = NULL; + void *handle = NULL; +@@ -1517,164 +1699,298 @@ pkcs11_register_provider(char *provider_ + CK_FUNCTION_LIST *f = NULL; + CK_TOKEN_INFO *token; + CK_ULONG i; ++ char *provider_module = NULL; ++ struct pkcs11_module *m = NULL; + +- if (providerp == 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; ++#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); +- goto fail; ++ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL ++ && m->valid) { ++ debug_f("provider module already initialized: %s", provider_module); ++ free(provider_module); ++ /* Skip the initialization of PKCS#11 module */ ++ m->refcount++; ++ p->module = m; ++ p->valid = 1; ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ } else { ++ m = xcalloc(1, sizeof(*m)); ++ 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()); ++ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { ++ 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; + } +- 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) { + error("C_GetFunctionList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->function_list = f; ++ m->function_list = f; + if ((rv = f->C_Initialize(NULL)) != CKR_OK) { + error("C_Initialize for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } + need_finalize = 1; +- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { ++ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { + error("C_GetInfo for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strcmp(uri->lib_manuf, m->info.manufacturerID)) { ++ debug_f("Skipping provider %s not matching library_manufacturer", ++ m->info.manufacturerID); ++ goto fail; ++ } ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); + debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" + " libraryDescription <%s> libraryVersion %d.%d", +- provider_id, +- p->info.manufacturerID, +- p->info.cryptokiVersion.major, +- p->info.cryptokiVersion.minor, +- p->info.libraryDescription, +- p->info.libraryVersion.major, +- p->info.libraryVersion.minor); +- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ provider_module, ++ m->info.manufacturerID, ++ m->info.cryptokiVersion.major, ++ m->info.cryptokiVersion.minor, ++ m->info.libraryDescription, ++ m->info.libraryVersion.major, ++ m->info.libraryVersion.minor); ++ ++ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } +- if (p->nslots == 0) { +- debug_f("provider %s returned no slots", provider_id); ++ if (m->nslots == 0) { ++ debug_f("provider %s returned no slots", provider_module); + ret = -SSH_PKCS11_ERR_NO_SLOTS; + goto fail; + } +- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); +- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) ++ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); ++ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) + != CKR_OK) { + error("C_GetSlotList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->slotinfo = xcalloc(p->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; ++ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) + != CKR_OK) { + error("C_GetTokenInfo for provider %s slot %lu " +- "failed: %lu", provider_id, (u_long)i, rv); +- continue; +- } +- if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { +- debug2_f("ignoring uninitialised token in " +- "provider %s slot %lu", provider_id, (u_long)i); ++ "failed: %lu", provider_module, (u_long)i, rv); ++ 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)); ++ } ++ m->module_path = provider_module; ++ provider_module = NULL; ++ ++ /* insert unconditionally -- remove if there will be no keys later */ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ ++fail: ++ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) ++ error("C_Finalize for provider %s failed: %lu", ++ provider_module, rv); ++ free(provider_module); ++ if (m) { ++ free(m->slotlist); ++ free(m); ++ } ++ if (p) { ++ free(p->name); ++ free(p); ++ } ++ if (handle) ++ dlclose(handle); ++ return ret; ++} ++ ++/* ++ * register a new provider, fails if provider already exists. if ++ * keyp is provided, fetch keys. ++ */ ++static int ++pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, ++ CK_ULONG user) ++{ ++ int nkeys; ++ int ret = -1; ++ struct pkcs11_provider *p = NULL; ++ CK_ULONG i; ++ CK_TOKEN_INFO *token; ++ char *provider_uri = NULL; ++ ++ if (providerp == NULL) ++ goto fail; ++ *providerp = NULL; ++ ++ if (keyp != NULL) ++ *keyp = NULL; ++ ++ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { ++ goto fail; ++ } ++ ++ provider_uri = pkcs11_uri_get(uri); ++ if (pin == NULL && uri->pin != NULL) { ++ pin = uri->pin; ++ } ++ nkeys = 0; ++ for (i = 0; i < p->module->nslots; i++) { ++ token = &p->module->slotinfo[i].token; ++ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { ++ debug2_f("ignoring uninitialised token in " ++ "provider %s slot %lu", provider_uri, (u_long)i); ++ continue; ++ } ++ if (uri->token != NULL && ++ strcmp(token->label, uri->token) != 0) { ++ debug2_f("ignoring token not matching label (%s) " ++ "specified by PKCS#11 URI in slot %lu", ++ token->label, (unsigned long)i); ++ continue; ++ } ++ if (uri->manuf != NULL && ++ strcmp(token->manufacturerID, uri->manuf) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "manufacturerID (%s) specified by PKCS#11 URI in " ++ "slot %lu", token->manufacturerID, (unsigned long)i); ++ continue; ++ } + debug("provider %s slot %lu: label <%s> manufacturerID <%s> " + "model <%s> serial <%s> flags 0x%lx", +- provider_id, (unsigned long)i, ++ provider_uri, (unsigned long)i, + 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 ++ * retrieve public keys (if keyp is provided) + */ +- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || ++ if ((p->module->slotinfo[i].session != 0 || ++ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ + keyp == NULL) + continue; +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +- if (nkeys == 0 && !p->slotinfo[i].logged_in && ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && + pkcs11_interactive) { + /* + * Some tokens require login before they will + * expose keys. + */ +- if (pkcs11_login_slot(p, &p->slotinfo[i], ++ debug3_f("Trying to login as there were no keys found"); ++ if (pkcs11_login_slot(p, &p->module->slotinfo[i], + CKU_USER) < 0) { + error("login failed"); + continue; + } +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ } ++ if (nkeys == 0 && uri->object != NULL) { ++ debug3_f("No keys found. Retrying without label (%s) ", ++ uri->object); ++ /* Try once more without the label filter */ ++ char *label = uri->object; ++ uri->object = NULL; /* XXX clone uri? */ ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ uri->object = label; + } + } ++ pin = NULL; /* Will be cleaned up with URI */ + + /* now owned by caller */ + *providerp = p; + +- 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) +- error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + if (p) { +- free(p->name); +- free(p->slotlist); +- free(p->slotinfo); +- free(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); ++ pkcs11_provider_unref(p); + } +- if (handle) +- dlclose(handle); + if (ret > 0) + ret = -1; + return (ret); + } + +-/* +- * register a new provider and get number of keys hold by the token, +- * fails if provider already exists +- */ ++static int ++pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, ++ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) ++{ ++ struct pkcs11_uri *uri = NULL; ++ int r; ++ ++ debug_f("called, provider_id = %s", provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); ++ pkcs11_uri_cleanup(uri); ++ ++ return r; ++} ++ + int +-pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, +- char ***labelsp) ++pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp) + { + struct pkcs11_provider *p = NULL; + int nkeys; ++ char *provider_uri = pkcs11_uri_get(uri); ++ ++ debug_f("called, provider_uri = %s", provider_uri); + +- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, +- &p, CKU_USER); ++ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); + + /* no keys found or some other error, de-register provider */ + if (nkeys <= 0 && p != NULL) { +@@ -1683,7 +1999,37 @@ pkcs11_add_provider(char *provider_id, c + pkcs11_provider_unref(p); + } + if (nkeys == 0) +- debug_f("provider %s returned no keys", provider_id); ++ debug_f("provider %s returned no keys", provider_uri); ++ ++ free(provider_uri); ++ return nkeys; ++} ++ ++/* ++ * register a new provider and get number of keys hold by the token, ++ * fails if provider already exists ++ */ ++int ++pkcs11_add_provider(char *provider_id, char *pin, ++ struct sshkey ***keyp, char ***labelsp) ++{ ++ struct pkcs11_uri *uri; ++ int nkeys; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } ++ ++ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); ++ pkcs11_uri_cleanup(uri); + + return (nkeys); + } +diff -up openssh-8.6p1/ssh-pkcs11.h.pkcs11-uri openssh-8.6p1/ssh-pkcs11.h +--- openssh-8.6p1/ssh-pkcs11.h.pkcs11-uri 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/ssh-pkcs11.h 2021-05-06 11:35:55.115653297 +0200 +@@ -22,10 +22,14 @@ + #define SSH_PKCS11_ERR_PIN_REQUIRED 4 + #define SSH_PKCS11_ERR_PIN_LOCKED 5 + ++#include "ssh-pkcs11-uri.h" ++ + int pkcs11_init(int); + void pkcs11_terminate(void); + int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); ++int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); + int pkcs11_del_provider(char *); ++int pkcs11_uri_write(const struct sshkey *, FILE *); + #ifdef WITH_PKCS11_KEYGEN + struct sshkey * + pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, +diff -up openssh-8.6p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.6p1/ssh-pkcs11-uri.c +--- openssh-8.6p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-05-06 11:35:55.114653289 +0200 ++++ openssh-8.6p1/ssh-pkcs11-uri.c 2021-05-06 11:35:55.114653289 +0200 @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2017 Red Hat @@ -1636,11 +3005,9 @@ index 00000000..e1a7b4e0 +} + +#endif /* ENABLE_PKCS11 */ -diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h -new file mode 100644 -index 00000000..942a5a5a ---- /dev/null -+++ b/ssh-pkcs11-uri.h +diff -up openssh-8.6p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.6p1/ssh-pkcs11-uri.h +--- openssh-8.6p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-05-06 11:35:55.114653289 +0200 ++++ openssh-8.6p1/ssh-pkcs11-uri.h 2021-05-06 11:35:55.114653289 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Red Hat @@ -1684,1430 +3051,3 @@ index 00000000..942a5a5a +struct pkcs11_uri *pkcs11_uri_init(); +char *pkcs11_uri_get(struct pkcs11_uri *uri); + -diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index a302c79c..879fe917 100644 ---- a/ssh-pkcs11.c -+++ b/ssh-pkcs11.c -@@ -54,8 +54,8 @@ struct pkcs11_slotinfo { - int logged_in; - }; - --struct pkcs11_provider { -- char *name; -+struct pkcs11_module { -+ char *module_path; - void *handle; - CK_FUNCTION_LIST *function_list; - CK_INFO info; -@@ -64,6 +64,13 @@ struct pkcs11_provider { - struct pkcs11_slotinfo *slotinfo; - int valid; - int refcount; -+}; -+ -+struct pkcs11_provider { -+ char *name; -+ struct pkcs11_module *module; /* can be shared between various providers */ -+ int refcount; -+ int valid; - TAILQ_ENTRY(pkcs11_provider) next; - }; - -@@ -74,6 +81,7 @@ struct pkcs11_key { - CK_ULONG slotidx; - char *keyid; - int keyid_len; -+ char *label; - }; - - int pkcs11_interactive = 0; -@@ -106,26 +114,61 @@ pkcs11_init(int interactive) - * this is called when a provider gets unregistered. - */ - static void --pkcs11_provider_finalize(struct pkcs11_provider *p) -+pkcs11_module_finalize(struct pkcs11_module *m) - { - CK_RV rv; - CK_ULONG i; - -- debug("pkcs11_provider_finalize: %p refcount %d valid %d", -- p, p->refcount, p->valid); -- if (!p->valid) -+ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); -+ if (!m->valid) - return; -- for (i = 0; i < p->nslots; i++) { -- if (p->slotinfo[i].session && -- (rv = p->function_list->C_CloseSession( -- p->slotinfo[i].session)) != CKR_OK) -+ for (i = 0; i < m->nslots; i++) { -+ if (m->slotinfo[i].session && -+ (rv = m->function_list->C_CloseSession( -+ m->slotinfo[i].session)) != CKR_OK) - error("C_CloseSession failed: %lu", rv); - } -- 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); -+ m->valid = 0; -+ m->function_list = NULL; -+ dlclose(m->handle); -+} -+ -+/* -+ * remove a reference to the pkcs11 module. -+ * called when a provider is unregistered. -+ */ -+static void -+pkcs11_module_unref(struct pkcs11_module *m) -+{ -+ debug_f("%p refcount %d", m, m->refcount); -+ if (--m->refcount <= 0) { -+ pkcs11_module_finalize(m); -+ if (m->valid) -+ error_f("%p still valid", m); -+ free(m->slotlist); -+ free(m->slotinfo); -+ free(m->module_path); -+ free(m); -+ } -+} -+ -+/* -+ * finalize a provider shared libarary, it's no longer usable. -+ * however, there might still be keys referencing this provider, -+ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). -+ * this is called when a provider gets unregistered. -+ */ -+static void -+pkcs11_provider_finalize(struct pkcs11_provider *p) -+{ -+ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); -+ if (!p->valid) -+ return; -+ pkcs11_module_unref(p->module); -+ p->module = NULL; - p->valid = 0; -- p->function_list = NULL; -- dlclose(p->handle); - } - - /* -@@ -135,13 +180,11 @@ pkcs11_provider_finalize(struct pkcs11_provider *p) - static void - pkcs11_provider_unref(struct pkcs11_provider *p) - { -- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); -+ debug_f("%p refcount %d", p, p->refcount); - if (--p->refcount <= 0) { -- if (p->valid) -- error("pkcs11_provider_unref: %p still valid", p); - free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -+ if (p->module) -+ pkcs11_module_unref(p->module); - free(p); - } - } -@@ -159,6 +202,20 @@ pkcs11_terminate(void) - } - } - -+/* lookup provider by module path */ -+static struct pkcs11_module * -+pkcs11_provider_lookup_module(char *module_path) -+{ -+ struct pkcs11_provider *p; -+ -+ TAILQ_FOREACH(p, &pkcs11_providers, next) { -+ debug("check %p %s (%s)", p, p->name, p->module->module_path); -+ if (!strcmp(module_path, p->module->module_path)) -+ return (p->module); -+ } -+ return (NULL); -+} -+ - /* lookup provider by name */ - static struct pkcs11_provider * - pkcs11_provider_lookup(char *provider_id) -@@ -173,19 +230,52 @@ pkcs11_provider_lookup(char *provider_id) - return (NULL); - } - -+int pkcs11_del_provider_by_uri(struct pkcs11_uri *); -+ - /* unregister provider by name */ - int - pkcs11_del_provider(char *provider_id) -+{ -+ int rv; -+ struct pkcs11_uri *uri; -+ -+ debug_f("called, provider_id = %s", provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ rv = pkcs11_del_provider_by_uri(uri); -+ pkcs11_uri_cleanup(uri); -+ return rv; -+} -+ -+/* unregister provider by PKCS#11 URI */ -+int -+pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) - { - struct pkcs11_provider *p; -+ int rv = -1; -+ char *provider_uri = pkcs11_uri_get(uri); - -- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3_f("called with provider %s", provider_uri); -+ -+ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { - TAILQ_REMOVE(&pkcs11_providers, p, next); - pkcs11_provider_finalize(p); - pkcs11_provider_unref(p); -- return (0); -+ rv = 0; - } -- return (-1); -+ free(provider_uri); -+ return rv; - } - - static RSA_METHOD *rsa_method; -@@ -195,6 +285,55 @@ static EC_KEY_METHOD *ec_key_method; - static int ec_key_idx = 0; - #endif - -+/* -+ * This can't be in the ssh-pkcs11-uri, becase we can not depend on -+ * PKCS#11 structures in ssh-agent (using client-helper communication) -+ */ -+int -+pkcs11_uri_write(const struct sshkey *key, FILE *f) -+{ -+ char *p = NULL; -+ struct pkcs11_uri uri; -+ struct pkcs11_key *k11; -+ -+ /* sanity - is it a RSA key with associated app_data? */ -+ switch (key->type) { -+ case KEY_RSA: -+ k11 = RSA_get_ex_data(key->rsa, rsa_idx); -+ break; -+#ifdef HAVE_EC_KEY_METHOD_NEW -+ case KEY_ECDSA: -+ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); -+ break; -+#endif -+ default: -+ error("Unknown key type %d", key->type); -+ return -1; -+ } -+ if (k11 == NULL) { -+ error("Failed to get ex_data for key type %d", key->type); -+ return (-1); -+ } -+ -+ /* omit type -- we are looking for private-public or private-certificate pairs */ -+ uri.id = k11->keyid; -+ uri.id_len = k11->keyid_len; -+ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; -+ uri.object = k11->label; -+ uri.module_path = k11->provider->module->module_path; -+ uri.lib_manuf = k11->provider->module->info.manufacturerID; -+ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; -+ -+ p = pkcs11_uri_get(&uri); -+ /* do not cleanup -- we do not allocate here, only reference */ -+ if (p == NULL) -+ return -1; -+ -+ fprintf(f, " %s", p); -+ free(p); -+ return 0; -+} -+ - /* release a wrapped object */ - static void - pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, -@@ -208,6 +347,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, - if (k11->provider) - pkcs11_provider_unref(k11->provider); - free(k11->keyid); -+ free(k11->label); - free(k11); - } - -@@ -222,8 +362,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, - CK_RV rv; - int ret = -1; - -- f = p->function_list; -- session = p->slotinfo[slotidx].session; -+ f = p->module->function_list; -+ session = p->module->slotinfo[slotidx].session; - if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { - error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); - return (-1); -@@ -262,12 +402,12 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, - else { - snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", - si->token.label); -- if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { -+ if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { - debug_f("no pin specified"); - return (-1); /* bail out */ - } - } -- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, -+ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, - (pin != NULL) ? strlen(pin) : 0); - if (pin != NULL) - freezero(pin, strlen(pin)); -@@ -282,13 +422,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, - static int - pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) - { -- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { -+ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || -+ k11->provider->module == NULL || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - - return pkcs11_login_slot(k11->provider, -- &k11->provider->slotinfo[k11->slotidx], type); -+ &k11->provider->module->slotinfo[k11->slotidx], type); - } - - -@@ -304,13 +445,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, - - *val = 0; - -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || -+ !k11->provider->module || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - attr.type = type; - attr.pValue = &flag; -@@ -341,13 +483,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) - int always_auth = 0; - int did_login = 0; - -- if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || -+ !k11->provider->module || !k11->provider->module->valid) { - error("no pkcs11 (valid) provider found"); - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { - if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -424,8 +567,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - return (-1); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - tlen = RSA_size(rsa); - - /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -469,7 +612,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, -- CK_ATTRIBUTE *keyid_attrib, RSA *rsa) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, RSA *rsa) - { - struct pkcs11_key *k11; - -@@ -487,6 +630,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - } - -+ if (label_attrib->ulValueLen > 0 ) { -+ k11->label = xmalloc(label_attrib->ulValueLen+1); -+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen); -+ k11->label[label_attrib->ulValueLen] = 0; -+ } -+ - RSA_set_method(rsa, rsa_method); - RSA_set_ex_data(rsa, rsa_idx, k11); - return (0); -@@ -517,8 +666,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, - return (NULL); - } - -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; - - siglen = ECDSA_size(ec); - sig = xmalloc(siglen); -@@ -583,7 +732,7 @@ pkcs11_ecdsa_start_wrapper(void) - - static int - pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, -- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) -+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ec) - { - struct pkcs11_key *k11; - -@@ -599,6 +748,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); - -+ if (label_attrib->ulValueLen > 0 ) { -+ k11->label = xmalloc(label_attrib->ulValueLen+1); -+ 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); - -@@ -635,8 +790,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, - CK_SESSION_HANDLE session; - int login_required, ret; - -- f = p->function_list; -- si = &p->slotinfo[slotidx]; -+ f = p->module->function_list; -+ si = &p->module->slotinfo[slotidx]; - - login_required = si->token.flags & CKF_LOGIN_REQUIRED; - -@@ -646,9 +801,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, - error("pin required"); - return (-SSH_PKCS11_ERR_PIN_REQUIRED); - } -- if ((rv = f->C_OpenSession(p->slotlist[slotidx], CKF_RW_SESSION| -+ if ((rv = f->C_OpenSession(p->module->slotlist[slotidx], CKF_RW_SESSION| - CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK) { -- error("C_OpenSession failed: %lu", rv); -+ error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); - return (-1); - } - if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -684,7 +839,8 @@ static struct sshkey * - pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj) - { -- CK_ATTRIBUTE key_attr[3]; -+ CK_ATTRIBUTE key_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -698,14 +854,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - - memset(&key_attr, 0, sizeof(key_attr)); - key_attr[0].type = CKA_ID; -- key_attr[1].type = CKA_EC_POINT; -- key_attr[2].type = CKA_EC_PARAMS; -+ key_attr[1].type = CKA_LABEL; -+ key_attr[2].type = CKA_EC_POINT; -+ key_attr[3].type = CKA_EC_PARAMS; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return (NULL); -@@ -717,19 +874,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (key_attr[1].ulValueLen == 0 || -- key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || -+ key_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return (NULL); - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (key_attr[i].ulValueLen > 0) - key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); - - /* retrieve ID, public point and curve parameters of EC key */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto fail; -@@ -740,8 +898,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; - } - -- attrp = key_attr[2].pValue; -- group = d2i_ECPKParameters(NULL, &attrp, key_attr[2].ulValueLen); -+ attrp = key_attr[3].pValue; -+ group = d2i_ECPKParameters(NULL, &attrp, key_attr[3].ulValueLen); - if (group == NULL) { - ossl_error("d2i_ECPKParameters failed"); - goto fail; -@@ -752,13 +910,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; - } - -- if (key_attr[1].ulValueLen <= 2) { -+ if (key_attr[2].ulValueLen <= 2) { - error("CKA_EC_POINT too small"); - goto fail; - } - -- attrp = key_attr[1].pValue; -- octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[1].ulValueLen); -+ attrp = key_attr[2].pValue; -+ octet = d2i_ASN1_OCTET_STRING(NULL, &attrp, key_attr[2].ulValueLen); - if (octet == NULL) { - ossl_error("d2i_ASN1_OCTET_STRING failed"); - goto fail; -@@ -775,7 +933,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; - } - -- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) -+ if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], ec)) - goto fail; - - key = sshkey_new(KEY_UNSPEC); -@@ -791,7 +949,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - ec = NULL; /* now owned by key */ - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - if (ec) - EC_KEY_free(ec); -@@ -808,7 +966,8 @@ static struct sshkey * - pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj) - { -- CK_ATTRIBUTE key_attr[3]; -+ CK_ATTRIBUTE key_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -819,14 +978,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - - memset(&key_attr, 0, sizeof(key_attr)); - key_attr[0].type = CKA_ID; -- key_attr[1].type = CKA_MODULUS; -- key_attr[2].type = CKA_PUBLIC_EXPONENT; -+ key_attr[1].type = CKA_LABEL; -+ key_attr[2].type = CKA_MODULUS; -+ key_attr[3].type = CKA_PUBLIC_EXPONENT; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return (NULL); -@@ -838,19 +998,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * ensure that none of the others are zero length. - * XXX assumes CKA_ID is always first. - */ -- if (key_attr[1].ulValueLen == 0 || -- key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || -+ key_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return (NULL); - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (key_attr[i].ulValueLen > 0) - key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); - - /* retrieve ID, modulus and public exponent of RSA key */ -- rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, key_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto fail; -@@ -861,8 +1022,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto fail; - } - -- rsa_n = BN_bin2bn(key_attr[1].pValue, key_attr[1].ulValueLen, NULL); -- rsa_e = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); -+ rsa_n = BN_bin2bn(key_attr[2].pValue, key_attr[2].ulValueLen, NULL); -+ rsa_e = BN_bin2bn(key_attr[3].pValue, key_attr[3].ulValueLen, NULL); - if (rsa_n == NULL || rsa_e == NULL) { - error("BN_bin2bn failed"); - goto fail; -@@ -871,7 +1032,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - fatal_f("set key"); - rsa_n = rsa_e = NULL; /* transferred */ - -- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) -+ if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], &key_attr[1], rsa)) - goto fail; - - key = sshkey_new(KEY_UNSPEC); -@@ -886,7 +1047,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - rsa = NULL; /* now owned by key */ - - fail: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(key_attr[i].pValue); - RSA_free(rsa); - -@@ -897,7 +1058,8 @@ static int - pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) - { -- CK_ATTRIBUTE cert_attr[3]; -+ CK_ATTRIBUTE cert_attr[4]; -+ int nattr = 4; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -921,14 +1083,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - - memset(&cert_attr, 0, sizeof(cert_attr)); - cert_attr[0].type = CKA_ID; -- cert_attr[1].type = CKA_SUBJECT; -- cert_attr[2].type = CKA_VALUE; -+ cert_attr[1].type = CKA_LABEL; -+ cert_attr[2].type = CKA_SUBJECT; -+ cert_attr[3].type = CKA_VALUE; - -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - - /* figure out size of the attributes */ -- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - return -1; -@@ -940,18 +1103,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * XXX assumes CKA_ID is always first. - */ - if (cert_attr[1].ulValueLen == 0 || -- cert_attr[2].ulValueLen == 0) { -+ cert_attr[2].ulValueLen == 0 || -+ cert_attr[3].ulValueLen == 0) { - error("invalid attribute length"); - return -1; - } - - /* allocate buffers for attributes */ -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - if (cert_attr[i].ulValueLen > 0) - cert_attr[i].pValue = xcalloc(1, cert_attr[i].ulValueLen); - - /* retrieve ID, subject and value of certificate */ -- rv = f->C_GetAttributeValue(session, *obj, cert_attr, 3); -+ rv = f->C_GetAttributeValue(session, *obj, cert_attr, nattr); - if (rv != CKR_OK) { - error("C_GetAttributeValue failed: %lu", rv); - goto out; -@@ -965,8 +1129,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - subject = xstrdup("invalid subject"); - X509_NAME_free(x509_name); - -- cp = cert_attr[2].pValue; -- if ((x509 = d2i_X509(NULL, &cp, cert_attr[2].ulValueLen)) == NULL) { -+ cp = cert_attr[3].pValue; -+ if ((x509 = d2i_X509(NULL, &cp, cert_attr[3].ulValueLen)) == NULL) { - error("d2i_x509 failed"); - goto out; - } -@@ -986,7 +1150,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto out; - } - -- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) -+ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) - goto out; - - key = sshkey_new(KEY_UNSPEC); -@@ -1016,7 +1180,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto out; - } - -- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) -+ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) - goto out; - - key = sshkey_new(KEY_UNSPEC); -@@ -1036,7 +1200,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto out; - } - out: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(cert_attr[i].pValue); - X509_free(x509); - RSA_free(rsa); -@@ -1071,11 +1235,12 @@ have_rsa_key(const RSA *rsa) - */ - static int - pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) - { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[1]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1092,10 +1257,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, - 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; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ key_attr[nattr].ulValueLen = strlen(uri->object); -+ nattr++; -+ } -+ -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - -- rv = f->C_FindObjectsInit(session, key_attr, 1); -+ rv = f->C_FindObjectsInit(session, key_attr, nattr); - if (rv != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - goto fail; -@@ -1175,11 +1353,12 @@ fail: - */ - static int - pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) - { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[2]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1195,10 +1374,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, - 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; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ key_attr[nattr].ulValueLen = strlen(uri->object); -+ nattr++; -+ } -+ -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - -- rv = f->C_FindObjectsInit(session, key_attr, 1); -+ rv = f->C_FindObjectsInit(session, key_attr, nattr); - if (rv != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - goto fail; -@@ -1466,16 +1658,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, - } - #endif /* WITH_PKCS11_KEYGEN */ - --/* -- * register a new provider, fails if provider already exists. if -- * keyp is provided, fetch keys. -- */ - static int --pkcs11_register_provider(char *provider_id, char *pin, -- struct sshkey ***keyp, char ***labelsp, -- struct pkcs11_provider **providerp, CK_ULONG user) -+pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) - { -- int nkeys, need_finalize = 0; -+ int need_finalize = 0; - int ret = -1; - struct pkcs11_provider *p = NULL; - void *handle = NULL; -@@ -1484,164 +1670,298 @@ pkcs11_register_provider(char *provider_id, char *pin, - CK_FUNCTION_LIST *f = NULL; - CK_TOKEN_INFO *token; - CK_ULONG i; -- -- if (providerp == NULL) -+ char *provider_module = NULL; -+ struct pkcs11_module *m = 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; -- -- if (keyp != NULL) -- *keyp = NULL; -- if (labelsp != NULL) -- *labelsp = NULL; -+#endif -+ } else { -+ provider_module = strdup(uri->module_path); -+ } - -- if (pkcs11_provider_lookup(provider_id) != NULL) { -- debug_f("provider already registered: %s", provider_id); -- goto fail; -+ p = xcalloc(1, sizeof(*p)); -+ p->name = pkcs11_uri_get(uri); -+ -+ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL -+ && m->valid) { -+ debug_f("provider module already initialized: %s", provider_module); -+ free(provider_module); -+ /* Skip the initialization of PKCS#11 module */ -+ m->refcount++; -+ p->module = m; -+ p->valid = 1; -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; -+ } else { -+ m = xcalloc(1, sizeof(*m)); -+ 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()); -+ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { -+ 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; - } -- 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) { - error("C_GetFunctionList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->function_list = f; -+ m->function_list = f; - if ((rv = f->C_Initialize(NULL)) != CKR_OK) { - error("C_Initialize for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } - need_finalize = 1; -- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { -+ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { - error("C_GetInfo for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); -+ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); -+ if (uri->lib_manuf != NULL && -+ strcmp(uri->lib_manuf, m->info.manufacturerID)) { -+ debug_f("Skipping provider %s not matching library_manufacturer", -+ m->info.manufacturerID); -+ goto fail; -+ } -+ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); - debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" - " libraryDescription <%s> libraryVersion %d.%d", -- provider_id, -- p->info.manufacturerID, -- p->info.cryptokiVersion.major, -- p->info.cryptokiVersion.minor, -- p->info.libraryDescription, -- p->info.libraryVersion.major, -- p->info.libraryVersion.minor); -- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { -+ provider_module, -+ m->info.manufacturerID, -+ m->info.cryptokiVersion.major, -+ m->info.cryptokiVersion.minor, -+ m->info.libraryDescription, -+ m->info.libraryVersion.major, -+ m->info.libraryVersion.minor); -+ -+ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { - error("C_GetSlotList failed: %lu", rv); - goto fail; - } -- if (p->nslots == 0) { -+ if (m->nslots == 0) { -- debug_f("provider %s returned no slots", provider_id); -+ debug_f("provider %s returned no slots", provider_module); - ret = -SSH_PKCS11_ERR_NO_SLOTS; - goto fail; - } -- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); -- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) -+ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); -+ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) - != CKR_OK) { - error("C_GetSlotList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->slotinfo = xcalloc(p->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; -+ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) - != CKR_OK) { - error("C_GetTokenInfo for provider %s slot %lu " -- "failed: %lu", provider_id, (u_long)i, rv); -+ "failed: %lu", provider_module, (u_long)i, rv); -+ 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)); -+ } -+ m->module_path = provider_module; -+ provider_module = NULL; -+ -+ /* insert unconditionally -- remove if there will be no keys later */ -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; -+ -+fail: -+ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -+ error("C_Finalize for provider %s failed: %lu", -+ provider_module, rv); -+ free(provider_module); -+ if (m) { -+ free(m->slotlist); -+ free(m); -+ } -+ if (p) { -+ free(p->name); -+ free(p); -+ } -+ if (handle) -+ dlclose(handle); -+ return ret; -+} -+ -+/* -+ * register a new provider, fails if provider already exists. if -+ * keyp is provided, fetch keys. -+ */ -+static int -+pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, -+ CK_ULONG user) -+{ -+ int nkeys; -+ int ret = -1; -+ struct pkcs11_provider *p = NULL; -+ CK_ULONG i; -+ CK_TOKEN_INFO *token; -+ char *provider_uri = NULL; -+ -+ if (providerp == NULL) -+ goto fail; -+ *providerp = NULL; -+ -+ if (keyp != NULL) -+ *keyp = NULL; -+ -+ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { -+ goto fail; -+ } -+ -+ provider_uri = pkcs11_uri_get(uri); -+ if (pin == NULL && uri->pin != NULL) { -+ pin = uri->pin; -+ } -+ nkeys = 0; -+ for (i = 0; i < p->module->nslots; i++) { -+ token = &p->module->slotinfo[i].token; - if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { - debug2_f("ignoring uninitialised token in " -- "provider %s slot %lu", provider_id, (u_long)i); -+ "provider %s slot %lu", provider_uri, (u_long)i); -+ continue; -+ } -+ if (uri->token != NULL && -+ strcmp(token->label, uri->token) != 0) { -+ debug2_f("ignoring token not matching label (%s) " -+ "specified by PKCS#11 URI in slot %lu", -+ token->label, (unsigned long)i); -+ continue; -+ } -+ if (uri->manuf != NULL && -+ strcmp(token->manufacturerID, uri->manuf) != 0) { -+ debug2_f("ignoring token not matching requrested " -+ "manufacturerID (%s) specified by PKCS#11 URI in " -+ "slot %lu", token->manufacturerID, (unsigned long)i); - 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", -- provider_id, (unsigned long)i, -+ provider_uri, (unsigned long)i, - 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 -+ * retrieve public keys (if keyp is provided) - */ -- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || -+ if ((p->module->slotinfo[i].session != 0 || -+ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ - keyp == NULL) - continue; -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -- if (nkeys == 0 && !p->slotinfo[i].logged_in && -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && - pkcs11_interactive) { - /* - * Some tokens require login before they will - * expose keys. - */ -- if (pkcs11_login_slot(p, &p->slotinfo[i], -+ debug3_f("Trying to login as there were no keys found"); -+ if (pkcs11_login_slot(p, &p->module->slotinfo[i], - CKU_USER) < 0) { - error("login failed"); - continue; - } -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ } -+ if (nkeys == 0 && uri->object != NULL) { -+ debug3_f("No keys found. Retrying without label (%s) ", -+ uri->object); -+ /* Try once more without the label filter */ -+ char *label = uri->object; -+ uri->object = NULL; /* XXX clone uri? */ -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ uri->object = label; - } - } -+ pin = NULL; /* Will be cleaned up with URI */ - - /* now owned by caller */ - *providerp = p; - -- 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) -- error("C_Finalize for provider %s failed: %lu", -- provider_id, rv); - if (p) { -- free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -- free(p); -+ TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); - } -- if (handle) -- dlclose(handle); - if (ret > 0) - ret = -1; - return (ret); - } - --/* -- * register a new provider and get number of keys hold by the token, -- * fails if provider already exists -- */ -+static int -+pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, -+ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) -+{ -+ struct pkcs11_uri *uri = NULL; -+ int r; -+ -+ debug_f("called, provider_id = %s", provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); -+ pkcs11_uri_cleanup(uri); -+ -+ return r; -+} -+ - int --pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, -- char ***labelsp) -+pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp) - { - struct pkcs11_provider *p = NULL; - int nkeys; -+ char *provider_uri = pkcs11_uri_get(uri); -+ -+ debug_f("called, provider_uri = %s", provider_uri); - -- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, -- &p, CKU_USER); -+ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); - - /* no keys found or some other error, de-register provider */ - if (nkeys <= 0 && p != NULL) { -@@ -1652,7 +1974,37 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, - pkcs11_provider_unref(p); - } - if (nkeys == 0) -- debug_f("provider %s returned no keys", provider_id); -+ debug_f("provider %s returned no keys", provider_uri); -+ -+ free(provider_uri); -+ return nkeys; -+} -+ -+/* -+ * register a new provider and get number of keys hold by the token, -+ * fails if provider already exists -+ */ -+int -+pkcs11_add_provider(char *provider_id, char *pin, -+ struct sshkey ***keyp, char ***labelsp) -+{ -+ struct pkcs11_uri *uri; -+ int nkeys; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); -+ pkcs11_uri_cleanup(uri); - - return (nkeys); - } -diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h -index 81f1d7c5..feaf74de 100644 ---- a/ssh-pkcs11.h -+++ b/ssh-pkcs11.h -@@ -22,10 +22,14 @@ - #define SSH_PKCS11_ERR_PIN_REQUIRED 4 - #define SSH_PKCS11_ERR_PIN_LOCKED 5 - -+#include "ssh-pkcs11-uri.h" -+ - int pkcs11_init(int); - void pkcs11_terminate(void); - int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); -+int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); - int pkcs11_del_provider(char *); -+int pkcs11_uri_write(const struct sshkey *, FILE *); - #ifdef WITH_PKCS11_KEYGEN - struct sshkey * - pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, -diff --git a/ssh.c b/ssh.c -index 15aee569..976844cb 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -795,6 +795,14 @@ main(int ac, char **av) - options.gss_deleg_creds = 1; - break; - case 'i': -+#ifdef ENABLE_PKCS11 -+ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(optarg, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ add_identity_file(&options, NULL, optarg, 1); -+ break; -+ } -+#endif - p = tilde_expand_filename(optarg, getuid()); - if (stat(p, &st) == -1) - fprintf(stderr, "Warning: Identity file %s " -@@ -1603,6 +1611,7 @@ main(int ac, char **av) - free(options.certificate_files[i]); - options.certificate_files[i] = NULL; - } -+ pkcs11_terminate(); - - skip_connect: - exit_status = ssh_session2(ssh, cinfo); -@@ -2076,6 +2085,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) - options.escape_char : SSH_ESCAPECHAR_NONE, id); - } - -+#ifdef ENABLE_PKCS11 -+static void -+load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], -+ struct sshkey *identity_keys[], int *n_ids) -+{ -+ int nkeys, i; -+ struct sshkey **keys; -+ struct pkcs11_uri *uri; -+ -+ debug("identity file '%s' from pkcs#11", pkcs11_uri); -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); -+ -+ /* we need to merge URI and provider together */ -+ if (options.pkcs11_provider != NULL && uri->module_path == NULL) -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && -+ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { -+ for (i = 0; i < nkeys; i++) { -+ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { -+ sshkey_free(keys[i]); -+ continue; -+ } -+ identity_keys[*n_ids] = keys[i]; -+ identity_files[*n_ids] = pkcs11_uri_get(uri); -+ (*n_ids)++; -+ } -+ free(keys); -+ } -+ -+ pkcs11_uri_cleanup(uri); -+} -+#endif /* ENABLE_PKCS11 */ -+ - /* Loads all IdentityFile and CertificateFile keys */ - static void - load_public_identity_files(const struct ssh_conn_info *cinfo) -@@ -2090,11 +2138,6 @@ load_public_identity_files(struct passwd *pw) - char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; - struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; - int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; --#ifdef ENABLE_PKCS11 -- struct sshkey **keys = NULL; -- char **comments = NULL; -- int nkeys; --#endif /* PKCS11 */ - - n_ids = n_certs = 0; - memset(identity_files, 0, sizeof(identity_files)); -@@ -2107,33 +2150,46 @@ load_public_identity_files(struct passwd *pw) - sizeof(certificate_file_userprovided)); - - #ifdef ENABLE_PKCS11 -- if (options.pkcs11_provider != NULL && -- options.num_identity_files < SSH_MAX_IDENTITY_FILES && -- (pkcs11_init(!options.batch_mode) == 0) && -- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, -- &keys, &comments)) > 0) { -- for (i = 0; i < nkeys; i++) { -- if (n_ids >= SSH_MAX_IDENTITY_FILES) { -- sshkey_free(keys[i]); -- free(comments[i]); -- continue; -- } -- identity_keys[n_ids] = keys[i]; -- identity_files[n_ids] = comments[i]; /* transferred */ -- n_ids++; -- } -- free(keys); -- free(comments); -+ /* handle fallback from PKCS11Provider option */ -+ pkcs11_init(!options.batch_mode); -+ -+ if (options.pkcs11_provider != NULL) { -+ struct pkcs11_uri *uri; -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ /* Construct simple PKCS#11 URI to simplify access */ -+ uri->module_path = strdup(options.pkcs11_provider); -+ -+ /* Add it as any other IdentityFile */ -+ cp = pkcs11_uri_get(uri); -+ add_identity_file(&options, NULL, cp, 1); -+ free(cp); -+ -+ pkcs11_uri_cleanup(uri); - } - #endif /* ENABLE_PKCS11 */ - for (i = 0; i < options.num_identity_files; i++) { -+ char *name = options.identity_files[i]; - if (n_ids >= SSH_MAX_IDENTITY_FILES || -- strcasecmp(options.identity_files[i], "none") == 0) { -+ strcasecmp(name, "none") == 0) { - free(options.identity_files[i]); - options.identity_files[i] = NULL; - continue; - } -- cp = tilde_expand_filename(options.identity_files[i], getuid()); -+#ifdef ENABLE_PKCS11 -+ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(name, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ load_pkcs11_identity(name, identity_files, -+ identity_keys, &n_ids); -+ free(options.identity_files[i]); -+ continue; -+ } -+#endif /* ENABLE_PKCS11 */ -+ cp = tilde_expand_filename(name, getuid()); - filename = default_client_percent_dollar_expand(cp, cinfo); - free(cp); - check_load(sshkey_load_public(filename, &public, NULL), -diff --git a/ssh_config.5 b/ssh_config.5 -index 06a32d31..4b2763bd 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -986,6 +986,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 --git a/openssh-8.0p1-preserve-pam-errors.patch b/openssh-8.0p1-preserve-pam-errors.patch new file mode 100644 index 0000000..dbdbe93 --- /dev/null +++ b/openssh-8.0p1-preserve-pam-errors.patch @@ -0,0 +1,44 @@ +diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c +--- openssh-8.0p1/auth-pam.c.preserve-pam-errors 2021-03-31 17:03:15.618592347 +0200 ++++ openssh-8.0p1/auth-pam.c 2021-03-31 17:06:58.115220014 +0200 +@@ -511,7 +511,11 @@ sshpam_thread(void *ctxtp) + goto auth_fail; + + if (!do_pam_account()) { +- sshpam_err = PAM_ACCT_EXPIRED; ++ /* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN. ++ * Backward compatibility for other errors. */ ++ if (sshpam_err != PAM_PERM_DENIED ++ && sshpam_err != PAM_USER_UNKNOWN) ++ sshpam_err = PAM_ACCT_EXPIRED; + goto auth_fail; + } + if (sshpam_authctxt->force_pwchange) { +@@ -568,8 +572,10 @@ sshpam_thread(void *ctxtp) + pam_strerror(sshpam_handle, sshpam_err))) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + /* XXX - can't do much about an error here */ +- if (sshpam_err == PAM_ACCT_EXPIRED) +- ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer); ++ if (sshpam_err == PAM_PERM_DENIED ++ || sshpam_err == PAM_USER_UNKNOWN ++ || sshpam_err == PAM_ACCT_EXPIRED) ++ ssh_msg_send(ctxt->pam_csock, sshpam_err, buffer); + else if (sshpam_maxtries_reached) + ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer); + else +@@ -856,10 +862,12 @@ sshpam_query(void *ctx, char **name, cha + plen++; + free(msg); + break; ++ case PAM_USER_UNKNOWN: ++ case PAM_PERM_DENIED: + case PAM_ACCT_EXPIRED: ++ sshpam_account_status = 0; ++ /* FALLTHROUGH */ + case PAM_MAXTRIES: +- if (type == PAM_ACCT_EXPIRED) +- sshpam_account_status = 0; + if (type == PAM_MAXTRIES) + sshpam_set_maxtries_reached(1); + /* FALLTHROUGH */ diff --git a/openssh.spec b/openssh.spec index d85dd55..a589e46 100644 --- a/openssh.spec +++ b/openssh.spec @@ -50,15 +50,15 @@ %{?static_openssl:%global static_libcrypto 1} # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 -%global openssh_ver 8.5p1 -%global openssh_rel 3 +%global openssh_ver 8.6p1 +%global openssh_rel 1 %global pam_ssh_agent_ver 0.10.4 -%global pam_ssh_agent_rel 2 +%global pam_ssh_agent_rel 3 Summary: An open source implementation of SSH protocol version 2 Name: openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}.1 +Release: %{openssh_rel}%{?dist} URL: http://www.openssh.com/portable.html #URL1: https://github.com/jbeverly/pam_ssh_agent_auth/ Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz @@ -191,6 +191,10 @@ Patch965: openssh-8.2p1-visibility.patch Patch966: openssh-8.2p1-x11-without-ipv6.patch # https://bugzilla.mindrot.org/show_bug.cgi?id=3213 Patch969: openssh-8.4p1-debian-compat.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 License: BSD Requires: /sbin/nologin @@ -262,7 +266,7 @@ Requires: openssh = %{version}-%{release} %package -n pam_ssh_agent_auth Summary: PAM module for authentication with ssh-agent Version: %{pam_ssh_agent_ver} -Release: %{pam_ssh_agent_rel}.%{openssh_rel}%{?dist}.1 +Release: %{pam_ssh_agent_rel}.%{openssh_rel}%{?dist} License: BSD %description @@ -366,6 +370,8 @@ popd %patch965 -p1 -b .visibility %patch966 -p1 -b .x11-ipv6 %patch969 -p0 -b .debian +%patch974 -p1 -b .keygen-strip-doseol +%patch975 -p1 -b .preserve-pam-errors %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -650,6 +656,9 @@ test -f %{sysconfig_anaconda} && \ %endif %changelog +* Thu May 06 2021 Dmitry Belyavskiy - 8.6p1-1 + 0.10.4-3 +- New upstream release (#1952957) + * Fri Apr 16 2021 Mohan Boddu - 8.5p1-3.1 - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 diff --git a/sources b/sources index 173dd73..0675af0 100644 --- a/sources +++ b/sources @@ -1,4 +1,4 @@ -SHA512 (openssh-8.5p1.tar.gz) = af9c34d89170a30fc92a63973e32c766ed4a6d254bb210e317c000d46913e78d0c60c7befe62d993d659be000b828b9d4d3832fc40df1c3d33850aaa6293846f -SHA512 (openssh-8.5p1.tar.gz.asc) = 264a991c7207f2215875e2b472a649ede1a69f6486d25777bf522047c26ea77c2995d34b6917a993ea9a250b7dd5298a30f1975e20e471f079c9064ce283cec2 +SHA512 (openssh-8.6p1.tar.gz) = 9854eda0b773c64c9f1f74844ce466b2b42ee8845f58ad062b73141d617af944fa4ebafdf72069f400106d2c2bd0a69c92fe805ec1fc26d4f0faadf06c3fbbe6 +SHA512 (openssh-8.6p1.tar.gz.asc) = ea75d7fe350fd1761ee5490b222249e9b8915b2a02a1d41979195f15d239def387e4c6467362ab9515d517087750fa66bc368f5baa15c325502f725172631967 SHA512 (pam_ssh_agent_auth-0.10.4.tar.gz) = caccf72174d15e43f4c86a459ac6448682e62116557cf1e1e828955f3d1731595b238df42adec57860e7f341e92daf5d8285020bcb5018f3b8a5145aa32ee1c2 SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21