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,11 +65,85 @@ 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} \ +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 + + trace "remove pkcs11 keys" +- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 ++ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -e failed: exit code $r" +diff -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 \ @@ -184,32 +153,17 @@ index 774c10d4..6bf3b627 100644 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: +@@ -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 \ ++ $$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 -@@ -113,7 +113,7 @@ else - done - - trace "remove pkcs11 keys" -- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 -+ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -e failed: exit code $r" -diff --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/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,523 +1121,222 @@ 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) - free(fp); - } else { - (void) sshkey_write(keys[i], stdout); /* XXX check */ -- fprintf(stdout, "%s%s\n", -- *(comments[i]) == '\0' ? "" : " ", comments[i]); -+ if (*(comments[i]) != '\0') { -+ fprintf(stdout, " %s", comments[i]); +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; + } -+ (void) pkcs11_uri_write(keys[i], stdout); -+ fprintf(stdout, "\n"); - } - 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, - u_int nkeys, i; - struct sshbuf *msg; ++#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(); -+ debug_f("called, name = %s", name); -+ - if (fd < 0 && pkcs11_start_helper() < 0) - return (-1); + 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); + } -@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, - *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); - if (labelsp) - *labelsp = xcalloc(nkeys, sizeof(char *)); -+ debug_f("nkeys = %u", nkeys); - for (i = 0; i < nkeys; i++) { - /* XXX clean up properly instead of fatal() */ - if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || -diff --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 -@@ -0,0 +1,419 @@ -+/* -+ * Copyright (c) 2017 Red Hat -+ * -+ * Authors: Jakub Jelen -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include "includes.h" -+ +#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; + -+#include -+#include ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); + -+#include "sshkey.h" -+#include "sshbuf.h" -+#include "log.h" ++ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); + -+#define CRYPTOKI_COMPAT -+#include "pkcs11.h" ++ /* we need to merge URI and provider together */ ++ if (options.pkcs11_provider != NULL && uri->module_path == NULL) ++ uri->module_path = strdup(options.pkcs11_provider); + -+#include "ssh-pkcs11-uri.h" ++ 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); ++ } + -+#define PKCS11_URI_PATH_SEPARATOR ";" -+#define PKCS11_URI_QUERY_SEPARATOR "&" -+#define PKCS11_URI_VALUE_SEPARATOR "=" -+#define PKCS11_URI_ID "id" -+#define PKCS11_URI_TOKEN "token" -+#define PKCS11_URI_OBJECT "object" -+#define PKCS11_URI_LIB_MANUF "library-manufacturer" -+#define PKCS11_URI_MANUF "manufacturer" -+#define PKCS11_URI_MODULE_PATH "module-path" -+#define PKCS11_URI_PIN_VALUE "pin-value" ++ pkcs11_uri_cleanup(uri); ++} ++#endif /* ENABLE_PKCS11 */ + -+/* Keyword tokens. */ -+typedef enum { -+ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, -+ pPinValue, pBadOption -+} pkcs11uriOpCodes; -+ -+/* Textual representation of the tokens. */ -+static struct { -+ const char *name; -+ pkcs11uriOpCodes opcode; -+} keywords[] = { -+ { PKCS11_URI_ID, pId }, -+ { PKCS11_URI_TOKEN, pToken }, -+ { PKCS11_URI_OBJECT, pObject }, -+ { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, -+ { PKCS11_URI_MANUF, pManufacturer }, -+ { PKCS11_URI_MODULE_PATH, pModulePath }, -+ { PKCS11_URI_PIN_VALUE, pPinValue }, -+ { NULL, pBadOption } -+}; -+ -+static pkcs11uriOpCodes -+parse_token(const char *cp) -+{ -+ u_int i; -+ -+ for (i = 0; keywords[i].name; i++) -+ if (strncasecmp(cp, keywords[i].name, -+ strlen(keywords[i].name)) == 0) -+ return keywords[i].opcode; -+ -+ return pBadOption; -+} -+ -+int -+percent_decode(char *data, char **outp) -+{ -+ char tmp[3]; -+ char *out, *tmp_end; -+ char *p = data; -+ long value; -+ size_t outlen = 0; -+ -+ out = malloc(strlen(data)+1); /* upper bound */ -+ if (out == NULL) -+ return -1; -+ while (*p != '\0') { -+ switch (*p) { -+ case '%': -+ p++; -+ if (*p == '\0') -+ goto fail; -+ tmp[0] = *p++; -+ if (*p == '\0') -+ goto fail; -+ tmp[1] = *p++; -+ tmp[2] = '\0'; -+ tmp_end = NULL; -+ value = strtol(tmp, &tmp_end, 16); -+ if (tmp_end != tmp+2) -+ goto fail; -+ else -+ out[outlen++] = (char) value; -+ break; -+ default: -+ out[outlen++] = *p++; -+ break; -+ } -+ } -+ -+ /* zero terminate */ -+ out[outlen] = '\0'; -+ *outp = out; -+ return outlen; -+fail: -+ free(out); -+ return -1; -+} -+ -+struct sshbuf * -+percent_encode(const char *data, size_t length, const char *allow_list) -+{ -+ struct sshbuf *b = NULL; -+ char tmp[4], *cp; -+ size_t i; -+ -+ if ((b = sshbuf_new()) == NULL) -+ return NULL; -+ for (i = 0; i < length; i++) { -+ cp = strchr(allow_list, data[i]); -+ /* if c is specified as '\0' pointer to terminator is returned !! */ -+ if (cp != NULL && *cp != '\0') { -+ if (sshbuf_put(b, &data[i], 1) != 0) -+ goto err; -+ } else -+ if (snprintf(tmp, 4, "%%%02X", (unsigned char) data[i]) < 3 -+ || sshbuf_put(b, tmp, 3) != 0) -+ goto err; -+ } -+ if (sshbuf_put(b, "\0", 1) == 0) -+ return b; -+err: -+ sshbuf_free(b); -+ return NULL; -+} -+ -+char * -+pkcs11_uri_append(char *part, const char *separator, const char *key, -+ struct sshbuf *value) -+{ -+ char *new_part; -+ size_t size = 0; -+ -+ if (value == NULL) -+ return NULL; -+ -+ size = asprintf(&new_part, -+ "%s%s%s" PKCS11_URI_VALUE_SEPARATOR "%s", -+ (part != NULL ? part : ""), -+ (part != NULL ? separator : ""), -+ key, sshbuf_ptr(value)); -+ sshbuf_free(value); -+ free(part); -+ -+ if (size <= 0) -+ return NULL; -+ return new_part; -+} -+ -+char * -+pkcs11_uri_get(struct pkcs11_uri *uri) -+{ -+ size_t size = 0; -+ char *p = NULL, *path = NULL, *query = NULL; -+ -+ /* compose a percent-encoded ID */ -+ if (uri->id_len > 0) { -+ struct sshbuf *key_id = percent_encode(uri->id, uri->id_len, ""); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_ID, key_id); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write object label */ -+ if (uri->object) { -+ struct sshbuf *label = percent_encode(uri->object, strlen(uri->object), -+ PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_OBJECT, label); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write token label */ -+ if (uri->token) { -+ struct sshbuf *label = percent_encode(uri->token, strlen(uri->token), -+ PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_TOKEN, label); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write manufacturer */ -+ if (uri->manuf) { -+ struct sshbuf *manuf = percent_encode(uri->manuf, -+ strlen(uri->manuf), PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_MANUF, manuf); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write module_path */ -+ if (uri->module_path) { -+ struct sshbuf *module = percent_encode(uri->module_path, -+ strlen(uri->module_path), PKCS11_URI_WHITELIST "/"); -+ query = pkcs11_uri_append(query, PKCS11_URI_QUERY_SEPARATOR, -+ PKCS11_URI_MODULE_PATH, module); -+ if (query == NULL) -+ goto err; -+ } -+ -+ size = asprintf(&p, PKCS11_URI_SCHEME "%s%s%s", -+ path != NULL ? path : "", -+ query != NULL ? "?" : "", -+ query != NULL ? query : ""); -+err: -+ free(query); -+ free(path); -+ if (size <= 0) -+ return NULL; -+ return p; -+} -+ -+struct pkcs11_uri * -+pkcs11_uri_init() -+{ -+ struct pkcs11_uri *d = calloc(1, sizeof(struct pkcs11_uri)); -+ return d; -+} -+ -+void -+pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) -+{ -+ if (pkcs11 == NULL) { -+ return; -+ } -+ -+ free(pkcs11->id); -+ free(pkcs11->module_path); -+ free(pkcs11->token); -+ free(pkcs11->object); -+ free(pkcs11->lib_manuf); -+ free(pkcs11->manuf); -+ if (pkcs11->pin) -+ freezero(pkcs11->pin, strlen(pkcs11->pin)); -+ free(pkcs11); -+} -+ -+int -+pkcs11_uri_parse(const char *uri, struct pkcs11_uri *pkcs11) -+{ -+ char *saveptr1, *saveptr2, *str1, *str2, *tok; -+ int rv = 0, len; -+ char *p = NULL; -+ -+ size_t scheme_len = strlen(PKCS11_URI_SCHEME); -+ if (strlen(uri) < scheme_len || /* empty URI matches everything */ -+ strncmp(uri, PKCS11_URI_SCHEME, scheme_len) != 0) { -+ error_f("The '%s' does not look like PKCS#11 URI", uri); -+ return -1; -+ } -+ -+ if (pkcs11 == NULL) { -+ error_f("Bad arguments. The pkcs11 can't be null"); -+ return -1; -+ } -+ -+ /* skip URI schema name */ -+ p = strdup(uri); -+ str1 = p; -+ -+ /* everything before ? */ -+ tok = strtok_r(str1, "?", &saveptr1); -+ if (tok == NULL) { -+ error_f("pk11-path expected, got EOF"); -+ rv = -1; -+ goto out; -+ } -+ -+ /* skip URI schema name: -+ * the scheme ensures that there is at least something before "?" -+ * allowing empty pk11-path. Resulting token at worst pointing to -+ * \0 byte */ -+ tok = tok + scheme_len; -+ -+ /* parse pk11-path */ -+ for (str2 = tok; ; str2 = NULL) { -+ char **charptr, *arg = NULL; -+ pkcs11uriOpCodes opcode; -+ tok = strtok_r(str2, PKCS11_URI_PATH_SEPARATOR, &saveptr2); -+ if (tok == NULL) -+ break; -+ opcode = parse_token(tok); -+ if (opcode != pBadOption) -+ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ -+ -+ switch (opcode) { -+ case pId: -+ /* CKA_ID */ -+ if (pkcs11->id != NULL) { -+ verbose_f("The id already set in the PKCS#11 URI"); -+ rv = -1; -+ goto out; -+ } -+ len = percent_decode(arg, &pkcs11->id); -+ if (len <= 0) { -+ verbose_f("Failed to percent-decode CKA_ID: %s", arg); -+ rv = -1; -+ goto out; -+ } else -+ pkcs11->id_len = len; -+ debug3_f("Setting CKA_ID = %s from PKCS#11 URI", arg); -+ break; -+ case pToken: -+ /* CK_TOKEN_INFO -> label */ -+ charptr = &pkcs11->token; -+ parse_string: -+ if (*charptr != NULL) { -+ verbose_f("The %s already set in the PKCS#11 URI", -+ keywords[opcode].name); -+ rv = -1; -+ goto out; -+ } -+ percent_decode(arg, charptr); -+ debug3_f("Setting %s = %s from PKCS#11 URI", -+ keywords[opcode].name, *charptr); -+ break; -+ -+ case pObject: -+ /* CK_TOKEN_INFO -> manufacturerID */ -+ charptr = &pkcs11->object; -+ goto parse_string; -+ -+ case pManufacturer: -+ /* CK_TOKEN_INFO -> manufacturerID */ -+ charptr = &pkcs11->manuf; -+ goto parse_string; -+ -+ case pLibraryManufacturer: -+ /* CK_INFO -> manufacturerID */ -+ charptr = &pkcs11->lib_manuf; -+ goto parse_string; + /* 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); + -+ default: -+ /* Unrecognized attribute in the URI path SHOULD be error */ -+ verbose_f("Unknown part of path in PKCS#11 URI: %s", tok); -+ } -+ } ++ if (options.pkcs11_provider != NULL) { ++ struct pkcs11_uri *uri; + -+ tok = strtok_r(NULL, "?", &saveptr1); -+ if (tok == NULL) { -+ goto out; -+ } -+ /* parse pk11-query (optional) */ -+ for (str2 = tok; ; str2 = NULL) { -+ char *arg; -+ pkcs11uriOpCodes opcode; -+ tok = strtok_r(str2, PKCS11_URI_QUERY_SEPARATOR, &saveptr2); -+ if (tok == NULL) -+ break; -+ opcode = parse_token(tok); -+ if (opcode != pBadOption) -+ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); + -+ switch (opcode) { -+ case pModulePath: -+ /* module-path is PKCS11Provider */ -+ if (pkcs11->module_path != NULL) { -+ verbose_f("Multiple module-path attributes are" -+ "not supported the PKCS#11 URI"); -+ rv = -1; -+ goto out; -+ } -+ percent_decode(arg, &pkcs11->module_path); -+ debug3_f("Setting PKCS11Provider = %s from PKCS#11 URI", -+ pkcs11->module_path); -+ break; ++ /* Construct simple PKCS#11 URI to simplify access */ ++ uri->module_path = strdup(options.pkcs11_provider); + -+ case pPinValue: -+ /* pin-value */ -+ if (pkcs11->pin != NULL) { -+ verbose_f("Multiple pin-value attributes are" -+ "not supported the PKCS#11 URI"); -+ rv = -1; -+ goto out; -+ } -+ percent_decode(arg, &pkcs11->pin); -+ debug3_f("Setting PIN from PKCS#11 URI"); -+ break; ++ /* Add it as any other IdentityFile */ ++ cp = pkcs11_uri_get(uri); ++ add_identity_file(&options, NULL, cp, 1); ++ free(cp); + -+ default: -+ /* Unrecognized attribute in the URI query SHOULD be ignored */ -+ verbose_f("Unknown part of query in PKCS#11 URI: %s", tok); ++ 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; + } -+ } -+out: -+ free(p); -+ return rv; -+} -+ +#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 -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (c) 2017 Red Hat -+ * -+ * Authors: Jakub Jelen -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#define PKCS11_URI_SCHEME "pkcs11:" -+#define PKCS11_URI_WHITELIST "abcdefghijklmnopqrstuvwxyz" \ -+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ -+ "0123456789_-.()" -+ -+struct pkcs11_uri { -+ /* path */ -+ char *id; -+ size_t id_len; -+ char *token; -+ char *object; -+ char *lib_manuf; -+ char *manuf; -+ /* query */ -+ char *module_path; -+ char *pin; /* Only parsed, but not printed */ -+}; -+ -+struct pkcs11_uri *pkcs11_uri_init(); -+void pkcs11_uri_cleanup(struct pkcs11_uri *); -+int pkcs11_uri_parse(const char *, struct pkcs11_uri *); -+struct pkcs11_uri *pkcs11_uri_init(); -+char *pkcs11_uri_get(struct pkcs11_uri *uri); ++ 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 */ +- fprintf(stdout, "%s%s\n", +- *(comments[i]) == '\0' ? "" : " ", comments[i]); ++ if (*(comments[i]) != '\0') { ++ fprintf(stdout, " %s", comments[i]); ++ } ++ (void) pkcs11_uri_write(keys[i], stdout); ++ fprintf(stdout, "\n"); + } + free(comments[i]); + sshkey_free(keys[i]); +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; + ++ debug_f("called, name = %s", name); + -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 { + if (fd < 0 && pkcs11_start_helper() < 0) + return (-1); + +@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pi + *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); + if (labelsp) + *labelsp = xcalloc(nkeys, sizeof(char *)); ++ debug_f("nkeys = %u", nkeys); + for (i = 0; i < nkeys; i++) { + /* XXX clean up properly instead of fatal() */ + if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || +diff -up openssh-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; }; @@ -1699,7 +1347,7 @@ index a302c79c..879fe917 100644 void *handle; CK_FUNCTION_LIST *function_list; CK_INFO info; -@@ -64,6 +64,13 @@ struct pkcs11_provider { +@@ -65,6 +65,13 @@ struct pkcs11_provider { struct pkcs11_slotinfo *slotinfo; int valid; int refcount; @@ -1713,7 +1361,7 @@ index a302c79c..879fe917 100644 TAILQ_ENTRY(pkcs11_provider) next; }; -@@ -74,6 +81,7 @@ struct pkcs11_key { +@@ -75,6 +82,7 @@ struct pkcs11_key { CK_ULONG slotidx; char *keyid; int keyid_len; @@ -1794,7 +1442,7 @@ index a302c79c..879fe917 100644 } /* -@@ -135,13 +180,11 @@ pkcs11_provider_finalize(struct pkcs11_provider *p) +@@ -135,13 +178,11 @@ pkcs11_provider_finalize(struct pkcs11_p static void pkcs11_provider_unref(struct pkcs11_provider *p) { @@ -1811,7 +1459,7 @@ index a302c79c..879fe917 100644 free(p); } } -@@ -159,6 +202,20 @@ pkcs11_terminate(void) +@@ -159,6 +200,20 @@ pkcs11_terminate(void) } } @@ -1832,7 +1480,7 @@ index a302c79c..879fe917 100644 /* lookup provider by name */ static struct pkcs11_provider * pkcs11_provider_lookup(char *provider_id) -@@ -173,19 +230,52 @@ pkcs11_provider_lookup(char *provider_id) +@@ -173,19 +228,55 @@ pkcs11_provider_lookup(char *provider_id return (NULL); } @@ -1841,12 +1489,15 @@ index a302c79c..879fe917 100644 /* 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"); @@ -1867,7 +1518,7 @@ index a302c79c..879fe917 100644 +/* 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); @@ -1888,7 +1539,7 @@ index a302c79c..879fe917 100644 } static RSA_METHOD *rsa_method; -@@ -195,6 +285,55 @@ static EC_KEY_METHOD *ec_key_method; +@@ -195,6 +283,55 @@ static EC_KEY_METHOD *ec_key_method; static int ec_key_idx = 0; #endif @@ -1944,7 +1595,7 @@ index a302c79c..879fe917 100644 /* 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, +@@ -208,6 +345,7 @@ pkcs11_k11_free(void *parent, void *ptr, if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); @@ -1952,7 +1603,7 @@ index a302c79c..879fe917 100644 free(k11); } -@@ -222,8 +362,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, +@@ -222,8 +360,8 @@ pkcs11_find(struct pkcs11_provider *p, C CK_RV rv; int ret = -1; @@ -1963,7 +1614,7 @@ index a302c79c..879fe917 100644 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, +@@ -262,12 +400,12 @@ pkcs11_login_slot(struct pkcs11_provider else { snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", si->token.label); @@ -1978,7 +1629,7 @@ index a302c79c..879fe917 100644 (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, +@@ -297,13 +435,14 @@ pkcs11_login_slot(struct pkcs11_provider static int pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) { @@ -1995,7 +1646,7 @@ index a302c79c..879fe917 100644 } -@@ -304,13 +445,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, +@@ -319,13 +458,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs *val = 0; @@ -2013,7 +1664,7 @@ index a302c79c..879fe917 100644 attr.type = type; attr.pValue = &flag; -@@ -341,13 +483,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) +@@ -356,13 +496,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C int always_auth = 0; int did_login = 0; @@ -2031,7 +1682,7 @@ index a302c79c..879fe917 100644 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, +@@ -439,8 +580,8 @@ pkcs11_rsa_private_encrypt(int flen, con return (-1); } @@ -2042,7 +1693,7 @@ index a302c79c..879fe917 100644 tlen = RSA_size(rsa); /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -469,7 +612,7 @@ pkcs11_rsa_start_wrapper(void) +@@ -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, @@ -2051,7 +1702,7 @@ index a302c79c..879fe917 100644 { struct pkcs11_key *k11; -@@ -487,6 +630,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +@@ -502,6 +643,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -2064,7 +1715,7 @@ index a302c79c..879fe917 100644 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, +@@ -532,8 +679,8 @@ ecdsa_do_sign(const unsigned char *dgst, return (NULL); } @@ -2075,7 +1726,7 @@ index a302c79c..879fe917 100644 siglen = ECDSA_size(ec); sig = xmalloc(siglen); -@@ -583,7 +732,7 @@ pkcs11_ecdsa_start_wrapper(void) +@@ -598,7 +745,7 @@ pkcs11_ecdsa_start_wrapper(void) static int pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -2084,7 +1735,7 @@ index a302c79c..879fe917 100644 { struct pkcs11_key *k11; -@@ -599,6 +748,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +@@ -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); @@ -2097,7 +1748,7 @@ index a302c79c..879fe917 100644 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, +@@ -650,8 +803,8 @@ pkcs11_open_session(struct pkcs11_provid CK_SESSION_HANDLE session; int login_required, ret; @@ -2108,7 +1759,7 @@ index a302c79c..879fe917 100644 login_required = si->token.flags & CKF_LOGIN_REQUIRED; -@@ -646,9 +801,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, +@@ -661,9 +814,9 @@ pkcs11_open_session(struct pkcs11_provid error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -2120,7 +1771,7 @@ index a302c79c..879fe917 100644 return (-1); } if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -684,7 +839,8 @@ static struct sshkey * +@@ -699,7 +852,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2130,7 +1781,7 @@ index a302c79c..879fe917 100644 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, +@@ -713,14 +867,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2151,7 +1802,7 @@ index a302c79c..879fe917 100644 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, +@@ -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. */ @@ -2175,7 +1826,7 @@ index a302c79c..879fe917 100644 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, +@@ -755,8 +910,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -2186,7 +1837,7 @@ index a302c79c..879fe917 100644 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, +@@ -767,13 +922,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -2203,7 +1854,7 @@ index a302c79c..879fe917 100644 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, +@@ -790,7 +945,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -2212,7 +1863,7 @@ index a302c79c..879fe917 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -791,7 +949,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -806,7 +961,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ ec = NULL; /* now owned by key */ fail: @@ -2221,7 +1872,7 @@ index a302c79c..879fe917 100644 free(key_attr[i].pValue); if (ec) EC_KEY_free(ec); -@@ -808,7 +966,8 @@ static struct sshkey * +@@ -823,7 +978,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2231,7 +1882,7 @@ index a302c79c..879fe917 100644 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, +@@ -834,14 +990,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2252,7 +1903,7 @@ index a302c79c..879fe917 100644 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, +@@ -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. */ @@ -2276,7 +1927,7 @@ index a302c79c..879fe917 100644 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, +@@ -876,8 +1033,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr goto fail; } @@ -2287,7 +1938,7 @@ index a302c79c..879fe917 100644 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, +@@ -886,7 +1043,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ @@ -2296,7 +1947,7 @@ index a302c79c..879fe917 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -886,7 +1047,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -901,7 +1058,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr rsa = NULL; /* now owned by key */ fail: @@ -2305,7 +1956,7 @@ index a302c79c..879fe917 100644 free(key_attr[i].pValue); RSA_free(rsa); -@@ -897,7 +1058,8 @@ static int +@@ -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) { @@ -2315,7 +1966,7 @@ index a302c79c..879fe917 100644 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, +@@ -936,14 +1094,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -2336,7 +1987,7 @@ index a302c79c..879fe917 100644 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, +@@ -955,18 +1114,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2359,7 +2010,7 @@ index a302c79c..879fe917 100644 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, +@@ -980,8 +1140,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p subject = xstrdup("invalid subject"); X509_NAME_free(x509_name); @@ -2370,7 +2021,7 @@ index a302c79c..879fe917 100644 error("d2i_x509 failed"); goto out; } -@@ -986,7 +1150,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1001,7 +1161,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2379,7 +2030,7 @@ index a302c79c..879fe917 100644 goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1016,7 +1180,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1031,7 +1191,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } @@ -2388,7 +2039,7 @@ index a302c79c..879fe917 100644 goto out; key = sshkey_new(KEY_UNSPEC); -@@ -1036,7 +1200,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1051,7 +1211,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p goto out; } out: @@ -2397,7 +2048,7 @@ index a302c79c..879fe917 100644 free(cert_attr[i].pValue); X509_free(x509); RSA_free(rsa); -@@ -1071,11 +1235,12 @@ have_rsa_key(const RSA *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, @@ -2412,7 +2063,7 @@ index a302c79c..879fe917 100644 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, +@@ -1123,10 +1284,23 @@ pkcs11_fetch_certs(struct pkcs11_provide key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2439,7 +2090,7 @@ index a302c79c..879fe917 100644 if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1175,11 +1353,12 @@ fail: +@@ -1207,11 +1381,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2454,7 +2105,7 @@ index a302c79c..879fe917 100644 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, +@@ -1227,10 +1402,23 @@ pkcs11_fetch_keys(struct pkcs11_provider key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2481,7 +2132,7 @@ index a302c79c..879fe917 100644 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, +@@ -1499,16 +1687,10 @@ pkcs11_ecdsa_generate_private_key(struct } #endif /* WITH_PKCS11_KEYGEN */ @@ -2500,39 +2151,37 @@ index a302c79c..879fe917 100644 int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1484,164 +1670,298 @@ pkcs11_register_provider(char *provider_id, char *pin, +@@ -1517,164 +1699,298 @@ pkcs11_register_provider(char *provider_ 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 (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; -- -- if (keyp != NULL) -- *keyp = NULL; -- if (labelsp != NULL) -- *labelsp = NULL; ++ 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; -+ 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); @@ -2623,8 +2272,8 @@ index a302c79c..879fe917 100644 goto fail; } - if (p->nslots == 0) { -+ if (m->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; @@ -2653,14 +2302,19 @@ index a302c79c..879fe917 100644 != 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)); + 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; @@ -2723,9 +2377,8 @@ index a302c79c..879fe917 100644 + 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); ++ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { ++ debug2_f("ignoring uninitialised token in " + "provider %s slot %lu", provider_uri, (u_long)i); + continue; + } @@ -2741,12 +2394,8 @@ index a302c79c..879fe917 100644 + 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)); ++ continue; ++ } debug("provider %s slot %lu: label <%s> manufacturerID <%s> " "model <%s> serial <%s> flags 0x%lx", - provider_id, (unsigned long)i, @@ -2835,279 +2484,570 @@ index a302c79c..879fe917 100644 +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; ++ 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 ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "includes.h" ++ ++#ifdef ENABLE_PKCS11 ++ ++#include ++#include ++ ++#include "sshkey.h" ++#include "sshbuf.h" ++#include "log.h" ++ ++#define CRYPTOKI_COMPAT ++#include "pkcs11.h" ++ ++#include "ssh-pkcs11-uri.h" ++ ++#define PKCS11_URI_PATH_SEPARATOR ";" ++#define PKCS11_URI_QUERY_SEPARATOR "&" ++#define PKCS11_URI_VALUE_SEPARATOR "=" ++#define PKCS11_URI_ID "id" ++#define PKCS11_URI_TOKEN "token" ++#define PKCS11_URI_OBJECT "object" ++#define PKCS11_URI_LIB_MANUF "library-manufacturer" ++#define PKCS11_URI_MANUF "manufacturer" ++#define PKCS11_URI_MODULE_PATH "module-path" ++#define PKCS11_URI_PIN_VALUE "pin-value" ++ ++/* Keyword tokens. */ ++typedef enum { ++ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, ++ pPinValue, pBadOption ++} pkcs11uriOpCodes; ++ ++/* Textual representation of the tokens. */ ++static struct { ++ const char *name; ++ pkcs11uriOpCodes opcode; ++} keywords[] = { ++ { PKCS11_URI_ID, pId }, ++ { PKCS11_URI_TOKEN, pToken }, ++ { PKCS11_URI_OBJECT, pObject }, ++ { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, ++ { PKCS11_URI_MANUF, pManufacturer }, ++ { PKCS11_URI_MODULE_PATH, pModulePath }, ++ { PKCS11_URI_PIN_VALUE, pPinValue }, ++ { NULL, pBadOption } ++}; ++ ++static pkcs11uriOpCodes ++parse_token(const char *cp) ++{ ++ u_int i; ++ ++ for (i = 0; keywords[i].name; i++) ++ if (strncasecmp(cp, keywords[i].name, ++ strlen(keywords[i].name)) == 0) ++ return keywords[i].opcode; ++ ++ return pBadOption; ++} ++ ++int ++percent_decode(char *data, char **outp) ++{ ++ char tmp[3]; ++ char *out, *tmp_end; ++ char *p = data; ++ long value; ++ size_t outlen = 0; ++ ++ out = malloc(strlen(data)+1); /* upper bound */ ++ if (out == NULL) ++ return -1; ++ while (*p != '\0') { ++ switch (*p) { ++ case '%': ++ p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[0] = *p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[1] = *p++; ++ tmp[2] = '\0'; ++ tmp_end = NULL; ++ value = strtol(tmp, &tmp_end, 16); ++ if (tmp_end != tmp+2) ++ goto fail; ++ else ++ out[outlen++] = (char) value; ++ break; ++ default: ++ out[outlen++] = *p++; ++ break; ++ } ++ } ++ ++ /* zero terminate */ ++ out[outlen] = '\0'; ++ *outp = out; ++ return outlen; ++fail: ++ free(out); ++ return -1; ++} ++ ++struct sshbuf * ++percent_encode(const char *data, size_t length, const char *allow_list) ++{ ++ struct sshbuf *b = NULL; ++ char tmp[4], *cp; ++ size_t i; ++ ++ if ((b = sshbuf_new()) == NULL) ++ return NULL; ++ for (i = 0; i < length; i++) { ++ cp = strchr(allow_list, data[i]); ++ /* if c is specified as '\0' pointer to terminator is returned !! */ ++ if (cp != NULL && *cp != '\0') { ++ if (sshbuf_put(b, &data[i], 1) != 0) ++ goto err; ++ } else ++ if (snprintf(tmp, 4, "%%%02X", (unsigned char) data[i]) < 3 ++ || sshbuf_put(b, tmp, 3) != 0) ++ goto err; ++ } ++ if (sshbuf_put(b, "\0", 1) == 0) ++ return b; ++err: ++ sshbuf_free(b); ++ return NULL; ++} ++ ++char * ++pkcs11_uri_append(char *part, const char *separator, const char *key, ++ struct sshbuf *value) ++{ ++ char *new_part; ++ size_t size = 0; + -+ debug_f("called, provider_id = %s", provider_id); ++ if (value == NULL) ++ return NULL; + -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("failed to init PKCS#11 URI"); ++ size = asprintf(&new_part, ++ "%s%s%s" PKCS11_URI_VALUE_SEPARATOR "%s", ++ (part != NULL ? part : ""), ++ (part != NULL ? separator : ""), ++ key, sshbuf_ptr(value)); ++ sshbuf_free(value); ++ free(part); + -+ 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); ++ if (size <= 0) ++ return NULL; ++ return new_part; ++} ++ ++char * ++pkcs11_uri_get(struct pkcs11_uri *uri) ++{ ++ size_t size = 0; ++ char *p = NULL, *path = NULL, *query = NULL; ++ ++ /* compose a percent-encoded ID */ ++ if (uri->id_len > 0) { ++ struct sshbuf *key_id = percent_encode(uri->id, uri->id_len, ""); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_ID, key_id); ++ if (path == NULL) ++ goto err; + } + -+ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); -+ pkcs11_uri_cleanup(uri); ++ /* Write object label */ ++ if (uri->object) { ++ struct sshbuf *label = percent_encode(uri->object, strlen(uri->object), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_OBJECT, label); ++ if (path == NULL) ++ goto err; ++ } + -+ return r; ++ /* Write token label */ ++ if (uri->token) { ++ struct sshbuf *label = percent_encode(uri->token, strlen(uri->token), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_TOKEN, label); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write manufacturer */ ++ if (uri->manuf) { ++ struct sshbuf *manuf = percent_encode(uri->manuf, ++ strlen(uri->manuf), PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_MANUF, manuf); ++ if (path == NULL) ++ goto err; ++ } ++ ++ /* Write module_path */ ++ if (uri->module_path) { ++ struct sshbuf *module = percent_encode(uri->module_path, ++ strlen(uri->module_path), PKCS11_URI_WHITELIST "/"); ++ query = pkcs11_uri_append(query, PKCS11_URI_QUERY_SEPARATOR, ++ PKCS11_URI_MODULE_PATH, module); ++ if (query == NULL) ++ goto err; ++ } ++ ++ size = asprintf(&p, PKCS11_URI_SCHEME "%s%s%s", ++ path != NULL ? path : "", ++ query != NULL ? "?" : "", ++ query != NULL ? query : ""); ++err: ++ free(query); ++ free(path); ++ if (size <= 0) ++ return NULL; ++ return p; +} + - 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); ++struct pkcs11_uri * ++pkcs11_uri_init() ++{ ++ struct pkcs11_uri *d = calloc(1, sizeof(struct pkcs11_uri)); ++ return d; ++} + -+ 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); ++void ++pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) ++{ ++ if (pkcs11 == NULL) { ++ return; ++ } + -+ free(provider_uri); -+ return nkeys; ++ free(pkcs11->id); ++ free(pkcs11->module_path); ++ free(pkcs11->token); ++ free(pkcs11->object); ++ free(pkcs11->lib_manuf); ++ free(pkcs11->manuf); ++ if (pkcs11->pin) ++ freezero(pkcs11->pin, strlen(pkcs11->pin)); ++ free(pkcs11); +} + -+/* -+ * 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) ++pkcs11_uri_parse(const char *uri, struct pkcs11_uri *pkcs11) +{ -+ struct pkcs11_uri *uri; -+ int nkeys; ++ char *saveptr1, *saveptr2, *str1, *str2, *tok; ++ int rv = 0, len; ++ char *p = NULL; + -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); ++ size_t scheme_len = strlen(PKCS11_URI_SCHEME); ++ if (strlen(uri) < scheme_len || /* empty URI matches everything */ ++ strncmp(uri, PKCS11_URI_SCHEME, scheme_len) != 0) { ++ error_f("The '%s' does not look like PKCS#11 URI", uri); ++ return -1; ++ } + -+ 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); ++ if (pkcs11 == NULL) { ++ error_f("Bad arguments. The pkcs11 can't be null"); ++ return -1; + } + -+ 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" ++ /* skip URI schema name */ ++ p = strdup(uri); ++ str1 = p; + - 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; ++ /* everything before ? */ ++ tok = strtok_r(str1, "?", &saveptr1); ++ if (tok == NULL) { ++ error_f("pk11-path expected, got EOF"); ++ rv = -1; ++ goto out; ++ } ++ ++ /* skip URI schema name: ++ * the scheme ensures that there is at least something before "?" ++ * allowing empty pk11-path. Resulting token at worst pointing to ++ * \0 byte */ ++ tok = tok + scheme_len; ++ ++ /* parse pk11-path */ ++ for (str2 = tok; ; str2 = NULL) { ++ char **charptr, *arg = NULL; ++ pkcs11uriOpCodes opcode; ++ tok = strtok_r(str2, PKCS11_URI_PATH_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ opcode = parse_token(tok); ++ if (opcode != pBadOption) ++ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ ++ ++ switch (opcode) { ++ case pId: ++ /* CKA_ID */ ++ if (pkcs11->id != NULL) { ++ verbose_f("The id already set in the PKCS#11 URI"); ++ rv = -1; ++ goto out; ++ } ++ len = percent_decode(arg, &pkcs11->id); ++ if (len <= 0) { ++ verbose_f("Failed to percent-decode CKA_ID: %s", arg); ++ rv = -1; ++ goto out; ++ } else ++ pkcs11->id_len = len; ++ debug3_f("Setting CKA_ID = %s from PKCS#11 URI", arg); ++ break; ++ case pToken: ++ /* CK_TOKEN_INFO -> label */ ++ charptr = &pkcs11->token; ++ parse_string: ++ if (*charptr != NULL) { ++ verbose_f("The %s already set in the PKCS#11 URI", ++ keywords[opcode].name); ++ rv = -1; ++ goto out; + } -+#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; ++ percent_decode(arg, charptr); ++ debug3_f("Setting %s = %s from PKCS#11 URI", ++ keywords[opcode].name, *charptr); ++ break; + -+ debug("identity file '%s' from pkcs#11", pkcs11_uri); -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); ++ case pObject: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->object; ++ goto parse_string; + -+ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++ case pManufacturer: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->manuf; ++ goto parse_string; + -+ /* we need to merge URI and provider together */ -+ if (options.pkcs11_provider != NULL && uri->module_path == NULL) -+ uri->module_path = strdup(options.pkcs11_provider); ++ case pLibraryManufacturer: ++ /* CK_INFO -> manufacturerID */ ++ charptr = &pkcs11->lib_manuf; ++ goto parse_string; + -+ 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)++; ++ default: ++ /* Unrecognized attribute in the URI path SHOULD be error */ ++ verbose_f("Unknown part of path in PKCS#11 URI: %s", tok); + } -+ free(keys); + } + -+ pkcs11_uri_cleanup(uri); -+} -+#endif /* ENABLE_PKCS11 */ ++ tok = strtok_r(NULL, "?", &saveptr1); ++ if (tok == NULL) { ++ goto out; ++ } ++ /* parse pk11-query (optional) */ ++ for (str2 = tok; ; str2 = NULL) { ++ char *arg; ++ pkcs11uriOpCodes opcode; ++ tok = strtok_r(str2, PKCS11_URI_QUERY_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ opcode = parse_token(tok); ++ if (opcode != pBadOption) ++ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ + - /* 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); ++ switch (opcode) { ++ case pModulePath: ++ /* module-path is PKCS11Provider */ ++ if (pkcs11->module_path != NULL) { ++ verbose_f("Multiple module-path attributes are" ++ "not supported the PKCS#11 URI"); ++ rv = -1; ++ goto out; ++ } ++ percent_decode(arg, &pkcs11->module_path); ++ debug3_f("Setting PKCS11Provider = %s from PKCS#11 URI", ++ pkcs11->module_path); ++ break; + -+ if (options.pkcs11_provider != NULL) { -+ struct pkcs11_uri *uri; ++ case pPinValue: ++ /* pin-value */ ++ if (pkcs11->pin != NULL) { ++ verbose_f("Multiple pin-value attributes are" ++ "not supported the PKCS#11 URI"); ++ rv = -1; ++ goto out; ++ } ++ percent_decode(arg, &pkcs11->pin); ++ debug3_f("Setting PIN from PKCS#11 URI"); ++ break; + -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); ++ default: ++ /* Unrecognized attribute in the URI query SHOULD be ignored */ ++ verbose_f("Unknown part of query in PKCS#11 URI: %s", tok); ++ } ++ } ++out: ++ free(p); ++ return rv; ++} + -+ /* Construct simple PKCS#11 URI to simplify access */ -+ uri->module_path = strdup(options.pkcs11_provider); ++#endif /* ENABLE_PKCS11 */ +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 ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ + -+ /* Add it as any other IdentityFile */ -+ cp = pkcs11_uri_get(uri); -+ add_identity_file(&options, NULL, cp, 1); -+ free(cp); ++#define PKCS11_URI_SCHEME "pkcs11:" ++#define PKCS11_URI_WHITELIST "abcdefghijklmnopqrstuvwxyz" \ ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ ++ "0123456789_-.()" ++ ++struct pkcs11_uri { ++ /* path */ ++ char *id; ++ size_t id_len; ++ char *token; ++ char *object; ++ char *lib_manuf; ++ char *manuf; ++ /* query */ ++ char *module_path; ++ char *pin; /* Only parsed, but not printed */ ++}; ++ ++struct pkcs11_uri *pkcs11_uri_init(); ++void pkcs11_uri_cleanup(struct pkcs11_uri *); ++int pkcs11_uri_parse(const char *, struct pkcs11_uri *); ++struct pkcs11_uri *pkcs11_uri_init(); ++char *pkcs11_uri_get(struct pkcs11_uri *uri); + -+ 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