diff --git a/CVE-2018-15919.patch b/CVE-2018-15919.patch deleted file mode 100644 index 4eefc9d6d134f50a01e29b7a4e863e2466fca644..0000000000000000000000000000000000000000 --- a/CVE-2018-15919.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 4286e434ab29c077a42d52c97e7a2e92f93fc1c3 Mon Sep 17 00:00:00 2001 -From: zhuqingfu -Date: Tue, 15 Sep 2020 15:09:52 +0800 -Subject: [PATCH] CVE-2018-15919 - ---- - auth.h | 1 + - auth2-gss.c | 1 + - auth2.c | 4 ++++ - 3 files changed, 6 insertions(+) - -diff --git a/auth.h b/auth.h -index c3a92df..1127fdf 100644 ---- a/auth.h -+++ b/auth.h -@@ -58,6 +58,7 @@ struct Authctxt { - int attempt; - int failures; - int server_caused_failure; -+ int server_caused_gssapi_failure; - int force_pwchange; - char *user; /* username sent by the client */ - char *service; -diff --git a/auth2-gss.c b/auth2-gss.c -index 4708375..6008319 100644 ---- a/auth2-gss.c -+++ b/auth2-gss.c -@@ -156,6 +156,7 @@ userauth_gssapi(struct ssh *ssh) - ssh_gssapi_delete_ctx(&ctxt); - free(doid); - authctxt->server_caused_failure = 1; -+ authctxt->server_caused_gssapi_failure = 1; - return (0); - } - -diff --git a/auth2.c b/auth2.c -index 956b9cf..2c4fc97 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -345,6 +345,7 @@ if (options.check_user_splash) - auth2_authctxt_reset_info(authctxt); - authctxt->postponed = 0; - authctxt->server_caused_failure = 0; -+ authctxt->server_caused_gssapi_failure = 0; - - /* try to authenticate user */ - m = authmethod_lookup(authctxt, method); -@@ -442,6 +443,9 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method, - if (!partial && !authctxt->server_caused_failure && - (authctxt->attempt > 1 || strcmp(method, "none") != 0)) - authctxt->failures++; -+ if (!partial && authctxt->server_caused_gssapi_failure && -+ (authctxt->attempt > 1 || strcmp(method, "none") != 0)) -+ authctxt->failures++; - if (authctxt->failures >= options.max_authtries) { - #ifdef SSH_AUDIT_EVENTS - PRIVSEP(audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES)); --- -1.8.3.1 - diff --git a/CVE-2020-12062-1.patch b/CVE-2020-12062-1.patch deleted file mode 100644 index 7c1ae1e1130771dc4541111545b871d041616c87..0000000000000000000000000000000000000000 --- a/CVE-2020-12062-1.patch +++ /dev/null @@ -1,202 +0,0 @@ -From aad87b88fc2536b1ea023213729aaf4eaabe1894 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Fri, 1 May 2020 06:31:42 +0000 -Subject: [PATCH] upstream: when receving a file in sink(), be careful to send - at - -most a single error response after the file has been opened. Otherwise the -source() and sink() can become desyncronised. Reported by Daniel Goujot, -Georges-Axel Jaloyan, Ryan Lahfa, and David Naccache. - -ok deraadt@ markus@ - -OpenBSD-Commit-ID: 6c14d233c97349cb811a8f7921ded3ae7d9e0035 ---- - scp.c | 96 ++++++++++++++++++++++++++++++++++++----------------------- - 1 file changed, 59 insertions(+), 37 deletions(-) - -diff --git a/scp.c b/scp.c -index 812ab5301..439025980 100644 ---- a/scp.c -+++ b/scp.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: scp.c,v 1.207 2020/01/23 07:10:22 dtucker Exp $ */ -+/* $OpenBSD: scp.c,v 1.209 2020/05/01 06:31:42 djm Exp $ */ - /* - * scp - secure remote copy. This is basically patched BSD rcp which - * uses ssh to do the data transfer (instead of using rcmd). -@@ -374,6 +374,7 @@ BUF *allocbuf(BUF *, int, int); - void lostconn(int); - int okname(char *); - void run_err(const char *,...); -+int note_err(const char *,...); - void verifydir(char *); - - struct passwd *pwd; -@@ -1231,9 +1232,6 @@ sink(int argc, char **argv, const char *src) - { - static BUF buffer; - struct stat stb; -- enum { -- YES, NO, DISPLAYED -- } wrerr; - BUF *bp; - off_t i; - size_t j, count; -@@ -1241,7 +1239,7 @@ sink(int argc, char **argv, const char *src) - mode_t mode, omode, mask; - off_t size, statbytes; - unsigned long long ull; -- int setimes, targisdir, wrerrno = 0; -+ int setimes, targisdir, wrerr; - char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; - char **patterns = NULL; - size_t n, npatterns = 0; -@@ -1450,8 +1448,13 @@ bad: run_err("%s: %s", np, strerror(errno)); - continue; - } - cp = bp->buf; -- wrerr = NO; -+ wrerr = 0; - -+ /* -+ * NB. do not use run_err() unless immediately followed by -+ * exit() below as it may send a spurious reply that might -+ * desyncronise us from the peer. Use note_err() instead. -+ */ - statbytes = 0; - if (showprogress) - start_progress_meter(curfile, size, &statbytes); -@@ -1476,11 +1479,12 @@ bad: run_err("%s: %s", np, strerror(errno)); - - if (count == bp->cnt) { - /* Keep reading so we stay sync'd up. */ -- if (wrerr == NO) { -+ if (!wrerr) { - if (atomicio(vwrite, ofd, bp->buf, - count) != count) { -- wrerr = YES; -- wrerrno = errno; -+ note_err("%s: %s", np, -+ strerror(errno)); -+ wrerr = 1; - } - } - count = 0; -@@ -1488,16 +1492,14 @@ bad: run_err("%s: %s", np, strerror(errno)); - } - } - unset_nonblock(remin); -- if (count != 0 && wrerr == NO && -+ if (count != 0 && !wrerr && - atomicio(vwrite, ofd, bp->buf, count) != count) { -- wrerr = YES; -- wrerrno = errno; -- } -- if (wrerr == NO && (!exists || S_ISREG(stb.st_mode)) && -- ftruncate(ofd, size) != 0) { -- run_err("%s: truncate: %s", np, strerror(errno)); -- wrerr = DISPLAYED; -+ note_err("%s: %s", np, strerror(errno)); -+ wrerr = 1; - } -+ if (!wrerr && (!exists || S_ISREG(stb.st_mode)) && -+ ftruncate(ofd, size) != 0) -+ note_err("%s: truncate: %s", np, strerror(errno)); - if (pflag) { - if (exists || omode != mode) - #ifdef HAVE_FCHMOD -@@ -1505,9 +1507,8 @@ bad: run_err("%s: %s", np, strerror(errno)); - #else /* HAVE_FCHMOD */ - if (chmod(np, omode)) { - #endif /* HAVE_FCHMOD */ -- run_err("%s: set mode: %s", -+ note_err("%s: set mode: %s", - np, strerror(errno)); -- wrerr = DISPLAYED; - } - } else { - if (!exists && omode != mode) -@@ -1516,36 +1517,25 @@ bad: run_err("%s: %s", np, strerror(errno)); - #else /* HAVE_FCHMOD */ - if (chmod(np, omode & ~mask)) { - #endif /* HAVE_FCHMOD */ -- run_err("%s: set mode: %s", -+ note_err("%s: set mode: %s", - np, strerror(errno)); -- wrerr = DISPLAYED; - } - } -- if (close(ofd) == -1) { -- wrerr = YES; -- wrerrno = errno; -- } -+ if (close(ofd) == -1) -+ note_err(np, "%s: close: %s", np, strerror(errno)); - (void) response(); - if (showprogress) - stop_progress_meter(); -- if (setimes && wrerr == NO) { -+ if (setimes && !wrerr) { - setimes = 0; - if (utimes(np, tv) == -1) { -- run_err("%s: set times: %s", -+ note_err("%s: set times: %s", - np, strerror(errno)); -- wrerr = DISPLAYED; - } - } -- switch (wrerr) { -- case YES: -- run_err("%s: %s", np, strerror(wrerrno)); -- break; -- case NO: -+ /* If no error was noted then signal success for this file */ -+ if (note_err(NULL) == 0) - (void) atomicio(vwrite, remout, "", 1); -- break; -- case DISPLAYED: -- break; -- } - } - done: - for (n = 0; n < npatterns; n++) -@@ -1633,6 +1623,38 @@ run_err(const char *fmt,...) - } - } - -+/* -+ * Notes a sink error for sending at the end of a file transfer. Returns 0 if -+ * no error has been noted or -1 otherwise. Use note_err(NULL) to flush -+ * any active error at the end of the transfer. -+ */ -+int -+note_err(const char *fmt, ...) -+{ -+ static char *emsg; -+ va_list ap; -+ -+ /* Replay any previously-noted error */ -+ if (fmt == NULL) { -+ if (emsg == NULL) -+ return 0; -+ run_err("%s", emsg); -+ free(emsg); -+ emsg = NULL; -+ return -1; -+ } -+ -+ errs++; -+ /* Prefer first-noted error */ -+ if (emsg != NULL) -+ return -1; -+ -+ va_start(ap, fmt); -+ vasnmprintf(&emsg, INT_MAX, NULL, fmt, ap); -+ va_end(ap); -+ return -1; -+} -+ - void - verifydir(char *cp) - { diff --git a/CVE-2020-12062-2.patch b/CVE-2020-12062-2.patch deleted file mode 100644 index 2e7caa80835996d40bb4e12edea7c047a5dfdd8a..0000000000000000000000000000000000000000 --- a/CVE-2020-12062-2.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 955854cafca88e0cdcd3d09ca1ad4ada465364a1 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Wed, 6 May 2020 20:57:38 +0000 -Subject: [PATCH] upstream: another case where a utimes() failure could make - scp send - -a desynchronising error; reminded by Aymeric Vincent ok deraadt markus - -OpenBSD-Commit-ID: 2ea611d34d8ff6d703a7a8bf858aa5dbfbfa7381 ---- - scp.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/scp.c b/scp.c -index 439025980..b4492a062 100644 ---- a/scp.c -+++ b/scp.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: scp.c,v 1.209 2020/05/01 06:31:42 djm Exp $ */ -+/* $OpenBSD: scp.c,v 1.210 2020/05/06 20:57:38 djm Exp $ */ - /* - * scp - secure remote copy. This is basically patched BSD rcp which - * uses ssh to do the data transfer (instead of using rcmd). -@@ -1427,9 +1427,7 @@ sink(int argc, char **argv, const char *src) - sink(1, vect, src); - if (setimes) { - setimes = 0; -- if (utimes(vect[0], tv) == -1) -- run_err("%s: set times: %s", -- vect[0], strerror(errno)); -+ (void) utimes(vect[0], tv); - } - if (mod_flag) - (void) chmod(vect[0], mode); diff --git a/CVE-2020-14145.patch b/CVE-2020-14145.patch deleted file mode 100644 index 76fb3e843b640c07525ef6932c6c15f6e54cd065..0000000000000000000000000000000000000000 --- a/CVE-2020-14145.patch +++ /dev/null @@ -1,92 +0,0 @@ -From b3855ff053f5078ec3d3c653cdaedefaa5fc362d Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Fri, 18 Sep 2020 05:23:03 +0000 -Subject: upstream: tweak the client hostkey preference ordering algorithm to - -prefer the default ordering if the user has a key that matches the -best-preference default algorithm. - -feedback and ok markus@ - -OpenBSD-Commit-ID: a92dd7d7520ddd95c0a16786a7519e6d0167d35f ---- - sshconnect2.c | 41 ++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 38 insertions(+), 3 deletions(-) - -diff --git a/sshconnect2.c b/sshconnect2.c -index 347e348c..f64aae66 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: sshconnect2.c,v 1.320 2020/02/06 22:48:23 djm Exp $ */ -+/* $OpenBSD: sshconnect2.c,v 1.326 2020/09/18 05:23:03 djm Exp $ */ - /* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * Copyright (c) 2008 Damien Miller. All rights reserved. -@@ -102,12 +102,25 @@ verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) - return 0; - } - -+/* Returns the first item from a comma-separated algorithm list */ -+static char * -+first_alg(const char *algs) -+{ -+ char *ret, *cp; -+ -+ ret = xstrdup(algs); -+ if ((cp = strchr(ret, ',')) != NULL) -+ *cp = '\0'; -+ return ret; -+} -+ - static char * - order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) - { -- char *oavail, *avail, *first, *last, *alg, *hostname, *ret; -+ char *oavail = NULL, *avail = NULL, *first = NULL, *last = NULL; -+ char *alg = NULL, *hostname = NULL, *ret = NULL, *best = NULL; - size_t maxlen; -- struct hostkeys *hostkeys; -+ struct hostkeys *hostkeys = NULL; - int ktype; - u_int i; - -@@ -119,6 +132,26 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) - for (i = 0; i < options.num_system_hostfiles; i++) - load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); - -+ /* -+ * If a plain public key exists that matches the type of the best -+ * preference HostkeyAlgorithms, then use the whole list as is. -+ * Note that we ignore whether the best preference algorithm is a -+ * certificate type, as sshconnect.c will downgrade certs to -+ * plain keys if necessary. -+ */ -+ best = first_alg(options.hostkeyalgorithms); -+ if (lookup_key_in_hostkeys_by_type(hostkeys, -+ sshkey_type_plain(sshkey_type_from_name(best)), NULL)) { -+ debug3("%s: have matching best-preference key type %s, " -+ "using HostkeyAlgorithms verbatim", __func__, best); -+ ret = xstrdup(options.hostkeyalgorithms); -+ goto out; -+ } -+ -+ /* -+ * Otherwise, prefer the host key algorithms that match known keys -+ * while keeping the ordering of HostkeyAlgorithms as much as possible. -+ */ - oavail = avail = xstrdup(options.hostkeyalgorithms); - maxlen = strlen(avail) + 1; - first = xmalloc(maxlen); -@@ -159,6 +192,8 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) - if (*first != '\0') - debug3("%s: prefer hostkeyalgs: %s", __func__, first); - -+ out: -+ free(best); - free(first); - free(last); - free(hostname); --- -cgit v1.2.3 - diff --git a/add-strict-scp-check-for-CVE-2020-15778.patch b/add-strict-scp-check-for-CVE-2020-15778.patch deleted file mode 100644 index 7dfd9d26a79137ddcf7e2f068d732e7b6c2e532f..0000000000000000000000000000000000000000 --- a/add-strict-scp-check-for-CVE-2020-15778.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 2e0b74242220a97926d006719d1ac6e113918e2b Mon Sep 17 00:00:00 2001 -From: seuzw <930zhaowei@163.com> -Date: Thu, 20 May 2021 20:23:30 +0800 -Subject: [PATCH] add strict-scp-check for CVE-2020-15778 - ---- - servconf.c | 12 ++++++++++++ - servconf.h | 1 + - session.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 63 insertions(+) - -diff --git a/servconf.c b/servconf.c -index 76147f9..4e0401f 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -90,6 +90,7 @@ initialize_server_options(ServerOptions *options) - { - memset(options, 0, sizeof(*options)); - -+ options->strict_scp_check = -1; - /* Portable-specific options */ - options->use_pam = -1; - -@@ -330,6 +331,8 @@ fill_default_server_options(ServerOptions *options) - _PATH_HOST_XMSS_KEY_FILE, 0); - #endif /* WITH_XMSS */ - } -+ if (options->strict_scp_check == -1) -+ options->strict_scp_check = 0; - /* No certificates by default */ - if (options->num_ports == 0) - options->ports[options->num_ports++] = SSH_DEFAULT_PORT; -@@ -540,6 +543,7 @@ fill_default_server_options(ServerOptions *options) - /* Keyword tokens. */ - typedef enum { - sBadOption, /* == unknown option */ -+ sStrictScpCheck, - /* Portable-specific options */ - sUsePAM, - /* Standard Options */ -@@ -598,6 +602,7 @@ static struct { - #else - { "usepam", sUnsupported, SSHCFG_GLOBAL }, - #endif -+ { "strictscpcheck", sStrictScpCheck, SSHCFG_GLOBAL }, - { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL }, - /* Standard Options */ - { "port", sPort, SSHCFG_GLOBAL }, -@@ -1372,6 +1377,11 @@ process_server_config_line_depth(ServerOptions *options, char *line, - /* Standard Options */ - case sBadOption: - return -1; -+ -+ case sStrictScpCheck: -+ intptr = &options->strict_scp_check; -+ goto parse_flag; -+ - case sPort: - /* ignore ports from configfile if cmdline specifies ports */ - if (options->ports_from_cmdline) -@@ -2556,6 +2566,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) - dst->n = src->n; \ - } while (0) - -+ M_CP_INTOPT(strict_scp_check); - M_CP_INTOPT(password_authentication); - M_CP_INTOPT(gss_authentication); - M_CP_INTOPT(pubkey_authentication); -@@ -2846,6 +2857,7 @@ dump_config(ServerOptions *o) - #ifdef USE_PAM - dump_cfg_fmtint(sUsePAM, o->use_pam); - #endif -+ dump_cfg_fmtint(sStrictScpCheck, o->strict_scp_check); - dump_cfg_int(sLoginGraceTime, o->login_grace_time); - dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); - dump_cfg_int(sX11MaxDisplays, o->x11_max_displays); -diff --git a/servconf.h b/servconf.h -index 2c16b5a..e37dc25 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -192,6 +192,7 @@ typedef struct { - * disconnect the session - */ - -+ int strict_scp_check; - u_int num_authkeys_files; /* Files containing public keys */ - char **authorized_keys_files; - -diff --git a/session.c b/session.c -index 607f17a..383c8ee 100644 ---- a/session.c -+++ b/session.c -@@ -175,6 +175,50 @@ static char *auth_sock_dir = NULL; - - /* removes the agent forwarding socket */ - -+int scp_check(const char *command) -+{ -+ debug("Entering scp check"); -+ int check = 0; -+ if (command == NULL) { -+ debug("scp check succeeded for shell mode"); -+ return check; -+ } -+ int lc = strlen(command); -+ char special_characters[] = "|;&$><`\\!\n"; -+ int ls = strlen(special_characters); -+ int count_char[128] = {0}; -+ -+ for (int i = 0; i < ls; i++) { -+ count_char[special_characters[i]] = 1; -+ } -+ -+ char scp_prefix[6] = "scp -"; -+ int lp = 5; -+ -+ if (lc <= lp) { -+ debug("scp check succeeded for length"); -+ return check; -+ } -+ -+ for (int i = 0; i < lp; i++) { -+ if (command[i] - scp_prefix[i]) { -+ debug("scp check succeeded for prefix"); -+ return check; -+ } -+ } -+ -+ for (int i = lp; i < lc; i++) { -+ if (command[i] > 0 && command[i] < 128) { -+ if (count_char[command[i]]) { -+ check = 1; -+ debug("scp check failed at %d: %c", i, command[i]); -+ break; -+ } -+ } -+ } -+ return check; -+} -+ - static void - auth_sock_cleanup_proc(struct passwd *pw) - { -@@ -696,6 +740,12 @@ do_exec(struct ssh *ssh, Session *s, const char *command) - command = auth_opts->force_command; - forced = "(key-option)"; - } -+ -+ if (options.strict_scp_check && scp_check(command)) { -+ verbose("Special characters not allowed in scp"); -+ return 1; -+ } -+ - #ifdef GSSAPI - #ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */ - else if (k5users_allowed_cmds) { --- -2.23.0 - diff --git a/backport-CVE-2021-41617-1.patch b/backport-CVE-2021-41617-1.patch deleted file mode 100644 index 31159d96ea684e6bb10c8b1aca28c62f40b7ceb3..0000000000000000000000000000000000000000 --- a/backport-CVE-2021-41617-1.patch +++ /dev/null @@ -1,34 +0,0 @@ -From f3cbe43e28fe71427d41cfe3a17125b972710455 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Sun, 26 Sep 2021 14:01:03 +0000 -Subject: upstream: need initgroups() before setresgid(); reported by anton@, - -ok deraadt@ - -OpenBSD-Commit-ID: 6aa003ee658b316960d94078f2a16edbc25087ce - ---- - auth.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/auth.c b/auth.c -index c73444a..e510a05 100644 ---- a/auth.c -+++ b/auth.c -@@ -852,6 +852,13 @@ subprocess(const char *tag, struct passwd *pw, const char *command, - } - closefrom(STDERR_FILENO + 1); - -+ if (geteuid() == 0 && -+ initgroups(pw->pw_name, pw->pw_gid) == -1) { -+ error("%s: initgroups(%s, %u): %s", tag, -+ pw->pw_name, (u_int)pw->pw_gid, strerror(errno)); -+ _exit(1); -+ } -+ - /* Don't use permanently_set_uid() here to avoid fatal() */ - if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) { - error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, --- -1.8.3.1 - diff --git a/backport-CVE-2021-41617-2.patch b/backport-CVE-2021-41617-2.patch deleted file mode 100644 index 93871b16ea5ddb1704fb288935fc87ca20f353a3..0000000000000000000000000000000000000000 --- a/backport-CVE-2021-41617-2.patch +++ /dev/null @@ -1,28 +0,0 @@ -From f3cbe43e28fe71427d41cfe3a17125b972710455 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Sun, 26 Sep 2021 14:01:03 +0000 -Subject: upstream: need initgroups() before setresgid(); reported by anton@, - -ok deraadt@ - -OpenBSD-Commit-ID: 6aa003ee658b316960d94078f2a16edbc25087ce - ---- - auth.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/auth.c b/auth.c -index e510a05..46b56cf 100644 ---- a/auth.c -+++ b/auth.c -@@ -39,6 +39,7 @@ - # include - #endif - #include -+#include - #ifdef HAVE_LOGIN_H - #include - #endif --- -1.8.3.1 - diff --git a/backport-move-closefrom-to-before-first-malloc.patch b/backport-move-closefrom-to-before-first-malloc.patch deleted file mode 100644 index b94c365b064fce9ea16e3de6895bff63d6a49bb5..0000000000000000000000000000000000000000 --- a/backport-move-closefrom-to-before-first-malloc.patch +++ /dev/null @@ -1,46 +0,0 @@ -From c9f7bba2e6f70b7ac1f5ea190d890cb5162ce127 Mon Sep 17 00:00:00 2001 -From: Darren Tucker -Date: Fri, 25 Jun 2021 15:08:18 +1000 -Subject: Move closefrom() to before first malloc. - -When built against tcmalloc, tcmalloc allocates a descriptor for its -internal use, so calling closefrom() afterward causes the descriptor -number to be reused resulting in a corrupted connection. Moving the -closefrom a little earlier should resolve this. From kircherlike at -outlook.com via bz#3321, ok djm@ ---- - ssh.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/ssh.c b/ssh.c -index cf8c018e..0343cba3 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -609,6 +609,12 @@ main(int ac, char **av) - /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ - sanitise_stdfd(); - -+ /* -+ * Discard other fds that are hanging around. These can cause problem -+ * with backgrounded ssh processes started by ControlPersist. -+ */ -+ closefrom(STDERR_FILENO + 1); -+ - __progname = ssh_get_progname(av[0]); - #if OPENSSL_VERSION_NUMBER < 0x10100000L - SSLeay_add_all_algorithms(); -@@ -638,12 +644,6 @@ main(int ac, char **av) - debug("FIPS mode initialized"); - } - -- /* -- * Discard other fds that are hanging around. These can cause problem -- * with backgrounded ssh processes started by ControlPersist. -- */ -- closefrom(STDERR_FILENO + 1); -- - /* Get user data. */ - pw = getpwuid(getuid()); - if (!pw) { --- -cgit v1.2.3 diff --git a/backport-upstream-Remove-debug-message-from-sigchld-handler.patch b/backport-upstream-Remove-debug-message-from-sigchld-handler.patch deleted file mode 100644 index b6728d8dc532678acd8b80447f583ff20472f7fd..0000000000000000000000000000000000000000 --- a/backport-upstream-Remove-debug-message-from-sigchld-handler.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a35d3e911e193a652bd09eed40907e3e165b0a7b Mon Sep 17 00:00:00 2001 -From: "dtucker@openbsd.org" -Date: Fri, 5 Feb 2021 02:20:23 +0000 -Subject: upstream: Remove debug message from sigchld handler. While this -works on OpenBSD it can cause problems on other platforms. From kircherlike -at outlook.com via bz#3259, ok djm@ - -OpenBSD-Commit_ID: 3e241d7ac1ee77e3de3651780b5dc47b283a7668 - -Conflict:NA -Reference:https://anongit.mindrot.org/openssh.git/commit/?id=a35d3e911e193a652bd09eed40907e3e165b0a7b - ---- - sshd.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/sshd.c b/sshd.c -index c291a5e..23fb202 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -364,8 +364,6 @@ main_sigchld_handler(int sig) - pid_t pid; - int status; - -- debug("main_sigchld_handler: %s", strsignal(sig)); -- - while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || - (pid == -1 && errno == EINTR)) - ; --- -1.8.3.1 - diff --git a/bugfix-debug3-to-verbose-in-command.patch b/bugfix-debug3-to-verbose-in-command.patch deleted file mode 100644 index 7589231d54fd54181997e0cde9720532900ec3dc..0000000000000000000000000000000000000000 --- a/bugfix-debug3-to-verbose-in-command.patch +++ /dev/null @@ -1,25 +0,0 @@ -From ed070c21ae68170e1cead6f5be16482d4f73ae2b Mon Sep 17 00:00:00 2001 -From: kircher -Date: Thu, 5 Mar 2020 21:02:06 +0800 -Subject: [PATCH] d2v - ---- - monitor_wrap.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/monitor_wrap.c b/monitor_wrap.c -index 7f5a8fa..6ebcda1 100644 ---- a/monitor_wrap.c -+++ b/monitor_wrap.c -@@ -928,7 +928,7 @@ mm_audit_run_command(const char *command) - int r; - int handle; - -- debug3("%s entering command %s", __func__, command); -+ verbose("%s entering command %s", __func__, command); - - if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); --- -2.19.1 - diff --git a/bugfix-openssh-6.6p1-log-usepam-no.patch b/bugfix-openssh-6.6p1-log-usepam-no.patch index 4eeee2dc0cd663d8311c120d3adb41be021f5c11..de7fe4d5fc4c39a093e21f11fe947a1889ef9ae8 100644 --- a/bugfix-openssh-6.6p1-log-usepam-no.patch +++ b/bugfix-openssh-6.6p1-log-usepam-no.patch @@ -22,8 +22,8 @@ index c6c03ae..c291a5e 100644 - logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems."); + logit("WARNING: 'UsePAM no' is not supported in openEuler and may cause several problems."); - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); + #ifdef WITH_OPENSSL + if (options.moduli_file != NULL) diff --git a/sshd_config b/sshd_config index e125992..ebc28b3 100644 --- a/sshd_config @@ -31,7 +31,7 @@ index e125992..ebc28b3 100644 @@ -87,7 +87,7 @@ AuthorizedKeysFile .ssh/authorized_keys # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication - # and ChallengeResponseAuthentication to 'no'. + # and KbdInteractiveAuthentication to 'no'. -# WARNING: 'UsePAM no' is not supported in Fedora and may cause several +# WARNING: 'UsePAM no' is not supported in openEuler and may cause several # problems. diff --git a/bugfix-openssh-add-option-check-username-splash.patch b/bugfix-openssh-add-option-check-username-splash.patch index c6c13290425499997aa99409da4ef4491cf8eb47..9293230bc3e61e13637eac6e70697458434ddbf0 100644 --- a/bugfix-openssh-add-option-check-username-splash.patch +++ b/bugfix-openssh-add-option-check-username-splash.patch @@ -97,14 +97,14 @@ index ebc28b3..b121450 100644 --- a/sshd_config +++ b/sshd_config @@ -125,6 +125,8 @@ Subsystem sftp /usr/libexec/sftp-server + # Example of overriding settings on a per-user basis + #Match User anoncvs + # X11Forwarding no + # AllowTcpForwarding no # PermitTTY no # ForceCommand cvs server - +#CheckUserSplash yes + - # To modify the system-wide ssh configuration, create a *.conf file under - # /etc/ssh/sshd_config.d/ which will be automatically included below - Include /etc/ssh/sshd_config.d/*.conf -- 2.23.0 diff --git a/feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch b/feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch index 47e67b34d79947d1ee1158d9f4bbdf55d4fbace6..3fa984dd5f92aab25c3401a2a41680e58de0f2db 100644 --- a/feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch +++ b/feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch @@ -6,8 +6,8 @@ Subject: [PATCH] sync patch, add new judgement and Signed-off-by: s00467541 --- - sftp-server.c | 702 +++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 691 insertions(+), 11 deletions(-) + sftp-server.c | 703 +++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 691 insertions(+), 12 deletions(-) diff --git a/sftp-server.c b/sftp-server.c index 01d6f8f..682c19a 100644 @@ -43,7 +43,7 @@ index 01d6f8f..682c19a 100644 + char *sftp_realpath(const char *, char *); /* sftp-realpath.c */ - /* Our verbosity */ + /* Maximum data read that we are willing to accept */ @@ -89,6 +106,452 @@ struct Stat { Attrib attrib; }; @@ -500,7 +500,7 @@ index 01d6f8f..682c19a 100644 @@ -695,6 +1158,15 @@ process_open(u_int32_t id) (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ (r = decode_attrib(iqueue, &a)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + /* add begin 2013/10/12 SR-0000287268 */ + if (RETURN_OK != path_permition_check(name,FLAG_PERMITOP)) + { @@ -524,7 +524,7 @@ index 01d6f8f..682c19a 100644 @@ -759,6 +1233,17 @@ process_read(u_int32_t id) (r = sshbuf_get_u32(iqueue, &len)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + /* add begin 2013/10/12 SR-0000287268*/ + char *path = NULL; @@ -537,12 +537,12 @@ index 01d6f8f..682c19a 100644 + } + /* add end 2013/10/12 SR-0000287268*/ + - debug("request %u: read \"%s\" (handle %d) off %llu len %d", + debug("request %u: read \"%s\" (handle %d) off %llu len %u", id, handle_to_name(handle), handle, (unsigned long long)off, len); - if (len > sizeof buf) { + if ((fd = handle_to_fd(handle)) == -1) @@ -800,6 +1285,18 @@ process_write(u_int32_t id) (r = sshbuf_get_string(iqueue, &data, &len)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + /* add begin 2013/10/12 SR-0000287268*/ + char *path = NULL; @@ -559,19 +559,20 @@ index 01d6f8f..682c19a 100644 debug("request %u: write \"%s\" (handle %d) off %llu len %zu", id, handle_to_name(handle), handle, (unsigned long long)off, len); fd = handle_to_fd(handle); -@@ -813,16 +1310,30 @@ process_write(u_int32_t id) - error("process_write: seek failed"); +@@ -813,17 +1310,30 @@ process_write(u_int32_t id) + strerror(errno)); } else { /* XXX ATOMICIO ? */ - ret = write(fd, data, len); - if (ret == -1) { -- error("process_write: write failed"); - status = errno_to_portable(errno); +- error_f("write \"%.100s\": %s", +- handle_to_name(handle), strerror(errno)); - } else if ((size_t)ret == len) { - status = SSH2_FX_OK; - handle_update_write(handle, ret); - } else { -- debug2("nothing at all written"); +- debug2_f("nothing at all written"); + /* add begin sftp oom fix */ + if (storage_flag == 1) + debug("cflag is %d",cflag); @@ -601,7 +602,7 @@ index 01d6f8f..682c19a 100644 } @@ -841,6 +1352,16 @@ process_do_stat(u_int32_t id, int do_lstat) if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + /* add begin 2013/10/12 SR-0000287268 */ + if (RETURN_OK != path_permition_check(name,FLAG_PERMITOP)) @@ -619,7 +620,7 @@ index 01d6f8f..682c19a 100644 @@ -877,6 +1398,16 @@ process_fstat(u_int32_t id) if ((r = get_handle(iqueue, &handle)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + + char *path = NULL; + path = handle_to_name(handle); @@ -635,7 +636,7 @@ index 01d6f8f..682c19a 100644 fd = handle_to_fd(handle); @@ -929,6 +1460,14 @@ process_setstat(u_int32_t id) (r = decode_attrib(iqueue, &a)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(name,FLAG_PROTECTDIR)) + { @@ -664,7 +665,7 @@ index 01d6f8f..682c19a 100644 name, (unsigned long long)a.size); @@ -1040,6 +1586,14 @@ process_opendir(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { @@ -690,7 +691,7 @@ index 01d6f8f..682c19a 100644 stats[count].long_name = ls_file(dp->d_name, &st, 0, 0); @@ -1125,6 +1683,14 @@ process_remove(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(name,FLAG_PROTECTDIR)) + { @@ -705,7 +706,7 @@ index 01d6f8f..682c19a 100644 r = unlink(name); @@ -1144,6 +1710,14 @@ process_mkdir(u_int32_t id) (r = decode_attrib(iqueue, &a)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(name,FLAG_PERMITOP)) + { @@ -720,7 +721,7 @@ index 01d6f8f..682c19a 100644 debug3("request %u: mkdir", id); @@ -1163,6 +1737,14 @@ process_rmdir(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(name,FLAG_PROTECTDIR)) + { @@ -750,7 +751,7 @@ index 01d6f8f..682c19a 100644 attrib_clear(&s.attrib); @@ -1209,6 +1795,16 @@ process_rename(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if ((RETURN_OK != path_permition_check(oldpath,FLAG_PROTECTDIR)) + || (RETURN_OK != path_permition_check(newpath,FLAG_PROTECTDIR))) @@ -767,7 +768,7 @@ index 01d6f8f..682c19a 100644 status = SSH2_FX_FAILURE; @@ -1268,6 +1864,14 @@ process_readlink(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { @@ -782,7 +783,7 @@ index 01d6f8f..682c19a 100644 if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) @@ -1293,6 +1897,16 @@ process_symlink(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if ((RETURN_OK != path_permition_check(oldpath,FLAG_PROTECTDIR)) + || (RETURN_OK != path_permition_check(newpath,FLAG_PROTECTDIR))) @@ -799,7 +800,7 @@ index 01d6f8f..682c19a 100644 /* this will fail if 'newpath' exists */ @@ -1313,6 +1927,16 @@ process_extended_posix_rename(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if ((RETURN_OK != path_permition_check(oldpath,FLAG_PROTECTDIR)) + || (RETURN_OK != path_permition_check(newpath,FLAG_PROTECTDIR))) @@ -817,7 +818,7 @@ index 01d6f8f..682c19a 100644 @@ -1331,6 +1955,15 @@ process_extended_statvfs(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { @@ -833,7 +834,7 @@ index 01d6f8f..682c19a 100644 @@ -1349,6 +1982,17 @@ process_extended_fstatvfs(u_int32_t id) if ((r = get_handle(iqueue, &handle)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + + char *path = NULL; + path = handle_to_name(handle); @@ -850,7 +851,7 @@ index 01d6f8f..682c19a 100644 if ((fd = handle_to_fd(handle)) < 0) { @@ -1371,6 +2015,15 @@ process_extended_hardlink(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + if ((RETURN_OK != path_permition_check(oldpath,FLAG_PROTECTDIR)) + || (RETURN_OK != path_permition_check(newpath,FLAG_PROTECTDIR))) @@ -867,7 +868,7 @@ index 01d6f8f..682c19a 100644 @@ -1387,6 +2040,17 @@ process_extended_fsync(u_int32_t id) if ((r = get_handle(iqueue, &handle)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "parse"); + + char *path = NULL; + path = handle_to_name(handle); diff --git a/openssh-4.3p2-askpass-grab-info.patch b/openssh-4.3p2-askpass-grab-info.patch index e9a0b0d0739506cefc48aac9a43d2fe3b2c200ff..120ed1b607c9edf5e3d79dba3a5de3ed9d20d5b8 100644 --- a/openssh-4.3p2-askpass-grab-info.patch +++ b/openssh-4.3p2-askpass-grab-info.patch @@ -1,19 +1,18 @@ -diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-7.4p1/contrib/gnome-ssh-askpass2.c ---- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info 2016-12-23 13:31:22.645213115 +0100 -+++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c 2016-12-23 13:31:40.997216691 +0100 -@@ -65,9 +65,12 @@ report_failed_grab (GtkWidget *parent_wi +diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/contrib/gnome-ssh-askpass2.c +--- openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info 2021-04-19 13:57:11.720113536 +0200 ++++ openssh-8.6p1/contrib/gnome-ssh-askpass2.c 2021-04-19 13:59:29.842163204 +0200 +@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_wi + err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, -- "Could not grab %s. " -- "A malicious client may be eavesdropping " -- "on your session.", what); -+ "SSH password dialog could not grab the %s input.\n" -+ "This might be caused by application such as screensaver, " -+ "however it could also mean that someone may be eavesdropping " -+ "on your session.\n" -+ "Either close the application which grabs the %s or " -+ "log out and log in again to prevent this from happening.", what, what); + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, +- "Could not grab %s. A malicious client may be eavesdropping " +- "on your session.", what); ++ "SSH password dialog could not grab the %s input.\n" ++ "This might be caused by application such as screensaver, " ++ "however it could also mean that someone may be eavesdropping " ++ "on your session.\n" ++ "Either close the application which grabs the %s or " ++ "log out and log in again to prevent this from happening.", what, what); gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); gtk_dialog_run(GTK_DIALOG(err)); diff --git a/openssh-5.1p1-askpass-progress.patch b/openssh-5.1p1-askpass-progress.patch index 21f6502390f93801bdca3f1e21730de0d8b18282..ff609da597c87686aa09bd9f150425e62d3b79b6 100644 --- a/openssh-5.1p1-askpass-progress.patch +++ b/openssh-5.1p1-askpass-progress.patch @@ -2,15 +2,15 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr --- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c 2016-12-23 13:31:16.545211926 +0100 @@ -53,6 +53,7 @@ - #include #include + #include +#include #include #include - + #include @@ -81,14 +82,25 @@ ok_dialog(GtkWidget *entry, gpointer dia - gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + return 1; } +static void @@ -34,39 +34,44 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr - GtkWidget *parent_window, *dialog, *entry; + GtkWidget *parent_window, *dialog, *entry, *progress, *hbox; GdkGrabStatus status; + GdkColor fg, bg; + int fg_set = 0, bg_set = 0; +@@ -104,14 +116,19 @@ passphrase_dialog(char *message) + gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg); - grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); -@@ -104,16 +116,37 @@ passphrase_dialog(char *message) - gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); - - if (prompt_type == PROMPT_ENTRY) { + if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) { + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, + FALSE, 0); + gtk_widget_show(hbox); + entry = gtk_entry_new(); + if (fg_set) + gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg); + if (bg_set) + gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg); gtk_box_pack_start( - GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), - entry, FALSE, FALSE, 0); -+ GTK_BOX(hbox), entry, -+ TRUE, FALSE, 0); ++ GTK_BOX(hbox), entry, TRUE, FALSE, 0); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 2); gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); gtk_widget_grab_focus(entry); - gtk_widget_show(entry); - /* Make close dialog */ - g_signal_connect(G_OBJECT(entry), "activate", - G_CALLBACK(ok_dialog), dialog); + if (prompt_type == PROMPT_ENTRY) { +@@ -130,6 +145,22 @@ passphrase_dialog(char *message) + g_signal_connect(G_OBJECT(entry), "key_press_event", + G_CALLBACK(check_none), dialog); + } + + hbox = gtk_hbox_new(FALSE, 0); -+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, -+ FALSE, 8); ++ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), ++ hbox, FALSE, FALSE, 8); + gtk_widget_show(hbox); + + progress = gtk_progress_bar_new(); + -+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "Passphrase length hidden intentionally"); ++ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), ++ "Passphrase length hidden intentionally"); + gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE, + TRUE, 5); + gtk_widget_show(progress); diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index 12602424031b2991fe9ed3b1882af0dfa16cc628..426c1727d167a90f41107fcf67fe7191febecb13 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -1,19 +1,19 @@ -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) +diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c +--- openssh-8.6p1/log.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/log.c 2021-04-19 14:43:08.544843434 +0200 +@@ -194,6 +194,11 @@ void + 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 -@@ -273,8 +278,10 @@ log_init(char *av0, LogLevel level, Sysl +@@ -206,8 +211,10 @@ log_init(const char *av0, LogLevel level exit(1); } @@ -26,21 +26,21 @@ diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c log_on_stderr = on_stderr; if (on_stderr) -diff -up openssh-7.4p1/log.h.log-in-chroot openssh-7.4p1/log.h ---- openssh-7.4p1/log.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/log.h 2016-12-23 15:14:33.330168088 +0100 -@@ -49,6 +49,7 @@ typedef enum { - typedef void (log_handler_fn)(LogLevel, const char *, void *); - - void log_init(char *, LogLevel, SyslogFacility, int); -+void log_init_handler(char *, LogLevel, SyslogFacility, int, int); +diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h +--- openssh-8.6p1/log.h.log-in-chroot 2021-04-19 14:43:08.544843434 +0200 ++++ openssh-8.6p1/log.h 2021-04-19 14:56:46.931042176 +0200 +@@ -52,6 +52,7 @@ typedef enum { + typedef void (log_handler_fn)(LogLevel, int, const char *, void *); + + void log_init(const char *, LogLevel, SyslogFacility, int); ++void log_init_handler(const char *, LogLevel, SyslogFacility, int, int); LogLevel log_level_get(void); int log_change_level(LogLevel); int log_is_on_stderr(void); -diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.log-in-chroot 2016-12-23 15:14:33.311168085 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 15:16:42.154193100 +0100 -@@ -307,6 +307,8 @@ monitor_child_preauth(Authctxt *_authctx +diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c +--- openssh-8.6p1/monitor.c.log-in-chroot 2021-04-19 14:43:08.526843298 +0200 ++++ openssh-8.6p1/monitor.c 2021-04-19 14:55:25.286424043 +0200 +@@ -297,6 +297,8 @@ monitor_child_preauth(struct ssh *ssh, s close(pmonitor->m_log_sendfd); pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; @@ -49,7 +49,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c authctxt = (Authctxt *)ssh->authctxt; memset(authctxt, 0, sizeof(*authctxt)); ssh->authctxt = authctxt; -@@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p +@@ -408,6 +410,8 @@ monitor_child_postauth(struct ssh *ssh, close(pmonitor->m_recvfd); pmonitor->m_recvfd = -1; @@ -58,16 +58,16 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c monitor_set_child_handler(pmonitor->m_pid); ssh_signal(SIGHUP, &monitor_child_handler); ssh_signal(SIGTERM, &monitor_child_handler); -@@ -472,7 +476,7 @@ monitor_read_log(struct monitor *pmonito +@@ -480,7 +484,7 @@ monitor_read_log(struct monitor *pmonito + /* Log it */ if (log_level_name(level) == NULL) - fatal("%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); +- sshlogdirect(level, forced, "%s [preauth]", msg); ++ sshlogdirect(level, forced, "%s [%s]", msg, pmonitor->m_state); sshbuf_free(logmsg); free(msg); -@@ -1719,13 +1723,28 @@ monitor_init(void) +@@ -1868,13 +1872,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); @@ -98,10 +98,10 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c } #ifdef GSSAPI -diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h ---- openssh-7.4p1/monitor.h.log-in-chroot 2016-12-23 15:14:33.330168088 +0100 -+++ openssh-7.4p1/monitor.h 2016-12-23 15:16:28.372190424 +0100 -@@ -83,10 +83,11 @@ struct monitor { +diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h +--- openssh-8.6p1/monitor.h.log-in-chroot 2021-04-19 14:43:08.527843305 +0200 ++++ openssh-8.6p1/monitor.h 2021-04-19 14:43:08.545843441 +0200 +@@ -80,10 +80,11 @@ struct monitor { int m_log_sendfd; struct kex **m_pkex; pid_t m_pid; @@ -114,9 +114,9 @@ diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h struct Authctxt; void monitor_child_preauth(struct ssh *, struct monitor *); -diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.log-in-chroot 2016-12-23 15:14:33.319168086 +0100 -+++ openssh-7.4p1/session.c 2016-12-23 15:18:18.742211853 +0100 +diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.log-in-chroot 2021-04-19 14:43:08.534843358 +0200 ++++ openssh-8.6p1/session.c 2021-04-19 14:43:08.545843441 +0200 @@ -160,6 +160,7 @@ login_cap_t *lc; static int is_child = 0; @@ -125,7 +125,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c /* File containing userauth info, if ExposeAuthInfo set */ static char *auth_info_file = NULL; -@@ -619,6 +620,7 @@ do_exec(Session *s, const char *command) +@@ -661,6 +662,7 @@ do_exec(struct ssh *ssh, Session *s, con int ret; const char *forced = NULL, *tty = NULL; char session_type[1024]; @@ -133,7 +133,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c if (options.adm_forced_command) { original_command = command; -@@ -676,6 +678,10 @@ do_exec(Session *s, const char *command) +@@ -720,6 +722,10 @@ do_exec(struct ssh *ssh, Session *s, con tty += 5; } @@ -144,10 +144,10 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", -@@ -1486,14 +1492,6 @@ child_close_fds(void) - * descriptors left by system functions. They will be closed later. - */ - endpwent(); +@@ -1524,14 +1530,6 @@ child_close_fds(struct ssh *ssh) + + /* Stop directing logs to a high-numbered fd before we close it */ + log_redirect_stderr_to(NULL); - - /* - * Close any extra open file descriptors so that we don't have them @@ -159,7 +159,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c } /* -@@ -1629,8 +1627,6 @@ do_child(Session *s, const char *command +@@ -1665,8 +1663,6 @@ do_child(struct ssh *ssh, Session *s, co exit(1); } @@ -168,7 +168,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c do_rc_files(ssh, s, shell); /* restore SIGPIPE for child */ -@@ -1653,9 +1649,17 @@ do_child(Session *s, const char *command +@@ -1691,9 +1687,17 @@ do_child(struct ssh *ssh, Session *s, co argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; @@ -187,9 +187,9 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c fflush(NULL); /* Get the last component of the shell name. */ -diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h ---- openssh-7.4p1/sftp.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sftp.h 2016-12-23 15:14:33.331168088 +0100 +diff -up openssh-8.6p1/sftp.h.log-in-chroot openssh-8.6p1/sftp.h +--- openssh-8.6p1/sftp.h.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp.h 2021-04-19 14:43:08.545843441 +0200 @@ -97,5 +97,5 @@ struct passwd; @@ -197,10 +197,10 @@ diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h -int sftp_server_main(int, char **, struct passwd *); +int sftp_server_main(int, char **, struct passwd *, int); void sftp_server_cleanup_exit(int) __attribute__((noreturn)); -diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c ---- openssh-7.4p1/sftp-server.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sftp-server.c 2016-12-23 15:14:33.331168088 +0100 -@@ -1497,7 +1497,7 @@ sftp_server_usage(void) +diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c +--- openssh-8.6p1/sftp-server.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp-server.c 2021-04-19 14:43:08.545843441 +0200 +@@ -1644,7 +1644,7 @@ sftp_server_usage(void) } int @@ -209,7 +209,7 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c { fd_set *rset, *wset; int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; -@@ -1511,7 +1511,7 @@ sftp_server_main(int argc, char **argv, +@@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv, extern char *__progname; __progname = ssh_get_progname(argv[0]); @@ -218,7 +218,7 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c pw = pwcopy(user_pw); -@@ -1582,7 +1582,7 @@ sftp_server_main(int argc, char **argv, +@@ -1730,7 +1730,7 @@ sftp_server_main(int argc, char **argv, } } @@ -227,20 +227,20 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c /* * On platforms where we can, avoid making /proc/self/{mem,maps} -diff -up openssh-7.4p1/sftp-server-main.c.log-in-chroot openssh-7.4p1/sftp-server-main.c ---- openssh-7.4p1/sftp-server-main.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sftp-server-main.c 2016-12-23 15:14:33.331168088 +0100 -@@ -49,5 +49,5 @@ main(int argc, char **argv) +diff -up openssh-8.6p1/sftp-server-main.c.log-in-chroot openssh-8.6p1/sftp-server-main.c +--- openssh-8.6p1/sftp-server-main.c.log-in-chroot 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/sftp-server-main.c 2021-04-19 14:43:08.545843441 +0200 +@@ -50,5 +50,5 @@ main(int argc, char **argv) return 1; } - return (sftp_server_main(argc, argv, user_pw)); + return (sftp_server_main(argc, argv, user_pw, 0)); } -diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.log-in-chroot 2016-12-23 15:14:33.328168088 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 15:14:33.332168088 +0100 -@@ -650,7 +650,7 @@ privsep_postauth(Authctxt *authctxt) +diff -up openssh-8.6p1/sshd.c.log-in-chroot openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.log-in-chroot 2021-04-19 14:43:08.543843426 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 14:43:08.545843441 +0200 +@@ -559,7 +559,7 @@ privsep_postauth(struct ssh *ssh, Authct } /* New socket pair */ @@ -249,7 +249,7 @@ diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) -@@ -668,6 +668,11 @@ privsep_postauth(Authctxt *authctxt) +@@ -578,6 +578,11 @@ privsep_postauth(struct ssh *ssh, Authct close(pmonitor->m_sendfd); pmonitor->m_sendfd = -1; diff --git a/openssh-6.6.1p1-selinux-contexts.patch b/openssh-6.6.1p1-selinux-contexts.patch index 3a7193e817c05d6b82b1e10feb7f978346629e35..fa9d5914de1250f852dd63ceda625ecafeeed748 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 01ea15612c219fd1dd67d4ebeb8553b5bde4d1cb..cccb3e067b307261474e7f0448bccf9e0ed086b2 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -28,7 +28,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c + options->enable_k5users = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->challenge_response_authentication = -1; + options->permit_empty_passwd = -1; @@ -345,6 +346,8 @@ fill_default_server_options(ServerOption #endif if (options->use_kuserok == -1) @@ -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, @@ -72,9 +72,9 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c + intptr = &options->enable_k5users; + goto parse_flag; + - case sPermitListen: - case sPermitOpen: - if (opcode == sPermitListen) { + case sMatch: + if (cmdline) + fatal("Match directive not supported as a command-line " @@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch deleted file mode 100644 index 9454c502d0d6788f1b430700cfefcd91d30d4ca9..0000000000000000000000000000000000000000 --- a/openssh-6.6p1-ctr-cavstest.patch +++ /dev/null @@ -1,257 +0,0 @@ -diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in ---- openssh-6.8p1/Makefile.in.ctr-cavs 2015-03-18 11:22:05.493289018 +0100 -+++ openssh-6.8p1/Makefile.in 2015-03-18 11:22:44.504196316 +0100 -@@ -28,6 +28,7 @@ SSH_KEYSIGN=$(libexecdir)/ssh-keysign - SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper - SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper - SSH_KEYCAT=$(libexecdir)/ssh-keycat -+CTR_CAVSTEST=$(libexecdir)/ctr-cavstest - SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper - SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper - PRIVSEP_PATH=@PRIVSEP_PATH@ -@@ -66,7 +67,7 @@ EXEEXT=@EXEEXT@ - - .SUFFIXES: .lo - --TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) -+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) - - XMSS_OBJS=\ - ssh-xmss.o \ -@@ -194,6 +195,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l - ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o - $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) - -+ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o -+ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) -+ - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) - $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) - -@@ -326,6 +330,7 @@ install-files: - $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ - fi - $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) -+ $(INSTALL) -m 0755 $(STRIP_OPT) ctr-cavstest$(EXEEXT) $(DESTDIR)$(libexecdir)/ctr-cavstest$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) - $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c ---- openssh-6.8p1/ctr-cavstest.c.ctr-cavs 2015-03-18 11:22:05.521288952 +0100 -+++ openssh-6.8p1/ctr-cavstest.c 2015-03-18 11:22:05.521288952 +0100 -@@ -0,0 +1,215 @@ -+/* -+ * -+ * invocation (all of the following are equal): -+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 -+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 --iv 00000000000000000000000000000000 -+ * echo -n a6deca405eef2e8e4609abf3c3ccf4a6 | ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt -+ */ -+ -+#include "includes.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "xmalloc.h" -+#include "log.h" -+#include "ssherr.h" -+#include "cipher.h" -+ -+/* compatibility with old or broken OpenSSL versions */ -+#include "openbsd-compat/openssl-compat.h" -+ -+void usage(void) { -+ fprintf(stderr, "Usage: ctr-cavstest --algo \n" -+ " --key --mode \n" -+ " [--iv ] --data \n\n" -+ "Hexadecimal output is printed to stdout.\n" -+ "Hexadecimal input data can be alternatively read from stdin.\n"); -+ exit(1); -+} -+ -+void *fromhex(char *hex, size_t *len) -+{ -+ unsigned char *bin; -+ char *p; -+ size_t n = 0; -+ int shift = 4; -+ unsigned char out = 0; -+ unsigned char *optr; -+ -+ bin = xmalloc(strlen(hex)/2); -+ optr = bin; -+ -+ for (p = hex; *p != '\0'; ++p) { -+ unsigned char c; -+ -+ c = *p; -+ if (isspace(c)) -+ continue; -+ -+ if (c >= '0' && c <= '9') { -+ c = c - '0'; -+ } else if (c >= 'A' && c <= 'F') { -+ c = c - 'A' + 10; -+ } else if (c >= 'a' && c <= 'f') { -+ c = c - 'a' + 10; -+ } else { -+ /* truncate on nonhex cipher */ -+ break; -+ } -+ -+ out |= c << shift; -+ shift = (shift + 4) % 8; -+ -+ if (shift) { -+ *(optr++) = out; -+ out = 0; -+ ++n; -+ } -+ } -+ -+ *len = n; -+ return bin; -+} -+ -+#define READ_CHUNK 4096 -+#define MAX_READ_SIZE 1024*1024*100 -+char *read_stdin(void) -+{ -+ char *buf; -+ size_t n, total = 0; -+ -+ buf = xmalloc(READ_CHUNK); -+ -+ do { -+ n = fread(buf + total, 1, READ_CHUNK, stdin); -+ if (n < READ_CHUNK) /* terminate on short read */ -+ break; -+ -+ total += n; -+ buf = xreallocarray(buf, total + READ_CHUNK, 1); -+ } while(total < MAX_READ_SIZE); -+ return buf; -+} -+ -+int main (int argc, char *argv[]) -+{ -+ -+ const struct sshcipher *c; -+ struct sshcipher_ctx *cc; -+ char *algo = "aes128-ctr"; -+ char *hexkey = NULL; -+ char *hexiv = "00000000000000000000000000000000"; -+ char *hexdata = NULL; -+ char *p; -+ int i, r; -+ int encrypt = 1; -+ void *key; -+ size_t keylen; -+ void *iv; -+ size_t ivlen; -+ void *data; -+ size_t datalen; -+ void *outdata; -+ -+ for (i = 1; i < argc; ++i) { -+ if (strcmp(argv[i], "--algo") == 0) { -+ algo = argv[++i]; -+ } else if (strcmp(argv[i], "--key") == 0) { -+ hexkey = argv[++i]; -+ } else if (strcmp(argv[i], "--mode") == 0) { -+ ++i; -+ if (argv[i] == NULL) { -+ usage(); -+ } -+ if (strncmp(argv[i], "enc", 3) == 0) { -+ encrypt = 1; -+ } else if (strncmp(argv[i], "dec", 3) == 0) { -+ encrypt = 0; -+ } else { -+ usage(); -+ } -+ } else if (strcmp(argv[i], "--iv") == 0) { -+ hexiv = argv[++i]; -+ } else if (strcmp(argv[i], "--data") == 0) { -+ hexdata = argv[++i]; -+ } -+ } -+ -+ if (hexkey == NULL || algo == NULL) { -+ usage(); -+ } -+ -+ OpenSSL_add_all_algorithms(); -+ -+ c = cipher_by_name(algo); -+ if (c == NULL) { -+ fprintf(stderr, "Error: unknown algorithm\n"); -+ return 2; -+ } -+ -+ if (hexdata == NULL) { -+ hexdata = read_stdin(); -+ } else { -+ hexdata = xstrdup(hexdata); -+ } -+ -+ key = fromhex(hexkey, &keylen); -+ -+ if (keylen != 16 && keylen != 24 && keylen == 32) { -+ fprintf(stderr, "Error: unsupported key length\n"); -+ return 2; -+ } -+ -+ iv = fromhex(hexiv, &ivlen); -+ -+ if (ivlen != 16) { -+ fprintf(stderr, "Error: unsupported iv length\n"); -+ return 2; -+ } -+ -+ data = fromhex(hexdata, &datalen); -+ -+ if (data == NULL || datalen == 0) { -+ fprintf(stderr, "Error: no data to encrypt/decrypt\n"); -+ return 2; -+ } -+ -+ if ((r = cipher_init(&cc, c, key, keylen, iv, ivlen, encrypt)) != 0) { -+ fprintf(stderr, "Error: cipher_init failed: %s\n", ssh_err(r)); -+ return 2; -+ } -+ -+ free(key); -+ free(iv); -+ -+ outdata = malloc(datalen); -+ if(outdata == NULL) { -+ fprintf(stderr, "Error: memory allocation failure\n"); -+ return 2; -+ } -+ -+ if ((r = cipher_crypt(cc, 0, outdata, data, datalen, 0, 0)) != 0) { -+ fprintf(stderr, "Error: cipher_crypt failed: %s\n", ssh_err(r)); -+ return 2; -+ } -+ -+ free(data); -+ -+ cipher_free(cc); -+ -+ for (p = outdata; datalen > 0; ++p, --datalen) { -+ printf("%02X", (unsigned char)*p); -+ } -+ -+ free(outdata); -+ -+ printf("\n"); -+ return 0; -+} -+ diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 5fc9b9ed4200db798631af792f74996c0ab7400f..2aa14bd44e420e4e5a87f56dc6df9da1d935e5cd 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 @@ -36,16 +35,16 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in --- openssh/Makefile.in.keycat 2015-06-24 10:57:50.152849621 +0200 +++ openssh/Makefile.in 2015-06-24 10:57:50.157849608 +0200 @@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server + ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass + SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign - SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper - SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper +SSH_KEYCAT=$(libexecdir)/ssh-keycat SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper PRIVSEP_PATH=@PRIVSEP_PATH@ @@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@ + K5LIBS=@K5LIBS@ GSSLIBS=@GSSLIBS@ - SSHLIBS=@SSHLIBS@ SSHDLIBS=@SSHDLIBS@ +KEYCATLIBS=@KEYCATLIBS@ LIBEDIT=@LIBEDIT@ @@ -55,25 +54,25 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in .SUFFIXES: .lo --TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-ldap-helper$(EXEEXT) -+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) +-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) XMSS_OBJS=\ ssh-xmss.o \ @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) - ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o - $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS) + ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) + $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o -+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) ++ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -321,6 +325,7 @@ install-files: - $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ - $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ - fi + $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) @@ -466,16 +465,16 @@ index 3bbccfd..6481f1f 100644 esac fi @@ -4042,6 +4044,7 @@ AC_ARG_WITH([selinux], + fi ] ) - AC_SUBST([SSHLIBS]) AC_SUBST([SSHDLIBS]) +AC_SUBST([KEYCATLIBS]) # Check whether user wants Kerberos 5 support KRB5_MSG="no" @@ -5031,6 +5034,9 @@ fi - if test ! -z "${SSHLIBS}"; then - echo " +for ssh: ${SSHLIBS}" + if test ! -z "${SSHDLIBS}"; then + echo " +for sshd: ${SSHDLIBS}" fi +if test ! -z "${KEYCATLIBS}"; then +echo " +for ssh-keycat: ${KEYCATLIBS}" diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 8428c1c8eca9b9b0b26fca2407e0c1991626a2c6..6f14a991b0aff5c966877ce2efdd436566a2a533 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -182,7 +182,7 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c + options->use_kuserok = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->challenge_response_authentication = -1; + options->permit_empty_passwd = -1; @@ -278,6 +279,8 @@ fill_default_server_options(ServerOption if (options->gss_kex_algorithms == NULL) options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); @@ -193,14 +193,14 @@ 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, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, + sPort, sHostKeyFile, sLoginGraceTime, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, - sKerberosGetAFSToken, sKerberosUniqueCCache, + sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, - sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, + sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, @@ -478,12 +481,14 @@ static struct { { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -217,16 +217,16 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, @@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions - *activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value; - break; - + } + break; + + case sKerberosUseKuserok: + intptr = &options->use_kuserok; + goto parse_flag; + - case sPermitListen: - case sPermitOpen: - if (opcode == sPermitListen) { + case sMatch: + if (cmdline) + fatal("Match directive not supported as a command-line " @@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(client_alive_interval); M_CP_INTOPT(ip_qos_interactive); diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 3d4c2874ba6270e29b5b8e7d129c830516f192a7..8047fc339447d01fe0a419fb9180bdd0bece663b 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 3f34464f51a09454c49053ce9e4eb769a6d1693b..930de695266cb117a05b906dad8caa17861e8a1c 100644 --- a/openssh-6.7p1-coverity.patch +++ b/openssh-6.7p1-coverity.patch @@ -1,21 +1,259 @@ +diff -up openssh-8.5p1/addr.c.coverity openssh-8.5p1/addr.c +--- openssh-8.5p1/addr.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/addr.c 2021-03-24 12:03:33.782968159 +0100 +@@ -312,8 +312,10 @@ addr_pton(const char *p, struct xaddr *n + if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) + return -1; + +- if (ai == NULL || ai->ai_addr == NULL) ++ if (ai == NULL || ai->ai_addr == NULL) { ++ freeaddrinfo(ai); + return -1; ++ } + + if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, + n) == -1) { +@@ -336,12 +338,16 @@ addr_sa_pton(const char *h, const char * + if (h == NULL || getaddrinfo(h, s, &hints, &ai) != 0) + return -1; + +- if (ai == NULL || ai->ai_addr == NULL) ++ if (ai == NULL || ai->ai_addr == NULL) { ++ freeaddrinfo(ai); + return -1; ++ } + + if (sa != NULL) { +- if (slen < ai->ai_addrlen) ++ if (slen < ai->ai_addrlen) { ++ freeaddrinfo(ai); + return -1; ++ } + memcpy(sa, &ai->ai_addr, ai->ai_addrlen); + } + +diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c +--- openssh-8.5p1/auth-krb5.c.coverity 2021-03-24 12:03:33.724967756 +0100 ++++ openssh-8.5p1/auth-krb5.c 2021-03-24 12:03:33.782968159 +0100 +@@ -426,6 +426,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, + umask(old_umask); + if (tmpfd == -1) { + logit("mkstemp(): %.100s", strerror(oerrno)); ++ free(ccname); + return oerrno; + } + +@@ -433,6 +434,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, + oerrno = errno; + logit("fchmod(): %.100s", strerror(oerrno)); + close(tmpfd); ++ free(ccname); + return oerrno; + } + /* make sure the KRB5CCNAME is set for non-standard location */ +diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c +--- openssh-8.5p1/auth-options.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/auth-options.c 2021-03-24 12:03:33.782968159 +0100 +@@ -706,6 +708,7 @@ serialise_array(struct sshbuf *m, char * + return r; + } + /* success */ ++ sshbuf_free(b); + return 0; + } + diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c --- openssh-7.4p1/channels.c.coverity 2016-12-23 16:40:26.881788686 +0100 +++ openssh-7.4p1/channels.c 2016-12-23 16:42:36.244818763 +0100 -@@ -288,11 +288,11 @@ channel_register_fds(Channel *c, int rfd - - /* enable nonblocking mode */ - if (nonblock) { -- if (rfd != -1) -+ if (rfd >= 0) - set_nonblock(rfd); -- if (wfd != -1) -+ if (wfd >= 0) - set_nonblock(wfd); -- if (efd != -1) -+ if (efd >= 0) - set_nonblock(efd); +@@ -1875,7 +1875,7 @@ channel_post_connecting(struct ssh *ssh, + debug("channel %d: connection failed: %s", + c->self, strerror(err)); + /* Try next address, if any */ +- if ((sock = connect_next(&c->connect_ctx)) > 0) { ++ if ((sock = connect_next(&c->connect_ctx)) >= 0) { + close(c->sock); + c->sock = c->rfd = c->wfd = sock; + channel_find_maxfd(ssh->chanctxt); +@@ -3804,7 +3804,7 @@ int + channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) + { + int r, success = 0, idx = -1; +- char *host_to_connect, *listen_host, *listen_path; ++ char *host_to_connect = NULL, *listen_host = NULL, *listen_path = NULL; + int port_to_connect, listen_port; + + /* Send the forward request to the remote side. */ +@@ -3832,7 +3832,6 @@ channel_request_remote_forwarding(struct + success = 1; + if (success) { + /* Record that connection to this host/port is permitted. */ +- host_to_connect = listen_host = listen_path = NULL; + port_to_connect = listen_port = 0; + if (fwd->connect_path != NULL) { + host_to_connect = xstrdup(fwd->connect_path); +@@ -3853,6 +3852,9 @@ channel_request_remote_forwarding(struct + host_to_connect, port_to_connect, + listen_host, listen_path, listen_port, NULL); + } ++ free(host_to_connect); ++ free(listen_host); ++ free(listen_path); + return idx; + } + +diff -up openssh-8.5p1/compat.c.coverity openssh-8.5p1/compat.c +--- openssh-8.5p1/compat.c.coverity 2021-03-24 12:03:33.768968062 +0100 ++++ openssh-8.5p1/compat.c 2021-03-24 12:03:33.783968166 +0100 +@@ -191,10 +191,12 @@ compat_kex_proposal(struct ssh *ssh, cha + return p; + debug2_f("original KEX proposal: %s", p); + if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) ++ /* coverity[overwrite_var : FALSE] */ + if ((p = match_filter_denylist(p, + "curve25519-sha256@libssh.org")) == NULL) + fatal("match_filter_denylist failed"); + if ((ssh->compat & SSH_OLD_DHGEX) != 0) { ++ /* coverity[overwrite_var : FALSE] */ + if ((p = match_filter_denylist(p, + "diffie-hellman-group-exchange-sha256," + "diffie-hellman-group-exchange-sha1")) == NULL) +diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c +--- openssh-8.5p1/dns.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/dns.c 2021-03-24 12:03:33.783968166 +0100 +@@ -282,6 +282,7 @@ verify_host_key_dns(const char *hostname + &hostkey_digest, &hostkey_digest_len, hostkey)) { + error("Error calculating key fingerprint."); + freerrset(fingerprints); ++ free(dnskey_digest); + return -1; + } + +diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c +--- openssh-8.5p1/gss-genr.c.coverity 2021-03-26 11:52:46.613942552 +0100 ++++ openssh-8.5p1/gss-genr.c 2021-03-26 11:54:37.881726318 +0100 +@@ -167,8 +167,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup + enclen = __b64_ntop(digest, + ssh_digest_bytes(SSH_DIGEST_MD5), encoded, + ssh_digest_bytes(SSH_DIGEST_MD5) * 2); +- ++#pragma GCC diagnostic ignored "-Wstringop-overflow" + cp = strncpy(s, kex, strlen(kex)); ++#pragma pop + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + if (sshbuf_len(buf) != 0 && +diff -up openssh-8.5p1/kexgssc.c.coverity openssh-8.5p1/kexgssc.c +--- openssh-8.5p1/kexgssc.c.coverity 2021-03-24 12:03:33.711967665 +0100 ++++ openssh-8.5p1/kexgssc.c 2021-03-24 12:03:33.783968166 +0100 +@@ -98,8 +98,10 @@ kexgss_client(struct ssh *ssh) + default: + fatal_f("Unexpected KEX type %d", kex->kex_type); } +- if (r != 0) ++ if (r != 0) { ++ ssh_gssapi_delete_ctx(&ctxt); + return r; ++ } + + token_ptr = GSS_C_NO_BUFFER; + +diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c +--- openssh-8.5p1/krl.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/krl.c 2021-03-24 12:03:33.783968166 +0100 +@@ -1209,6 +1209,7 @@ ssh_krl_from_blob(struct sshbuf *buf, st + sshkey_free(key); + sshbuf_free(copy); + sshbuf_free(sect); ++ /* coverity[leaked_storage : FALSE] */ + return r; } + +@@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); + free(rb.blob); ++ rb.blob = NULL; /* make coverity happy */ + if (erb != NULL) { + KRL_DBG(("revoked by key SHA1")); + return SSH_ERR_KEY_REVOKED; +@@ -1271,6 +1273,7 @@ is_key_revoked(struct ssh_krl *krl, cons + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb); + free(rb.blob); ++ rb.blob = NULL; /* make coverity happy */ + if (erb != NULL) { + KRL_DBG(("revoked by key SHA256")); + return SSH_ERR_KEY_REVOKED; +@@ -1282,6 +1285,7 @@ is_key_revoked(struct ssh_krl *krl, cons + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); + free(rb.blob); ++ rb.blob = NULL; /* make coverity happy */ + if (erb != NULL) { + KRL_DBG(("revoked by explicit key")); + return SSH_ERR_KEY_REVOKED; +diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c +--- openssh-8.5p1/loginrec.c.coverity 2021-03-24 13:18:53.793225885 +0100 ++++ openssh-8.5p1/loginrec.c 2021-03-24 13:21:27.948404751 +0100 +@@ -690,9 +690,11 @@ construct_utmp(struct logininfo *li, + */ + + /* Use strncpy because we don't necessarily want null termination */ ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut->ut_name, li->username, + MIN_SIZEOF(ut->ut_name, li->username)); + # ifdef HAVE_HOST_IN_UTMP ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut->ut_host, li->hostname, + MIN_SIZEOF(ut->ut_host, li->hostname)); + # endif +@@ -1690,6 +1692,7 @@ record_failed_login(struct ssh *ssh, con + + memset(&ut, 0, sizeof(ut)); + /* strncpy because we don't necessarily want nul termination */ ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut.ut_user, username, sizeof(ut.ut_user)); + strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line)); + +@@ -1699,6 +1702,7 @@ record_failed_login(struct ssh *ssh, con + ut.ut_pid = getpid(); + + /* strncpy because we don't necessarily want nul termination */ ++ /* coverity[buffer_size_warning : FALSE] */ + strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); + + if (ssh_packet_connection_is_on_socket(ssh) && +diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c +--- openssh-8.5p1/misc.c.coverity 2021-03-24 12:03:33.745967902 +0100 ++++ openssh-8.5p1/misc.c 2021-03-24 13:31:47.037079617 +0100 +@@ -1425,6 +1425,8 @@ sanitise_stdfd(void) + } + if (nullfd > STDERR_FILENO) + close(nullfd); ++ /* coverity[leaked_handle : FALSE]*/ ++ /* coverity[leaked_handle : FALSE]*/ + } + + char * +@@ -2511,6 +2513,7 @@ stdfd_devnull(int do_stdin, int do_stdou + } + if (devnull > STDERR_FILENO) + close(devnull); ++ /* coverity[leaked_handle : FALSE]*/ + return ret; + } + +diff -up openssh-8.5p1/moduli.c.coverity openssh-8.5p1/moduli.c +--- openssh-8.5p1/moduli.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/moduli.c 2021-03-24 12:03:33.784968173 +0100 +@@ -476,6 +476,7 @@ write_checkpoint(char *cpfile, u_int32_t + else + logit("failed to write to checkpoint file '%s': %s", cpfile, + strerror(errno)); ++ /* coverity[leaked_storage : FALSE] */ + } + + static unsigned long diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c --- openssh-7.4p1/monitor.c.coverity 2016-12-23 16:40:26.888788688 +0100 +++ openssh-7.4p1/monitor.c 2016-12-23 16:40:26.900788691 +0100 @@ -28,13 +266,22 @@ diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c ; if (pmonitor->m_recvfd >= 0) +@@ -1678,7 +1678,7 @@ mm_answer_pty(struct ssh *ssh, int sock, + s->ptymaster = s->ptyfd; + + debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd); +- ++ /* coverity[leaked_handle : FALSE] */ + return (0); + + error: diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c --- openssh-7.4p1/monitor_wrap.c.coverity 2016-12-23 16:40:26.892788689 +0100 +++ openssh-7.4p1/monitor_wrap.c 2016-12-23 16:40:26.900788691 +0100 @@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || (tmp2 = dup(pmonitor->m_recvfd)) == -1) { - error("%s: cannot allocate fds for pty", __func__); + error_f("cannot allocate fds for pty"); - if (tmp1 > 0) + if (tmp1 >= 0) close(tmp1); @@ -57,30 +304,67 @@ diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/open int i; if (sa == NULL) { -diff -up openssh-7.4p1/scp.c.coverity openssh-7.4p1/scp.c ---- openssh-7.4p1/scp.c.coverity 2016-12-23 16:40:26.856788681 +0100 -+++ openssh-7.4p1/scp.c 2016-12-23 16:40:26.901788691 +0100 -@@ -157,7 +157,7 @@ killchild(int signo) +diff -up openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity openssh-8.7p1/openbsd-compat/bsd-pselect.c +--- openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity 2021-08-30 16:36:11.357288009 +0200 ++++ openssh-8.7p1/openbsd-compat/bsd-pselect.c 2021-08-30 16:37:21.791897976 +0200 +@@ -113,13 +113,13 @@ pselect_notify_setup(void) + static void + pselect_notify_parent(void) + { +- if (notify_pipe[1] != -1) ++ if (notify_pipe[1] >= 0) + (void)write(notify_pipe[1], "", 1); + } + static void + pselect_notify_prepare(fd_set *readset) + { +- if (notify_pipe[0] != -1) ++ if (notify_pipe[0] >= 0) + FD_SET(notify_pipe[0], readset); + } + static void +@@ -127,8 +127,8 @@ pselect_notify_done(fd_set *readset) + { + char c; + +- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) { +- 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_f("reading"); + FD_CLR(notify_pipe[0], readset); + } +diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c +--- openssh-8.5p1/readconf.c.coverity 2021-03-24 12:03:33.778968131 +0100 ++++ openssh-8.5p1/readconf.c 2021-03-24 12:03:33.785968180 +0100 +@@ -1847,6 +1847,7 @@ parse_pubkey_algos: + } else if (r != 0) { + error("%.200s line %d: glob failed for %s.", + filename, linenum, arg2); ++ free(arg2); + goto out; + } + free(arg2); +diff -up openssh-8.7p1/scp.c.coverity openssh-8.7p1/scp.c +--- openssh-8.7p1/scp.c.coverity 2021-08-30 16:23:35.389741329 +0200 ++++ openssh-8.7p1/scp.c 2021-08-30 16:27:04.854555296 +0200 +@@ -186,11 +186,11 @@ killchild(int signo) { if (do_cmd_pid > 1) { kill(do_cmd_pid, signo ? signo : SIGTERM); - waitpid(do_cmd_pid, NULL, 0); + (void) waitpid(do_cmd_pid, NULL, 0); } + if (do_cmd_pid2 > 1) { + kill(do_cmd_pid2, signo ? signo : SIGTERM); +- waitpid(do_cmd_pid2, NULL, 0); ++ (void) waitpid(do_cmd_pid2, NULL, 0); + } if (signo) diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c --- openssh-7.4p1/servconf.c.coverity 2016-12-23 16:40:26.896788690 +0100 +++ openssh-7.4p1/servconf.c 2016-12-23 16:40:26.901788691 +0100 -@@ -1547,7 +1547,7 @@ process_server_config_line(ServerOptions - fatal("%s line %d: Missing subsystem name.", - filename, linenum); - if (!*activep) { -- arg = strdelim(&cp); -+ /*arg =*/ (void) strdelim(&cp); - break; - } - for (i = 0; i < options->num_subsystems; i++) @@ -1638,8 +1638,9 @@ process_server_config_line(ServerOptions if (*activep && *charptr == NULL) { *charptr = tilde_expand_filename(arg, getuid()); @@ -93,38 +377,11 @@ diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c } break; -diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c ---- openssh-7.4p1/serverloop.c.coverity 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/serverloop.c 2016-12-23 16:40:26.902788691 +0100 -@@ -125,13 +125,13 @@ notify_setup(void) - static void - notify_parent(void) - { -- if (notify_pipe[1] != -1) -+ if (notify_pipe[1] >= 0) - (void)write(notify_pipe[1], "", 1); - } - static void - notify_prepare(fd_set *readset) - { -- if (notify_pipe[0] != -1) -+ if (notify_pipe[0] >= 0) - FD_SET(notify_pipe[0], readset); - } - static void -@@ -139,8 +139,8 @@ notify_done(fd_set *readset) - { - char c; - -- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) -- 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__); - } - -@@ -518,7 +518,7 @@ server_request_tun(void) - debug("%s: invalid tun", __func__); +diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c +--- openssh-8.7p1/serverloop.c.coverity 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/serverloop.c 2021-08-30 16:28:22.416226981 +0200 +@@ -547,7 +547,7 @@ server_request_tun(struct ssh *ssh) + debug_f("invalid tun"); goto done; } - if (auth_opts->force_tun_device != -1) { @@ -132,6 +389,24 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != (int)tun) goto done; +diff -up openssh-8.5p1/session.c.coverity openssh-8.5p1/session.c +--- openssh-8.5p1/session.c.coverity 2021-03-24 12:03:33.777968124 +0100 ++++ openssh-8.5p1/session.c 2021-03-24 12:03:33.786968187 +0100 +@@ -1223,12 +1223,14 @@ do_setup_env(struct ssh *ssh, Session *s + /* Environment specified by admin */ + for (i = 0; i < options.num_setenv; i++) { + cp = xstrdup(options.setenv[i]); ++ /* coverity[overwrite_var : FALSE] */ + if ((value = strchr(cp, '=')) == NULL) { + /* shouldn't happen; vars are checked in servconf.c */ + fatal("Invalid config SetEnv: %s", options.setenv[i]); + } + *value++ = '\0'; + child_set_env(&env, &envsize, cp, value); ++ free(cp); + } + + /* SSH_CLIENT deprecated */ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c --- openssh-7.4p1/sftp.c.coverity 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/sftp.c 2016-12-23 16:40:26.903788691 +0100 @@ -144,9 +419,45 @@ diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c } _exit(1); +@@ -762,6 +762,8 @@ process_put(struct sftp_conn *conn, cons + fflag || global_fflag) == -1) + err = -1; + } ++ free(abs_dst); ++ abs_dst = NULL; + } + + out: +@@ -985,6 +987,7 @@ do_globbed_ls(struct sftp_conn *conn, co + if (lflag & LS_LONG_VIEW) { + if (g.gl_statv[i] == NULL) { + error("no stat information for %s", fname); ++ free(fname); + continue; + } + lname = ls_file(fname, g.gl_statv[i], 1, +diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c +--- openssh-8.5p1/sk-usbhid.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/sk-usbhid.c 2021-03-24 12:03:33.786968187 +0100 +@@ -1256,6 +1256,7 @@ sk_load_resident_keys(const char *pin, s + freezero(rks[i], sizeof(*rks[i])); + } + free(rks); ++ free(device); + return ret; + } + diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c --- openssh-7.4p1/ssh-agent.c.coverity 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/ssh-agent.c 2016-12-23 16:40:26.903788691 +0100 +@@ -869,6 +869,7 @@ sanitize_pkcs11_provider(const char *pro + + if (pkcs11_uri_parse(provider, uri) != 0) { + error("Failed to parse PKCS#11 URI"); ++ pkcs11_uri_cleanup(uri); + return NULL; + } + /* validate also provider from URI */ @@ -1220,8 +1220,8 @@ main(int ac, char **av) sanitise_stdfd(); @@ -158,6 +469,17 @@ diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c platform_disable_tracing(0); /* strict=no */ +diff -up openssh-8.5p1/ssh.c.coverity openssh-8.5p1/ssh.c +--- openssh-8.5p1/ssh.c.coverity 2021-03-24 12:03:33.779968138 +0100 ++++ openssh-8.5p1/ssh.c 2021-03-24 12:03:33.786968187 +0100 +@@ -1746,6 +1746,7 @@ control_persist_detach(void) + close(muxserver_sock); + muxserver_sock = -1; + options.control_master = SSHCTL_MASTER_NO; ++ /* coverity[leaked_handle: FALSE]*/ + muxclient(options.control_path); + /* muxclient() doesn't return on success. */ + fatal("Failed to connect to new control master"); diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c --- openssh-7.4p1/sshd.c.coverity 2016-12-23 16:40:26.897788690 +0100 +++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100 @@ -183,3 +505,67 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c } /* +@@ -2474,7 +2479,7 @@ do_ssh2_kex(struct ssh *ssh) + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); +- ++ /* coverity[leaked_storage : FALSE]*/ + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( + ssh, list_hostkey_types()); + +@@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh) + + if (newstr) + myproposal[PROPOSAL_KEX_ALGS] = newstr; +- else ++ else { + fatal("No supported key exchange algorithms"); ++ free(gss); ++ } ++ /* coverity[leaked_storage: FALSE]*/ + } + #endif + +diff -up openssh-8.5p1/ssh-keygen.c.coverity openssh-8.5p1/ssh-keygen.c +--- openssh-8.5p1/ssh-keygen.c.coverity 2021-03-24 12:03:33.780968145 +0100 ++++ openssh-8.5p1/ssh-keygen.c 2021-03-24 12:03:33.787968194 +0100 +@@ -2332,6 +2332,9 @@ update_krl_from_file(struct passwd *pw, + r = ssh_krl_revoke_key_sha256(krl, blob, blen); + if (r != 0) + fatal_fr(r, "revoke key failed"); ++ freezero(blob, blen); ++ blob = NULL; ++ blen = 0; + } else { + if (strncasecmp(cp, "key:", 4) == 0) { + cp += 4; +@@ -2879,6 +2882,7 @@ do_moduli_screen(const char *out_file, c + } else if (strncmp(opts[i], "start-line=", 11) == 0) { + start_lineno = strtoul(opts[i]+11, NULL, 10); + } else if (strncmp(opts[i], "checkpoint=", 11) == 0) { ++ free(checkpoint); + checkpoint = xstrdup(opts[i]+11); + } else if (strncmp(opts[i], "generator=", 10) == 0) { + generator_wanted = (u_int32_t)strtonum( +@@ -2920,6 +2924,9 @@ do_moduli_screen(const char *out_file, c + #else /* WITH_OPENSSL */ + fatal("Moduli screening is not supported"); + #endif /* WITH_OPENSSL */ ++ free(checkpoint); ++ if (in != stdin) ++ fclose(in); + } + + static char * +diff -up openssh-8.5p1/sshsig.c.coverity openssh-8.5p1/sshsig.c +--- openssh-8.5p1/sshsig.c.coverity 2021-03-02 11:31:47.000000000 +0100 ++++ openssh-8.5p1/sshsig.c 2021-03-24 12:03:33.787968194 +0100 +@@ -515,6 +515,7 @@ hash_file(int fd, const char *hashalg, s + oerrno = errno; + error_f("read: %s", strerror(errno)); + ssh_digest_free(ctx); ++ ctx = NULL; + errno = oerrno; + r = SSH_ERR_SYSTEM_ERROR; + goto out; diff --git a/openssh-6.7p1-kdf-cavs.patch b/openssh-6.7p1-kdf-cavs.patch deleted file mode 100644 index 971ac3d8db6bdf9d89e35c42fda9654e5839af9e..0000000000000000000000000000000000000000 --- a/openssh-6.7p1-kdf-cavs.patch +++ /dev/null @@ -1,618 +0,0 @@ -diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in ---- openssh-6.8p1/Makefile.in.kdf-cavs 2015-03-18 11:23:46.346049359 +0100 -+++ openssh-6.8p1/Makefile.in 2015-03-18 11:24:20.395968445 +0100 -@@ -29,6 +29,7 @@ SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-h - SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper - SSH_KEYCAT=$(libexecdir)/ssh-keycat - CTR_CAVSTEST=$(libexecdir)/ctr-cavstest -+SSH_CAVS=$(libexecdir)/ssh-cavs - SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper - SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper - PRIVSEP_PATH=@PRIVSEP_PATH@ -@@ -67,7 +68,7 @@ EXEEXT=@EXEEXT@ - - .SUFFIXES: .lo - --TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) -+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) ssh-cavs$(EXEEXT) - - XMSS_OBJS=\ - ssh-xmss.o \ -@@ -198,6 +199,9 @@ ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHD - ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o - $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) - -+ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-cavs.o $(SKOBJS) -+ $(LD) -o $@ ssh-cavs.o $(SKOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) - $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) - -@@ -331,6 +335,8 @@ install-files: - fi - $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) ctr-cavstest$(EXEEXT) $(DESTDIR)$(libexecdir)/ctr-cavstest$(EXEEXT) -+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-cavs$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-cavs$(EXEEXT) -+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-cavs_driver.pl $(DESTDIR)$(libexecdir)/ssh-cavs_driver.pl - $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) - $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c ---- openssh-6.8p1/ssh-cavs.c.kdf-cavs 2015-03-18 11:23:46.348049354 +0100 -+++ openssh-6.8p1/ssh-cavs.c 2015-03-18 11:23:46.348049354 +0100 -@@ -0,0 +1,387 @@ -+/* -+ * Copyright (C) 2015, Stephan Mueller -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, and the entire permission notice in its entirety, -+ * including the disclaimer of warranties. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The name of the author may not be used to endorse or promote -+ * products derived from this software without specific prior -+ * written permission. -+ * -+ * ALTERNATIVELY, this product may be distributed under the terms of -+ * the GNU General Public License, in which case the provisions of the GPL2 -+ * are required INSTEAD OF the above restrictions. (This clause is -+ * necessary due to a potential bad interaction between the GPL and -+ * the restrictions contained in a BSD-style copyright.) -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF -+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ */ -+ -+#include "includes.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "xmalloc.h" -+#include "sshbuf.h" -+#include "sshkey.h" -+#include "cipher.h" -+#include "kex.h" -+#include "packet.h" -+#include "digest.h" -+ -+static int bin_char(unsigned char hex) -+{ -+ if (48 <= hex && 57 >= hex) -+ return (hex - 48); -+ if (65 <= hex && 70 >= hex) -+ return (hex - 55); -+ if (97 <= hex && 102 >= hex) -+ return (hex - 87); -+ return 0; -+} -+ -+/* -+ * Convert hex representation into binary string -+ * @hex input buffer with hex representation -+ * @hexlen length of hex -+ * @bin output buffer with binary data -+ * @binlen length of already allocated bin buffer (should be at least -+ * half of hexlen -- if not, only a fraction of hexlen is converted) -+ */ -+static void hex2bin(const char *hex, size_t hexlen, -+ unsigned char *bin, size_t binlen) -+{ -+ size_t i = 0; -+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen; -+ -+ for (i = 0; i < chars; i++) { -+ bin[i] = bin_char(hex[(i*2)]) << 4; -+ bin[i] |= bin_char(hex[((i*2)+1)]); -+ } -+} -+ -+/* -+ * Allocate sufficient space for binary representation of hex -+ * and convert hex into bin -+ * -+ * Caller must free bin -+ * @hex input buffer with hex representation -+ * @hexlen length of hex -+ * @bin return value holding the pointer to the newly allocated buffer -+ * @binlen return value holding the allocated size of bin -+ * -+ * return: 0 on success, !0 otherwise -+ */ -+static int hex2bin_alloc(const char *hex, size_t hexlen, -+ unsigned char **bin, size_t *binlen) -+{ -+ unsigned char *out = NULL; -+ size_t outlen = 0; -+ -+ if (!hexlen) -+ return -EINVAL; -+ -+ outlen = (hexlen + 1) / 2; -+ -+ out = calloc(1, outlen); -+ if (!out) -+ return -errno; -+ -+ hex2bin(hex, hexlen, out, outlen); -+ *bin = out; -+ *binlen = outlen; -+ return 0; -+} -+ -+static char hex_char_map_l[] = { '0', '1', '2', '3', '4', '5', '6', '7', -+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; -+static char hex_char_map_u[] = { '0', '1', '2', '3', '4', '5', '6', '7', -+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; -+static char hex_char(unsigned int bin, int u) -+{ -+ if (bin < sizeof(hex_char_map_l)) -+ return (u) ? hex_char_map_u[bin] : hex_char_map_l[bin]; -+ return 'X'; -+} -+ -+/* -+ * Convert binary string into hex representation -+ * @bin input buffer with binary data -+ * @binlen length of bin -+ * @hex output buffer to store hex data -+ * @hexlen length of already allocated hex buffer (should be at least -+ * twice binlen -- if not, only a fraction of binlen is converted) -+ * @u case of hex characters (0=>lower case, 1=>upper case) -+ */ -+static void bin2hex(const unsigned char *bin, size_t binlen, -+ char *hex, size_t hexlen, int u) -+{ -+ size_t i = 0; -+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen; -+ -+ for (i = 0; i < chars; i++) { -+ hex[(i*2)] = hex_char((bin[i] >> 4), u); -+ hex[((i*2)+1)] = hex_char((bin[i] & 0x0f), u); -+ } -+} -+ -+struct kdf_cavs { -+ unsigned char *K; -+ size_t Klen; -+ unsigned char *H; -+ size_t Hlen; -+ unsigned char *session_id; -+ size_t session_id_len; -+ -+ unsigned int iv_len; -+ unsigned int ek_len; -+ unsigned int ik_len; -+}; -+ -+static int sshkdf_cavs(struct kdf_cavs *test) -+{ -+ int ret = 0; -+ struct kex kex; -+ struct sshbuf *Kb = NULL; -+ BIGNUM *Kbn = NULL; -+ int mode = 0; -+ struct newkeys *ctoskeys; -+ struct newkeys *stockeys; -+ struct ssh *ssh = NULL; -+ -+#define HEXOUTLEN 500 -+ char hex[HEXOUTLEN]; -+ -+ memset(&kex, 0, sizeof(struct kex)); -+ -+ Kbn = BN_new(); -+ BN_bin2bn(test->K, test->Klen, Kbn); -+ if (!Kbn) { -+ printf("cannot convert K into bignum\n"); -+ ret = 1; -+ goto out; -+ } -+ Kb = sshbuf_new(); -+ if (!Kb) { -+ printf("cannot convert K into sshbuf\n"); -+ ret = 1; -+ goto out; -+ } -+ sshbuf_put_bignum2(Kb, Kbn); -+ -+ kex.session_id = test->session_id; -+ kex.session_id_len = test->session_id_len; -+ -+ /* setup kex */ -+ -+ /* select the right hash based on struct ssh_digest digests */ -+ switch (test->ik_len) { -+ case 20: -+ kex.hash_alg = SSH_DIGEST_SHA1; -+ break; -+ case 32: -+ kex.hash_alg = SSH_DIGEST_SHA256; -+ break; -+ case 48: -+ kex.hash_alg = SSH_DIGEST_SHA384; -+ break; -+ case 64: -+ kex.hash_alg = SSH_DIGEST_SHA512; -+ break; -+ default: -+ printf("Wrong hash type %u\n", test->ik_len); -+ ret = 1; -+ goto out; -+ } -+ -+ /* implement choose_enc */ -+ for (mode = 0; mode < 2; mode++) { -+ kex.newkeys[mode] = calloc(1, sizeof(struct newkeys)); -+ if (!kex.newkeys[mode]) { -+ printf("allocation of newkeys failed\n"); -+ ret = 1; -+ goto out; -+ } -+ kex.newkeys[mode]->enc.iv_len = test->iv_len; -+ kex.newkeys[mode]->enc.key_len = test->ek_len; -+ kex.newkeys[mode]->enc.block_size = (test->iv_len == 64) ? 8 : 16; -+ kex.newkeys[mode]->mac.key_len = test->ik_len; -+ } -+ -+ /* implement kex_choose_conf */ -+ kex.we_need = kex.newkeys[0]->enc.key_len; -+ if (kex.we_need < kex.newkeys[0]->enc.block_size) -+ kex.we_need = kex.newkeys[0]->enc.block_size; -+ if (kex.we_need < kex.newkeys[0]->enc.iv_len) -+ kex.we_need = kex.newkeys[0]->enc.iv_len; -+ if (kex.we_need < kex.newkeys[0]->mac.key_len) -+ kex.we_need = kex.newkeys[0]->mac.key_len; -+ -+ /* MODE_OUT (1) -> server to client -+ * MODE_IN (0) -> client to server */ -+ kex.server = 1; -+ -+ /* do it */ -+ if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL){ -+ printf("Allocation error\n"); -+ goto out; -+ } -+ ssh->kex = &kex; -+ kex_derive_keys(ssh, test->H, test->Hlen, Kb); -+ -+ ctoskeys = kex.newkeys[0]; -+ stockeys = kex.newkeys[1]; -+ -+ /* get data */ -+ memset(hex, 0, HEXOUTLEN); -+ bin2hex(ctoskeys->enc.iv, (size_t)ctoskeys->enc.iv_len, -+ hex, HEXOUTLEN, 0); -+ printf("Initial IV (client to server) = %s\n", hex); -+ memset(hex, 0, HEXOUTLEN); -+ bin2hex(stockeys->enc.iv, (size_t)stockeys->enc.iv_len, -+ hex, HEXOUTLEN, 0); -+ printf("Initial IV (server to client) = %s\n", hex); -+ -+ memset(hex, 0, HEXOUTLEN); -+ bin2hex(ctoskeys->enc.key, (size_t)ctoskeys->enc.key_len, -+ hex, HEXOUTLEN, 0); -+ printf("Encryption key (client to server) = %s\n", hex); -+ memset(hex, 0, HEXOUTLEN); -+ bin2hex(stockeys->enc.key, (size_t)stockeys->enc.key_len, -+ hex, HEXOUTLEN, 0); -+ printf("Encryption key (server to client) = %s\n", hex); -+ -+ memset(hex, 0, HEXOUTLEN); -+ bin2hex(ctoskeys->mac.key, (size_t)ctoskeys->mac.key_len, -+ hex, HEXOUTLEN, 0); -+ printf("Integrity key (client to server) = %s\n", hex); -+ memset(hex, 0, HEXOUTLEN); -+ bin2hex(stockeys->mac.key, (size_t)stockeys->mac.key_len, -+ hex, HEXOUTLEN, 0); -+ printf("Integrity key (server to client) = %s\n", hex); -+ -+out: -+ if (Kbn) -+ BN_free(Kbn); -+ if (Kb) -+ sshbuf_free(Kb); -+ if (ssh) -+ ssh_packet_close(ssh); -+ return ret; -+} -+ -+static void usage(void) -+{ -+ fprintf(stderr, "\nOpenSSH KDF CAVS Test\n\n"); -+ fprintf(stderr, "Usage:\n"); -+ fprintf(stderr, "\t-K\tShared secret string\n"); -+ fprintf(stderr, "\t-H\tHash string\n"); -+ fprintf(stderr, "\t-s\tSession ID string\n"); -+ fprintf(stderr, "\t-i\tIV length to be generated\n"); -+ fprintf(stderr, "\t-e\tEncryption key length to be generated\n"); -+ fprintf(stderr, "\t-m\tMAC key length to be generated\n"); -+} -+ -+/* -+ * Test command example: -+ * ./ssh-cavs -K 0055d50f2d163cc07cd8a93cc7c3430c30ce786b572c01ad29fec7597000cf8618d664e2ec3dcbc8bb7a1a7eb7ef67f61cdaf291625da879186ac0a5cb27af571b59612d6a6e0627344d846271959fda61c78354aa498773d59762f8ca2d0215ec590d8633de921f920d41e47b3de6ab9a3d0869e1c826d0e4adebf8e3fb646a15dea20a410b44e969f4b791ed6a67f13f1b74234004d5fa5e87eff7abc32d49bbdf44d7b0107e8f10609233b7e2b7eff74a4daf25641de7553975dac6ac1e5117df6f6dbaa1c263d23a6c3e5a3d7d49ae8a828c1e333ac3f85fbbf57b5c1a45be45e43a7be1a4707eac779b8285522d1f531fe23f890fd38a004339932b93eda4 -H d3ab91a850febb417a25d892ec48ed5952c7a5de -s d3ab91a850febb417a25d892ec48ed5952c7a5de -i 8 -e 24 -m 20 -+ * -+ * Initial IV (client to server) = 4bb320d1679dfd3a -+ * Initial IV (server to client) = 43dea6fdf263a308 -+ * Encryption key (client to server) = 13048cc600b9d3cf9095aa6cf8e2ff9cf1c54ca0520c89ed -+ * Encryption key (server to client) = 1e483c5134e901aa11fc4e0a524e7ec7b75556148a222bb0 -+ * Integrity key (client to server) = ecef63a092b0dcc585bdc757e01b2740af57d640 -+ * Integrity key (server to client) = 7424b05f3c44a72b4ebd281fb71f9cbe7b64d479 -+ */ -+int main(int argc, char *argv[]) -+{ -+ struct kdf_cavs test; -+ int ret = 1; -+ int opt = 0; -+ -+ memset(&test, 0, sizeof(struct kdf_cavs)); -+ while((opt = getopt(argc, argv, "K:H:s:i:e:m:")) != -1) -+ { -+ size_t len = 0; -+ switch(opt) -+ { -+ /* -+ * CAVS K is MPINT -+ * we want a hex (i.e. the caller must ensure the -+ * following transformations already happened): -+ * 1. cut off first four bytes -+ * 2. if most significant bit of value is -+ * 1, prepend 0 byte -+ */ -+ case 'K': -+ len = strlen(optarg); -+ ret = hex2bin_alloc(optarg, len, -+ &test.K, &test.Klen); -+ if (ret) -+ goto out; -+ break; -+ case 'H': -+ len = strlen(optarg); -+ ret = hex2bin_alloc(optarg, len, -+ &test.H, &test.Hlen); -+ if (ret) -+ goto out; -+ break; -+ case 's': -+ len = strlen(optarg); -+ ret = hex2bin_alloc(optarg, len, -+ &test.session_id, -+ &test.session_id_len); -+ if (ret) -+ goto out; -+ break; -+ case 'i': -+ test.iv_len = strtoul(optarg, NULL, 10); -+ break; -+ case 'e': -+ test.ek_len = strtoul(optarg, NULL, 10); -+ break; -+ case 'm': -+ test.ik_len = strtoul(optarg, NULL, 10); -+ break; -+ default: -+ usage(); -+ goto out; -+ } -+ } -+ -+ ret = sshkdf_cavs(&test); -+ -+out: -+ if (test.session_id) -+ free(test.session_id); -+ if (test.K) -+ free(test.K); -+ if (test.H) -+ free(test.H); -+ return ret; -+ -+} -diff -up openssh-6.8p1/ssh-cavs_driver.pl.kdf-cavs openssh-6.8p1/ssh-cavs_driver.pl ---- openssh-6.8p1/ssh-cavs_driver.pl.kdf-cavs 2015-03-18 11:23:46.348049354 +0100 -+++ openssh-6.8p1/ssh-cavs_driver.pl 2015-03-18 11:23:46.348049354 +0100 -@@ -0,0 +1,184 @@ -+#!/usr/bin/env perl -+# -+# CAVS test driver for OpenSSH -+# -+# Copyright (C) 2015, Stephan Mueller -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# NO WARRANTY -+# -+# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+# REPAIR OR CORRECTION. -+# -+# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+# POSSIBILITY OF SUCH DAMAGES. -+# -+use strict; -+use warnings; -+use IPC::Open2; -+ -+# Executing a program by feeding STDIN and retrieving -+# STDOUT -+# $1: data string to be piped to the app on STDIN -+# rest: program and args -+# returns: STDOUT of program as string -+sub pipe_through_program($@) { -+ my $in = shift; -+ my @args = @_; -+ -+ my ($CO, $CI); -+ my $pid = open2($CO, $CI, @args); -+ -+ my $out = ""; -+ my $len = length($in); -+ my $first = 1; -+ while (1) { -+ my $rin = ""; -+ my $win = ""; -+ # Output of prog is FD that we read -+ vec($rin,fileno($CO),1) = 1; -+ # Input of prog is FD that we write -+ # check for $first is needed because we can have NULL input -+ # that is to be written to the app -+ if ( $len > 0 || $first) { -+ (vec($win,fileno($CI),1) = 1); -+ $first=0; -+ } -+ # Let us wait for 100ms -+ my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1); -+ if ( $wout ) { -+ my $written = syswrite($CI, $in, $len); -+ die "broken pipe" if !defined $written; -+ $len -= $written; -+ substr($in, 0, $written) = ""; -+ if ($len <= 0) { -+ close $CI or die "broken pipe: $!"; -+ } -+ } -+ if ( $rout ) { -+ my $tmp_out = ""; -+ my $bytes_read = sysread($CO, $tmp_out, 4096); -+ $out .= $tmp_out; -+ last if ($bytes_read == 0); -+ } -+ } -+ close $CO or die "broken pipe: $!"; -+ waitpid $pid, 0; -+ -+ return $out; -+} -+ -+# Parser of CAVS test vector file -+# $1: Test vector file -+# $2: Output file for test results -+# return: nothing -+sub parse($$) { -+ my $infile = shift; -+ my $outfile = shift; -+ -+ my $out = ""; -+ -+ my $K = ""; -+ my $H = ""; -+ my $session_id = ""; -+ my $ivlen = 0; -+ my $eklen = ""; -+ my $iklen = ""; -+ -+ open(IN, "<$infile"); -+ while() { -+ -+ my $line = $_; -+ chomp($line); -+ $line =~ s/\r//; -+ -+ if ($line =~ /\[SHA-1\]/) { -+ $iklen = 20; -+ } elsif ($line =~ /\[SHA-256\]/) { -+ $iklen = 32; -+ } elsif ($line =~ /\[SHA-384\]/) { -+ $iklen = 48; -+ } elsif ($line =~ /\[SHA-512\]/) { -+ $iklen = 64; -+ } elsif ($line =~ /^\[IV length\s*=\s*(.*)\]/) { -+ $ivlen = $1; -+ $ivlen = $ivlen / 8; -+ } elsif ($line =~ /^\[encryption key length\s*=\s*(.*)\]/) { -+ $eklen = $1; -+ $eklen = $eklen / 8; -+ } elsif ($line =~ /^K\s*=\s*(.*)/) { -+ $K = $1; -+ $K = substr($K, 8); -+ $K = "00" . $K; -+ } elsif ($line =~ /^H\s*=\s*(.*)/) { -+ $H = $1; -+ } elsif ($line =~ /^session_id\s*=\s*(.*)/) { -+ $session_id = $1; -+ } -+ $out .= $line . "\n"; -+ -+ if ($K ne "" && $H ne "" && $session_id ne "" && -+ $ivlen ne "" && $eklen ne "" && $iklen > 0) { -+ $out .= pipe_through_program("", "./ssh-cavs -H $H -K $K -s $session_id -i $ivlen -e $eklen -m $iklen"); -+ -+ $K = ""; -+ $H = ""; -+ $session_id = ""; -+ } -+ } -+ close IN; -+ $out =~ s/\n/\r\n/g; # make it a dos file -+ open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?"; -+ print OUT $out; -+ close OUT; -+} -+ -+############################################################ -+# -+# let us pretend to be C :-) -+sub main() { -+ -+ my $infile=$ARGV[0]; -+ die "Error: Test vector file $infile not found" if (! -f $infile); -+ -+ my $outfile = $infile; -+ # let us add .rsp regardless whether we could strip .req -+ $outfile =~ s/\.req$//; -+ $outfile .= ".rsp"; -+ if (-f $outfile) { -+ die "Output file $outfile could not be removed: $?" -+ unless unlink($outfile); -+ } -+ print STDERR "Performing tests from source file $infile with results stored in destination file $outfile\n"; -+ -+ # Do the job -+ parse($infile, $outfile); -+} -+ -+########################################### -+# Call it -+main(); -+1; diff --git a/openssh-6.7p1-ldap.patch b/openssh-6.7p1-ldap.patch deleted file mode 100644 index aec47942166d2621f3d0c747a2c15ec6000c0db4..0000000000000000000000000000000000000000 --- a/openssh-6.7p1-ldap.patch +++ /dev/null @@ -1,2748 +0,0 @@ -diff -up openssh-6.8p1/HOWTO.ldap-keys.ldap openssh-6.8p1/HOWTO.ldap-keys ---- openssh-6.8p1/HOWTO.ldap-keys.ldap 2015-03-18 11:11:29.029801467 +0100 -+++ openssh-6.8p1/HOWTO.ldap-keys 2015-03-18 11:11:29.029801467 +0100 -@@ -0,0 +1,122 @@ -+ -+HOW TO START -+ -+1) configure LDAP server -+ * Use LDAP server documentation -+2) add appropriate LDAP schema -+ * For OpenLDAP or SunONE Use attached schema, otherwise you have to create it. -+ * LDAP user entry -+ User entry: -+ - attached to the 'ldapPublicKey' objectclass -+ - attached to the 'posixAccount' objectclass -+ - with a filled 'sshPublicKey' attribute -+3) insert users into LDAP -+ * Use LDAP Tree management tool as useful -+ * Entry in the LDAP server must respect 'posixAccount' and 'ldapPublicKey' which are defined in core.schema and the additionnal lpk.schema. -+ * Example: -+ dn: uid=captain,ou=commanders,dc=enterprise,dc=universe -+ objectclass: top -+ objectclass: person -+ objectclass: organizationalPerson -+ objectclass: posixAccount -+ objectclass: ldapPublicKey -+ description: Jonathan Archer -+ userPassword: Porthos -+ cn: onathan Archer -+ sn: onathan Archer -+ uid: captain -+ uidNumber: 1001 -+ gidNumber: 1001 -+ homeDirectory: /home/captain -+ sshPublicKey: ssh-rss AAAAB3.... =captain@universe -+ sshPublicKey: command="kill -9 1" ssh-rss AAAAM5... -+4) on the ssh side set in sshd_config -+ * Set up the backend -+ AuthorizedKeysCommand /usr/libexec/openssh/ssh-ldap-wrapper -+ AuthorizedKeysCommandUser -+ * Do not forget to set -+ PubkeyAuthentication yes -+ * Swith off unnecessary auth methods -+5) confugure ldap.conf -+ * Default ldap.conf is placed in /etc/ssh -+ * The configuration style is the same as other ldap based aplications -+6) if necessary edit ssh-ldap-wrapper -+ * There is a possibility to change ldap.conf location -+ * There are some debug options -+ * Example -+ /usr/libexec/openssh -s -f /etc/ldap.conf -w -d >> /tmp/ldapdebuglog.txt -+7) Configure SELinux boolean which allows ldap-helper to bind ldap server -+ Run this command -+ # setsebool -P authlogin_nsswitch_use_ldap on -+ -+HOW TO MIGRATE FROM LPK -+ -+1) goto HOW TO START 4) .... the ldap schema is the same -+ -+2) convert the group requests to the appropriate LDAP requests -+ -+HOW TO SOLVE PROBLEMS -+ -+1) use debug in sshd -+ * /usr/sbin/sshd -d -d -d -d -+2) use debug in ssh-ldap-helper -+ * ssh-ldap-helper -d -d -d -d -s -+3) use tcpdump ... other ldap client etc. -+ -+HOW TO CONFIGURE SSH FOR OTHER LDAP CONFIGURATION / SERVER /SCHEMA -+ -+You can adjust search format string in /etc/ldap.conf using -+ 1) SSH_Filter option to limit results for only specified users -+ (this appends search condition after original query) -+ 2) Search_Format option to define your own search string using expansion -+ characters %u for username, %c for objectclass and %f for above mentioned filter. -+ -+Example: -+Search_Format (&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%u)%f) -+ -+ADVANTAGES -+ -+1) Blocking an user account can be done directly from LDAP (if sshd is using PubkeyAuthentication + AuthorizedKeysCommand with ldap only). -+ -+DISADVANTAGES -+ -+1) LDAP must be well configured, getting the public key of some user is not a problem, but if anonymous LDAP -+ allows write to users dn, somebody could replace some user's public key by his own and impersonate some -+ of your users in all your server farm -- be VERY CAREFUL. -+2) With incomplete PKI the MITM attack when sshd is requesting the public key, could lead to a compromise of your servers allowing login -+ as the impersonated user. -+3) If LDAP server is down there may be no fallback on passwd auth. -+ -+MISC. -+ -+1) todo -+ * Possibility to reuse the ssh-ldap-helper. -+ * Tune the LDAP part to accept all possible LDAP configurations. -+ -+2) differences from original lpk -+ * No LDAP code in sshd. -+ * Support for various LDAP platforms and configurations. -+ * LDAP is configured in separate ldap.conf file. -+ -+3) docs/link -+ * http://pacsec.jp/core05/psj05-barisani-en.pdf -+ * http://fritz.potsdam.edu/projects/openssh-lpk/ -+ * http://fritz.potsdam.edu/projects/sshgate/ -+ * http://dev.inversepath.com/trac/openssh-lpk -+ * http://lam.sf.net/ ( http://lam.sourceforge.net/documentation/supportedSchemas.htm ) -+ -+4) contributors/ideas/greets -+ - Eric AUGE -+ - Andrea Barisani -+ - Falk Siemonsmeier. -+ - Jacob Rief. -+ - Michael Durchgraf. -+ - frederic peters. -+ - Finlay dobbie. -+ - Stefan Fisher. -+ - Robin H. Johnson. -+ - Adrian Bridgett. -+ -+5) Author -+ Jan F. Chadima -+ -diff -up openssh-6.8p1/Makefile.in.ldap openssh-6.8p1/Makefile.in ---- openssh-6.8p1/Makefile.in.ldap 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/Makefile.in 2015-03-18 11:13:10.147561177 +0100 -@@ -25,6 +25,8 @@ SSH_PROGRAM=@bindir@/ssh - ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass - SFTP_SERVER=$(libexecdir)/sftp-server - SSH_KEYSIGN=$(libexecdir)/ssh-keysign -+SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper -+SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper - SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper - SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper - PRIVSEP_PATH=@PRIVSEP_PATH@ -@@ -50,6 +50,7 @@ - CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ - PICFLAG=@PICFLAG@ - LIBS=@LIBS@ -+LDAPLIBS=@LDAPLIBS@ - K5LIBS=@K5LIBS@ - GSSLIBS=@GSSLIBS@ - SSHLIBS=@SSHLIBS@ -@@ -61,10 +63,11 @@ XAUTH_PATH=@XAUTH_PATH@ - EXEEXT=@EXEEXT@ - MANFMT=@MANFMT@ - MKDIR_P=@MKDIR_P@ -+INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ - - .SUFFIXES: .lo - --TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) -+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) ssh-ldap-helper$(EXEEXT) - - XMSS_OBJS=\ - ssh-xmss.o \ -@@ -112,8 +115,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passw - - SFTP_OBJS= sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o - --MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out sshd_config.5.out ssh_config.5.out --MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5 -+MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap-helper.8.out ssh-ldap.conf.5.out -+MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5 ssh-ldap-helper.8 ssh-ldap.conf.5 - MANTYPE = @MANTYPE@ - - CONFIGFILES=sshd_config.out ssh_config.out moduli.out -@@ -184,6 +187,9 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libss - ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) - $(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) - -+ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o -+ $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) $(LDAPLIBS) -+ - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) - $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) - -@@ -311,6 +317,10 @@ install-files: - $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ $(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ -+ $(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ -+ fi - $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) - $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) - $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -@@ -327,6 +337,10 @@ install-files: - $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 - $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 - $(INSTALL) -m 644 ssh-sk-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8 -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ $(INSTALL) -m 644 ssh-ldap-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 ; \ -+ $(INSTALL) -m 644 ssh-ldap.conf.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh-ldap.conf.5 ; \ -+ fi - - install-sysconf: - $(MKDIR_P) $(DESTDIR)$(sysconfdir) -@@ -356,6 +370,13 @@ install-sysconf: - else \ - echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ - fi -+ if test ! -z "$(INSTALL_SSH_LDAP_HELPER)" ; then \ -+ if [ ! -f $(DESTDIR)$(sysconfdir)/ldap.conf ]; then \ -+ $(INSTALL) -m 644 ldap.conf $(DESTDIR)$(sysconfdir)/ldap.conf; \ -+ else \ -+ echo "$(DESTDIR)$(sysconfdir)/ldap.conf already exists, install will not overwrite"; \ -+ fi ; \ -+ fi - - host-key: ssh-keygen$(EXEEXT) - @if [ -z "$(DESTDIR)" ] ; then \ -@@ -419,6 +440,8 @@ uninstall: - -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) - -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) - -rm -f $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) -+ -rm -f $(DESTDIR)$(SSH_LDAP_HELPER)$(EXEEXT) -+ -rm -f $(DESTDIR)$(SSH_LDAP_WRAPPER)$(EXEEXT) - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 -@@ -430,6 +453,7 @@ uninstall: - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8 -+ -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-ldap-helper.8 - - regress-prep: - $(MKDIR_P) `pwd`/regress/unittests/test_helper -diff -up openssh-6.8p1/configure.ac.ldap openssh-6.8p1/configure.ac ---- openssh-6.8p1/configure.ac.ldap 2015-03-17 06:49:20.000000000 +0100 -+++ openssh-6.8p1/configure.ac 2015-03-18 11:11:29.030801464 +0100 -@@ -1605,6 +1605,110 @@ if test "x$use_pie" != "xno"; then - CFLAGS="$SAVED_CFLAGS" - AC_SUBST([PICFLAG]) - -+# Check whether user wants LDAP support -+LDAP_MSG="no" -+INSTALL_SSH_LDAP_HELPER="" -+AC_ARG_WITH(ldap, -+ [ --with-ldap[[=PATH]] Enable LDAP pubkey support (optionally in PATH)], -+ [ -+ if test "x$withval" != "xno" ; then -+ -+ INSTALL_SSH_LDAP_HELPER="yes" -+ CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED" -+ -+ if test "x$withval" != "xyes" ; then -+ CPPFLAGS="$CPPFLAGS -I${withval}/include" -+ LDFLAGS="$LDFLAGS -L${withval}/lib" -+ fi -+ -+ AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support]) -+ LDAP_MSG="yes" -+ -+ AC_CHECK_HEADERS(lber.h) -+ AC_CHECK_HEADERS(ldap.h, , AC_MSG_ERROR(could not locate )) -+ AC_CHECK_HEADERS(ldap_ssl.h) -+ -+ AC_ARG_WITH(ldap-lib, -+ [ --with-ldap-lib=type select ldap library [auto|netscape5|netscape4|netscape3|umich|openldap]]) -+ -+ if test -z "$with_ldap_lib"; then -+ with_ldap_lib=auto -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \); then -+ AC_CHECK_LIB(lber, main, LDAPLIBS="-llber $LDAPLIBS" found_ldap_lib=yes) -+ AC_CHECK_LIB(ldap, main, LDAPLIBS="-lldap $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \); then -+ AC_CHECK_LIB(ldap50, main, LDAPLIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \); then -+ AC_CHECK_LIB(ldapssl41, main, LDAPLIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LDAPLIBS" found_ldap_lib=yes) -+ if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldapssl40, main, LDAPLIBS="-lldapssl40 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldap41, main, LDAPLIBS="-lldap41 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ if test -z "$found_ldap_lib"; then -+ AC_CHECK_LIB(ldap40, main, LDAPLIBS="-lldap40 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ fi -+ -+ if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \); then -+ AC_CHECK_LIB(ldapssl30, main, LDAPLIBS="-lldapssl30 $LDAPLIBS" found_ldap_lib=yes) -+ fi -+ -+ if test -z "$found_ldap_lib"; then -+ AC_MSG_ERROR(could not locate a valid LDAP library) -+ fi -+ -+ saved_LIBS="$LIBS" -+ LIBS="$LIBS $LDAPLIBS" -+ AC_MSG_CHECKING([for working LDAP support]) -+ AC_TRY_COMPILE( -+ [#include -+ #include ], -+ [(void)ldap_init(0, 0);], -+ [AC_MSG_RESULT(yes)], -+ [ -+ AC_MSG_RESULT(no) -+ AC_MSG_ERROR([** Incomplete or missing ldap libraries **]) -+ ]) -+ AC_CHECK_FUNCS( \ -+ ldap_init \ -+ ldap_get_lderrno \ -+ ldap_set_lderrno \ -+ ldap_parse_result \ -+ ldap_memfree \ -+ ldap_controls_free \ -+ ldap_set_option \ -+ ldap_get_option \ -+ ldapssl_init \ -+ ldap_start_tls_s \ -+ ldap_pvt_tls_set_option \ -+ ldap_initialize \ -+ ) -+ AC_CHECK_FUNCS(ldap_set_rebind_proc, -+ AC_MSG_CHECKING([number arguments of ldap_set_rebind_proc]) -+ AC_TRY_COMPILE( -+ [#include -+ #include ], -+ [ldap_set_rebind_proc(0, 0, 0);], -+ [ac_cv_ldap_set_rebind_proc=3], -+ [ac_cv_ldap_set_rebind_proc=2]) -+ AC_MSG_RESULT($ac_cv_ldap_set_rebind_proc) -+ AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $ac_cv_ldap_set_rebind_proc, [number arguments of ldap_set_rebind_proc]) -+ ) -+ LIBS="$saved_LIBS" -+ fi -+ ] -+) -+AC_SUBST(INSTALL_SSH_LDAP_HELPER) -+AC_SUBST(LDAPLIBS) -+ - dnl Checks for library functions. Please keep in alphabetical order - AC_CHECK_FUNCS([ \ - Blowfish_initstate \ -@@ -5227,6 +5352,9 @@ - echo "Preprocessor flags: ${CPPFLAGS}" - echo " Linker flags: ${LDFLAGS}" - echo " Libraries: ${LIBS}" -+if test ! -z "${LDAPLIBS}"; then -+echo " +for ldap: ${LDAPLIBS}" -+fi - if test ! -z "${SSHDLIBS}"; then - echo " +for sshd: ${SSHDLIBS}" - fi -diff -up openssh-6.8p1/ldap-helper.c.ldap openssh-6.8p1/ldap-helper.c ---- openssh-6.8p1/ldap-helper.c.ldap 2015-03-18 11:11:29.030801464 +0100 -+++ openssh-6.8p1/ldap-helper.c 2015-03-18 11:11:29.030801464 +0100 -@@ -0,0 +1,151 @@ -+/* $OpenBSD: ssh-pka-ldap.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "ldapincludes.h" -+#include "log.h" -+#include "misc.h" -+#include "xmalloc.h" -+#include "ldapconf.h" -+#include "ldapbody.h" -+#include -+#include -+#include -+ -+static int config_debug = 0; -+int config_exclusive_config_file = 0; -+static char *config_file_name = "/etc/ssh/ldap.conf"; -+static char *config_single_user = NULL; -+static int config_verbose = SYSLOG_LEVEL_VERBOSE; -+int config_warning_config_file = 0; -+extern char *__progname; -+ -+static void -+usage(void) -+{ -+ fprintf(stderr, "usage: %s [options]\n", -+ __progname); -+ fprintf(stderr, "Options:\n"); -+ fprintf(stderr, " -d Output the log messages to stderr.\n"); -+ fprintf(stderr, " -e Check the config file for unknown commands.\n"); -+ fprintf(stderr, " -f file Use alternate config file (default is /etc/ssh/ldap.conf).\n"); -+ fprintf(stderr, " -s user Do not demonize, send the user's key to stdout.\n"); -+ fprintf(stderr, " -v Increase verbosity of the debug output (implies -d).\n"); -+ fprintf(stderr, " -w Warn on unknown commands in the config file.\n"); -+ exit(1); -+} -+ -+/* -+ * Main program for the ssh pka ldap agent. -+ */ -+ -+int -+main(int ac, char **av) -+{ -+ int opt; -+ FILE *outfile = NULL; -+ -+ __progname = ssh_get_progname(av[0]); -+ -+ log_init(__progname, SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); -+ -+ /* -+ * Initialize option structure to indicate that no values have been -+ * set. -+ */ -+ initialize_options(); -+ -+ /* Parse command-line arguments. */ -+ while ((opt = getopt(ac, av, "def:s:vw")) != -1) { -+ switch (opt) { -+ case 'd': -+ config_debug = 1; -+ break; -+ -+ case 'e': -+ config_exclusive_config_file = 1; -+ config_warning_config_file = 1; -+ break; -+ -+ case 'f': -+ config_file_name = optarg; -+ break; -+ -+ case 's': -+ config_single_user = optarg; -+ outfile = fdopen (dup (fileno (stdout)), "w"); -+ break; -+ -+ case 'v': -+ config_debug = 1; -+ if (config_verbose < SYSLOG_LEVEL_DEBUG3) -+ config_verbose++; -+ break; -+ -+ case 'w': -+ config_warning_config_file = 1; -+ break; -+ -+ case '?': -+ default: -+ usage(); -+ break; -+ } -+ } -+ -+ /* Initialize loging */ -+ log_init(__progname, config_verbose, SYSLOG_FACILITY_AUTH, config_debug); -+ -+ if (ac != optind) -+ fatal ("illegal extra parameter %s", av[1]); -+ -+ /* Ensure that fds 0 and 2 are open or directed to /dev/null */ -+ if (config_debug == 0) -+ sanitise_stdfd(); -+ -+ /* Read config file */ -+ read_config_file(config_file_name); -+ fill_default_options(); -+ if (config_verbose == SYSLOG_LEVEL_DEBUG3) { -+ debug3 ("=== Configuration ==="); -+ dump_config(); -+ debug3 ("=== *** ==="); -+ } -+ -+ ldap_checkconfig(); -+ ldap_do_connect(); -+ -+ if (config_single_user) { -+ process_user (config_single_user, outfile); -+ } else { -+ usage(); -+ fatal ("Not yet implemented"); -+/* TODO -+ * open unix socket a run the loop on it -+ */ -+ } -+ -+ ldap_do_close(); -+ return 0; -+} -diff -up openssh-6.8p1/ldap-helper.h.ldap openssh-6.8p1/ldap-helper.h ---- openssh-6.8p1/ldap-helper.h.ldap 2015-03-18 11:11:29.031801462 +0100 -+++ openssh-6.8p1/ldap-helper.h 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,32 @@ -+/* $OpenBSD: ldap-helper.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAP_HELPER_H -+#define LDAP_HELPER_H -+ -+extern int config_exclusive_config_file; -+extern int config_warning_config_file; -+ -+#endif /* LDAP_HELPER_H */ -diff -up openssh-6.8p1/ldap.conf.ldap openssh-6.8p1/ldap.conf ---- openssh-6.8p1/ldap.conf.ldap 2015-03-18 11:11:29.031801462 +0100 -+++ openssh-6.8p1/ldap.conf 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,95 @@ -+# $Id: openssh-5.5p1-ldap.patch,v 1.3 2010/07/07 13:48:36 jfch2222 Exp $ -+# -+# This is the example configuration file for the OpenSSH -+# LDAP backend -+# -+# see ssh-ldap.conf(5) -+# -+ -+# URI with your LDAP server name. This allows to use -+# Unix Domain Sockets to connect to a local LDAP Server. -+#uri ldap://127.0.0.1/ -+#uri ldaps://127.0.0.1/ -+#uri ldapi://%2fvar%2frun%2fldapi_sock/ -+# Note: %2f encodes the '/' used as directory separator -+ -+# Another way to specify your LDAP server is to provide an -+# host name and the port of our LDAP server. Host name -+# must be resolvable without using LDAP. -+# Multiple hosts may be specified, each separated by a -+# space. How long nss_ldap takes to failover depends on -+# whether your LDAP client library supports configurable -+# network or connect timeouts (see bind_timelimit). -+#host 127.0.0.1 -+ -+# The port. -+# Optional: default is 389. -+#port 389 -+ -+# The distinguished name to bind to the server with. -+# Optional: default is to bind anonymously. -+#binddn cn=openssh_keys,dc=example,dc=org -+ -+# The credentials to bind with. -+# Optional: default is no credential. -+#bindpw TopSecret -+ -+# The distinguished name of the search base. -+#base dc=example,dc=org -+ -+# The LDAP version to use (defaults to 3 -+# if supported by client library) -+#ldap_version 3 -+ -+# The search scope. -+#scope sub -+#scope one -+#scope base -+ -+# Search timelimit -+#timelimit 30 -+ -+# Bind/connect timelimit -+#bind_timelimit 30 -+ -+# Reconnect policy: hard (default) will retry connecting to -+# the software with exponential backoff, soft will fail -+# immediately. -+#bind_policy hard -+ -+# SSL setup, may be implied by URI also. -+#ssl no -+#ssl on -+#ssl start_tls -+ -+# OpenLDAP SSL options -+# Require and verify server certificate (yes/no) -+# Default is to use libldap's default behavior, which can be configured in -+# /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for -+# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes". -+#tls_checkpeer hard -+ -+# CA certificates for server certificate verification -+# At least one of these are required if tls_checkpeer is "yes" -+#tls_cacertfile /etc/ssl/ca.cert -+#tls_cacertdir /etc/pki/tls/certs -+ -+# Seed the PRNG if /dev/urandom is not provided -+#tls_randfile /var/run/egd-pool -+ -+# SSL cipher suite -+# See man ciphers for syntax -+#tls_ciphers TLSv1 -+ -+# Client certificate and key -+# Use these, if your server requires client authentication. -+#tls_cert -+#tls_key -+ -+# OpenLDAP search_format -+# format used to search for users in LDAP directory using substitution -+# for %u for user name and %f for SSH_Filter option (optional, empty by default) -+#search_format (&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f) -+ -+#AccountClass posixAccount -+ -diff -up openssh-6.8p1/ldapbody.c.ldap openssh-6.8p1/ldapbody.c ---- openssh-6.8p1/ldapbody.c.ldap 2015-03-18 11:11:29.031801462 +0100 -+++ openssh-6.8p1/ldapbody.c 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,499 @@ -+/* $OpenBSD: ldapbody.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "ldapincludes.h" -+#include "log.h" -+#include "xmalloc.h" -+#include "ldapconf.h" -+#include "ldapmisc.h" -+#include "ldapbody.h" -+#include -+#include -+#include -+#include "misc.h" -+ -+#define LDAPSEARCH_FORMAT "(&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f)" -+#define PUBKEYATTR "sshPublicKey" -+#define LDAP_LOGFILE "%s/ldap.%d" -+ -+static FILE *logfile = NULL; -+static LDAP *ld; -+ -+static char *attrs[] = { -+ PUBKEYATTR, -+ NULL -+}; -+ -+void -+ldap_checkconfig (void) -+{ -+#ifdef HAVE_LDAP_INITIALIZE -+ if (options.host == NULL && options.uri == NULL) -+#else -+ if (options.host == NULL) -+#endif -+ fatal ("missing \"host\" in config file"); -+} -+ -+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -+static int -+#if LDAP_API_VERSION > 3000 -+_rebind_proc (LDAP * ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params) -+#else -+_rebind_proc (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid) -+#endif -+{ -+ struct timeval timeout; -+ int rc; -+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE) -+ LDAPMessage *result; -+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */ -+ -+ debug2 ("Doing LDAP rebind to %s", options.binddn); -+ if (options.ssl == SSL_START_TLS) { -+ if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) { -+ error ("ldap_starttls_s: %s", ldap_err2string (rc)); -+ return LDAP_OPERATIONS_ERROR; -+ } -+ } -+ -+#if !defined(HAVE_LDAP_PARSE_RESULT) || !defined(HAVE_LDAP_CONTROLS_FREE) -+ return ldap_simple_bind_s (ld, options.binddn, options.bindpw); -+#else -+ if (ldap_simple_bind(ld, options.binddn, options.bindpw) < 0) -+ fatal ("ldap_simple_bind %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0))); -+ -+ timeout.tv_sec = options.bind_timelimit; -+ timeout.tv_usec = 0; -+ result = NULL; -+ if ((rc = ldap_result (ld, msgid, 0, &timeout, &result)) < 1) { -+ error ("ldap_result %s", ldap_err2string (ldap_get_lderrno (ld, 0, 0))); -+ ldap_msgfree (result); -+ return LDAP_OPERATIONS_ERROR; -+ } -+ debug3 ("LDAP rebind to %s succesfull", options.binddn); -+ return rc; -+#endif -+} -+#else -+ -+static int -+_rebind_proc (LDAP * ld, char **whop, char **credp, int *methodp, int freeit) -+{ -+ if (freeit) -+ return LDAP_SUCCESS; -+ -+ *whop = strdup (options.binddn); -+ *credp = strdup (options.bindpw); -+ *methodp = LDAP_AUTH_SIMPLE; -+ debug2 ("Doing LDAP rebind for %s", *whop); -+ return LDAP_SUCCESS; -+} -+#endif -+ -+void -+ldap_do_connect(void) -+{ -+ int rc, msgid, ld_errno = 0; -+ struct timeval timeout; -+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE) -+ int parserc; -+ LDAPMessage *result; -+ LDAPControl **controls; -+ int reconnect = 0; -+#endif /* HAVE_LDAP_PARSE_RESULT && HAVE_LDAP_CONTROLS_FREE */ -+ -+ debug ("LDAP do connect"); -+ -+retry: -+ if (reconnect) { -+ debug3 ("Reconnecting with ld_errno %d", ld_errno); -+ if (options.bind_policy == 0 || -+ (ld_errno != LDAP_SERVER_DOWN && ld_errno != LDAP_TIMEOUT) || -+ reconnect > 5) -+ fatal ("Cannot connect to LDAP server"); -+ -+ if (reconnect > 1) -+ sleep (reconnect - 1); -+ -+ if (ld != NULL) { -+ ldap_unbind (ld); -+ ld = NULL; -+ } -+ logit("reconnecting to LDAP server..."); -+ } -+ -+ if (ld == NULL) { -+ int rc; -+ struct timeval tv; -+ -+#ifdef HAVE_LDAP_SET_OPTION -+ if (options.debug > 0) { -+#ifdef LBER_OPT_LOG_PRINT_FILE -+ if (options.logdir) { -+ char *logfilename; -+ int logfilenamelen; -+ -+ logfilenamelen = strlen(LDAP_LOGFILE) -+ + strlen("000000") + strlen (options.logdir); -+ logfilename = xmalloc (logfilenamelen); -+ snprintf (logfilename, logfilenamelen, LDAP_LOGFILE, options.logdir, (int) getpid ()); -+ logfilename[logfilenamelen - 1] = 0; -+ if ((logfile = fopen (logfilename, "a")) == NULL) -+ fatal ("cannot append to %s: %s", logfilename, strerror (errno)); -+ debug3 ("LDAP debug into %s", logfilename); -+ free (logfilename); -+ ber_set_option (NULL, LBER_OPT_LOG_PRINT_FILE, logfile); -+ } -+#endif -+ if (options.debug) { -+#ifdef LBER_OPT_DEBUG_LEVEL -+ ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &options.debug); -+#endif /* LBER_OPT_DEBUG_LEVEL */ -+#ifdef LDAP_OPT_DEBUG_LEVEL -+ (void) ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &options.debug); -+#endif /* LDAP_OPT_DEBUG_LEVEL */ -+ debug3 ("Set LDAP debug to %d", options.debug); -+ } -+ } -+#endif /* HAVE_LDAP_SET_OPTION */ -+ -+ ld = NULL; -+#ifdef HAVE_LDAPSSL_INIT -+ if (options.host != NULL) { -+ if (options.ssl_on == SSL_LDAPS) { -+ if ((rc = ldapssl_client_init (options.sslpath, NULL)) != LDAP_SUCCESS) -+ fatal ("ldapssl_client_init %s", ldap_err2string (rc)); -+ debug3 ("LDAPssl client init"); -+ } -+ -+ if (options.ssl_on != SSL_OFF) { -+ if ((ld = ldapssl_init (options.host, options.port, 1)) == NULL) -+ fatal ("ldapssl_init failed"); -+ debug3 ("LDAPssl init"); -+ } -+ } -+#endif /* HAVE_LDAPSSL_INIT */ -+ -+ /* continue with opening */ -+ if (ld == NULL) { -+#if defined (HAVE_LDAP_START_TLS_S) || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) -+ /* Some global TLS-specific options need to be set before we create our -+ * session context, so we set them here. */ -+ -+#ifdef LDAP_OPT_X_TLS_RANDOM_FILE -+ /* rand file */ -+ if (options.tls_randfile != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE, -+ options.tls_randfile)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_RANDOM_FILE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS random file %s", options.tls_randfile); -+ } -+#endif /* LDAP_OPT_X_TLS_RANDOM_FILE */ -+ -+ /* ca cert file */ -+ if (options.tls_cacertfile != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, -+ options.tls_cacertfile)) != LDAP_SUCCESS) -+ error ("ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS CA cert file %s ", options.tls_cacertfile); -+ } -+ -+ /* ca cert directory */ -+ if (options.tls_cacertdir != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR, -+ options.tls_cacertdir)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_CACERTDIR): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS CA cert dir %s ", options.tls_cacertdir); -+ } -+ -+ /* require cert? */ -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, -+ &options.tls_checkpeer)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_REQUIRE_CERT): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS check peer to %d ", options.tls_checkpeer); -+ -+ /* set cipher suite, certificate and private key: */ -+ if (options.tls_ciphers != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, -+ options.tls_ciphers)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_CIPHER_SUITE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS ciphers to %s ", options.tls_ciphers); -+ } -+ -+ /* cert file */ -+ if (options.tls_cert != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE, -+ options.tls_cert)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_CERTFILE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS cert file %s ", options.tls_cert); -+ } -+ -+ /* key file */ -+ if (options.tls_key != NULL) { -+ if ((rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE, -+ options.tls_key)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS_KEYFILE): %s", -+ ldap_err2string (rc)); -+ debug3 ("Set TLS key file %s ", options.tls_key); -+ } -+#endif -+#ifdef HAVE_LDAP_INITIALIZE -+ if (options.uri != NULL) { -+ if ((rc = ldap_initialize (&ld, options.uri)) != LDAP_SUCCESS) -+ fatal ("ldap_initialize %s", ldap_err2string (rc)); -+ debug3 ("LDAP initialize %s", options.uri); -+ } -+ } -+#endif /* HAVE_LDAP_INTITIALIZE */ -+ -+ /* continue with opening */ -+ if ((ld == NULL) && (options.host != NULL)) { -+#ifdef HAVE_LDAP_INIT -+ if ((ld = ldap_init (options.host, options.port)) == NULL) -+ fatal ("ldap_init failed"); -+ debug3 ("LDAP init %s:%d", options.host, options.port); -+#else -+ if ((ld = ldap_open (options.host, options.port)) == NULL) -+ fatal ("ldap_open failed"); -+ debug3 ("LDAP open %s:%d", options.host, options.port); -+#endif /* HAVE_LDAP_INIT */ -+ } -+ -+ if (ld == NULL) -+ fatal ("no way to open ldap"); -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) -+ if (options.ssl == SSL_LDAPS) { -+ if ((rc = ldap_set_option (ld, LDAP_OPT_X_TLS, &options.tls_checkpeer)) != LDAP_SUCCESS) -+ fatal ("ldap_set_option(LDAP_OPT_X_TLS) %s", ldap_err2string (rc)); -+ debug3 ("LDAP set LDAP_OPT_X_TLS_%d", options.tls_checkpeer); -+ } -+#endif /* LDAP_OPT_X_TLS */ -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_PROTOCOL_VERSION) -+ (void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, -+ &options.ldap_version); -+#else -+ ld->ld_version = options.ldap_version; -+#endif -+ debug3 ("LDAP set version to %d", options.ldap_version); -+ -+#if LDAP_SET_REBIND_PROC_ARGS == 3 -+ ldap_set_rebind_proc (ld, _rebind_proc, NULL); -+#elif LDAP_SET_REBIND_PROC_ARGS == 2 -+ ldap_set_rebind_proc (ld, _rebind_proc); -+#else -+#warning unknown LDAP_SET_REBIND_PROC_ARGS -+#endif -+ debug3 ("LDAP set rebind proc"); -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_DEREF) -+ (void) ldap_set_option (ld, LDAP_OPT_DEREF, &options.deref); -+#else -+ ld->ld_deref = options.deref; -+#endif -+ debug3 ("LDAP set deref to %d", options.deref); -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_TIMELIMIT) -+ (void) ldap_set_option (ld, LDAP_OPT_TIMELIMIT, -+ &options.timelimit); -+#else -+ ld->ld_timelimit = options.timelimit; -+#endif -+ debug3 ("LDAP set timelimit to %d", options.timelimit); -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_X_OPT_CONNECT_TIMEOUT) -+ /* -+ * This is a new option in the Netscape SDK which sets -+ * the TCP connect timeout. For want of a better value, -+ * we use the bind_timelimit to control this. -+ */ -+ timeout = options.bind_timelimit * 1000; -+ (void) ldap_set_option (ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout); -+ debug3 ("LDAP set opt connect timeout to %d", timeout); -+#endif -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT) -+ tv.tv_sec = options.bind_timelimit; -+ tv.tv_usec = 0; -+ (void) ldap_set_option (ld, LDAP_OPT_NETWORK_TIMEOUT, &tv); -+ debug3 ("LDAP set opt network timeout to %ld.0", tv.tv_sec); -+#endif -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_REFERRALS) -+ (void) ldap_set_option (ld, LDAP_OPT_REFERRALS, -+ options.referrals ? LDAP_OPT_ON : LDAP_OPT_OFF); -+ debug3 ("LDAP set referrals to %d", options.referrals); -+#endif -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_RESTART) -+ (void) ldap_set_option (ld, LDAP_OPT_RESTART, -+ options.restart ? LDAP_OPT_ON : LDAP_OPT_OFF); -+ debug3 ("LDAP set restart to %d", options.restart); -+#endif -+ -+#ifdef HAVE_LDAP_START_TLS_S -+ if (options.ssl == SSL_START_TLS) { -+ int version; -+ -+ if (ldap_get_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version) -+ == LDAP_SUCCESS) { -+ if (version < LDAP_VERSION3) { -+ version = LDAP_VERSION3; -+ (void) ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, -+ &version); -+ debug3 ("LDAP set version to %d", version); -+ } -+ } -+ -+ if ((rc = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS) -+ fatal ("ldap_starttls_s: %s", ldap_err2string (rc)); -+ debug3 ("LDAP start TLS"); -+ } -+#endif /* HAVE_LDAP_START_TLS_S */ -+ } -+ -+ if ((msgid = ldap_simple_bind (ld, options.binddn, -+ options.bindpw)) == -1) { -+ ld_errno = ldap_get_lderrno (ld, 0, 0); -+ -+ error ("ldap_simple_bind %s", ldap_err2string (ld_errno)); -+ reconnect++; -+ goto retry; -+ } -+ debug3 ("LDAP simple bind (%s)", options.binddn); -+ -+ timeout.tv_sec = options.bind_timelimit; -+ timeout.tv_usec = 0; -+ if ((rc = ldap_result (ld, msgid, 0, &timeout, &result)) < 1) { -+ ld_errno = ldap_get_lderrno (ld, 0, 0); -+ -+ error ("ldap_result %s", ldap_err2string (ld_errno)); -+ reconnect++; -+ goto retry; -+ } -+ debug3 ("LDAP result in time"); -+ -+#if defined(HAVE_LDAP_PARSE_RESULT) && defined(HAVE_LDAP_CONTROLS_FREE) -+ controls = NULL; -+ if ((parserc = ldap_parse_result (ld, result, &rc, 0, 0, 0, &controls, 1)) != LDAP_SUCCESS) -+ fatal ("ldap_parse_result %s", ldap_err2string (parserc)); -+ debug3 ("LDAP parse result OK"); -+ -+ if (controls != NULL) { -+ ldap_controls_free (controls); -+ } -+#else -+ rc = ldap_result2error (session->ld, result, 1); -+#endif -+ if (rc != LDAP_SUCCESS) -+ fatal ("error trying to bind as user \"%s\" (%s)", -+ options.binddn, ldap_err2string (rc)); -+ -+ debug2 ("LDAP do connect OK"); -+} -+ -+void -+process_user (const char *user, FILE *output) -+{ -+ LDAPMessage *res, *e; -+ char *buffer, *format; -+ int rc, i; -+ struct timeval timeout; -+ -+ debug ("LDAP process user"); -+ -+ /* quick check for attempts to be evil */ -+ if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) || -+ (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL)) { -+ logit ("illegal user name %s not processed", user); -+ return; -+ } -+ -+ /* build filter for LDAP request */ -+ format = LDAPSEARCH_FORMAT; -+ if (options.search_format != NULL) -+ format = options.search_format; -+ buffer = percent_expand(format, "c", options.account_class, "u", user, "f", options.ssh_filter, (char *)NULL); -+ -+ debug3 ("LDAP search scope = %d %s", options.scope, buffer); -+ -+ timeout.tv_sec = options.timelimit; -+ timeout.tv_usec = 0; -+ if ((rc = ldap_search_st(ld, options.base, options.scope, buffer, attrs, 0, &timeout, &res)) != LDAP_SUCCESS) { -+ error ("ldap_search_st(): %s", ldap_err2string (rc)); -+ free (buffer); -+ return; -+ } -+ -+ /* free */ -+ free (buffer); -+ -+ for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) { -+ int num; -+ struct berval **keys; -+ -+ keys = ldap_get_values_len(ld, e, PUBKEYATTR); -+ num = ldap_count_values_len(keys); -+ for (i = 0 ; i < num ; i++) { -+ char *cp; //, *options = NULL; -+ -+ for (cp = keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++); -+ if (!*cp || *cp == '\n' || *cp == '#') -+ continue; -+ -+ /* We have found the desired key. */ -+ fprintf (output, "%s\n", keys[i]->bv_val); -+ } -+ -+ ldap_value_free_len(keys); -+ } -+ -+ ldap_msgfree(res); -+ debug2 ("LDAP process user finished"); -+} -+ -+void -+ldap_do_close(void) -+{ -+ int rc; -+ -+ debug ("LDAP do close"); -+ if ((rc = ldap_unbind_ext(ld, NULL, NULL)) != LDAP_SUCCESS) -+ fatal ("ldap_unbind_ext: %s", -+ ldap_err2string (rc)); -+ -+ ld = NULL; -+ debug2 ("LDAP do close OK"); -+ return; -+} -+ -diff -up openssh-6.8p1/ldapbody.h.ldap openssh-6.8p1/ldapbody.h ---- openssh-6.8p1/ldapbody.h.ldap 2015-03-18 11:11:29.031801462 +0100 -+++ openssh-6.8p1/ldapbody.h 2015-03-18 11:11:29.031801462 +0100 -@@ -0,0 +1,37 @@ -+/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAPBODY_H -+#define LDAPBODY_H -+ -+#include -+ -+void ldap_checkconfig(void); -+void ldap_do_connect(void); -+void process_user(const char *, FILE *); -+void ldap_do_close(void); -+ -+#endif /* LDAPBODY_H */ -+ -diff -up openssh-6.8p1/ldapconf.c.ldap openssh-6.8p1/ldapconf.c ---- openssh-6.8p1/ldapconf.c.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapconf.c 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,729 @@ -+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "ldapincludes.h" -+#include "ldap-helper.h" -+#include "log.h" -+#include "misc.h" -+#include "xmalloc.h" -+#include "ldapconf.h" -+#include -+#include -+#include -+ -+/* Keyword tokens. */ -+ -+typedef enum { -+ lBadOption, -+ lHost, lURI, lBase, lBindDN, lBindPW, lRootBindDN, -+ lScope, lDeref, lPort, lTimeLimit, lBind_TimeLimit, -+ lLdap_Version, lBind_Policy, lSSLPath, lSSL, lReferrals, -+ lRestart, lTLS_CheckPeer, lTLS_CaCertFile, -+ lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key, -+ lTLS_RandFile, lLogDir, lDebug, lSSH_Filter, lSearch_Format, -+ lAccountClass, lDeprecated, lUnsupported -+} OpCodes; -+ -+/* Textual representations of the tokens. */ -+ -+static struct { -+ const char *name; -+ OpCodes opcode; -+} keywords[] = { -+ { "URI", lURI }, -+ { "Base", lBase }, -+ { "BindDN", lBindDN }, -+ { "BindPW", lBindPW }, -+ { "RootBindDN", lRootBindDN }, -+ { "Host", lHost }, -+ { "Port", lPort }, -+ { "Scope", lScope }, -+ { "Deref", lDeref }, -+ { "TimeLimit", lTimeLimit }, -+ { "TimeOut", lTimeLimit }, -+ { "Bind_Timelimit", lBind_TimeLimit }, -+ { "Network_TimeOut", lBind_TimeLimit }, -+/* -+ * Todo -+ * SIZELIMIT -+ */ -+ { "Ldap_Version", lLdap_Version }, -+ { "Version", lLdap_Version }, -+ { "Bind_Policy", lBind_Policy }, -+ { "SSLPath", lSSLPath }, -+ { "SSL", lSSL }, -+ { "Referrals", lReferrals }, -+ { "Restart", lRestart }, -+ { "TLS_CheckPeer", lTLS_CheckPeer }, -+ { "TLS_ReqCert", lTLS_CheckPeer }, -+ { "TLS_CaCertFile", lTLS_CaCertFile }, -+ { "TLS_CaCert", lTLS_CaCertFile }, -+ { "TLS_CaCertDir", lTLS_CaCertDir }, -+ { "TLS_Ciphers", lTLS_Ciphers }, -+ { "TLS_Cipher_Suite", lTLS_Ciphers }, -+ { "TLS_Cert", lTLS_Cert }, -+ { "TLS_Certificate", lTLS_Cert }, -+ { "TLS_Key", lTLS_Key }, -+ { "TLS_RandFile", lTLS_RandFile }, -+/* -+ * Todo -+ * TLS_CRLCHECK -+ * TLS_CRLFILE -+ */ -+ { "LogDir", lLogDir }, -+ { "Debug", lDebug }, -+ { "SSH_Filter", lSSH_Filter }, -+ { "search_format", lSearch_Format }, -+ { "AccountClass", lAccountClass }, -+ { NULL, lBadOption } -+}; -+ -+/* Configuration ptions. */ -+ -+Options options; -+ -+/* -+ * Returns the number of the token pointed to by cp or oBadOption. -+ */ -+ -+static OpCodes -+parse_token(const char *cp, const char *filename, int linenum) -+{ -+ u_int i; -+ -+ for (i = 0; keywords[i].name; i++) -+ if (strcasecmp(cp, keywords[i].name) == 0) -+ return keywords[i].opcode; -+ -+ if (config_warning_config_file) -+ logit("%s: line %d: Bad configuration option: %s", -+ filename, linenum, cp); -+ return lBadOption; -+} -+ -+/* Characters considered whitespace in strsep calls. */ -+#define WHITESPACE " \t\r\n" -+ -+/* return next token in configuration line */ -+static char * -+ldap_strdelim(char **s) -+{ -+ char *old; -+ int wspace = 0; -+ -+ if (*s == NULL) -+ return NULL; -+ -+ old = *s; -+ -+ *s = strpbrk(*s, WHITESPACE); -+ if (*s == NULL) -+ return (old); -+ -+ *s[0] = '\0'; -+ -+ /* Skip any extra whitespace after first token */ -+ *s += strspn(*s + 1, WHITESPACE) + 1; -+ if (*s[0] == '=' && !wspace) -+ *s += strspn(*s + 1, WHITESPACE) + 1; -+ -+ return (old); -+} -+ -+/* -+ * Processes a single option line as used in the configuration files. This -+ * only sets those values that have not already been set. -+ */ -+#define WHITESPACE " \t\r\n" -+ -+static int -+process_config_line(char *line, const char *filename, int linenum) -+{ -+ char *s, **charptr, **xstringptr, *endofnumber, *keyword, *arg; -+ char *rootbinddn = NULL; -+ int opcode, *intptr, value; -+ size_t len; -+ -+ /* Strip trailing whitespace */ -+ for (len = strlen(line) - 1; len > 0; len--) { -+ if (strchr(WHITESPACE, line[len]) == NULL) -+ break; -+ line[len] = '\0'; -+ } -+ -+ s = line; -+ /* Get the keyword. (Each line is supposed to begin with a keyword). */ -+ if ((keyword = ldap_strdelim(&s)) == NULL) -+ return 0; -+ /* Ignore leading whitespace. */ -+ if (*keyword == '\0') -+ keyword = ldap_strdelim(&s); -+ if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') -+ return 0; -+ -+ opcode = parse_token(keyword, filename, linenum); -+ -+ switch (opcode) { -+ case lBadOption: -+ /* don't panic, but count bad options */ -+ return -1; -+ /* NOTREACHED */ -+ -+ case lHost: -+ xstringptr = &options.host; -+parse_xstring: -+ if (!s || *s == '\0') -+ fatal("%s line %d: missing dn",filename,linenum); -+ if (*xstringptr == NULL) -+ *xstringptr = xstrdup(s); -+ return 0; -+ -+ case lURI: -+ xstringptr = &options.uri; -+ goto parse_xstring; -+ -+ case lBase: -+ xstringptr = &options.base; -+ goto parse_xstring; -+ -+ case lBindDN: -+ xstringptr = &options.binddn; -+ goto parse_xstring; -+ -+ case lBindPW: -+ charptr = &options.bindpw; -+parse_string: -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing argument.", filename, linenum); -+ if (*charptr == NULL) -+ *charptr = xstrdup(arg); -+ break; -+ -+ case lRootBindDN: -+ xstringptr = &rootbinddn; -+ goto parse_xstring; -+ -+ case lScope: -+ intptr = &options.scope; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing sub/one/base argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp (arg, "sub") == 0 || strcasecmp (arg, "subtree") == 0) -+ value = LDAP_SCOPE_SUBTREE; -+ else if (strcasecmp (arg, "one") == 0) -+ value = LDAP_SCOPE_ONELEVEL; -+ else if (strcasecmp (arg, "base") == 0) -+ value = LDAP_SCOPE_BASE; -+ else -+ fatal("%.200s line %d: Bad sub/one/base argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lDeref: -+ intptr = &options.scope; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing never/searching/finding/always argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (!strcasecmp (arg, "never")) -+ value = LDAP_DEREF_NEVER; -+ else if (!strcasecmp (arg, "searching")) -+ value = LDAP_DEREF_SEARCHING; -+ else if (!strcasecmp (arg, "finding")) -+ value = LDAP_DEREF_FINDING; -+ else if (!strcasecmp (arg, "always")) -+ value = LDAP_DEREF_ALWAYS; -+ else -+ fatal("%.200s line %d: Bad never/searching/finding/always argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lPort: -+ intptr = &options.port; -+parse_int: -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing argument.", filename, linenum); -+ if (arg[0] < '0' || arg[0] > '9') -+ fatal("%.200s line %d: Bad number.", filename, linenum); -+ -+ /* Octal, decimal, or hex format? */ -+ value = strtol(arg, &endofnumber, 0); -+ if (arg == endofnumber) -+ fatal("%.200s line %d: Bad number.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lTimeLimit: -+ intptr = &options.timelimit; -+parse_time: -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%s line %d: missing time value.", -+ filename, linenum); -+ if ((value = convtime(arg)) == -1) -+ fatal("%s line %d: invalid time value.", -+ filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lBind_TimeLimit: -+ intptr = &options.bind_timelimit; -+ goto parse_time; -+ -+ case lLdap_Version: -+ intptr = &options.ldap_version; -+ goto parse_int; -+ -+ case lBind_Policy: -+ intptr = &options.bind_policy; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing soft/hard argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "hard_open") == 0 || strcasecmp(arg, "hard_init") == 0) -+ value = 1; -+ else if (strcasecmp(arg, "soft") == 0) -+ value = 0; -+ else -+ fatal("%.200s line %d: Bad soft/hard argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lSSLPath: -+ charptr = &options.sslpath; -+ goto parse_string; -+ -+ case lSSL: -+ intptr = &options.ssl; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing yes/no/start_tls argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0) -+ value = SSL_LDAPS; -+ else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) -+ value = SSL_OFF; -+ else if (!strcasecmp (arg, "start_tls")) -+ value = SSL_START_TLS; -+ else -+ fatal("%.200s line %d: Bad yes/no/start_tls argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lReferrals: -+ intptr = &options.referrals; -+parse_flag: -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0) -+ value = 1; -+ else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) -+ value = 0; -+ else -+ fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lRestart: -+ intptr = &options.restart; -+ goto parse_flag; -+ -+ case lTLS_CheckPeer: -+ intptr = &options.tls_checkpeer; -+ arg = ldap_strdelim(&s); -+ if (!arg || *arg == '\0') -+ fatal("%.200s line %d: Missing never/hard/demand/alow/try argument.", filename, linenum); -+ value = 0; /* To avoid compiler warning... */ -+ if (strcasecmp(arg, "never") == 0 || strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) -+ value = LDAP_OPT_X_TLS_NEVER; -+ else if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0) -+ value = LDAP_OPT_X_TLS_HARD; -+ else if (strcasecmp(arg, "demand") == 0) -+ value = LDAP_OPT_X_TLS_DEMAND; -+ else if (strcasecmp(arg, "allow") == 0) -+ value = LDAP_OPT_X_TLS_ALLOW; -+ else if (strcasecmp(arg, "try") == 0) -+ value = LDAP_OPT_X_TLS_TRY; -+ else -+ fatal("%.200s line %d: Bad never/hard/demand/alow/try argument.", filename, linenum); -+ if (*intptr == -1) -+ *intptr = value; -+ break; -+ -+ case lTLS_CaCertFile: -+ charptr = &options.tls_cacertfile; -+ goto parse_string; -+ -+ case lTLS_CaCertDir: -+ charptr = &options.tls_cacertdir; -+ goto parse_string; -+ -+ case lTLS_Ciphers: -+ xstringptr = &options.tls_ciphers; -+ goto parse_xstring; -+ -+ case lTLS_Cert: -+ charptr = &options.tls_cert; -+ goto parse_string; -+ -+ case lTLS_Key: -+ charptr = &options.tls_key; -+ goto parse_string; -+ -+ case lTLS_RandFile: -+ charptr = &options.tls_randfile; -+ goto parse_string; -+ -+ case lLogDir: -+ charptr = &options.logdir; -+ goto parse_string; -+ -+ case lDebug: -+ intptr = &options.debug; -+ goto parse_int; -+ -+ case lSSH_Filter: -+ xstringptr = &options.ssh_filter; -+ goto parse_xstring; -+ -+ case lSearch_Format: -+ charptr = &options.search_format; -+ goto parse_string; -+ -+ case lAccountClass: -+ charptr = &options.account_class; -+ goto parse_string; -+ -+ case lDeprecated: -+ debug("%s line %d: Deprecated option \"%s\"", -+ filename, linenum, keyword); -+ return 0; -+ -+ case lUnsupported: -+ error("%s line %d: Unsupported option \"%s\"", -+ filename, linenum, keyword); -+ return 0; -+ -+ default: -+ fatal("process_config_line: Unimplemented opcode %d", opcode); -+ } -+ -+ /* Check that there is no garbage at end of line. */ -+ if ((arg = ldap_strdelim(&s)) != NULL && *arg != '\0') { -+ fatal("%.200s line %d: garbage at end of line; \"%.200s\".", -+ filename, linenum, arg); -+ } -+ return 0; -+} -+ -+/* -+ * Reads the config file and modifies the options accordingly. Options -+ * should already be initialized before this call. This never returns if -+ * there is an error. If the file does not exist, this returns 0. -+ */ -+ -+void -+read_config_file(const char *filename) -+{ -+ FILE *f; -+ char line[1024]; -+ int linenum; -+ int bad_options = 0; -+ struct stat sb; -+ -+ if ((f = fopen(filename, "r")) == NULL) -+ fatal("fopen %s: %s", filename, strerror(errno)); -+ -+ if (fstat(fileno(f), &sb) == -1) -+ fatal("fstat %s: %s", filename, strerror(errno)); -+ if (((sb.st_uid != 0 && sb.st_uid != getuid()) || -+ (sb.st_mode & 022) != 0)) -+ fatal("Bad owner or permissions on %s", filename); -+ -+ debug("Reading configuration data %.200s", filename); -+ -+ /* -+ * Mark that we are now processing the options. This flag is turned -+ * on/off by Host specifications. -+ */ -+ linenum = 0; -+ while (fgets(line, sizeof(line), f)) { -+ /* Update line number counter. */ -+ linenum++; -+ if (process_config_line(line, filename, linenum) != 0) -+ bad_options++; -+ } -+ fclose(f); -+ if ((bad_options > 0) && config_exclusive_config_file) -+ fatal("%s: terminating, %d bad configuration options", -+ filename, bad_options); -+} -+ -+/* -+ * Initializes options to special values that indicate that they have not yet -+ * been set. Read_config_file will only set options with this value. Options -+ * are processed in the following order: command line, user config file, -+ * system config file. Last, fill_default_options is called. -+ */ -+ -+void -+initialize_options(void) -+{ -+ memset(&options, 'X', sizeof(options)); -+ options.host = NULL; -+ options.uri = NULL; -+ options.base = NULL; -+ options.binddn = NULL; -+ options.bindpw = NULL; -+ options.scope = -1; -+ options.deref = -1; -+ options.port = -1; -+ options.timelimit = -1; -+ options.bind_timelimit = -1; -+ options.ldap_version = -1; -+ options.bind_policy = -1; -+ options.sslpath = NULL; -+ options.ssl = -1; -+ options.referrals = -1; -+ options.restart = -1; -+ options.tls_checkpeer = -1; -+ options.tls_cacertfile = NULL; -+ options.tls_cacertdir = NULL; -+ options.tls_ciphers = NULL; -+ options.tls_cert = NULL; -+ options.tls_key = NULL; -+ options.tls_randfile = NULL; -+ options.logdir = NULL; -+ options.debug = -1; -+ options.ssh_filter = NULL; -+ options.search_format = NULL; -+ options.account_class = NULL; -+} -+ -+/* -+ * Called after processing other sources of option data, this fills those -+ * options for which no value has been specified with their default values. -+ */ -+ -+void -+fill_default_options(void) -+{ -+ if (options.uri != NULL) { -+ LDAPURLDesc *ludp; -+ -+ if (ldap_url_parse(options.uri, &ludp) == LDAP_SUCCESS) { -+ if (options.ssl == -1) { -+ if (strcmp (ludp->lud_scheme, "ldap") == 0) -+ options.ssl = 2; -+ if (strcmp (ludp->lud_scheme, "ldapi") == 0) -+ options.ssl = 0; -+ else if (strcmp (ludp->lud_scheme, "ldaps") == 0) -+ options.ssl = 1; -+ } -+ if (options.host == NULL) -+ options.host = xstrdup (ludp->lud_host); -+ if (options.port == -1) -+ options.port = ludp->lud_port; -+ -+ ldap_free_urldesc (ludp); -+ } -+ } -+ if (options.ssl == -1) -+ options.ssl = SSL_START_TLS; -+ if (options.port == -1) -+ options.port = (options.ssl == 0) ? 389 : 636; -+ if (options.uri == NULL) { -+ int len; -+#define MAXURILEN 4096 -+ -+ options.uri = xmalloc (MAXURILEN); -+ len = snprintf (options.uri, MAXURILEN, "ldap%s://%s:%d", -+ (options.ssl == 0) ? "" : "s", options.host, options.port); -+ options.uri[MAXURILEN - 1] = 0; -+ options.uri = xreallocarray(options.uri, len + 1, 1); -+ } -+ if (options.binddn == NULL) -+ options.binddn = ""; -+ if (options.bindpw == NULL) -+ options.bindpw = ""; -+ if (options.scope == -1) -+ options.scope = LDAP_SCOPE_SUBTREE; -+ if (options.deref == -1) -+ options.deref = LDAP_DEREF_NEVER; -+ if (options.timelimit == -1) -+ options.timelimit = 10; -+ if (options.bind_timelimit == -1) -+ options.bind_timelimit = 10; -+ if (options.ldap_version == -1) -+ options.ldap_version = 3; -+ if (options.bind_policy == -1) -+ options.bind_policy = 1; -+ if (options.referrals == -1) -+ options.referrals = 1; -+ if (options.restart == -1) -+ options.restart = 1; -+ if (options.tls_checkpeer == -1) -+ options.tls_checkpeer = LDAP_OPT_X_TLS_HARD; -+ if (options.debug == -1) -+ options.debug = 0; -+ if (options.ssh_filter == NULL) -+ options.ssh_filter = ""; -+ if (options.account_class == NULL) -+ options.account_class = "posixAccount"; -+} -+ -+static const char * -+lookup_opcode_name(OpCodes code) -+{ -+ u_int i; -+ -+ for (i = 0; keywords[i].name != NULL; i++) -+ if (keywords[i].opcode == code) -+ return(keywords[i].name); -+ return "UNKNOWN"; -+} -+ -+static void -+dump_cfg_string(OpCodes code, const char *val) -+{ -+ if (val == NULL) -+ debug3("%s ", lookup_opcode_name(code)); -+ else -+ debug3("%s %s", lookup_opcode_name(code), val); -+} -+ -+static void -+dump_cfg_int(OpCodes code, int val) -+{ -+ if (val == -1) -+ debug3("%s ", lookup_opcode_name(code)); -+ else -+ debug3("%s %d", lookup_opcode_name(code), val); -+} -+ -+struct names { -+ int value; -+ char *name; -+}; -+ -+static void -+dump_cfg_namedint(OpCodes code, int val, struct names *names) -+{ -+ u_int i; -+ -+ if (val == -1) -+ debug3("%s ", lookup_opcode_name(code)); -+ else { -+ for (i = 0; names[i].value != -1; i++) -+ if (names[i].value == val) { -+ debug3("%s %s", lookup_opcode_name(code), names[i].name); -+ return; -+ } -+ debug3("%s unknown: %d", lookup_opcode_name(code), val); -+ } -+} -+ -+static struct names _yesnotls[] = { -+ { 0, "No" }, -+ { 1, "Yes" }, -+ { 2, "Start_TLS" }, -+ { -1, NULL }}; -+ -+static struct names _scope[] = { -+ { LDAP_SCOPE_BASE, "Base" }, -+ { LDAP_SCOPE_ONELEVEL, "One" }, -+ { LDAP_SCOPE_SUBTREE, "Sub"}, -+ { -1, NULL }}; -+ -+static struct names _deref[] = { -+ { LDAP_DEREF_NEVER, "Never" }, -+ { LDAP_DEREF_SEARCHING, "Searching" }, -+ { LDAP_DEREF_FINDING, "Finding" }, -+ { LDAP_DEREF_ALWAYS, "Always" }, -+ { -1, NULL }}; -+ -+static struct names _yesno[] = { -+ { 0, "No" }, -+ { 1, "Yes" }, -+ { -1, NULL }}; -+ -+static struct names _bindpolicy[] = { -+ { 0, "Soft" }, -+ { 1, "Hard" }, -+ { -1, NULL }}; -+ -+static struct names _checkpeer[] = { -+ { LDAP_OPT_X_TLS_NEVER, "Never" }, -+ { LDAP_OPT_X_TLS_HARD, "Hard" }, -+ { LDAP_OPT_X_TLS_DEMAND, "Demand" }, -+ { LDAP_OPT_X_TLS_ALLOW, "Allow" }, -+ { LDAP_OPT_X_TLS_TRY, "TRY" }, -+ { -1, NULL }}; -+ -+void -+dump_config(void) -+{ -+ dump_cfg_string(lURI, options.uri); -+ dump_cfg_string(lHost, options.host); -+ dump_cfg_int(lPort, options.port); -+ dump_cfg_namedint(lSSL, options.ssl, _yesnotls); -+ dump_cfg_int(lLdap_Version, options.ldap_version); -+ dump_cfg_int(lTimeLimit, options.timelimit); -+ dump_cfg_int(lBind_TimeLimit, options.bind_timelimit); -+ dump_cfg_string(lBase, options.base); -+ dump_cfg_string(lBindDN, options.binddn); -+ dump_cfg_string(lBindPW, options.bindpw); -+ dump_cfg_namedint(lScope, options.scope, _scope); -+ dump_cfg_namedint(lDeref, options.deref, _deref); -+ dump_cfg_namedint(lReferrals, options.referrals, _yesno); -+ dump_cfg_namedint(lRestart, options.restart, _yesno); -+ dump_cfg_namedint(lBind_Policy, options.bind_policy, _bindpolicy); -+ dump_cfg_string(lSSLPath, options.sslpath); -+ dump_cfg_namedint(lTLS_CheckPeer, options.tls_checkpeer, _checkpeer); -+ dump_cfg_string(lTLS_CaCertFile, options.tls_cacertfile); -+ dump_cfg_string(lTLS_CaCertDir, options.tls_cacertdir); -+ dump_cfg_string(lTLS_Ciphers, options.tls_ciphers); -+ dump_cfg_string(lTLS_Cert, options.tls_cert); -+ dump_cfg_string(lTLS_Key, options.tls_key); -+ dump_cfg_string(lTLS_RandFile, options.tls_randfile); -+ dump_cfg_string(lLogDir, options.logdir); -+ dump_cfg_int(lDebug, options.debug); -+ dump_cfg_string(lSSH_Filter, options.ssh_filter); -+ dump_cfg_string(lSearch_Format, options.search_format); -+ dump_cfg_string(lAccountClass, options.account_class); -+} -+ -diff -up openssh-6.8p1/ldapconf.h.ldap openssh-6.8p1/ldapconf.h ---- openssh-6.8p1/ldapconf.h.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapconf.h 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,73 @@ -+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAPCONF_H -+#define LDAPCONF_H -+ -+#define SSL_OFF 0 -+#define SSL_LDAPS 1 -+#define SSL_START_TLS 2 -+ -+/* Data structure for representing option data. */ -+ -+typedef struct { -+ char *host; -+ char *uri; -+ char *base; -+ char *binddn; -+ char *bindpw; -+ int scope; -+ int deref; -+ int port; -+ int timelimit; -+ int bind_timelimit; -+ int ldap_version; -+ int bind_policy; -+ char *sslpath; -+ int ssl; -+ int referrals; -+ int restart; -+ int tls_checkpeer; -+ char *tls_cacertfile; -+ char *tls_cacertdir; -+ char *tls_ciphers; -+ char *tls_cert; -+ char *tls_key; -+ char *tls_randfile; -+ char *logdir; -+ int debug; -+ char *ssh_filter; -+ char *search_format; -+ char *account_class; -+} Options; -+ -+extern Options options; -+ -+void read_config_file(const char *); -+void initialize_options(void); -+void fill_default_options(void); -+void dump_config(void); -+ -+#endif /* LDAPCONF_H */ -diff -up openssh-6.8p1/ldapincludes.h.ldap openssh-6.8p1/ldapincludes.h ---- openssh-6.8p1/ldapincludes.h.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapincludes.h 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,41 @@ -+/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAPINCLUDES_H -+#define LDAPINCLUDES_H -+ -+#include "includes.h" -+ -+#ifdef HAVE_LBER_H -+#include -+#endif -+#ifdef HAVE_LDAP_H -+#include -+#endif -+#ifdef HAVE_LDAP_SSL_H -+#include -+#endif -+ -+#endif /* LDAPINCLUDES_H */ -diff -up openssh-6.8p1/ldapmisc.c.ldap openssh-6.8p1/ldapmisc.c ---- openssh-6.8p1/ldapmisc.c.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapmisc.c 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,79 @@ -+ -+#include "ldapincludes.h" -+#include "ldapmisc.h" -+ -+#ifndef HAVE_LDAP_GET_LDERRNO -+int -+ldap_get_lderrno (LDAP * ld, char **m, char **s) -+{ -+#ifdef HAVE_LDAP_GET_OPTION -+ int rc; -+#endif -+ int lderrno; -+ -+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) -+ if ((rc = ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, &lderrno)) != LDAP_SUCCESS) -+ return rc; -+#else -+ lderrno = ld->ld_errno; -+#endif -+ -+ if (s != NULL) { -+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_STRING) -+ if ((rc = ldap_get_option (ld, LDAP_OPT_ERROR_STRING, s)) != LDAP_SUCCESS) -+ return rc; -+#else -+ *s = ld->ld_error; -+#endif -+ } -+ -+ if (m != NULL) { -+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_MATCHED_DN) -+ if ((rc = ldap_get_option (ld, LDAP_OPT_MATCHED_DN, m)) != LDAP_SUCCESS) -+ return rc; -+#else -+ *m = ld->ld_matched; -+#endif -+ } -+ -+ return lderrno; -+} -+#endif -+ -+#ifndef HAVE_LDAP_SET_LDERRNO -+int -+ldap_set_lderrno (LDAP * ld, int lderrno, const char *m, const char *s) -+{ -+#ifdef HAVE_LDAP_SET_OPTION -+ int rc; -+#endif -+ -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) -+ if ((rc = ldap_set_option (ld, LDAP_OPT_ERROR_NUMBER, &lderrno)) != LDAP_SUCCESS) -+ return rc; -+#else -+ ld->ld_errno = lderrno; -+#endif -+ -+ if (s != NULL) { -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_ERROR_STRING) -+ if ((rc = ldap_set_option (ld, LDAP_OPT_ERROR_STRING, s)) != LDAP_SUCCESS) -+ return rc; -+#else -+ ld->ld_error = s; -+#endif -+ } -+ -+ if (m != NULL) { -+#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_MATCHED_DN) -+ if ((rc = ldap_set_option (ld, LDAP_OPT_MATCHED_DN, m)) != LDAP_SUCCESS) -+ return rc; -+#else -+ ld->ld_matched = m; -+#endif -+ } -+ -+ return LDAP_SUCCESS; -+} -+#endif -+ -diff -up openssh-6.8p1/ldapmisc.h.ldap openssh-6.8p1/ldapmisc.h ---- openssh-6.8p1/ldapmisc.h.ldap 2015-03-18 11:11:29.032801460 +0100 -+++ openssh-6.8p1/ldapmisc.h 2015-03-18 11:11:29.032801460 +0100 -@@ -0,0 +1,35 @@ -+/* $OpenBSD: ldapbody.h,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ -+/* -+ * Copyright (c) 2009 Jan F. Chadima. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LDAPMISC_H -+#define LDAPMISC_H -+ -+#include "ldapincludes.h" -+ -+int ldap_get_lderrno (LDAP *, char **, char **); -+int ldap_set_lderrno (LDAP *, int, const char *, const char *); -+ -+#endif /* LDAPMISC_H */ -+ -diff -up openssh-6.8p1/openssh-lpk-openldap.schema.ldap openssh-6.8p1/openssh-lpk-openldap.schema ---- openssh-6.8p1/openssh-lpk-openldap.schema.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/openssh-lpk-openldap.schema 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,21 @@ -+# -+# LDAP Public Key Patch schema for use with openssh-ldappubkey -+# useful with PKA-LDAP also -+# -+# Author: Eric AUGE -+# -+# Based on the proposal of : Mark Ruijter -+# -+ -+ -+# octetString SYNTAX -+attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' -+ DESC 'MANDATORY: OpenSSH Public key' -+ EQUALITY octetStringMatch -+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) -+ -+# printableString SYNTAX yes|no -+objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY -+ DESC 'MANDATORY: OpenSSH LPK objectclass' -+ MUST ( sshPublicKey $ uid ) -+ ) -diff -up openssh-6.8p1/openssh-lpk-sun.schema.ldap openssh-6.8p1/openssh-lpk-sun.schema ---- openssh-6.8p1/openssh-lpk-sun.schema.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/openssh-lpk-sun.schema 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,23 @@ -+# -+# LDAP Public Key Patch schema for use with openssh-ldappubkey -+# useful with PKA-LDAP also -+# -+# Author: Eric AUGE -+# -+# Schema for Sun Directory Server. -+# Based on the original schema, modified by Stefan Fischer. -+# -+ -+dn: cn=schema -+ -+# octetString SYNTAX -+attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' -+ DESC 'MANDATORY: OpenSSH Public key' -+ EQUALITY octetStringMatch -+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) -+ -+# printableString SYNTAX yes|no -+objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY -+ DESC 'MANDATORY: OpenSSH LPK objectclass' -+ MUST ( sshPublicKey $ uid ) -+ ) -diff -up openssh-6.8p1/ssh-ldap-helper.8.ldap openssh-6.8p1/ssh-ldap-helper.8 ---- openssh-6.8p1/ssh-ldap-helper.8.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/ssh-ldap-helper.8 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,79 @@ -+.\" $OpenBSD: ssh-ldap-helper.8,v 1.1 2010/02/10 23:20:38 markus Exp $ -+.\" -+.\" Copyright (c) 2010 Jan F. Chadima. All rights reserved. -+.\" -+.\" Permission to use, copy, modify, and distribute this software for any -+.\" purpose with or without fee is hereby granted, provided that the above -+.\" copyright notice and this permission notice appear in all copies. -+.\" -+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+.\" -+.Dd $Mdocdate: April 29 2010 $ -+.Dt SSH-LDAP-HELPER 8 -+.Os -+.Sh NAME -+.Nm ssh-ldap-helper -+.Nd sshd helper program for ldap support -+.Sh SYNOPSIS -+.Nm ssh-ldap-helper -+.Op Fl devw -+.Op Fl f Ar file -+.Op Fl s Ar user -+.Sh DESCRIPTION -+.Nm -+is used by -+.Xr sshd 1 -+to access keys provided by an LDAP. -+.Nm -+is disabled by default and can only be enabled in the -+sshd configuration file -+.Pa /etc/ssh/sshd_config -+by setting -+.Cm AuthorizedKeysCommand -+to -+.Dq /usr/libexec/ssh-ldap-wrapper . -+.Pp -+.Nm -+is not intended to be invoked by the user, but from -+.Xr sshd 8 via -+.Xr ssh-ldap-wrapper . -+.Pp -+The options are as follows: -+.Bl -tag -width Ds -+.It Fl d -+Set the debug mode; -+.Nm -+prints all logs to stderr instead of syslog. -+.It Fl e -+Implies \-w; -+.Nm -+halts if it encounters an unknown item in the ldap.conf file. -+.It Fl f -+.Nm -+uses this file as the ldap configuration file instead of /etc/ssh/ldap.conf (default). -+.It Fl s -+.Nm -+prints out the user's keys to stdout and exits. -+.It Fl v -+Implies \-d; -+increases verbosity. -+.It Fl w -+.Nm -+writes warnings about unknown items in the ldap.conf configuration file. -+.El -+.Sh SEE ALSO -+.Xr sshd 8 , -+.Xr sshd_config 5 , -+.Xr ssh-ldap.conf 5 , -+.Sh HISTORY -+.Nm -+first appeared in -+OpenSSH 5.5 + PKA-LDAP . -+.Sh AUTHORS -+.An Jan F. Chadima Aq jchadima@redhat.com -diff -up openssh-6.8p1/ssh-ldap-wrapper.ldap openssh-6.8p1/ssh-ldap-wrapper ---- openssh-6.8p1/ssh-ldap-wrapper.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/ssh-ldap-wrapper 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,4 @@ -+#!/bin/sh -+ -+exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" -+ -diff -up openssh-6.8p1/ssh-ldap.conf.5.ldap openssh-6.8p1/ssh-ldap.conf.5 ---- openssh-6.8p1/ssh-ldap.conf.5.ldap 2015-03-18 11:11:29.033801457 +0100 -+++ openssh-6.8p1/ssh-ldap.conf.5 2015-03-18 11:11:29.033801457 +0100 -@@ -0,0 +1,385 @@ -+.\" $OpenBSD: ssh-ldap.conf.5,v 1.1 2010/02/10 23:20:38 markus Exp $ -+.\" -+.\" Copyright (c) 2010 Jan F. Chadima. All rights reserved. -+.\" -+.\" Permission to use, copy, modify, and distribute this software for any -+.\" purpose with or without fee is hereby granted, provided that the above -+.\" copyright notice and this permission notice appear in all copies. -+.\" -+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+.\" -+.Dd $Mdocdate: may 12 2010 $ -+.Dt SSH-LDAP.CONF 5 -+.Os -+.Sh NAME -+.Nm ssh-ldap.conf -+.Nd configuration file for ssh-ldap-helper -+.Sh SYNOPSIS -+.Nm /etc/ssh/ldap.conf -+.Sh DESCRIPTION -+.Xr ssh-ldap-helper 8 -+reads configuration data from -+.Pa /etc/ssh/ldap.conf -+(or the file specified with -+.Fl f -+on the command line). -+The file contains keyword-argument pairs, one per line. -+Lines starting with -+.Ql # -+and empty lines are interpreted as comments. -+.Pp -+The value starts with the first non-blank character after -+the keyword's name, and terminates at the end of the line, -+or at the last sequence of blanks before the end of the line. -+Quoting values that contain blanks -+may be incorrect, as the quotes would become part of the value. -+The possible keywords and their meanings are as follows (note that -+keywords are case-insensitive, and arguments, on a case by case basis, may be case-sensitive). -+.Bl -tag -width Ds -+.It Cm URI -+The argument(s) are in the form -+.Pa ldap[si]://[name[:port]] -+and specify the URI(s) of an LDAP server(s) to which the -+.Xr ssh-ldap-helper 8 -+should connect. The URI scheme may be any of -+.Dq ldap , -+.Dq ldaps -+or -+.Dq ldapi , -+which refer to LDAP over TCP, LDAP over SSL (TLS) and LDAP -+over IPC (UNIX domain sockets), respectively. -+Each server's name can be specified as a -+domain-style name or an IP address literal. Optionally, the -+server's name can followed by a ':' and the port number the LDAP -+server is listening on. If no port number is provided, the default -+port for the scheme is used (389 for ldap://, 636 for ldaps://). -+For LDAP over IPC, name is the name of the socket, and no port -+is required, nor allowed; note that directory separators must be -+URL-encoded, like any other characters that are special to URLs; -+A space separated list of URIs may be provided. -+There is no default. -+.It Cm Base -+Specifies the default base Distinguished Name (DN) to use when performing ldap operations. -+The base must be specified as a DN in LDAP format. -+There is no default. -+.It Cm BindDN -+Specifies the default BIND DN to use when connecting to the ldap server. -+The bind DN must be specified as a Distinguished Name in LDAP format. -+There is no default. -+.It Cm BindPW -+Specifies the default password to use when connecting to the ldap server via -+.Cm BindDN . -+There is no default. -+.It Cm RootBindDN -+Intentionaly does nothing. Recognized for compatibility reasons. -+.It Cm Host -+The argument(s) specifies the name(s) of an LDAP server(s) to which the -+.Xr ssh-ldap-helper 8 -+should connect. Each server's name can be specified as a -+domain-style name or an IP address and optionally followed by a ':' and -+the port number the ldap server is listening on. A space-separated -+list of hosts may be provided. -+There is no default. -+.Cm Host -+is deprecated in favor of -+.Cm URI . -+.It Cm Port -+Specifies the default port used when connecting to LDAP servers(s). -+The port may be specified as a number. -+The default port is 389 for ldap:// or 636 for ldaps:// respectively. -+.Cm Port -+is deprecated in favor of -+.Cm URI . -+.It Cm Scope -+Specifies the starting point of an LDAP search and the depth from the base DN to which the search should descend. -+There are three options (values) that can be assigned to the -+.Cm Scope parameter: -+.Dq base , -+.Dq one -+and -+.Dq subtree . -+Alias for the subtree is -+.Dq sub . -+The value -+.Dq base -+is used to indicate searching only the entry at the base DN, resulting in only that entry being returned (keeping in mind that it also has to meet the search filter criteria!). -+The value -+.Dq one -+is used to indicate searching all entries one level under the base DN, but not including the base DN and not including any entries under that one level under the base DN. -+The value -+.Dq subtree -+is used to indicate searching of all entries at all levels under and including the specified base DN. -+The default is -+.Dq subtree . -+.It Cm Deref -+Specifies how alias dereferencing is done when performing a search. There are four -+possible values that can be assigned to the -+.Cm Deref -+parameter: -+.Dq never , -+.Dq searching , -+.Dq finding , -+and -+.Dq always . -+The value -+.Dq never -+means that the aliases are never dereferenced. -+The value -+.Dq searching -+means that the aliases are dereferenced in subordinates of the base object, but -+not in locating the base object of the search. -+The value -+.Dq finding -+means that the aliases are only dereferenced when locating the base object of the search. -+The value -+.Dq always -+means that the aliases are dereferenced both in searching and in locating the base object -+of the search. -+The default is -+.Dq never . -+.It Cm TimeLimit -+Specifies a time limit (in seconds) to use when performing searches. -+The number should be a non-negative integer. A -+.Cm TimeLimit -+of zero (0) specifies that the search time is unlimited. Please note that the server -+may still apply any server-side limit on the duration of a search operation. -+The default value is 10. -+.It Cm TimeOut -+Is an aliast to -+.Cm TimeLimit . -+.It Cm Bind_TimeLimit -+Specifies the timeout (in seconds) after which the poll(2)/select(2) -+following a connect(2) returns in case of no activity. -+The default value is 10. -+.It Cm Network_TimeOut -+Is an alias to -+.Cm Bind_TimeLimit . -+.It Cm Ldap_Version -+Specifies what version of the LDAP protocol should be used. -+The allowed values are 2 or 3. The default is 3. -+.It Cm Version -+Is an alias to -+.Cm Ldap_Version . -+.It Cm Bind_Policy -+Specifies the policy to use for reconnecting to an unavailable LDAP server. There are 2 available values: -+.Dq hard -+and -+.Dq soft. -+.Dq hard has 2 aliases -+.Dq hard_open -+and -+.Dq hard_init . -+The value -+.Dq hard -+means that reconects that the -+.Xr ssh-ldap-helper 8 -+tries to reconnect to the LDAP server 5 times before failure. There is exponential backoff before retrying. -+The value -+.Dq soft -+means that -+.Xr ssh-ldap-helper 8 -+fails immediately when it cannot connect to the LDAP seerver. -+The deault is -+.Dq hard . -+.It Cm SSLPath -+Specifies the path to the X.509 certificate database. -+There is no default. -+.It Cm SSL -+Specifies whether to use SSL/TLS or not. -+There are three allowed values: -+.Dq yes , -+.Dq no -+and -+.Dq start_tls -+Both -+.Dq true -+and -+.Dq on -+are the aliases for -+.Dq yes . -+.Dq false -+and -+.Dq off -+are the aliases for -+.Dq no . -+If -+.Dq start_tls -+is specified then StartTLS is used rather than raw LDAP over SSL. -+The default for ldap:// is -+.Dq start_tls , -+for ldaps:// -+.Dq yes -+and -+.Dq no -+for the ldapi:// . -+In case of host based configuration the default is -+.Dq start_tls . -+.It Cm Referrals -+Specifies if the client should automatically follow referrals returned -+by LDAP servers. -+The value can be or -+.Dq yes -+or -+.Dq no . -+.Dq true -+and -+.Dq on -+are the aliases for -+.Dq yes . -+.Dq false -+and -+.Dq off -+are the aliases for -+.Dq no . -+The default is yes. -+.It Cm Restart -+Specifies whether the LDAP client library should restart the select(2) system call when interrupted. -+The value can be or -+.Dq yes -+or -+.Dq no . -+.Dq true -+and -+.Dq on -+are the aliases for -+.Dq yes . -+.Dq false -+and -+.Dq off -+are the aliases for -+.Dq no . -+The default is yes. -+.It Cm TLS_CheckPeer -+Specifies what checks to perform on server certificates in a TLS session, -+if any. The value -+can be specified as one of the following keywords: -+.Dq never , -+.Dq hard , -+.Dq demand , -+.Dq allow -+and -+.Dq try . -+.Dq true , -+.Dq on -+and -+.Dq yes -+are aliases for -+.Dq hard . -+.Dq false , -+.Dq off -+and -+.Dq no -+are the aliases for -+.Dq never . -+The value -+.Dq never -+means that the client will not request or check any server certificate. -+The value -+.Dq allow -+means that the server certificate is requested. If no certificate is provided, -+the session proceeds normally. If a bad certificate is provided, it will -+be ignored and the session proceeds normally. -+The value -+.Dq try -+means that the server certificate is requested. If no certificate is provided, -+the session proceeds normally. If a bad certificate is provided, -+the session is immediately terminated. -+The value -+.Dq demand -+means that the server certificate is requested. If no -+certificate is provided, or a bad certificate is provided, the session -+is immediately terminated. -+The value -+.Dq hard -+is the same as -+.Dq demand . -+It requires an SSL connection. In the case of the plain conection the -+session is immediately terminated. -+The default is -+.Dq hard . -+.It Cm TLS_ReqCert -+Is an alias for -+.Cm TLS_CheckPeer . -+.It Cm TLS_CACertFile -+Specifies the file that contains certificates for all of the Certificate -+Authorities the client will recognize. -+There is no default. -+.It Cm TLS_CACert -+Is an alias for -+.Cm TLS_CACertFile . -+.It Cm TLS_CACertDIR -+Specifies the path of a directory that contains Certificate Authority -+certificates in separate individual files. The -+.Cm TLS_CACert -+is always used before -+.Cm TLS_CACertDir . -+The specified directory must be managed with the OpenSSL c_rehash utility. -+There is no default. -+.It Cm TLS_Ciphers -+Specifies acceptable cipher suite and preference order. -+The value should be a cipher specification for OpenSSL, -+e.g., -+.Dq HIGH:MEDIUM:+SSLv2 . -+The default is -+.Dq ALL . -+.It Cm TLS_Cipher_Suite -+Is an alias for -+.Cm TLS_Ciphers . -+.It Cm TLS_Cert -+Specifies the file that contains the client certificate. -+There is no default. -+.It Cm TLS_Certificate -+Is an alias for -+.Cm TLS_Cert . -+.It Cm TLS_Key -+Specifies the file that contains the private key that matches the certificate -+stored in the -+.Cm TLS_Cert -+file. Currently, the private key must not be protected with a password, so -+it is of critical importance that the key file is protected carefully. -+There is no default. -+.It Cm TLS_RandFile -+Specifies the file to obtain random bits from when /dev/[u]random is -+not available. Generally set to the name of the EGD/PRNGD socket. -+The environment variable RANDFILE can also be used to specify the filename. -+There is no default. -+.It Cm LogDir -+Specifies the directory used for logging by the LDAP client library. -+There is no default. -+.It Cm Debug -+Specifies the debug level used for logging by the LDAP client library. -+There is no default. -+.It Cm SSH_Filter -+Specifies the user filter applied on the LDAP search. -+The default is no filter. -+.It Cm AccountClass -+Specifies the LDAP class used to find user accounts. -+The default is posixAccount. -+.It Cm search_format -+Specifies the user format of search string in LDAP substituting %u for user name -+and %f for additional ssh filter -+.Cm SSH_Filter -+(optional). -+The default value is (&(objectclass=%c)(objectclass=ldapPublicKey)(uid=%u)%f) -+.El -+.Sh FILES -+.Bl -tag -width Ds -+.It Pa /etc/ssh/ldap.conf -+Ldap configuration file for -+.Xr ssh-ldap-helper 8 . -+.El -+.Sh "SEE ALSO" -+.Xr ldap.conf 5 , -+.Xr ssh-ldap-helper 8 -+.Sh HISTORY -+.Nm -+first appeared in -+OpenSSH 5.5 + PKA-LDAP . -+.Sh AUTHORS -+.An Jan F. Chadima Aq jchadima@redhat.com -diff --git a/openssh-lpk-openldap.ldif b/openssh-lpk-openldap.ldif -new file mode 100644 -index 0000000..9adf4b8 ---- /dev/null -+++ b/openssh-lpk-openldap.ldif -@@ -0,0 +1,19 @@ -+# -+# LDAP Public Key Patch schema for use with openssh-ldappubkey -+# useful with PKA-LDAP also -+# -+# Author: Eric AUGE -+# -+# LDIF for openLDAP Directory Server. -+# Based on the original schema, modified by Jakub Jelen. -+# -+ -+dn: cn=openssh-lpk,cn=schema,cn=config -+objectClass: olcSchemaConfig -+cn: openssh-lpk -+olcAttributeTypes: {0}( 1.3.6.1.4.1.24552.500.1.1.1.13 -+ NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' -+ EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) -+olcObjectClasses: {0}( 1.3.6.1.4.1.24552.500.1.1.2.0 -+ NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass' -+ SUP top AUXILIARY MUST ( sshPublicKey $ uid ) ) -diff --git a/openssh-lpk-sun.ldif b/openssh-lpk-sun.ldif -new file mode 100644 -index 0000000..9adf4b8 ---- /dev/null -+++ b/openssh-lpk-sun.ldif -@@ -0,0 +1,17 @@ -+# -+# LDAP Public Key Patch schema for use with openssh-ldappubkey -+# useful with PKA-LDAP also -+# -+# Author: Eric AUGE -+# -+# LDIF for Sun Directory Server. -+# Based on the original schema, modified by Jakub Jelen. -+# -+ -+dn: cn=schema -+attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 -+ NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' -+ EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) -+objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 -+ NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass' -+ SUP top AUXILIARY MUST ( sshPublicKey $ uid ) ) diff --git a/openssh-6.7p1-sftp-force-permission.patch b/openssh-6.7p1-sftp-force-permission.patch index 2d6e7304370b8f879cadeffceb2a9a4206df095f..1cfa309425c786b2cec52f51aac9a0ef16fc3d62 100644 --- a/openssh-6.7p1-sftp-force-permission.patch +++ b/openssh-6.7p1-sftp-force-permission.patch @@ -2,21 +2,23 @@ diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8 --- openssh-7.2p2/sftp-server.8.sftp-force-mode 2016-03-09 19:04:48.000000000 +0100 +++ openssh-7.2p2/sftp-server.8 2016-06-23 16:18:20.463854117 +0200 @@ -38,6 +38,7 @@ - .Op Fl P Ar blacklisted_requests - .Op Fl p Ar whitelisted_requests + .Op Fl P Ar denied_requests + .Op Fl p Ar allowed_requests .Op Fl u Ar umask +.Op Fl m Ar force_file_perms .Ek .Nm .Fl Q Ar protocol_feature -@@ -138,6 +139,10 @@ Sets an explicit +@@ -138,6 +139,12 @@ Sets an explicit .Xr umask 2 to be applied to newly-created files and directories, instead of the user's default mask. +.It Fl m Ar force_file_perms +Sets explicit file permissions to be applied to newly-created files instead +of the default or client requested mode. Numeric values include: -+777, 755, 750, 666, 644, 640, etc. Option -u is ineffective if -m is set. ++777, 755, 750, 666, 644, 640, etc. Using both -m and -u switches makes the ++umask (-u) effective only for newly created directories and explicit mode (-m) ++for newly created files. .El .Pp On some systems, @@ -65,9 +67,9 @@ diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c @@ -1494,7 +1505,7 @@ sftp_server_usage(void) fprintf(stderr, "usage: %s [-ehR] [-d start_directory] [-f log_facility] " - "[-l log_level]\n\t[-P blacklisted_requests] " -- "[-p whitelisted_requests] [-u umask]\n" -+ "[-p whitelisted_requests] [-u umask] [-m force_file_perms]\n" + "[-l log_level]\n\t[-P denied_requests] " +- "[-p allowed_requests] [-u umask]\n" ++ "[-p allowed_requests] [-u umask] [-m force_file_perms]\n" " %s -Q protocol_feature\n", __progname, __progname); exit(1); diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index 9c9a6804735d4f6d762d1ec28de4a1b25c8f9e71..b5895f7a35a63ec27f875ae09c54320fa740e0c1 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; + } @@ -137,7 +137,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c } @@ -1538,6 +1565,34 @@ child_close_fds(void) - endpwent(); + log_redirect_stderr_to(NULL); } +void diff --git a/openssh-7.2p2-k5login_directory.patch b/openssh-7.2p2-k5login_directory.patch index 242294a2cdb82184f344ce395bbe93e95394316c..80e7678e91446df8d10b336c4e330206a96b3def 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.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index c8a147b809e9f4f1d9a7ede2e98e2dbc16c21a03..135f05016f07c5f3a67444749e4f4bb4ec8e7d35 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -110,8 +110,8 @@ diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c options->x11_use_localhost = 1; if (options->xauth_location == NULL) @@ -419,7 +422,7 @@ typedef enum { - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, + sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, sPrintMotd, sPrintLastLog, sIgnoreRhosts, - sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, + sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 024d9905475dd11bbc0f3e7085ae1f3fd08ab961..44735188a9c8b6a600cc784673c815973a347db6 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -1,7 +1,7 @@ -diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c ---- openssh/audit-bsm.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit-bsm.c 2019-04-03 17:02:20.713886041 +0200 -@@ -372,13 +372,26 @@ audit_connection_from(const char *host, +diff -up openssh-8.6p1/audit-bsm.c.audit openssh-8.6p1/audit-bsm.c +--- openssh-8.6p1/audit-bsm.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit-bsm.c 2021-04-19 16:47:35.753062106 +0200 +@@ -373,13 +373,26 @@ audit_connection_from(const char *host, #endif } @@ -29,7 +29,7 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c audit_session_open(struct logininfo *li) { /* not implemented */ -@@ -390,6 +403,12 @@ audit_session_close(struct logininfo *li +@@ -391,6 +404,12 @@ audit_session_close(struct logininfo *li /* not implemented */ } @@ -42,7 +42,7 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c void audit_event(struct ssh *ssh, ssh_audit_event_t event) { -@@ -451,4 +470,28 @@ audit_event(struct ssh *ssh, ssh_audit_e +@@ -452,4 +471,28 @@ audit_event(struct ssh *ssh, ssh_audit_e debug("%s: unhandled event %d", __func__, event); } } @@ -71,9 +71,9 @@ diff -up openssh/audit-bsm.c.audit openssh/audit-bsm.c + /* not implemented */ +} #endif /* BSM */ -diff -up openssh/audit.c.audit openssh/audit.c ---- openssh/audit.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit.c 2019-04-03 17:02:20.713886041 +0200 +diff -up openssh-8.6p1/audit.c.audit openssh-8.6p1/audit.c +--- openssh-8.6p1/audit.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit.c 2021-04-19 16:47:35.753062106 +0200 @@ -34,6 +34,12 @@ #include "log.h" #include "hostfile.h" @@ -251,9 +251,9 @@ diff -up openssh/audit.c.audit openssh/audit.c } # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/audit.h.audit openssh/audit.h ---- openssh/audit.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit.h 2019-04-03 17:02:20.713886041 +0200 +diff -up openssh-8.6p1/audit.h.audit openssh-8.6p1/audit.h +--- openssh-8.6p1/audit.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit.h 2021-04-19 16:47:35.753062106 +0200 @@ -26,6 +26,7 @@ # define _SSH_AUDIT_H @@ -296,9 +296,9 @@ diff -up openssh/audit.h.audit openssh/audit.h +void audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); #endif /* _SSH_AUDIT_H */ -diff -up openssh/audit-linux.c.audit openssh/audit-linux.c ---- openssh/audit-linux.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/audit-linux.c 2019-04-03 17:02:20.713886041 +0200 +diff -up openssh-8.6p1/audit-linux.c.audit openssh-8.6p1/audit-linux.c +--- openssh-8.6p1/audit-linux.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/audit-linux.c 2021-04-19 16:47:35.753062106 +0200 @@ -33,27 +33,40 @@ #include "log.h" @@ -669,9 +669,9 @@ diff -up openssh/audit-linux.c.audit openssh/audit-linux.c + error("cannot write into audit"); +} #endif /* USE_LINUX_AUDIT */ -diff -up openssh/auditstub.c.audit openssh/auditstub.c ---- openssh/auditstub.c.audit 2019-04-03 17:02:20.714886050 +0200 -+++ openssh/auditstub.c 2019-04-03 17:02:20.714886050 +0200 +diff -up openssh-8.6p1/auditstub.c.audit openssh-8.6p1/auditstub.c +--- openssh-8.6p1/auditstub.c.audit 2021-04-19 16:47:35.754062114 +0200 ++++ openssh-8.6p1/auditstub.c 2021-04-19 16:47:35.754062114 +0200 @@ -0,0 +1,52 @@ +/* $Id: auditstub.c,v 1.1 jfch Exp $ */ + @@ -725,10 +725,10 @@ diff -up openssh/auditstub.c.audit openssh/auditstub.c +audit_session_key_free_body(struct ssh *ssh, int ctos, pid_t pid, uid_t uid) +{ +} -diff -up openssh/auth2.c.audit openssh/auth2.c ---- openssh/auth2.c.audit 2019-04-03 17:02:20.651885453 +0200 -+++ openssh/auth2.c 2019-04-03 17:02:20.714886050 +0200 -@@ -303,9 +303,6 @@ input_userauth_request(int type, u_int32 +diff -up openssh-8.6p1/auth2.c.audit openssh-8.6p1/auth2.c +--- openssh-8.6p1/auth2.c.audit 2021-04-19 16:47:35.682061561 +0200 ++++ openssh-8.6p1/auth2.c 2021-04-19 16:47:35.754062114 +0200 +@@ -298,9 +298,6 @@ input_userauth_request(int type, u_int32 } else { /* Invalid user, fake password information */ authctxt->pw = fakepw(); @@ -738,9 +738,9 @@ diff -up openssh/auth2.c.audit openssh/auth2.c } #ifdef USE_PAM if (options.use_pam) -diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c ---- openssh/auth2-hostbased.c.audit 2019-04-03 17:02:20.612885083 +0200 -+++ openssh/auth2-hostbased.c 2019-04-03 17:02:20.714886050 +0200 +diff -up openssh-8.6p1/auth2-hostbased.c.audit openssh-8.6p1/auth2-hostbased.c +--- openssh-8.6p1/auth2-hostbased.c.audit 2021-04-19 16:47:35.656061361 +0200 ++++ openssh-8.6p1/auth2-hostbased.c 2021-04-19 16:47:35.754062114 +0200 @@ -158,7 +158,7 @@ userauth_hostbased(struct ssh *ssh) authenticated = 0; if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser, @@ -771,10 +771,10 @@ diff -up openssh/auth2-hostbased.c.audit openssh/auth2-hostbased.c /* return 1 if given hostkey is allowed */ int hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, -diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.audit 2019-04-03 17:02:20.691885832 +0200 -+++ openssh/auth2-pubkey.c 2019-04-03 17:02:20.714886050 +0200 -@@ -219,7 +219,7 @@ userauth_pubkey(struct ssh *ssh) +diff -up openssh-8.6p1/auth2-pubkey.c.audit openssh-8.6p1/auth2-pubkey.c +--- openssh-8.6p1/auth2-pubkey.c.audit 2021-04-19 16:47:35.726061899 +0200 ++++ openssh-8.6p1/auth2-pubkey.c 2021-04-19 16:47:35.754062114 +0200 +@@ -213,7 +213,7 @@ userauth_pubkey(struct ssh *ssh) /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) && @@ -783,7 +783,7 @@ diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, ssh->compat, &sig_details)) == 0) { -@@ -278,6 +278,20 @@ done: +@@ -305,6 +305,20 @@ done: return authenticated; } @@ -804,19 +804,10 @@ diff -up openssh/auth2-pubkey.c.audit openssh/auth2-pubkey.c static int match_principals_option(const char *principal_list, struct sshkey_cert *cert) { -diff -up openssh/auth.c.audit openssh/auth.c ---- openssh/auth.c.audit 2019-04-03 17:02:20.691885832 +0200 -+++ openssh/auth.c 2019-04-03 17:02:20.714886050 +0200 -@@ -366,7 +366,7 @@ auth_log(struct ssh *ssh, int authentica - # endif - #endif - #ifdef SSH_AUDIT_EVENTS -- if (authenticated == 0 && !authctxt->postponed) -+ if (authenticated == 0 && !authctxt->postponed && !partial) - audit_event(ssh, audit_classify_auth(method)); - #endif - } -@@ -592,9 +592,6 @@ getpwnamallow(struct ssh *ssh, const cha +diff -up openssh-8.6p1/auth.c.audit openssh-8.6p1/auth.c +--- openssh-8.6p1/auth.c.audit 2021-04-19 16:47:35.681061553 +0200 ++++ openssh-8.6p1/auth.c 2021-04-19 16:47:35.754062114 +0200 +@@ -597,9 +597,6 @@ getpwnamallow(struct ssh *ssh, const cha record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif @@ -826,10 +817,10 @@ diff -up openssh/auth.c.audit openssh/auth.c return (NULL); } if (!allowed_user(ssh, pw)) -diff -up openssh/auth.h.audit openssh/auth.h ---- openssh/auth.h.audit 2019-04-03 17:02:20.692885842 +0200 -+++ openssh/auth.h 2019-04-03 17:02:20.714886050 +0200 -@@ -195,6 +195,8 @@ struct passwd * getpwnamallow(struct ssh +diff -up openssh-8.6p1/auth.h.audit openssh-8.6p1/auth.h +--- openssh-8.6p1/auth.h.audit 2021-04-19 16:47:35.697061676 +0200 ++++ openssh-8.6p1/auth.h 2021-04-19 16:47:35.754062114 +0200 +@@ -193,6 +193,8 @@ struct passwd * getpwnamallow(struct ssh char *expand_authorized_keys(const char *, struct passwd *pw); char *authorized_principals_file(struct passwd *); @@ -838,7 +829,7 @@ diff -up openssh/auth.h.audit openssh/auth.h FILE *auth_openkeyfile(const char *, struct passwd *, int); FILE *auth_openprincipals(const char *, struct passwd *, int); -@@ -214,6 +216,8 @@ struct sshkey *get_hostkey_private_by_ty +@@ -212,6 +214,8 @@ struct sshkey *get_hostkey_private_by_ty int get_hostkey_index(struct sshkey *, int, struct ssh *); int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *); @@ -847,10 +838,10 @@ diff -up openssh/auth.h.audit openssh/auth.h /* Key / cert options linkage to auth layer */ const struct sshauthopt *auth_options(struct ssh *); -diff -up openssh/cipher.c.audit openssh/cipher.c ---- openssh/cipher.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/cipher.c 2019-04-03 17:02:20.714886050 +0200 -@@ -61,25 +61,6 @@ struct sshcipher_ctx { +diff -up openssh-8.6p1/cipher.c.audit openssh-8.6p1/cipher.c +--- openssh-8.6p1/cipher.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/cipher.c 2021-04-19 16:47:35.755062122 +0200 +@@ -64,25 +64,6 @@ struct sshcipher_ctx { const struct sshcipher *cipher; }; @@ -876,19 +867,19 @@ diff -up openssh/cipher.c.audit openssh/cipher.c static const struct sshcipher ciphers[] = { #ifdef WITH_OPENSSL #ifndef OPENSSL_NO_DES -@@ -410,7 +391,7 @@ cipher_get_length(struct sshcipher_ctx * +@@ -422,7 +403,7 @@ cipher_get_length(struct sshcipher_ctx * void cipher_free(struct sshcipher_ctx *cc) { - if (cc == NULL) + if (cc == NULL || cc->cipher == NULL) return; - if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) - explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); -diff -up openssh/cipher.h.audit openssh/cipher.h ---- openssh/cipher.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/cipher.h 2019-04-03 17:02:20.714886050 +0200 -@@ -45,7 +45,25 @@ + if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { + chachapoly_free(cc->cp_ctx); +diff -up openssh-8.6p1/cipher.h.audit openssh-8.6p1/cipher.h +--- openssh-8.6p1/cipher.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/cipher.h 2021-04-19 16:47:35.755062122 +0200 +@@ -47,7 +47,25 @@ #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 @@ -915,10 +906,10 @@ diff -up openssh/cipher.h.audit openssh/cipher.h struct sshcipher_ctx; const struct sshcipher *cipher_by_name(const char *); -diff -up openssh/kex.c.audit openssh/kex.c ---- openssh/kex.c.audit 2019-04-03 17:02:20.652885462 +0200 -+++ openssh/kex.c 2019-04-03 17:02:20.715886060 +0200 -@@ -60,6 +60,7 @@ +diff -up openssh-8.6p1/kex.c.audit openssh-8.6p1/kex.c +--- openssh-8.6p1/kex.c.audit 2021-04-19 16:47:35.743062030 +0200 ++++ openssh-8.6p1/kex.c 2021-04-19 16:47:35.755062122 +0200 +@@ -65,6 +65,7 @@ #include "ssherr.h" #include "sshbuf.h" #include "digest.h" @@ -926,7 +917,7 @@ diff -up openssh/kex.c.audit openssh/kex.c #ifdef GSSAPI #include "ssh-gss.h" -@@ -758,12 +759,16 @@ kex_start_rekex(struct ssh *ssh) +@@ -816,12 +817,16 @@ kex_start_rekex(struct ssh *ssh) } static int @@ -943,9 +934,9 @@ 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 +@@ -842,8 +847,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -957,9 +948,9 @@ 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 +@@ -856,12 +865,16 @@ choose_mac(struct ssh *ssh, struct sshma } static int @@ -978,7 +969,7 @@ diff -up openssh/kex.c.audit openssh/kex.c #ifdef WITH_ZLIB if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; -@@ -933,7 +946,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1002,7 +1015,7 @@ kex_choose_conf(struct ssh *ssh) nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; @@ -987,7 +978,7 @@ diff -up openssh/kex.c.audit openssh/kex.c sprop[nenc])) != 0) { kex->failed_choice = peer[nenc]; peer[nenc] = NULL; -@@ -948,7 +961,7 @@ kex_choose_conf(struct ssh *ssh) +@@ -1017,7 +1030,7 @@ kex_choose_conf(struct ssh *ssh) peer[nmac] = NULL; goto out; } @@ -996,7 +987,7 @@ diff -up openssh/kex.c.audit openssh/kex.c sprop[ncomp])) != 0) { kex->failed_choice = peer[ncomp]; peer[ncomp] = NULL; -@@ -971,6 +984,10 @@ kex_choose_conf(struct ssh *ssh) +@@ -1040,6 +1053,10 @@ kex_choose_conf(struct ssh *ssh) dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); @@ -1007,7 +998,7 @@ diff -up openssh/kex.c.audit openssh/kex.c } /* XXX need runden? */ kex->we_need = need; -@@ -1129,6 +1146,36 @@ dump_digest(const char *msg, const u_cha +@@ -1297,6 +1314,36 @@ dump_digest(const char *msg, const u_cha } #endif @@ -1044,9 +1035,9 @@ diff -up openssh/kex.c.audit openssh/kex.c /* * Send a plaintext error message to the peer, suffixed by \r\n. * Only used during banner exchange, and there only for the server. -diff -up openssh/kex.h.audit openssh/kex.h ---- openssh/kex.h.audit 2019-04-03 17:02:20.652885462 +0200 -+++ openssh/kex.h 2019-04-03 17:02:20.715886060 +0200 +diff -up openssh-8.6p1/kex.h.audit openssh-8.6p1/kex.h +--- openssh-8.6p1/kex.h.audit 2021-04-19 16:47:35.683061568 +0200 ++++ openssh-8.6p1/kex.h 2021-04-19 16:47:35.756062129 +0200 @@ -226,6 +226,8 @@ int kexgss_client(struct ssh *); int kexgss_server(struct ssh *); #endif @@ -1056,10 +1047,10 @@ diff -up openssh/kex.h.audit openssh/kex.h int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **); -diff -up openssh/mac.c.audit openssh/mac.c ---- openssh/mac.c.audit 2019-04-03 17:02:20.652885462 +0200 -+++ openssh/mac.c 2019-04-03 17:02:20.715886060 +0200 -@@ -243,6 +243,20 @@ mac_clear(struct sshmac *mac) +diff -up openssh-8.6p1/mac.c.audit openssh-8.6p1/mac.c +--- openssh-8.6p1/mac.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/mac.c 2021-04-19 16:47:35.756062129 +0200 +@@ -239,6 +239,20 @@ mac_clear(struct sshmac *mac) mac->umac_ctx = NULL; } @@ -1080,9 +1071,9 @@ diff -up openssh/mac.c.audit openssh/mac.c /* XXX copied from ciphers_valid */ #define MAC_SEP "," int -diff -up openssh/mac.h.audit openssh/mac.h ---- openssh/mac.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/mac.h 2019-04-03 17:02:20.715886060 +0200 +diff -up openssh-8.6p1/mac.h.audit openssh-8.6p1/mac.h +--- openssh-8.6p1/mac.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/mac.h 2021-04-19 16:47:35.756062129 +0200 @@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, const u_char *, size_t); @@ -1090,21 +1081,21 @@ diff -up openssh/mac.h.audit openssh/mac.h +void mac_destroy(struct sshmac *); #endif /* SSHMAC_H */ -diff -up openssh/Makefile.in.audit openssh/Makefile.in ---- openssh/Makefile.in.audit 2019-04-03 17:02:20.705885965 +0200 -+++ openssh/Makefile.in 2019-04-03 17:02:20.715886060 +0200 -@@ -109,7 +109,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ +diff -up openssh-8.6p1/Makefile.in.audit openssh-8.6p1/Makefile.in +--- openssh-8.6p1/Makefile.in.audit 2021-04-19 16:47:35.731061937 +0200 ++++ openssh-8.6p1/Makefile.in 2021-04-19 16:47:35.756062129 +0200 +@@ -112,7 +112,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kexsntrup761x25519.o sntrup761.o kexgen.o \ kexgssc.o \ - sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ + sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o + sshbuf-io.o auditstub.o SKOBJS= ssh-sk-client.o -diff -up openssh/monitor.c.audit openssh/monitor.c ---- openssh/monitor.c.audit 2019-04-03 17:02:20.674885671 +0200 -+++ openssh/monitor.c 2019-04-03 17:03:17.201421405 +0200 +diff -up openssh-8.6p1/monitor.c.audit openssh-8.6p1/monitor.c +--- openssh-8.6p1/monitor.c.audit 2021-04-19 16:47:35.707061753 +0200 ++++ openssh-8.6p1/monitor.c 2021-04-19 16:47:35.756062129 +0200 @@ -93,6 +93,7 @@ #include "compat.h" #include "ssh2.h" @@ -1113,7 +1104,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c #include "match.h" #include "ssherr.h" #include "sk-api.h" -@@ -107,6 +108,8 @@ extern u_char session_id[]; +@@ -107,6 +108,8 @@ extern u_int utmp_len; extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ @@ -1157,9 +1148,9 @@ diff -up openssh/monitor.c.audit openssh/monitor.c #endif {0, 0, NULL} }; -@@ -1445,8 +1462,10 @@ mm_answer_keyverify(struct ssh *ssh, int - size_t signaturelen, datalen, bloblen; - int r, ret, req_presence = 0, valid_data = 0, encoded_ret; +@@ -1444,8 +1461,10 @@ mm_answer_keyverify(struct ssh *ssh, int + int r, ret, req_presence = 0, req_verify = 0, valid_data = 0; + int encoded_ret; struct sshkey_sig_details *sig_details = NULL; + int type = 0; @@ -1169,18 +1160,18 @@ diff -up openssh/monitor.c.audit openssh/monitor.c (r = sshbuf_get_string_direct(m, &signature, &signaturelen)) != 0 || (r = sshbuf_get_string_direct(m, &data, &datalen)) != 0 || (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) -@@ -1455,6 +1474,8 @@ mm_answer_keyverify(struct ssh *ssh, int +@@ -1454,6 +1473,8 @@ mm_answer_keyverify(struct ssh *ssh, int if (hostbased_cuser == NULL || hostbased_chost == NULL || !monitor_allowed_key(blob, bloblen)) - fatal("%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 +@@ -1469,14 +1490,19 @@ 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,57 +1189,55 @@ diff -up openssh/monitor.c.audit openssh/monitor.c break; } if (!valid_data) - fatal("%s: bad signature data blob", __func__); - - if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, +@@ -1488,8 +1514,6 @@ mm_answer_keyverify(struct ssh *ssh, int 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, - (ret == 0) ? "verified" : "unverified", - (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); -@@ -1536,13 +1560,19 @@ mm_record_login(struct ssh *ssh, Session + debug3_f("%s %s signature %s%s%s", auth_method, sshkey_type(key), + (ret == 0) ? "verified" : "unverified", + (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); +@@ -1576,13 +1600,19 @@ mm_record_login(struct ssh *ssh, Session } static void -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 session_unused(s->self); } -@@ -1609,7 +1639,7 @@ mm_answer_pty(struct ssh *ssh, int sock, +@@ -1649,7 +1679,7 @@ mm_answer_pty(struct ssh *ssh, int sock, error: if (s != NULL) - 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 +@@ -1668,7 +1698,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); sshbuf_reset(m); free(tty); return (0); -@@ -1650,6 +1680,8 @@ mm_answer_term(struct ssh *ssh, int sock +@@ -1690,6 +1720,8 @@ mm_answer_term(struct ssh *ssh, int sock sshpam_cleanup(); #endif @@ -1257,7 +1246,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); -@@ -1696,12 +1728,47 @@ mm_answer_audit_command(struct ssh *ssh, +@@ -1736,12 +1768,47 @@ mm_answer_audit_command(struct ssh *ssh, { char *cmd; int r; @@ -1271,7 +1260,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,31 +1282,31 @@ 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); } -@@ -1767,6 +1834,7 @@ monitor_apply_keystate(struct ssh *ssh, +@@ -1813,6 +1880,7 @@ monitor_apply_keystate(struct ssh *ssh, void mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) { + 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 +@@ -1820,6 +1888,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(); @@ -1334,7 +1323,7 @@ diff -up openssh/monitor.c.audit openssh/monitor.c } -@@ -2066,3 +2147,102 @@ mm_answer_gss_updatecreds(struct ssh *ss +@@ -2111,3 +2192,102 @@ mm_answer_gss_updatecreds(struct ssh *ss #endif /* GSSAPI */ @@ -1345,7 +1334,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 +1359,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 +1387,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 +1412,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); @@ -1437,9 +1426,9 @@ diff -up openssh/monitor.c.audit openssh/monitor.c + return 0; +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/monitor.h.audit openssh/monitor.h ---- openssh/monitor.h.audit 2019-04-03 17:02:20.674885671 +0200 -+++ openssh/monitor.h 2019-04-03 17:02:20.715886060 +0200 +diff -up openssh-8.6p1/monitor.h.audit openssh-8.6p1/monitor.h +--- openssh-8.6p1/monitor.h.audit 2021-04-19 16:47:35.707061753 +0200 ++++ openssh-8.6p1/monitor.h 2021-04-19 16:47:35.757062137 +0200 @@ -65,7 +65,13 @@ enum monitor_reqtype { MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, @@ -1455,10 +1444,10 @@ diff -up openssh/monitor.h.audit openssh/monitor.h MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, -diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c ---- openssh/monitor_wrap.c.audit 2019-04-03 17:02:20.653885472 +0200 -+++ openssh/monitor_wrap.c 2019-04-03 17:02:20.716886069 +0200 -@@ -513,7 +513,7 @@ mm_key_allowed(enum mm_keytype type, con +diff -up openssh-8.6p1/monitor_wrap.c.audit openssh-8.6p1/monitor_wrap.c +--- openssh-8.6p1/monitor_wrap.c.audit 2021-04-19 16:47:35.685061584 +0200 ++++ openssh-8.6p1/monitor_wrap.c 2021-04-19 16:47:35.757062137 +0200 +@@ -520,7 +520,7 @@ mm_key_allowed(enum mm_keytype type, con */ int @@ -1467,17 +1456,17 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c const u_char *data, size_t datalen, const char *sigalg, u_int compat, struct sshkey_sig_details **sig_detailsp) { -@@ -525,7 +525,8 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -536,7 +536,8 @@ mm_sshkey_verify(const struct sshkey *ke *sig_detailsp = NULL; if ((m = sshbuf_new()) == NULL) - fatal("%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 || (r = sshbuf_put_string(m, sig, siglen)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0) -@@ -547,6 +548,22 @@ mm_sshkey_verify(const struct sshkey *ke +@@ -569,6 +570,22 @@ mm_sshkey_verify(const struct sshkey *ke return 0; } @@ -1500,7 +1489,7 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c void mm_send_keystate(struct ssh *ssh, struct monitor *monitor) { -@@ -900,11 +915,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi +@@ -921,11 +938,12 @@ mm_audit_event(struct ssh *ssh, ssh_audi sshbuf_free(m); } @@ -1515,14 +1504,14 @@ diff -up openssh/monitor_wrap.c.audit openssh/monitor_wrap.c debug3("%s entering command %s", __func__, command); -@@ -914,6 +930,30 @@ mm_audit_run_command(const char *command +@@ -935,6 +953,30 @@ mm_audit_run_command(const char *command fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); + 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,19 +1523,19 @@ 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); } #endif /* SSH_AUDIT_EVENTS */ -@@ -1074,3 +1114,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc +@@ -1095,3 +1137,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc } #endif /* GSSAPI */ @@ -1558,9 +1547,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 +1566,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 +1574,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 +1590,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,20 +1609,20 @@ 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); +} +#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h ---- openssh/monitor_wrap.h.audit 2019-04-03 17:02:20.653885472 +0200 -+++ openssh/monitor_wrap.h 2019-04-03 17:02:20.716886069 +0200 -@@ -57,7 +57,9 @@ int mm_user_key_allowed(struct ssh *, st +diff -up openssh-8.6p1/monitor_wrap.h.audit openssh-8.6p1/monitor_wrap.h +--- openssh-8.6p1/monitor_wrap.h.audit 2021-04-19 16:47:35.685061584 +0200 ++++ openssh-8.6p1/monitor_wrap.h 2021-04-19 16:47:35.757062137 +0200 +@@ -61,7 +61,9 @@ int mm_user_key_allowed(struct ssh *, st struct sshauthopt **); int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, const char *, struct sshkey *); @@ -1644,7 +1633,7 @@ diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); #ifdef GSSAPI -@@ -82,7 +84,12 @@ void mm_sshpam_free_ctx(void *); +@@ -86,7 +88,12 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" void mm_audit_event(struct ssh *, ssh_audit_event_t); @@ -1658,10 +1647,10 @@ diff -up openssh/monitor_wrap.h.audit openssh/monitor_wrap.h #endif struct Session; -diff -up openssh/packet.c.audit openssh/packet.c ---- openssh/packet.c.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/packet.c 2019-04-03 17:02:20.716886069 +0200 -@@ -77,6 +77,7 @@ +diff -up openssh-8.6p1/packet.c.audit openssh-8.6p1/packet.c +--- openssh-8.6p1/packet.c.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/packet.c 2021-04-19 16:48:46.885608837 +0200 +@@ -81,6 +81,7 @@ #endif #include "xmalloc.h" @@ -1669,7 +1658,7 @@ diff -up openssh/packet.c.audit openssh/packet.c #include "compat.h" #include "ssh2.h" #include "cipher.h" -@@ -510,6 +511,13 @@ ssh_packet_get_connection_out(struct ssh +@@ -506,6 +507,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -1683,7 +1672,7 @@ diff -up openssh/packet.c.audit openssh/packet.c /* * Returns the IP-address of the remote host as a string. The returned * string must not be freed. -@@ -587,22 +595,19 @@ ssh_packet_close_internal(struct ssh *ss +@@ -583,22 +591,19 @@ ssh_packet_close_internal(struct ssh *ss { struct session_state *state = ssh->state; u_int mode; @@ -1711,7 +1700,7 @@ diff -up openssh/packet.c.audit openssh/packet.c for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; -@@ -636,8 +641,18 @@ ssh_packet_close_internal(struct ssh *ss +@@ -634,8 +639,18 @@ ssh_packet_close_internal(struct ssh *ss #endif /* WITH_ZLIB */ cipher_free(state->send_context); cipher_free(state->receive_context); @@ -1730,15 +1719,15 @@ diff -up openssh/packet.c.audit openssh/packet.c free(ssh->local_ipaddr); ssh->local_ipaddr = NULL; free(ssh->remote_ipaddr); -@@ -864,6 +879,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod - (unsigned long long)state->p_send.bytes, - (unsigned long long)state->p_send.blocks); +@@ -892,6 +907,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod + (unsigned long long)state->p_send.bytes, + (unsigned long long)state->p_send.blocks); kex_free_newkeys(state->newkeys[mode]); + audit_session_key_free(ssh, mode); state->newkeys[mode] = NULL; } /* note that both bytes and the seqnr are not reset */ -@@ -2167,6 +2183,71 @@ ssh_packet_get_output(struct ssh *ssh) +@@ -2173,6 +2189,72 @@ ssh_packet_get_output(struct ssh *ssh) return (void *)ssh->state->output; } @@ -1769,6 +1758,7 @@ diff -up openssh/packet.c.audit openssh/packet.c + + cipher_free(state->receive_context); + cipher_free(state->send_context); ++ state->send_context = state->receive_context = NULL; + + sshbuf_free(state->input); + state->input = NULL; @@ -1810,18 +1800,18 @@ diff -up openssh/packet.c.audit openssh/packet.c /* Reset after_authentication and reset compression in post-auth privsep */ static int ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh/packet.h.audit openssh/packet.h ---- openssh/packet.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/packet.h 2019-04-03 17:02:20.716886069 +0200 -@@ -217,4 +217,5 @@ const u_char *sshpkt_ptr(struct ssh *, s +diff -up openssh-8.6p1/packet.h.audit openssh-8.6p1/packet.h +--- openssh-8.6p1/packet.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/packet.h 2021-04-19 16:47:35.758062145 +0200 +@@ -218,4 +218,5 @@ const u_char *sshpkt_ptr(struct ssh *, s # undef EC_POINT #endif +void packet_destroy_all(struct ssh *, int, int); #endif /* PACKET_H */ -diff -up openssh/session.c.audit openssh/session.c ---- openssh/session.c.audit 2019-04-03 17:02:20.712886031 +0200 -+++ openssh/session.c 2019-04-03 17:02:20.716886069 +0200 +diff -up openssh-8.6p1/session.c.audit openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.audit 2021-04-19 16:47:35.722061868 +0200 ++++ openssh-8.6p1/session.c 2021-04-19 16:47:35.758062145 +0200 @@ -136,7 +136,7 @@ extern char *__progname; extern int debug_flag; extern u_int utmp_len; @@ -1831,7 +1821,7 @@ diff -up openssh/session.c.audit openssh/session.c extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; extern char *tun_fwd_ifnames; /* serverloop.c */ -@@ -648,6 +648,14 @@ do_exec_pty(struct ssh *ssh, Session *s, +@@ -644,6 +644,14 @@ do_exec_pty(struct ssh *ssh, Session *s, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); @@ -1846,7 +1836,7 @@ diff -up openssh/session.c.audit openssh/session.c /* Enter interactive session. */ s->ptymaster = ptymaster; ssh_packet_set_interactive(ssh, 1, -@@ -740,15 +748,19 @@ do_exec(struct ssh *ssh, Session *s, con +@@ -736,15 +744,19 @@ do_exec(struct ssh *ssh, Session *s, con s->self); #ifdef SSH_AUDIT_EVENTS @@ -1868,7 +1858,7 @@ diff -up openssh/session.c.audit openssh/session.c #endif if (s->ttyfd != -1) ret = do_exec_pty(ssh, s, command); -@@ -1556,8 +1568,11 @@ do_child(struct ssh *ssh, Session *s, co +@@ -1550,8 +1562,11 @@ do_child(struct ssh *ssh, Session *s, co sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); /* remove hostkey from the child's memory */ @@ -1881,7 +1871,7 @@ diff -up openssh/session.c.audit openssh/session.c /* Force a password change */ if (s->authctxt->force_pwchange) { -@@ -1769,6 +1784,9 @@ session_unused(int id) +@@ -1763,6 +1778,9 @@ session_unused(int id) sessions[id].ttyfd = -1; sessions[id].ptymaster = -1; sessions[id].x11_chanids = NULL; @@ -1891,7 +1881,7 @@ diff -up openssh/session.c.audit openssh/session.c sessions[id].next_unused = sessions_first_unused; sessions_first_unused = id; } -@@ -1851,6 +1869,19 @@ session_open(Authctxt *authctxt, int cha +@@ -1843,6 +1861,19 @@ session_open(Authctxt *authctxt, int cha } Session * @@ -1902,7 +1892,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; +} @@ -1911,7 +1901,7 @@ diff -up openssh/session.c.audit openssh/session.c session_by_tty(char *tty) { int i; -@@ -2461,6 +2492,32 @@ session_exit_message(struct ssh *ssh, Se +@@ -2450,6 +2481,32 @@ session_exit_message(struct ssh *ssh, Se chan_write_failed(ssh, c); } @@ -1944,7 +1934,7 @@ diff -up openssh/session.c.audit openssh/session.c void session_close(struct ssh *ssh, Session *s) { -@@ -2474,6 +2531,10 @@ session_close(struct ssh *ssh, Session * +@@ -2463,6 +2520,10 @@ session_close(struct ssh *ssh, Session * if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1955,7 +1945,7 @@ diff -up openssh/session.c.audit openssh/session.c free(s->term); free(s->display); free(s->x11_chanids); -@@ -2549,14 +2610,14 @@ session_close_by_channel(struct ssh *ssh +@@ -2537,14 +2598,14 @@ session_close_by_channel(struct ssh *ssh } void @@ -1972,7 +1962,7 @@ diff -up openssh/session.c.audit openssh/session.c else session_close(ssh, s); } -@@ -2683,6 +2744,15 @@ do_authenticated2(struct ssh *ssh, Authc +@@ -2671,6 +2732,15 @@ do_authenticated2(struct ssh *ssh, Authc server_loop2(ssh, authctxt); } @@ -1988,7 +1978,7 @@ diff -up openssh/session.c.audit openssh/session.c void do_cleanup(struct ssh *ssh, Authctxt *authctxt) { -@@ -2746,7 +2816,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au +@@ -2734,7 +2804,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au * or if running in monitor. */ if (!use_privsep || mm_is_monitor()) @@ -1997,9 +1987,9 @@ diff -up openssh/session.c.audit openssh/session.c } /* Return a name for the remote host that fits inside utmp_size */ -diff -up openssh/session.h.audit openssh/session.h ---- openssh/session.h.audit 2019-03-27 23:26:14.000000000 +0100 -+++ openssh/session.h 2019-04-03 17:02:20.717886079 +0200 +diff -up openssh-8.6p1/session.h.audit openssh-8.6p1/session.h +--- openssh-8.6p1/session.h.audit 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/session.h 2021-04-19 16:47:35.758062145 +0200 @@ -61,6 +61,12 @@ struct Session { char *name; char *val; @@ -2027,9 +2017,9 @@ diff -up openssh/session.h.audit openssh/session.h Session *session_by_tty(char *); void session_close(struct ssh *, Session *); void do_setusercontext(struct passwd *); -diff -up openssh/sshd.c.audit openssh/sshd.c ---- openssh/sshd.c.audit 2019-04-03 17:02:20.692885842 +0200 -+++ openssh/sshd.c 2019-04-03 17:02:20.717886079 +0200 +diff -up openssh-8.6p1/sshd.c.audit openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.audit 2021-04-19 16:47:35.727061907 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 16:47:35.759062152 +0200 @@ -122,6 +122,7 @@ #include "ssh-gss.h" #endif @@ -2038,7 +2028,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c #include "ssh-sandbox.h" #include "auth-options.h" #include "version.h" -@@ -261,8 +262,8 @@ struct sshbuf *loginmsg; +@@ -260,8 +261,8 @@ struct sshbuf *loginmsg; struct passwd *privsep_pw = NULL; /* Prototypes for various functions defined later in this file. */ @@ -2049,7 +2039,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c static void do_ssh2_kex(struct ssh *); static char *listener_proctitle; -@@ -278,6 +279,15 @@ close_listen_socks(void) +@@ -279,6 +280,15 @@ close_listen_socks(void) num_listen_socks = -1; } @@ -2065,8 +2055,8 @@ diff -up openssh/sshd.c.audit openssh/sshd.c static void close_startup_pipes(void) { -@@ -380,18 +390,45 @@ grace_alarm_handler(int sig) - ssh_remote_port(the_active_state)); +@@ -377,18 +387,45 @@ grace_alarm_handler(int sig) + } } -/* Destroy the host and server keys. They will no longer be needed. */ @@ -2114,7 +2104,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) +@@ -397,20 +434,38 @@ destroy_sensitive_data(void) /* Demote private to public keys for network child */ void @@ -2141,9 +2131,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) { @@ -2155,7 +2144,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c } /* Certs do not need demotion */ } -@@ -442,7 +497,7 @@ reseed_prngs(void) +@@ -438,7 +493,7 @@ reseed_prngs(void) } static void @@ -2164,7 +2153,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c { gid_t gidset[1]; -@@ -457,7 +512,7 @@ privsep_preauth_child(void) +@@ -453,7 +508,7 @@ privsep_preauth_child(void) reseed_prngs(); /* Demote the private keys to public keys. */ @@ -2173,7 +2162,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c #ifdef WITH_SELINUX sshd_selinux_change_privsep_preauth_context(); -@@ -496,7 +551,7 @@ privsep_preauth(struct ssh *ssh) +@@ -492,7 +547,7 @@ privsep_preauth(struct ssh *ssh) if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -2182,7 +2171,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { -@@ -542,7 +597,7 @@ privsep_preauth(struct ssh *ssh) +@@ -537,7 +592,7 @@ privsep_preauth(struct ssh *ssh) /* Arrange for logging to be sent to the monitor */ set_log_handler(mm_log_handler, pmonitor); @@ -2191,7 +2180,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c setproctitle("%s", "[net]"); if (box != NULL) ssh_sandbox_child(box); -@@ -594,7 +649,7 @@ privsep_postauth(struct ssh *ssh, Authct +@@ -589,7 +644,7 @@ privsep_postauth(struct ssh *ssh, Authct set_log_handler(mm_log_handler, pmonitor); /* Demote the private keys to public keys. */ @@ -2200,7 +2189,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c reseed_prngs(); -@@ -1057,7 +1112,7 @@ server_listen(void) +@@ -1143,7 +1198,7 @@ server_listen(void) * from this function are in a forked subprocess. */ static void @@ -2209,7 +2198,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c { fd_set *fdset; int i, j, ret, maxfd; -@@ -1112,6 +1167,7 @@ server_accept_loop(int *sock_in, int *so +@@ -1204,6 +1259,7 @@ server_accept_loop(int *sock_in, int *so if (received_sigterm) { logit("Received signal %d; terminating.", (int) received_sigterm); @@ -2217,7 +2206,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c close_listen_socks(); if (options.pid_file != NULL) unlink(options.pid_file); -@@ -1978,7 +2034,7 @@ main(int ac, char **av) +@@ -2098,7 +2154,7 @@ main(int ac, char **av) #endif /* Accept a connection and return in a forked child */ @@ -2226,7 +2215,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c &newsock, config_s); } -@@ -2222,6 +2278,9 @@ main(int ac, char **av) +@@ -2333,6 +2389,9 @@ main(int ac, char **av) do_authenticated(ssh, authctxt); /* The connection has been terminated. */ @@ -2236,7 +2225,7 @@ diff -up openssh/sshd.c.audit openssh/sshd.c ssh_packet_get_bytes(ssh, &ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); -@@ -2401,6 +2460,15 @@ do_ssh2_kex(struct ssh *ssh) +@@ -2513,6 +2572,15 @@ do_ssh2_kex(struct ssh *ssh) void cleanup_exit(int i) { @@ -2252,8 +2241,8 @@ diff -up openssh/sshd.c.audit openssh/sshd.c if (the_active_state != NULL && the_authctxt != NULL) { do_cleanup(the_active_state, the_authctxt); if (use_privsep && privsep_is_preauth && -@@ -2414,9 +2482,16 @@ cleanup_exit(int i) - pmonitor->m_pid, strerror(errno)); +@@ -2525,9 +2593,16 @@ cleanup_exit(int i) + } } } + is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0; @@ -2270,10 +2259,10 @@ diff -up openssh/sshd.c.audit openssh/sshd.c audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif _exit(i); -diff -up openssh/sshkey.c.audit openssh/sshkey.c ---- openssh/sshkey.c.audit 2019-04-03 17:02:20.657885510 +0200 -+++ openssh/sshkey.c 2019-04-03 17:02:20.718886088 +0200 -@@ -331,6 +331,38 @@ sshkey_type_is_valid_ca(int type) +diff -up openssh-8.6p1/sshkey.c.audit openssh-8.6p1/sshkey.c +--- openssh-8.6p1/sshkey.c.audit 2021-04-19 16:47:35.741062014 +0200 ++++ openssh-8.6p1/sshkey.c 2021-04-19 16:47:35.759062152 +0200 +@@ -371,6 +371,38 @@ sshkey_type_is_valid_ca(int type) } int @@ -2312,10 +2301,10 @@ diff -up openssh/sshkey.c.audit openssh/sshkey.c sshkey_is_cert(const struct sshkey *k) { if (k == NULL) -diff -up openssh/sshkey.h.audit openssh/sshkey.h ---- openssh/sshkey.h.audit 2019-04-03 17:02:20.657885510 +0200 -+++ openssh/sshkey.h 2019-04-03 17:02:20.718886088 +0200 -@@ -148,6 +148,7 @@ u_int sshkey_size(const struct sshkey +diff -up openssh-8.6p1/sshkey.h.audit openssh-8.6p1/sshkey.h +--- openssh-8.6p1/sshkey.h.audit 2021-04-19 16:47:35.741062014 +0200 ++++ openssh-8.6p1/sshkey.h 2021-04-19 16:47:35.759062152 +0200 +@@ -189,6 +189,7 @@ int sshkey_shield_private(struct sshke int sshkey_unshield_private(struct sshkey *); int sshkey_type_from_name(const char *); diff --git a/openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch index 08cd349efe1e3ca98834ede2311b8e3e9ce9ca0e..f7cd50fe548dc9feafe88431f15f5110ecafd53b 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 9500cc35a560cc40616a7ad3db73a9d9ec7edad8..a628243aeb13d2e804cdc1aa5e4a8faa78739df3 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -1,6 +1,6 @@ -diff -up openssh-8.0p1/cipher-ctr.c.fips openssh-8.0p1/cipher-ctr.c ---- openssh-8.0p1/cipher-ctr.c.fips 2019-07-23 14:55:45.326525641 +0200 -+++ openssh-8.0p1/cipher-ctr.c 2019-07-23 14:55:45.401526401 +0200 +diff -up openssh-8.6p1/cipher-ctr.c.fips openssh-8.6p1/cipher-ctr.c +--- openssh-8.6p1/cipher-ctr.c.fips 2021-04-19 16:53:02.994577324 +0200 ++++ openssh-8.6p1/cipher-ctr.c 2021-04-19 16:53:03.064577862 +0200 @@ -179,7 +179,8 @@ evp_aes_128_ctr(void) aes_ctr.do_cipher = ssh_aes_ctr; #ifndef SSH_OLD_EVP @@ -11,10 +11,10 @@ diff -up openssh-8.0p1/cipher-ctr.c.fips openssh-8.0p1/cipher-ctr.c #endif return (&aes_ctr); } -diff -up openssh-8.0p1/dh.c.fips openssh-8.0p1/dh.c ---- openssh-8.0p1/dh.c.fips 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/dh.c 2019-07-23 14:55:45.401526401 +0200 -@@ -152,6 +152,12 @@ choose_dh(int min, int wantbits, int max +diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c +--- openssh-8.6p1/dh.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/dh.c 2021-04-19 16:58:47.750263410 +0200 +@@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max int best, bestcount, which, linenum; struct dhgroup dhg; @@ -24,10 +24,10 @@ diff -up openssh-8.0p1/dh.c.fips openssh-8.0p1/dh.c + return (dh_new_group_fallback(max)); + } + - if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) { + if ((f = fopen(get_moduli_filename(), "r")) == NULL) { logit("WARNING: could not open %s (%s), using fixed modulus", - _PATH_DH_MODULI, strerror(errno)); -@@ -489,4 +495,38 @@ dh_estimate(int bits) + get_moduli_filename(), strerror(errno)); +@@ -502,4 +508,38 @@ dh_estimate(int bits) return 8192; } @@ -66,21 +66,21 @@ diff -up openssh-8.0p1/dh.c.fips openssh-8.0p1/dh.c +} + #endif /* WITH_OPENSSL */ -diff -up openssh-8.0p1/dh.h.fips openssh-8.0p1/dh.h ---- openssh-8.0p1/dh.h.fips 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/dh.h 2019-07-23 14:55:45.401526401 +0200 -@@ -43,6 +43,7 @@ DH *dh_new_group_fallback(int); +diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h +--- openssh-8.6p1/dh.h.fips 2021-04-19 16:53:03.064577862 +0200 ++++ openssh-8.6p1/dh.h 2021-04-19 16:59:31.951616078 +0200 +@@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int); int dh_gen_key(DH *, int); int dh_pub_is_valid(const DH *, const BIGNUM *); +int dh_is_known_group(const DH *); u_int dh_estimate(int); - -diff -up openssh-8.0p1/kex.c.fips openssh-8.0p1/kex.c ---- openssh-8.0p1/kex.c.fips 2019-07-23 14:55:45.395526340 +0200 -+++ openssh-8.0p1/kex.c 2019-07-23 14:55:45.402526411 +0200 -@@ -199,7 +199,10 @@ kex_names_valid(const char *names) + void dh_set_moduli_file(const char *); +diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c +--- openssh-8.6p1/kex.c.fips 2021-04-19 16:53:03.058577815 +0200 ++++ openssh-8.6p1/kex.c 2021-04-19 16:53:03.065577869 +0200 +@@ -203,7 +203,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -92,9 +92,9 @@ diff -up openssh-8.0p1/kex.c.fips openssh-8.0p1/kex.c free(s); return 0; } -diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c ---- openssh-8.0p1/kexgexc.c.fips 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/kexgexc.c 2019-07-23 14:55:45.402526411 +0200 +diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c +--- openssh-8.6p1/kexgexc.c.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/kexgexc.c 2021-04-19 16:53:03.065577869 +0200 @@ -28,6 +28,7 @@ #ifdef WITH_OPENSSL @@ -103,7 +103,7 @@ diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c #include #include -@@ -113,6 +114,10 @@ input_kex_dh_gex_group(int type, u_int32 +@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32 r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -114,56 +114,12 @@ diff -up openssh-8.0p1/kexgexc.c.fips openssh-8.0p1/kexgexc.c p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ -diff -up openssh-8.0p1/Makefile.in.fips openssh-8.0p1/Makefile.in ---- openssh-8.0p1/Makefile.in.fips 2019-07-23 14:55:45.396526350 +0200 -+++ openssh-8.0p1/Makefile.in 2019-07-23 14:55:45.402526411 +0200 -@@ -180,25 +180,25 @@ libssh.a: $(LIBSSH_OBJS) - $(RANLIB) $@ - - ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) -- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS) -+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHLIBS) $(LIBS) $(GSSLIBS) - - sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) -- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) -+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) - - scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) - $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS) -- $(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHAGENT_OBJS) -- $(LD) -o $@ $(SSHAGENT_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ $(SSHAGENT_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYGEN_OBJS) -- $(LD) -o $@ $(SSHKEYGEN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ $(SSHKEYGEN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSIGN_OBJS) -- $(LD) -o $@ $(SSHKEYSIGN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ $(SSHKEYSIGN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS) - $(LD) -o $@ $(P11HELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -@@ -216,7 +216,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a - $(LD) -o $@ ssh-cavs.o $(SKOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) -- $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -+ $(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) - - sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTPSERVER_OBJS) - $(LD) -o $@ $(SFTPSERVER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h ---- openssh-8.0p1/myproposal.h.fips 2019-04-18 00:52:57.000000000 +0200 -+++ openssh-8.0p1/myproposal.h 2019-07-23 14:55:45.402526411 +0200 -@@ -111,6 +111,20 @@ - "rsa-sha2-256," \ - "ssh-rsa" +diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h +--- openssh-8.6p1/myproposal.h.fips 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/myproposal.h 2021-04-19 16:53:03.065577869 +0200 +@@ -57,6 +57,18 @@ + "rsa-sha2-512," \ + "rsa-sha2-256" +#define KEX_FIPS_PK_ALG \ + "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ @@ -171,18 +127,16 @@ diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h + "ecdsa-sha2-nistp521-cert-v01@openssh.com," \ + "rsa-sha2-512-cert-v01@openssh.com," \ + "rsa-sha2-256-cert-v01@openssh.com," \ -+ "ssh-rsa-cert-v01@openssh.com," \ + "ecdsa-sha2-nistp256," \ + "ecdsa-sha2-nistp384," \ + "ecdsa-sha2-nistp521," \ + "rsa-sha2-512," \ + "rsa-sha2-256," \ -+ "ssh-rsa" + #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ "aes128-ctr,aes192-ctr,aes256-ctr," \ -@@ -134,6 +142,27 @@ +@@ -78,6 +92,27 @@ #define KEX_CLIENT_MAC KEX_SERVER_MAC @@ -209,36 +163,36 @@ 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," \ -diff -up openssh-8.0p1/readconf.c.fips openssh-8.0p1/readconf.c ---- openssh-8.0p1/readconf.c.fips 2019-07-23 14:55:45.334525723 +0200 -+++ openssh-8.0p1/readconf.c 2019-07-23 14:55:45.402526411 +0200 -@@ -2179,11 +2179,16 @@ fill_default_options(Options * options) + "ssh-ed25519," \ +diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c +--- openssh-8.6p1/readconf.c.fips 2021-04-19 16:53:02.999577362 +0200 ++++ openssh-8.6p1/readconf.c 2021-04-19 16:53:03.065577869 +0200 +@@ -2538,11 +2538,16 @@ fill_default_options(Options * options) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); /* remove unsupported algos from default lists */ -- def_cipher = match_filter_whitelist(KEX_CLIENT_ENCRYPT, all_cipher); -- def_mac = match_filter_whitelist(KEX_CLIENT_MAC, all_mac); -- def_kex = match_filter_whitelist(KEX_CLIENT_KEX, all_kex); -- def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key); -- def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig); -+ def_cipher = match_filter_whitelist((FIPS_mode() ? +- def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher); +- def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac); +- def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex); +- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); +- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); ++ def_cipher = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher); -+ def_mac = match_filter_whitelist((FIPS_mode() ? ++ def_mac = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac); -+ def_kex = match_filter_whitelist((FIPS_mode() ? ++ def_kex = match_filter_allowlist((FIPS_mode() ? + KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex); -+ def_key = match_filter_whitelist((FIPS_mode() ? ++ def_key = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); -+ def_sig = match_filter_whitelist((FIPS_mode() ? ++ def_sig = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); #define ASSEMBLE(what, defaults, all) \ do { \ if ((r = kex_assemble_names(&options->what, \ -diff -up openssh-8.0p1/sandbox-seccomp-filter.c.fips openssh-8.0p1/sandbox-seccomp-filter.c ---- openssh-8.0p1/sandbox-seccomp-filter.c.fips 2019-07-23 14:55:45.373526117 +0200 -+++ openssh-8.0p1/sandbox-seccomp-filter.c 2019-07-23 14:55:45.402526411 +0200 -@@ -137,6 +137,9 @@ static const struct sock_filter preauth_ +diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c +--- openssh-8.6p1/sandbox-seccomp-filter.c.fips 2021-04-19 16:53:03.034577631 +0200 ++++ openssh-8.6p1/sandbox-seccomp-filter.c 2021-04-19 16:53:03.065577869 +0200 +@@ -160,6 +160,9 @@ static const struct sock_filter preauth_ #ifdef __NR_open SC_DENY(__NR_open, EACCES), #endif @@ -248,75 +202,57 @@ diff -up openssh-8.0p1/sandbox-seccomp-filter.c.fips openssh-8.0p1/sandbox-secco #ifdef __NR_openat SC_DENY(__NR_openat, EACCES), #endif -diff -up openssh-8.0p1/servconf.c.fips openssh-8.0p1/servconf.c ---- openssh-8.0p1/servconf.c.fips 2019-07-23 14:55:45.361525996 +0200 -+++ openssh-8.0p1/servconf.c 2019-07-23 14:55:45.403526421 +0200 -@@ -208,11 +208,16 @@ assemble_algorithms(ServerOptions *o) +diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c +--- openssh-8.6p1/servconf.c.fips 2021-04-19 16:53:03.027577577 +0200 ++++ openssh-8.6p1/servconf.c 2021-04-19 16:53:03.066577877 +0200 +@@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o) all_key = sshkey_alg_list(0, 0, 1, ','); all_sig = sshkey_alg_list(0, 1, 1, ','); /* remove unsupported algos from default lists */ -- def_cipher = match_filter_whitelist(KEX_SERVER_ENCRYPT, all_cipher); -- def_mac = match_filter_whitelist(KEX_SERVER_MAC, all_mac); -- def_kex = match_filter_whitelist(KEX_SERVER_KEX, all_kex); -- def_key = match_filter_whitelist(KEX_DEFAULT_PK_ALG, all_key); -- def_sig = match_filter_whitelist(SSH_ALLOWED_CA_SIGALGS, all_sig); -+ def_cipher = match_filter_whitelist((FIPS_mode() ? +- def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher); +- def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac); +- def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex); +- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key); +- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig); ++ def_cipher = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher); -+ def_mac = match_filter_whitelist((FIPS_mode() ? ++ def_mac = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac); -+ def_kex = match_filter_whitelist((FIPS_mode() ? ++ def_kex = match_filter_allowlist((FIPS_mode() ? + KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex); -+ def_key = match_filter_whitelist((FIPS_mode() ? ++ def_key = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key); -+ def_sig = match_filter_whitelist((FIPS_mode() ? ++ def_sig = match_filter_allowlist((FIPS_mode() ? + KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig); #define ASSEMBLE(what, defaults, all) \ do { \ if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ -diff -up openssh-8.0p1/ssh.c.fips openssh-8.0p1/ssh.c ---- openssh-8.0p1/ssh.c.fips 2019-07-23 14:55:45.378526168 +0200 -+++ openssh-8.0p1/ssh.c 2019-07-23 14:55:45.403526421 +0200 -@@ -76,6 +76,8 @@ +diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c +--- openssh-8.6p1/ssh.c.fips 2021-04-19 16:53:03.038577662 +0200 ++++ openssh-8.6p1/ssh.c 2021-04-19 16:53:03.066577877 +0200 +@@ -77,6 +77,7 @@ #include #include #endif +#include -+#include #include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/sys-queue.h" -@@ -600,6 +602,16 @@ main(int ac, char **av) - sanitise_stdfd(); - - __progname = ssh_get_progname(av[0]); -+#if OPENSSL_VERSION_NUMBER < 0x10100000L -+ SSLeay_add_all_algorithms(); -+#endif -+ if (access("/etc/system-fips", F_OK) == 0) -+ if (! FIPSCHECK_verify(NULL, NULL)){ -+ if (FIPS_mode()) -+ fatal("FIPS integrity verification test failed."); -+ else -+ logit("FIPS integrity verification test failed."); -+ } - - #ifndef HAVE_SETPROCTITLE - /* Prepare for later setproctitle emulation */ -@@ -614,6 +626,10 @@ main(int ac, char **av) - - seed_rng(); +@@ -1516,6 +1517,10 @@ main(int ac, char **av) + exit(0); + } + if (FIPS_mode()) { + debug("FIPS mode initialized"); + } + - /* - * Discard other fds that are hanging around. These can cause problem - * with backgrounded ssh processes started by ControlPersist. -diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c ---- openssh-8.0p1/sshconnect2.c.fips 2019-07-23 14:55:45.336525743 +0200 -+++ openssh-8.0p1/sshconnect2.c 2019-07-23 14:55:45.403526421 +0200 -@@ -44,6 +44,8 @@ + /* Expand SecurityKeyProvider if it refers to an environment variable */ + if (options.sk_provider != NULL && *options.sk_provider == '$' && + strlen(options.sk_provider) > 1) { +diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c +--- openssh-8.6p1/sshconnect2.c.fips 2021-04-19 16:53:03.055577792 +0200 ++++ openssh-8.6p1/sshconnect2.c 2021-04-19 16:53:03.066577877 +0200 +@@ -45,6 +45,8 @@ #include #endif @@ -325,7 +261,7 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -198,29 +203,34 @@ ssh_kex2(struct ssh *ssh, char *host, st +@@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st #if defined(GSSAPI) && defined(WITH_OPENSSL) if (options.gss_keyex) { @@ -333,13 +269,39 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c - * client to the key exchange algorithm proposal */ - orig = myproposal[PROPOSAL_KEX_ALGS]; - -- if (options.gss_server_identity) +- if (options.gss_server_identity) { - gss_host = xstrdup(options.gss_server_identity); -- else if (options.gss_trust_dns) +- } else if (options.gss_trust_dns) { - gss_host = remote_hostname(ssh); -- else +- /* Fall back to specified host if we are using proxy command +- * and can not use DNS on that socket */ +- if (strcmp(gss_host, "UNKNOWN") == 0) { +- free(gss_host); ++ if (FIPS_mode()) { ++ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); ++ options.gss_keyex = 0; ++ } else { ++ /* Add the GSSAPI mechanisms currently supported on this ++ * client to the key exchange algorithm proposal */ ++ orig = myproposal[PROPOSAL_KEX_ALGS]; ++ ++ if (options.gss_server_identity) { ++ gss_host = xstrdup(options.gss_server_identity); ++ } else if (options.gss_trust_dns) { ++ gss_host = remote_hostname(ssh); ++ /* Fall back to specified host if we are using proxy command ++ * and can not use DNS on that socket */ ++ if (strcmp(gss_host, "UNKNOWN") == 0) { ++ free(gss_host); ++ gss_host = xstrdup(host); ++ } ++ } else { + gss_host = xstrdup(host); + } +- } else { - gss_host = xstrdup(host); -- +- } + - gss = ssh_gssapi_client_mechanisms(gss_host, - options.gss_client_identity, options.gss_kex_algorithms); - if (gss) { @@ -352,21 +314,6 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c - orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; - xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], - "%s,null", orig); -+ if (FIPS_mode()) { -+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); -+ options.gss_keyex = 0; -+ } else { -+ /* Add the GSSAPI mechanisms currently supported on this -+ * client to the key exchange algorithm proposal */ -+ orig = myproposal[PROPOSAL_KEX_ALGS]; -+ -+ if (options.gss_server_identity) -+ gss_host = xstrdup(options.gss_server_identity); -+ else if (options.gss_trust_dns) -+ gss_host = remote_hostname(ssh); -+ else -+ gss_host = xstrdup(host); -+ + gss = ssh_gssapi_client_mechanisms(gss_host, + options.gss_client_identity, options.gss_kex_algorithms); + if (gss) { @@ -383,9 +330,9 @@ diff -up openssh-8.0p1/sshconnect2.c.fips openssh-8.0p1/sshconnect2.c } } #endif -diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c ---- openssh-8.0p1/sshd.c.fips 2019-07-23 14:55:45.398526371 +0200 -+++ openssh-8.0p1/sshd.c 2019-07-23 14:55:45.403526421 +0200 +diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.fips 2021-04-19 16:53:03.060577831 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 16:57:45.827769340 +0200 @@ -66,6 +66,7 @@ #include #include @@ -394,35 +341,23 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c #include #include #include -@@ -77,6 +78,8 @@ +@@ -77,6 +78,7 @@ #include #include #include +#include -+#include #include "openbsd-compat/openssl-compat.h" #endif -@@ -1529,6 +1532,18 @@ main(int ac, char **av) +@@ -1619,6 +1621,7 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); + OpenSSL_add_all_algorithms(); -+ if (access("/etc/system-fips", F_OK) == 0) -+ if (! FIPSCHECK_verify(NULL, NULL)) { -+ openlog(__progname, LOG_PID, LOG_AUTHPRIV); -+ if (FIPS_mode()) { -+ syslog(LOG_CRIT, "FIPS integrity verification test failed."); -+ cleanup_exit(255); -+ } -+ else -+ syslog(LOG_INFO, "FIPS integrity verification test failed."); -+ closelog(); -+ } /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; rexec_argc = ac; -@@ -1992,6 +2007,10 @@ main(int ac, char **av) +@@ -2110,6 +2113,10 @@ main(int ac, char **av) /* Reinitialize the log (because of the fork above). */ log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -430,10 +365,10 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c + debug("FIPS mode initialized"); + } + - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ - if (chdir("/") == -1) -@@ -2382,10 +2401,14 @@ do_ssh2_kex(struct ssh *ssh) + /* + * Chdir to the root directory so that the current disk can be + * unmounted if desired. +@@ -2494,10 +2501,14 @@ do_ssh2_kex(struct ssh *ssh) if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) orig = NULL; @@ -452,9 +387,9 @@ diff -up openssh-8.0p1/sshd.c.fips openssh-8.0p1/sshd.c if (gss && orig) xasprintf(&newstr, "%s,%s", gss, orig); -diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c ---- openssh-8.0p1/sshkey.c.fips 2019-07-23 14:55:45.398526371 +0200 -+++ openssh-8.0p1/sshkey.c 2019-07-23 14:55:45.404526431 +0200 +diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c +--- openssh-8.6p1/sshkey.c.fips 2021-04-19 16:53:03.061577838 +0200 ++++ openssh-8.6p1/sshkey.c 2021-04-19 16:53:03.067577885 +0200 @@ -34,6 +34,7 @@ #include #include @@ -471,19 +406,19 @@ diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c #include "ssh-sk.h" #ifdef WITH_XMSS -@@ -1591,6 +1593,8 @@ rsa_generate_private_key(u_int bits, RSA +@@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || !RSA_generate_key_ex(private, bits, f4, NULL)) { + 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 -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c ---- openssh-8.0p1/ssh-keygen.c.fips 2019-07-23 14:55:45.391526300 +0200 -+++ openssh-8.0p1/ssh-keygen.c 2019-07-23 14:57:54.118830056 +0200 -@@ -199,6 +199,12 @@ type_bits_valid(int type, const char *na +diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c +--- openssh-8.6p1/ssh-keygen.c.fips 2021-04-19 16:53:03.038577662 +0200 ++++ openssh-8.6p1/ssh-keygen.c 2021-04-19 16:53:03.068577892 +0200 +@@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na #endif } #ifdef WITH_OPENSSL @@ -496,7 +431,7 @@ diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c switch (type) { case KEY_DSA: if (*bitsp != 1024) -@@ -1029,9 +1035,17 @@ do_gen_all_hostkeys(struct passwd *pw) +@@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw) first = 1; printf("%s: generating new host keys: ", __progname); } @@ -513,5 +448,5 @@ diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c fflush(stdout); - type = sshkey_type_from_name(key_types[i].key_type); if ((fd = mkstemp(prv_tmp)) == -1) { - error("Could not save your public key in %s: %s", + error("Could not save your private key in %s: %s", prv_tmp, strerror(errno)); diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 93862494d5276810796a4f526f380aa4aa1481c8..64e96ab236575953ac5ba5455fd8e662e52bee62 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -1,7 +1,26 @@ -diff --git a/auth-krb5.c b/auth-krb5.c -index a5a81ed2..63f877f2 100644 ---- a/auth-krb5.c -+++ b/auth-krb5.c +diff -up openssh-8.6p1/auth.h.ccache_name openssh-8.6p1/auth.h +--- openssh-8.6p1/auth.h.ccache_name 2021-04-19 14:05:10.820744325 +0200 ++++ openssh-8.6p1/auth.h 2021-04-19 14:05:10.853744569 +0200 +@@ -83,6 +83,7 @@ struct Authctxt { + krb5_principal krb5_user; + char *krb5_ticket_file; + char *krb5_ccname; ++ int krb5_set_env; + #endif + struct sshbuf *loginmsg; + +@@ -231,7 +232,7 @@ struct passwd *fakepw(void); + int sys_auth_passwd(struct ssh *, const char *); + + #if defined(KRB5) && !defined(HEIMDAL) +-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); ++krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); + #endif + + #endif /* AUTH_H */ +diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c +--- openssh-8.6p1/auth-krb5.c.ccache_name 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/auth-krb5.c 2021-04-19 14:40:55.142832954 +0200 @@ -51,6 +51,7 @@ #include #include @@ -10,7 +29,7 @@ index a5a81ed2..63f877f2 100644 extern ServerOptions options; -@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c #endif krb5_error_code problem; krb5_ccache ccache = NULL; @@ -19,24 +38,18 @@ index a5a81ed2..63f877f2 100644 char *client, *platform_client; const char *errmsg; -@@ -163,7 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, c goto out; } -- problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache); +- problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, +- &authctxt->krb5_fwd_ccache); + problem = ssh_krb5_cc_new_unique(authctxt->krb5_ctx, + &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env); if (problem) goto out; -@@ -172,21 +174,20 @@ auth_krb5_password(Authctxt *authctxt, const char *password) - if (problem) - goto out; - -- problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, -+ problem = krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, - &creds); - if (problem) +@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, c goto out; #endif @@ -57,7 +70,7 @@ index a5a81ed2..63f877f2 100644 do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); #endif -@@ -222,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password) +@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, c void krb5_cleanup_proc(Authctxt *authctxt) { @@ -113,7 +126,7 @@ index a5a81ed2..63f877f2 100644 if (authctxt->krb5_user) { krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); authctxt->krb5_user = NULL; -@@ -237,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt) +@@ -238,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt) } } @@ -151,7 +164,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 +192,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; + } @@ -198,16 +211,13 @@ index a5a81ed2..63f877f2 100644 + return -1; +} + - krb5_error_code --ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { -- int tmpfd, ret, oerrno; -- char ccname[40]; ++krb5_error_code +ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { + profile_t p; + int ret = 0; + char *value = NULL; + -+ debug3("%s: called", __func__); ++ debug3_f("called"); + ret = krb5_get_profile(ctx, &p); + if (ret) + return ret; @@ -218,11 +228,14 @@ 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; +} + -+krb5_error_code + krb5_error_code +-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { +- int tmpfd, ret, oerrno; +- char ccname[40]; +ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) { + int tmpfd, ret, oerrno, type_len; + char *ccname = NULL; @@ -242,7 +255,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 +296,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 +317,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,36 +331,47 @@ 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)); + } } #endif /* !HEIMDAL */ #endif /* KRB5 */ -diff --git a/auth.h b/auth.h -index 29491df9..fdab5040 100644 ---- a/auth.h -+++ b/auth.h -@@ -82,6 +82,7 @@ struct Authctxt { - krb5_principal krb5_user; - char *krb5_ticket_file; - char *krb5_ccname; -+ int krb5_set_env; - #endif - struct sshbuf *loginmsg; +diff -up openssh-8.6p1/gss-serv.c.ccache_name openssh-8.6p1/gss-serv.c +--- openssh-8.6p1/gss-serv.c.ccache_name 2021-04-19 14:05:10.844744503 +0200 ++++ openssh-8.6p1/gss-serv.c 2021-04-19 14:05:10.854744577 +0200 +@@ -413,13 +413,15 @@ ssh_gssapi_cleanup_creds(void) + } -@@ -238,7 +239,7 @@ int sys_auth_passwd(struct ssh *, const char *); - int sys_auth_passwd(struct ssh *, const char *); + /* As user */ +-void ++int + ssh_gssapi_storecreds(void) + { + if (gssapi_client.mech && gssapi_client.mech->storecreds) { +- (*gssapi_client.mech->storecreds)(&gssapi_client); ++ return (*gssapi_client.mech->storecreds)(&gssapi_client); + } else + debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); ++ ++ return 0; + } - #if defined(KRB5) && !defined(HEIMDAL) --krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); -+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); + /* This allows GSSAPI methods to do things to the child's environment based +@@ -499,9 +501,7 @@ ssh_gssapi_rekey_creds(void) { + char *envstr; #endif - #endif /* AUTH_H */ -diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c ---- openssh-7.9p1/gss-serv-krb5.c.ccache_name 2019-03-01 15:17:42.708611802 +0100 -+++ openssh-7.9p1/gss-serv-krb5.c 2019-03-01 15:17:42.713611844 +0100 +- if (gssapi_client.store.filename == NULL && +- gssapi_client.store.envval == NULL && +- gssapi_client.store.envvar == NULL) ++ if (gssapi_client.store.envval == NULL) + return; + + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); +diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c +--- openssh-8.6p1/gss-serv-krb5.c.ccache_name 2021-04-19 14:05:10.852744562 +0200 ++++ openssh-8.6p1/gss-serv-krb5.c 2021-04-19 14:05:10.854744577 +0200 @@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri /* This writes out any forwarded credentials from the structure populated * during userauth. Called after we have setuid to the user */ @@ -450,7 +474,7 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c do_pam_putenv(client->store.envvar, client->store.envval); #endif -@@ -361,7 +355,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl +@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl client->store.data = krb_context; @@ -459,43 +483,10 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c } int -diff --git a/gss-serv.c b/gss-serv.c -index 6cae720e..16e55cbc 100644 ---- a/gss-serv.c -+++ b/gss-serv.c -@@ -320,13 +320,15 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) - } - - /* As user */ --void -+int - ssh_gssapi_storecreds(void) - { - if (gssapi_client.mech && gssapi_client.mech->storecreds) { -- (*gssapi_client.mech->storecreds)(&gssapi_client); -+ return (*gssapi_client.mech->storecreds)(&gssapi_client); - } else - debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); -+ -+ return 0; - } - - /* This allows GSSAPI methods to do things to the childs environment based -@@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() { - char *envstr; - #endif - -- if (gssapi_client.store.filename == NULL && -- gssapi_client.store.envval == NULL && -- gssapi_client.store.envvar == NULL) -+ if (gssapi_client.store.envval == NULL) - return; - - ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); -diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c ---- openssh-7.9p1/servconf.c.ccache_name 2019-03-01 15:17:42.704611768 +0100 -+++ openssh-7.9p1/servconf.c 2019-03-01 15:17:42.713611844 +0100 -@@ -123,6 +123,7 @@ initialize_server_options(ServerOptions +diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c +--- openssh-8.6p1/servconf.c.ccache_name 2021-04-19 14:05:10.848744532 +0200 ++++ openssh-8.6p1/servconf.c 2021-04-19 14:05:10.854744577 +0200 +@@ -136,6 +136,7 @@ initialize_server_options(ServerOptions options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -503,7 +494,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c options->gss_authentication=-1; options->gss_keyex = -1; options->gss_cleanup_creds = -1; -@@ -315,6 +316,8 @@ fill_default_server_options(ServerOptions *options) +@@ -359,6 +360,8 @@ fill_default_server_options(ServerOption options->kerberos_ticket_cleanup = 1; if (options->kerberos_get_afs_token == -1) options->kerberos_get_afs_token = 0; @@ -512,17 +503,17 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_keyex == -1) -@@ -447,7 +450,8 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, sChallengeResponseAuthentication, +@@ -506,7 +509,8 @@ typedef enum { + sPort, sHostKeyFile, sLoginGraceTime, + sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +- sKerberosGetAFSToken, sPasswordAuthentication, + sKerberosGetAFSToken, sKerberosUniqueCCache, -+ sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, - sPrintMotd, sPrintLastLog, sIgnoreRhosts, -@@ -526,11 +530,13 @@ static struct { ++ sPasswordAuthentication, + sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sPrintMotd, sPrintLastLog, sIgnoreRhosts, + sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, +@@ -593,11 +597,13 @@ static struct { #else { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif @@ -536,7 +527,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c #endif { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1437,6 +1443,10 @@ process_server_config_line(ServerOptions *options, char *line, +@@ -1573,6 +1579,10 @@ process_server_config_line_depth(ServerO intptr = &options->kerberos_get_afs_token; goto parse_flag; @@ -547,7 +538,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c case sGssAuthentication: intptr = &options->gss_authentication; goto parse_flag; -@@ -2507,6 +2517,7 @@ dump_config(ServerOptions *o) +@@ -2891,6 +2901,7 @@ dump_config(ServerOptions *o) # ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); # endif @@ -555,11 +546,10 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c #endif #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); -diff --git a/servconf.h b/servconf.h -index db8362c6..4fa42d64 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -123,6 +123,8 @@ typedef struct { +diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h +--- openssh-8.6p1/servconf.h.ccache_name 2021-04-19 14:05:10.848744532 +0200 ++++ openssh-8.6p1/servconf.h 2021-04-19 14:05:10.855744584 +0200 +@@ -140,6 +140,8 @@ typedef struct { * file on logout. */ int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ @@ -568,13 +558,12 @@ index db8362c6..4fa42d64 100644 int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_keyex; /* If true, permit GSSAPI key exchange */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ -diff --git a/session.c b/session.c -index 85df6a27..480a5ead 100644 ---- a/session.c -+++ b/session.c -@@ -1033,7 +1033,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c +--- openssh-8.6p1/session.c.ccache_name 2021-04-19 14:05:10.852744562 +0200 ++++ openssh-8.6p1/session.c 2021-04-19 14:05:10.855744584 +0200 +@@ -1038,7 +1038,8 @@ do_setup_env(struct ssh *ssh, Session *s /* Allow any GSSAPI methods that we've used to alter - * the childs environment as they see fit + * the child's environment as they see fit */ - ssh_gssapi_do_child(&env, &envsize); + if (s->authctxt->krb5_set_env) @@ -582,7 +571,7 @@ index 85df6a27..480a5ead 100644 #endif /* Set basic environment. */ -@@ -1105,7 +1106,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) +@@ -1114,7 +1115,7 @@ do_setup_env(struct ssh *ssh, Session *s } #endif #ifdef KRB5 @@ -591,33 +580,10 @@ index 85df6a27..480a5ead 100644 child_set_env(&env, &envsize, "KRB5CCNAME", s->authctxt->krb5_ccname); #endif -diff --git a/ssh-gss.h b/ssh-gss.h -index 6593e422..245178af 100644 ---- a/ssh-gss.h -+++ b/ssh-gss.h -@@ -83,7 +82,7 @@ typedef struct ssh_gssapi_mech_struct { - int (*dochild) (ssh_gssapi_client *); - int (*userok) (ssh_gssapi_client *, char *); - int (*localname) (ssh_gssapi_client *, char **); -- void (*storecreds) (ssh_gssapi_client *); -+ int (*storecreds) (ssh_gssapi_client *); - int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); - } ssh_gssapi_mech; - -@@ -127,7 +126,7 @@ int ssh_gssapi_userok(char *name); - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); --void ssh_gssapi_storecreds(void); -+int ssh_gssapi_storecreds(void); - const char *ssh_gssapi_displayname(void); - - char *ssh_gssapi_server_mechanisms(void); -diff --git a/sshd.c b/sshd.c -index edbe815c..89514e8a 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -2162,7 +2162,7 @@ main(int ac, char **av) +diff -up openssh-8.6p1/sshd.c.ccache_name openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.ccache_name 2021-04-19 14:05:10.849744540 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 14:05:10.855744584 +0200 +@@ -2284,7 +2284,7 @@ main(int ac, char **av) #ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(authctxt->pw); @@ -626,11 +592,10 @@ index edbe815c..89514e8a 100644 restore_uid(); } #endif -diff --git a/sshd_config.5 b/sshd_config.5 -index c0683d4a..2349f477 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -860,6 +860,14 @@ Specifies whether to automatically destroy the user's ticket cache +diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5 +--- openssh-8.6p1/sshd_config.5.ccache_name 2021-04-19 14:05:10.849744540 +0200 ++++ openssh-8.6p1/sshd_config.5 2021-04-19 14:05:10.856744592 +0200 +@@ -939,6 +939,14 @@ Specifies whether to automatically destr file on logout. The default is .Cm yes . @@ -645,3 +610,24 @@ index c0683d4a..2349f477 100644 .It Cm KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated. +diff -up openssh-8.6p1/ssh-gss.h.ccache_name openssh-8.6p1/ssh-gss.h +--- openssh-8.6p1/ssh-gss.h.ccache_name 2021-04-19 14:05:10.852744562 +0200 ++++ openssh-8.6p1/ssh-gss.h 2021-04-19 14:05:10.855744584 +0200 +@@ -114,7 +114,7 @@ typedef struct ssh_gssapi_mech_struct { + int (*dochild) (ssh_gssapi_client *); + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); +- void (*storecreds) (ssh_gssapi_client *); ++ int (*storecreds) (ssh_gssapi_client *); + int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); + } ssh_gssapi_mech; + +@@ -175,7 +175,7 @@ int ssh_gssapi_userok(char *name, struct + OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); + void ssh_gssapi_do_child(char ***, u_int *); + void ssh_gssapi_cleanup_creds(void); +-void ssh_gssapi_storecreds(void); ++int ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); + + char *ssh_gssapi_server_mechanisms(void); diff --git a/openssh-7.7p1.patch b/openssh-7.7p1.patch index 0bf26bda2b4c3d13b2f38a4cc49ffc6bf911b8a5..fcda6c6dfd00866c04b287acdfcf6174b9d1d4b9 100644 --- a/openssh-7.7p1.patch +++ b/openssh-7.7p1.patch @@ -1,13 +1,16 @@ diff -up openssh/ssh_config.redhat openssh/ssh_config --- openssh/ssh_config.redhat 2020-02-11 23:28:35.000000000 +0100 +++ openssh/ssh_config 2020-02-13 18:13:39.180641839 +0100 -@@ -43,3 +43,7 @@ - # VisualHostKey no +@@ -43,3 +43,10 @@ # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h + # UserKnownHostsFile ~/.ssh/known_hosts.d/%k +# -+# To modify the system-wide ssh configuration, create a *.conf file under -+# /etc/ssh/ssh_config.d/ which will be automatically included below ++# This system is following system-wide crypto policy. ++# To modify the crypto properties (Ciphers, MACs, ...), create a *.conf ++# file under /etc/ssh/ssh_config.d/ which will be automatically ++# included below. For more information, see manual page for ++# update-crypto-policies(8) and ssh_config(5). +Include /etc/ssh/ssh_config.d/*.conf diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat --- openssh/ssh_config_redhat.redhat 2020-02-13 18:13:39.180641839 +0100 @@ -65,10 +68,14 @@ diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5 diff -up openssh/sshd_config.redhat openssh/sshd_config --- openssh/sshd_config.redhat 2020-02-11 23:28:35.000000000 +0100 +++ openssh/sshd_config 2020-02-13 18:20:16.349913681 +0100 -@@ -10,6 +10,10 @@ +@@ -10,6 +10,14 @@ # possible, but leave them commented. Uncommented options override the # default value. - + ++# To modify the system-wide sshd configuration, create a *.conf file under ++# /etc/ssh/sshd_config.d/ which will be automatically included below ++Include /etc/ssh/sshd_config.d/*.conf ++ +# If you want to change the port on a SELinux system, you have to tell +# SELinux about this change. +# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER @@ -76,30 +83,19 @@ diff -up openssh/sshd_config.redhat openssh/sshd_config #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 -@@ -114,3 +118,7 @@ Subsystem sftp /usr/libexec/sftp-server - # AllowTcpForwarding no - # PermitTTY no - # ForceCommand cvs server -+ -+# To modify the system-wide ssh configuration, create a *.conf file under -+# /etc/ssh/sshd_config.d/ which will be automatically included below -+Include /etc/ssh/sshd_config.d/*.conf diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat --- openssh/sshd_config_redhat.redhat 2020-02-13 18:14:02.268006439 +0100 +++ openssh/sshd_config_redhat 2020-02-13 18:19:20.765035947 +0100 -@@ -0,0 +1,31 @@ -+# System-wide Crypto policy: +@@ -0,0 +1,28 @@ +# This system is following system-wide crypto policy. The changes to -+# Ciphers, MACs, KexAlgoritms and GSSAPIKexAlgorithsm will not have any -+# effect here. They will be overridden by command-line options passed on -+# the server start up. -+# To opt out, uncomment a line with redefinition of CRYPTO_POLICY= -+# variable in /etc/sysconfig/sshd to overwrite the policy. -+# For more information, see manual page for update-crypto-policies(8). ++# crypto properties (Ciphers, MACs, ...) will not have any effect in ++# this or following included files. To override some configuration option, ++# write it before this block or include it before this file. ++# Please, see manual pages for update-crypto-policies(8) and sshd_config(5). ++Include /etc/crypto-policies/back-ends/opensshserver.config + +SyslogFacility AUTHPRIV + -+PasswordAuthentication yes +ChallengeResponseAuthentication no + +GSSAPIAuthentication yes diff --git a/openssh-7.8p1-UsePAM-warning.patch b/openssh-7.8p1-UsePAM-warning.patch index d4c53db5c857c658ce2d41c29948f8f65e20c006..8560c9fe1e6257a7b1a5dbaf97af9c7baa20f74e 100644 --- a/openssh-7.8p1-UsePAM-warning.patch +++ b/openssh-7.8p1-UsePAM-warning.patch @@ -1,7 +1,7 @@ -diff --git a/sshd.c b/sshd.c ---- a/sshd.c -+++ b/sshd.c -@@ -1701,6 +1701,10 @@ main(int ac, char **av) +diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c +--- openssh-8.6p1/sshd.c.log-usepam-no 2021-04-19 14:00:45.099735129 +0200 ++++ openssh-8.6p1/sshd.c 2021-04-19 14:03:21.140920974 +0200 +@@ -1749,6 +1749,10 @@ main(int ac, char **av) parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, cfg, &includes, NULL); @@ -9,16 +9,16 @@ diff --git a/sshd.c b/sshd.c + if (! options.use_pam) + logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems."); + - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); - -diff --git a/sshd_config b/sshd_config ---- a/sshd_config -+++ b/sshd_config -@@ -101,6 +101,8 @@ GSSAPICleanupCredentials no + #ifdef WITH_OPENSSL + if (options.moduli_file != NULL) + dh_set_moduli_file(options.moduli_file); +diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config +--- openssh-8.6p1/sshd_config.log-usepam-no 2021-04-19 14:00:45.098735121 +0200 ++++ openssh-8.6p1/sshd_config 2021-04-19 14:00:45.099735129 +0200 +@@ -87,6 +87,8 @@ AuthorizedKeysFile .ssh/authorized_keys # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication - # and ChallengeResponseAuthentication to 'no'. + # and KbdInteractiveAuthentication to 'no'. +# WARNING: 'UsePAM no' is not supported in Fedora and may cause several +# problems. #UsePAM no diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index fb7ce7c71770e394caa30522b2d446f161ecb5e0..48f9f1002d660119c2543a7913b7fa5d3459cd52 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 @@ -154,20 +154,6 @@ diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h char ** fetch_pam_environment(void); char ** fetch_pam_child_environment(void); void free_pam_environment(char **); -diff -up openssh/configure.ac.role-mls openssh/configure.ac ---- openssh/configure.ac.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/configure.ac 2018-08-22 11:14:56.820430957 +0200 -@@ -4241,10 +4241,7 @@ AC_ARG_WITH([selinux], - LIBS="$LIBS -lselinux" - ], - AC_MSG_ERROR([SELinux support requires libselinux library])) -- SSHLIBS="$SSHLIBS $LIBSELINUX" -- SSHDLIBS="$SSHDLIBS $LIBSELINUX" - AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level]) -- LIBS="$save_LIBS" - fi ] - ) - AC_SUBST([SSHLIBS]) diff -up openssh/misc.c.role-mls openssh/misc.c --- openssh/misc.c.role-mls 2018-08-20 07:57:29.000000000 +0200 +++ openssh/misc.c 2018-08-22 11:14:56.817430932 +0200 @@ -193,10 +179,10 @@ diff -up openssh/misc.c.role-mls openssh/misc.c } return NULL; } -diff -up openssh/monitor.c.role-mls openssh/monitor.c ---- openssh/monitor.c.role-mls 2018-08-20 07:57:29.000000000 +0200 -+++ openssh/monitor.c 2018-08-22 11:19:56.006844867 +0200 -@@ -115,6 +115,9 @@ int mm_answer_sign(int, struct sshbuf *) +diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c +--- openssh-8.6p1/monitor.c.role-mls 2021-04-16 05:55:25.000000000 +0200 ++++ openssh-8.6p1/monitor.c 2021-05-21 14:21:56.719414087 +0200 +@@ -117,6 +117,9 @@ int mm_answer_sign(struct ssh *, int, st int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); int mm_answer_authserv(struct ssh *, int, struct sshbuf *); @@ -206,7 +192,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); -@@ -189,6 +192,9 @@ struct mon_table mon_dispatch_proto20[] +@@ -195,6 +198,9 @@ struct mon_table mon_dispatch_proto20[] {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, @@ -216,7 +202,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -796,6 +802,9 @@ mm_answer_pwnamallow(int sock, struct ss +@@ -803,6 +809,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -226,7 +212,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); #ifdef USE_PAM -@@ -842,6 +851,26 @@ mm_answer_authserv(int sock, struct sshb +@@ -877,6 +886,26 @@ key_base_type_match(const char *method, return found; } @@ -238,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); @@ -253,7 +239,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c int mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) { -@@ -1218,7 +1247,7 @@ monitor_valid_userblob(u_char *data, u_i +@@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh, { struct sshbuf *b; const u_char *p; @@ -262,16 +248,16 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c size_t len; u_char type; int r, fail = 0; -@@ -1251,6 +1280,8 @@ monitor_valid_userblob(u_char *data, u_i +@@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh, 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, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); -@@ -1286,7 +1317,7 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1317,7 +1348,7 @@ monitor_valid_hostbasedblob(const u_char { struct sshbuf *b; const u_char *p; @@ -280,11 +266,11 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c size_t len; int r, fail = 0; u_char type; -@@ -1308,6 +1339,8 @@ monitor_valid_hostbasedblob(u_char *data +@@ -1338,6 +1370,8 @@ monitor_valid_hostbasedblob(const u_char fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ if ((s = strchr(p, '/')) != NULL) + fatal_fr(r, "parse userstyle"); ++ if ((s = strchr(cp, '/')) != NULL) + *s = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", @@ -319,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); @@ -338,8 +324,8 @@ diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h --- openssh/monitor_wrap.h.role-mls 2018-08-22 11:14:56.818430941 +0200 +++ openssh/monitor_wrap.h 2018-08-22 11:22:10.439929513 +0200 @@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int); - int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, - const u_char *, size_t, const char *, const char *, u_int compat); + const u_char *, size_t, const char *, const char *, + const char *, u_int compat); void mm_inform_authserv(char *, char *); +#ifdef WITH_SELINUX +void mm_inform_authrole(char *); @@ -351,7 +337,7 @@ diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Make --- openssh/openbsd-compat/Makefile.in.role-mls 2018-08-20 07:57:29.000000000 +0200 +++ openssh/openbsd-compat/Makefile.in 2018-08-22 11:14:56.819430949 +0200 @@ -92,7 +92,8 @@ PORTS= port-aix.o \ - port-linux.o \ + port-prngd.o \ port-solaris.o \ port-net.o \ - port-uw.o @@ -371,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; @@ -407,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; + } + @@ -432,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 @@ -544,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"); @@ -706,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); + + } + @@ -734,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 @@ -760,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); + @@ -797,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 + } @@ -837,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) @@ -852,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 d47880a197843b1fc7ab803af7e3851c94c88c44..0000000000000000000000000000000000000000 --- a/openssh-7.9p1-ssh-copy-id.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff -up openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id openssh-7.9p1/contrib/ssh-copy-id ---- openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id 2018-10-17 02:01:20.000000000 +0200 -+++ openssh-7.9p1/contrib/ssh-copy-id 2019-01-23 20:49:30.513393667 +0100 -@@ -112,7 +112,8 @@ do - usage - } - -- OPT= OPTARG= -+ OPT= -+ OPTARG= - # implement something like getopt to avoid Solaris pain - case "$1" in - -i?*|-o?*|-p?*) -@@ -261,7 +262,7 @@ populate_new_ids() { - fi - if [ -z "$NEW_IDS" ] ; then - printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 -- printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2 -+ printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' >&2 - exit 0 - fi - printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 -@@ -296,7 +297,7 @@ case "$REMOTE_VERSION" in - # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; - # 'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh. - [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ -- ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ -+ ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys || exit 1; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ - || exit 1 - ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) - ;; diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index 89bd369aff3e29dd98e3ecb61aeaf87f3c516809..2ad438c1100d23ad7b20ee538a57755d237a66ff 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -1,29 +1,60 @@ -diff -up openssh/ssh_config.5.crypto-policies openssh/ssh_config.5 ---- openssh/ssh_config.5.crypto-policies 2020-02-07 15:05:55.665451715 +0100 -+++ openssh/ssh_config.5 2020-02-07 15:07:11.632641922 +0100 -@@ -361,15 +361,15 @@ domains. +diff -up openssh-8.7p1/ssh_config.5.crypto-policies openssh-8.7p1/ssh_config.5 +--- openssh-8.7p1/ssh_config.5.crypto-policies 2021-08-30 13:29:00.174292872 +0200 ++++ openssh-8.7p1/ssh_config.5 2021-08-30 13:31:32.009548808 +0200 +@@ -373,17 +373,13 @@ or + causes no CNAMEs to be considered for canonicalization. + This is the default behaviour. .It Cm CASignatureAlgorithms ++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 which algorithms are allowed for signing of certificates 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, +-sk-ssh-ed25519@openssh.com, +-sk-ecdsa-sha2-nistp256@openssh.com, +-rsa-sha2-512,rsa-sha2-256 -.Ed -.Pp - .Xr ssh 1 - will not accept host certificates signed using algorithms other than those - specified. -+.Pp + If the specified list begins with a + .Sq + + character, then the specified algorithms will be appended to the default set +@@ -445,20 +441,25 @@ If the option is set to + (the default), + the check will not be executed. + .It Cm Ciphers +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 - .It Cm CertificateFile - Specifies a file from which the user's certificate is read. - A corresponding private key must be provided separately in order -@@ -453,12 +453,10 @@ aes256-gcm@openssh.com + Specifies the ciphers allowed and their order of preference. + Multiple ciphers must be comma-separated. + If the specified list begins with a + .Sq + +-character, then the specified ciphers will be appended to the default set +-instead of replacing them. ++character, then the specified ciphers 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 ciphers (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 ciphers will be placed at the head of the +-default set. ++built-in openssh default set. + .Pp + The supported ciphers are: + .Bd -literal -offset indent +@@ -474,13 +475,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .Ed .Pp @@ -33,30 +64,60 @@ diff -up openssh/ssh_config.5.crypto-policies openssh/ssh_config.5 -aes128-ctr,aes192-ctr,aes256-ctr, -aes128-gcm@openssh.com,aes256-gcm@openssh.com -.Ed +-.Pp + The list of available ciphers may also be obtained using + .Qq ssh -Q cipher . + .It Cm ClearAllForwardings +@@ -874,6 +868,11 @@ command line will be passed untouched to + The default is + .Dq no . + .It Cm GSSAPIKexAlgorithms +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 - The list of available ciphers may also be obtained using - .Qq ssh -Q cipher . -@@ -824,8 +822,10 @@ gss-nistp256-sha256-, ++.Pp + The list of key exchange algorithms that are offered for GSSAPI + key exchange. Possible values are + .Bd -literal -offset 3n +@@ -886,10 +885,8 @@ gss-nistp256-sha256-, gss-curve25519-sha256- .Ed .Pp -The default is --.Dq gss-gex-sha1-,gss-group14-sha1- . +-.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 HashKnownHosts + Indicates that + .Xr ssh 1 +@@ -1219,29 +1216,25 @@ it may be zero or more of: + and + .Cm pam . + .It Cm KexAlgorithms +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 . - This option only applies to protocol version 2 connections using GSSAPI. - .It Cm HashKnownHosts - Indicates that -@@ -1162,15 +1162,10 @@ If the specified list begins with a ++.Pp + Specifies the available KEX (Key Exchange) algorithms. + Multiple algorithms must be comma-separated. + If the specified list begins with a + .Sq + +-character, then the specified algorithms will be appended to the default set +-instead of replacing them. ++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 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 methods will be placed at the head of the - default set. + character, then the specified algorithms will be placed at the head of the +-default set. -The default is: -.Bd -literal -offset indent -curve25519-sha256,curve25519-sha256@libssh.org, @@ -66,14 +127,42 @@ diff -up openssh/ssh_config.5.crypto-policies openssh/ssh_config.5 -diffie-hellman-group18-sha512, -diffie-hellman-group14-sha256 -.Ed ++built-in openssh default set. + .Pp + The list of available key exchange algorithms may also be obtained using + .Qq ssh -Q kex . +@@ -1351,37 +1344,33 @@ function, and all code in the + 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 . +To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . ++.Pp + Specifies the MAC (message authentication code) algorithms + in order of preference. + The MAC algorithm is used for data integrity protection. + Multiple algorithms must be comma-separated. + If the specified list begins with a + .Sq + +-character, then the specified algorithms will be appended to the default set +-instead of replacing them. ++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 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 algorithms will be placed at the head of the +-default set. ++built-in openssh default set. .Pp - The list of available key exchange algorithms may also be obtained using - .Qq ssh -Q kex . -@@ -1252,14 +1247,10 @@ The algorithms that contain + The algorithms that contain + .Qq -etm calculate the MAC after encryption (encrypt-then-mac). These are considered safer and their use recommended. .Pp @@ -85,65 +174,113 @@ diff -up openssh/ssh_config.5.crypto-policies openssh/ssh_config.5 -umac-64@openssh.com,umac-128@openssh.com, -hmac-sha2-256,hmac-sha2-512,hmac-sha1 -.Ed +-.Pp + The list of available MAC algorithms may also be obtained using + .Qq ssh -Q mac . + .It Cm NoHostAuthenticationForLocalhost +@@ -1553,36 +1542,25 @@ instead of continuing to execute and pas + The default is + .Cm no . + .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 - The list of available MAC algorithms may also be obtained using - .Qq ssh -Q mac . -@@ -1407,22 +1398,10 @@ If the specified list begins with a ++.Pp + 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 algorithms after it will be appended to the default +-instead of replacing it. ++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 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 - default set. + 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 +-rsa-sha2-512,rsa-sha2-256 -.Ed ++built-in openssh default set. + .Pp + The list of available signature algorithms may also be obtained using + .Qq ssh -Q PubkeyAcceptedAlgorithms . +diff -up openssh-8.7p1/sshd_config.5.crypto-policies openssh-8.7p1/sshd_config.5 +--- openssh-8.7p1/sshd_config.5.crypto-policies 2021-08-30 13:29:00.157292731 +0200 ++++ openssh-8.7p1/sshd_config.5 2021-08-30 13:32:16.263918533 +0200 +@@ -373,17 +373,13 @@ If the argument is + then no banner is displayed. + By default, no banner is displayed. + .It Cm CASignatureAlgorithms +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 - The list of available key types may also be obtained using - .Qq ssh -Q PubkeyAcceptedKeyTypes . -diff -up openssh/sshd_config.5.crypto-policies openssh/sshd_config.5 ---- openssh/sshd_config.5.crypto-policies 2020-02-07 15:05:55.639451308 +0100 -+++ openssh/sshd_config.5 2020-02-07 15:05:55.672451825 +0100 -@@ -377,14 +377,14 @@ By default, no banner is displayed. - .It Cm CASignatureAlgorithms ++.Pp Specifies which algorithms are allowed for signing of certificates 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, +-sk-ssh-ed25519@openssh.com, +-sk-ecdsa-sha2-nistp256@openssh.com, +-rsa-sha2-512,rsa-sha2-256 -.Ed -.Pp - Certificates signed using other algorithms will not be accepted for - public key or host-based authentication. -+.Pp + If the specified list begins with a + .Sq + + character, then the specified algorithms will be appended to the default set +@@ -450,20 +446,25 @@ The default is + indicating not to + .Xr chroot 2 . + .It Cm Ciphers +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 - .It Cm ChallengeResponseAuthentication - Specifies whether challenge-response authentication is allowed (e.g. via - PAM or through authentication styles supported in -@@ -486,12 +486,10 @@ aes256-gcm@openssh.com + Specifies the ciphers allowed. + Multiple ciphers must be comma-separated. + If the specified list begins with a + .Sq + +-character, then the specified ciphers will be appended to the default set +-instead of replacing them. ++character, then the specified ciphers 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 ciphers (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 ciphers will be placed at the head of the +-default set. ++built-in openssh default set. + .Pp + The supported ciphers are: + .Pp +@@ -490,13 +491,6 @@ aes256-gcm@openssh.com chacha20-poly1305@openssh.com .El .Pp @@ -153,55 +290,107 @@ diff -up openssh/sshd_config.5.crypto-policies openssh/sshd_config.5 -aes128-ctr,aes192-ctr,aes256-ctr, -aes128-gcm@openssh.com,aes256-gcm@openssh.com -.Ed +-.Pp + The list of available ciphers may also be obtained using + .Qq ssh -Q cipher . + .It Cm ClientAliveCountMax +@@ -685,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 +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 - The list of available ciphers may also be obtained using - .Qq ssh -Q cipher . -@@ -693,8 +691,10 @@ gss-nistp256-sha256-, ++.Pp + The list of key exchange algorithms that are accepted by GSSAPI + key exchange. Possible values are + .Bd -literal -offset 3n +-gss-gex-sha1-, +-gss-group1-sha1-, +-gss-group14-sha1-, +-gss-group14-sha256-, +-gss-group16-sha512-, +-gss-nistp256-sha256-, ++gss-gex-sha1- ++gss-group1-sha1- ++gss-group14-sha1- ++gss-group14-sha256- ++gss-group16-sha512- ++gss-nistp256-sha256- gss-curve25519-sha256- .Ed - .Pp +-.Pp -The default is --.Dq gss-gex-sha1-,gss-group14-sha1- . +-.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 HostbasedAcceptedAlgorithms + Specifies the signature algorithms that will be accepted for hostbased +@@ -799,26 +794,13 @@ is specified, the location of the socket + .Ev SSH_AUTH_SOCK + environment variable. + .It Cm HostKeyAlgorithms +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 . - This option only applies to protocol version 2 connections using GSSAPI. - .It Cm HostbasedAcceptedKeyTypes - Specifies the key types that will be accepted for hostbased authentication -@@ -794,22 +794,10 @@ environment variable. - .It Cm HostKeyAlgorithms - Specifies the host key algorithms ++.Pp + 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 signature algorithms may also be obtained using + .Qq ssh -Q HostKeyAlgorithms . + .It Cm IgnoreRhosts +@@ -965,20 +947,25 @@ Specifies whether to look at .k5login fi + The default is + .Cm yes . + .It Cm KexAlgorithms +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 available KEX (Key Exchange) algorithms. + Multiple algorithms must be comma-separated. + Alternately if the specified list begins with a + .Sq + +-character, then the specified algorithms will be appended to the default set +-instead of replacing them. ++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 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 algorithms will be placed at the head of the +-default set. ++built-in openssh default set. + The supported algorithms are: .Pp - The list of available key types may also be obtained using - .Qq ssh -Q HostKeyAlgorithms . -@@ -987,14 +975,10 @@ ecdh-sha2-nistp521 - sntrup4591761x25519-sha512@tinyssh.org + .Bl -item -compact -offset indent +@@ -1010,15 +997,6 @@ ecdh-sha2-nistp521 + sntrup761x25519-sha512@openssh.com .El .Pp -The default is: @@ -212,14 +401,42 @@ diff -up openssh/sshd_config.5.crypto-policies openssh/sshd_config.5 -diffie-hellman-group16-sha512,diffie-hellman-group18-sha512, -diffie-hellman-group14-sha256 -.Ed +-.Pp + The list of available key exchange algorithms may also be obtained using + .Qq ssh -Q KexAlgorithms . + .It Cm ListenAddress +@@ -1104,21 +1082,26 @@ function, and all code in the + 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 . +To see the defaults and how to modify this default, see manual page +.Xr update-crypto-policies 8 . ++.Pp + Specifies the available MAC (message authentication code) algorithms. + The MAC algorithm is used for data integrity protection. + Multiple algorithms must be comma-separated. + If the specified list begins with a + .Sq + +-character, then the specified algorithms will be appended to the default set +-instead of replacing them. ++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 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 algorithms will be placed at the head of the +-default set. ++built-in openssh default set. .Pp - The list of available key exchange algorithms may also be obtained using - .Qq ssh -Q KexAlgorithms . -@@ -1121,14 +1105,10 @@ umac-64-etm@openssh.com + The algorithms that contain + .Qq -etm +@@ -1161,15 +1144,6 @@ umac-64-etm@openssh.com umac-128-etm@openssh.com .El .Pp @@ -231,37 +448,54 @@ diff -up openssh/sshd_config.5.crypto-policies openssh/sshd_config.5 -umac-64@openssh.com,umac-128@openssh.com, -hmac-sha2-256,hmac-sha2-512,hmac-sha1 -.Ed +-.Pp + The list of available MAC algorithms may also be obtained using + .Qq ssh -Q mac . + .It Cm Match +@@ -1548,37 +1522,25 @@ or equivalent.) + The default is + .Cm yes . + .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 - The list of available MAC algorithms may also be obtained using - .Qq ssh -Q mac . -@@ -1492,22 +1472,10 @@ If the specified list begins with a ++.Pp + 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 algorithms will be appended to the default set +-instead of replacing them. ++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 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 - default set. + 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 -+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 . ++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 9e7ea7256c981c6f609b0e0b55d2e86a59e86213..e26bebdae03254946f6534bd8445d088bf1fdb5a 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,13 +17,12 @@ 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 ---- a/auth.c -+++ b/auth.c -@@ -400,7 +400,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) +diff -up a/auth.c.gsskex b/auth.c +--- a/auth.c.gsskex 2021-08-20 06:03:49.000000000 +0200 ++++ b/auth.c 2021-08-27 12:41:51.262788953 +0200 +@@ -402,7 +402,8 @@ auth_root_allowed(struct ssh *ssh, const case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -33,18 +32,15 @@ index 086b8ebb..687c57b4 100644 return 1; break; case PERMIT_FORCED_ONLY: -@@ -724,99 +725,6 @@ fakepw(void) - return (&fake); +@@ -730,97 +731,6 @@ fakepw(void) } --/* + /* - * Returns the remote DNS hostname as a string. The returned string must not - * be freed. NB. this will usually trigger a DNS query the first time it is - * called. - * This function does additional checks on the hostname to mitigate some -- * attacks on legacy rhosts-style authentication. -- * XXX is RhostsRSAAuthentication vulnerable to these? -- * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) +- * attacks on based on conflation of hostnames and IP addresses. - */ - -static char * @@ -130,15 +126,16 @@ index 086b8ebb..687c57b4 100644 - return xstrdup(name); -} - - /* +-/* * Return the canonical name of the host in the other side of the current * connection. The host name is cached, so it is efficient to call this + * several times. diff --git a/auth2-gss.c b/auth2-gss.c 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 +162,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 +194,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 +438,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 +446,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 +458,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 +480,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 +542,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 +559,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 +574,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 +590,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 +712,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, } @@ -964,7 +955,7 @@ index ab3a15f0..6ce56e92 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,7 +1,7 @@ - /* $OpenBSD: gss-serv.c,v 1.31 2018/07/09 21:37:55 markus Exp $ */ + /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -1123,10 +1114,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 +1366,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 +1380,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 +1489,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 +1588,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 +1776,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 +2065,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 +2186,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 +2226,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 +2382,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 +2625,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 +2676,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 +2691,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 +2705,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 +2717,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 +2733,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 +2757,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 +2778,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 +2793,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 +2830,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 +2849,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 +2872,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 +2880,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); + @@ -2927,10 +2910,9 @@ index 23ab096a..485590c1 100644 #endif #ifdef USE_PAM -diff --git a/readconf.c b/readconf.c -index f3cac6b3..da8022dd 100644 ---- a/readconf.c -+++ b/readconf.c +diff -up a/readconf.c.gsskex b/readconf.c +--- a/readconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 ++++ b/readconf.c 2021-08-27 12:25:42.556421509 +0200 @@ -67,6 +67,7 @@ #include "uidswap.h" #include "myproposal.h" @@ -2939,7 +2921,7 @@ index f3cac6b3..da8022dd 100644 /* Format of the configuration file: -@@ -160,6 +161,8 @@ typedef enum { +@@ -161,6 +162,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -2948,7 +2930,7 @@ index f3cac6b3..da8022dd 100644 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -204,10 +207,22 @@ static struct { +@@ -206,10 +209,22 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -2971,7 +2953,7 @@ index f3cac6b3..da8022dd 100644 #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1029,10 +1044,42 @@ parse_time: +@@ -1113,10 +1128,42 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -3000,7 +2982,7 @@ index f3cac6b3..da8022dd 100644 + goto parse_flag; + + case oGssKexAlgorithms: -+ arg = strdelim(&s); ++ arg = argv_next(&ac, &av); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); @@ -3014,9 +2996,9 @@ index f3cac6b3..da8022dd 100644 case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1911,7 +1958,13 @@ initialize_options(Options * options) +@@ -2306,7 +2353,13 @@ initialize_options(Options * options) + options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; - options->challenge_response_authentication = -1; options->gss_authentication = -1; + options->gss_keyex = -1; options->gss_deleg_creds = -1; @@ -3028,8 +3010,8 @@ index f3cac6b3..da8022dd 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2059,8 +2112,18 @@ fill_default_options(Options * options) - options->challenge_response_authentication = 1; +@@ -2463,8 +2516,18 @@ fill_default_options(Options * options) + options->pubkey_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; + if (options->gss_keyex == -1) @@ -3047,7 +3029,7 @@ index f3cac6b3..da8022dd 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -2702,7 +2765,14 @@ dump_client_config(Options *o, const char *host) +@@ -3246,7 +3309,14 @@ dump_client_config(Options *o, const cha dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -3062,13 +3044,12 @@ index f3cac6b3..da8022dd 100644 #endif /* GSSAPI */ dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); -diff --git a/readconf.h b/readconf.h -index feedb3d2..a8a8870d 100644 ---- a/readconf.h -+++ b/readconf.h -@@ -41,7 +41,13 @@ typedef struct { - int challenge_response_authentication; - /* Try S/Key or TIS, authentication. */ +diff -up a/readconf.h.gsskex b/readconf.h +--- a/readconf.h.gsskex 2021-08-27 12:05:29.248142431 +0200 ++++ b/readconf.h 2021-08-27 12:22:19.270679852 +0200 +@@ -39,7 +39,13 @@ typedef struct { + int pubkey_authentication; /* Try ssh2 pubkey authentication. */ + int hostbased_authentication; /* ssh2's rhosts_rsa */ int gss_authentication; /* Try GSS authentication */ + int gss_keyex; /* Try GSS key exchange */ int gss_deleg_creds; /* Delegate GSS credentials */ @@ -3080,11 +3061,10 @@ index feedb3d2..a8a8870d 100644 int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff --git a/servconf.c b/servconf.c -index 70f5f73f..191575a1 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -69,6 +69,7 @@ +diff -up a/servconf.c.gsskex b/servconf.c +--- a/servconf.c.gsskex 2021-08-20 06:03:49.000000000 +0200 ++++ b/servconf.c 2021-08-27 12:28:15.887735189 +0200 +@@ -70,6 +70,7 @@ #include "auth.h" #include "myproposal.h" #include "digest.h" @@ -3092,7 +3072,7 @@ index 70f5f73f..191575a1 100644 static void add_listen_addr(ServerOptions *, const char *, const char *, int); -@@ -133,8 +134,11 @@ initialize_server_options(ServerOptions *options) +@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3103,8 +3083,8 @@ index 70f5f73f..191575a1 100644 + options->gss_kex_algorithms = NULL; options->password_authentication = -1; options->kbd_interactive_authentication = -1; - options->challenge_response_authentication = -1; -@@ -375,10 +379,18 @@ fill_default_server_options(ServerOptions *options) + options->permit_empty_passwd = -1; +@@ -356,10 +360,18 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3123,15 +3103,15 @@ index 70f5f73f..191575a1 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -531,6 +543,7 @@ typedef enum { - sHostKeyAlgorithms, +@@ -506,6 +518,7 @@ typedef enum { + sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -607,12 +620,22 @@ static struct { +@@ -587,12 +600,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3153,8 +3133,8 @@ index 70f5f73f..191575a1 100644 + { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, - { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1548,6 +1571,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, + { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ +@@ -1576,6 +1599,10 @@ process_server_config_line_depth(ServerO intptr = &options->gss_authentication; goto parse_flag; @@ -3165,7 +3145,7 @@ index 70f5f73f..191575a1 100644 case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1556,6 +1583,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1584,6 +1611,22 @@ process_server_config_line_depth(ServerO intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3174,7 +3154,7 @@ index 70f5f73f..191575a1 100644 + goto parse_flag; + + case sGssKexAlgorithms: -+ arg = strdelim(&cp); ++ arg = argv_next(&ac, &av); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); @@ -3188,7 +3168,7 @@ index 70f5f73f..191575a1 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2777,6 +2820,10 @@ dump_config(ServerOptions *o) +@@ -2892,6 +2935,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -3246,14 +3226,14 @@ 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. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -61,10 +61,30 @@ +@@ -61,10 +61,34 @@ #define SSH_GSS_OIDTYPE 0x06 @@ -3273,8 +3253,12 @@ index 36180d07..70dd3665 100644 +#define KEX_GSS_C25519_SHA256_ID "gss-curve25519-sha256-" + +#define GSS_KEX_DEFAULT_KEX \ -+ KEX_GSS_GEX_SHA1_ID "," \ -+ KEX_GSS_GRP14_SHA1_ID ++ KEX_GSS_GRP14_SHA256_ID "," \ ++ KEX_GSS_GRP16_SHA512_ID "," \ ++ KEX_GSS_NISTP256_SHA256_ID "," \ ++ KEX_GSS_C25519_SHA256_ID "," \ ++ KEX_GSS_GRP14_SHA1_ID "," \ ++ KEX_GSS_GEX_SHA1_ID + typedef struct { char *filename; @@ -3328,7 +3312,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 *); @@ -3378,7 +3362,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 @@ -3429,7 +3413,7 @@ diff --git a/ssh_config.5 b/ssh_config.5 index 06a32d31..3f490697 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -766,10 +766,67 @@ The default is +@@ -766,10 +766,68 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . @@ -3492,8 +3476,9 @@ index 06a32d31..3f490697 100644 +.Ed +.Pp +The default is -+.Dq gss-gex-sha1-,gss-group14-sha1- . -+This option only applies to protocol version 2 connections using GSSAPI. ++.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 HashKnownHosts Indicates that .Xr ssh 1 @@ -3521,9 +3506,9 @@ index af00fb30..03bc87eb 100644 + xxx_host = host; xxx_hostaddr = hostaddr; - -@@ -206,6 +209,35 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) - compat_pkalg_proposal(options.hostkeyalgorithms); + xxx_conn_info = cinfo; +@@ -206,6 +209,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) + compat_pkalg_proposal(ssh, options.hostkeyalgorithms); } +#if defined(GSSAPI) && defined(WITH_OPENSSL) @@ -3532,12 +3517,19 @@ index af00fb30..03bc87eb 100644 + * client to the key exchange algorithm proposal */ + orig = myproposal[PROPOSAL_KEX_ALGS]; + -+ if (options.gss_server_identity) ++ if (options.gss_server_identity) { + gss_host = xstrdup(options.gss_server_identity); -+ else if (options.gss_trust_dns) ++ } else if (options.gss_trust_dns) { + gss_host = remote_hostname(ssh); -+ else ++ /* Fall back to specified host if we are using proxy command ++ * and can not use DNS on that socket */ ++ if (strcmp(gss_host, "UNKNOWN") == 0) { ++ free(gss_host); ++ gss_host = xstrdup(host); ++ } ++ } else { + gss_host = xstrdup(host); ++ } + + gss = ssh_gssapi_client_mechanisms(gss_host, + options.gss_client_identity, options.gss_kex_algorithms); @@ -3576,7 +3568,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) @@ -3592,7 +3584,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 */ @@ -3604,7 +3596,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 *); @@ -3626,18 +3618,25 @@ index af00fb30..03bc87eb 100644 {"gssapi-with-mic", userauth_gssapi, userauth_gssapi_cleanup, -@@ -716,12 +784,25 @@ userauth_gssapi(struct ssh *ssh) +@@ -716,12 +784,32 @@ userauth_gssapi(struct ssh *ssh) OM_uint32 min; int r, ok = 0; gss_OID mech = NULL; -+ char *gss_host; ++ char *gss_host = NULL; + -+ if (options.gss_server_identity) ++ if (options.gss_server_identity) { + gss_host = xstrdup(options.gss_server_identity); -+ else if (options.gss_trust_dns) ++ } else if (options.gss_trust_dns) { + gss_host = remote_hostname(ssh); -+ else ++ /* Fall back to specified host if we are using proxy command ++ * and can not use DNS on that socket */ ++ if (strcmp(gss_host, "UNKNOWN") == 0) { ++ free(gss_host); ++ gss_host = xstrdup(authctxt->host); ++ } ++ } else { + gss_host = xstrdup(authctxt->host); ++ } /* Try one GSSAPI method at a time, rather than sending them all at * once. */ @@ -3695,13 +3694,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))) { @@ -3715,7 +3714,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); @@ -3732,11 +3731,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); @@ -3753,7 +3752,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) + { @@ -3799,7 +3798,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; @@ -3818,7 +3817,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 @@ -3849,7 +3848,7 @@ index 70ccea44..f6b41a2f 100644 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -660,6 +665,31 @@ machine's default store. +@@ -660,6 +665,32 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Cm yes . @@ -3876,11 +3875,12 @@ index 70ccea44..f6b41a2f 100644 +.Ed +.Pp +The default is -+.Dq gss-gex-sha1-,gss-group14-sha1- . -+This option only applies to protocol version 2 connections using GSSAPI. - .It Cm HostbasedAcceptedKeyTypes - Specifies the key types that will be accepted for hostbased authentication - as a list of comma-separated patterns. ++.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 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-keygen-strip-doseol.patch b/openssh-8.0p1-keygen-strip-doseol.patch new file mode 100644 index 0000000000000000000000000000000000000000..3117a7afa0bf83485f56d50d05e061f5ba60f660 --- /dev/null +++ b/openssh-8.0p1-keygen-strip-doseol.patch @@ -0,0 +1,12 @@ +diff -up openssh-8.0p1/ssh-keygen.c.strip-doseol openssh-8.0p1/ssh-keygen.c +--- openssh-8.0p1/ssh-keygen.c.strip-doseol 2021-03-18 17:41:34.472404994 +0100 ++++ openssh-8.0p1/ssh-keygen.c 2021-03-18 17:41:55.255538761 +0100 +@@ -901,7 +901,7 @@ do_fingerprint(struct passwd *pw) + while (getline(&line, &linesize, f) != -1) { + lnum++; + cp = line; +- cp[strcspn(cp, "\n")] = '\0'; ++ cp[strcspn(cp, "\r\n")] = '\0'; + /* Trim leading space and comments */ + cp = line + strspn(line, " \t"); + if (*cp == '#' || *cp == '\0') diff --git a/openssh-8.0p1-openssl-kdf.patch b/openssh-8.0p1-openssl-kdf.patch index 1db95c32e0884103c40db09893e74bb67250ea7b..5d76a4f97f58261c0fec698e515f2d5be930d01b 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 712f703bdb88f29ef9eabdcb55a8b5065104fa29..859260791dcfc7e6a703b14bc38cbe6600283a19 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,112 +1,7 @@ -commit ed3eaf7d68c083b6015ca3425b75932999dafaad -Author: Jakub Jelen -Date: Wed Apr 24 17:23:21 2019 +0200 - - PKCS#11 URI from Fedora - - * Print PKCS#11 URIs from ssh-keygen - * Accept PKCS#11 URIs in -i argument to ssh - * Allow PKCS#11 URI specification in ssh_config - * Fallback to p11-kit-proxy - * PKCS#11 URI support for ssh-add and ssh-agent - * internal representation is URI - * Allow to specify pin-value in URI to avoid interactive prompts - - Currently recognized and used parts of PKCS#11 URI: - * path (optional) - * token - * id - * manufacturer - * (library-manufacturer) - * query (optional) - * module-path - * pin-value - - Unit test for PKCS#11 URIs - - * test PKCS#11 URI parser, generator - * test percent_encodeer and decoder - - Regression tests for PKCS#11 URI support - - * soft-pkcs11.so from people.su.se/~lha/soft-pkcs11 - * Return correct CKR for unknown attributes - * Adjust and build it with regress tests (allowing agent-pkcs11 test) - * Test PKCS#11 URIs support with soft-pkcs11 - * Direct usage from commandline (URI, provider and combination) - * Usage from configuration files - * Usage in ssh-agent (add, sign, remove) - * Make sure it is built with correct paths - -diff --git a/Makefile.in b/Makefile.in -index e7549470..4511f82a 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -102,7 +102,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ - ssh-ed25519-sk.o ssh-rsa.o dh.o \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ -- ssh-pkcs11.o smult_curve25519_ref.o \ -+ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ - poly1305.o chacha.o cipher-chachapoly.o \ - ssh-ed25519.o digest-openssl.o digest-libc.o \ - hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ -@@ -289,6 +289,8 @@ clean: regressclean - rm -f regress/unittests/match/test_match$(EXEEXT) - rm -f regress/unittests/utf8/*.o - rm -f regress/unittests/utf8/test_utf8$(EXEEXT) -+ rm -f regress/unittests/pkcs11/*.o -+ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) - rm -f regress/misc/kexfuzz/*.o - rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) - rm -f regress/misc/sk-dummy/*.o -@@ -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) -@@ -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 ] || \ -@@ -617,6 +622,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ - regress/unittests/test_helper/libtest_helper.a \ - -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) - -+UNITTESTS_TEST_PKCS11_OBJS=\ -+ regress/unittests/pkcs11/tests.o -+ -+regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ -+ ${UNITTESTS_TEST_PKCS11_OBJS} \ -+ regress/unittests/test_helper/libtest_helper.a libssh.a -+ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ -+ regress/unittests/test_helper/libtest_helper.a \ -+ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -+ - MISC_KEX_FUZZ_OBJS=\ - regress/misc/kexfuzz/kexfuzz.o \ - $(SKOBJS) -@@ -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 -diff --git a/configure.ac b/configure.ac -index b689db4b..98d3ce4f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1911,12 +1911,14 @@ AC_LINK_IFELSE( +diff -up openssh-8.7p1/configure.ac.pkcs11-uri openssh-8.7p1/configure.ac +--- openssh-8.7p1/configure.ac.pkcs11-uri 2021-08-30 13:07:43.646699953 +0200 ++++ openssh-8.7p1/configure.ac 2021-08-30 13:07:43.662700088 +0200 +@@ -1985,12 +1985,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -121,7 +16,7 @@ index b689db4b..98d3ce4f 100644 fi ] ) -@@ -1945,6 +1947,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) +@@ -2019,6 +2021,40 @@ AC_SEARCH_LIBS([dlopen], [dl]) AC_CHECK_FUNCS([dlopen]) AC_CHECK_DECL([RTLD_NOW], [], [], [#include ]) @@ -162,7 +57,7 @@ index b689db4b..98d3ce4f 100644 # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5401,6 +5437,7 @@ echo " BSD Auth support: $BSD_AUTH_MSG" +@@ -5624,6 +5660,7 @@ echo " BSD Auth support echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" echo " PKCS#11 support: $enable_pkcs11" @@ -170,11 +65,87 @@ index b689db4b..98d3ce4f 100644 echo " U2F/FIDO support: $enable_sk" echo "" -diff --git a/regress/Makefile b/regress/Makefile -index 774c10d4..6bf3b627 100644 ---- a/regress/Makefile -+++ b/regress/Makefile -@@ -116,7 +116,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ +diff -up openssh-8.7p1/Makefile.in.pkcs11-uri openssh-8.7p1/Makefile.in +--- openssh-8.7p1/Makefile.in.pkcs11-uri 2021-08-30 13:07:43.571699324 +0200 ++++ openssh-8.7p1/Makefile.in 2021-08-30 13:07:43.663700096 +0200 +@@ -103,7 +103,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ + ssh-ed25519-sk.o ssh-rsa.o dh.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ +- ssh-pkcs11.o smult_curve25519_ref.o \ ++ ssh-pkcs11.o ssh-pkcs11-uri.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o \ + hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ +@@ -302,6 +302,8 @@ clean: regressclean + rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT) + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8$(EXEEXT) ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11$(EXEEXT) + rm -f regress/misc/sk-dummy/*.o + rm -f regress/misc/sk-dummy/*.lo + rm -f regress/misc/sk-dummy/sk-dummy.so +@@ -339,6 +341,8 @@ distclean: regressclean + rm -f regress/unittests/sshsig/test_sshsig + rm -f regress/unittests/utf8/*.o + rm -f regress/unittests/utf8/test_utf8 ++ rm -f regress/unittests/pkcs11/*.o ++ rm -f regress/unittests/pkcs11/test_pkcs11 + (cd openbsd-compat && $(MAKE) distclean) + if test -d pkg ; then \ + rm -fr pkg ; \ +@@ -513,6 +517,7 @@ regress-prep: + $(MKDIR_P) `pwd`/regress/unittests/sshkey + $(MKDIR_P) `pwd`/regress/unittests/sshsig + $(MKDIR_P) `pwd`/regress/unittests/utf8 ++ $(MKDIR_P) `pwd`/regress/unittests/pkcs11 + $(MKDIR_P) `pwd`/regress/misc/sk-dummy + [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile +@@ -677,6 +682,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + ++UNITTESTS_TEST_PKCS11_OBJS=\ ++ regress/unittests/pkcs11/tests.o ++ ++regress/unittests/pkcs11/test_pkcs11$(EXEEXT): \ ++ ${UNITTESTS_TEST_PKCS11_OBJS} \ ++ regress/unittests/test_helper/libtest_helper.a libssh.a ++ $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_PKCS11_OBJS) \ ++ regress/unittests/test_helper/libtest_helper.a \ ++ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) ++ + # These all need to be compiled -fPIC, so they are treated differently. + SK_DUMMY_OBJS=\ + regress/misc/sk-dummy/sk-dummy.lo \ +@@ -711,7 +726,8 @@ regress-unit-binaries: regress-prep $(RE + regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ + regress/unittests/sshkey/test_sshkey$(EXEEXT) \ + regress/unittests/sshsig/test_sshsig$(EXEEXT) \ +- regress/unittests/utf8/test_utf8$(EXEEXT) ++ regress/unittests/utf8/test_utf8$(EXEEXT) \ ++ regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ + + tests: file-tests t-exec interop-tests unit + echo all tests passed +diff -up openssh-8.7p1/regress/agent-pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/agent-pkcs11.sh +--- openssh-8.7p1/regress/agent-pkcs11.sh.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/regress/agent-pkcs11.sh 2021-08-30 13:07:43.663700096 +0200 +@@ -113,7 +113,7 @@ else + done + + trace "remove pkcs11 keys" +- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 ++ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-add -e failed: exit code $r" +diff -up openssh-8.7p1/regress/Makefile.pkcs11-uri openssh-8.7p1/regress/Makefile +--- openssh-8.7p1/regress/Makefile.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/regress/Makefile 2021-08-30 13:07:43.663700096 +0200 +@@ -122,7 +122,8 @@ CLEANFILES= *.core actual agent-key.* au known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ pidfile putty.rsa2 ready regress.log remote_pid \ @@ -184,32 +155,21 @@ index 774c10d4..6bf3b627 100644 rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ -@@ -246,6 +247,7 @@ unit: +@@ -252,8 +253,9 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ +- $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ +- $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ + $$V ${.OBJDIR}/unittests/pkcs11/test_pkcs11 ; \ - $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ - $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ ++ $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ ++ $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ -d ${.CURDIR}/unittests/sshkey/testdata ; \ -diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh -index fbbaea51..5d75d69f 100644 ---- a/regress/agent-pkcs11.sh -+++ b/regress/agent-pkcs11.sh -@@ -113,7 +113,7 @@ else - done - - trace "remove pkcs11 keys" -- echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 -+ ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -e failed: exit code $r" -diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh -new file mode 100644 -index 00000000..a91aee94 ---- /dev/null -+++ b/regress/pkcs11.sh + $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ + -d ${.CURDIR}/unittests/sshsig/testdata ; \ +diff -up openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri openssh-8.7p1/regress/pkcs11.sh +--- openssh-8.7p1/regress/pkcs11.sh.pkcs11-uri 2021-08-30 13:07:43.663700096 +0200 ++++ openssh-8.7p1/regress/pkcs11.sh 2021-08-30 13:07:43.663700096 +0200 @@ -0,0 +1,349 @@ +# +# Copyright (c) 2017 Red Hat @@ -560,23 +520,20 @@ index 00000000..a91aee94 + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi -diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile -index 4e56e110..2690ebeb 100644 ---- a/regress/unittests/Makefile -+++ b/regress/unittests/Makefile +diff -up openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri openssh-8.7p1/regress/unittests/Makefile +--- openssh-8.7p1/regress/unittests/Makefile.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/regress/unittests/Makefile 2021-08-30 13:07:43.663700096 +0200 @@ -2,6 +2,6 @@ REGRESS_FAIL_EARLY?= yes SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion --SUBDIR+=authopt misc -+SUBDIR+=authopt misc pkcs11 +-SUBDIR+=authopt misc sshsig ++SUBDIR+=authopt misc sshsig pkcs11 .include -diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c -new file mode 100644 -index 00000000..b637cb13 ---- /dev/null -+++ b/regress/unittests/pkcs11/tests.c +diff -up openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri openssh-8.7p1/regress/unittests/pkcs11/tests.c +--- openssh-8.7p1/regress/unittests/pkcs11/tests.c.pkcs11-uri 2021-08-30 13:07:43.664700104 +0200 ++++ openssh-8.7p1/regress/unittests/pkcs11/tests.c 2021-08-30 13:07:43.664700104 +0200 @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2017 Red Hat @@ -807,7 +764,7 @@ index 00000000..b637cb13 +} + +void -+check_encode(char *source, size_t len, char *whitelist, char *expect) ++check_encode(char *source, size_t len, char *allow_list, char *expect) +{ + char *buf = NULL; + struct sshbuf *b; @@ -816,7 +773,7 @@ index 00000000..b637cb13 + TEST_START(buf); + free(buf); + -+ b = percent_encode(source, len, whitelist); ++ b = percent_encode(source, len, allow_list); + ASSERT_STRING_EQ(sshbuf_ptr(b), expect); + sshbuf_free(b); + TEST_DONE(); @@ -841,14 +798,14 @@ index 00000000..b637cb13 +static void +test_percent_encode(void) +{ -+ /* Without whitelist encodes everything (for CKA_ID) */ ++ /* Without allow list encodes everything (for CKA_ID) */ + check_encode("A*", 2, "", "%41%2A"); + check_encode("\x00", 1, "", "%00"); + check_encode("\x7F", 1, "", "%7F"); + check_encode("\x80", 1, "", "%80"); + check_encode("\xff", 1, "", "%FF"); + -+ /* Default whitelist encodes anything but safe letters */ ++ /* Default allow list encodes anything but safe letters */ + check_encode("test" "\x00" "0alpha", 11, PKCS11_URI_WHITELIST, + "test%000alpha"); + check_encode(" ", 1, PKCS11_URI_WHITELIST, @@ -915,19 +872,18 @@ index 00000000..b637cb13 + test_parse_invalid(); + test_generate_valid(); +} -diff --git a/ssh-add.c b/ssh-add.c -index 8057eb1f..0c470e32 100644 ---- a/ssh-add.c -+++ b/ssh-add.c -@@ -67,6 +67,7 @@ - #include "ssherr.h" +diff -up openssh-8.7p1/ssh-add.c.pkcs11-uri openssh-8.7p1/ssh-add.c +--- openssh-8.7p1/ssh-add.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-add.c 2021-08-30 13:07:43.664700104 +0200 +@@ -68,6 +68,7 @@ #include "digest.h" #include "ssh-sk.h" + #include "sk-api.h" +#include "ssh-pkcs11-uri.h" /* argv0 */ extern char *__progname; -@@ -193,6 +194,32 @@ delete_all(int agent_fd, int qflag) +@@ -229,6 +230,32 @@ delete_all(int agent_fd, int qflag) return ret; } @@ -960,7 +916,7 @@ index 8057eb1f..0c470e32 100644 static int add_file(int agent_fd, const char *filename, int key_only, int qflag, const char *skprovider) -@@ -402,12 +429,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag, +@@ -445,12 +472,11 @@ add_file(int agent_fd, const char *filen } static int @@ -975,7 +931,7 @@ index 8057eb1f..0c470e32 100644 if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN)) == NULL) return -1; -@@ -591,6 +617,13 @@ static int +@@ -630,6 +656,13 @@ static int do_file(int agent_fd, int deleting, int key_only, char *file, int qflag, const char *skprovider) { @@ -989,7 +945,7 @@ index 8057eb1f..0c470e32 100644 if (deleting) { if (delete_file(agent_fd, file, key_only, qflag) == -1) return -1; -@@ -773,7 +806,7 @@ main(int argc, char **argv) +@@ -813,7 +846,7 @@ main(int argc, char **argv) } if (pkcs11provider != NULL) { if (update_card(agent_fd, !deleting, pkcs11provider, @@ -998,11 +954,10 @@ index 8057eb1f..0c470e32 100644 ret = 1; goto done; } -diff --git a/ssh-agent.c b/ssh-agent.c -index 7eb6f0dc..27d8e4af 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -641,10 +641,72 @@ no_identities(SocketEntry *e) +diff -up openssh-8.7p1/ssh-agent.c.pkcs11-uri openssh-8.7p1/ssh-agent.c +--- openssh-8.7p1/ssh-agent.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-agent.c 2021-08-30 13:07:43.664700104 +0200 +@@ -847,10 +847,72 @@ no_identities(SocketEntry *e) } #ifdef ENABLE_PKCS11 @@ -1045,9 +1000,9 @@ index 7eb6f0dc..27d8e4af 100644 + return NULL; + } + free(module_path); -+ if (match_pattern_list(canonical_provider, provider_whitelist, 0) != 1) { ++ if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { + verbose("refusing PKCS#11 provider \"%.100s\": " -+ "not whitelisted", canonical_provider); ++ "not allowed", canonical_provider); + pkcs11_uri_cleanup(uri); + return NULL; + } @@ -1075,31 +1030,31 @@ 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; -@@ -681,33 +743,28 @@ process_add_smartcard_key(SocketEntry *e) - goto send; - } + u_int seconds = 0; +@@ -869,33 +931,28 @@ process_add_smartcard_key(SocketEntry *e + error_f("failed to parse constraints"); + goto send; } - if (realpath(provider, canonical_provider) == NULL) { - verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", - provider, strerror(errno)); - goto send; - } -- if (match_pattern_list(canonical_provider, provider_whitelist, 0) != 1) { +- if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { - verbose("refusing PKCS#11 add of \"%.100s\": " -- "provider not whitelisted", canonical_provider); +- "provider not allowed", canonical_provider); + + sane_uri = sanitize_pkcs11_provider(provider); + 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]; @@ -1118,7 +1073,7 @@ index 7eb6f0dc..27d8e4af 100644 } id->death = death; id->confirm = confirm; -@@ -721,6 +778,7 @@ process_add_smartcard_key(SocketEntry *e) +@@ -910,6 +967,7 @@ process_add_smartcard_key(SocketEntry *e send: free(pin); free(provider); @@ -1126,7 +1081,7 @@ index 7eb6f0dc..27d8e4af 100644 free(keys); free(comments); send_status(e, success); -@@ -729,7 +787,7 @@ send: +@@ -918,7 +976,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1135,7 +1090,7 @@ index 7eb6f0dc..27d8e4af 100644 int r, success = 0; Identity *id, *nxt; -@@ -740,30 +798,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -930,30 +988,29 @@ process_remove_smartcard_key(SocketEntry } free(pin); @@ -1147,8 +1102,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,18 +1120,192 @@ 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); send_status(e, success); } #endif /* ENABLE_PKCS11 */ -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 0d6ed1ff..182f4f2b 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -855,8 +855,11 @@ do_download(struct passwd *pw) +diff -up openssh-8.7p1/ssh_config.5.pkcs11-uri openssh-8.7p1/ssh_config.5 +--- openssh-8.7p1/ssh_config.5.pkcs11-uri 2021-08-30 13:07:43.578699383 +0200 ++++ openssh-8.7p1/ssh_config.5 2021-08-30 13:07:43.664700104 +0200 +@@ -1111,6 +1111,21 @@ may also be used in conjunction with + .Cm CertificateFile + in order to provide any certificate also needed for authentication with + the identity. ++.Pp ++The authentication identity can be also specified in a form of PKCS#11 URI ++starting with a string ++.Cm pkcs11: . ++There is supported a subset of the PKCS#11 URI as defined ++in RFC 7512 (implemented path arguments ++.Cm id , ++.Cm manufacturer , ++.Cm object , ++.Cm token ++and query arguments ++.Cm module-path ++and ++.Cm pin-value ++). The URI can not be in quotes. + .It Cm IgnoreUnknown + Specifies a pattern-list of unknown options to be ignored if they are + encountered in configuration parsing. +diff -up openssh-8.7p1/ssh.c.pkcs11-uri openssh-8.7p1/ssh.c +--- openssh-8.7p1/ssh.c.pkcs11-uri 2021-08-30 13:07:43.578699383 +0200 ++++ openssh-8.7p1/ssh.c 2021-08-30 13:07:43.666700121 +0200 +@@ -826,6 +826,14 @@ main(int ac, char **av) + options.gss_deleg_creds = 1; + break; + case 'i': ++#ifdef ENABLE_PKCS11 ++ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(optarg, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ add_identity_file(&options, NULL, optarg, 1); ++ break; ++ } ++#endif + p = tilde_expand_filename(optarg, getuid()); + if (stat(p, &st) == -1) + fprintf(stderr, "Warning: Identity file %s " +@@ -1681,6 +1689,7 @@ main(int ac, char **av) + #ifdef ENABLE_PKCS11 + (void)pkcs11_del_provider(options.pkcs11_provider); + #endif ++ pkcs11_terminate(); + + skip_connect: + exit_status = ssh_session2(ssh, cinfo); +@@ -2197,6 +2206,45 @@ ssh_session2(struct ssh *ssh, const stru + options.escape_char : SSH_ESCAPECHAR_NONE, id); + } + ++#ifdef ENABLE_PKCS11 ++static void ++load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], ++ struct sshkey *identity_keys[], int *n_ids) ++{ ++ int nkeys, i; ++ struct sshkey **keys; ++ struct pkcs11_uri *uri; ++ ++ debug("identity file '%s' from pkcs#11", pkcs11_uri); ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); ++ ++ /* we need to merge URI and provider together */ ++ if (options.pkcs11_provider != NULL && uri->module_path == NULL) ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && ++ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { ++ for (i = 0; i < nkeys; i++) { ++ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { ++ sshkey_free(keys[i]); ++ continue; ++ } ++ identity_keys[*n_ids] = keys[i]; ++ identity_files[*n_ids] = pkcs11_uri_get(uri); ++ (*n_ids)++; ++ } ++ free(keys); ++ } ++ ++ pkcs11_uri_cleanup(uri); ++} ++#endif /* ENABLE_PKCS11 */ ++ + /* Loads all IdentityFile and CertificateFile keys */ + static void + load_public_identity_files(const struct ssh_conn_info *cinfo) +@@ -2211,11 +2259,6 @@ load_public_identity_files(const struct + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; + int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; +-#ifdef ENABLE_PKCS11 +- struct sshkey **keys = NULL; +- char **comments = NULL; +- int nkeys; +-#endif /* PKCS11 */ + + n_ids = n_certs = 0; + memset(identity_files, 0, sizeof(identity_files)); +@@ -2228,33 +2271,46 @@ load_public_identity_files(const struct + sizeof(certificate_file_userprovided)); + + #ifdef ENABLE_PKCS11 +- if (options.pkcs11_provider != NULL && +- options.num_identity_files < SSH_MAX_IDENTITY_FILES && +- (pkcs11_init(!options.batch_mode) == 0) && +- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, +- &keys, &comments)) > 0) { +- for (i = 0; i < nkeys; i++) { +- if (n_ids >= SSH_MAX_IDENTITY_FILES) { +- sshkey_free(keys[i]); +- free(comments[i]); +- continue; +- } +- identity_keys[n_ids] = keys[i]; +- identity_files[n_ids] = comments[i]; /* transferred */ +- n_ids++; +- } +- free(keys); +- free(comments); ++ /* handle fallback from PKCS11Provider option */ ++ pkcs11_init(!options.batch_mode); ++ ++ if (options.pkcs11_provider != NULL) { ++ struct pkcs11_uri *uri; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ /* Construct simple PKCS#11 URI to simplify access */ ++ uri->module_path = strdup(options.pkcs11_provider); ++ ++ /* Add it as any other IdentityFile */ ++ cp = pkcs11_uri_get(uri); ++ add_identity_file(&options, NULL, cp, 1); ++ free(cp); ++ ++ pkcs11_uri_cleanup(uri); + } + #endif /* ENABLE_PKCS11 */ + for (i = 0; i < options.num_identity_files; i++) { ++ char *name = options.identity_files[i]; + if (n_ids >= SSH_MAX_IDENTITY_FILES || +- strcasecmp(options.identity_files[i], "none") == 0) { ++ strcasecmp(name, "none") == 0) { + free(options.identity_files[i]); + options.identity_files[i] = NULL; + continue; + } +- cp = tilde_expand_filename(options.identity_files[i], getuid()); ++#ifdef ENABLE_PKCS11 ++ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(name, PKCS11_URI_SCHEME, ++ strlen(PKCS11_URI_SCHEME)) == 0) { ++ load_pkcs11_identity(name, identity_files, ++ identity_keys, &n_ids); ++ free(options.identity_files[i]); ++ continue; ++ } ++#endif /* ENABLE_PKCS11 */ ++ cp = tilde_expand_filename(name, getuid()); + filename = default_client_percent_dollar_expand(cp, cinfo); + free(cp); + check_load(sshkey_load_public(filename, &public, NULL), +diff -up openssh-8.7p1/ssh-keygen.c.pkcs11-uri openssh-8.7p1/ssh-keygen.c +--- openssh-8.7p1/ssh-keygen.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-keygen.c 2021-08-30 13:07:43.666700121 +0200 +@@ -860,8 +860,11 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1190,765 +1319,286 @@ index 0d6ed1ff..182f4f2b 100644 } free(comments[i]); sshkey_free(keys[i]); -diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c -index 8a0ffef5..ead8a562 100644 ---- a/ssh-pkcs11-client.c -+++ b/ssh-pkcs11-client.c -@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, +diff -up openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-client.c +--- openssh-8.7p1/ssh-pkcs11-client.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-pkcs11-client.c 2021-08-30 13:07:43.666700121 +0200 +@@ -323,6 +323,8 @@ pkcs11_add_provider(char *name, char *pi 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); -@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, +@@ -342,6 +344,7 @@ pkcs11_add_provider(char *name, char *pi *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); -+ 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 || -diff --git a/ssh-pkcs11-uri.c b/ssh-pkcs11-uri.c -new file mode 100644 -index 00000000..e1a7b4e0 ---- /dev/null -+++ b/ssh-pkcs11-uri.c -@@ -0,0 +1,421 @@ -+/* -+ * Copyright (c) 2017 Red Hat -+ * -+ * Authors: Jakub Jelen -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include "includes.h" +diff -up openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11.c +--- openssh-8.7p1/ssh-pkcs11.c.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-pkcs11.c 2021-08-30 13:12:27.709084157 +0200 +@@ -55,8 +55,8 @@ struct pkcs11_slotinfo { + int logged_in; + }; + +-struct pkcs11_provider { +- char *name; ++struct pkcs11_module { ++ char *module_path; + void *handle; + CK_FUNCTION_LIST *function_list; + CK_INFO info; +@@ -65,6 +65,13 @@ struct pkcs11_provider { + struct pkcs11_slotinfo *slotinfo; + int valid; + int refcount; ++}; + -+#ifdef ENABLE_PKCS11 ++struct pkcs11_provider { ++ char *name; ++ struct pkcs11_module *module; /* can be shared between various providers */ ++ int refcount; ++ int valid; + TAILQ_ENTRY(pkcs11_provider) next; + }; + +@@ -75,6 +82,7 @@ struct pkcs11_key { + CK_ULONG slotidx; + char *keyid; + int keyid_len; ++ char *label; + }; + + int pkcs11_interactive = 0; +@@ -106,26 +114,61 @@ pkcs11_init(int interactive) + * this is called when a provider gets unregistered. + */ + static void +-pkcs11_provider_finalize(struct pkcs11_provider *p) ++pkcs11_module_finalize(struct pkcs11_module *m) + { + CK_RV rv; + CK_ULONG i; + +- debug_f("provider \"%s\" refcount %d valid %d", +- p->name, p->refcount, p->valid); +- if (!p->valid) ++ debug_f("%p refcount %d valid %d", m, m->refcount, m->valid); ++ if (!m->valid) + return; +- for (i = 0; i < p->nslots; i++) { +- if (p->slotinfo[i].session && +- (rv = p->function_list->C_CloseSession( +- p->slotinfo[i].session)) != CKR_OK) ++ for (i = 0; i < m->nslots; i++) { ++ if (m->slotinfo[i].session && ++ (rv = m->function_list->C_CloseSession( ++ m->slotinfo[i].session)) != CKR_OK) + error("C_CloseSession failed: %lu", rv); + } +- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) ++ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) + error("C_Finalize failed: %lu", rv); ++ m->valid = 0; ++ m->function_list = NULL; ++ dlclose(m->handle); ++} + -+#include -+#include ++/* ++ * remove a reference to the pkcs11 module. ++ * called when a provider is unregistered. ++ */ ++static void ++pkcs11_module_unref(struct pkcs11_module *m) ++{ ++ debug_f("%p refcount %d", m, m->refcount); ++ if (--m->refcount <= 0) { ++ pkcs11_module_finalize(m); ++ if (m->valid) ++ error_f("%p still valid", m); ++ free(m->slotlist); ++ free(m->slotinfo); ++ free(m->module_path); ++ free(m); ++ } ++} + -+#include "sshkey.h" -+#include "sshbuf.h" -+#include "log.h" ++/* ++ * finalize a provider shared library, it's no longer usable. ++ * however, there might still be keys referencing this provider, ++ * so the actual freeing of memory is handled by pkcs11_provider_unref(). ++ * this is called when a provider gets unregistered. ++ */ ++static void ++pkcs11_provider_finalize(struct pkcs11_provider *p) ++{ ++ debug_f("%p refcount %d valid %d", p, p->refcount, p->valid); ++ if (!p->valid) ++ return; ++ pkcs11_module_unref(p->module); ++ p->module = NULL; + p->valid = 0; +- p->function_list = NULL; +- dlclose(p->handle); + } + + /* +@@ -137,11 +180,9 @@ pkcs11_provider_unref(struct pkcs11_prov + { + debug_f("provider \"%s\" refcount %d", p->name, p->refcount); + if (--p->refcount <= 0) { +- if (p->valid) +- error_f("provider \"%s\" still valid", p->name); + free(p->name); +- free(p->slotlist); +- free(p->slotinfo); ++ if (p->module) ++ pkcs11_module_unref(p->module); + free(p); + } + } +@@ -159,6 +200,20 @@ pkcs11_terminate(void) + } + } + ++/* lookup provider by module path */ ++static struct pkcs11_module * ++pkcs11_provider_lookup_module(char *module_path) ++{ ++ struct pkcs11_provider *p; + -+#define CRYPTOKI_COMPAT -+#include "pkcs11.h" ++ TAILQ_FOREACH(p, &pkcs11_providers, next) { ++ debug("check %p %s (%s)", p, p->name, p->module->module_path); ++ if (!strcmp(module_path, p->module->module_path)) ++ return (p->module); ++ } ++ return (NULL); ++} + -+#include "ssh-pkcs11-uri.h" + /* lookup provider by name */ + static struct pkcs11_provider * + pkcs11_provider_lookup(char *provider_id) +@@ -173,19 +228,55 @@ pkcs11_provider_lookup(char *provider_id + return (NULL); + } + ++int pkcs11_del_provider_by_uri(struct pkcs11_uri *); + -+#define PKCS11_URI_PATH_SEPARATOR ";" -+#define PKCS11_URI_QUERY_SEPARATOR "&" -+#define PKCS11_URI_VALUE_SEPARATOR "=" -+#define PKCS11_URI_ID "id" -+#define PKCS11_URI_TOKEN "token" -+#define PKCS11_URI_OBJECT "object" -+#define PKCS11_URI_LIB_MANUF "library-manufacturer" -+#define PKCS11_URI_MANUF "manufacturer" -+#define PKCS11_URI_MODULE_PATH "module-path" -+#define PKCS11_URI_PIN_VALUE "pin-value" + /* unregister provider by name */ + int + pkcs11_del_provider(char *provider_id) + { ++ int rv; ++ struct pkcs11_uri *uri; + -+/* Keyword tokens. */ -+typedef enum { -+ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, -+ pPinValue, pBadOption -+} pkcs11uriOpCodes; ++ debug_f("called, provider_id = %s", provider_id); + -+/* Textual representation of the tokens. */ -+static struct { -+ const char *name; -+ pkcs11uriOpCodes opcode; -+} keywords[] = { -+ { PKCS11_URI_ID, pId }, -+ { PKCS11_URI_TOKEN, pToken }, -+ { PKCS11_URI_OBJECT, pObject }, -+ { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, -+ { PKCS11_URI_MANUF, pManufacturer }, -+ { PKCS11_URI_MODULE_PATH, pModulePath }, -+ { PKCS11_URI_PIN_VALUE, pPinValue }, -+ { NULL, pBadOption } -+}; ++ if (provider_id == NULL) ++ return 0; + -+static pkcs11uriOpCodes -+parse_token(const char *cp) -+{ -+ u_int i; ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); + -+ for (i = 0; keywords[i].name; i++) -+ if (strncasecmp(cp, keywords[i].name, -+ strlen(keywords[i].name)) == 0) -+ return keywords[i].opcode; ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); ++ } + -+ return pBadOption; ++ rv = pkcs11_del_provider_by_uri(uri); ++ pkcs11_uri_cleanup(uri); ++ return rv; +} + ++/* unregister provider by PKCS#11 URI */ +int -+percent_decode(char *data, char **outp) ++pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) +{ -+ char tmp[3]; -+ char *out, *tmp_end; -+ char *p = data; -+ long value; -+ size_t outlen = 0; -+ -+ out = malloc(strlen(data)+1); /* upper bound */ -+ if (out == NULL) -+ return -1; -+ while (*p != '\0') { -+ switch (*p) { -+ case '%': -+ p++; -+ if (*p == '\0') -+ goto fail; -+ tmp[0] = *p++; -+ if (*p == '\0') -+ goto fail; -+ tmp[1] = *p++; -+ tmp[2] = '\0'; -+ tmp_end = NULL; -+ value = strtol(tmp, &tmp_end, 16); -+ if (tmp_end != tmp+2) -+ goto fail; -+ else -+ out[outlen++] = (char) value; -+ break; -+ default: -+ out[outlen++] = *p++; -+ break; -+ } -+ } -+ -+ /* zero terminate */ -+ out[outlen] = '\0'; -+ *outp = out; -+ return outlen; -+fail: -+ free(out); -+ return -1; -+} -+ -+struct sshbuf * -+percent_encode(const char *data, size_t length, const char *whitelist) -+{ -+ struct sshbuf *b = NULL; -+ char tmp[4], *cp; -+ size_t i; -+ -+ if ((b = sshbuf_new()) == NULL) -+ return NULL; -+ for (i = 0; i < length; i++) { -+ cp = strchr(whitelist, data[i]); -+ /* if c is specified as '\0' pointer to terminator is returned !! */ -+ if (cp != NULL && *cp != '\0') { -+ if (sshbuf_put(b, &data[i], 1) != 0) -+ goto err; -+ } else -+ if (snprintf(tmp, 4, "%%%02X", (unsigned char) data[i]) < 3 -+ || sshbuf_put(b, tmp, 3) != 0) -+ goto err; -+ } -+ if (sshbuf_put(b, "\0", 1) == 0) -+ return b; -+err: -+ sshbuf_free(b); -+ return NULL; -+} -+ -+char * -+pkcs11_uri_append(char *part, const char *separator, const char *key, -+ struct sshbuf *value) -+{ -+ char *new_part; -+ size_t size = 0; -+ -+ if (value == NULL) -+ return NULL; -+ -+ size = asprintf(&new_part, -+ "%s%s%s" PKCS11_URI_VALUE_SEPARATOR "%s", -+ (part != NULL ? part : ""), -+ (part != NULL ? separator : ""), -+ key, sshbuf_ptr(value)); -+ sshbuf_free(value); -+ free(part); -+ -+ if (size <= 0) -+ return NULL; -+ return new_part; -+} -+ -+char * -+pkcs11_uri_get(struct pkcs11_uri *uri) -+{ -+ size_t size = 0; -+ char *p = NULL, *path = NULL, *query = NULL; -+ -+ /* compose a percent-encoded ID */ -+ if (uri->id_len > 0) { -+ struct sshbuf *key_id = percent_encode(uri->id, uri->id_len, ""); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_ID, key_id); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write object label */ -+ if (uri->object) { -+ struct sshbuf *label = percent_encode(uri->object, strlen(uri->object), -+ PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_OBJECT, label); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write token label */ -+ if (uri->token) { -+ struct sshbuf *label = percent_encode(uri->token, strlen(uri->token), -+ PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_TOKEN, label); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write manufacturer */ -+ if (uri->manuf) { -+ struct sshbuf *manuf = percent_encode(uri->manuf, -+ strlen(uri->manuf), PKCS11_URI_WHITELIST); -+ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, -+ PKCS11_URI_MANUF, manuf); -+ if (path == NULL) -+ goto err; -+ } -+ -+ /* Write module_path */ -+ if (uri->module_path) { -+ struct sshbuf *module = percent_encode(uri->module_path, -+ strlen(uri->module_path), PKCS11_URI_WHITELIST "/"); -+ query = pkcs11_uri_append(query, PKCS11_URI_QUERY_SEPARATOR, -+ PKCS11_URI_MODULE_PATH, module); -+ if (query == NULL) -+ goto err; -+ } -+ -+ size = asprintf(&p, PKCS11_URI_SCHEME "%s%s%s", -+ path != NULL ? path : "", -+ query != NULL ? "?" : "", -+ query != NULL ? query : ""); -+err: -+ free(query); -+ free(path); -+ if (size <= 0) -+ return NULL; -+ return p; -+} -+ -+struct pkcs11_uri * -+pkcs11_uri_init() -+{ -+ struct pkcs11_uri *d = calloc(1, sizeof(struct pkcs11_uri)); -+ return d; -+} -+ -+void -+pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) -+{ -+ free(pkcs11->id); -+ free(pkcs11->module_path); -+ free(pkcs11->token); -+ free(pkcs11->object); -+ free(pkcs11->lib_manuf); -+ free(pkcs11->manuf); -+ if (pkcs11->pin) -+ freezero(pkcs11->pin, strlen(pkcs11->pin)); -+ free(pkcs11); -+} + struct pkcs11_provider *p; ++ int rv = -1; ++ char *provider_uri = pkcs11_uri_get(uri); + +- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { ++ debug3_f("called with provider %s", provider_uri); + ++ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); +- return (0); ++ rv = 0; + } +- return (-1); ++ free(provider_uri); ++ return rv; + } + + static RSA_METHOD *rsa_method; +@@ -195,6 +286,55 @@ static EC_KEY_METHOD *ec_key_method; + static int ec_key_idx = 0; + #endif + ++/* ++ * This can't be in the ssh-pkcs11-uri, becase we can not depend on ++ * PKCS#11 structures in ssh-agent (using client-helper communication) ++ */ +int -+pkcs11_uri_parse(const char *uri, struct pkcs11_uri *pkcs11) ++pkcs11_uri_write(const struct sshkey *key, FILE *f) +{ -+ char *saveptr1, *saveptr2, *str1, *str2, *tok; -+ int rv = 0, len; + char *p = NULL; ++ struct pkcs11_uri uri; ++ struct pkcs11_key *k11; + -+ 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); -+ return -1; -+ } -+ -+ if (pkcs11 == NULL) { -+ error("%s: Bad arguments. The pkcs11 can't be null", __func__); ++ /* sanity - is it a RSA key with associated app_data? */ ++ switch (key->type) { ++ case KEY_RSA: ++ k11 = RSA_get_ex_data(key->rsa, rsa_idx); ++ break; ++#ifdef HAVE_EC_KEY_METHOD_NEW ++ case KEY_ECDSA: ++ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); ++ break; ++#endif ++ default: ++ error("Unknown key type %d", key->type); + return -1; + } -+ -+ /* skip URI schema name */ -+ p = strdup(uri); -+ str1 = p; -+ -+ /* everything before ? */ -+ tok = strtok_r(str1, "?", &saveptr1); -+ if (tok == NULL) { -+ error("%s: pk11-path expected, got EOF", __func__); -+ rv = -1; -+ goto out; ++ if (k11 == NULL) { ++ error("Failed to get ex_data for key type %d", key->type); ++ return (-1); + } + -+ /* skip URI schema name: -+ * the scheme ensures that there is at least something before "?" -+ * allowing empty pk11-path. Resulting token at worst pointing to -+ * \0 byte */ -+ tok = tok + scheme_len; -+ -+ /* parse pk11-path */ -+ for (str2 = tok; ; str2 = NULL) { -+ char **charptr, *arg = NULL; -+ pkcs11uriOpCodes opcode; -+ tok = strtok_r(str2, PKCS11_URI_PATH_SEPARATOR, &saveptr2); -+ if (tok == NULL) -+ break; -+ opcode = parse_token(tok); -+ if (opcode != pBadOption) -+ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ -+ -+ switch (opcode) { -+ case pId: -+ /* CKA_ID */ -+ if (pkcs11->id != NULL) { -+ verbose("%s: The id already set in the PKCS#11 URI", -+ __func__); -+ rv = -1; -+ goto out; -+ } -+ len = percent_decode(arg, &pkcs11->id); -+ if (len <= 0) { -+ verbose("%s: Failed to percent-decode CKA_ID: %s", -+ __func__, arg); -+ rv = -1; -+ goto out; -+ } else -+ pkcs11->id_len = len; -+ debug3("%s: Setting CKA_ID = %s from PKCS#11 URI", -+ __func__, 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__); -+ rv = -1; -+ goto out; -+ } -+ percent_decode(arg, charptr); -+ debug3("%s: Setting %s = %s from PKCS#11 URI", -+ __func__, keywords[opcode].name, *charptr); -+ break; ++ /* omit type -- we are looking for private-public or private-certificate pairs */ ++ uri.id = k11->keyid; ++ uri.id_len = k11->keyid_len; ++ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; ++ uri.object = k11->label; ++ uri.module_path = k11->provider->module->module_path; ++ uri.lib_manuf = k11->provider->module->info.manufacturerID; ++ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; + -+ case pObject: -+ /* CK_TOKEN_INFO -> manufacturerID */ -+ charptr = &pkcs11->object; -+ goto parse_string; ++ p = pkcs11_uri_get(&uri); ++ /* do not cleanup -- we do not allocate here, only reference */ ++ if (p == NULL) ++ return -1; + -+ case pManufacturer: -+ /* CK_TOKEN_INFO -> manufacturerID */ -+ charptr = &pkcs11->manuf; -+ goto parse_string; -+ -+ case pLibraryManufacturer: -+ /* CK_INFO -> manufacturerID */ -+ charptr = &pkcs11->lib_manuf; -+ goto parse_string; -+ -+ default: -+ /* Unrecognized attribute in the URI path SHOULD be error */ -+ verbose("%s: Unknown part of path in PKCS#11 URI: %s", -+ __func__, tok); -+ } -+ } -+ -+ tok = strtok_r(NULL, "?", &saveptr1); -+ if (tok == NULL) { -+ goto out; -+ } -+ /* parse pk11-query (optional) */ -+ for (str2 = tok; ; str2 = NULL) { -+ char *arg; -+ pkcs11uriOpCodes opcode; -+ tok = strtok_r(str2, PKCS11_URI_QUERY_SEPARATOR, &saveptr2); -+ if (tok == NULL) -+ break; -+ opcode = parse_token(tok); -+ if (opcode != pBadOption) -+ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ -+ -+ switch (opcode) { -+ 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__); -+ rv = -1; -+ goto out; -+ } -+ percent_decode(arg, &pkcs11->module_path); -+ debug3("%s: Setting PKCS11Provider = %s from PKCS#11 URI", -+ __func__, 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__); -+ rv = -1; -+ goto out; -+ } -+ percent_decode(arg, &pkcs11->pin); -+ debug3("%s: Setting PIN from PKCS#11 URI", __func__); -+ break; -+ -+ default: -+ /* Unrecognized attribute in the URI query SHOULD be ignored */ -+ verbose("%s: Unknown part of query in PKCS#11 URI: %s", -+ __func__, tok); -+ } -+ } -+out: -+ free(p); -+ return rv; -+} -+ -+#endif /* ENABLE_PKCS11 */ -diff --git a/ssh-pkcs11-uri.h b/ssh-pkcs11-uri.h -new file mode 100644 -index 00000000..942a5a5a ---- /dev/null -+++ b/ssh-pkcs11-uri.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (c) 2017 Red Hat -+ * -+ * Authors: Jakub Jelen -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#define PKCS11_URI_SCHEME "pkcs11:" -+#define PKCS11_URI_WHITELIST "abcdefghijklmnopqrstuvwxyz" \ -+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ -+ "0123456789_-.()" -+ -+struct pkcs11_uri { -+ /* path */ -+ char *id; -+ size_t id_len; -+ char *token; -+ char *object; -+ char *lib_manuf; -+ char *manuf; -+ /* query */ -+ char *module_path; -+ char *pin; /* Only parsed, but not printed */ -+}; -+ -+struct pkcs11_uri *pkcs11_uri_init(); -+void pkcs11_uri_cleanup(struct pkcs11_uri *); -+int pkcs11_uri_parse(const char *, struct pkcs11_uri *); -+struct pkcs11_uri *pkcs11_uri_init(); -+char *pkcs11_uri_get(struct pkcs11_uri *uri); -+ -diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index a302c79c..879fe917 100644 ---- a/ssh-pkcs11.c -+++ b/ssh-pkcs11.c -@@ -54,8 +54,8 @@ struct pkcs11_slotinfo { - int logged_in; - }; - --struct pkcs11_provider { -- char *name; -+struct pkcs11_module { -+ char *module_path; - void *handle; - CK_FUNCTION_LIST *function_list; - CK_INFO info; -@@ -64,6 +64,13 @@ struct pkcs11_provider { - struct pkcs11_slotinfo *slotinfo; - int valid; - int refcount; -+}; -+ -+struct pkcs11_provider { -+ char *name; -+ struct pkcs11_module *module; /* can be shared between various providers */ -+ int refcount; -+ int valid; - TAILQ_ENTRY(pkcs11_provider) next; - }; - -@@ -74,6 +81,7 @@ struct pkcs11_key { - CK_ULONG slotidx; - char *keyid; - int keyid_len; -+ char *label; - }; - - int pkcs11_interactive = 0; -@@ -106,26 +114,63 @@ pkcs11_init(int interactive) - * this is called when a provider gets unregistered. - */ - static void --pkcs11_provider_finalize(struct pkcs11_provider *p) -+pkcs11_module_finalize(struct pkcs11_module *m) - { - CK_RV rv; - CK_ULONG i; - -- debug("pkcs11_provider_finalize: %p refcount %d valid %d", -- p, p->refcount, p->valid); -- if (!p->valid) -+ debug("%s: %p refcount %d valid %d", __func__, -+ m, m->refcount, m->valid); -+ if (!m->valid) - return; -- for (i = 0; i < p->nslots; i++) { -- if (p->slotinfo[i].session && -- (rv = p->function_list->C_CloseSession( -- p->slotinfo[i].session)) != CKR_OK) -+ for (i = 0; i < m->nslots; i++) { -+ if (m->slotinfo[i].session && -+ (rv = m->function_list->C_CloseSession( -+ m->slotinfo[i].session)) != CKR_OK) - error("C_CloseSession failed: %lu", rv); - } -- if ((rv = p->function_list->C_Finalize(NULL)) != CKR_OK) -+ if ((rv = m->function_list->C_Finalize(NULL)) != CKR_OK) - error("C_Finalize failed: %lu", rv); -+ m->valid = 0; -+ m->function_list = NULL; -+ dlclose(m->handle); -+} -+ -+/* -+ * remove a reference to the pkcs11 module. -+ * called when a provider is unregistered. -+ */ -+static void -+pkcs11_module_unref(struct pkcs11_module *m) -+{ -+ debug("%s: %p refcount %d", __func__, m, m->refcount); -+ if (--m->refcount <= 0) { -+ pkcs11_module_finalize(m); -+ if (m->valid) -+ error("%s: %p still valid", __func__, m); -+ free(m->slotlist); -+ free(m->slotinfo); -+ free(m->module_path); -+ free(m); -+ } -+} -+ -+/* -+ * finalize a provider shared libarary, it's no longer usable. -+ * however, there might still be keys referencing this provider, -+ * so the actuall freeing of memory is handled by pkcs11_provider_unref(). -+ * this is called when a provider gets unregistered. -+ */ -+static void -+pkcs11_provider_finalize(struct pkcs11_provider *p) -+{ -+ debug("%s: %p refcount %d valid %d", __func__, -+ p, p->refcount, p->valid); -+ if (!p->valid) -+ return; -+ pkcs11_module_unref(p->module); -+ p->module = NULL; - p->valid = 0; -- p->function_list = NULL; -- dlclose(p->handle); - } - - /* -@@ -135,13 +180,11 @@ pkcs11_provider_finalize(struct pkcs11_provider *p) - static void - pkcs11_provider_unref(struct pkcs11_provider *p) - { -- debug("pkcs11_provider_unref: %p refcount %d", p, p->refcount); -+ debug("%s: %p refcount %d", __func__, p, p->refcount); - if (--p->refcount <= 0) { -- if (p->valid) -- error("pkcs11_provider_unref: %p still valid", p); - free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -+ if (p->module) -+ pkcs11_module_unref(p->module); - free(p); - } - } -@@ -159,6 +202,20 @@ pkcs11_terminate(void) - } - } - -+/* lookup provider by module path */ -+static struct pkcs11_module * -+pkcs11_provider_lookup_module(char *module_path) -+{ -+ struct pkcs11_provider *p; -+ -+ TAILQ_FOREACH(p, &pkcs11_providers, next) { -+ debug("check %p %s (%s)", p, p->name, p->module->module_path); -+ if (!strcmp(module_path, p->module->module_path)) -+ return (p->module); -+ } -+ return (NULL); -+} -+ - /* lookup provider by name */ - static struct pkcs11_provider * - pkcs11_provider_lookup(char *provider_id) -@@ -173,19 +230,52 @@ pkcs11_provider_lookup(char *provider_id) - return (NULL); - } - -+int pkcs11_del_provider_by_uri(struct pkcs11_uri *); -+ - /* unregister provider by name */ - int - pkcs11_del_provider(char *provider_id) -+{ -+ int rv; -+ struct pkcs11_uri *uri; -+ -+ debug("%s: called, provider_id = %s", __func__, provider_id); -+ -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); -+ } -+ -+ rv = pkcs11_del_provider_by_uri(uri); -+ pkcs11_uri_cleanup(uri); -+ return rv; -+} -+ -+/* unregister provider by PKCS#11 URI */ -+int -+pkcs11_del_provider_by_uri(struct pkcs11_uri *uri) - { - struct pkcs11_provider *p; -+ int rv = -1; -+ char *provider_uri = pkcs11_uri_get(uri); - -- if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { -+ debug3("%s(%s): called", __func__, provider_uri); -+ -+ if ((p = pkcs11_provider_lookup(provider_uri)) != NULL) { - TAILQ_REMOVE(&pkcs11_providers, p, next); - pkcs11_provider_finalize(p); - pkcs11_provider_unref(p); -- return (0); -+ rv = 0; - } -- return (-1); -+ free(provider_uri); -+ return rv; - } - - static RSA_METHOD *rsa_method; -@@ -195,6 +285,55 @@ static EC_KEY_METHOD *ec_key_method; - static int ec_key_idx = 0; - #endif - -+/* -+ * This can't be in the ssh-pkcs11-uri, becase we can not depend on -+ * PKCS#11 structures in ssh-agent (using client-helper communication) -+ */ -+int -+pkcs11_uri_write(const struct sshkey *key, FILE *f) -+{ -+ char *p = NULL; -+ struct pkcs11_uri uri; -+ struct pkcs11_key *k11; -+ -+ /* sanity - is it a RSA key with associated app_data? */ -+ switch (key->type) { -+ case KEY_RSA: -+ k11 = RSA_get_ex_data(key->rsa, rsa_idx); -+ break; -+#ifdef HAVE_EC_KEY_METHOD_NEW -+ case KEY_ECDSA: -+ k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx); -+ break; -+#endif -+ default: -+ error("Unknown key type %d", key->type); -+ return -1; -+ } -+ if (k11 == NULL) { -+ error("Failed to get ex_data for key type %d", key->type); -+ return (-1); -+ } -+ -+ /* omit type -- we are looking for private-public or private-certificate pairs */ -+ uri.id = k11->keyid; -+ uri.id_len = k11->keyid_len; -+ uri.token = k11->provider->module->slotinfo[k11->slotidx].token.label; -+ uri.object = k11->label; -+ uri.module_path = k11->provider->module->module_path; -+ uri.lib_manuf = k11->provider->module->info.manufacturerID; -+ uri.manuf = k11->provider->module->slotinfo[k11->slotidx].token.manufacturerID; -+ -+ p = pkcs11_uri_get(&uri); -+ /* do not cleanup -- we do not allocate here, only reference */ -+ if (p == NULL) -+ return -1; -+ -+ fprintf(f, " %s", p); -+ free(p); -+ return 0; -+} ++ fprintf(f, " %s", p); ++ free(p); ++ return 0; ++} + /* release a wrapped object */ static void pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, -@@ -208,6 +347,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, +@@ -208,6 +348,7 @@ pkcs11_k11_free(void *parent, void *ptr, if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); @@ -1956,7 +1606,7 @@ index a302c79c..879fe917 100644 free(k11); } -@@ -222,8 +362,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, +@@ -222,8 +363,8 @@ pkcs11_find(struct pkcs11_provider *p, C CK_RV rv; int ret = -1; @@ -1967,13 +1617,13 @@ index a302c79c..879fe917 100644 if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); -@@ -262,12 +402,12 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, +@@ -262,12 +403,12 @@ pkcs11_login_slot(struct pkcs11_provider else { snprintf(prompt, sizeof(prompt), "Enter PIN for '%s': ", si->token.label); - if ((pin = read_passphrase(prompt, RP_ALLOW_EOF)) == NULL) { + if ((pin = read_passphrase(prompt, RP_ALLOW_EOF|RP_ALLOW_STDIN)) == NULL) { - debug("%s: no pin specified", __func__); + debug_f("no pin specified"); return (-1); /* bail out */ } } @@ -1982,7 +1632,7 @@ index a302c79c..879fe917 100644 (pin != NULL) ? strlen(pin) : 0); if (pin != NULL) freezero(pin, strlen(pin)); -@@ -282,13 +422,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, +@@ -297,13 +438,14 @@ pkcs11_login_slot(struct pkcs11_provider static int pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) { @@ -1999,7 +1649,7 @@ index a302c79c..879fe917 100644 } -@@ -304,13 +445,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, +@@ -319,13 +461,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs *val = 0; @@ -2017,7 +1667,7 @@ index a302c79c..879fe917 100644 attr.type = type; attr.pValue = &flag; -@@ -341,13 +483,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) +@@ -356,13 +499,14 @@ pkcs11_get_key(struct pkcs11_key *k11, C int always_auth = 0; int did_login = 0; @@ -2035,7 +1685,7 @@ index a302c79c..879fe917 100644 if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -424,8 +567,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, +@@ -439,8 +583,8 @@ pkcs11_rsa_private_encrypt(int flen, con return (-1); } @@ -2046,7 +1696,7 @@ index a302c79c..879fe917 100644 tlen = RSA_size(rsa); /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -469,7 +612,7 @@ pkcs11_rsa_start_wrapper(void) +@@ -484,7 +628,7 @@ pkcs11_rsa_start_wrapper(void) /* redirect private key operations for rsa key to pkcs11 token */ static int pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -2055,7 +1705,7 @@ index a302c79c..879fe917 100644 { struct pkcs11_key *k11; -@@ -487,6 +630,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +@@ -502,6 +646,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider * memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -2068,7 +1718,7 @@ index a302c79c..879fe917 100644 RSA_set_method(rsa, rsa_method); RSA_set_ex_data(rsa, rsa_idx, k11); return (0); -@@ -517,8 +666,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, +@@ -532,8 +682,8 @@ ecdsa_do_sign(const unsigned char *dgst, return (NULL); } @@ -2079,7 +1729,7 @@ index a302c79c..879fe917 100644 siglen = ECDSA_size(ec); sig = xmalloc(siglen); -@@ -583,7 +732,7 @@ pkcs11_ecdsa_start_wrapper(void) +@@ -598,7 +748,7 @@ pkcs11_ecdsa_start_wrapper(void) static int pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -2088,7 +1738,7 @@ index a302c79c..879fe917 100644 { struct pkcs11_key *k11; -@@ -599,6 +748,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +@@ -614,6 +764,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); @@ -2101,7 +1751,7 @@ index a302c79c..879fe917 100644 EC_KEY_set_method(ec, ec_key_method); EC_KEY_set_ex_data(ec, ec_key_idx, k11); -@@ -635,8 +790,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, +@@ -650,8 +806,8 @@ pkcs11_open_session(struct pkcs11_provid CK_SESSION_HANDLE session; int login_required, ret; @@ -2112,7 +1762,7 @@ index a302c79c..879fe917 100644 login_required = si->token.flags & CKF_LOGIN_REQUIRED; -@@ -646,9 +801,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, +@@ -661,9 +817,9 @@ pkcs11_open_session(struct pkcs11_provid error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -2124,7 +1774,7 @@ index a302c79c..879fe917 100644 return (-1); } if (login_required && pin != NULL && strlen(pin) != 0) { -@@ -684,7 +839,8 @@ static struct sshkey * +@@ -699,7 +855,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2134,7 +1784,7 @@ index a302c79c..879fe917 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -698,14 +854,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -713,14 +870,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2155,12 +1805,13 @@ index a302c79c..879fe917 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -717,18 +874,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -731,19 +889,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ + * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ - if (key_attr[1].ulValueLen == 0 || +- if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ key_attr[2].ulValueLen == 0 || ++ if (key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); @@ -2178,7 +1829,7 @@ index a302c79c..879fe917 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -740,8 +898,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -755,8 +913,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -2189,7 +1840,7 @@ index a302c79c..879fe917 100644 if (group == NULL) { ossl_error("d2i_ECPKParameters failed"); goto fail; -@@ -752,13 +910,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -767,13 +925,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -2206,7 +1857,7 @@ index a302c79c..879fe917 100644 if (octet == NULL) { ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; -@@ -775,7 +933,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -790,7 +948,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ goto fail; } @@ -2215,7 +1866,7 @@ index a302c79c..879fe917 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -791,7 +949,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -806,7 +964,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_ ec = NULL; /* now owned by key */ fail: @@ -2224,7 +1875,7 @@ index a302c79c..879fe917 100644 free(key_attr[i].pValue); if (ec) EC_KEY_free(ec); -@@ -808,7 +966,8 @@ static struct sshkey * +@@ -823,7 +981,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2234,7 +1885,7 @@ index a302c79c..879fe917 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -819,14 +978,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -834,14 +993,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2255,12 +1906,13 @@ index a302c79c..879fe917 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -838,18 +998,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -852,19 +1012,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + * ensure that none of the others are zero length. * XXX assumes CKA_ID is always first. */ - if (key_attr[1].ulValueLen == 0 || +- if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ key_attr[2].ulValueLen == 0 || ++ if (key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); @@ -2278,7 +1930,7 @@ index a302c79c..879fe917 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -861,8 +1022,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -876,8 +1036,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr goto fail; } @@ -2289,8 +1941,8 @@ index a302c79c..879fe917 100644 if (rsa_n == NULL || rsa_e == NULL) { error("BN_bin2bn failed"); goto fail; -@@ -871,7 +1032,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - fatal("%s: set key", __func__); +@@ -886,7 +1046,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr + fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ - if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) @@ -2298,7 +1950,7 @@ index a302c79c..879fe917 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -886,7 +1047,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -901,7 +1061,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_pr rsa = NULL; /* now owned by key */ fail: @@ -2307,7 +1959,7 @@ index a302c79c..879fe917 100644 free(key_attr[i].pValue); RSA_free(rsa); -@@ -897,7 +1058,8 @@ static int +@@ -912,7 +1072,8 @@ static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) { @@ -2317,7 +1969,7 @@ index a302c79c..879fe917 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -921,14 +1083,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -936,14 +1097,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -2338,7 +1990,7 @@ index a302c79c..879fe917 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return -1; -@@ -940,18 +1103,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -955,18 +1117,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2361,7 +2013,7 @@ index a302c79c..879fe917 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto out; -@@ -965,8 +1129,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -980,8 +1143,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p subject = xstrdup("invalid subject"); X509_NAME_free(x509_name); @@ -2372,769 +2024,1033 @@ index a302c79c..879fe917 100644 error("d2i_x509 failed"); goto out; } -@@ -986,7 +1150,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto out; +@@ -1001,7 +1164,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + goto out; + } + +- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) ++ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1031,7 +1194,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + goto out; + } + +- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) ++ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) + goto out; + + key = sshkey_new(KEY_UNSPEC); +@@ -1051,7 +1214,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_p + goto out; + } + out: +- for (i = 0; i < 3; i++) ++ for (i = 0; i < nattr; i++) + free(cert_attr[i].pValue); + X509_free(x509); + RSA_free(rsa); +@@ -1102,11 +1265,12 @@ note_key(struct pkcs11_provider *p, CK_U + */ + static int + pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[1]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1123,10 +1287,23 @@ pkcs11_fetch_certs(struct pkcs11_provide + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } ++ ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1207,11 +1384,12 @@ fail: + */ + static int + pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +- struct sshkey ***keysp, char ***labelsp, int *nkeys) ++ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) + { + struct sshkey *key = NULL; + CK_OBJECT_CLASS key_class; +- CK_ATTRIBUTE key_attr[2]; ++ CK_ATTRIBUTE key_attr[3]; ++ int nattr = 1; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; +@@ -1227,10 +1405,23 @@ pkcs11_fetch_keys(struct pkcs11_provider + key_attr[0].pValue = &key_class; + key_attr[0].ulValueLen = sizeof(key_class); + +- session = p->slotinfo[slotidx].session; +- f = p->function_list; ++ if (uri->id != NULL) { ++ key_attr[nattr].type = CKA_ID; ++ key_attr[nattr].pValue = uri->id; ++ key_attr[nattr].ulValueLen = uri->id_len; ++ nattr++; ++ } ++ if (uri->object != NULL) { ++ key_attr[nattr].type = CKA_LABEL; ++ key_attr[nattr].pValue = uri->object; ++ key_attr[nattr].ulValueLen = strlen(uri->object); ++ nattr++; ++ } + +- rv = f->C_FindObjectsInit(session, key_attr, 1); ++ session = p->module->slotinfo[slotidx].session; ++ f = p->module->function_list; ++ ++ rv = f->C_FindObjectsInit(session, key_attr, nattr); + if (rv != CKR_OK) { + error("C_FindObjectsInit failed: %lu", rv); + goto fail; +@@ -1499,16 +1690,10 @@ pkcs11_ecdsa_generate_private_key(struct + } + #endif /* WITH_PKCS11_KEYGEN */ + +-/* +- * register a new provider, fails if provider already exists. if +- * keyp is provided, fetch keys. +- */ + static int +-pkcs11_register_provider(char *provider_id, char *pin, +- struct sshkey ***keyp, char ***labelsp, +- struct pkcs11_provider **providerp, CK_ULONG user) ++pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) + { +- int nkeys, need_finalize = 0; ++ int need_finalize = 0; + int ret = -1; + struct pkcs11_provider *p = NULL; + void *handle = NULL; +@@ -1517,164 +1702,298 @@ pkcs11_register_provider(char *provider_ + CK_FUNCTION_LIST *f = NULL; + CK_TOKEN_INFO *token; + CK_ULONG i; ++ char *provider_module = NULL; ++ struct pkcs11_module *m = NULL; + +- if (providerp == NULL) ++ /* if no provider specified, fallback to p11-kit */ ++ if (uri->module_path == NULL) { ++#ifdef PKCS11_DEFAULT_PROVIDER ++ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); ++#else ++ error_f("No module path provided"); + goto fail; +- *providerp = NULL; ++#endif ++ } else { ++ provider_module = strdup(uri->module_path); ++ } + +- if (keyp != NULL) +- *keyp = NULL; +- if (labelsp != NULL) +- *labelsp = NULL; ++ p = xcalloc(1, sizeof(*p)); ++ p->name = pkcs11_uri_get(uri); + +- if (pkcs11_provider_lookup(provider_id) != NULL) { +- debug_f("provider already registered: %s", provider_id); +- goto fail; ++ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL ++ && m->valid) { ++ debug_f("provider module already initialized: %s", provider_module); ++ free(provider_module); ++ /* Skip the initialization of PKCS#11 module */ ++ m->refcount++; ++ p->module = m; ++ p->valid = 1; ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ } else { ++ m = xcalloc(1, sizeof(*m)); ++ p->module = m; ++ m->refcount++; + } ++ + /* open shared pkcs11-library */ +- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { +- error("dlopen %s failed: %s", provider_id, dlerror()); ++ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { ++ error("dlopen %s failed: %s", provider_module, dlerror()); + goto fail; + } + if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { + error("dlsym(C_GetFunctionList) failed: %s", dlerror()); + goto fail; + } +- p = xcalloc(1, sizeof(*p)); +- p->name = xstrdup(provider_id); +- p->handle = handle; ++ ++ p->module->handle = handle; + /* setup the pkcs11 callbacks */ + if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { + error("C_GetFunctionList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->function_list = f; ++ m->function_list = f; + if ((rv = f->C_Initialize(NULL)) != CKR_OK) { + error("C_Initialize for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } + need_finalize = 1; +- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { ++ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { + error("C_GetInfo for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); ++ goto fail; ++ } ++ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); ++ if (uri->lib_manuf != NULL && ++ strcmp(uri->lib_manuf, m->info.manufacturerID)) { ++ debug_f("Skipping provider %s not matching library_manufacturer", ++ m->info.manufacturerID); + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); + debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" + " libraryDescription <%s> libraryVersion %d.%d", +- provider_id, +- p->info.manufacturerID, +- p->info.cryptokiVersion.major, +- p->info.cryptokiVersion.minor, +- p->info.libraryDescription, +- p->info.libraryVersion.major, +- p->info.libraryVersion.minor); +- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { ++ provider_module, ++ m->info.manufacturerID, ++ m->info.cryptokiVersion.major, ++ m->info.cryptokiVersion.minor, ++ m->info.libraryDescription, ++ m->info.libraryVersion.major, ++ m->info.libraryVersion.minor); ++ ++ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { + error("C_GetSlotList failed: %lu", rv); + goto fail; + } +- if (p->nslots == 0) { +- debug_f("provider %s returned no slots", provider_id); ++ if (m->nslots == 0) { ++ debug_f("provider %s returned no slots", provider_module); + ret = -SSH_PKCS11_ERR_NO_SLOTS; + goto fail; + } +- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); +- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) ++ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); ++ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) + != CKR_OK) { + error("C_GetSlotList for provider %s failed: %lu", +- provider_id, rv); ++ provider_module, rv); + goto fail; + } +- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); + p->valid = 1; +- nkeys = 0; +- for (i = 0; i < p->nslots; i++) { +- token = &p->slotinfo[i].token; +- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) ++ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); ++ m->valid = 1; ++ for (i = 0; i < m->nslots; i++) { ++ token = &m->slotinfo[i].token; ++ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) + != CKR_OK) { + error("C_GetTokenInfo for provider %s slot %lu " +- "failed: %lu", provider_id, (u_long)i, rv); +- continue; +- } +- if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { +- debug2_f("ignoring uninitialised token in " +- "provider %s slot %lu", provider_id, (u_long)i); ++ "failed: %lu", provider_module, (u_long)i, rv); ++ token->flags = 0; + continue; } - -- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) -+ if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], rsa)) - goto out; - - key = sshkey_new(KEY_UNSPEC); -@@ -1016,7 +1180,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto out; + rmspace(token->label, sizeof(token->label)); + rmspace(token->manufacturerID, sizeof(token->manufacturerID)); + rmspace(token->model, sizeof(token->model)); + rmspace(token->serialNumber, sizeof(token->serialNumber)); ++ } ++ m->module_path = provider_module; ++ provider_module = NULL; ++ ++ /* insert unconditionally -- remove if there will be no keys later */ ++ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); ++ p->refcount++; /* add to provider list */ ++ *providerp = p; ++ return 0; ++ ++fail: ++ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) ++ error("C_Finalize for provider %s failed: %lu", ++ provider_module, rv); ++ free(provider_module); ++ if (m) { ++ free(m->slotlist); ++ free(m); ++ } ++ if (p) { ++ free(p->name); ++ free(p); ++ } ++ if (handle) ++ dlclose(handle); ++ return ret; ++} ++ ++/* ++ * register a new provider, fails if provider already exists. if ++ * keyp is provided, fetch keys. ++ */ ++static int ++pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, ++ CK_ULONG user) ++{ ++ int nkeys; ++ int ret = -1; ++ struct pkcs11_provider *p = NULL; ++ CK_ULONG i; ++ CK_TOKEN_INFO *token; ++ char *provider_uri = NULL; ++ ++ if (providerp == NULL) ++ goto fail; ++ *providerp = NULL; ++ ++ if (keyp != NULL) ++ *keyp = NULL; ++ ++ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { ++ goto fail; ++ } ++ ++ provider_uri = pkcs11_uri_get(uri); ++ if (pin == NULL && uri->pin != NULL) { ++ pin = uri->pin; ++ } ++ nkeys = 0; ++ for (i = 0; i < p->module->nslots; i++) { ++ token = &p->module->slotinfo[i].token; ++ if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { ++ debug2_f("ignoring uninitialised token in " ++ "provider %s slot %lu", provider_uri, (u_long)i); ++ continue; ++ } ++ if (uri->token != NULL && ++ strcmp(token->label, uri->token) != 0) { ++ debug2_f("ignoring token not matching label (%s) " ++ "specified by PKCS#11 URI in slot %lu", ++ token->label, (unsigned long)i); ++ continue; ++ } ++ if (uri->manuf != NULL && ++ strcmp(token->manufacturerID, uri->manuf) != 0) { ++ debug2_f("ignoring token not matching requrested " ++ "manufacturerID (%s) specified by PKCS#11 URI in " ++ "slot %lu", token->manufacturerID, (unsigned long)i); ++ continue; ++ } + debug("provider %s slot %lu: label <%s> manufacturerID <%s> " + "model <%s> serial <%s> flags 0x%lx", +- provider_id, (unsigned long)i, ++ provider_uri, (unsigned long)i, + token->label, token->manufacturerID, token->model, + token->serialNumber, token->flags); + /* +- * open session, login with pin and retrieve public +- * keys (if keyp is provided) ++ * open session if not yet openend, login with pin and ++ * retrieve public keys (if keyp is provided) + */ +- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || ++ if ((p->module->slotinfo[i].session != 0 || ++ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ + keyp == NULL) + continue; +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +- if (nkeys == 0 && !p->slotinfo[i].logged_in && ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && + pkcs11_interactive) { + /* + * Some tokens require login before they will + * expose keys. + */ +- if (pkcs11_login_slot(p, &p->slotinfo[i], ++ debug3_f("Trying to login as there were no keys found"); ++ if (pkcs11_login_slot(p, &p->module->slotinfo[i], + CKU_USER) < 0) { + error("login failed"); + continue; + } +- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ } ++ if (nkeys == 0 && uri->object != NULL) { ++ debug3_f("No keys found. Retrying without label (%s) ", ++ uri->object); ++ /* Try once more without the label filter */ ++ char *label = uri->object; ++ uri->object = NULL; /* XXX clone uri? */ ++ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); ++ uri->object = label; } + } ++ pin = NULL; /* Will be cleaned up with URI */ -- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) -+ if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], &cert_attr[1], ec)) - goto out; + /* now owned by caller */ + *providerp = p; - key = sshkey_new(KEY_UNSPEC); -@@ -1036,7 +1200,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - goto out; +- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); +- p->refcount++; /* add to provider list */ +- ++ free(provider_uri); + return (nkeys); + fail: +- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) +- error("C_Finalize for provider %s failed: %lu", +- provider_id, rv); + if (p) { +- free(p->name); +- free(p->slotlist); +- free(p->slotinfo); +- free(p); ++ TAILQ_REMOVE(&pkcs11_providers, p, next); ++ pkcs11_provider_unref(p); } - out: -- for (i = 0; i < 3; i++) -+ for (i = 0; i < nattr; i++) - free(cert_attr[i].pValue); - X509_free(x509); - RSA_free(rsa); -@@ -1071,11 +1235,12 @@ have_rsa_key(const RSA *rsa) - */ - static int - pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) - { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[1]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1092,10 +1257,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, - key_attr[0].pValue = &key_class; - key_attr[0].ulValueLen = sizeof(key_class); +- if (handle) +- dlclose(handle); + if (ret > 0) + ret = -1; + return (ret); + } -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ if (uri->id != NULL) { -+ key_attr[nattr].type = CKA_ID; -+ key_attr[nattr].pValue = uri->id; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ key_attr[nattr].ulValueLen = strlen(uri->object); -+ nattr++; +-/* +- * register a new provider and get number of keys hold by the token, +- * fails if provider already exists +- */ ++static int ++pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, ++ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) ++{ ++ struct pkcs11_uri *uri = NULL; ++ int r; ++ ++ debug_f("called, provider_id = %s", provider_id); ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); + } + -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; - -- rv = f->C_FindObjectsInit(session, key_attr, 1); -+ rv = f->C_FindObjectsInit(session, key_attr, nattr); - if (rv != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - goto fail; -@@ -1175,11 +1353,12 @@ fail: - */ - static int - pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, -- struct sshkey ***keysp, char ***labelsp, int *nkeys) -+ struct sshkey ***keysp, char ***labelsp, int *nkeys, struct pkcs11_uri *uri) ++ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); ++ pkcs11_uri_cleanup(uri); ++ ++ return r; ++} ++ + int +-pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, +- char ***labelsp) ++pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, ++ struct sshkey ***keyp, char ***labelsp) { - struct sshkey *key = NULL; - CK_OBJECT_CLASS key_class; -- CK_ATTRIBUTE key_attr[2]; -+ CK_ATTRIBUTE key_attr[3]; -+ int nattr = 1; - CK_SESSION_HANDLE session; - CK_FUNCTION_LIST *f = NULL; - CK_RV rv; -@@ -1195,10 +1374,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, - key_attr[0].pValue = &key_class; - key_attr[0].ulValueLen = sizeof(key_class); + struct pkcs11_provider *p = NULL; + int nkeys; ++ char *provider_uri = pkcs11_uri_get(uri); ++ ++ debug_f("called, provider_uri = %s", provider_uri); -- session = p->slotinfo[slotidx].session; -- f = p->function_list; -+ if (uri->id != NULL) { -+ key_attr[nattr].type = CKA_ID; -+ key_attr[nattr].pValue = uri->id; -+ key_attr[nattr].ulValueLen = uri->id_len; -+ nattr++; -+ } -+ if (uri->object != NULL) { -+ key_attr[nattr].type = CKA_LABEL; -+ key_attr[nattr].pValue = uri->object; -+ key_attr[nattr].ulValueLen = strlen(uri->object); -+ nattr++; +- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, +- &p, CKU_USER); ++ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); + + /* no keys found or some other error, de-register provider */ + if (nkeys <= 0 && p != NULL) { +@@ -1683,7 +2002,37 @@ pkcs11_add_provider(char *provider_id, c + pkcs11_provider_unref(p); + } + if (nkeys == 0) +- debug_f("provider %s returned no keys", provider_id); ++ debug_f("provider %s returned no keys", provider_uri); ++ ++ free(provider_uri); ++ return nkeys; ++} ++ ++/* ++ * register a new provider and get number of keys hold by the token, ++ * fails if provider already exists ++ */ ++int ++pkcs11_add_provider(char *provider_id, char *pin, ++ struct sshkey ***keyp, char ***labelsp) ++{ ++ struct pkcs11_uri *uri; ++ int nkeys; ++ ++ uri = pkcs11_uri_init(); ++ if (uri == NULL) ++ fatal("Failed to init PKCS#11 URI"); ++ ++ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && ++ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { ++ if (pkcs11_uri_parse(provider_id, uri) != 0) ++ fatal("Failed to parse PKCS#11 URI"); ++ } else { ++ uri->module_path = strdup(provider_id); + } + -+ session = p->module->slotinfo[slotidx].session; -+ f = p->module->function_list; ++ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); ++ pkcs11_uri_cleanup(uri); -- rv = f->C_FindObjectsInit(session, key_attr, 1); -+ rv = f->C_FindObjectsInit(session, key_attr, nattr); - if (rv != CKR_OK) { - error("C_FindObjectsInit failed: %lu", rv); - goto fail; -@@ -1466,16 +1658,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, + return (nkeys); } - #endif /* WITH_PKCS11_KEYGEN */ +diff -up openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11.h +--- openssh-8.7p1/ssh-pkcs11.h.pkcs11-uri 2021-08-20 06:03:49.000000000 +0200 ++++ openssh-8.7p1/ssh-pkcs11.h 2021-08-30 13:07:43.666700121 +0200 +@@ -22,10 +22,14 @@ + #define SSH_PKCS11_ERR_PIN_REQUIRED 4 + #define SSH_PKCS11_ERR_PIN_LOCKED 5 --/* -- * register a new provider, fails if provider already exists. if -- * keyp is provided, fetch keys. -- */ - static int --pkcs11_register_provider(char *provider_id, char *pin, -- struct sshkey ***keyp, char ***labelsp, -- struct pkcs11_provider **providerp, CK_ULONG user) -+pkcs11_initialize_provider(struct pkcs11_uri *uri, struct pkcs11_provider **providerp) - { -- int nkeys, need_finalize = 0; -+ int need_finalize = 0; - int ret = -1; - struct pkcs11_provider *p = NULL; - void *handle = NULL; -@@ -1484,165 +1670,301 @@ pkcs11_register_provider(char *provider_id, char *pin, - CK_FUNCTION_LIST *f = NULL; - CK_TOKEN_INFO *token; - CK_ULONG i; -- -- if (providerp == NULL) -+ char *provider_module = NULL; -+ struct pkcs11_module *m = NULL; ++#include "ssh-pkcs11-uri.h" ++ + int pkcs11_init(int); + void pkcs11_terminate(void); + int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); ++int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); + int pkcs11_del_provider(char *); ++int pkcs11_uri_write(const struct sshkey *, FILE *); + #ifdef WITH_PKCS11_KEYGEN + struct sshkey * + pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, +diff -up openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.c +--- openssh-8.7p1/ssh-pkcs11-uri.c.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 ++++ openssh-8.7p1/ssh-pkcs11-uri.c 2021-08-30 13:07:43.667700130 +0200 +@@ -0,0 +1,419 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "includes.h" ++ ++#ifdef ENABLE_PKCS11 ++ ++#include ++#include ++ ++#include "sshkey.h" ++#include "sshbuf.h" ++#include "log.h" ++ ++#define CRYPTOKI_COMPAT ++#include "pkcs11.h" ++ ++#include "ssh-pkcs11-uri.h" ++ ++#define PKCS11_URI_PATH_SEPARATOR ";" ++#define PKCS11_URI_QUERY_SEPARATOR "&" ++#define PKCS11_URI_VALUE_SEPARATOR "=" ++#define PKCS11_URI_ID "id" ++#define PKCS11_URI_TOKEN "token" ++#define PKCS11_URI_OBJECT "object" ++#define PKCS11_URI_LIB_MANUF "library-manufacturer" ++#define PKCS11_URI_MANUF "manufacturer" ++#define PKCS11_URI_MODULE_PATH "module-path" ++#define PKCS11_URI_PIN_VALUE "pin-value" ++ ++/* Keyword tokens. */ ++typedef enum { ++ pId, pToken, pObject, pLibraryManufacturer, pManufacturer, pModulePath, ++ pPinValue, pBadOption ++} pkcs11uriOpCodes; ++ ++/* Textual representation of the tokens. */ ++static struct { ++ const char *name; ++ pkcs11uriOpCodes opcode; ++} keywords[] = { ++ { PKCS11_URI_ID, pId }, ++ { PKCS11_URI_TOKEN, pToken }, ++ { PKCS11_URI_OBJECT, pObject }, ++ { PKCS11_URI_LIB_MANUF, pLibraryManufacturer }, ++ { PKCS11_URI_MANUF, pManufacturer }, ++ { PKCS11_URI_MODULE_PATH, pModulePath }, ++ { PKCS11_URI_PIN_VALUE, pPinValue }, ++ { NULL, pBadOption } ++}; ++ ++static pkcs11uriOpCodes ++parse_token(const char *cp) ++{ ++ u_int i; ++ ++ for (i = 0; keywords[i].name; i++) ++ if (strncasecmp(cp, keywords[i].name, ++ strlen(keywords[i].name)) == 0) ++ return keywords[i].opcode; ++ ++ return pBadOption; ++} ++ ++int ++percent_decode(char *data, char **outp) ++{ ++ char tmp[3]; ++ char *out, *tmp_end; ++ char *p = data; ++ long value; ++ size_t outlen = 0; ++ ++ out = malloc(strlen(data)+1); /* upper bound */ ++ if (out == NULL) ++ return -1; ++ while (*p != '\0') { ++ switch (*p) { ++ case '%': ++ p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[0] = *p++; ++ if (*p == '\0') ++ goto fail; ++ tmp[1] = *p++; ++ tmp[2] = '\0'; ++ tmp_end = NULL; ++ value = strtol(tmp, &tmp_end, 16); ++ if (tmp_end != tmp+2) ++ goto fail; ++ else ++ out[outlen++] = (char) value; ++ break; ++ default: ++ out[outlen++] = *p++; ++ break; ++ } ++ } ++ ++ /* zero terminate */ ++ out[outlen] = '\0'; ++ *outp = out; ++ return outlen; ++fail: ++ free(out); ++ return -1; ++} ++ ++struct sshbuf * ++percent_encode(const char *data, size_t length, const char *allow_list) ++{ ++ struct sshbuf *b = NULL; ++ char tmp[4], *cp; ++ size_t i; + -+ /* if no provider specified, fallback to p11-kit */ -+ if (uri->module_path == NULL) { -+#ifdef PKCS11_DEFAULT_PROVIDER -+ provider_module = strdup(PKCS11_DEFAULT_PROVIDER); -+#else -+ error("%s: No module path provided", __func__); - goto fail; -- *providerp = NULL; -- -- if (keyp != NULL) -- *keyp = NULL; -- if (labelsp != NULL) -- *labelsp = NULL; -+#endif -+ } else { -+ provider_module = strdup(uri->module_path); ++ if ((b = sshbuf_new()) == NULL) ++ return NULL; ++ for (i = 0; i < length; i++) { ++ cp = strchr(allow_list, data[i]); ++ /* if c is specified as '\0' pointer to terminator is returned !! */ ++ if (cp != NULL && *cp != '\0') { ++ if (sshbuf_put(b, &data[i], 1) != 0) ++ goto err; ++ } else ++ if (snprintf(tmp, 4, "%%%02X", (unsigned char) data[i]) < 3 ++ || sshbuf_put(b, tmp, 3) != 0) ++ goto err; + } - -- if (pkcs11_provider_lookup(provider_id) != NULL) { -- debug("%s: provider already registered: %s", -- __func__, provider_id); -- goto fail; -+ p = xcalloc(1, sizeof(*p)); -+ p->name = pkcs11_uri_get(uri); ++ if (sshbuf_put(b, "\0", 1) == 0) ++ return b; ++err: ++ sshbuf_free(b); ++ return NULL; ++} + -+ if ((m = pkcs11_provider_lookup_module(provider_module)) != NULL -+ && m->valid) { -+ debug("%s: provider module already initialized: %s", -+ __func__, provider_module); -+ free(provider_module); -+ /* Skip the initialization of PKCS#11 module */ -+ m->refcount++; -+ p->module = m; -+ p->valid = 1; -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; -+ } else { -+ m = xcalloc(1, sizeof(*m)); -+ p->module = m; -+ m->refcount++; - } ++char * ++pkcs11_uri_append(char *part, const char *separator, const char *key, ++ struct sshbuf *value) ++{ ++ char *new_part; ++ size_t size = 0; + - /* open shared pkcs11-library */ -- if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) { -- error("dlopen %s failed: %s", provider_id, dlerror()); -+ if ((handle = dlopen(provider_module, RTLD_NOW)) == NULL) { -+ error("dlopen %s failed: %s", provider_module, dlerror()); - goto fail; - } - if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) { - error("dlsym(C_GetFunctionList) failed: %s", dlerror()); - goto fail; - } -- p = xcalloc(1, sizeof(*p)); -- p->name = xstrdup(provider_id); -- p->handle = handle; ++ if (value == NULL) ++ return NULL; + -+ p->module->handle = handle; - /* setup the pkcs11 callbacks */ - if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { - error("C_GetFunctionList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->function_list = f; -+ m->function_list = f; - if ((rv = f->C_Initialize(NULL)) != CKR_OK) { - error("C_Initialize for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } - need_finalize = 1; -- if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { -+ if ((rv = f->C_GetInfo(&m->info)) != CKR_OK) { - error("C_GetInfo for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); -+ rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); -+ if (uri->lib_manuf != NULL && -+ strcmp(uri->lib_manuf, m->info.manufacturerID)) { -+ debug("%s: Skipping provider %s not matching library_manufacturer", -+ __func__, m->info.manufacturerID); -+ goto fail; ++ size = asprintf(&new_part, ++ "%s%s%s" PKCS11_URI_VALUE_SEPARATOR "%s", ++ (part != NULL ? part : ""), ++ (part != NULL ? separator : ""), ++ key, sshbuf_ptr(value)); ++ sshbuf_free(value); ++ free(part); ++ ++ if (size <= 0) ++ return NULL; ++ return new_part; ++} ++ ++char * ++pkcs11_uri_get(struct pkcs11_uri *uri) ++{ ++ size_t size = 0; ++ char *p = NULL, *path = NULL, *query = NULL; ++ ++ /* compose a percent-encoded ID */ ++ if (uri->id_len > 0) { ++ struct sshbuf *key_id = percent_encode(uri->id, uri->id_len, ""); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_ID, key_id); ++ if (path == NULL) ++ goto err; + } -+ rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); - debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" - " libraryDescription <%s> libraryVersion %d.%d", -- provider_id, -- p->info.manufacturerID, -- p->info.cryptokiVersion.major, -- p->info.cryptokiVersion.minor, -- p->info.libraryDescription, -- p->info.libraryVersion.major, -- p->info.libraryVersion.minor); -- if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &p->nslots)) != CKR_OK) { -+ provider_module, -+ m->info.manufacturerID, -+ m->info.cryptokiVersion.major, -+ m->info.cryptokiVersion.minor, -+ m->info.libraryDescription, -+ m->info.libraryVersion.major, -+ m->info.libraryVersion.minor); + -+ if ((rv = f->C_GetSlotList(CK_TRUE, NULL, &m->nslots)) != CKR_OK) { - error("C_GetSlotList failed: %lu", rv); - goto fail; - } -- if (p->nslots == 0) { -+ if (m->nslots == 0) { - debug("%s: provider %s returned no slots", __func__, -- provider_id); -+ provider_module); - ret = -SSH_PKCS11_ERR_NO_SLOTS; - goto fail; - } -- p->slotlist = xcalloc(p->nslots, sizeof(CK_SLOT_ID)); -- if ((rv = f->C_GetSlotList(CK_TRUE, p->slotlist, &p->nslots)) -+ m->slotlist = xcalloc(m->nslots, sizeof(CK_SLOT_ID)); -+ if ((rv = f->C_GetSlotList(CK_TRUE, m->slotlist, &m->nslots)) - != CKR_OK) { - error("C_GetSlotList for provider %s failed: %lu", -- provider_id, rv); -+ provider_module, rv); - goto fail; - } -- p->slotinfo = xcalloc(p->nslots, sizeof(struct pkcs11_slotinfo)); - p->valid = 1; -- nkeys = 0; -- for (i = 0; i < p->nslots; i++) { -- token = &p->slotinfo[i].token; -- if ((rv = f->C_GetTokenInfo(p->slotlist[i], token)) -+ m->slotinfo = xcalloc(m->nslots, sizeof(struct pkcs11_slotinfo)); -+ m->valid = 1; -+ for (i = 0; i < m->nslots; i++) { -+ token = &m->slotinfo[i].token; -+ if ((rv = f->C_GetTokenInfo(m->slotlist[i], token)) - != CKR_OK) { - error("C_GetTokenInfo for provider %s slot %lu " -- "failed: %lu", provider_id, (unsigned long)i, rv); -+ "failed: %lu", provider_module, (unsigned long)i, rv); -+ token->flags = 0; - continue; - } -+ rmspace(token->label, sizeof(token->label)); -+ rmspace(token->manufacturerID, sizeof(token->manufacturerID)); -+ rmspace(token->model, sizeof(token->model)); -+ rmspace(token->serialNumber, sizeof(token->serialNumber)); ++ /* Write object label */ ++ if (uri->object) { ++ struct sshbuf *label = percent_encode(uri->object, strlen(uri->object), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_OBJECT, label); ++ if (path == NULL) ++ goto err; + } -+ m->module_path = provider_module; -+ provider_module = NULL; + -+ /* insert unconditionally -- remove if there will be no keys later */ -+ TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -+ p->refcount++; /* add to provider list */ -+ *providerp = p; -+ return 0; ++ /* Write token label */ ++ if (uri->token) { ++ struct sshbuf *label = percent_encode(uri->token, strlen(uri->token), ++ PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_TOKEN, label); ++ if (path == NULL) ++ goto err; ++ } + -+fail: -+ if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -+ error("C_Finalize for provider %s failed: %lu", -+ provider_module, rv); -+ free(provider_module); -+ if (m) { -+ free(m->slotlist); -+ free(m); ++ /* Write manufacturer */ ++ if (uri->manuf) { ++ struct sshbuf *manuf = percent_encode(uri->manuf, ++ strlen(uri->manuf), PKCS11_URI_WHITELIST); ++ path = pkcs11_uri_append(path, PKCS11_URI_PATH_SEPARATOR, ++ PKCS11_URI_MANUF, manuf); ++ if (path == NULL) ++ goto err; + } -+ if (p) { -+ free(p->name); -+ free(p); ++ ++ /* Write module_path */ ++ if (uri->module_path) { ++ struct sshbuf *module = percent_encode(uri->module_path, ++ strlen(uri->module_path), PKCS11_URI_WHITELIST "/"); ++ query = pkcs11_uri_append(query, PKCS11_URI_QUERY_SEPARATOR, ++ PKCS11_URI_MODULE_PATH, module); ++ if (query == NULL) ++ goto err; + } -+ if (handle) -+ dlclose(handle); -+ return ret; ++ ++ size = asprintf(&p, PKCS11_URI_SCHEME "%s%s%s", ++ path != NULL ? path : "", ++ query != NULL ? "?" : "", ++ query != NULL ? query : ""); ++err: ++ free(query); ++ free(path); ++ if (size <= 0) ++ return NULL; ++ return p; ++} ++ ++struct pkcs11_uri * ++pkcs11_uri_init() ++{ ++ struct pkcs11_uri *d = calloc(1, sizeof(struct pkcs11_uri)); ++ return d; +} + -+/* -+ * register a new provider, fails if provider already exists. if -+ * keyp is provided, fetch keys. -+ */ -+static int -+pkcs11_register_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp, struct pkcs11_provider **providerp, -+ CK_ULONG user) ++void ++pkcs11_uri_cleanup(struct pkcs11_uri *pkcs11) +{ -+ int nkeys; -+ int ret = -1; -+ struct pkcs11_provider *p = NULL; -+ CK_ULONG i; -+ CK_TOKEN_INFO *token; -+ char *provider_uri = NULL; ++ if (pkcs11 == NULL) { ++ return; ++ } + -+ if (providerp == NULL) -+ goto fail; -+ *providerp = NULL; ++ free(pkcs11->id); ++ free(pkcs11->module_path); ++ free(pkcs11->token); ++ free(pkcs11->object); ++ free(pkcs11->lib_manuf); ++ free(pkcs11->manuf); ++ if (pkcs11->pin) ++ freezero(pkcs11->pin, strlen(pkcs11->pin)); ++ free(pkcs11); ++} + -+ if (keyp != NULL) -+ *keyp = NULL; ++int ++pkcs11_uri_parse(const char *uri, struct pkcs11_uri *pkcs11) ++{ ++ char *saveptr1, *saveptr2, *str1, *str2, *tok; ++ int rv = 0, len; ++ char *p = NULL; + -+ if ((ret = pkcs11_initialize_provider(uri, &p)) != 0) { -+ goto fail; ++ size_t scheme_len = strlen(PKCS11_URI_SCHEME); ++ if (strlen(uri) < scheme_len || /* empty URI matches everything */ ++ strncmp(uri, PKCS11_URI_SCHEME, scheme_len) != 0) { ++ error_f("The '%s' does not look like PKCS#11 URI", uri); ++ return -1; + } + -+ provider_uri = pkcs11_uri_get(uri); -+ nkeys = 0; -+ 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); -+ 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__, -+ token->label, (unsigned long)i); -+ continue; -+ } -+ if (uri->manuf != NULL && -+ strcmp(token->manufacturerID, uri->manuf) != 0) { -+ debug2("%s: ignoring token not matching requrested " -+ "manufacturerID (%s) specified by PKCS#11 URI in " -+ "slot %lu", __func__, -+ token->manufacturerID, (unsigned long)i); - continue; - } -- rmspace(token->label, sizeof(token->label)); -- rmspace(token->manufacturerID, sizeof(token->manufacturerID)); -- rmspace(token->model, sizeof(token->model)); -- rmspace(token->serialNumber, sizeof(token->serialNumber)); - debug("provider %s slot %lu: label <%s> manufacturerID <%s> " - "model <%s> serial <%s> flags 0x%lx", -- provider_id, (unsigned long)i, -+ provider_uri, (unsigned long)i, - token->label, token->manufacturerID, token->model, - token->serialNumber, token->flags); -+ if (pin == NULL && uri->pin != NULL) { -+ pin = uri->pin; -+ } - /* -- * open session, login with pin and retrieve public -- * keys (if keyp is provided) -+ * open session if not yet openend, login with pin and -+ * retrieve public keys (if keyp is provided) - */ -- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || -+ if ((p->module->slotinfo[i].session != 0 || -+ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ - keyp == NULL) - continue; -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -- if (nkeys == 0 && !p->slotinfo[i].logged_in && -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && - pkcs11_interactive) { - /* - * Some tokens require login before they will - * expose keys. - */ -- if (pkcs11_login_slot(p, &p->slotinfo[i], -+ debug3("%s: Trying to login as there were no keys found", -+ __func__); -+ if (pkcs11_login_slot(p, &p->module->slotinfo[i], - CKU_USER) < 0) { - error("login failed"); - continue; - } -- pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); -- pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ } -+ if (nkeys == 0 && uri->object != NULL) { -+ debug3("%s: No keys found. Retrying without label (%s) ", -+ __func__, uri->object); -+ /* Try once more without the label filter */ -+ char *label = uri->object; -+ uri->object = NULL; /* XXX clone uri? */ -+ pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys, uri); -+ uri->object = label; - } -+ pin = NULL; /* Will be cleaned up with URI */ - } - - /* now owned by caller */ - *providerp = p; - -- TAILQ_INSERT_TAIL(&pkcs11_providers, p, next); -- p->refcount++; /* add to provider list */ -- -+ free(provider_uri); - return (nkeys); - fail: -- if (need_finalize && (rv = f->C_Finalize(NULL)) != CKR_OK) -- error("C_Finalize for provider %s failed: %lu", -- provider_id, rv); - if (p) { -- free(p->name); -- free(p->slotlist); -- free(p->slotinfo); -- free(p); -+ TAILQ_REMOVE(&pkcs11_providers, p, next); -+ pkcs11_provider_unref(p); - } -- if (handle) -- dlclose(handle); - return (ret); - } - --/* -- * register a new provider and get number of keys hold by the token, -- * fails if provider already exists -- */ -+static int -+pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, -+ char ***labelsp, struct pkcs11_provider **providerp, CK_ULONG user) -+{ -+ struct pkcs11_uri *uri = NULL; -+ int r; -+ -+ debug("%s: called, provider_id = %s", __func__, provider_id); ++ if (pkcs11 == NULL) { ++ error_f("Bad arguments. The pkcs11 can't be null"); ++ return -1; ++ } + -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("failed to init PKCS#11 URI"); ++ /* skip URI schema name */ ++ p = strdup(uri); ++ str1 = p; + -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); ++ /* everything before ? */ ++ tok = strtok_r(str1, "?", &saveptr1); ++ if (tok == NULL) { ++ error_f("pk11-path expected, got EOF"); ++ rv = -1; ++ goto out; + } + -+ r = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, providerp, user); -+ pkcs11_uri_cleanup(uri); -+ -+ return r; -+} ++ /* skip URI schema name: ++ * the scheme ensures that there is at least something before "?" ++ * allowing empty pk11-path. Resulting token at worst pointing to ++ * \0 byte */ ++ tok = tok + scheme_len; + - int --pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, -- char ***labelsp) -+pkcs11_add_provider_by_uri(struct pkcs11_uri *uri, char *pin, -+ struct sshkey ***keyp, char ***labelsp) - { -- struct pkcs11_provider *p = NULL; - int nkeys; -+ struct pkcs11_provider *p = NULL; -+ char *provider_uri = pkcs11_uri_get(uri); ++ /* parse pk11-path */ ++ for (str2 = tok; ; str2 = NULL) { ++ char **charptr, *arg = NULL; ++ pkcs11uriOpCodes opcode; ++ tok = strtok_r(str2, PKCS11_URI_PATH_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ opcode = parse_token(tok); ++ if (opcode != pBadOption) ++ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ + -+ debug("%s: called, provider_uri = %s", __func__, provider_uri); - -- nkeys = pkcs11_register_provider(provider_id, pin, keyp, labelsp, -- &p, CKU_USER); -+ nkeys = pkcs11_register_provider_by_uri(uri, pin, keyp, labelsp, &p, CKU_USER); - - /* no keys found or some other error, de-register provider */ - if (nkeys <= 0 && p != NULL) { -@@ -1652,7 +1974,37 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, - } - if (nkeys == 0) - debug("%s: provider %s returned no keys", __func__, -- provider_id); -+ provider_uri); ++ switch (opcode) { ++ case pId: ++ /* CKA_ID */ ++ if (pkcs11->id != NULL) { ++ verbose_f("The id already set in the PKCS#11 URI"); ++ rv = -1; ++ goto out; ++ } ++ len = percent_decode(arg, &pkcs11->id); ++ if (len <= 0) { ++ verbose_f("Failed to percent-decode CKA_ID: %s", arg); ++ rv = -1; ++ goto out; ++ } else ++ pkcs11->id_len = len; ++ debug3_f("Setting CKA_ID = %s from PKCS#11 URI", arg); ++ break; ++ case pToken: ++ /* CK_TOKEN_INFO -> label */ ++ charptr = &pkcs11->token; ++ parse_string: ++ if (*charptr != NULL) { ++ verbose_f("The %s already set in the PKCS#11 URI", ++ keywords[opcode].name); ++ rv = -1; ++ goto out; ++ } ++ percent_decode(arg, charptr); ++ debug3_f("Setting %s = %s from PKCS#11 URI", ++ keywords[opcode].name, *charptr); ++ break; + -+ free(provider_uri); -+ return nkeys; -+} ++ case pObject: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->object; ++ goto parse_string; + -+/* -+ * register a new provider and get number of keys hold by the token, -+ * fails if provider already exists -+ */ -+int -+pkcs11_add_provider(char *provider_id, char *pin, -+ struct sshkey ***keyp, char ***labelsp) -+{ -+ struct pkcs11_uri *uri; -+ int nkeys; ++ case pManufacturer: ++ /* CK_TOKEN_INFO -> manufacturerID */ ++ charptr = &pkcs11->manuf; ++ goto parse_string; + -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); ++ case pLibraryManufacturer: ++ /* CK_INFO -> manufacturerID */ ++ charptr = &pkcs11->lib_manuf; ++ goto parse_string; + -+ if (strlen(provider_id) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(provider_id, PKCS11_URI_SCHEME, strlen(PKCS11_URI_SCHEME)) == 0) { -+ if (pkcs11_uri_parse(provider_id, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI"); -+ } else { -+ uri->module_path = strdup(provider_id); ++ default: ++ /* Unrecognized attribute in the URI path SHOULD be error */ ++ verbose_f("Unknown part of path in PKCS#11 URI: %s", tok); ++ } + } + -+ nkeys = pkcs11_add_provider_by_uri(uri, pin, keyp, labelsp); -+ pkcs11_uri_cleanup(uri); - - 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 -+++ b/ssh-pkcs11.h -@@ -22,10 +22,14 @@ - #define SSH_PKCS11_ERR_PIN_REQUIRED 4 - #define SSH_PKCS11_ERR_PIN_LOCKED 5 - -+#include "ssh-pkcs11-uri.h" ++ tok = strtok_r(NULL, "?", &saveptr1); ++ if (tok == NULL) { ++ goto out; ++ } ++ /* parse pk11-query (optional) */ ++ for (str2 = tok; ; str2 = NULL) { ++ char *arg; ++ pkcs11uriOpCodes opcode; ++ tok = strtok_r(str2, PKCS11_URI_QUERY_SEPARATOR, &saveptr2); ++ if (tok == NULL) ++ break; ++ opcode = parse_token(tok); ++ if (opcode != pBadOption) ++ arg = tok + strlen(keywords[opcode].name) + 1; /* separator "=" */ + - int pkcs11_init(int); - void pkcs11_terminate(void); - int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); -+int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***, char ***); - int pkcs11_del_provider(char *); -+int pkcs11_uri_write(const struct sshkey *, FILE *); - #ifdef WITH_PKCS11_KEYGEN - struct sshkey * - pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, -diff --git a/ssh.c b/ssh.c -index 15aee569..976844cb 100644 ---- a/ssh.c -+++ b/ssh.c -@@ -795,6 +795,14 @@ main(int ac, char **av) - options.gss_deleg_creds = 1; - break; - case 'i': -+#ifdef ENABLE_PKCS11 -+ if (strlen(optarg) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(optarg, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ add_identity_file(&options, NULL, optarg, 1); -+ break; ++ switch (opcode) { ++ case pModulePath: ++ /* module-path is PKCS11Provider */ ++ if (pkcs11->module_path != NULL) { ++ verbose_f("Multiple module-path attributes are" ++ "not supported the PKCS#11 URI"); ++ rv = -1; ++ goto out; + } -+#endif - p = tilde_expand_filename(optarg, getuid()); - if (stat(p, &st) == -1) - fprintf(stderr, "Warning: Identity file %s " -@@ -1603,6 +1611,7 @@ main(int ac, char **av) - free(options.certificate_files[i]); - options.certificate_files[i] = NULL; - } -+ pkcs11_terminate(); - - skip_connect: - exit_status = ssh_session2(ssh, pw); -@@ -2076,6 +2085,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) - options.escape_char : SSH_ESCAPECHAR_NONE, id); - } - -+#ifdef ENABLE_PKCS11 -+static void -+load_pkcs11_identity(char *pkcs11_uri, char *identity_files[], -+ struct sshkey *identity_keys[], int *n_ids) -+{ -+ int nkeys, i; -+ struct sshkey **keys; -+ struct pkcs11_uri *uri; -+ -+ debug("identity file '%s' from pkcs#11", pkcs11_uri); -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); -+ -+ if (pkcs11_uri_parse(pkcs11_uri, uri) != 0) -+ fatal("Failed to parse PKCS#11 URI %s", pkcs11_uri); -+ -+ /* we need to merge URI and provider together */ -+ if (options.pkcs11_provider != NULL && uri->module_path == NULL) -+ uri->module_path = strdup(options.pkcs11_provider); ++ percent_decode(arg, &pkcs11->module_path); ++ debug3_f("Setting PKCS11Provider = %s from PKCS#11 URI", ++ pkcs11->module_path); ++ break; + -+ if (options.num_identity_files < SSH_MAX_IDENTITY_FILES && -+ (nkeys = pkcs11_add_provider_by_uri(uri, NULL, &keys, NULL)) > 0) { -+ for (i = 0; i < nkeys; i++) { -+ if (*n_ids >= SSH_MAX_IDENTITY_FILES) { -+ sshkey_free(keys[i]); -+ continue; ++ case pPinValue: ++ /* pin-value */ ++ if (pkcs11->pin != NULL) { ++ verbose_f("Multiple pin-value attributes are" ++ "not supported the PKCS#11 URI"); ++ rv = -1; ++ goto out; + } -+ identity_keys[*n_ids] = keys[i]; -+ identity_files[*n_ids] = pkcs11_uri_get(uri); -+ (*n_ids)++; ++ percent_decode(arg, &pkcs11->pin); ++ debug3_f("Setting PIN from PKCS#11 URI"); ++ break; ++ ++ default: ++ /* Unrecognized attribute in the URI query SHOULD be ignored */ ++ verbose_f("Unknown part of query in PKCS#11 URI: %s", tok); + } -+ free(keys); + } -+ -+ pkcs11_uri_cleanup(uri); ++out: ++ free(p); ++ return rv; +} -+#endif /* ENABLE_PKCS11 */ -+ - /* Loads all IdentityFile and CertificateFile keys */ - static void - load_public_identity_files(struct passwd *pw) -@@ -2090,11 +2138,6 @@ load_public_identity_files(struct passwd *pw) - char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; - struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; - int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; --#ifdef ENABLE_PKCS11 -- struct sshkey **keys = NULL; -- char **comments = NULL; -- int nkeys; --#endif /* PKCS11 */ - - n_ids = n_certs = 0; - memset(identity_files, 0, sizeof(identity_files)); -@@ -2107,33 +2150,46 @@ load_public_identity_files(struct passwd *pw) - sizeof(certificate_file_userprovided)); - - #ifdef ENABLE_PKCS11 -- if (options.pkcs11_provider != NULL && -- options.num_identity_files < SSH_MAX_IDENTITY_FILES && -- (pkcs11_init(!options.batch_mode) == 0) && -- (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL, -- &keys, &comments)) > 0) { -- for (i = 0; i < nkeys; i++) { -- if (n_ids >= SSH_MAX_IDENTITY_FILES) { -- sshkey_free(keys[i]); -- free(comments[i]); -- continue; -- } -- identity_keys[n_ids] = keys[i]; -- identity_files[n_ids] = comments[i]; /* transferred */ -- n_ids++; -- } -- free(keys); -- free(comments); -+ /* handle fallback from PKCS11Provider option */ -+ pkcs11_init(!options.batch_mode); + -+ if (options.pkcs11_provider != NULL) { -+ struct pkcs11_uri *uri; ++#endif /* ENABLE_PKCS11 */ +diff -up openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri openssh-8.7p1/ssh-pkcs11-uri.h +--- openssh-8.7p1/ssh-pkcs11-uri.h.pkcs11-uri 2021-08-30 13:07:43.667700130 +0200 ++++ openssh-8.7p1/ssh-pkcs11-uri.h 2021-08-30 13:07:43.667700130 +0200 +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2017 Red Hat ++ * ++ * Authors: Jakub Jelen ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ + -+ uri = pkcs11_uri_init(); -+ if (uri == NULL) -+ fatal("Failed to init PKCS#11 URI"); ++#define PKCS11_URI_SCHEME "pkcs11:" ++#define PKCS11_URI_WHITELIST "abcdefghijklmnopqrstuvwxyz" \ ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ ++ "0123456789_-.()" + -+ /* Construct simple PKCS#11 URI to simplify access */ -+ uri->module_path = strdup(options.pkcs11_provider); ++struct pkcs11_uri { ++ /* path */ ++ char *id; ++ size_t id_len; ++ char *token; ++ char *object; ++ char *lib_manuf; ++ char *manuf; ++ /* query */ ++ char *module_path; ++ char *pin; /* Only parsed, but not printed */ ++}; + -+ /* Add it as any other IdentityFile */ -+ cp = pkcs11_uri_get(uri); -+ add_identity_file(&options, NULL, cp, 1); -+ free(cp); ++struct pkcs11_uri *pkcs11_uri_init(); ++void pkcs11_uri_cleanup(struct pkcs11_uri *); ++int pkcs11_uri_parse(const char *, struct pkcs11_uri *); ++struct pkcs11_uri *pkcs11_uri_init(); ++char *pkcs11_uri_get(struct pkcs11_uri *uri); + -+ pkcs11_uri_cleanup(uri); - } - #endif /* ENABLE_PKCS11 */ - for (i = 0; i < options.num_identity_files; i++) { -+ char *name = options.identity_files[i]; - if (n_ids >= SSH_MAX_IDENTITY_FILES || -- strcasecmp(options.identity_files[i], "none") == 0) { -+ strcasecmp(name, "none") == 0) { - free(options.identity_files[i]); - options.identity_files[i] = NULL; - continue; - } -- cp = tilde_expand_filename(options.identity_files[i], getuid()); -+#ifdef ENABLE_PKCS11 -+ if (strlen(name) >= strlen(PKCS11_URI_SCHEME) && -+ strncmp(name, PKCS11_URI_SCHEME, -+ strlen(PKCS11_URI_SCHEME)) == 0) { -+ load_pkcs11_identity(name, identity_files, -+ identity_keys, &n_ids); -+ free(options.identity_files[i]); -+ continue; -+ } -+#endif /* ENABLE_PKCS11 */ -+ cp = tilde_expand_filename(name, getuid()); - filename = percent_expand(cp, "d", pw->pw_dir, - "u", pw->pw_name, "l", thishost, "h", host, - "r", options.user, (char *)NULL); -diff --git a/ssh_config.5 b/ssh_config.5 -index 06a32d31..4b2763bd 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -986,6 +986,21 @@ may also be used in conjunction with - .Cm CertificateFile - in order to provide any certificate also needed for authentication with - the identity. -+.Pp -+The authentication identity can be also specified in a form of PKCS#11 URI -+starting with a string -+.Cm pkcs11: . -+There is supported a subset of the PKCS#11 URI as defined -+in RFC 7512 (implemented path arguments -+.Cm id , -+.Cm manufacturer , -+.Cm object , -+.Cm token -+and query arguments -+.Cm module-path -+and -+.Cm pin-value -+). The URI can not be in quotes. - .It Cm IgnoreUnknown - Specifies a pattern-list of unknown options to be ignored if they are - encountered in configuration parsing. diff --git a/openssh-8.0p1-preserve-pam-errors.patch b/openssh-8.0p1-preserve-pam-errors.patch new file mode 100644 index 0000000000000000000000000000000000000000..dbdbe938919a4f210a64b1bef72f8491cc2a7202 --- /dev/null +++ b/openssh-8.0p1-preserve-pam-errors.patch @@ -0,0 +1,44 @@ +diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c +--- openssh-8.0p1/auth-pam.c.preserve-pam-errors 2021-03-31 17:03:15.618592347 +0200 ++++ openssh-8.0p1/auth-pam.c 2021-03-31 17:06:58.115220014 +0200 +@@ -511,7 +511,11 @@ sshpam_thread(void *ctxtp) + goto auth_fail; + + if (!do_pam_account()) { +- sshpam_err = PAM_ACCT_EXPIRED; ++ /* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN. ++ * Backward compatibility for other errors. */ ++ if (sshpam_err != PAM_PERM_DENIED ++ && sshpam_err != PAM_USER_UNKNOWN) ++ sshpam_err = PAM_ACCT_EXPIRED; + goto auth_fail; + } + if (sshpam_authctxt->force_pwchange) { +@@ -568,8 +572,10 @@ sshpam_thread(void *ctxtp) + pam_strerror(sshpam_handle, sshpam_err))) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + /* XXX - can't do much about an error here */ +- if (sshpam_err == PAM_ACCT_EXPIRED) +- ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer); ++ if (sshpam_err == PAM_PERM_DENIED ++ || sshpam_err == PAM_USER_UNKNOWN ++ || sshpam_err == PAM_ACCT_EXPIRED) ++ ssh_msg_send(ctxt->pam_csock, sshpam_err, buffer); + else if (sshpam_maxtries_reached) + ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer); + else +@@ -856,10 +862,12 @@ sshpam_query(void *ctx, char **name, cha + plen++; + free(msg); + break; ++ case PAM_USER_UNKNOWN: ++ case PAM_PERM_DENIED: + case PAM_ACCT_EXPIRED: ++ sshpam_account_status = 0; ++ /* FALLTHROUGH */ + case PAM_MAXTRIES: +- if (type == PAM_ACCT_EXPIRED) +- sshpam_account_status = 0; + if (type == PAM_MAXTRIES) + sshpam_set_maxtries_reached(1); + /* FALLTHROUGH */ diff --git a/openssh-8.2p1-visibility.patch b/openssh-8.2p1-visibility.patch index 2f0b191c7c091f5bc7922dc96b91ca433459714f..89c35ef64de14194be1c4622c3cf77d3f98dcb6a 100644 --- a/openssh-8.2p1-visibility.patch +++ b/openssh-8.2p1-visibility.patch @@ -26,7 +26,7 @@ index dca158de..afdcb1d2 100644 -int +int __attribute__((visibility("default"))) - sk_sign(uint32_t alg, const uint8_t *message, size_t message_len, + sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, const char *application, const uint8_t *key_handle, size_t key_handle_len, uint8_t flags, const char *pin, struct sk_option **options, @@ -518,7 +518,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len, diff --git a/openssh-8.2p1-x11-without-ipv6.patch b/openssh-8.2p1-x11-without-ipv6.patch new file mode 100644 index 0000000000000000000000000000000000000000..8b83bc30c1184b919627646de46659501c17232b --- /dev/null +++ b/openssh-8.2p1-x11-without-ipv6.patch @@ -0,0 +1,30 @@ +diff --git a/channels.c b/channels.c +--- a/channels.c ++++ b/channels.c +@@ -3933,16 +3933,26 @@ x11_create_display_inet(int x11_display_ + if (ai->ai_family == AF_INET6) + sock_set_v6only(sock); + if (x11_use_localhost) + set_reuseaddr(sock); + if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { + debug2_f("bind port %d: %.100s", port, + strerror(errno)); + close(sock); ++ ++ /* do not remove successfully opened ++ * sockets if the request failed because ++ * the protocol IPv4/6 is not available ++ * (e.g. IPv6 may be disabled while being ++ * supported) ++ */ ++ if (EADDRNOTAVAIL == errno) ++ continue; ++ + for (n = 0; n < num_socks; n++) + close(socks[n]); + num_socks = 0; + break; + } + socks[num_socks++] = sock; + if (num_socks == NUM_SOCKS) + break; diff --git a/openssh-8.2p1.tar.gz b/openssh-8.2p1.tar.gz deleted file mode 100644 index 056b7af039a5e9ededcf29b824a1657cf98f9cf6..0000000000000000000000000000000000000000 Binary files a/openssh-8.2p1.tar.gz and /dev/null differ diff --git a/openssh-8.2p1.tar.gz.asc b/openssh-8.2p1.tar.gz.asc deleted file mode 100644 index a28fad95614e976c0b0de0ed27019a55e617e031..0000000000000000000000000000000000000000 --- a/openssh-8.2p1.tar.gz.asc +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQHDBAABCgAdFiEEWcIRjtIG2SfmZ+vj0+X1a22SDTAFAl5F7e8ACgkQ0+X1a22S -DTBoGQx+Lw7zBdx+GFg4T5uDbpN3zXcscEvPRfKCP07WGVnQsSOqbfa9v0coSnAK -thE0R1iVr/uwFQ+MsgUWFWUQ4yWmKCiIFrnmuX8rqtN3NJBa2PG2mUGi/eAYsctW -ZFPT2B9Is264TWi94/p1dQaDM7tFxqtsLePvq+hPY5IFOu5y5bpEMFCXFHC1TNko -nY3dP2ij3IVjeBSEfotjbE04EUaoOlLh8g65vZV1vQDSIMHoqZ9cWmdtdonK8BNf -ql2JU5RM5+NJk69quQM6RruDfJ6W0XelDaO286u33Loyl1mDAXXT6z8ooSipryHF -OcM2FYUgI42GLfrmpqOsUD0z6GHcUpHWD30wlQkPwX7VWRWQlXORUnVwRTF94TFs -nMOvFOWn7oCn5SVwZXBWitgZ6DGzVdsi1E7WZZZlSbxFgXMFYqCqKL1+dSlcN66l -lRlC/kldYgeRV+OwCM0MPHok77A8W+nwNxWMj56HNnUMJXm3rZTs1MKmKKLfksEr -PlC6zMmFgClq6RayKqHwp14bwAxqsg== -=t8DJ ------END PGP SIGNATURE----- diff --git a/openssh-8.7p1-scp-kill-switch.patch b/openssh-8.7p1-scp-kill-switch.patch new file mode 100644 index 0000000000000000000000000000000000000000..6710304c1dc676ef2e5d13a327fb6fdad52ea93e --- /dev/null +++ b/openssh-8.7p1-scp-kill-switch.patch @@ -0,0 +1,46 @@ +diff -up openssh-8.7p1/pathnames.h.kill-scp openssh-8.7p1/pathnames.h +--- openssh-8.7p1/pathnames.h.kill-scp 2021-09-16 11:37:57.240171687 +0200 ++++ openssh-8.7p1/pathnames.h 2021-09-16 11:42:29.183427917 +0200 +@@ -42,6 +42,7 @@ + #define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key" + #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" + #define _PATH_DH_MODULI SSHDIR "/moduli" ++#define _PATH_SCP_KILL_SWITCH SSHDIR "/disable_scp" + + #ifndef _PATH_SSH_PROGRAM + #define _PATH_SSH_PROGRAM "/usr/bin/ssh" +diff -up openssh-8.7p1/scp.1.kill-scp openssh-8.7p1/scp.1 +--- openssh-8.7p1/scp.1.kill-scp 2021-09-16 12:09:02.646714578 +0200 ++++ openssh-8.7p1/scp.1 2021-09-16 12:26:49.978628226 +0200 +@@ -278,6 +278,13 @@ to print debugging messages about their + This is helpful in + debugging connection, authentication, and configuration problems. + .El ++.Pp ++Usage of SCP protocol can be blocked by creating a world-readable ++.Ar /etc/ssh/disable_scp ++file. If this file exists, when SCP protocol is in use (either remotely or ++via the ++.Fl O ++option), the program will exit. + .Sh EXIT STATUS + .Ex -std scp + .Sh SEE ALSO +diff -up openssh-8.7p1/scp.c.kill-scp openssh-8.7p1/scp.c +--- openssh-8.7p1/scp.c.kill-scp 2021-09-16 11:42:56.013650519 +0200 ++++ openssh-8.7p1/scp.c 2021-09-16 11:53:03.249713836 +0200 +@@ -596,6 +596,14 @@ main(int argc, char **argv) + if (iamremote) + mode = MODE_SCP; + ++ if (mode == MODE_SCP) { ++ FILE *f = fopen(_PATH_SCP_KILL_SWITCH, "r"); ++ if (f != NULL) { ++ fclose(f); ++ fatal("SCP protocol is forbidden via %s", _PATH_SCP_KILL_SWITCH); ++ } ++ } ++ + if ((pwd = getpwuid(userid = getuid())) == NULL) + fatal("unknown user %u", (u_int) userid); + diff --git a/openssh-8.8p1.tar.gz b/openssh-8.8p1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..85ba061dad5479b066f6e2164edc600f8aa0f6dd Binary files /dev/null and b/openssh-8.8p1.tar.gz differ diff --git a/openssh-8.8p1.tar.gz.asc b/openssh-8.8p1.tar.gz.asc new file mode 100644 index 0000000000000000000000000000000000000000..9a1fd8e67da5cdb68c5401e903465b223a06b067 --- /dev/null +++ b/openssh-8.8p1.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmFQfp8ACgkQKj9BTnNg +YLq2SQ/8C3iOHTkyqX82FYt0SKkybebe9b2iBPr91HQOUmx+U3I+vgrSWArXabWJ +uSu0b685RQKlcr7UjEtPk6g0cm45NoJFjju9ljvnOFfZw73V3a5qX15Lx4xRnkRx +v1LJn6Yh12PKLWL4/A1qPQnfAObVwq/BF0BR01FfXLAOt5+lFwYvg79HpE+69b0r +KtcIEpsyTEn2lSKSWD7q4lpe6Z/iR+XzBKfnB6JJXhKyHiDV63hlAJk9Pt3mIvS6 +tnE9/7GDawvi+Tsl018kw3wsf6aHVSQ+O+vzcDgfy0vDJVGjD6Ec9it9FvikXJh6 +3pSTBYuUJdt+CAQYvmEui73v4nrkfouHXsxqgzEDZaTwIZC4wPrvNYxUaIyirWlc +l4/YSnxSxSiYbvPa5eYRBvXvoWbnQXjPOkuhjETxz/KTcHirQpWE9eldi0jHcKUa +FVu9YqMPAjIUd1Jj4vC5bgH7v5cLeEMm/AetMvKsJs+rhY9NZaKpiqOqU2m6Geb+ +sQSXHNTeA8uOlrHim4SmYHtmfglVbH5lIroiUqtRzjbOhMhqUb+yN9+aAxe0bwmN +VcFMSThlbmYokb9bkQryY2I/FfXb997vxgF6v15Z8d9e8HH2zc2Irj1HYXG4Bf3o +WCiSvd8+Tr/FxS2Gn8qj/vgSPWXT0d0Hy4zHW9JeT/jn3RtIYhU= +=EnoG +-----END PGP SIGNATURE----- diff --git a/openssh.spec b/openssh.spec index 66294fb84e04bcaf5042b2d6afd499771e8ed298..a9afa2fd9f3e9ad3cf758dc6758b9f57598d6d0d 100644 --- a/openssh.spec +++ b/openssh.spec @@ -6,10 +6,10 @@ %{?no_gtk2:%global gtk2 0} %global sshd_uid 74 -%global openssh_release 14 +%global openssh_release 1 Name: openssh -Version: 8.2p1 +Version: 8.8p1 Release: %{openssh_release} URL: http://www.openssh.com/portable.html License: BSD @@ -18,7 +18,7 @@ Summary: An open source implementation of SSH protocol version 2 Source0: https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz Source1: https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz.asc Source2: sshd.pam -Source4: http://prdownloads.sourceforge.net/pamsshagentauth/pam_ssh_agent_auth/pam_ssh_agent_auth-0.10.3.tar.bz2 +Source4: http://prdownloads.sourceforge.net/pamsshagentauth/pam_ssh_agent_auth/pam_ssh_agent_auth-0.10.4.tar.gz Source5: pam_ssh_agent-rmheaders Source6: ssh-keycat.pam Source7: sshd.sysconfig @@ -27,8 +27,8 @@ Source10: sshd.socket Source11: sshd.service Source12: sshd-keygen@.service Source13: sshd-keygen -Source14: sshd.tmpfiles Source15: sshd-keygen.target +Source16: ssh-agent.service Patch0: openssh-6.7p1-coverity.patch Patch1: openssh-7.6p1-audit.patch Patch2: openssh-7.1p2-audit-race-condition.patch @@ -40,7 +40,6 @@ Patch7: pam_ssh_agent_auth-0.10.2-compat.patch Patch8: pam_ssh_agent_auth-0.10.2-dereference.patch Patch9: openssh-7.8p1-role-mls.patch Patch10: openssh-6.6p1-privsep-selinux.patch -Patch11: openssh-6.7p1-ldap.patch Patch12: openssh-6.6p1-keycat.patch Patch13: openssh-6.6p1-allow-ip-opts.patch Patch14: openssh-6.6p1-keyperm.patch @@ -53,8 +52,6 @@ Patch20: openssh-4.3p2-askpass-grab-info.patch Patch21: openssh-7.7p1.patch Patch22: openssh-7.8p1-UsePAM-warning.patch Patch23: openssh-6.3p1-ctr-evp-fast.patch -Patch24: openssh-6.6p1-ctr-cavstest.patch -Patch25: openssh-6.7p1-kdf-cavs.patch Patch26: openssh-8.0p1-gssapi-keyex.patch Patch27: openssh-6.6p1-force_krb.patch Patch28: openssh-6.6p1-GSSAPIEnablek5users.patch @@ -74,35 +71,28 @@ Patch41: openssh-7.6p1-cleanup-selinux.patch Patch42: openssh-7.5p1-sandbox.patch Patch43: openssh-8.0p1-pkcs11-uri.patch Patch44: openssh-7.8p1-scp-ipv6.patch -Patch45: openssh-7.9p1-ssh-copy-id.patch Patch46: openssh-8.0p1-crypto-policies.patch Patch47: openssh-8.0p1-openssl-evp.patch Patch48: openssh-8.0p1-openssl-kdf.patch Patch49: openssh-8.2p1-visibility.patch -Patch50: bugfix-sftp-when-parse_user_host_path-empty-path-should-be-allowed.patch -Patch51: bugfix-openssh-6.6p1-log-usepam-no.patch -Patch52: bugfix-openssh-add-option-check-username-splash.patch -Patch53: feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch -Patch54: bugfix-openssh-fix-sftpserver.patch -Patch55: bugfix-debug3-to-verbose-in-command.patch -Patch56: set-sshd-config.patch -Patch57: CVE-2020-12062-1.patch -Patch58: CVE-2020-12062-2.patch -Patch59: upstream-expose-vasnmprintf.patch -Patch60: CVE-2018-15919.patch -Patch61: CVE-2020-14145.patch -Patch62: add-strict-scp-check-for-CVE-2020-15778.patch -Patch63: backport-move-closefrom-to-before-first-malloc.patch -Patch64: backport-upstream-Remove-debug-message-from-sigchld-handler.patch -Patch65: backport-CVE-2021-41617-1.patch -Patch66: backport-CVE-2021-41617-2.patch +Patch50: openssh-8.2p1-x11-without-ipv6.patch +Patch51: openssh-8.0p1-keygen-strip-doseol.patch +Patch52: openssh-8.0p1-preserve-pam-errors.patch +Patch53: openssh-8.7p1-scp-kill-switch.patch + +Patch54: bugfix-sftp-when-parse_user_host_path-empty-path-should-be-allowed.patch +Patch55: bugfix-openssh-6.6p1-log-usepam-no.patch +Patch56: bugfix-openssh-add-option-check-username-splash.patch +Patch57: feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch +Patch58: bugfix-openssh-fix-sftpserver.patch +Patch59: set-sshd-config.patch Requires: /sbin/nologin Requires: libselinux >= 2.3-5 audit-libs >= 1.0.8 Requires: openssh-server = %{version}-%{release} BuildRequires: gtk2-devel libX11-devel openldap-devel autoconf automake perl-interpreter perl-generators -BuildRequires: zlib-devel audit-libs-devel >= 2.0.5 util-linux groff pam-devel fipscheck-devel >= 1.3.0 +BuildRequires: zlib-devel audit-libs-devel >= 2.0.5 util-linux groff pam-devel BuildRequires: openssl-devel >= 0.9.8j perl-podlators systemd-devel gcc p11-kit-devel krb5-devel BuildRequires: libedit-devel ncurses-devel libselinux-devel >= 2.3-5 audit-libs >= 1.0.8 xauth gnupg2 @@ -111,7 +101,6 @@ Recommends: p11-kit %package clients Summary: An open source SSH client applications Requires: openssh = %{version}-%{release} -Requires: fipscheck-lib%{_isa} >= 1.3.0 Requires: crypto-policies >= 20180306-1 %package server @@ -119,14 +108,9 @@ Summary: An open source SSH server daemon Requires: openssh = %{version}-%{release} Requires(pre): shadow Requires: pam >= 1.0.1-3 -Requires: fipscheck-lib%{_isa} >= 1.3.0 Requires: crypto-policies >= 20180306-1 %{?systemd_requires} -%package ldap -Summary: A LDAP support for open source SSH server daemon -Requires: openssh = %{version}-%{release} - %package keycat Summary: A mls keycat backend for openssh Requires: openssh = %{version}-%{release} @@ -134,17 +118,11 @@ Requires: openssh = %{version}-%{release} %package askpass Summary: A passphrase dialog for OpenSSH and X Requires: openssh = %{version}-%{release} -Obsoletes: openssh-askpass-gnome -Provides: openssh-askpass-gnome - -%package cavs -Summary: CAVS tests for FIPS validation -Requires: openssh = %{version}-%{release} %package -n pam_ssh_agent_auth Summary: PAM module for authentication with ssh-agent -Version: 0.10.3 -Release: 9.%{openssh_release} +Version: 0.10.4 +Release: 4.%{openssh_release} License: BSD %description @@ -164,10 +142,6 @@ into and executing commands on a remote machine. This package contains the secure shell daemon (sshd). The sshd daemon allows SSH clients to securely connect to your SSH server. -%description ldap -OpenSSH LDAP backend is a way how to distribute the authorized tokens -among the servers in the network. - %description keycat OpenSSH mls keycat is backend for using the authorized keys in the openssh in the mls mode. @@ -177,10 +151,6 @@ OpenSSH is a free version of SSH (Secure SHell), a program for logging into and executing commands on a remote machine. This package contains an X11 passphrase dialog for OpenSSH. -%description cavs -This package contains test binaries and scripts to make FIPS validation -easier. Now contains CTR and KDF CAVS test driver. - %description -n pam_ssh_agent_auth Provides PAM module for the use of authentication with ssh-agent. Through the use of the\ forwarding of ssh-agent connection it also allows to authenticate with remote ssh-agent \ @@ -191,7 +161,7 @@ instance. The module is most useful for su and sudo service stacks. %prep %setup -q -a 4 -pushd pam_ssh_agent_auth-0.10.3 +pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 %patch3 -p2 -b .psaa-build %patch4 -p2 -b .psaa-seteuid %patch5 -p2 -b .psaa-visibility @@ -204,7 +174,6 @@ popd %patch9 -p1 -b .role-mls %patch10 -p1 -b .privsep-selinux -%patch11 -p1 -b .ldap %patch12 -p1 -b .keycat %patch13 -p1 -b .ip-opts %patch14 -p1 -b .keyperm @@ -216,8 +185,6 @@ popd %patch21 -p1 %patch22 -p1 -b .log-usepam-no %patch23 -p1 -b .evp-ctr -%patch24 -p1 -b .ctr-cavs -%patch25 -p1 -b .kdf-cavs %patch26 -p1 -b .gsskex %patch27 -p1 -b .force_krb %patch29 -p1 -b .ccache_name @@ -237,36 +204,28 @@ popd %patch42 -p1 -b .sandbox %patch43 -p1 -b .pkcs11-uri %patch44 -p1 -b .scp-ipv6 -%patch45 -p1 -b .ssh-copy-id %patch46 -p1 -b .crypto-policies %patch47 -p1 -b .openssl-evp %patch48 -p1 -b .openssl-kdf %patch49 -p1 -b .visibility +%patch50 -p1 -b .x11-ipv6 +%patch51 -p1 -b .keygen-strip-doseol +%patch52 -p1 -b .preserve-pam-errors +%patch53 -p1 -b .kill-scp %patch1 -p1 -b .audit %patch2 -p1 -b .audit-race %patch18 -p1 -b .fips %patch0 -p1 -b .coverity -%patch50 -p1 -%patch51 -p1 -%patch52 -p1 -%patch53 -p1 %patch54 -p1 %patch55 -p1 %patch56 -p1 %patch57 -p1 %patch58 -p1 %patch59 -p1 -%patch60 -p1 -%patch61 -p1 -%patch62 -p1 -%patch63 -p1 -%patch64 -p1 -%patch65 -p1 -%patch66 -p1 autoreconf -pushd pam_ssh_agent_auth-0.10.3 +pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 autoreconf popd @@ -306,7 +265,7 @@ fi --with-privsep-path=%{_var}/empty/sshd --disable-strip \ --without-zlib-version-check --with-ssl-engine --with-ipaddr-display \ --with-pie=no --without-hardening --with-systemd --with-default-pkcs11-provider=yes \ - --with-ldap --with-pam --with-selinux --with-audit=linux \ + --with-pam --with-selinux --with-audit=linux --with-security-key-buildin=yes \ %ifnarch riscv64 --with-sandbox=seccomp_filter \ %endif @@ -327,18 +286,13 @@ else fi popd -pushd pam_ssh_agent_auth-0.10.3 +pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 LDFLAGS="$SAVE_LDFLAGS" %configure --with-selinux --libexecdir=/%{_libdir}/security --with-mantype=man \ --without-openssl-header-check make popd -%global __spec_install_post \ - %%{?__debug_package:%%{__debug_install_post}} %%{__arch_install_post} %%{__os_install_post} \ - fipshmac -d $RPM_BUILD_ROOT%{_libdir}/fipscheck $RPM_BUILD_ROOT%{_bindir}/ssh $RPM_BUILD_ROOT%{_sbindir}/sshd \ -%{nil} - %check #to run tests use "--with check" %if %{?_with_check:1}%{!?_with_check:0} @@ -353,12 +307,9 @@ mkdir -p -m755 $RPM_BUILD_ROOT%{_var}/empty/sshd %make_install -rm -f $RPM_BUILD_ROOT%{_sysconfdir}/ssh/ldap.conf - install -d $RPM_BUILD_ROOT/etc/pam.d/ install -d $RPM_BUILD_ROOT/etc/sysconfig/ install -d $RPM_BUILD_ROOT%{_libexecdir}/openssh -install -d $RPM_BUILD_ROOT%{_libdir}/fipscheck install -m644 %{SOURCE2} $RPM_BUILD_ROOT/etc/pam.d/sshd install -m644 %{SOURCE6} $RPM_BUILD_ROOT/etc/pam.d/ssh-keycat install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/sysconfig/sshd @@ -369,10 +320,11 @@ 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/ -install -m644 -D %{SOURCE14} $RPM_BUILD_ROOT%{_tmpfilesdir}/%{name}.conf install contrib/gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/gnome-ssh-askpass ln -s gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/ssh-askpass @@ -382,7 +334,7 @@ install -m 755 contrib/redhat/gnome-ssh-askpass.sh $RPM_BUILD_ROOT%{_sysconfdir} perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* -pushd pam_ssh_agent_auth-0.10.3 +pushd pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4 make install DESTDIR=$RPM_BUILD_ROOT popd @@ -415,7 +367,6 @@ getent passwd sshd >/dev/null || \ %files clients %attr(0755,root,root) %{_bindir}/ssh -%attr(0644,root,root) %{_libdir}/fipscheck/ssh.hmac %attr(0755,root,root) %{_bindir}/scp %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config.d/05-redhat.conf @@ -426,11 +377,11 @@ getent passwd sshd >/dev/null || \ %attr(0755,root,root) %{_bindir}/ssh-copy-id %attr(0755,root,root) %{_libexecdir}/openssh/ssh-pkcs11-helper %attr(0755,root,root) %{_libexecdir}/openssh/ssh-sk-helper +%attr(0755,root,root) %{_userunitdir}/ssh-agent.service %files server %dir %attr(0711,root,root) %{_var}/empty/sshd %attr(0755,root,root) %{_sbindir}/sshd -%attr(0644,root,root) %{_libdir}/fipscheck/sshd.hmac %attr(0755,root,root) %{_libexecdir}/openssh/sftp-server %attr(0755,root,root) %{_libexecdir}/openssh/sshd-keygen %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config @@ -441,11 +392,6 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_unitdir}/sshd.socket %attr(0644,root,root) %{_unitdir}/sshd-keygen@.service %attr(0644,root,root) %{_unitdir}/sshd-keygen.target -%attr(0644,root,root) %{_tmpfilesdir}/openssh.conf - -%files ldap -%attr(0755,root,root) %{_libexecdir}/openssh/ssh-ldap-helper -%attr(0755,root,root) %{_libexecdir}/openssh/ssh-ldap-wrapper %files keycat %attr(0755,root,root) %{_libexecdir}/openssh/ssh-keycat @@ -456,18 +402,13 @@ getent passwd sshd >/dev/null || \ %attr(0755,root,root) %{_libexecdir}/openssh/gnome-ssh-askpass %attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass -%files cavs -%attr(0755,root,root) %{_libexecdir}/openssh/ctr-cavstest -%attr(0755,root,root) %{_libexecdir}/openssh/ssh-cavs -%attr(0755,root,root) %{_libexecdir}/openssh/ssh-cavs_driver.pl - %files -n pam_ssh_agent_auth -%license pam_ssh_agent_auth-0.10.3/OPENSSH_LICENSE +%license pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/OPENSSH_LICENSE %attr(0755,root,root) %{_libdir}/security/pam_ssh_agent_auth.so %files help -%doc ChangeLog OVERVIEW PROTOCOL* README README.privsep README.tun README.dns TODO openssh-lpk-openldap.schema -%doc openssh-lpk-sun.schema ldap.conf openssh-lpk-openldap.ldif openssh-lpk-sun.ldif HOWTO.ssh-keycat HOWTO.ldap-keys +%doc ChangeLog OVERVIEW PROTOCOL* README README.privsep README.tun README.dns TODO +%doc HOWTO.ssh-keycat %attr(0644,root,root) %{_mandir}/man1/scp.1* %attr(0644,root,root) %{_mandir}/man1/ssh*.1* %attr(0644,root,root) %{_mandir}/man1/sftp.1* @@ -478,6 +419,12 @@ getent passwd sshd >/dev/null || \ %attr(0644,root,root) %{_mandir}/man8/sftp-server.8* %changelog +* Wed Dec 8 2021 renmingshuai - 8.8P1-1 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:update to openssh-8.8p1 + * Fri Oct 29 2021 kircher - 8.2P1-14 - Type:CVE - CVE:CVE-2021-41617 diff --git a/pam_ssh_agent-rmheaders b/pam_ssh_agent-rmheaders index 06d899d9190315315bbe0b40dde64bf23ee6d14d..ab5899fc9884fc8db3269ff7d160a794cf7b8a3a 100644 --- a/pam_ssh_agent-rmheaders +++ b/pam_ssh_agent-rmheaders @@ -9,7 +9,6 @@ buffer.c cleanup.c cipher.h compat.h -defines.h entropy.c entropy.h fatal.c diff --git a/pam_ssh_agent_auth-0.10.2-compat.patch b/pam_ssh_agent_auth-0.10.2-compat.patch index d1d4f59eff74080c3062448e558a224dda200fac..0822b61450532fe54c7cb7d7ae0d82f6df5c1b68 100644 --- a/pam_ssh_agent_auth-0.10.2-compat.patch +++ b/pam_ssh_agent_auth-0.10.2-compat.patch @@ -1,6 +1,6 @@ -diff -up openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c ---- openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c 2020-02-07 10:43:05.011757956 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c 2020-09-23 10:52:16.424001475 +0200 @@ -27,6 +27,7 @@ * or implied, of Jamie Beverly. */ @@ -9,7 +9,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat openss #include #include #include -@@ -65,8 +66,8 @@ proc_pid_cmdline(char *** inargv) +@@ -66,8 +67,8 @@ proc_pid_cmdline(char *** inargv) case EOF: case '\0': if (len > 0) { @@ -20,7 +20,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat openss strncpy(argv[count++], argbuf, len); memset(argbuf, '\0', MAX_LEN_PER_CMDLINE_ARG + 1); len = 0; -@@ -105,9 +106,9 @@ pamsshagentauth_free_command_line(char * +@@ -106,9 +107,9 @@ pamsshagentauth_free_command_line(char * { size_t i; for (i = 0; i < n_args; i++) @@ -32,9 +32,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat openss return; } -diff -up openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/identity.h ---- openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/identity.h 2020-02-07 10:43:05.011757956 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h 2020-09-23 10:52:16.424001475 +0200 @@ -30,8 +30,8 @@ #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" @@ -55,9 +55,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-compat openssh/pam_ss char *filename; /* comment for agent-only keys */ int tried; int isprivate; /* key points to the private key */ -diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c ---- openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat 2020-02-07 10:43:05.009757925 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c 2020-02-07 10:43:05.012757972 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c.psaa-compat 2020-09-23 10:52:16.421001434 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c 2020-09-23 10:52:16.424001475 +0200 @@ -36,8 +36,8 @@ #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" @@ -285,10 +285,10 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat EVP_cleanup(); return retval; } -diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c ---- openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat 2020-02-07 10:43:05.010757940 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c 2020-02-07 10:43:05.012757972 +0100 -@@ -104,7 +104,7 @@ pam_sm_authenticate(pam_handle_t * pamh, +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c.psaa-compat 2020-09-23 10:52:16.423001461 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c 2020-09-23 10:53:10.631727657 +0200 +@@ -106,7 +106,7 @@ pam_sm_authenticate(pam_handle_t * pamh, * a patch 8-) */ #if ! HAVE___PROGNAME || HAVE_BUNDLE @@ -297,7 +297,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open #endif for(i = argc, argv_ptr = (char **) argv; i > 0; ++argv_ptr, i--) { -@@ -130,11 +130,11 @@ pam_sm_authenticate(pam_handle_t * pamh, +@@ -132,11 +132,11 @@ pam_sm_authenticate(pam_handle_t * pamh, #endif } @@ -311,7 +311,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open if(ruser_ptr) { strncpy(ruser, ruser_ptr, sizeof(ruser) - 1); -@@ -149,12 +149,12 @@ pam_sm_authenticate(pam_handle_t * pamh, +@@ -151,12 +151,12 @@ pam_sm_authenticate(pam_handle_t * pamh, #ifdef ENABLE_SUDO_HACK if( (strlen(sudo_service_name) > 0) && strncasecmp(servicename, sudo_service_name, sizeof(sudo_service_name) - 1) == 0 && getenv("SUDO_USER") ) { strncpy(ruser, getenv("SUDO_USER"), sizeof(ruser) - 1 ); @@ -326,7 +326,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open goto cleanexit; } strncpy(ruser, getpwuid(getuid())->pw_name, sizeof(ruser) - 1); -@@ -163,11 +163,11 @@ pam_sm_authenticate(pam_handle_t * pamh, +@@ -165,11 +165,11 @@ pam_sm_authenticate(pam_handle_t * pamh, /* Might as well explicitely confirm the user exists here */ if(! getpwnam(ruser) ) { @@ -340,7 +340,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open goto cleanexit; } -@@ -177,8 +177,8 @@ pam_sm_authenticate(pam_handle_t * pamh, +@@ -179,8 +179,8 @@ pam_sm_authenticate(pam_handle_t * pamh, */ parse_authorized_key_file(user, authorized_keys_file_input); } else { @@ -351,7 +351,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open } /* -@@ -187,19 +187,19 @@ pam_sm_authenticate(pam_handle_t * pamh, +@@ -189,7 +189,7 @@ pam_sm_authenticate(pam_handle_t * pamh, */ if(user && strlen(ruser) > 0) { @@ -359,11 +359,26 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open + verbose("Attempting authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file); /* + * Attempt to read data from the sshd if we're being called as an auth agent. +@@ -197,10 +197,10 @@ pam_sm_authenticate(pam_handle_t * pamh, + const char* ssh_user_auth = pam_getenv(pamh, "SSH_AUTH_INFO_0"); + int sshd_service = strncasecmp(servicename, sshd_service_name, sizeof(sshd_service_name) - 1); + if (sshd_service == 0 && ssh_user_auth != NULL) { +- pamsshagentauth_verbose("Got SSH_AUTH_INFO_0: `%.20s...'", ssh_user_auth); ++ verbose("Got SSH_AUTH_INFO_0: `%.20s...'", ssh_user_auth); + if (userauth_pubkey_from_pam(ruser, ssh_user_auth) > 0) { + retval = PAM_SUCCESS; +- pamsshagentauth_logit("Authenticated (sshd): `%s' as `%s' using %s", ruser, user, authorized_keys_file); ++ logit("Authenticated (sshd): `%s' as `%s' using %s", ruser, user, authorized_keys_file); + goto cleanexit; + } + } +@@ -208,13 +208,13 @@ pam_sm_authenticate(pam_handle_t * pamh, * this pw_uid is used to validate the SSH_AUTH_SOCK, and so must be the uid of the ruser invoking the program, not the target-user */ if(pamsshagentauth_find_authorized_keys(user, ruser, servicename)) { /* getpwnam(ruser)->pw_uid)) { */ -- pamsshagentauth_logit("Authenticated: `%s' as `%s' using %s", ruser, user, authorized_keys_file); -+ logit("Authenticated: `%s' as `%s' using %s", ruser, user, authorized_keys_file); +- pamsshagentauth_logit("Authenticated (agent): `%s' as `%s' using %s", ruser, user, authorized_keys_file); ++ logit("Authenticated (agent): `%s' as `%s' using %s", ruser, user, authorized_keys_file); retval = PAM_SUCCESS; } else { - pamsshagentauth_logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file); @@ -375,9 +390,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open } cleanexit: -diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c ---- openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c 2020-02-07 10:43:05.012757972 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c 2020-09-23 10:52:16.424001475 +0200 @@ -66,8 +66,8 @@ #include "xmalloc.h" #include "match.h" @@ -442,9 +457,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c.psaa-compa { return pamsshagentauth_user_key_allowed2(getpwuid(authorized_keys_file_allowed_owner_uid), -diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h ---- openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h 2020-02-07 10:43:05.012757972 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h 2020-09-23 10:52:16.424001475 +0200 @@ -32,7 +32,7 @@ #define _PAM_USER_KEY_ALLOWED_H @@ -454,9 +469,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h.psaa-compa void parse_authorized_key_file(const char *, const char *); #endif -diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c ---- openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c 2020-02-07 10:43:05.012757972 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c 2020-09-23 10:52:16.424001475 +0200 @@ -45,44 +45,46 @@ #include "xmalloc.h" #include "ssh.h" @@ -731,9 +746,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-compat o + restore_uid(); return found_key; } -diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h ---- openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h 2020-02-07 10:43:05.012757972 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h 2020-09-23 10:52:16.424001475 +0200 @@ -32,7 +32,7 @@ #define _PAM_USER_KEY_ALLOWED_H @@ -744,9 +759,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h.psaa-compat o +int pamsshagentauth_user_key_command_allowed2(char *, char *, struct passwd *, struct sshkey *); #endif -diff -up openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c ---- openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c 2020-02-07 10:43:05.012757972 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c 2020-09-23 10:52:16.424001475 +0200 @@ -53,8 +53,8 @@ #include "xmalloc.h" #include "match.h" @@ -788,9 +803,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c.psaa-compat openssh buf); break; } -diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c ---- openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c 2020-02-07 10:43:23.520048960 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c 2020-09-23 10:52:16.424001475 +0200 @@ -37,10 +37,11 @@ #include "xmalloc.h" #include "ssh.h" @@ -887,9 +902,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-compat CRYPTO_cleanup_all_ex_data(); return authenticated; } -diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h ---- openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h 2020-02-07 10:43:05.013757988 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h 2020-09-23 10:52:16.424001475 +0200 @@ -31,7 +31,7 @@ #ifndef _USERAUTH_PUBKEY_FROM_ID_H #define _USERAUTH_PUBKEY_FROM_ID_H @@ -900,9 +915,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h.psaa-compat +int userauth_pubkey_from_id(const char *, Identity *, struct sshbuf *); #endif -diff -up openssh/pam_ssh_agent_auth-0.10.3/uuencode.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/uuencode.c ---- openssh/pam_ssh_agent_auth-0.10.3/uuencode.c.psaa-compat 2016-11-13 04:24:32.000000000 +0100 -+++ openssh/pam_ssh_agent_auth-0.10.3/uuencode.c 2020-02-07 10:43:05.013757988 +0100 +diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c.psaa-compat 2019-07-08 18:36:13.000000000 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c 2020-09-23 10:52:16.424001475 +0200 @@ -56,7 +56,7 @@ pamsshagentauth_uudecode(const char *src /* and remove trailing whitespace because __b64_pton needs this */ *p = '\0'; @@ -928,3 +943,50 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/uuencode.c.psaa-compat openssh/pam_ss - pamsshagentauth_xfree(buf); + free(buf); } +--- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_pam.c.compat 2020-09-23 11:32:30.783695267 +0200 ++++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_pam.c 2020-09-23 11:33:21.383389036 +0200 +@@ -33,7 +33,8 @@ + #include + + #include "defines.h" +-#include "key.h" ++#include ++#include "sshkey.h" + #include "log.h" + + #include "pam_user_authorized_keys.h" +@@ -42,28 +42,28 @@ + int authenticated = 0; + const char method[] = "publickey "; + +- char* ai = pamsshagentauth_xstrdup(ssh_auth_info); ++ char* ai = xstrdup(ssh_auth_info); + char* saveptr; + + char* auth_line = strtok_r(ai, "\n", &saveptr); + while (auth_line != NULL) { + if (strncmp(auth_line, method, sizeof(method) - 1) == 0) { + char* key_str = auth_line + sizeof(method) - 1; +- Key* key = pamsshagentauth_key_new(KEY_UNSPEC); ++ struct sshkey* key = sshkey_new(KEY_UNSPEC); + if (key == NULL) { + continue; + } +- int r = pamsshagentauth_key_read(key, &key_str); ++ int r = sshkey_read(key, &key_str); + if (r == 1) { + if (pam_user_key_allowed(ruser, key)) { + authenticated = 1; +- pamsshagentauth_key_free(key); ++ sshkey_free(key); + break; + } + } else { +- pamsshagentauth_verbose("Failed to create key for %s: %d", auth_line, r); ++ verbose("Failed to create key for %s: %d", auth_line, r); + } +- pamsshagentauth_key_free(key); ++ sshkey_free(key); + } + auth_line = strtok_r(NULL, "\n", &saveptr); + } diff --git a/pam_ssh_agent_auth-0.10.3.tar.bz2 b/pam_ssh_agent_auth-0.10.3.tar.bz2 deleted file mode 100644 index c41c269ffc7aced58221549472f42df45acea2f9..0000000000000000000000000000000000000000 Binary files a/pam_ssh_agent_auth-0.10.3.tar.bz2 and /dev/null differ diff --git a/pam_ssh_agent_auth-0.10.4.tar.gz b/pam_ssh_agent_auth-0.10.4.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..f076e2caefec1ee8b6b4419f1c8aeeffa39bd009 Binary files /dev/null and b/pam_ssh_agent_auth-0.10.4.tar.gz differ diff --git a/pam_ssh_agent_auth-0.9.3-build.patch b/pam_ssh_agent_auth-0.9.3-build.patch index bb9a94d035a10ee0a24600e04d3469cba29079df..4018c4d8971077bcc221616ce673f15cc55f8003 100644 --- a/pam_ssh_agent_auth-0.9.3-build.patch +++ b/pam_ssh_agent_auth-0.9.3-build.patch @@ -174,8 +174,8 @@ diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in.psaa-build openssh- ED25519OBJS=ed25519-donna/ed25519.o --PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o -+PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o secure_filename.o +-PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o userauth_pubkey_from_pam.o ++PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o userauth_pubkey_from_pam.o secure_filename.o MANPAGES_IN = pam_ssh_agent_auth.pod diff --git a/set-sshd-config.patch b/set-sshd-config.patch index bc20877281e6894c2704884e198341ef06937eaa..73669252f127802bd3677283cf80fcc0d2f4e1c7 100644 --- a/set-sshd-config.patch +++ b/set-sshd-config.patch @@ -1,17 +1,26 @@ -From 8f2d1c4f30dd88e36ed4c9b5771c92c878378125 Mon Sep 17 00:00:00 2001 -From: kircher -Date: Thu, 16 Apr 2020 19:25:27 +0800 -Subject: [PATCH] sshd_config +From ca0b2bcd17a2c0e1682b8125960ac81e08d0f6dd Mon Sep 17 00:00:00 2001 +From: kircher +Date: Wed, 27 Oct 2021 16:51:41 +0800 +Subject: [PATCH] set --- - sshd_config | 28 ++++++++++++++++++---------- - 1 file changed, 18 insertions(+), 10 deletions(-) + sshd_config | 32 +++++++++++++++++++------------- + 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/sshd_config b/sshd_config -index b121450..e8e6299 100644 +index 42ecf9b..67739b2 100644 --- a/sshd_config +++ b/sshd_config -@@ -19,21 +19,22 @@ +@@ -12,7 +12,7 @@ + + # To modify the system-wide sshd configuration, create a *.conf file under + # /etc/ssh/sshd_config.d/ which will be automatically included below +-Include /etc/ssh/sshd_config.d/*.conf ++#Include /etc/ssh/sshd_config.d/*.conf + + # If you want to change the port on a SELinux system, you have to tell + # SELinux about this change. +@@ -23,21 +23,22 @@ Include /etc/ssh/sshd_config.d/*.conf #ListenAddress 0.0.0.0 #ListenAddress :: @@ -38,19 +47,21 @@ index b121450..e8e6299 100644 #StrictModes yes #MaxAuthTries 6 #MaxSessions 10 -@@ -60,9 +61,11 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -62,11 +63,11 @@ AuthorizedKeysFile .ssh/authorized_keys + #IgnoreRhosts yes + # To disable tunneled clear text passwords, change to no here! - #PasswordAuthentication yes - #PermitEmptyPasswords no +-#PasswordAuthentication yes +PasswordAuthentication yes + #PermitEmptyPasswords no # Change to no to disable s/key passwords - #ChallengeResponseAuthentication yes -+ChallengeResponseAuthentication no +-#KbdInteractiveAuthentication yes ++KbdInteractiveAuthentication no # Kerberos options #KerberosAuthentication no -@@ -72,8 +75,8 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -76,8 +77,8 @@ AuthorizedKeysFile .ssh/authorized_keys #KerberosUseKuserok yes # GSSAPI options @@ -61,8 +72,8 @@ index b121450..e8e6299 100644 #GSSAPIStrictAcceptorCheck yes #GSSAPIKeyExchange no #GSSAPIEnablek5users no -@@ -89,16 +92,16 @@ AuthorizedKeysFile .ssh/authorized_keys - # and ChallengeResponseAuthentication to 'no'. +@@ -93,16 +94,16 @@ AuthorizedKeysFile .ssh/authorized_keys + # and KbdInteractiveAuthentication to 'no'. # WARNING: 'UsePAM no' is not supported in openEuler and may cause several # problems. -#UsePAM no @@ -81,7 +92,7 @@ index b121450..e8e6299 100644 #PrintLastLog yes #TCPKeepAlive yes #PermitUserEnvironment no -@@ -115,6 +118,11 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -119,8 +120,13 @@ AuthorizedKeysFile .ssh/authorized_keys # no default banner path #Banner none @@ -91,14 +102,11 @@ index b121450..e8e6299 100644 +AcceptEnv XMODIFIERS + # override default of no subsystems - Subsystem sftp /usr/libexec/sftp-server - -@@ -129,4 +137,4 @@ Subsystem sftp /usr/libexec/sftp-server +-Subsystem sftp /usr/libexec/sftp-server ++Subsystem sftp /usr/libexec/openssh/sftp-server - # To modify the system-wide ssh configuration, create a *.conf file under - # /etc/ssh/sshd_config.d/ which will be automatically included below --Include /etc/ssh/sshd_config.d/*.conf -+#Include /etc/ssh/sshd_config.d/*.conf + # Example of overriding settings on a per-user basis + #Match User anoncvs -- -2.19.1 +1.8.3.1 diff --git a/ssh-agent.service b/ssh-agent.service new file mode 100644 index 0000000000000000000000000000000000000000..c2150227fb5b25343f853eb3ee907e58f488b397 --- /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 diff --git a/sshd.service b/sshd.service index 8f3dbd65651fa7795e58c3c30266689d67717d33..e8afb869854ca11c713832b710733d19f7fc65ff 100644 --- a/sshd.service +++ b/sshd.service @@ -6,10 +6,8 @@ Wants=sshd-keygen.target [Service] Type=notify -EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config -EnvironmentFile=-/etc/sysconfig/sshd-permitrootlogin EnvironmentFile=-/etc/sysconfig/sshd -ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY $PERMITROOTLOGIN +ExecStart=/usr/sbin/sshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure diff --git a/sshd.sysconfig b/sshd.sysconfig index 6c2bff94717f1768942410769049d6b48484ded2..a217ce7cd60884dd4db85857dc33d3be5943ba01 100644 --- a/sshd.sysconfig +++ b/sshd.sysconfig @@ -5,7 +5,3 @@ # example using systemctl enable sshd-keygen@dsa.service to allow creation # of DSA key or systemctl mask sshd-keygen@rsa.service to disable RSA key # creation. - -# System-wide crypto policy: -# To opt-out, uncomment the following line -# CRYPTO_POLICY= diff --git a/sshd.tmpfiles b/sshd.tmpfiles deleted file mode 100644 index c35a2b843cd9053c9b88086a902507f889b37a56..0000000000000000000000000000000000000000 --- a/sshd.tmpfiles +++ /dev/null @@ -1 +0,0 @@ -d /var/empty/sshd 711 root root - diff --git a/sshd@.service b/sshd@.service index e4fd7f4eb1b7cade22e4db4df56bf84fa92ef162..196c555ae54f339b718c3f65858b1caa4adf6365 100644 --- a/sshd@.service +++ b/sshd@.service @@ -5,8 +5,6 @@ Wants=sshd-keygen.target After=sshd-keygen.target [Service] -EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config -EnvironmentFile=-/etc/sysconfig/sshd-permitrootlogin EnvironmentFile=-/etc/sysconfig/sshd -ExecStart=-/usr/sbin/sshd -i $OPTIONS $CRYPTO_POLICY $PERMITROOTLOGIN +ExecStart=-/usr/sbin/sshd -i $OPTIONS StandardInput=socket diff --git a/upstream-expose-vasnmprintf.patch b/upstream-expose-vasnmprintf.patch deleted file mode 100644 index 002bb1159d44dab04af1ee6e2c565ebb46fc4d8b..0000000000000000000000000000000000000000 --- a/upstream-expose-vasnmprintf.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 31909696c4620c431dd55f6cd15db65c4e9b98da Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Fri, 1 May 2020 06:28:52 +0000 -Subject: [PATCH] upstream: expose vasnmprintf(); ok (as part of other commit) - markus - -deraadt - -OpenBSD-Commit-ID: 2e80cea441c599631a870fd40307d2ade5a7f9b5 ---- - utf8.c | 5 ++--- - utf8.h | 3 ++- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/utf8.c b/utf8.c -index f83401996..7f63b25ae 100644 ---- a/utf8.c -+++ b/utf8.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: utf8.c,v 1.8 2018/08/21 13:56:27 schwarze Exp $ */ -+/* $OpenBSD: utf8.c,v 1.11 2020/05/01 06:28:52 djm Exp $ */ - /* - * Copyright (c) 2016 Ingo Schwarze - * -@@ -43,7 +43,6 @@ - - static int dangerous_locale(void); - static int grow_dst(char **, size_t *, size_t, char **, size_t); --static int vasnmprintf(char **, size_t, int *, const char *, va_list); - - - /* -@@ -101,7 +100,7 @@ grow_dst(char **dst, size_t *sz, size_t maxsz, char **dp, size_t need) - * written is returned in *wp. - */ - --static int -+int - vasnmprintf(char **str, size_t maxsz, int *wp, const char *fmt, va_list ap) - { - char *src; /* Source string returned from vasprintf. */ -diff --git a/utf8.h b/utf8.h -index 20a11dc59..9d6d9a32c 100644 ---- a/utf8.h -+++ b/utf8.h -@@ -1,4 +1,4 @@ --/* $OpenBSD: utf8.h,v 1.1 2016/05/25 23:48:45 schwarze Exp $ */ -+/* $OpenBSD: utf8.h,v 1.3 2020/05/01 06:28:52 djm Exp $ */ - /* - * Copyright (c) 2016 Ingo Schwarze - * -@@ -15,6 +15,7 @@ - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -+int vasnmprintf(char **, size_t, int *, const char *, va_list); - int mprintf(const char *, ...) - __attribute__((format(printf, 1, 2))); - int fmprintf(FILE *, const char *, ...)