diff --git a/.gitignore b/.gitignore index 0a4a73d..508d80d 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,6 @@ pam_ssh_agent_auth-0.9.2.tar.bz2 /openssh-8.4p1.tar.gz /openssh-8.4p1.tar.gz.asc /pam_ssh_agent_auth-0.10.4.tar.gz +/openssh-8.5p1.tar.gz +/openssh-8.5p1.tar.gz.asc +/gpgkey-736060BA.gpg diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index fa0717f..664e11a 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -2,14 +2,14 @@ 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,...) - void - log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) + log_init(const char *av0, LogLevel level, SyslogFacility facility, + int on_stderr) { + log_init_handler(av0, level, facility, on_stderr, 1); +} + +void -+log_init_handler(char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) { ++log_init_handler(const char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) { #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif @@ -30,10 +30,10 @@ 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 { - typedef void (log_handler_fn)(LogLevel, const char *, void *); + const char *, void *); - void log_init(char *, LogLevel, SyslogFacility, int); -+void log_init_handler(char *, LogLevel, SyslogFacility, int, int); + 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); @@ -59,14 +59,14 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c ssh_signal(SIGHUP, &monitor_child_handler); ssh_signal(SIGTERM, &monitor_child_handler); @@ -472,7 +476,7 @@ monitor_read_log(struct monitor *pmonito + /* Log it */ if (log_level_name(level) == NULL) - fatal("%s: invalid log level %u (corrupted message?)", - __func__, level); -- do_log2(level, "%s [preauth]", msg); -+ do_log2(level, "%s [%s]", msg, pmonitor->m_state); + 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); sshbuf_free(logmsg); - free(msg); + free(file); @@ -1719,13 +1723,28 @@ monitor_init(void) mon = xcalloc(1, sizeof(*mon)); monitor_openfds(mon, 1); @@ -89,7 +89,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c + xasprintf(&dev_log_path, "%s/dev/log", chroot_dir); + + if (stat(dev_log_path, &dev_log_stat) != 0) { -+ debug("%s: /dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", __func__, chroot_dir); ++ debug_f("/dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", chroot_dir); + do_logfds = 1; + } + free(dev_log_path); diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index 3a7193e..fa9d591 100644 --- a/openssh-6.6.1p1-selinux-contexts.patch +++ b/openssh-6.6.1p1-selinux-contexts.patch @@ -34,19 +34,19 @@ index 8f32464..18a2ca4 100644 + + contexts_path = selinux_openssh_contexts_path(); + if (contexts_path == NULL) { -+ debug3("%s: Failed to get the path to SELinux context", __func__); ++ debug3_f("Failed to get the path to SELinux context"); + return; + } + + if ((contexts_file = fopen(contexts_path, "r")) == NULL) { -+ debug("%s: Failed to open SELinux context file", __func__); ++ debug_f("Failed to open SELinux context file"); + return; + } + + if (fstat(fileno(contexts_file), &sb) != 0 || + sb.st_uid != 0 || (sb.st_mode & 022) != 0) { -+ logit("%s: SELinux context file needs to be owned by root" -+ " and not writable by anyone else", __func__); ++ logit_f("SELinux context file needs to be owned by root" ++ " and not writable by anyone else"); + fclose(contexts_file); + return; + } @@ -70,7 +70,7 @@ index 8f32464..18a2ca4 100644 + if (arg && strcmp(arg, "privsep_preauth") == 0) { + arg = strdelim(&cp); + if (!arg || *arg == '\0') { -+ debug("%s: privsep_preauth is empty", __func__); ++ debug_f("privsep_preauth is empty"); + fclose(contexts_file); + return; + } @@ -80,8 +80,8 @@ index 8f32464..18a2ca4 100644 + fclose(contexts_file); + + if (preauth_context == NULL) { -+ debug("%s: Unable to find 'privsep_preauth' option in" -+ " SELinux context file", __func__); ++ debug_f("Unable to find 'privsep_preauth' option in" ++ " SELinux context file"); + return; + } + @@ -101,10 +101,11 @@ index 22ea8ef..1fc963d 100644 if ((cx = index(cx + 1, ':'))) strlcat(newctx, cx, newlen); - debug3("%s: setting context from '%s' to '%s'", __func__, -+ debug("%s: setting context from '%s' to '%s'", __func__, ++ debug_f("setting context from '%s' to '%s'", oldctx, newctx); if (setcon(newctx) < 0) - switchlog("%s: setcon %s from %s failed with %s", __func__, + do_log2(log_level, "%s: setcon %s from %s failed with %s", + __func__, newctx, oldctx, strerror(errno)); diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index cb51f99..8b7cda2 100644 --- a/openbsd-compat/port-linux.h diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index 01ea156..6ee2535 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -39,8 +39,8 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -418,7 +421,7 @@ typedef enum { - sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, - sHostKeyAlgorithms, + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, + sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 9e71efe..2aa14bd 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,10 +1,10 @@ -diff -up openssh/auth.c.keycat openssh/misc.c ---- openssh/auth.c.keycat 2015-06-24 10:57:50.158849606 +0200 -+++ openssh/auth.c 2015-06-24 11:04:23.989868638 +0200 -@@ -966,6 +966,14 @@ subprocess(const char *tag, struct passw +diff -up openssh/misc.c.keycat openssh/misc.c +--- openssh/misc.c.keycat 2015-06-24 10:57:50.158849606 +0200 ++++ openssh/misc.c 2015-06-24 11:04:23.989868638 +0200 +@@ -966,6 +966,13 @@ subprocess(const char *tag, struct passw + error("%s: dup2: %s", tag, strerror(errno)); _exit(1); } - +#ifdef WITH_SELINUX + if (sshd_selinux_setup_env_variables() < 0) { + error ("failed to copy environment: %s", @@ -12,10 +12,9 @@ diff -up openssh/auth.c.keycat openssh/misc.c + _exit(127); + } +#endif -+ - execve(av[0], av, child_env); - error("%s exec \"%s\": %s", tag, command, strerror(errno)); - _exit(127); + if (env != NULL) + execve(av[0], av, env); + else diff -up openssh/HOWTO.ssh-keycat.keycat openssh/HOWTO.ssh-keycat --- openssh/HOWTO.ssh-keycat.keycat 2015-06-24 10:57:50.157849608 +0200 +++ openssh/HOWTO.ssh-keycat 2015-06-24 10:57:50.157849608 +0200 diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 5009e2a..407ff4c 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -193,7 +193,7 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -399,7 +402,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sKerberosUniqueCCache, diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 3d4c287..8047fc3 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -13,7 +13,7 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh- --- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux 2016-12-23 18:58:52.973122201 +0100 +++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c 2016-12-23 18:58:52.974122201 +0100 @@ -419,6 +419,28 @@ sshd_selinux_setup_exec_context(char *pw - debug3("%s: done", __func__); + debug3_f("done"); } +void @@ -25,15 +25,15 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh- + return; + + if (getexeccon((security_context_t *)&ctx) != 0) { -+ logit("%s: getexeccon failed with %s", __func__, strerror(errno)); ++ logit_f("getexeccon failed with %s", strerror(errno)); + return; + } + if (ctx != NULL) { + /* unset exec context before we will lose this capabililty */ + if (setexeccon(NULL) != 0) -+ fatal("%s: setexeccon failed with %s", __func__, strerror(errno)); ++ fatal_f("setexeccon failed with %s", strerror(errno)); + if (setcon(ctx) != 0) -+ fatal("%s: setcon failed with %s", __func__, strerror(errno)); ++ fatal_f("setcon failed with %s", strerror(errno)); + freecon(ctx); + } +} diff --git a/openssh-6.7p1-coverity.patch b/openssh-6.7p1-coverity.patch index 3f34464..5b75dda 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -34,7 +34,7 @@ diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c @@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || (tmp2 = dup(pmonitor->m_recvfd)) == -1) { - error("%s: cannot allocate fds for pty", __func__); + error_f("cannot allocate fds for pty"); - if (tmp1 > 0) + if (tmp1 >= 0) close(tmp1); @@ -120,11 +120,11 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c - while (read(notify_pipe[0], &c, 1) != -1) + if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) + while (read(notify_pipe[0], &c, 1) >= 0) - debug2("%s: reading", __func__); + debug2_f("reading"); } @@ -518,7 +518,7 @@ server_request_tun(void) - debug("%s: invalid tun", __func__); + debug_f("invalid tun"); goto done; } - if (auth_opts->force_tun_device != -1) { diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index de70ff5..b5895f7 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -13,33 +13,33 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c + struct sshbuf *m; + int r, ret = 0; + -+ debug3("%s: entering", __func__); ++ debug3_f("entering"); + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + do { + blen = atomicio(read, fdin, buf, sizeof(buf)); + if (blen == 0) /* closed pipe */ + break; + if (blen != sizeof(buf)) { -+ error("%s: Failed to read the buffer from child", __func__); ++ error_f("Failed to read the buffer from child"); + ret = -1; + break; + } + + msg_len = get_u32(buf); + if (msg_len > 256 * 1024) -+ fatal("%s: read: bad msg_len %d", __func__, msg_len); ++ fatal_f("read: bad msg_len %d", msg_len); + sshbuf_reset(m); + if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) { -+ error("%s: Failed to read the the buffer content from the child", __func__); ++ error_f("Failed to read the the buffer content from the child"); + ret = -1; + break; + } + if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen || + atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) { -+ error("%s: Failed to write the message to the monitor", __func__); ++ error_f("Failed to write the message to the monitor"); + ret = -1; + break; + } diff --git a/openssh-7.2p2-k5login_directory.patch b/openssh-7.2p2-k5login_directory.patch index 242294a..80e7678 100644 --- a/openssh-7.2p2-k5login_directory.patch +++ b/openssh-7.2p2-k5login_directory.patch @@ -49,7 +49,7 @@ index a7c0c5f..df8cc9a 100644 + int ret = 0; + + ret = ssh_krb5_get_k5login_directory(krb_context, &k5login_directory); -+ debug3("%s: k5login_directory = %s (rv=%d)", __func__, k5login_directory, ret); ++ debug3_f("k5login_directory = %s (rv=%d)", k5login_directory, ret); + if (k5login_directory == NULL || ret != 0) { + /* If not set, the library will look for k5login + * files in the user's home directory, with the filename .k5login. @@ -64,7 +64,7 @@ index a7c0c5f..df8cc9a 100644 + k5login_directory[strlen(k5login_directory)-1] != '/' ? "/" : "", + pw->pw_name); + } -+ debug("%s: Checking existence of file %s", __func__, file); ++ debug_f("Checking existence of file %s", file); - snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); return access(file, F_OK) == 0; diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 35a1a8a..85d0650 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -943,7 +943,7 @@ diff -up openssh/kex.c.audit openssh/kex.c return SSH_ERR_NO_CIPHER_ALG_MATCH; + } if ((enc->cipher = cipher_by_name(name)) == NULL) { - error("%s: unsupported cipher %s", __func__, name); + error_f("unsupported cipher %s", name); free(name); @@ -783,8 +788,12 @@ choose_mac(struct ssh *ssh, struct sshma { @@ -957,7 +957,7 @@ diff -up openssh/kex.c.audit openssh/kex.c return SSH_ERR_NO_MAC_ALG_MATCH; + } if (mac_setup(mac, name) < 0) { - error("%s: unsupported MAC %s", __func__, name); + error_f("unsupported MAC %s", name); free(name); @@ -796,12 +805,16 @@ choose_mac(struct ssh *ssh, struct sshma } @@ -1094,7 +1094,7 @@ 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} \ - sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ + kexsntrup761x25519.o sntrup761.o kexgen.o \ kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o @@ -1172,15 +1172,15 @@ diff -up openssh/monitor.c.audit openssh/monitor.c @@ -1455,6 +1474,8 @@ mm_answer_keyverify(struct ssh *ssh, int if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) - fatal("%s: bad key, not previously allowed", __func__); + fatal_f("bad key, not previously allowed"); + if (type != key_blobtype) -+ fatal("%s: bad key type", __func__); ++ fatal_f("bad key type"); /* Empty signature algorithm means NULL. */ if (*sigalg == '\0') { -@@ -1470,25 +1491,28 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1470,27 +1491,30 @@ mm_answer_keyverify(struct ssh *ssh, int case MM_USERKEY: - valid_data = monitor_valid_userblob(data, datalen); + valid_data = monitor_valid_userblob(ssh, data, datalen); auth_method = "publickey"; + ret = user_key_verify(ssh, key, signature, signaturelen, data, + datalen, sigalg, ssh->compat, &sig_details); @@ -1198,15 +1198,17 @@ diff -up openssh/monitor.c.audit openssh/monitor.c break; } if (!valid_data) - fatal("%s: bad signature data blob", __func__); + 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, SSH_FP_DEFAULT)) == NULL) - fatal("%s: sshkey_fingerprint failed", __func__); + fatal_f("sshkey_fingerprint failed"); - ret = sshkey_verify(key, signature, signaturelen, data, datalen, - sigalg, ssh->compat, &sig_details); - debug3("%s: %s %p signature %s%s%s", __func__, auth_method, key, + 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 @@ -1216,14 +1218,14 @@ diff -up openssh/monitor.c.audit openssh/monitor.c -mm_session_close(Session *s) +mm_session_close(struct ssh *ssh, Session *s) { - debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); + debug3_f("session %d pid %ld", s->self, (long)s->pid); if (s->ttyfd != -1) { - debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); + debug3_f("tty %s ptyfd %d", s->tty, s->ptyfd); session_pty_cleanup2(s); } +#ifdef SSH_AUDIT_EVENTS + if (s->command != NULL) { -+ debug3("%s: command %d", __func__, s->command_handle); ++ debug3_f("command %d", s->command_handle); + session_end_command2(ssh, s); + } +#endif @@ -1237,11 +1239,11 @@ diff -up openssh/monitor.c.audit openssh/monitor.c - mm_session_close(s); + mm_session_close(ssh, s); if ((r = sshbuf_put_u32(m, 0)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + 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 if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse tty"); if ((s = session_by_tty(tty)) != NULL) - mm_session_close(s); + mm_session_close(ssh, s); @@ -1271,7 +1273,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c - audit_run_command(cmd); + s = session_new(); + if (s == NULL) -+ fatal("%s: error allocating a session", __func__); ++ fatal_f("error allocating a session"); + s->command = cmd; +#ifdef SSH_AUDIT_EVENTS + s->command_handle = audit_run_command(ssh, cmd); @@ -1293,15 +1295,15 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + u_char *cmd = NULL; + Session *s; + -+ debug3("%s entering", __func__); ++ debug3_f("entering"); + if ((r = sshbuf_get_u32(m, &handle)) != 0 || + (r = sshbuf_get_string(m, &cmd, &len)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + s = session_by_id(handle); + if (s == NULL || s->ttyfd != -1 || s->command == NULL || + strcmp(s->command, cmd) != 0) -+ fatal("%s: invalid handle", __func__); ++ fatal_f("invalid handle"); + mm_session_close(ssh, s); free(cmd); return (0); @@ -1311,13 +1313,13 @@ diff -up openssh/monitor.c.audit openssh/monitor.c mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { + struct sshbuf *m; - debug3("%s: Waiting for new keys", __func__); + debug3_f("Waiting for new keys"); if ((child_state = sshbuf_new()) == NULL) @@ -1774,6 +1842,19 @@ mm_get_keystate(struct ssh *ssh, struct mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, child_state); - debug3("%s: GOT new keys", __func__); + debug3_f("GOT new keys"); + +#ifdef SSH_AUDIT_EVENTS + m = sshbuf_new(); @@ -1345,7 +1347,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + int what, r; + + if ((r = sshbuf_get_u32(m, &what)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + audit_unsupported_body(ssh, what); + @@ -1370,10 +1372,10 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + (r = sshbuf_get_cstring(m, &compress, NULL)) != 0 || + (r = sshbuf_get_cstring(m, &pfs, NULL)) != 0 || + (r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + pid = (pid_t) tmp; + if ((r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + uid = (pid_t) tmp; + + audit_kex_body(ssh, ctos, cipher, mac, compress, pfs, pid, uid); @@ -1398,10 +1400,10 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + + if ((r = sshbuf_get_u32(m, &ctos)) != 0 || + (r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + pid = (pid_t) tmp; + if ((r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + uid = (uid_t) tmp; + + audit_session_key_free_body(ssh, ctos, pid, uid); @@ -1423,10 +1425,10 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + + if ((r = sshbuf_get_cstring(m, &fp, &len)) != 0 || + (r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + pid = (pid_t) tmp; + if ((r = sshbuf_get_u64(m, &tmp)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + uid = (uid_t) tmp; + + audit_destroy_sensitive_data(ssh, fp, pid, uid); @@ -1470,7 +1472,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c @@ -525,7 +525,8 @@ mm_sshkey_verify(const struct sshkey *ke *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); - if ((r = sshkey_puts(key, m)) != 0 || + if ((r = sshbuf_put_u32(m, type)) != 0 || + (r = sshkey_puts(key, m)) != 0 || @@ -1522,7 +1524,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, m); + + if ((r = sshbuf_get_u32(m, &handle)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + sshbuf_free(m); + + return (handle); @@ -1534,13 +1536,13 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + int r; + struct sshbuf *m; + -+ debug3("%s entering command %s", __func__, command); ++ debug3_f("entering command %s", command); + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, handle)) != 0 || + (r = sshbuf_put_cstring(m, command)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, m); sshbuf_free(m); @@ -1558,9 +1560,9 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, what)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED, @@ -1577,7 +1579,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, ctos)) != 0 || + (r = sshbuf_put_cstring(m, cipher)) != 0 || + (r = sshbuf_put_cstring(m, (mac ? mac : ""))) != 0 || @@ -1585,7 +1587,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + (r = sshbuf_put_cstring(m, fps)) != 0 || + (r = sshbuf_put_u64(m, pid)) != 0 || + (r = sshbuf_put_u64(m, uid)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX, @@ -1601,11 +1603,11 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, ctos)) != 0 || + (r = sshbuf_put_u64(m, pid)) != 0 || + (r = sshbuf_put_u64(m, uid)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, @@ -1620,11 +1622,11 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c + struct sshbuf *m; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_cstring(m, fp)) != 0 || + (r = sshbuf_put_u64(m, pid)) != 0 || + (r = sshbuf_put_u64(m, uid)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m); + sshbuf_free(m); @@ -1903,7 +1905,7 @@ diff -up openssh/session.c.audit openssh/session.c + if (s->used) + return s; + } -+ debug("%s: unknown id %d", __func__, id); ++ debug_f("unknown id %d", id); + session_dump(); + return NULL; +} @@ -2115,7 +2117,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c sshkey_free(sensitive_data.host_certificates[i]); sensitive_data.host_certificates[i] = NULL; } -@@ -400,14 +437,26 @@ destroy_sensitive_data(void) +@@ -400,20 +437,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2142,9 +2144,8 @@ diff -up openssh/sshd.c.audit openssh/sshd.c + fp = NULL; if ((r = sshkey_from_private( sensitive_data.host_keys[i], &tmp)) != 0) - fatal("could not demote host %s key: %s", -@@ -415,6 +464,12 @@ demote_sensitive_data(void) - ssh_err(r)); + fatal_r(r, "could not demote host %s key", + sshkey_type(sensitive_data.host_keys[i])); sshkey_free(sensitive_data.host_keys[i]); sensitive_data.host_keys[i] = tmp; + if (fp != NULL) { @@ -2254,7 +2255,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c do_cleanup(the_active_state, the_authctxt); if (use_privsep && privsep_is_preauth && @@ -2414,9 +2482,16 @@ cleanup_exit(int i) - pmonitor->m_pid, strerror(errno)); + } } } + is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0; diff --git a/openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch index 08cd349..f7cd50f 100644 --- a/openssh-7.6p1-cleanup-selinux.patch +++ b/openssh-7.6p1-cleanup-selinux.patch @@ -2,9 +2,9 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c --- openssh/auth2-pubkey.c.refactor 2019-04-04 13:19:12.188821236 +0200 +++ openssh/auth2-pubkey.c 2019-04-04 13:19:12.276822078 +0200 @@ -72,6 +72,9 @@ + + /* import */ extern ServerOptions options; - extern u_char *session_id2; - extern u_int session_id2_len; +extern int inetd_flag; +extern int rexeced_flag; +extern Authctxt *the_authctxt; @@ -12,59 +12,59 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c static char * format_key(const struct sshkey *key) @@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh - - if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command, + if ((pid = subprocess("AuthorizedPrincipalsCommand", command, ac, av, &f, -- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) -+ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, + SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, +- runas_pw, temporarily_use_uid, restore_uid)) == 0) ++ runas_pw, temporarily_use_uid, restore_uid, + (inetd_flag && !rexeced_flag), the_authctxt)) == 0) goto out; uid_swapped = 1; @@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss - - if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command, + if ((pid = subprocess("AuthorizedKeysCommand", command, ac, av, &f, -- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) -+ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, + SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, +- runas_pw, temporarily_use_uid, restore_uid)) == 0) ++ runas_pw, temporarily_use_uid, restore_uid, + (inetd_flag && !rexeced_flag), the_authctxt)) == 0) goto out; uid_swapped = 1; -diff -up openssh/auth.c.refactor openssh/auth.c ---- openssh/auth.c.refactor 2019-04-04 13:19:12.235821686 +0200 -+++ openssh/auth.c 2019-04-04 13:19:12.276822078 +0200 +diff -up openssh/misc.c.refactor openssh/misc.c +--- openssh/misc.c.refactor 2019-04-04 13:19:12.235821686 +0200 ++++ openssh/misc.c 2019-04-04 13:19:12.276822078 +0200 @@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh * - */ pid_t - subprocess(const char *tag, struct passwd *pw, const char *command, -- int ac, char **av, FILE **child, u_int flags) -+ int ac, char **av, FILE **child, u_int flags, int inetd, -+ void *the_authctxt) + subprocess(const char *tag, const char *command, + int ac, char **av, FILE **child, u_int flags, +- struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs) ++ struct passwd *pw, privdrop_fn *drop_privs, ++ privrestore_fn *restore_privs, int inetd, void *the_authctxt) { FILE *f = NULL; struct stat st; @@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw + _exit(1); } - #ifdef WITH_SELINUX - if (sshd_selinux_setup_env_variables() < 0) { + if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) { error ("failed to copy environment: %s", strerror(errno)); _exit(127); -diff -up openssh/auth.h.refactor openssh/auth.h ---- openssh/auth.h.refactor 2019-04-04 13:19:12.251821839 +0200 -+++ openssh/auth.h 2019-04-04 13:19:12.276822078 +0200 +diff -up openssh/misc.h.refactor openssh/misc.h +--- openssh/misc.h.refactor 2019-04-04 13:19:12.251821839 +0200 ++++ openssh/misc.h 2019-04-04 13:19:12.276822078 +0200 @@ -235,7 +235,7 @@ struct passwd *fakepw(void); - #define SSH_SUBPROCESS_STDOUT_CAPTURE (1<<1) /* Redirect stdout */ - #define SSH_SUBPROCESS_STDERR_DISCARD (1<<2) /* Discard stderr */ - pid_t subprocess(const char *, struct passwd *, -- const char *, int, char **, FILE **, u_int flags); -+ const char *, int, char **, FILE **, u_int flags, int, void *); - - int sys_auth_passwd(struct ssh *, const char *); - + #define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */ + #define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */ + pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int, +- struct passwd *, privdrop_fn *, privrestore_fn *); ++ struct passwd *, privdrop_fn *, privrestore_fn *, int, void *); + + typedef struct arglist arglist; + struct arglist { diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h --- openssh/openbsd-compat/port-linux.h.refactor 2019-04-04 13:19:12.256821887 +0200 +++ openssh/openbsd-compat/port-linux.h 2019-04-04 13:19:12.276822078 +0200 @@ -145,7 +145,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa char *role; @@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it - debug3("%s: setting execution context", __func__); + debug3_f("setting execution context"); - ssh_selinux_get_role_level(&role, &reqlvl); + ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt); @@ -203,10 +203,10 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa + if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) { switch (security_getenforce()) { case -1: - fatal("%s: security_getenforce() failed", __func__); + fatal_f("security_getenforce() failed"); @@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw - debug3("%s: setting execution context", __func__); + debug3_f("setting execution context"); - r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); + r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt); @@ -269,3 +269,15 @@ diff -up openssh/sshd.c.refactor openssh/sshd.c #endif #ifdef USE_PAM if (options.use_pam) { +diff -up openssh/sshconnect.c.refactor openssh/sshconnect.c +--- openssh/sshconnect.c.refactor 2021-02-24 00:12:03.065325046 +0100 ++++ openssh/sshconnect.c 2021-02-24 00:12:12.126449544 +0100 +@@ -892,7 +892,7 @@ load_hostkeys_command(struct hostkeys *h + + if ((pid = subprocess(tag, command, ac, av, &f, + SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH| +- SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL)) == 0) ++ SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL, 0, NULL)) == 0) + goto out; + + load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1); diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 19f3d97..f199fb2 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -165,7 +165,7 @@ 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 \ - "ecdsa-sha2-nistp256," \ + "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 @@ -416,7 +416,7 @@ diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { + if (FIPS_mode()) -+ logit("%s: the key length might be unsupported by FIPS mode approved key generation method", __func__); ++ logit_f("the key length might be unsupported by FIPS mode approved key generation method"); ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 506c79a..3b9ef3a 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -151,7 +151,7 @@ index a5a81ed2..63f877f2 100644 +ssh_krb5_expand_template(char **result, const char *template) { + char *p_n, *p_o, *r, *tmp_template; + -+ debug3("%s: called, template = %s", __func__, template); ++ debug3_f("called, template = %s", template); + if (template == NULL) + return -1; + @@ -179,7 +179,7 @@ index a5a81ed2..63f877f2 100644 + } else { + p_o = strchr(p_n, '}') + 1; + *p_o = '\0'; -+ debug("%s: unsupported token %s in %s", __func__, p_n, template); ++ debug_f("unsupported token %s in %s", p_n, template); + /* unknown token, fallback to the default */ + goto cleanup; + } @@ -207,7 +207,7 @@ index a5a81ed2..63f877f2 100644 + int ret = 0; + char *value = NULL; + -+ debug3("%s: called", __func__); ++ debug3_f("called"); + ret = krb5_get_profile(ctx, &p); + if (ret) + return ret; @@ -218,7 +218,7 @@ index a5a81ed2..63f877f2 100644 + + ret = ssh_krb5_expand_template(ccname, value); + -+ debug3("%s: returning with ccname = %s", __func__, *ccname); ++ debug3_f("returning with ccname = %s", *ccname); + return ret; +} + @@ -242,7 +242,7 @@ index a5a81ed2..63f877f2 100644 - logit("mkstemp(): %.100s", strerror(oerrno)); - return oerrno; - } -+ debug3("%s: called", __func__); ++ debug3_f("called"); + if (need_environment) + *need_environment = 0; + ret = ssh_krb5_get_cctemplate(ctx, &ccname); @@ -283,7 +283,7 @@ index a5a81ed2..63f877f2 100644 - close(tmpfd); - return (krb5_cc_resolve(ctx, ccname, ccache)); -+ debug3("%s: setting default ccname to %s", __func__, ccname); ++ debug3_f("setting default ccname to %s", ccname); + /* set the default with already expanded user IDs */ + ret = krb5_cc_set_default_name(ctx, ccname); + if (ret) @@ -304,13 +304,13 @@ index a5a81ed2..63f877f2 100644 + * a primary cache for this collection, if it supports that (non-FILE) + */ + if (krb5_cc_support_switch(ctx, type)) { -+ debug3("%s: calling cc_new_unique(%s)", __func__, ccname); ++ debug3_f("calling cc_new_unique(%s)", ccname); + ret = krb5_cc_new_unique(ctx, type, NULL, ccache); + free(type); + if (ret) + return ret; + -+ debug3("%s: calling cc_switch()", __func__); ++ debug3_f("calling cc_switch()"); + return krb5_cc_switch(ctx, *ccache); + } else { + /* Otherwise, we can not create a unique ccname here (either @@ -318,7 +318,7 @@ index a5a81ed2..63f877f2 100644 + * collections + */ + free(type); -+ debug3("%s: calling cc_resolve(%s)", __func__, ccname); ++ debug3_f("calling cc_resolve(%s)", ccname); + return (krb5_cc_resolve(ctx, ccname, ccache)); + } } @@ -513,7 +513,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c options->gss_authentication = 0; if (options->gss_keyex == -1) @@ -447,7 +450,8 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sChallengeResponseAuthentication, diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index add4727..a6c3bae 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -52,7 +52,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c gss_buffer_desc mic, gssbuf; const char *displayname; @@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mic.value = p; mic.length = len; - ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, @@ -63,7 +63,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c +#endif + micuser = authctxt->user; + ssh_gssapi_buildmic(b, micuser, authctxt->service, - "gssapi-with-mic"); + "gssapi-with-mic", ssh->kex->session_id); if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) @@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple @@ -80,7 +80,7 @@ diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c +++ openssh/auth2-hostbased.c 2018-08-22 11:14:56.816430924 +0200 @@ -123,7 +123,16 @@ userauth_hostbased(struct ssh *ssh) /* reconstruct packet */ - if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || + if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || +#ifdef WITH_SELINUX + (authctxt->role @@ -224,8 +224,8 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c + monitor_permit_authentications(1); + + if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ debug3("%s: role=%s", __func__, authctxt->role); ++ fatal_f("buffer error: %s", ssh_err(r)); ++ debug3_f("role=%s", authctxt->role); + + if (strlen(authctxt->role) == 0) { + free(authctxt->role); @@ -251,7 +251,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c @@ -1251,6 +1280,8 @@ monitor_valid_userblob(u_char *data, u_i fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse userstyle"); + if ((s = strchr(cp, '/')) != NULL) + *s = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, @@ -269,7 +269,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c @@ -1308,6 +1339,8 @@ monitor_valid_hostbasedblob(u_char *data fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse userstyle"); + if ((s = strchr(p, '/')) != NULL) + *s = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, @@ -305,12 +305,12 @@ diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c + int r; + struct sshbuf *m; + -+ debug3("%s entering", __func__); ++ debug3_f("entering"); + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_f("buffer error: %s", ssh_err(r)); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m); + + sshbuf_free(m); @@ -357,7 +357,7 @@ diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/por -void -ssh_selinux_setup_exec_context(char *pwname) -{ -- security_context_t user_ctx = NULL; +- char *user_ctx = NULL; - - if (!ssh_selinux_enabled()) - return; @@ -393,7 +393,7 @@ diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/por - user_ctx = ssh_selinux_getctxbyname(pwname); + if (getexeccon(&user_ctx) != 0) { -+ error("%s: getexeccon: %s", __func__, strerror(errno)); ++ error_f("getexeccon: %s", strerror(errno)); + goto out; + } + @@ -418,7 +418,7 @@ diff -up openssh/openbsd-compat/port-linux.h.role-mls openssh/openbsd-compat/por diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compat/port-linux-sshd.c --- openssh/openbsd-compat/port-linux-sshd.c.role-mls 2018-08-22 11:14:56.819430949 +0200 +++ openssh/openbsd-compat/port-linux-sshd.c 2018-08-22 11:14:56.819430949 +0200 -@@ -0,0 +1,425 @@ +@@ -0,0 +1,421 @@ +/* + * Copyright (c) 2005 Daniel Walsh + * Copyright (c) 2014 Petr Lautrbach @@ -530,7 +530,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + access_vector_t bit; + security_class_t class; + -+ debug("%s: src:%s dst:%s", __func__, src, dst); ++ debug_f("src:%s dst:%s", src, dst); + class = string_to_security_class("context"); + if (!class) { + error("string_to_security_class failed to translate security class context"); @@ -692,7 +692,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + /* we actually don't change level */ + reqlvl = ""; + -+ debug("%s: current connection level '%s'", __func__, reqlvl); ++ debug_f("current connection level '%s'", reqlvl); + + } + @@ -720,8 +720,8 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + } + } + if (r != 0) { -+ error("%s: Failed to get default SELinux security " -+ "context for %s", __func__, pwname); ++ error_f("Failed to get default SELinux security " ++ "context for %s", pwname); + } + +#ifdef HAVE_GETSEUSERBYNAME @@ -746,7 +746,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + char *use_current; + int rv; + -+ debug3("%s: setting execution context", __func__); ++ debug3_f("setting execution context"); + + ssh_selinux_get_role_level(&role, &reqlvl); + @@ -783,32 +783,30 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + if (sshd_selinux_setup_pam_variables()) { + switch (security_getenforce()) { + case -1: -+ fatal("%s: security_getenforce() failed", __func__); ++ fatal_f("security_getenforce() failed"); + case 0: -+ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.", -+ __func__); ++ error_f("SELinux PAM variable setup failure. Continuing in permissive mode."); + break; + default: -+ fatal("%s: SELinux PAM variable setup failure. Aborting connection.", -+ __func__); ++ fatal_f("SELinux PAM variable setup failure. Aborting connection."); + } + } + return; + } + -+ debug3("%s: setting execution context", __func__); ++ debug3_f("setting execution context"); + + r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); + if (r >= 0) { + r = setexeccon(user_ctx); + if (r < 0) { -+ error("%s: Failed to set SELinux execution context %s for %s", -+ __func__, user_ctx, pwname); ++ error_f("Failed to set SELinux execution context %s for %s", ++ user_ctx, pwname); + } +#ifdef HAVE_SETKEYCREATECON + else if (setkeycreatecon(user_ctx) < 0) { -+ error("%s: Failed to set SELinux keyring creation context %s for %s", -+ __func__, user_ctx, pwname); ++ error_f("Failed to set SELinux keyring creation context %s for %s", ++ user_ctx, pwname); + } +#endif + } @@ -823,14 +821,12 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + if (r < 0) { + switch (security_getenforce()) { + case -1: -+ fatal("%s: security_getenforce() failed", __func__); ++ fatal_f("security_getenforce() failed"); + case 0: -+ error("%s: SELinux failure. Continuing in permissive mode.", -+ __func__); ++ error_f("ELinux failure. Continuing in permissive mode."); + break; + default: -+ fatal("%s: SELinux failure. Aborting connection.", -+ __func__); ++ fatal_f("SELinux failure. Aborting connection."); + } + } + if (user_ctx != NULL && user_ctx != default_ctx) @@ -838,7 +834,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa + if (default_ctx != NULL) + freecon(default_ctx); + -+ debug3("%s: done", __func__); ++ debug3_f("done"); +} + +#endif diff --git a/openssh-7.9p1-ssh-copy-id.patch b/openssh-7.9p1-ssh-copy-id.patch deleted file mode 100644 index 24598b8..0000000 --- a/openssh-7.9p1-ssh-copy-id.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 22bfdcf060b632b5a6ff603f8f42ff166c211a66 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 29 Sep 2020 10:02:45 +0000 -Subject: [PATCH] Fail hard on the first failed attempt to write the - authorized_keys_file - ---- - ssh-copy-id | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id -index 392f64f..e69a23f 100755 ---- a/contrib/ssh-copy-id -+++ b/contrib/ssh-copy-id -@@ -251,7 +251,7 @@ installkeys_sh() { - cd; - umask 077; - mkdir -p $(dirname "${AUTH_KEY_FILE}") && -- { [ -z \`tail -1c ${AUTH_KEY_FILE} 2>/dev/null\` ] || echo >> ${AUTH_KEY_FILE}; } && -+ { [ -z \`tail -1c ${AUTH_KEY_FILE} 2>/dev/null\` ] || echo >> ${AUTH_KEY_FILE} || exit 1; } && - cat >> ${AUTH_KEY_FILE} || - exit 1; - if type restorecon >/dev/null 2>&1; then --- -GitLab - - diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index fe2f7cd..813b7ac 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,17 +359,17 @@ or +@@ -359,14 +359,13 @@ or .Qq *.c.example.com domains. .It Cm CASignatureAlgorithms @@ -14,19 +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 --ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, --ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384, +-ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa -.Ed -.Pp .Xr ssh 1 will not accept host certificates signed using algorithms other than those specified. -+.Pp - .It Cm CertificateFile - Specifies a file from which the user's certificate is read. - A corresponding private key must be provided separately in order @@ -424,20 +424,25 @@ If the option is set to - .Cm no , + (the default), the check will not be executed. .It Cm Ciphers +The default is handled system-wide by @@ -133,8 +129,8 @@ diff -up openssh-8.2p1/ssh_config.5.crypto-policies openssh-8.2p1/ssh_config.5 The list of available key exchange algorithms may also be obtained using .Qq ssh -Q kex . @@ -1231,37 +1228,33 @@ The default is INFO. - DEBUG and DEBUG1 are equivalent. - DEBUG2 and DEBUG3 each specify higher levels of verbose output. + file. + This option is intended for debugging and no overrides are enabled by default. .It Cm MACs +The default is handled system-wide by +.Xr crypto-policies 7 . @@ -179,56 +175,57 @@ 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,36 +1387,25 @@ instead of continuing to execute and pas +@@ -1394,37 +1387,25 @@ instead of continuing to execute and pas The default is .Cm no . - .It Cm PubkeyAcceptedKeyTypes + .It Cm PubkeyAcceptedAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . +To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . +.Pp - Specifies the key types that will be used for public key authentication - as a comma-separated list of patterns. + Specifies the signature algorithms that will be used for public key + authentication as a comma-separated list of patterns. If the specified list begins with a .Sq + --character, then the key types after it will be appended to the default +-character, then the algorithms after it will be appended to the default -instead of replacing it. -+character, then the key types after it will be appended to the built-in ++character, then the algorithms after it will be appended to the built-in +openssh default instead of replacing it. If the specified list begins with a .Sq - - character, then the specified key types (including wildcards) will be removed + character, then the specified algorithms (including wildcards) will be removed -from the default set instead of replacing them. +from the built-in openssh default set instead of replacing them. If the specified list begins with a .Sq ^ - character, then the specified key types will be placed at the head of the + character, then the specified algorithms will be placed at the head of the -default set. -The default for this option is: -.Bd -literal -offset 3n +-ssh-ed25519-cert-v01@openssh.com, -ecdsa-sha2-nistp256-cert-v01@openssh.com, -ecdsa-sha2-nistp384-cert-v01@openssh.com, -ecdsa-sha2-nistp521-cert-v01@openssh.com, --sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, --ssh-ed25519-cert-v01@openssh.com, -sk-ssh-ed25519-cert-v01@openssh.com, +-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, -rsa-sha2-512-cert-v01@openssh.com, -rsa-sha2-256-cert-v01@openssh.com, -ssh-rsa-cert-v01@openssh.com, +-ssh-ed25519, -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-sk-ssh-ed25519@openssh.com, -sk-ecdsa-sha2-nistp256@openssh.com, --ssh-ed25519,sk-ssh-ed25519@openssh.com, -rsa-sha2-512,rsa-sha2-256,ssh-rsa -.Ed +built-in openssh default set. .Pp - The list of available key types may also be obtained using - .Qq ssh -Q PubkeyAcceptedKeyTypes . + 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,16 +375,16 @@ If the argument is +@@ -375,14 +375,13 @@ If the argument is then no banner is displayed. By default, no banner is displayed. .It Cm CASignatureAlgorithms @@ -241,16 +238,13 @@ 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 --ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, --ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa +-ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384, +-ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa -.Ed -.Pp Certificates signed using other algorithms will not be accepted for public key or host-based authentication. -+.Pp .It Cm ChallengeResponseAuthentication - Specifies whether challenge-response authentication is allowed (e.g. via - PAM or through authentication styles supported in @@ -446,20 +446,25 @@ The default is indicating not to .Xr chroot 2 . @@ -295,7 +289,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,22 +679,24 @@ For this to work +@@ -681,21 +679,22 @@ For this to work .Cm GSSAPIKeyExchange needs to be enabled in the server and also used by the client. .It Cm GSSAPIKexAlgorithms @@ -326,11 +320,9 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 -.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, -gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . This option only applies to connections using GSSAPI. -+.Pp - .It Cm HostbasedAcceptedKeyTypes - Specifies the key types that will be accepted for hostbased authentication - as a list of comma-separated patterns. -@@ -793,25 +793,13 @@ is specified, the location of the socket + .It Cm HostbasedAcceptedAlgorithms + Specifies the signature algorithms that will be accepted for hostbased +@@ -793,26 +793,13 @@ is specified, the location of the socket .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms @@ -339,26 +331,27 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 +To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . +.Pp - Specifies the host key algorithms + Specifies the host key signature algorithms that the server offers. -The default for this option is: -.Bd -literal -offset 3n +-ssh-ed25519-cert-v01@openssh.com, -ecdsa-sha2-nistp256-cert-v01@openssh.com, -ecdsa-sha2-nistp384-cert-v01@openssh.com, -ecdsa-sha2-nistp521-cert-v01@openssh.com, --sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, --ssh-ed25519-cert-v01@openssh.com, -sk-ssh-ed25519-cert-v01@openssh.com, +-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, -rsa-sha2-512-cert-v01@openssh.com, -rsa-sha2-256-cert-v01@openssh.com, -ssh-rsa-cert-v01@openssh.com, +-ssh-ed25519, -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-sk-ssh-ed25519@openssh.com, -sk-ecdsa-sha2-nistp256@openssh.com, --ssh-ed25519,sk-ssh-ed25519@openssh.com, -rsa-sha2-512,rsa-sha2-256,ssh-rsa -.Ed -.Pp - The list of available key types may also be obtained using + 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 @@ -392,7 +385,7 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 .Pp .Bl -item -compact -offset indent @@ -988,15 +981,6 @@ ecdh-sha2-nistp521 - sntrup4591761x25519-sha512@tinyssh.org + sntrup761x25519-sha512@openssh.com .El .Pp -The default is: @@ -408,8 +401,8 @@ diff -up openssh-8.2p1/sshd_config.5.crypto-policies openssh-8.2p1/sshd_config.5 .Qq ssh -Q KexAlgorithms . .It Cm ListenAddress @@ -1065,21 +1049,26 @@ DEBUG and DEBUG1 are equivalent. - DEBUG2 and DEBUG3 each specify higher levels of debugging output. - Logging with a DEBUG level violates the privacy of users and is not recommended. + file. + This option is intended for debugging and no overrides are enabled by default. .It Cm MACs +The default is handled system-wide by +.Xr crypto-policies 7 . @@ -454,49 +447,50 @@ 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,36 +1460,25 @@ or equivalent.) +@@ -1480,37 +1460,25 @@ or equivalent.) The default is .Cm yes . - .It Cm PubkeyAcceptedKeyTypes + .It Cm PubkeyAcceptedAlgorithms +The default is handled system-wide by +.Xr crypto-policies 7 . +To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . +.Pp - Specifies the key types that will be accepted for public key authentication - as a list of comma-separated patterns. + Specifies the signature algorithms that will be accepted for public key + authentication as a list of comma-separated patterns. Alternately if the specified list begins with a .Sq + --character, then the specified key types will be appended to the default set +-character, then the specified algorithms will be appended to the default set -instead of replacing them. -+character, then the specified key types will be appended to the built-in ++character, then the specified algorithms will be appended to the built-in +openssh default set instead of replacing them. If the specified list begins with a .Sq - - character, then the specified key types (including wildcards) will be removed + character, then the specified algorithms (including wildcards) will be removed -from the default set instead of replacing them. +from the built-in openssh default set instead of replacing them. If the specified list begins with a .Sq ^ - character, then the specified key types will be placed at the head of the + character, then the specified algorithms will be placed at the head of the -default set. -The default for this option is: -.Bd -literal -offset 3n +-ssh-ed25519-cert-v01@openssh.com, -ecdsa-sha2-nistp256-cert-v01@openssh.com, -ecdsa-sha2-nistp384-cert-v01@openssh.com, -ecdsa-sha2-nistp521-cert-v01@openssh.com, --sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, --ssh-ed25519-cert-v01@openssh.com, -sk-ssh-ed25519-cert-v01@openssh.com, +-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, -rsa-sha2-512-cert-v01@openssh.com, -rsa-sha2-256-cert-v01@openssh.com, -ssh-rsa-cert-v01@openssh.com, +-ssh-ed25519, -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +-sk-ssh-ed25519@openssh.com, -sk-ecdsa-sha2-nistp256@openssh.com, --ssh-ed25519,sk-ssh-ed25519@openssh.com, -rsa-sha2-512,rsa-sha2-256,ssh-rsa -.Ed +built-in openssh default set. .Pp - The list of available key types may also be obtained using - .Qq ssh -Q PubkeyAcceptedKeyTypes . + The list of available signature algorithms may also be obtained using + .Qq ssh -Q PubkeyAcceptedAlgorithms . diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index 770e99e..2c29486 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -5,7 +5,7 @@ index e7549470..b68c1710 100644 @@ -109,6 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ - sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ + kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ sshbuf-io.o @@ -17,7 +17,7 @@ index e7549470..b68c1710 100644 - auth2-gss.o gss-serv.o gss-serv-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o \ + srclimit.o sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff --git a/auth.c b/auth.c index 086b8ebb..687c57b4 100644 @@ -138,7 +138,7 @@ index 9351e042..d6446c0c 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,7 +1,7 @@ - /* $OpenBSD: auth2-gss.c,v 1.29 2018/07/31 03:10:27 djm Exp $ */ + /* $OpenBSD: auth2-gss.c,v 1.32 2021/01/27 10:15:08 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -165,19 +165,19 @@ index 9351e042..d6446c0c 100644 + + if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) -+ fatal("%s: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "parsing"); + + if ((b = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + mic.value = p; + mic.length = len; + + ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, -+ "gssapi-keyex"); ++ "gssapi-keyex", ssh->kex->session_id); + + if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -+ fatal("%s: sshbuf_mutable_ptr failed", __func__); ++ fatal_f("sshbuf_mutable_ptr failed"); + gssbuf.length = sshbuf_len(b); + + /* gss_kex_context is NULL with privsep, so we can't check it here */ @@ -197,7 +197,7 @@ index 9351e042..d6446c0c 100644 * how to check local user kuserok and the like) @@ -260,7 +302,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) if ((r = sshpkt_get_end(ssh)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse packet"); - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, @@ -441,7 +441,7 @@ index d56257b4..763a63ff 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -1,7 +1,7 @@ - /* $OpenBSD: gss-genr.c,v 1.26 2018/07/10 09:13:30 djm Exp $ */ + /* $OpenBSD: gss-genr.c,v 1.28 2021/01/27 10:05:28 djm Exp $ */ /* - * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. @@ -449,7 +449,7 @@ index d56257b4..763a63ff 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -41,12 +41,36 @@ +@@ -41,9 +41,33 @@ #include "sshbuf.h" #include "log.h" #include "ssh2.h" @@ -461,9 +461,6 @@ index d56257b4..763a63ff 100644 #include "ssh-gss.h" - extern u_char *session_id2; - extern u_int session_id2_len; - +typedef struct { + char *encoded; + gss_OID oid; @@ -486,7 +483,7 @@ index d56257b4..763a63ff 100644 /* sshbuf_get for gss_buffer_desc */ int ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) -@@ -62,6 +86,162 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) +@@ -62,6 +86,159 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) return 0; } @@ -548,7 +545,7 @@ index d56257b4..763a63ff 100644 + (gss_supported->count + 1)); + + if ((buf = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + oidpos = 0; + s = cp = xstrdup(kex); @@ -565,8 +562,7 @@ index d56257b4..763a63ff 100644 + gss_supported->elements[i].elements, + gss_supported->elements[i].length)) != 0 || + (r = ssh_digest_final(md, digest, sizeof(digest))) != 0) -+ fatal("%s: digest failed: %s", __func__, -+ ssh_err(r)); ++ fatal_fr(r, "digest failed"); + ssh_digest_free(md); + md = NULL; + @@ -581,12 +577,10 @@ index d56257b4..763a63ff 100644 + (p = strsep(&cp, ","))) { + if (sshbuf_len(buf) != 0 && + (r = sshbuf_put_u8(buf, ',')) != 0) -+ fatal("%s: sshbuf_put_u8 error: %s", -+ __func__, ssh_err(r)); ++ fatal_fr(r, "sshbuf_put_u8 error"); + if ((r = sshbuf_put(buf, p, strlen(p))) != 0 || + (r = sshbuf_put(buf, encoded, enclen)) != 0) -+ fatal("%s: sshbuf_put error: %s", -+ __func__, ssh_err(r)); ++ fatal_fr(r, "sshbuf_put error"); + } + + gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); @@ -599,7 +593,7 @@ index d56257b4..763a63ff 100644 + gss_enc2oid[oidpos].encoded = NULL; + + if ((mechs = sshbuf_dup_string(buf)) == NULL) -+ fatal("%s: sshbuf_dup_string failed", __func__); ++ fatal_f("sshbuf_dup_string failed"); + + sshbuf_free(buf); + @@ -721,7 +715,7 @@ index d56257b4..763a63ff 100644 + void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, - const char *context) + const char *context, const struct sshbuf *session_id) @@ -273,11 +500,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, } @@ -1123,10 +1117,10 @@ index ab3a15f0..6ce56e92 100644 + + if (gssapi_client.store.data != NULL) { + if ((problem = krb5_cc_resolve(gssapi_client.store.data, gssapi_client.store.envval, &ccache))) { -+ debug("%s: krb5_cc_resolve(): %.100s", __func__, ++ debug_f("krb5_cc_resolve(): %.100s", + krb5_get_err_text(gssapi_client.store.data, problem)); + } else if ((problem = krb5_cc_destroy(gssapi_client.store.data, ccache))) { -+ debug("%s: krb5_cc_destroy(): %.100s", __func__, ++ debug_f("krb5_cc_destroy(): %.100s", + krb5_get_err_text(gssapi_client.store.data, problem)); + } else { + krb5_free_context(gssapi_client.store.data); @@ -1375,7 +1369,7 @@ index ce85f043..574c7609 100644 @@ -698,6 +755,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->server_version); sshbuf_free(kex->client_pub); - free(kex->session_id); + sshbuf_free(kex->session_id); +#ifdef GSSAPI + free(kex->gss_host); +#endif /* GSSAPI */ @@ -1389,7 +1383,7 @@ index a5ae6ac0..fe714141 100644 @@ -102,6 +102,15 @@ enum kex_exchange { KEX_ECDH_SHA2, KEX_C25519_SHA256, - KEX_KEM_SNTRUP4591761X25519_SHA512, + KEX_KEM_SNTRUP761X25519_SHA512, +#ifdef GSSAPI + KEX_GSS_GRP1_SHA1, + KEX_GSS_GRP14_SHA1, @@ -1498,7 +1492,7 @@ new file mode 100644 index 00000000..f6e1405e --- /dev/null +++ b/kexgssc.c -@@ -0,0 +1,606 @@ +@@ -0,0 +1,599 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. + * @@ -1597,7 +1591,7 @@ index 00000000..f6e1405e + r = kex_c25519_keypair(kex); + break; + default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal_f("Unexpected KEX type %d", kex->kex_type); + } + if (r != 0) + return r; @@ -1785,7 +1779,7 @@ index 00000000..f6e1405e + server_blob, + shared_secret, + hash, &hashlen)) != 0) -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal_f("Unexpected KEX type %d", kex->kex_type); + + gssbuf.value = hash; + gssbuf.length = hashlen; @@ -2074,13 +2068,6 @@ index 00000000..f6e1405e + + gss_release_buffer(&min_status, &msg_tok); + -+ /* save session id */ -+ if (kex->session_id == NULL) { -+ kex->session_id_len = hashlen; -+ kex->session_id = xmalloc(kex->session_id_len); -+ memcpy(kex->session_id, hash, kex->session_id_len); -+ } -+ + if (kex->gss_deleg_creds) + ssh_gssapi_credentials_updated(ctxt); + @@ -2202,12 +2189,12 @@ index 00000000..60bc02de + free(mechs); + } + -+ debug2("%s: Identifying %s", __func__, kex->name); ++ debug2_f("Identifying %s", kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) + fatal("Unknown gssapi mechanism"); + -+ debug2("%s: Acquiring credentials", __func__); ++ debug2_f("Acquiring credentials"); + + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + fatal("Unable to acquire credentials for the server"); @@ -2242,7 +2229,7 @@ index 00000000..60bc02de + &shared_secret); + break; + default: -+ fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); ++ fatal_f("Unexpected KEX type %d", kex->kex_type); + } + if (r != 0) + goto out; @@ -2398,12 +2385,12 @@ index 00000000..60bc02de + if ((mechs = ssh_gssapi_server_mechanisms())) + free(mechs); + -+ debug2("%s: Identifying %s", __func__, kex->name); ++ debug2_f("Identifying %s", kex->name); + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); + if (oid == GSS_C_NO_OID) + fatal("Unknown gssapi mechanism"); + -+ debug2("%s: Acquiring credentials", __func__); ++ debug2_f("Acquiring credentials"); + + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) + fatal("Unable to acquire credentials for the server"); @@ -2641,44 +2628,44 @@ index 2ce89fe9..ebf76c7f 100644 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); @@ -1713,6 +1730,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) # ifdef OPENSSL_HAS_ECC - kex->kex[KEX_ECDH_SHA2] = kex_gen_server; + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif +# ifdef GSSAPI -+ if (options.gss_keyex) { -+ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; -+ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; -+ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; -+ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; -+ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; -+ } ++ if (options.gss_keyex) { ++ kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; ++ kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; ++ kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; ++ kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; ++ kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; ++ } +# endif #endif /* WITH_OPENSSL */ - kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; @@ -1806,8 +1834,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_char *p; int r; - if (!options.gss_authentication) -- fatal("%s: GSSAPI authentication not enabled", __func__); +- fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); if ((r = sshbuf_get_string(m, &p, &len)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); @@ -1839,8 +1867,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 flags = 0; /* GSI needs this */ int r; - if (!options.gss_authentication) -- fatal("%s: GSSAPI authentication not enabled", __func__); +- fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "ssh_gssapi_get_buffer_desc"); @@ -1860,6 +1888,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); @@ -2692,9 +2679,9 @@ index 2ce89fe9..ebf76c7f 100644 int r; - if (!options.gss_authentication) -- fatal("%s: GSSAPI authentication not enabled", __func__); +- fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) @@ -2707,13 +2694,13 @@ index 2ce89fe9..ebf76c7f 100644 const char *displayname; - if (!options.gss_authentication) -- fatal("%s: GSSAPI authentication not enabled", __func__); +- fatal_f("GSSAPI authentication not enabled"); + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); - authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); + if ((r = sshbuf_get_u32(m, &kex)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + authenticated = authctxt->valid && + ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); @@ -2721,7 +2708,7 @@ index 2ce89fe9..ebf76c7f 100644 sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) @@ -1913,7 +1946,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) - debug3("%s: sending result %d", __func__, authenticated); + debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); - auth_method = "gssapi-with-mic"; @@ -2733,7 +2720,7 @@ index 2ce89fe9..ebf76c7f 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -1921,5 +1958,85 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1921,5 +1958,84 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2749,16 +2736,15 @@ index 2ce89fe9..ebf76c7f 100644 + int r; + + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); + + if ((r = sshbuf_get_string(m, &p, &len)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + data.value = p; + data.length = len; + /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */ + if (data.length != 20 && data.length != 32 && data.length != 64) -+ fatal("%s: data length incorrect: %d", __func__, -+ (int) data.length); ++ fatal_f("data length incorrect: %d", (int) data.length); + + /* Save the session ID on the first time around */ + if (session_id2_len == 0) { @@ -2774,7 +2760,7 @@ index 2ce89fe9..ebf76c7f 100644 + + if ((r = sshbuf_put_u32(m, major)) != 0 || + (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); + @@ -2795,12 +2781,12 @@ index 2ce89fe9..ebf76c7f 100644 + int r, ok; + + if (!options.gss_authentication && !options.gss_keyex) -+ fatal("%s: GSSAPI not enabled", __func__); ++ fatal_f("GSSAPI not enabled"); + + if ((r = sshbuf_get_string(m, (u_char **)&store.filename, NULL)) != 0 || + (r = sshbuf_get_string(m, (u_char **)&store.envvar, NULL)) != 0 || + (r = sshbuf_get_string(m, (u_char **)&store.envval, NULL)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + ok = ssh_gssapi_update_creds(&store); + @@ -2810,7 +2796,7 @@ index 2ce89fe9..ebf76c7f 100644 + + sshbuf_reset(m); + if ((r = sshbuf_put_u32(m, ok)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); + @@ -2847,14 +2833,14 @@ index 001a8fa1..6edb509a 100644 int r, authenticated = 0; if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, kex)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); mm_request_receive_expect(pmonitor->m_recvfd, @@ -1012,4 +1014,57 @@ mm_ssh_gssapi_userok(char *user) - debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); + debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } + @@ -2866,16 +2852,16 @@ index 001a8fa1..6edb509a 100644 + int r; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_string(m, data->value, data->length)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, m); + + if ((r = sshbuf_get_u32(m, &major)) != 0 || + (r = ssh_gssapi_get_buffer_desc(m, hash)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + sshbuf_free(m); + @@ -2889,7 +2875,7 @@ index 001a8fa1..6edb509a 100644 + int r, ok; + + if ((m = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + if ((r = sshbuf_put_cstring(m, + store->filename ? store->filename : "")) != 0 || @@ -2897,13 +2883,13 @@ index 001a8fa1..6edb509a 100644 + store->envvar ? store->envvar : "")) != 0 || + (r = sshbuf_put_cstring(m, + store->envval ? store->envval : "")) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, m); + + if ((r = sshbuf_get_u32(m, &ok)) != 0) -+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "buffer error"); + + sshbuf_free(m); + @@ -3124,7 +3110,7 @@ index 70f5f73f..191575a1 100644 options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -531,6 +543,7 @@ typedef enum { - sHostKeyAlgorithms, + sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, @@ -3246,7 +3232,7 @@ index 36180d07..70dd3665 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -1,6 +1,6 @@ - /* $OpenBSD: ssh-gss.h,v 1.14 2018/07/10 09:13:30 djm Exp $ */ + /* $OpenBSD: ssh-gss.h,v 1.15 2021/01/27 10:05:28 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -3332,7 +3318,7 @@ index 36180d07..70dd3665 100644 @@ -123,17 +149,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(struct sshbuf *, const char *, - const char *, const char *); + const char *, const char *, const struct sshbuf *); -int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); +int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); +OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); @@ -3382,7 +3368,7 @@ index 60de6087..db5c65bc 100644 +.It GSSAPITrustDns .It HashKnownHosts .It Host - .It HostbasedAuthentication + .It HostbasedAcceptedAlgorithms @@ -579,6 +585,8 @@ flag), (supported message integrity codes), .Ar kex @@ -3526,9 +3512,9 @@ index af00fb30..03bc87eb 100644 + xxx_host = host; xxx_hostaddr = hostaddr; - + xxx_conn_info = cinfo; @@ -206,6 +209,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) - compat_pkalg_proposal(options.hostkeyalgorithms); + compat_pkalg_proposal(ssh, options.hostkeyalgorithms); } +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3588,7 +3574,7 @@ index af00fb30..03bc87eb 100644 +# endif +#endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; - ssh->kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_client; + ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; ssh->kex->verify_host_key=&verify_host_key_callback; +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3604,7 +3590,7 @@ index af00fb30..03bc87eb 100644 /* remove ext-info from the KEX proposals for rekeying */ myproposal[PROPOSAL_KEX_ALGS] = - compat_kex_proposal(options.kex_algorithms); + compat_kex_proposal(ssh, options.kex_algorithms); +#if defined(GSSAPI) && defined(WITH_OPENSSL) + /* repair myproposal after it was crumpled by the */ + /* ext-info removal above */ @@ -3616,7 +3602,7 @@ index af00fb30..03bc87eb 100644 + } +#endif if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0) - fatal("kex_prop2buf: %s", ssh_err(r)); + fatal_r(r, "kex_prop2buf"); @@ -330,6 +392,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *); static int input_gssapi_token(int type, u_int32_t, struct ssh *); @@ -3714,13 +3700,13 @@ index af00fb30..03bc87eb 100644 + } + + if ((b = sshbuf_new()) == NULL) -+ fatal("%s: sshbuf_new failed", __func__); ++ fatal_f("sshbuf_new failed"); + + ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, -+ "gssapi-keyex"); ++ "gssapi-keyex", ssh->kex->session_id); + + if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) -+ fatal("%s: sshbuf_mutable_ptr failed", __func__); ++ fatal_f("sshbuf_mutable_ptr failed"); + gssbuf.length = sshbuf_len(b); + + if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { @@ -3734,7 +3720,7 @@ index af00fb30..03bc87eb 100644 + (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || + (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 || + (r = sshpkt_send(ssh)) != 0) -+ fatal("%s: %s", __func__, ssh_err(r)); ++ fatal_fr(r, "parsing"); + + sshbuf_free(b); + gss_release_buffer(&ms, &mic); @@ -3751,11 +3737,11 @@ index 60b2aaf7..d92f03aa 100644 +++ b/sshd.c @@ -817,8 +817,8 @@ notify_hostkeys(struct ssh *ssh) } - debug3("%s: sent %u hostkeys", __func__, nkeys); + debug3_f("sent %u hostkeys", nkeys); if (nkeys == 0) -- fatal("%s: no hostkeys", __func__); +- fatal_f("no hostkeys"); - if ((r = sshpkt_send(ssh)) != 0) -+ debug3("%s: no hostkeys", __func__); ++ debug3_f("no hostkeys"); + else if ((r = sshpkt_send(ssh)) != 0) sshpkt_fatal(ssh, r, "%s: send", __func__); sshbuf_free(buf); @@ -3772,7 +3758,7 @@ index 60b2aaf7..d92f03aa 100644 } @@ -2347,6 +2348,48 @@ do_ssh2_kex(struct ssh *ssh) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( - list_hostkey_types()); + ssh, list_hostkey_types()); +#if defined(GSSAPI) && defined(WITH_OPENSSL) + { @@ -3818,7 +3804,7 @@ index 60b2aaf7..d92f03aa 100644 + /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) - fatal("kex_setup: %s", ssh_err(r)); + fatal_r(r, "kex_setup"); @@ -2362,7 +2405,18 @@ do_ssh2_kex(struct ssh *ssh) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; @@ -3837,7 +3823,7 @@ index 60b2aaf7..d92f03aa 100644 +# endif +#endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; kex->load_host_public_key=&get_hostkey_public_by_type; diff --git a/sshd_config b/sshd_config index 19b7c91a..2c48105f 100644 @@ -3898,9 +3884,9 @@ index 70ccea44..f6b41a2f 100644 +.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-, +gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- . +This option only applies to connections using GSSAPI. - .It Cm HostbasedAcceptedKeyTypes - Specifies the key types that will be accepted for hostbased authentication - as a list of comma-separated patterns. + .It Cm HostbasedAcceptedAlgorithms + Specifies the signature algorithms that will be accepted for hostbased + authentication as a list of comma-separated patterns. diff --git a/sshkey.c b/sshkey.c index 57995ee6..fd5b7724 100644 --- a/sshkey.c diff --git a/openssh-8.0p1-openssl-kdf.patch b/openssh-8.0p1-openssl-kdf.patch index 1db95c3..5d76a4f 100644 --- a/openssh-8.0p1-openssl-kdf.patch +++ b/openssh-8.0p1-openssl-kdf.patch @@ -96,7 +96,7 @@ index b6f041f4..1fbce2bb 100644 + goto out; + } + r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, -+ kex->session_id, kex->session_id_len); ++ sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id)); + if (r != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 0713ffe..748ab48 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -57,26 +57,26 @@ index e7549470..4511f82a 100644 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/kexfuzz/*.o - rm -f regress/misc/kexfuzz/kexfuzz$(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 - rm -f regress/misc/kexfuzz/*.o - rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) (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/kexfuzz $(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) @@ -91,17 +91,17 @@ index e7549470..4511f82a 100644 + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + - MISC_KEX_FUZZ_OBJS=\ - regress/misc/kexfuzz/kexfuzz.o \ - $(SKOBJS) + # 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) \ - regress/misc/kexfuzz/kexfuzz$(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 @@ -1075,10 +1075,10 @@ index 7eb6f0dc..27d8e4af 100644 + char *provider = NULL, *pin = NULL, *sane_uri = NULL; char **comments = NULL; int r, i, count = 0, success = 0, confirm = 0; - u_int seconds; + u_int seconds = 0; @@ -681,33 +743,28 @@ process_add_smartcard_key(SocketEntry *e) - goto send; - } + error_f("failed to parse constraints"); + goto send; } - if (realpath(provider, canonical_provider) == NULL) { - verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", @@ -1093,13 +1093,13 @@ index 7eb6f0dc..27d8e4af 100644 + if (sane_uri == NULL) goto send; - } -- debug("%s: add %.100s", __func__, canonical_provider); +- debug_f("add %.100s", canonical_provider); + if (lifetime && !death) death = monotime() + lifetime; - count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments); -+ debug("%s: add %.100s", __func__, sane_uri); ++ debug_f("add %.100s", sane_uri); + count = pkcs11_add_provider(sane_uri, pin, &keys, &comments); for (i = 0; i < count; i++) { k = keys[i]; @@ -1147,8 +1147,8 @@ index 7eb6f0dc..27d8e4af 100644 goto send; - } -- debug("%s: remove %.100s", __func__, canonical_provider); -+ debug("%s: remove %.100s", __func__, sane_uri); +- debug_f("remove %.100s", canonical_provider); ++ debug_f("remove %.100s", sane_uri); for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { nxt = TAILQ_NEXT(id, next); /* Skip file--based keys */ @@ -1165,7 +1165,7 @@ index 7eb6f0dc..27d8e4af 100644 + if (pkcs11_del_provider(sane_uri) == 0) success = 1; else - error("%s: pkcs11_del_provider failed", __func__); + error_f("pkcs11_del_provider failed"); send: free(provider); + free(sane_uri); @@ -1198,7 +1198,7 @@ index 8a0ffef5..ead8a562 100644 u_int nkeys, i; struct sshbuf *msg; -+ debug("%s: called, name = %s", __func__, name); ++ debug_f("called, name = %s", name); + if (fd < 0 && pkcs11_start_helper() < 0) return (-1); @@ -1207,7 +1207,7 @@ index 8a0ffef5..ead8a562 100644 *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); -+ debug("%s: nkeys = %u", __func__, nkeys); ++ 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 || @@ -1216,7 +1216,7 @@ new file mode 100644 index 00000000..e1a7b4e0 --- /dev/null +++ b/ssh-pkcs11-uri.c -@@ -0,0 +1,425 @@ +@@ -0,0 +1,419 @@ +/* + * Copyright (c) 2017 Red Hat + * @@ -1493,13 +1493,12 @@ index 00000000..e1a7b4e0 + 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("%s: The '%s' does not look like PKCS#11 URI", -+ __func__, uri); ++ error_f("The '%s' does not look like PKCS#11 URI", uri); + return -1; + } + + if (pkcs11 == NULL) { -+ error("%s: Bad arguments. The pkcs11 can't be null", __func__); ++ error_f("Bad arguments. The pkcs11 can't be null"); + return -1; + } + @@ -1510,7 +1509,7 @@ index 00000000..e1a7b4e0 + /* everything before ? */ + tok = strtok_r(str1, "?", &saveptr1); + if (tok == NULL) { -+ error("%s: pk11-path expected, got EOF", __func__); ++ error_f("pk11-path expected, got EOF"); + rv = -1; + goto out; + } @@ -1536,35 +1535,32 @@ index 00000000..e1a7b4e0 + case pId: + /* CKA_ID */ + if (pkcs11->id != NULL) { -+ verbose("%s: The id already set in the PKCS#11 URI", -+ __func__); ++ 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("%s: Failed to percent-decode CKA_ID: %s", -+ __func__, arg); ++ verbose_f("Failed to percent-decode CKA_ID: %s", arg); + rv = -1; + goto out; + } else + pkcs11->id_len = len; -+ debug3("%s: Setting CKA_ID = %s from PKCS#11 URI", -+ __func__, arg); ++ 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("%s: The %s already set in the PKCS#11 URI", -+ keywords[opcode].name, __func__); ++ verbose_f("The %s already set in the PKCS#11 URI", ++ keywords[opcode].name); + rv = -1; + goto out; + } + percent_decode(arg, charptr); -+ debug3("%s: Setting %s = %s from PKCS#11 URI", -+ __func__, keywords[opcode].name, *charptr); ++ debug3_f("Setting %s = %s from PKCS#11 URI", ++ keywords[opcode].name, *charptr); + break; + + case pObject: @@ -1584,8 +1580,7 @@ index 00000000..e1a7b4e0 + + default: + /* Unrecognized attribute in the URI path SHOULD be error */ -+ verbose("%s: Unknown part of path in PKCS#11 URI: %s", -+ __func__, tok); ++ verbose_f("Unknown part of path in PKCS#11 URI: %s", tok); + } + } + @@ -1608,32 +1603,31 @@ index 00000000..e1a7b4e0 + case pModulePath: + /* module-path is PKCS11Provider */ + if (pkcs11->module_path != NULL) { -+ verbose("%s: Multiple module-path attributes are" -+ "not supported the PKCS#11 URI", __func__); ++ verbose_f("Multiple module-path attributes are" ++ "not supported the PKCS#11 URI"); + rv = -1; + goto out; + } + percent_decode(arg, &pkcs11->module_path); -+ debug3("%s: Setting PKCS11Provider = %s from PKCS#11 URI", -+ __func__, pkcs11->module_path); ++ debug3_f("Setting PKCS11Provider = %s from PKCS#11 URI", ++ pkcs11->module_path); + break; + + case pPinValue: + /* pin-value */ + if (pkcs11->pin != NULL) { -+ verbose("%s: Multiple pin-value attributes are" -+ "not supported the PKCS#11 URI", __func__); ++ verbose_f("Multiple pin-value attributes are" ++ "not supported the PKCS#11 URI"); + rv = -1; + goto out; + } + percent_decode(arg, &pkcs11->pin); -+ debug3("%s: Setting PIN from PKCS#11 URI", __func__); ++ debug3_f("Setting PIN from PKCS#11 URI"); + break; + + default: + /* Unrecognized attribute in the URI query SHOULD be ignored */ -+ verbose("%s: Unknown part of query in PKCS#11 URI: %s", -+ __func__, tok); ++ verbose_f("Unknown part of query in PKCS#11 URI: %s", tok); + } + } +out: @@ -1727,7 +1721,7 @@ index a302c79c..879fe917 100644 }; int pkcs11_interactive = 0; -@@ -106,26 +114,63 @@ pkcs11_init(int interactive) +@@ -106,26 +114,61 @@ pkcs11_init(int interactive) * this is called when a provider gets unregistered. */ static void @@ -1740,8 +1734,7 @@ index a302c79c..879fe917 100644 - debug("pkcs11_provider_finalize: %p refcount %d valid %d", - p, p->refcount, p->valid); - if (!p->valid) -+ debug("%s: %p refcount %d valid %d", __func__, -+ m, m->refcount, m->valid); ++ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); + if (!m->valid) return; - for (i = 0; i < p->nslots; i++) { @@ -1769,11 +1762,11 @@ index a302c79c..879fe917 100644 +static void +pkcs11_module_unref(struct pkcs11_module *m) +{ -+ debug("%s: %p refcount %d", __func__, m, m->refcount); ++ debug_f("%p refcount %d", m, m->refcount); + if (--m->refcount <= 0) { + pkcs11_module_finalize(m); + if (m->valid) -+ error("%s: %p still valid", __func__, m); ++ error_f("%p still valid", m); + free(m->slotlist); + free(m->slotinfo); + free(m->module_path); @@ -1790,8 +1783,7 @@ index a302c79c..879fe917 100644 +static void +pkcs11_provider_finalize(struct pkcs11_provider *p) +{ -+ debug("%s: %p refcount %d valid %d", __func__, -+ p, p->refcount, p->valid); ++ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); + if (!p->valid) + return; + pkcs11_module_unref(p->module); @@ -1807,7 +1799,7 @@ index a302c79c..879fe917 100644 pkcs11_provider_unref(struct pkcs11_provider *p) { - debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); -+ debug("%s: %p refcount %d", __func__, p, p->refcount); ++ debug_f("%p refcount %d", p, p->refcount); if (--p->refcount <= 0) { - if (p->valid) - error("pkcs11_provider_unref: %p still valid", p); @@ -1853,7 +1845,7 @@ index a302c79c..879fe917 100644 + int rv; + struct pkcs11_uri *uri; + -+ debug("%s: called, provider_id = %s", __func__, provider_id); ++ debug_f("called, provider_id = %s", provider_id); + + uri = pkcs11_uri_init(); + if (uri == NULL) @@ -1881,7 +1873,7 @@ index a302c79c..879fe917 100644 + char *provider_uri = pkcs11_uri_get(uri); - if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3("%s(%s): called", __func__, provider_uri); ++ debug3_f("called with provider %s", provider_uri); + + if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { TAILQ_REMOVE(&pkcs11_providers, p, next); @@ -1977,7 +1969,7 @@ index a302c79c..879fe917 100644 si->token.label); - if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { + if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { - debug("%s: no pin specified", __func__); + debug_f("no pin specified"); return (-1); /* bail out */ } } @@ -2296,7 +2288,7 @@ index a302c79c..879fe917 100644 error("BN_bin2bn failed"); goto fail; @@ -871,7 +1032,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - fatal("%s: set key", __func__); + fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ - if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) @@ -2508,7 +2500,7 @@ index a302c79c..879fe917 100644 int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1484,167 +1670,303 @@ pkcs11_register_provider(char *provider_id, char *pin, +@@ -1484,164 +1670,298 @@ pkcs11_register_provider(char *provider_id, char *pin, CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2522,7 +2514,7 @@ index a302c79c..879fe917 100644 +#ifdef PKCS11_DEFAULT_PROVIDER + provider_module = strdup(PKCS11_DEFAULT_PROVIDER); +#else -+ error("%s: No module path provided", __func__); ++ error_f("No module path provided"); goto fail; - *providerp = NULL; - @@ -2536,16 +2528,14 @@ index a302c79c..879fe917 100644 + } - if (pkcs11_provider_lookup(provider_id) != NULL) { -- debug("%s: provider already registered: %s", -- __func__, provider_id); +- 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("%s: provider module already initialized: %s", -+ __func__, provider_module); ++ debug_f("provider module already initialized: %s", provider_module); + free(provider_module); + /* Skip the initialization of PKCS#11 module */ + m->refcount++; @@ -2605,8 +2595,8 @@ index a302c79c..879fe917 100644 + rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); + if (uri->lib_manuf != NULL && + strcmp(uri->lib_manuf, m->info.manufacturerID)) { -+ debug("%s: Skipping provider %s not matching library_manufacturer", -+ __func__, m->info.manufacturerID); ++ debug_f("Skipping provider %s not matching library_manufacturer", ++ m->info.manufacturerID); + goto fail; + } + rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); @@ -2634,9 +2624,8 @@ index a302c79c..879fe917 100644 } - if (p->nslots == 0) { + if (m->nslots == 0) { - debug("%s: provider %s returned no slots", __func__, -- provider_id); -+ provider_module); +- debug_f("provider %s returned no slots", provider_id); ++ debug_f("provider %s returned no slots", provider_module); ret = -SSH_PKCS11_ERR_NO_SLOTS; goto fail; } @@ -2663,8 +2652,8 @@ index a302c79c..879fe917 100644 + if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) != CKR_OK) { error("C_GetTokenInfo for provider %s slot %lu " -- "failed: %lu", provider_id, (unsigned long)i, rv); -+ "failed: %lu", provider_module, (unsigned long)i, rv); +- "failed: %lu", provider_id, (u_long)i, rv); ++ "failed: %lu", provider_module, (u_long)i, rv); + token->flags = 0; continue; } @@ -2735,25 +2724,23 @@ index a302c79c..879fe917 100644 + for (i = 0; i < p->module->nslots; i++) { + token = &p->module->slotinfo[i].token; if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { - debug2("%s: ignoring uninitialised token in " - "provider %s slot %lu", __func__, -- provider_id, (unsigned long)i); -+ provider_uri, (unsigned long)i); + debug2_f("ignoring uninitialised token in " +- "provider %s slot %lu", provider_id, (u_long)i); ++ "provider %s slot %lu", provider_uri, (u_long)i); + continue; + } + if (uri->token != NULL && + strcmp(token->label, uri->token) != 0) { -+ debug2("%s: ignoring token not matching label (%s) " -+ "specified by PKCS#11 URI in slot %lu", __func__, ++ debug2_f("ignoring token not matching label (%s) " ++ "specified by PKCS#11 URI in slot %lu", + token->label, (unsigned long)i); + continue; + } + if (uri->manuf != NULL && + strcmp(token->manufacturerID, uri->manuf) != 0) { -+ debug2("%s: ignoring token not matching requrested " ++ debug2_f("ignoring token not matching requrested " + "manufacturerID (%s) specified by PKCS#11 URI in " -+ "slot %lu", __func__, -+ token->manufacturerID, (unsigned long)i); ++ "slot %lu", token->manufacturerID, (unsigned long)i); continue; } - rmspace(token->label, sizeof(token->label)); @@ -2789,8 +2776,7 @@ index a302c79c..879fe917 100644 * expose keys. */ - if (pkcs11_login_slot(p, &p->slotinfo[i], -+ debug3("%s: Trying to login as there were no keys found", -+ __func__); ++ debug3_f("Trying to login as there were no keys found"); + if (pkcs11_login_slot(p, &p->module->slotinfo[i], CKU_USER) < 0) { error("login failed"); @@ -2802,8 +2788,8 @@ index a302c79c..879fe917 100644 + pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); + } + if (nkeys == 0 && uri->object != NULL) { -+ debug3("%s: No keys found. Retrying without label (%s) ", -+ __func__, uri->object); ++ debug3_f("No keys found. Retrying without label (%s) ", ++ uri->object); + /* Try once more without the label filter */ + char *label = uri->object; + uri->object = NULL; /* XXX clone uri? */ @@ -2852,7 +2838,7 @@ index a302c79c..879fe917 100644 + struct pkcs11_uri *uri = NULL; + int r; + -+ debug("%s: called, provider_id = %s", __func__, provider_id); ++ debug_f("called, provider_id = %s", provider_id); + + uri = pkcs11_uri_init(); + if (uri == NULL) @@ -2878,12 +2864,11 @@ index a302c79c..879fe917 100644 +pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, + struct sshkey ***keyp, char ***labelsp) { -- struct pkcs11_provider *p = NULL; + struct pkcs11_provider *p = NULL; int nkeys; -+ struct pkcs11_provider *p = NULL; + char *provider_uri = pkcs11_uri_get(uri); + -+ debug("%s: called, provider_uri = %s", __func__, provider_uri); ++ debug_f("called, provider_uri = %s", provider_uri); - nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, - &p, CKU_USER); @@ -2892,11 +2877,11 @@ index a302c79c..879fe917 100644 /* 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("%s: provider %s returned no keys", __func__, -- provider_id); -+ provider_uri); +- debug_f("provider %s returned no keys", provider_id); ++ debug_f("provider %s returned no keys", provider_uri); + + free(provider_uri); + return nkeys; @@ -2930,26 +2915,6 @@ index a302c79c..879fe917 100644 return (nkeys); } -@@ -1674,7 +2026,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, - - if ((p = pkcs11_provider_lookup(provider_id)) != NULL) - debug("%s: provider \"%s\" available", __func__, provider_id); -- else if ((ret = pkcs11_register_provider(provider_id, pin, NULL, NULL, -+ else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, NULL, - &p, CKU_SO)) < 0) { - debug("%s: could not register provider %s", __func__, - provider_id); -@@ -1746,8 +2098,8 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, - - if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { - debug("%s: using provider \"%s\"", __func__, provider_id); -- } else if (pkcs11_register_provider(provider_id, pin, NULL, NULL, &p, -- CKU_SO) < 0) { -+ } else if ((rv = pkcs11_register_provider(provider_id, pin, NULL, NULL, -+ &p, CKU_SO)) < 0) { - debug("%s: could not register provider %s", __func__, - provider_id); - goto out; diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h index 81f1d7c5..feaf74de 100644 --- a/ssh-pkcs11.h @@ -2995,7 +2960,7 @@ index 15aee569..976844cb 100644 + pkcs11_terminate(); skip_connect: - exit_status = ssh_session2(ssh, pw); + 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); } @@ -3041,7 +3006,7 @@ index 15aee569..976844cb 100644 + /* Loads all IdentityFile and CertificateFile keys */ static void - load_public_identity_files(struct passwd *pw) + 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]; @@ -3117,9 +3082,9 @@ index 15aee569..976844cb 100644 + } +#endif /* ENABLE_PKCS11 */ + cp = tilde_expand_filename(name, getuid()); - filename = default_client_percent_dollar_expand(cp, - pw->pw_dir, host, options.user, pw->pw_name); + 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 diff --git a/openssh-8.2p1-x11-without-ipv6.patch b/openssh-8.2p1-x11-without-ipv6.patch index 18b0376..8b83bc3 100644 --- a/openssh-8.2p1-x11-without-ipv6.patch +++ b/openssh-8.2p1-x11-without-ipv6.patch @@ -7,8 +7,8 @@ diff --git a/channels.c b/channels.c if (x11_use_localhost) set_reuseaddr(sock); if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { - debug2("%s: bind port %d: %.100s", __func__, - port, strerror(errno)); + debug2_f("bind port %d: %.100s", port, + strerror(errno)); close(sock); + + /* do not remove successfully opened diff --git a/openssh-8.4p1-debian-compat.patch b/openssh-8.4p1-debian-compat.patch index 0af1d3d..1285979 100644 --- a/openssh-8.4p1-debian-compat.patch +++ b/openssh-8.4p1-debian-compat.patch @@ -37,8 +37,8 @@ + * SHA2 signature types. + */ + if (alg == NULL && -+ (key->type == KEY_RSA && (datafellows & SSH_BUG_SIGTYPE74))) { -+ oallowed = allowed = xstrdup(options.pubkey_key_types); ++ (key->type == KEY_RSA && (ssh->compat & SSH_BUG_SIGTYPE74))) { ++ oallowed = allowed = xstrdup(options.pubkey_accepted_algos); + while ((cp = strsep(&allowed, ",")) != NULL) { + if (sshkey_type_from_name(cp) != key->type) + continue; diff --git a/openssh-8.4p1-sandbox-seccomp.patch b/openssh-8.4p1-sandbox-seccomp.patch deleted file mode 100644 index ac4ee61..0000000 --- a/openssh-8.4p1-sandbox-seccomp.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index e0768c06..5065ae7e 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -267,6 +267,9 @@ static const struct sock_filter preauth_insns[] = { - #ifdef __NR_pselect6 - SC_ALLOW(__NR_pselect6), - #endif -+#ifdef __NR_pselect6_time64 -+ SC_ALLOW(__NR_pselect6_time64), -+#endif - #ifdef __NR_read - SC_ALLOW(__NR_read), - #endif diff --git a/openssh-8.4p1-ssh-copy-id.patch b/openssh-8.4p1-ssh-copy-id.patch deleted file mode 100644 index 7bc4c7d..0000000 --- a/openssh-8.4p1-ssh-copy-id.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 66f16e5425eb881570e82bfef7baeac2e7accc0a Mon Sep 17 00:00:00 2001 -From: Oleg -Date: Thu, 1 Oct 2020 12:09:08 +0300 -Subject: [PATCH] Fix `EOF: command not found` error in ssh-copy-id - ---- - contrib/ssh-copy-id | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id -index 392f64f94..a76907717 100644 ---- a/contrib/ssh-copy-id -+++ b/contrib/ssh-copy-id -@@ -247,7 +247,7 @@ installkeys_sh() { - # the -z `tail ...` checks for a trailing newline. The echo adds one if was missing - # the cat adds the keys we're getting via STDIN - # and if available restorecon is used to restore the SELinux context -- INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF) -+ INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF - cd; - umask 077; - mkdir -p $(dirname "${AUTH_KEY_FILE}") && -@@ -258,6 +258,7 @@ installkeys_sh() { - restorecon -F .ssh ${AUTH_KEY_FILE}; - fi - EOF -+ ) - - # to defend against quirky remote shells: use 'exec sh -c' to get POSIX; - printf "exec sh -c '%s'" "${INSTALLKEYS_SH}" - -From de59a431cdec833e3ec15691dd950402b4c052cf Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Sat, 3 Oct 2020 00:20:07 +0200 -Subject: [PATCH] un-nest $() to make ksh cheerful - ---- - ssh-copy-id | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -From 02ac2c3c3db5478a440dfb1b90d15f686f2cbfc6 Mon Sep 17 00:00:00 2001 -From: Philip Hands -Date: Fri, 2 Oct 2020 21:30:10 +0200 -Subject: [PATCH] ksh doesn't grok 'local' - -and AFAICT it's not actually doing anything useful in the code, so let's -see how things go without it. ---- - ssh-copy-id | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id -index a769077..11c9463 100755 ---- a/contrib/ssh-copy-id -+++ b/contrib/ssh-copy-id -@@ -76,7 +76,7 @@ quote() { - } - - use_id_file() { -- local L_ID_FILE="$1" -+ L_ID_FILE="$1" - - if [ -z "$L_ID_FILE" ] ; then - printf '%s: ERROR: no ID file found\n' "$0" -@@ -94,7 +94,7 @@ use_id_file() { - # check that the files are readable - for f in "$PUB_ID_FILE" ${PRIV_ID_FILE:+"$PRIV_ID_FILE"} ; do - ErrMSG=$( { : < "$f" ; } 2>&1 ) || { -- local L_PRIVMSG="" -+ L_PRIVMSG="" - [ "$f" = "$PRIV_ID_FILE" ] && L_PRIVMSG=" (to install the contents of '$PUB_ID_FILE' anyway, look at the -f option)" - printf "\\n%s: ERROR: failed to open ID file '%s': %s\\n" "$0" "$f" "$(printf '%s\n%s\n' "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')" - exit 1 -@@ -169,7 +169,7 @@ fi - # populate_new_ids() uses several global variables ($USER_HOST, $SSH_OPTS ...) - # and has the side effect of setting $NEW_IDS - populate_new_ids() { -- local L_SUCCESS="$1" -+ L_SUCCESS="$1" - - # shellcheck disable=SC2086 - if [ "$FORCED" ] ; then -@@ -181,13 +181,12 @@ populate_new_ids() { - eval set -- "$SSH_OPTS" - - umask 0177 -- local L_TMP_ID_FILE - L_TMP_ID_FILE=$(mktemp ~/.ssh/ssh-copy-id_id.XXXXXXXXXX) - if test $? -ne 0 || test "x$L_TMP_ID_FILE" = "x" ; then - printf '%s: ERROR: mktemp failed\n' "$0" >&2 - exit 1 - fi -- local L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\"" -+ L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\"" - # shellcheck disable=SC2064 - trap "$L_CLEANUP" EXIT TERM INT QUIT - printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2 -@@ -237,7 +236,7 @@ populate_new_ids() { - # produce a one-liner to add the keys to remote authorized_keys file - # optionally takes an alternative path for authorized_keys - installkeys_sh() { -- local AUTH_KEY_FILE=${1:-.ssh/authorized_keys} -+ AUTH_KEY_FILE=${1:-.ssh/authorized_keys} - - # In setting INSTALLKEYS_SH: - # the tr puts it all on one line (to placate tcsh) --- - -diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id -index 11c9463..ee3f637 100755 ---- a/contrib/ssh-copy-id -+++ b/contrib/ssh-copy-id -@@ -237,6 +237,7 @@ populate_new_ids() { - # optionally takes an alternative path for authorized_keys - installkeys_sh() { - AUTH_KEY_FILE=${1:-.ssh/authorized_keys} -+ AUTH_KEY_DIR=$(dirname "${AUTH_KEY_FILE}") - - # In setting INSTALLKEYS_SH: - # the tr puts it all on one line (to placate tcsh) -@@ -249,7 +250,7 @@ installkeys_sh() { - INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF - cd; - umask 077; -- mkdir -p $(dirname "${AUTH_KEY_FILE}") && -+ mkdir -p "${AUTH_KEY_DIR}" && - { [ -z \`tail -1c ${AUTH_KEY_FILE} 2>/dev/null\` ] || echo >> ${AUTH_KEY_FILE} || exit 1; } && - cat >> ${AUTH_KEY_FILE} || - exit 1; --- diff --git a/openssh.spec b/openssh.spec index 11c0725..6f172dc 100644 --- a/openssh.spec +++ b/openssh.spec @@ -50,21 +50,21 @@ %{?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.4p1 -%global openssh_rel 5 +%global openssh_ver 8.5p1 +%global openssh_rel 2 %global pam_ssh_agent_ver 0.10.4 -%global pam_ssh_agent_rel 1 +%global pam_ssh_agent_rel 2 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 Source1: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc Source2: sshd.pam -Source3: DJM-GPG-KEY.gpg +Source3: gpgkey-736060BA.gpg Source4: https://github.com/jbeverly/pam_ssh_agent_auth/archive/pam_ssh_agent_auth-%{pam_ssh_agent_ver}.tar.gz Source5: pam_ssh_agent-rmheaders Source6: ssh-keycat.pam @@ -75,6 +75,7 @@ Source11: sshd.service Source12: sshd-keygen@.service Source13: sshd-keygen Source15: sshd-keygen.target +Source16: ssh-agent.service #https://bugzilla.mindrot.org/show_bug.cgi?id=2581 Patch100: openssh-6.7p1-coverity.patch @@ -178,9 +179,6 @@ Patch950: openssh-7.5p1-sandbox.patch Patch951: openssh-8.0p1-pkcs11-uri.patch # Unbreak scp between two IPv6 hosts (#1620333) Patch953: openssh-7.8p1-scp-ipv6.patch -# ssh-copy-id is unmaintained: Aggreagete patches -# https://gitlab.com/phil_hands/ssh-copy-id/-/merge_requests/2 -Patch958: openssh-7.9p1-ssh-copy-id.patch # Mention crypto-policies in manual pages (#1668325) Patch962: openssh-8.0p1-crypto-policies.patch # Use OpenSSL high-level API to produce and verify signatures (#1707485) @@ -191,9 +189,6 @@ Patch964: openssh-8.0p1-openssl-kdf.patch Patch965: openssh-8.2p1-visibility.patch # Do not break X11 without IPv6 Patch966: openssh-8.2p1-x11-without-ipv6.patch -Patch967: openssh-8.4p1-ssh-copy-id.patch -# https://bugzilla.mindrot.org/show_bug.cgi?id=3232 -Patch968: openssh-8.4p1-sandbox-seccomp.patch # https://bugzilla.mindrot.org/show_bug.cgi?id=3213 Patch969: openssh-8.4p1-debian-compat.patch @@ -216,6 +211,7 @@ BuildRequires: pam-devel BuildRequires: openssl-devel >= 0.9.8j BuildRequires: perl-podlators BuildRequires: systemd-devel +BuildRequires: systemd-rpm-macros BuildRequires: gcc make BuildRequires: p11-kit-devel BuildRequires: libfido2-devel @@ -266,7 +262,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}.3 +Release: %{pam_ssh_agent_rel}.%{openssh_rel}%{?dist} License: BSD %description @@ -364,14 +360,11 @@ popd %patch950 -p1 -b .sandbox %patch951 -p1 -b .pkcs11-uri %patch953 -p1 -b .scp-ipv6 -%patch958 -p1 -b .ssh-copy-id %patch962 -p1 -b .crypto-policies %patch963 -p1 -b .openssl-evp %patch964 -p1 -b .openssl-kdf %patch965 -p1 -b .visibility %patch966 -p1 -b .x11-ipv6 -%patch967 -p1 -b .ssh-copy-id -%patch968 -p1 -b .seccomp %patch969 -p0 -b .debian %patch200 -p1 -b .audit @@ -517,6 +510,8 @@ install -m644 %{SOURCE10} $RPM_BUILD_ROOT/%{_unitdir}/sshd.socket install -m644 %{SOURCE11} $RPM_BUILD_ROOT/%{_unitdir}/sshd.service install -m644 %{SOURCE12} $RPM_BUILD_ROOT/%{_unitdir}/sshd-keygen@.service install -m644 %{SOURCE15} $RPM_BUILD_ROOT/%{_unitdir}/sshd-keygen.target +install -d -m755 $RPM_BUILD_ROOT/%{_userunitdir} +install -m644 %{SOURCE16} $RPM_BUILD_ROOT/%{_userunitdir}/ssh-agent.service install -m744 %{SOURCE13} $RPM_BUILD_ROOT/%{_libexecdir}/openssh/sshd-keygen install -m755 contrib/ssh-copy-id $RPM_BUILD_ROOT%{_bindir}/ install contrib/ssh-copy-id.1 $RPM_BUILD_ROOT%{_mandir}/man1/ @@ -573,6 +568,12 @@ test -f %{sysconfig_anaconda} && \ %postun server %systemd_postun_with_restart sshd.service +%post clients +%systemd_user_post ssh-agent.service + +%preun clients +%systemd_user_preun ssh-agent.service + %files %license LICENCE %doc CREDITS ChangeLog OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns TODO @@ -607,6 +608,7 @@ test -f %{sysconfig_anaconda} && \ %attr(0644,root,root) %{_mandir}/man1/ssh-copy-id.1* %attr(0644,root,root) %{_mandir}/man8/ssh-pkcs11-helper.8* %attr(0644,root,root) %{_mandir}/man8/ssh-sk-helper.8* +%attr(0644,root,root) %{_userunitdir}/ssh-agent.service %files server %dir %attr(0711,root,root) %{_datadir}/empty.sshd @@ -648,6 +650,16 @@ test -f %{sysconfig_anaconda} && \ %endif %changelog +* Tue Mar 09 2021 Rex Dieter - 8.5p1-2 +- ssh-agent.serivce is user unit (#1761817#27) + +* Wed Mar 03 2021 Jakub Jelen - 8.5p1-1 + 0.10.4-2 +- New upstream release (#1934336) + +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 8.4p1-5.2 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + * Tue Jan 26 2021 Fedora Release Engineering - 8.4p1-5.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild diff --git a/sources b/sources index 41d33d0..173dd73 100644 --- a/sources +++ b/sources @@ -1,4 +1,4 @@ -SHA512 (openssh-8.4p1.tar.gz) = d65275b082c46c5efe7cf3264fa6794d6e99a36d4a54b50554fc56979d6c0837381587fd5399195e1db680d2a5ad1ef0b99a180eac2b4de5637906cb7a89e9ce -SHA512 (openssh-8.4p1.tar.gz.asc) = 3d9a026db27729a5a56785db3824230ccf2a3beca4bb48ef465e44d869b944dbc5d443152a1b1be21bc9c213c465d3d7ca1f876a387d0a6b9682a0cfec3e6e32 +SHA512 (openssh-8.5p1.tar.gz) = af9c34d89170a30fc92a63973e32c766ed4a6d254bb210e317c000d46913e78d0c60c7befe62d993d659be000b828b9d4d3832fc40df1c3d33850aaa6293846f +SHA512 (openssh-8.5p1.tar.gz.asc) = 264a991c7207f2215875e2b472a649ede1a69f6486d25777bf522047c26ea77c2995d34b6917a993ea9a250b7dd5298a30f1975e20e471f079c9064ce283cec2 SHA512 (pam_ssh_agent_auth-0.10.4.tar.gz) = caccf72174d15e43f4c86a459ac6448682e62116557cf1e1e828955f3d1731595b238df42adec57860e7f341e92daf5d8285020bcb5018f3b8a5145aa32ee1c2 -SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d +SHA512 (gpgkey-736060BA.gpg) = df44f3fdbcd1d596705348c7f5aed3f738c5f626a55955e0642f7c6c082995cf36a1b1891bb41b8715cb2aff34fef1c877e0eff0d3507dd00a055ba695757a21 diff --git a/ssh-agent.service b/ssh-agent.service new file mode 100644 index 0000000..c215022 --- /dev/null +++ b/ssh-agent.service @@ -0,0 +1,14 @@ +# Requires SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket" +# set in environment, handled for example in plasma via +# /etc/xdg/plasma-workspace/env/ssh-agent.sh +[Unit] +ConditionEnvironment=!SSH_AGENT_PID +Description=OpenSSH key agent +Documentation=man:ssh-agent(1) man:ssh-add(1) man:ssh(1) + +[Service] +Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket +ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK +PassEnvironment=SSH_AGENT_PID +SuccessExitStatus=2 +Type=forking