openssh-8.0p1-1 + 0.10.3-7

Resolves rhbz#1701072
This commit is contained in:
Jakub Jelen 2019-04-26 17:42:30 +02:00
parent f51d092120
commit def1debf2e
35 changed files with 7774 additions and 11995 deletions

2
.gitignore vendored
View File

@ -34,3 +34,5 @@ pam_ssh_agent_auth-0.9.2.tar.bz2
/openssh-7.8p1.tar.gz.asc
/openssh-7.9p1.tar.gz
/openssh-7.9p1.tar.gz.asc
/openssh-8.0p1.tar.gz
/openssh-8.0p1.tar.gz.asc

View File

@ -1,21 +0,0 @@
diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c
--- openssh-6.1p1/sshconnect2.c.canohost 2012-10-30 10:52:59.593301692 +0100
+++ openssh-6.1p1/sshconnect2.c 2012-10-30 11:01:12.870301632 +0100
@@ -699,12 +699,15 @@ userauth_gssapi(Authctxt *authctxt)
static u_int mech = 0;
OM_uint32 min;
int r, ok = 0;
- const char *gss_host;
+ const char *gss_host = NULL;
if (options.gss_server_identity)
gss_host = options.gss_server_identity;
- else if (options.gss_trust_dns)
+ else if (options.gss_trust_dns) {
gss_host = get_canonical_hostname(active_state, 1);
+ if (strcmp(gss_host, "UNKNOWN") == 0)
+ gss_host = authctxt->host;
+ }
else
gss_host = authctxt->host;

View File

@ -1,142 +0,0 @@
diff -up openssh-7.4p1/configure.ac.vendor openssh-7.4p1/configure.ac
--- openssh-7.4p1/configure.ac.vendor 2016-12-23 13:34:51.681253844 +0100
+++ openssh-7.4p1/configure.ac 2016-12-23 13:34:51.694253847 +0100
@@ -4930,6 +4930,12 @@ AC_ARG_WITH([lastlog],
fi
]
)
+AC_ARG_ENABLE(vendor-patchlevel,
+ [ --enable-vendor-patchlevel=TAG specify a vendor patch level],
+ [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.])
+ SSH_VENDOR_PATCHLEVEL="$enableval"],
+ [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.])
+ SSH_VENDOR_PATCHLEVEL=none])
dnl lastlog, [uw]tmpx? detection
dnl NOTE: set the paths in the platform section to avoid the
@@ -5194,6 +5200,7 @@ echo " Translate v4 in v6 hack
echo " BSD Auth support: $BSD_AUTH_MSG"
echo " Random number source: $RAND_MSG"
echo " Privsep sandbox style: $SANDBOX_STYLE"
+echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL"
echo ""
diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c
--- openssh-7.4p1/servconf.c.vendor 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/servconf.c 2016-12-23 13:36:07.555268628 +0100
@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions
options->max_authtries = -1;
options->max_sessions = -1;
options->banner = NULL;
+ options->show_patchlevel = -1;
options->use_dns = -1;
options->client_alive_interval = -1;
options->client_alive_count_max = -1;
@@ -325,6 +326,8 @@ fill_default_server_options(ServerOption
options->ip_qos_bulk = IPTOS_DSCP_CS1;
if (options->version_addendum == NULL)
options->version_addendum = xstrdup("");
+ if (options->show_patchlevel == -1)
+ options->show_patchlevel = 0;
if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
options->fwd_opts.streamlocal_bind_mask = 0177;
if (options->fwd_opts.streamlocal_bind_unlink == -1)
@@ -402,7 +405,7 @@ typedef enum {
sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile,
sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
- sBanner, sUseDNS, sHostbasedAuthentication,
+ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
sHostKeyAlgorithms,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
@@ -528,6 +531,7 @@ static struct {
{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
{ "maxsessions", sMaxSessions, SSHCFG_ALL },
{ "banner", sBanner, SSHCFG_ALL },
+ { "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL },
{ "usedns", sUseDNS, SSHCFG_GLOBAL },
{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
@@ -1369,6 +1373,10 @@ process_server_config_line(ServerOptions
intptr = &options->disable_forwarding;
goto parse_flag;
+ case sShowPatchLevel:
+ intptr = &options->show_patchlevel;
+ goto parse_flag;
+
case sAllowUsers:
while ((arg = strdelim(&cp)) && *arg != '\0') {
if (match_user(NULL, NULL, NULL, arg) == -1)
@@ -2269,6 +2277,7 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
dump_cfg_fmtint(sCompression, o->compression);
dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
+ dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel);
dump_cfg_fmtint(sUseDNS, o->use_dns);
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
diff -up openssh-7.4p1/servconf.h.vendor openssh-7.4p1/servconf.h
--- openssh-7.4p1/servconf.h.vendor 2016-12-19 05:59:41.000000000 +0100
+++ openssh-7.4p1/servconf.h 2016-12-23 13:34:51.694253847 +0100
@@ -149,6 +149,7 @@ typedef struct {
int max_authtries;
int max_sessions;
char *banner; /* SSH-2 banner message */
+ int show_patchlevel; /* Show vendor patch level to clients */
int use_dns;
int client_alive_interval; /*
* poke the client this often to
diff -up openssh-7.4p1/sshd_config.5.vendor openssh-7.4p1/sshd_config.5
--- openssh-7.4p1/sshd_config.5.vendor 2016-12-23 13:34:51.695253847 +0100
+++ openssh-7.4p1/sshd_config.5 2016-12-23 13:37:17.482282253 +0100
@@ -1334,6 +1334,13 @@ an OpenSSH Key Revocation List (KRL) as
.Cm AcceptEnv
or
.Cm PermitUserEnvironment .
+.It Cm ShowPatchLevel
+Specifies whether
+.Nm sshd
+will display the patch level of the binary in the identification string.
+The patch level is set at compile-time.
+The default is
+.Dq no .
.It Cm StreamLocalBindMask
Sets the octal file creation mode mask
.Pq umask
diff -up openssh-7.4p1/sshd_config.vendor openssh-7.4p1/sshd_config
--- openssh-7.4p1/sshd_config.vendor 2016-12-23 13:34:51.690253846 +0100
+++ openssh-7.4p1/sshd_config 2016-12-23 13:34:51.695253847 +0100
@@ -105,6 +105,7 @@ X11Forwarding yes
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
+#ShowPatchLevel no
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
diff -up openssh-7.4p1/sshd.c.vendor openssh-7.4p1/sshd.c
--- openssh-7.4p1/sshd.c.vendor 2016-12-23 13:34:51.682253844 +0100
+++ openssh-7.4p1/sshd.c 2016-12-23 13:38:32.434296856 +0100
@@ -367,7 +367,8 @@ sshd_exchange_identification(struct ssh
char remote_version[256]; /* Must be at least as big as buf. */
xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n",
- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2,
+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION,
*options.version_addendum == '\0' ? "" : " ",
options.version_addendum);
@@ -1650,7 +1651,8 @@ main(int ac, char **av)
exit(1);
}
- debug("sshd version %s, %s", SSH_VERSION,
+ debug("sshd version %s, %s",
+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION,
#ifdef WITH_OPENSSL
SSLeay_version(SSLEAY_VERSION)
#else

View File

@ -46,7 +46,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c
+ pmonitor->m_state = "preauth";
+
authctxt = _authctxt;
authctxt = (Authctxt *)ssh->authctxt;
memset(authctxt, 0, sizeof(*authctxt));
ssh->authctxt = authctxt;
@@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p
@ -113,7 +113,7 @@ diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h
+void monitor_reinit(struct monitor *, const char *);
struct Authctxt;
void monitor_child_preauth(struct Authctxt *, struct monitor *);
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

View File

@ -22,15 +22,15 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
--- openssh-7.4p1/servconf.c.GSSAPIEnablek5users 2016-12-23 15:18:40.615216100 +0100
+++ openssh-7.4p1/servconf.c 2016-12-23 15:35:36.354401156 +0100
@@ -168,6 +168,7 @@ initialize_server_options(ServerOptions
options->gss_strict_acceptor = -1;
options->gss_store_rekey = -1;
options->gss_kex_algorithms = NULL;
options->use_kuserok = -1;
+ options->enable_k5users = -1;
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->challenge_response_authentication = -1;
@@ -345,6 +346,8 @@ fill_default_server_options(ServerOption
options->gss_store_rekey = 0;
#endif
if (options->use_kuserok == -1)
options->use_kuserok = 1;
+ if (options->enable_k5users == -1)
@ -44,20 +44,22 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
- sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
+ sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel,
sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
@@ -497,12 +500,14 @@ static struct {
{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
@@ -497,14 +500,16 @@ static struct {
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
+ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
#else
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
+ { "gssapienablek5users", sUnsupported, SSHCFG_ALL },
#endif
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },

View File

@ -176,17 +176,17 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c
--- openssh-7.4p1/servconf.c.kuserok 2016-12-23 14:36:07.630465944 +0100
+++ openssh-7.4p1/servconf.c 2016-12-23 15:11:52.278133344 +0100
@@ -116,6 +116,7 @@ initialize_server_options(ServerOptions
options->gss_cleanup_creds = -1;
options->gss_strict_acceptor = -1;
options->gss_store_rekey = -1;
options->gss_kex_algorithms = NULL;
+ options->use_kuserok = -1;
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->challenge_response_authentication = -1;
@@ -278,6 +279,8 @@ fill_default_server_options(ServerOption
options->gss_strict_acceptor = 1;
if (options->gss_store_rekey == -1)
options->gss_store_rekey = 0;
if (options->gss_kex_algorithms == NULL)
options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
#endif
+ if (options->use_kuserok == -1)
+ options->use_kuserok = 1;
if (options->password_authentication == -1)

View File

@ -20,7 +20,7 @@ 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
@@ -411,7 +411,7 @@ monitor_child_preauth(Authctxt *_authctx
mm_get_keystate(pmonitor);
mm_get_keystate(ssh, pmonitor);
/* Drain any buffered messages from the child */
- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
@ -124,14 +124,14 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c
}
@@ -518,7 +518,7 @@ server_request_tun(void)
debug("%s: invalid tun", __func__);
goto done;
}
tun = packet_get_int();
- if (auth_opts->force_tun_device != -1) {
+ if (auth_opts->force_tun_device >= 0) {
if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun)
if (tun != SSH_TUNID_ANY &&
auth_opts->force_tun_device != (int)tun)
goto done;
tun = auth_opts->force_tun_device;
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
@ -163,7 +163,7 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
+++ openssh-7.4p1/sshd.c 2016-12-23 16:40:26.904788692 +0100
@@ -691,8 +691,10 @@ privsep_preauth(Authctxt *authctxt)
privsep_preauth_child();
privsep_preauth_child(ssh);
setproctitle("%s", "[net]");
- if (box != NULL)
+ if (box != NULL) {
@ -174,8 +174,8 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
return 0;
}
@@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so
if (num_listen_socks < 0)
break;
explicit_bzero(rnd, sizeof(rnd));
}
}
+
+ if (fdset != NULL)

View File

@ -40,7 +40,7 @@ diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in
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,377 @@
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
+ *
@ -208,6 +208,7 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
+{
+ int ret = 0;
+ struct kex kex;
+ struct sshbuf *Kb = NULL;
+ BIGNUM *Kbn = NULL;
+ int mode = 0;
+ struct newkeys *ctoskeys;
@ -222,10 +223,17 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
+ Kbn = BN_new();
+ BN_bin2bn(test->K, test->Klen, Kbn);
+ if (!Kbn) {
+ printf("cannot convert K into BIGNUM\n");
+ 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;
@ -285,7 +293,7 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
+ goto out;
+ }
+ ssh->kex = &kex;
+ kex_derive_keys_bn(ssh, test->H, test->Hlen, Kbn);
+ kex_derive_keys(ssh, test->H, test->Hlen, Kb);
+
+ ctoskeys = kex.newkeys[0];
+ stockeys = kex.newkeys[1];
@ -321,6 +329,8 @@ diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c
+out:
+ if (Kbn)
+ BN_free(Kbn);
+ if (Kb)
+ sshbuf_free(Kb);
+ if (ssh)
+ ssh_packet_close(ssh);
+ return ret;

View File

@ -10,18 +10,3 @@ diff -up openssh/servconf.c.sshdt openssh/servconf.c
dump_cfg_string(sForceCommand, o->adm_forced_command);
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
diff -up openssh/ssh.1.sshdt openssh/ssh.1
--- openssh/ssh.1.sshdt 2015-06-24 11:42:19.565102807 +0200
+++ openssh/ssh.1 2015-06-24 11:42:29.042078701 +0200
@@ -441,7 +441,11 @@ For full details of the options listed b
.It GatewayPorts
.It GlobalKnownHostsFile
.It GSSAPIAuthentication
+.It GSSAPIKeyExchange
+.It GSSAPIClientIdentity
.It GSSAPIDelegateCredentials
+.It GSSAPIRenewalForcesRekey
+.It GSSAPITrustDNS
.It HashKnownHosts
.It Host
.It HostbasedAuthentication

View File

@ -1,431 +0,0 @@
diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c
--- openssh-7.0p1/gss-genr.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200
+++ openssh-7.0p1/gss-genr.c 2015-08-19 12:28:38.078518839 +0200
@@ -78,7 +78,8 @@ ssh_gssapi_oid_table_ok() {
*/
char *
-ssh_gssapi_client_mechanisms(const char *host, const char *client) {
+ssh_gssapi_client_mechanisms(const char *host, const char *client,
+ const char *kex) {
gss_OID_set gss_supported;
OM_uint32 min_status;
@@ -86,12 +87,12 @@ ssh_gssapi_client_mechanisms(const char
return NULL;
return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
- host, client));
+ host, client, kex));
}
char *
ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
- const char *host, const char *client) {
+ const char *host, const char *client, const char *kex) {
struct sshbuf *buf;
size_t i;
int oidpos, enclen, r;
@@ -100,6 +101,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
char deroid[2];
const EVP_MD *evp_md = EVP_md5();
EVP_MD_CTX *md;
+ char *s, *cp, *p;
if (gss_enc2oid != NULL) {
for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
@@ -113,6 +115,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
md = EVP_MD_CTX_new();
oidpos = 0;
+ s = cp = xstrdup(kex);
for (i = 0; i < gss_supported->count; i++) {
if (gss_supported->elements[i].length < 128 &&
(*check)(NULL, &(gss_supported->elements[i]), host, client)) {
@@ -131,28 +134,25 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
encoded, EVP_MD_size(evp_md) * 2);
- if (oidpos != 0)
- if ((r = sshbuf_put_u8(buf, ',')) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
-
- if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID,
- sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 ||
- (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
- (r = sshbuf_put_u8(buf, ',')) != 0 ||
- (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID,
- sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 ||
- (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
- (r = sshbuf_put_u8(buf, ',')) != 0 ||
- (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID,
- sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 ||
- (r = sshbuf_put(buf, encoded, enclen)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ cp = strncpy(s, kex, strlen(kex));
+ for ((p = strsep(&cp, ",")); p && *p != '\0';
+ (p = strsep(&cp, ","))) {
+ if (sshbuf_len(buf) != 0)
+ if ((r = sshbuf_put_u8(buf, ',')) != 0)
+ fatal("%s: buffer error: %s",
+ __func__, ssh_err(r));
+ if ((r = sshbuf_put(buf, p, strlen(p))) != 0 ||
+ (r = sshbuf_put(buf, encoded, enclen)) != 0)
+ fatal("%s: buffer error: %s",
+ __func__, ssh_err(r));
+ }
gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
gss_enc2oid[oidpos].encoded = encoded;
oidpos++;
}
}
+ free(s);
EVP_MD_CTX_free(md);
gss_enc2oid[oidpos].oid = NULL;
gss_enc2oid[oidpos].encoded = NULL;
diff -up openssh-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c
--- openssh-7.0p1/gss-serv.c.gsskexalg 2015-08-19 12:28:38.024518959 +0200
+++ openssh-7.0p1/gss-serv.c 2015-08-19 12:28:38.078518839 +0200
@@ -149,7 +149,8 @@ ssh_gssapi_server_mechanisms() {
if (supported_oids == NULL)
ssh_gssapi_prepare_supported_oids();
return (ssh_gssapi_kex_mechs(supported_oids,
- &ssh_gssapi_server_check_mech, NULL, NULL));
+ &ssh_gssapi_server_check_mech, NULL, NULL,
+ options.gss_kex_algorithms));
}
/* Unprivileged */
diff -up openssh-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c
--- openssh-7.0p1/kex.c.gsskexalg 2015-08-19 12:28:38.078518839 +0200
+++ openssh-7.0p1/kex.c 2015-08-19 12:30:13.249306371 +0200
@@ -50,6 +50,7 @@
#include "misc.h"
#include "dispatch.h"
#include "monitor.h"
+#include "xmalloc.h"
#include "ssherr.h"
#include "sshbuf.h"
@@ -232,6 +232,29 @@ kex_assemble_names(const char *def, char
return r;
}
+/* Validate GSS KEX method name list */
+int
+gss_kex_names_valid(const char *names)
+{
+ char *s, *cp, *p;
+
+ if (names == NULL || *names == '\0')
+ return 0;
+ s = cp = xstrdup(names);
+ for ((p = strsep(&cp, ",")); p && *p != '\0';
+ (p = strsep(&cp, ","))) {
+ if (strncmp(p, "gss-", 4) != 0
+ || kex_alg_by_name(p) == NULL) {
+ error("Unsupported KEX algorithm \"%.100s\"", p);
+ free(s);
+ return 0;
+ }
+ }
+ debug3("gss kex names ok: [%s]", names);
+ free(s);
+ return 1;
+}
+
/* put algorithm proposal into buffer */
int
kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
diff -up openssh-7.0p1/kex.h.gsskexalg openssh-7.0p1/kex.h
--- openssh-7.0p1/kex.h.gsskexalg 2015-08-19 12:28:38.078518839 +0200
+++ openssh-7.0p1/kex.h 2015-08-19 12:30:52.404218958 +0200
@@ -173,6 +173,7 @@ int kex_names_valid(const char *);
char *kex_alg_list(char);
char *kex_names_cat(const char *, const char *);
int kex_assemble_names(char **, const char *, const char *);
+int gss_kex_names_valid(const char *);
int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **);
int kex_setup(struct ssh *, char *[PROPOSAL_MAX]);
diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c
--- openssh-7.0p1/readconf.c.gsskexalg 2015-08-19 12:28:38.026518955 +0200
+++ openssh-7.0p1/readconf.c 2015-08-19 12:31:28.333138747 +0200
@@ -61,6 +61,7 @@
#include "uidswap.h"
#include "myproposal.h"
#include "digest.h"
+#include "ssh-gss.h"
/* Format of the configuration file:
@@ -148,7 +149,7 @@ typedef enum {
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
- oGssServerIdentity,
+ oGssServerIdentity, oGssKexAlgorithms,
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
oHashKnownHosts,
@@ -200,6 +201,7 @@ static struct {
{ "gssapiclientidentity", oGssClientIdentity },
{ "gssapiserveridentity", oGssServerIdentity },
{ "gssapirenewalforcesrekey", oGssRenewalRekey },
+ { "gssapikexalgorithms", oGssKexAlgorithms },
# else
{ "gssapiauthentication", oUnsupported },
{ "gssapikeyexchange", oUnsupported },
@@ -207,6 +209,7 @@ static struct {
{ "gssapitrustdns", oUnsupported },
{ "gssapiclientidentity", oUnsupported },
{ "gssapirenewalforcesrekey", oUnsupported },
+ { "gssapikexalgorithms", oUnsupported },
#endif
#ifdef ENABLE_PKCS11
{ "smartcarddevice", oPKCS11Provider },
@@ -929,6 +932,18 @@ parse_time:
intptr = &options->gss_renewal_rekey;
goto parse_flag;
+ case oGssKexAlgorithms:
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing argument.",
+ filename, linenum);
+ if (!gss_kex_names_valid(arg))
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
+ filename, linenum, arg ? arg : "<NONE>");
+ if (*activep && options->gss_kex_algorithms == NULL)
+ options->gss_kex_algorithms = xstrdup(arg);
+ break;
+
case oBatchMode:
intptr = &options->batch_mode;
goto parse_flag;
@@ -1638,6 +1653,7 @@ initialize_options(Options * options)
options->gss_renewal_rekey = -1;
options->gss_client_identity = NULL;
options->gss_server_identity = NULL;
+ options->gss_kex_algorithms = NULL;
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->kbd_interactive_devices = NULL;
@@ -1773,6 +1789,10 @@ fill_default_options(Options * options)
options->gss_trust_dns = 0;
if (options->gss_renewal_rekey == -1)
options->gss_renewal_rekey = 0;
+#ifdef GSSAPI
+ if (options->gss_kex_algorithms == NULL)
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
+#endif
if (options->password_authentication == -1)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
@@ -2651,6 +2671,8 @@ dump_client_config(Options *o, const cha
dump_cfg_string(oGssClientIdentity, o->gss_client_identity);
dump_cfg_string(oGssServerIdentity, o->gss_client_identity);
dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey);
+ dump_cfg_string(oGssKexAlgorithms, o->gss_kex_algorithms ?
+ o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX);
#endif /* GSSAPI */
dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
diff -up openssh-7.9p1/readconf.h.gsskexalg openssh-7.9p1/readconf.h
--- openssh-7.9p1/readconf.h.gsskexalg 2018-11-14 09:20:06.616350574 +0100
+++ openssh-7.9p1/readconf.h 2018-11-14 09:20:06.647350828 +0100
@@ -46,6 +46,7 @@ typedef struct {
int gss_renewal_rekey; /* Credential renewal forces rekey */
char *gss_client_identity; /* Principal to initiate GSSAPI with */
char *gss_server_identity; /* GSSAPI target principal */
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */
int password_authentication; /* Try password
* authentication. */
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c
--- openssh-7.0p1/servconf.c.gsskexalg 2015-08-19 12:28:38.074518847 +0200
+++ openssh-7.0p1/servconf.c 2015-08-19 12:33:13.599902732 +0200
@@ -57,6 +57,7 @@
#include "auth.h"
#include "myproposal.h"
#include "digest.h"
+#include "ssh-gss.h"
static void add_listen_addr(ServerOptions *, const char *,
const char *, int);
@@ -121,6 +122,7 @@ initialize_server_options(ServerOptions
options->gss_cleanup_creds = -1;
options->gss_strict_acceptor = -1;
options->gss_store_rekey = -1;
+ options->gss_kex_algorithms = NULL;
options->use_kuserok = -1;
options->enable_k5users = -1;
options->password_authentication = -1;
@@ -288,6 +290,10 @@ fill_default_server_options(ServerOption
options->gss_strict_acceptor = 1;
if (options->gss_store_rekey == -1)
options->gss_store_rekey = 0;
+#ifdef GSSAPI
+ if (options->gss_kex_algorithms == NULL)
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
+#endif
if (options->use_kuserok == -1)
options->use_kuserok = 1;
if (options->enable_k5users == -1)
@@ -427,7 +431,7 @@ typedef enum {
sHostKeyAlgorithms,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel,
+ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
sHostCertificate,
@@ -506,6 +510,7 @@ static struct {
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
+ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
#else
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
@@ -513,6 +518,7 @@ static struct {
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
{ "gssapienablek5users", sUnsupported, SSHCFG_ALL },
+ { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
@@ -1273,6 +1279,18 @@ process_server_config_line(ServerOptions
intptr = &options->gss_store_rekey;
goto parse_flag;
+ case sGssKexAlgorithms:
+ arg = strdelim(&cp);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing argument.",
+ filename, linenum);
+ if (!gss_kex_names_valid(arg))
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
+ filename, linenum, arg ? arg : "<NONE>");
+ if (*activep && options->gss_kex_algorithms == NULL)
+ options->gss_kex_algorithms = xstrdup(arg);
+ break;
+
case sPasswordAuthentication:
intptr = &options->password_authentication;
goto parse_flag;
@@ -2304,6 +2322,7 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sGssKeyEx, o->gss_keyex);
dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
+ dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms);
#endif
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
dump_cfg_fmtint(sKbdInteractiveAuthentication,
diff -up openssh-7.0p1/servconf.h.gsskexalg openssh-7.0p1/servconf.h
--- openssh-7.0p1/servconf.h.gsskexalg 2015-08-19 12:28:38.080518834 +0200
+++ openssh-7.0p1/servconf.h 2015-08-19 12:34:46.328693944 +0200
@@ -122,6 +122,7 @@ typedef struct {
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */
int gss_store_rekey;
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */
int password_authentication; /* If true, permit password
* authentication. */
int kbd_interactive_authentication; /* If true, permit */
diff -up openssh-7.0p1/ssh.1.gsskexalg openssh-7.0p1/ssh.1
--- openssh-7.0p1/ssh.1.gsskexalg 2015-08-19 12:28:38.081518832 +0200
+++ openssh-7.0p1/ssh.1 2015-08-19 12:35:31.741591692 +0200
@@ -496,6 +496,7 @@ For full details of the options listed b
.It GSSAPIDelegateCredentials
.It GSSAPIRenewalForcesRekey
.It GSSAPITrustDNS
+.It GSSAPIKexAlgorithms
.It HashKnownHosts
.It Host
.It HostbasedAuthentication
diff -up openssh-7.0p1/ssh_config.5.gsskexalg openssh-7.0p1/ssh_config.5
--- openssh-7.0p1/ssh_config.5.gsskexalg 2015-08-19 12:28:38.028518950 +0200
+++ openssh-7.0p1/ssh_config.5 2015-08-19 12:28:38.082518830 +0200
@@ -786,6 +786,18 @@ command line will be passed untouched to
command line will be passed untouched to the GSSAPI library.
The default is
.Dq no .
+.It Cm GSSAPIKexAlgorithms
+The list of key exchange algorithms that are offered for GSSAPI
+key exchange. Possible values are
+.Bd -literal -offset 3n
+gss-gex-sha1-,
+gss-group1-sha1-,
+gss-group14-sha1-
+.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 HashKnownHosts
Indicates that
.Xr ssh 1
diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c
--- openssh-7.0p1/sshconnect2.c.gsskexalg 2015-08-19 12:28:38.045518912 +0200
+++ openssh-7.0p1/sshconnect2.c 2015-08-19 12:28:38.081518832 +0200
@@ -179,7 +179,8 @@ ssh_kex2(char *host, struct sockaddr *ho
else
gss_host = host;
- gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
+ gss = ssh_gssapi_client_mechanisms(gss_host,
+ options.gss_client_identity, options.gss_kex_algorithms);
if (gss) {
debug("Offering GSSAPI proposal: %s", gss);
xasprintf(&options.kex_algorithms,
--- openssh-7.1p1/sshd_config.5.gsskexalg 2015-12-10 15:32:48.105418092 +0100
+++ openssh-7.1p1/sshd_config.5 2015-12-10 15:33:47.771279548 +0100
@@ -663,6 +663,18 @@ or updated credentials from a compatible
For this to work
.Cm GSSAPIKeyExchange
needs to be enabled in the server and also used by the client.
+.It Cm GSSAPIKexAlgorithms
+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-
+.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.
diff -up openssh-7.0p1/ssh-gss.h.gsskexalg openssh-7.0p1/ssh-gss.h
--- openssh-7.0p1/ssh-gss.h.gsskexalg 2015-08-19 12:28:38.031518944 +0200
+++ openssh-7.0p1/ssh-gss.h 2015-08-19 12:28:38.081518832 +0200
@@ -76,6 +76,10 @@ extern char **k5users_allowed_cmds;
#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-"
#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-"
+#define GSS_KEX_DEFAULT_KEX \
+ KEX_GSS_GEX_SHA1_ID "," \
+ KEX_GSS_GRP14_SHA1_ID
+
typedef struct {
char *envvar;
char *envval;
@@ -147,9 +151,9 @@ int ssh_gssapi_credentials_updated(Gssct
/* In the server */
typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *,
const char *);
-char *ssh_gssapi_client_mechanisms(const char *, const char *);
+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *);
char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *,
- const char *);
+ const char *, const char *);
gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *,
const char *);

View File

@ -1,52 +0,0 @@
diff -up openssh-7.4p1/ssh_config.5.gss-docs openssh-7.4p1/ssh_config.5
--- openssh-7.4p1/ssh_config.5.gss-docs 2016-12-23 14:28:34.051714486 +0100
+++ openssh-7.4p1/ssh_config.5 2016-12-23 14:34:24.568522417 +0100
@@ -765,10 +765,19 @@ The default is
If set to
.Dq yes
then renewal of the client's GSSAPI credentials will force the rekeying of the
-ssh connection. With a compatible server, this can delegate the renewed
+ssh connection. With a compatible server, this will delegate the renewed
credentials to a session on the server.
+.Pp
+Checks are made to ensure that credentials are only propagated when the new
+credentials match the old ones on the originating client and where the
+receiving server still has the old set in its cache.
+.Pp
The default is
.Dq no .
+.Pp
+For this to work
+.Cm GSSAPIKeyExchange
+needs to be enabled in the server and also used by the client.
.It Cm GSSAPIServerIdentity
If set, specifies the GSSAPI server identity that ssh should expect when
connecting to the server. The default is unset, which means that the
@@ -776,9 +785,11 @@ expected GSSAPI server identity will be
hostname.
.It Cm GSSAPITrustDns
Set to
-.Dq yes to indicate that the DNS is trusted to securely canonicalize
+.Dq yes
+to indicate that the DNS is trusted to securely canonicalize
the name of the host being connected to. If
-.Dq no, the hostname entered on the
+.Dq no ,
+the hostname entered on the
command line will be passed untouched to the GSSAPI library.
The default is
.Dq no .
diff -up openssh-7.4p1/sshd_config.5.gss-docs openssh-7.4p1/sshd_config.5
--- openssh-7.4p1/sshd_config.5.gss-docs 2016-12-23 14:28:34.043714490 +0100
+++ openssh-7.4p1/sshd_config.5 2016-12-23 14:28:34.051714486 +0100
@@ -652,6 +652,10 @@ Controls whether the user's GSSAPI crede
successful connection rekeying. This option can be used to accepted renewed
or updated credentials from a compatible client. The default is
.Dq no .
+.Pp
+For this to work
+.Cm GSSAPIKeyExchange
+needs to be enabled in the server and also used by the client.
.It Cm HostbasedAcceptedKeyTypes
Specifies the key types that will be accepted for hostbased authentication
as a list of comma-separated patterns.

View File

@ -56,9 +56,9 @@ diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h
--- openssh-7.4p1/monitor_wrap.h.audit-race 2016-12-23 16:35:52.694685771 +0100
+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 16:35:52.698685772 +0100
@@ -83,6 +83,8 @@ void mm_audit_unsupported_body(int);
void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t);
void mm_audit_session_key_free_body(int, pid_t, uid_t);
void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t);
void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t);
void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t);
void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t);
+int mm_forward_audit_messages(int);
+void mm_set_monitor_pipe(int);
#endif
@ -82,7 +82,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
return 1;
}
+void child_destory_sensitive_data();
+void child_destory_sensitive_data(struct ssh *ssh);
+
#define USE_PIPES 1
/*
@ -91,7 +91,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
close(err[0]);
#endif
+ child_destory_sensitive_data();
+ child_destory_sensitive_data(ssh);
+
/* Do processing for the child (exec command etc). */
do_child(ssh, s, command);
@ -101,7 +101,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
close(ttyfd);
+ /* Do this early, so we will not block large MOTDs */
+ child_destory_sensitive_data();
+ child_destory_sensitive_data(ssh);
+
/* record login, etc. similar to login(1) */
#ifndef HAVE_OSF_SIA
@ -109,7 +109,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
@@ -717,6 +728,8 @@ do_exec(Session *s, const char *command)
}
if (s->command != NULL && s->ptyfd == -1)
s->command_handle = PRIVSEP(audit_run_command(s->command));
s->command_handle = PRIVSEP(audit_run_command(ssh, s->command));
+ if (pipe(paudit) < 0)
+ fatal("pipe: %s", strerror(errno));
#endif
@ -141,7 +141,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
}
+void
+child_destory_sensitive_data()
+child_destory_sensitive_data(struct ssh *ssh)
+{
+#ifdef SSH_AUDIT_EVENTS
+ int pparent = paudit[1];
@ -152,15 +152,15 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
+#endif
+
+ /* remove hostkey from the child's memory */
+ destroy_sensitive_data(use_privsep);
+ destroy_sensitive_data(ssh, use_privsep);
+ /*
+ * We can audit this, because we hacked the pipe to direct the
+ * messages over postauth child. But this message requires answer
+ * which we can't do using one-way pipe.
+ */
+ packet_destroy_all(0, 1);
+ packet_destroy_all(ssh, 0, 1);
+ /* XXX this will clean the rest but should not audit anymore */
+ /* packet_clear_keys(); */
+ /* packet_clear_keys(ssh); */
+
+#ifdef SSH_AUDIT_EVENTS
+ /* Notify parent that we are done */
@ -172,15 +172,15 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
* Performs common processing for the child, such as setting up the
* environment, closing extra file descriptors, setting the user and group
@@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command
pw = s->pw;
}
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
- /* remove hostkey from the child's memory */
- destroy_sensitive_data(1);
- packet_clear_keys();
- destroy_sensitive_data(ssh, 1);
- ssh_packet_clear_keys(ssh);
- /* Don't audit this - both us and the parent would be talking to the
- monitor over a single socket, with no synchronization. */
- packet_destroy_all(0, 1);
- packet_destroy_all(ssh, 0, 1);
-
/* Force a password change */
if (s->authctxt->force_pwchange) {

View File

@ -2,10 +2,11 @@ diff --git a/auth-krb5.c b/auth-krb5.c
index 2b02a04..19b9364 100644
--- a/auth-krb5.c
+++ b/auth-krb5.c
@@ -375,6 +375,22 @@ cleanup:
return -1;
@@ -375,5 +375,21 @@ cleanup:
return (krb5_cc_resolve(ctx, ccname, ccache));
}
}
+
+/*
+ * Reads k5login_directory option from the krb5.conf
+ */
@ -21,10 +22,8 @@ index 2b02a04..19b9364 100644
+ return profile_get_string(p, "libdefaults", "k5login_directory", NULL, NULL,
+ k5login_directory);
+}
+
krb5_error_code
ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
profile_t p;
#endif /* !HEIMDAL */
#endif /* KRB5 */
diff --git a/auth.h b/auth.h
index f9d191c..c432d2f 100644
--- a/auth.h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
--- openssh/auth2-pubkey.c.refactor 2017-09-27 13:10:19.556830609 +0200
+++ openssh/auth2-pubkey.c 2017-09-27 13:10:19.677831274 +0200
--- 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 @@
extern ServerOptions options;
extern u_char *session_id2;
@ -11,7 +11,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
static char *
format_key(const struct sshkey *key)
@@ -432,7 +435,8 @@ match_principals_command(struct passwd *
@@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command,
ac, av, &f,
@ -21,7 +21,7 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
goto out;
uid_swapped = 1;
@@ -762,7 +766,8 @@ user_key_command_allowed2(struct passwd
@@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss
if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command,
ac, av, &f,
@ -32,9 +32,9 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c
uid_swapped = 1;
diff -up openssh/auth.c.refactor openssh/auth.c
--- openssh/auth.c.refactor 2017-09-27 13:10:19.640831071 +0200
+++ openssh/auth.c 2017-09-27 13:10:19.678831279 +0200
@@ -1435,7 +1435,8 @@ argv_assemble(int argc, char **argv)
--- openssh/auth.c.refactor 2019-04-04 13:19:12.235821686 +0200
+++ openssh/auth.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,
@ -44,7 +44,7 @@ diff -up openssh/auth.c.refactor openssh/auth.c
{
FILE *f = NULL;
struct stat st;
@@ -1551,7 +1552,7 @@ subprocess(const char *tag, struct passw
@@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw
}
#ifdef WITH_SELINUX
@ -54,9 +54,9 @@ diff -up openssh/auth.c.refactor openssh/auth.c
strerror(errno));
_exit(127);
diff -up openssh/auth.h.refactor openssh/auth.h
--- openssh/auth.h.refactor 2017-09-25 01:48:10.000000000 +0200
+++ openssh/auth.h 2017-09-27 13:10:19.678831279 +0200
@@ -144,7 +144,7 @@ int exited_cleanly(pid_t, const char *,
--- openssh/auth.h.refactor 2019-04-04 13:19:12.251821839 +0200
+++ openssh/auth.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 *,
@ -66,8 +66,8 @@ diff -up openssh/auth.h.refactor openssh/auth.h
int sys_auth_passwd(struct ssh *, const char *);
diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h
--- openssh/openbsd-compat/port-linux.h.refactor 2017-09-27 13:10:19.634831038 +0200
+++ openssh/openbsd-compat/port-linux.h 2017-09-27 13:10:54.954025248 +0200
--- 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
@@ -26,8 +26,8 @@ void ssh_selinux_setfscreatecon(const ch
int sshd_selinux_enabled(void);
@ -80,9 +80,9 @@ diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/por
#endif
diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compat/port-linux-sshd.c
--- openssh/openbsd-compat/port-linux-sshd.c.refactor 2017-09-27 13:10:19.634831038 +0200
+++ openssh/openbsd-compat/port-linux-sshd.c 2017-09-27 13:12:06.811420371 +0200
@@ -48,11 +48,6 @@
--- openssh/openbsd-compat/port-linux-sshd.c.refactor 2019-04-04 13:19:12.256821887 +0200
+++ openssh/openbsd-compat/port-linux-sshd.c 2019-04-04 13:19:12.276822078 +0200
@@ -49,11 +49,6 @@
#include <unistd.h>
#endif
@ -94,7 +94,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
/* Wrapper around is_selinux_enabled() to log its return value once only */
int
sshd_selinux_enabled(void)
@@ -222,7 +217,8 @@ get_user_context(const char *sename, con
@@ -223,7 +218,8 @@ get_user_context(const char *sename, con
}
static void
@ -104,7 +104,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
{
*role = NULL;
*level = NULL;
@@ -240,8 +236,8 @@ ssh_selinux_get_role_level(char **role,
@@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role,
/* Return the default security context for the given username */
static int
@ -115,7 +115,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
{
char *sename, *lvl;
char *role;
@@ -249,7 +245,7 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
int r = 0;
context_t con = NULL;
@ -124,7 +124,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
#ifdef HAVE_GETSEUSERBYNAME
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
@@ -271,7 +267,7 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
if (r == 0) {
/* If launched from xinetd, we must use current level */
@ -133,7 +133,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
security_context_t sshdsc=NULL;
if (getcon_raw(&sshdsc) < 0)
@@ -332,7 +328,8 @@ sshd_selinux_getctxbyname(char *pwname,
@@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
/* Setup environment variables for pam_selinux */
static int
@ -143,7 +143,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
{
const char *reqlvl;
char *role;
@@ -341,11 +338,11 @@ sshd_selinux_setup_variables(int(*set_it
@@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
debug3("%s: setting execution context", __func__);
@ -157,7 +157,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
use_current = "1";
} else {
use_current = "";
@@ -361,9 +358,10 @@ sshd_selinux_setup_variables(int(*set_it
@@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it
}
static int
@ -170,7 +170,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
}
static int
@@ -373,25 +371,28 @@ do_setenv(char *name, const char *value)
@@ -374,25 +372,28 @@ do_setenv(char *name, const char *value)
}
int
@ -204,7 +204,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
switch (security_getenforce()) {
case -1:
fatal("%s: security_getenforce() failed", __func__);
@@ -409,7 +410,7 @@ sshd_selinux_setup_exec_context(char *pw
@@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw
debug3("%s: setting execution context", __func__);
@ -214,9 +214,9 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa
r = setexeccon(user_ctx);
if (r < 0) {
diff -up openssh/platform.c.refactor openssh/platform.c
--- openssh/platform.c.refactor 2017-09-27 13:10:19.574830708 +0200
+++ openssh/platform.c 2017-09-27 13:11:45.475303050 +0200
@@ -33,6 +33,9 @@
--- openssh/platform.c.refactor 2019-04-04 13:19:12.204821389 +0200
+++ openssh/platform.c 2019-04-04 13:19:12.277822088 +0200
@@ -32,6 +32,9 @@
extern int use_privsep;
extern ServerOptions options;
@ -226,7 +226,7 @@ diff -up openssh/platform.c.refactor openssh/platform.c
void
platform_pre_listen(void)
@@ -184,7 +187,9 @@ platform_setusercontext_post_groups(stru
@@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru
}
#endif /* HAVE_SETPCRED */
#ifdef WITH_SELINUX
@ -238,9 +238,27 @@ diff -up openssh/platform.c.refactor openssh/platform.c
}
diff -up openssh/sshd.c.refactor openssh/sshd.c
--- openssh/sshd.c.refactor 2017-09-27 13:10:19.674831257 +0200
+++ openssh/sshd.c 2017-09-27 13:12:01.635391909 +0200
@@ -2135,7 +2135,9 @@ main(int ac, char **av)
--- openssh/sshd.c.refactor 2019-04-04 13:19:12.275822068 +0200
+++ openssh/sshd.c 2019-04-04 13:19:51.270195262 +0200
@@ -158,7 +158,7 @@ int debug_flag = 0;
static int test_flag = 0;
/* Flag indicating that the daemon is being started from inetd. */
-static int inetd_flag = 0;
+int inetd_flag = 0;
/* Flag indicating that sshd should not detach and become a daemon. */
static int no_daemon_flag = 0;
@@ -171,7 +171,7 @@ static char **saved_argv;
static int saved_argc;
/* re-exec */
-static int rexeced_flag = 0;
+int rexeced_flag = 0;
static int rexec_flag = 1;
static int rexec_argc = 0;
static char **rexec_argv;
@@ -2192,7 +2192,9 @@ main(int ac, char **av)
}
#endif
#ifdef WITH_SELINUX

View File

@ -1,794 +0,0 @@
diff -up openssh/ssh-pkcs11-client.c.pkcs11-ecdsa openssh/ssh-pkcs11-client.c
--- openssh/ssh-pkcs11-client.c.pkcs11-ecdsa 2018-10-12 14:05:55.020656974 +0200
+++ openssh/ssh-pkcs11-client.c 2018-10-12 14:05:55.023656999 +0200
@@ -31,6 +31,15 @@
#include <errno.h>
#include <openssl/rsa.h>
+#ifdef OPENSSL_HAS_ECC
+#include <openssl/ecdsa.h>
+#if ((defined(LIBRESSL_VERSION_NUMBER) && \
+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
+ (OPENSSL_VERSION_NUMBER >= 0x00010100L)
+#define ENABLE_PKCS11_ECDSA 1
+#endif
+#endif
#include "openbsd-compat/openssl-compat.h"
@@ -155,9 +164,9 @@ pkcs11_rsa_private_encrypt(int flen, con
return (ret);
}
-/* redirect the private key encrypt operation to the ssh-pkcs11-helper */
+/* redirect the RSA private key encrypt operation to the ssh-pkcs11-helper */
static int
-wrap_key(RSA *rsa)
+wrap_rsa_key(RSA *rsa)
{
static RSA_METHOD *helper_rsa;
@@ -170,6 +179,88 @@ wrap_key(RSA *rsa)
return (0);
}
+#ifdef ENABLE_PKCS11_ECDSA
+static ECDSA_SIG *
+pkcs11_ecdsa_private_sign(const unsigned char *from, int flen,
+ const BIGNUM *inv, const BIGNUM *rp, EC_KEY * ecdsa)
+{
+ struct sshkey *key = NULL;
+ u_char *blob, *signature = NULL;
+ size_t blen, slen = 0;
+ struct sshbuf *msg = NULL;
+ ECDSA_SIG *ret = NULL;
+ BIGNUM *r = NULL, *s = NULL;
+ int rv;
+
+ if ((key = sshkey_new(KEY_ECDSA)) == NULL)
+ fatal("%s: sshkey_new failed", __func__);
+ key->ecdsa = ecdsa;
+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
+ if (sshkey_to_blob(key, &blob, &blen) == 0)
+ goto out;
+ if ((msg = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new failed", __func__);
+ if ((rv = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
+ (rv = sshbuf_put_string(msg, blob, blen)) != 0 ||
+ (rv = sshbuf_put_string(msg, from, flen)) != 0 ||
+ (rv = sshbuf_put_u32(msg, 0)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(rv));
+ free(blob);
+ send_msg(msg);
+ sshbuf_reset(msg);
+
+ if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
+ if ((rv = sshbuf_get_string(msg, &signature, &slen)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(rv));
+ if (slen <= (size_t)ECDSA_size(ecdsa)) {
+ int nlen = slen / 2;
+ ret = ECDSA_SIG_new();
+ r = BN_new();
+ s = BN_new();
+ BN_bin2bn(&signature[0], nlen, r);
+ BN_bin2bn(&signature[nlen], nlen, s);
+ ECDSA_SIG_set0(ret, r, s);
+ }
+ free(signature);
+ }
+out:
+ sshkey_free(key);
+ sshbuf_free(msg);
+ return (ret);
+}
+
+/* redirect the ECDSA private key encrypt operation to the ssh-pkcs11-helper */
+static int
+wrap_ecdsa_key(EC_KEY *ecdsa) {
+#if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
+ static EC_KEY_METHOD *helper_ecdsa = NULL;
+ if (helper_ecdsa == NULL) {
+ const EC_KEY_METHOD *def = EC_KEY_get_default_method();
+ helper_ecdsa = EC_KEY_METHOD_new(def);
+ EC_KEY_METHOD_set_sign(helper_ecdsa, NULL, NULL, pkcs11_ecdsa_private_sign);
+ }
+ EC_KEY_set_method(ecdsa, helper_ecdsa);
+#else
+ static ECDSA_METHOD *helper_ecdsa = NULL;
+ if(helper_ecdsa == NULL) {
+ const ECDSA_METHOD *def = ECDSA_get_default_method();
+# ifdef ECDSA_F_ECDSA_METHOD_NEW
+ helper_ecdsa = ECDSA_METHOD_new((ECDSA_METHOD *)def);
+ ECDSA_METHOD_set_name(helper_ecdsa, "ssh-pkcs11-helper-ecdsa");
+ ECDSA_METHOD_set_sign(helper_ecdsa, pkcs11_ecdsa_private_sign);
+# else
+ helper_ecdsa = xcalloc(1, sizeof(*helper_ecdsa));
+ memcpy(helper_ecdsa, def, sizeof(*helper_ecdsa));
+ helper_ecdsa->name = "ssh-pkcs11-helper-ecdsa";
+ helper_ecdsa->ecdsa_do_sign = pkcs11_ecdsa_private_sign;
+# endif
+ }
+ ECDSA_set_method(ecdsa, helper_ecdsa);
+#endif
+ return (0);
+}
+#endif
+
static int
pkcs11_start_helper(void)
{
@@ -238,7 +329,15 @@ pkcs11_add_provider(char *name, char *pi
__func__, ssh_err(r));
if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
fatal("%s: bad key: %s", __func__, ssh_err(r));
- wrap_key(k->rsa);
+ if(k->type == KEY_RSA) {
+ wrap_rsa_key(k->rsa);
+#ifdef ENABLE_PKCS11_ECDSA
+ } else if(k->type == KEY_ECDSA) {
+ wrap_ecdsa_key(k->ecdsa);
+#endif /* ENABLE_PKCS11_ECDSA */
+ } else {
+ /* Unsupported type */
+ }
(*keysp)[i] = k;
free(blob);
}
diff -up openssh/ssh-pkcs11.c.pkcs11-ecdsa openssh/ssh-pkcs11.c
--- openssh/ssh-pkcs11.c.pkcs11-ecdsa 2018-10-12 14:05:55.021656982 +0200
+++ openssh/ssh-pkcs11.c 2018-10-12 14:11:54.292636679 +0200
@@ -33,6 +33,16 @@
#include "openbsd-compat/openssl-compat.h"
#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#ifdef OPENSSL_HAS_ECC
+#include <openssl/ecdsa.h>
+#if ((defined(LIBRESSL_VERSION_NUMBER) && \
+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
+ (OPENSSL_VERSION_NUMBER >= 0x00010100L)
+#define ENABLE_PKCS11_ECDSA 1
+#endif
+#endif
#define CRYPTOKI_COMPAT
#include "pkcs11.h"
@@ -74,6 +84,7 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_pro
struct pkcs11_key {
struct pkcs11_provider *provider;
CK_ULONG slotidx;
+ CK_ULONG key_type;
int (*orig_finish)(RSA *rsa);
RSA_METHOD *rsa_method;
char *keyid;
@@ -82,6 +93,9 @@ struct pkcs11_key {
};
int pkcs11_interactive = 0;
+#ifdef ENABLE_PKCS11_ECDSA
+static int pkcs11_key_idx = -1;
+#endif /* ENABLE_PKCS11_ECDSA */
/*
* This can't be in the ssh-pkcs11-uri, becase we can not depend on
@@ -345,6 +359,40 @@ pkcs11_find(struct pkcs11_provider *p, C
return (ret);
}
+int pkcs11_login(struct pkcs11_key *k11, CK_FUNCTION_LIST *f, struct pkcs11_slotinfo *si) {
+ char *pin = NULL, prompt[1024];
+ CK_RV rv;
+ if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
+ if (!pkcs11_interactive) {
+ error("need pin entry%s", (si->token.flags &
+ CKF_PROTECTED_AUTHENTICATION_PATH) ?
+ " on reader keypad" : "");
+ return (-1);
+ }
+ if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
+ verbose("Deferring PIN entry to reader keypad.");
+ else {
+ snprintf(prompt, sizeof(prompt),
+ "Enter PIN for '%s': ", si->token.label);
+ pin = read_passphrase(prompt, RP_ALLOW_EOF);
+ if (pin == NULL)
+ return (-1); /* bail out */
+ }
+ rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
+ (pin != NULL) ? strlen(pin) : 0);
+ if (pin != NULL) {
+ explicit_bzero(pin, strlen(pin));
+ free(pin);
+ }
+ if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
+ error("C_Login failed: %lu", rv);
+ return (-1);
+ }
+ si->logged_in = 1;
+ }
+ return 0;
+}
+
/* openssl callback doing the actual signing operation */
static int
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
@@ -366,7 +414,6 @@ pkcs11_rsa_private_encrypt(int flen, con
{CKA_ID, NULL, 0},
{CKA_SIGN, NULL, sizeof(true_val) }
};
- char *pin = NULL, prompt[1024];
int rval = -1;
key_filter[0].pValue = &private_key_class;
@@ -383,33 +430,8 @@ pkcs11_rsa_private_encrypt(int flen, con
}
f = k11->provider->module->function_list;
si = &k11->provider->module->slotinfo[k11->slotidx];
- if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
- if (!pkcs11_interactive) {
- error("need pin entry%s", (si->token.flags &
- CKF_PROTECTED_AUTHENTICATION_PATH) ?
- " on reader keypad" : "");
- return (-1);
- }
- if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
- verbose("Deferring PIN entry to reader keypad.");
- else {
- snprintf(prompt, sizeof(prompt),
- "Enter PIN for '%s': ", si->token.label);
- pin = read_passphrase(prompt, RP_ALLOW_EOF);
- if (pin == NULL)
- return (-1); /* bail out */
- }
- rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
- (pin != NULL) ? strlen(pin) : 0);
- if (pin != NULL) {
- explicit_bzero(pin, strlen(pin));
- free(pin);
- }
- if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
- error("C_Login failed: %lu", rv);
- return (-1);
- }
- si->logged_in = 1;
+ if(pkcs11_login(k11, f, si)) {
+ return (-1);
}
key_filter[1].pValue = k11->keyid;
key_filter[1].ulValueLen = k11->keyid_len;
@@ -447,6 +469,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
const RSA_METHOD *def = RSA_get_default_method();
k11 = xcalloc(1, sizeof(*k11));
+ k11->key_type = CKK_RSA;
k11->provider = provider;
provider->refcount++; /* provider referenced by RSA key */
k11->slotidx = slotidx;
@@ -477,6 +500,184 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
return (0);
}
+#ifdef ENABLE_PKCS11_ECDSA
+static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len,
+ const BIGNUM *inv, const BIGNUM *rp,
+ EC_KEY *ecdsa) {
+ struct pkcs11_key *k11;
+ struct pkcs11_slotinfo *si;
+ CK_FUNCTION_LIST *f;
+ CK_OBJECT_HANDLE obj;
+ CK_ULONG tlen = 0;
+ CK_RV rv;
+ CK_OBJECT_CLASS private_key_class = CKO_PRIVATE_KEY;
+ CK_BBOOL true_val = CK_TRUE;
+ CK_MECHANISM mech = {
+ CKM_ECDSA, NULL_PTR, 0
+ };
+ CK_ATTRIBUTE key_filter[] = {
+ {CKA_CLASS, NULL, sizeof(private_key_class) },
+ {CKA_ID, NULL, 0},
+ {CKA_SIGN, NULL, sizeof(true_val) }
+ };
+ ECDSA_SIG *rval = NULL;
+ key_filter[0].pValue = &private_key_class;
+ key_filter[2].pValue = &true_val;
+
+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
+ if ((k11 = (struct pkcs11_key *)EC_KEY_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
+ error("EC_KEY_get_ex_data failed for ecdsa %p", ecdsa);
+ #else
+ if ((k11 = (struct pkcs11_key *)ECDSA_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
+ error("ECDSA_get_ex_data failed for ecdsa %p", ecdsa);
+ #endif
+ return NULL;
+ }
+ if (!k11->provider || !k11->provider->valid) {
+ error("no pkcs11 (valid) provider for ecdsa %p", ecdsa);
+ return NULL;
+ }
+ f = k11->provider->module->function_list;
+ si = &k11->provider->module->slotinfo[k11->slotidx];
+ if(pkcs11_login(k11, f, si)) {
+ return NULL;
+ }
+ key_filter[1].pValue = k11->keyid;
+ key_filter[1].ulValueLen = k11->keyid_len;
+ /* try to find object w/CKA_SIGN first, retry w/o */
+ if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 &&
+ pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) {
+ error("cannot find private key");
+ } else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
+ error("C_SignInit failed: %lu", rv);
+ } else {
+ CK_BYTE_PTR buf = NULL;
+ BIGNUM *r = NULL, *s = NULL;
+ int nlen;
+ /* Make a call to C_Sign to find out the size of the signature */
+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen);
+ if (rv != CKR_OK) {
+ error("C_Sign failed: %lu", rv);
+ return NULL;
+ }
+ if ((buf = xmalloc(tlen)) == NULL) {
+ error("failure to allocate signature buffer");
+ return NULL;
+ }
+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen);
+ if (rv != CKR_OK) {
+ error("C_Sign failed: %lu", rv);
+ }
+
+ if ((rval = ECDSA_SIG_new()) == NULL ||
+ (r = BN_new()) == NULL ||
+ (s = BN_new()) == NULL) {
+ error("failure to allocate ECDSA signature");
+ } else {
+ /*
+ * ECDSA signature is 2 large integers of same size returned
+ * concatenated by PKCS#11, we separate them to create an
+ * ECDSA_SIG for OpenSSL.
+ */
+ nlen = tlen / 2;
+ BN_bin2bn(&buf[0], nlen, r);
+ BN_bin2bn(&buf[nlen], nlen, s);
+ ECDSA_SIG_set0(rval, r, s);
+ }
+ free(buf);
+ }
+ return (rval);
+}
+
+#if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
+static EC_KEY_METHOD *get_pkcs11_ecdsa_method(void) {
+ static EC_KEY_METHOD *pkcs11_ecdsa_method = NULL;
+ if(pkcs11_key_idx == -1) {
+ pkcs11_key_idx = EC_KEY_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ }
+ if (pkcs11_ecdsa_method == NULL) {
+ const EC_KEY_METHOD *def = EC_KEY_get_default_method();
+ pkcs11_ecdsa_method = EC_KEY_METHOD_new(def);
+ EC_KEY_METHOD_set_sign(pkcs11_ecdsa_method, NULL, NULL, pkcs11_ecdsa_sign);
+ }
+#else
+static ECDSA_METHOD *get_pkcs11_ecdsa_method(void) {
+ static ECDSA_METHOD *pkcs11_ecdsa_method = NULL;
+ if(pkcs11_key_idx == -1) {
+ pkcs11_key_idx = ECDSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ }
+ if(pkcs11_ecdsa_method == NULL) {
+ const ECDSA_METHOD *def = ECDSA_get_default_method();
+ #ifdef ECDSA_F_ECDSA_METHOD_NEW
+ pkcs11_ecdsa_method = ECDSA_METHOD_new((ECDSA_METHOD *)def);
+ ECDSA_METHOD_set_name(pkcs11_ecdsa_method, "pkcs11");
+ ECDSA_METHOD_set_sign(pkcs11_ecdsa_method, pkcs11_ecdsa_sign);
+ #else
+ pkcs11_ecdsa_method = xcalloc(1, sizeof(*pkcs11_ecdsa_method));
+ memcpy(pkcs11_ecdsa_method, def, sizeof(*pkcs11_ecdsa_method));
+ pkcs11_ecdsa_method->name = "pkcs11";
+ pkcs11_ecdsa_method->ecdsa_do_sign = pkcs11_ecdsa_sign;
+ #endif
+ }
+#endif
+ return pkcs11_ecdsa_method;
+}
+
+static int
+pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
+ CK_ATTRIBUTE *keyid_attrib, CK_ATTRIBUTE *label_attrib, EC_KEY *ecdsa)
+{
+ struct pkcs11_key *k11;
+ k11 = xcalloc(1, sizeof(*k11));
+ k11->key_type = CKK_EC;
+ k11->provider = provider;
+ provider->refcount++; /* provider referenced by ECDSA key */
+ k11->slotidx = slotidx;
+ /* identify key object on smartcard */
+ k11->keyid_len = keyid_attrib->ulValueLen;
+ if (k11->keyid_len > 0) {
+ k11->keyid = xmalloc(k11->keyid_len);
+ memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
+ }
+ if (label_attrib->ulValueLen > 0 ) {
+ k11->label = xmalloc(label_attrib->ulValueLen+1);
+ memcpy(k11->label, label_attrib->pValue, label_attrib->ulValueLen);
+ k11->label[label_attrib->ulValueLen] = 0;
+ }
+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
+ EC_KEY_set_method(ecdsa, get_pkcs11_ecdsa_method());
+ EC_KEY_set_ex_data(ecdsa, pkcs11_key_idx, k11);
+ #else
+ ECDSA_set_method(ecdsa, get_pkcs11_ecdsa_method());
+ ECDSA_set_ex_data(ecdsa, pkcs11_key_idx, k11);
+ #endif
+ return (0);
+}
+#endif /* ENABLE_PKCS11_ECDSA */
+
+int pkcs11_del_key(struct sshkey *key) {
+#ifdef ENABLE_PKCS11_ECDSA
+ if(key->type == KEY_ECDSA) {
+ struct pkcs11_key *k11 = (struct pkcs11_key *)
+ #if (OPENSSL_VERSION_NUMBER >= 0x00010100L)
+ EC_KEY_get_ex_data(key->ecdsa, pkcs11_key_idx);
+ #else
+ ECDSA_get_ex_data(key->ecdsa, pkcs11_key_idx);
+ #endif
+ if (k11 == NULL) {
+ error("EC_KEY_get_ex_data failed for ecdsa %p", key->ecdsa);
+ } else {
+ if (k11->provider)
+ pkcs11_provider_unref(k11->provider);
+ free(k11->keyid);
+ free(k11);
+ }
+ }
+#endif /* ENABLE_PKCS11_ECDSA */
+ sshkey_free(key);
+ return (0);
+}
+
/* remove trailing spaces */
static void
rmspace(u_char *buf, size_t len)
@@ -544,11 +745,13 @@ static int
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
struct sshkey ***keysp, int *nkeys, struct pkcs11_uri *uri)
{
- size_t filter_size = 1;
+ size_t filter_size = 2;
+ CK_KEY_TYPE pubkey_type = CKK_RSA;
CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY;
CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
CK_ATTRIBUTE pubkey_filter[] = {
{ CKA_CLASS, NULL, sizeof(pubkey_class) },
+ { CKA_KEY_TYPE, NULL, sizeof(pubkey_type) },
{ CKA_ID, NULL, 0 },
{ CKA_LABEL, NULL, 0 }
};
@@ -569,37 +772,72 @@ pkcs11_fetch_keys(struct pkcs11_provider
{ CKA_SUBJECT, NULL, 0 },
{ CKA_VALUE, NULL, 0 }
};
+#ifdef ENABLE_PKCS11_ECDSA
+ CK_KEY_TYPE ecdsa_type = CKK_EC;
+ CK_ATTRIBUTE ecdsa_filter[] = {
+ { CKA_CLASS, NULL, sizeof(pubkey_class) },
+ { CKA_KEY_TYPE, NULL, sizeof(ecdsa_type) },
+ { CKA_ID, NULL, 0 },
+ { CKA_LABEL, NULL, 0 }
+ };
+ CK_ATTRIBUTE ecdsa_attribs[] = {
+ { CKA_ID, NULL, 0 },
+ { CKA_LABEL, NULL, 0 },
+ { CKA_EC_PARAMS, NULL, 0 },
+ { CKA_EC_POINT, NULL, 0 }
+ };
+ ecdsa_filter[0].pValue = &pubkey_class;
+ ecdsa_filter[1].pValue = &ecdsa_type;
+#endif /* ENABLE_PKCS11_ECDSA */
pubkey_filter[0].pValue = &pubkey_class;
+ pubkey_filter[1].pValue = &pubkey_type;
cert_filter[0].pValue = &cert_class;
if (uri->id != NULL) {
pubkey_filter[filter_size].pValue = uri->id;
pubkey_filter[filter_size].ulValueLen = uri->id_len;
- cert_filter[filter_size].pValue = uri->id;
- cert_filter[filter_size].ulValueLen = uri->id_len;
+#ifdef ENABLE_PKCS11_ECDSA
+ ecdsa_filter[filter_size].pValue = uri->id;
+ ecdsa_filter[filter_size].ulValueLen = uri->id_len;
+#endif /* ENABLE_PKCS11_ECDSA */
+ cert_filter[filter_size-1].pValue = uri->id;
+ cert_filter[filter_size-1].ulValueLen = uri->id_len;
filter_size++;
}
if (uri->object != NULL) {
pubkey_filter[filter_size].pValue = uri->object;
pubkey_filter[filter_size].ulValueLen = strlen(uri->object);
pubkey_filter[filter_size].type = CKA_LABEL;
- cert_filter[filter_size].pValue = uri->object;
- cert_filter[filter_size].ulValueLen = strlen(uri->object);
- cert_filter[filter_size].type = CKA_LABEL;
+#ifdef ENABLE_PKCS11_ECDSA
+ ecdsa_filter[filter_size].pValue = uri->object;
+ ecdsa_filter[filter_size].ulValueLen = strlen(uri->object);
+ ecdsa_filter[filter_size].type = CKA_LABEL;
+#endif /* ENABLE_PKCS11_ECDSA */
+ cert_filter[filter_size-1].pValue = uri->object;
+ cert_filter[filter_size-1].ulValueLen = strlen(uri->object);
+ cert_filter[filter_size-1].type = CKA_LABEL;
filter_size++;
}
if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size,
pubkey_attribs, keysp, nkeys) < 0 ||
- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size,
+#ifdef ENABLE_PKCS11_ECDSA
+ pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, filter_size,
+ ecdsa_attribs, keysp, nkeys) < 0||
+#endif /* ENABLE_PKCS11_ECDSA */
+ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1,
cert_attribs, keysp, nkeys) < 0)
return (-1);
if (*nkeys == 0) {
/* Try once more without the label filter */
filter_size--;
if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, filter_size,
pubkey_attribs, keysp, nkeys) < 0 ||
- pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size,
+#ifdef ENABLE_PKCS11_ECDSA
+ pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, filter_size,
+ ecdsa_attribs, keysp, nkeys) < 0||
+#endif /* ENABLE_PKCS11_ECDSA */
+ pkcs11_fetch_keys_filter(p, slotidx, cert_filter, filter_size - 1,
cert_attribs, keysp, nkeys) < 0)
return (-1);
}
@@ -624,8 +858,13 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
CK_ATTRIBUTE filter[], size_t filter_size, CK_ATTRIBUTE attribs[4],
struct sshkey ***keysp, int *nkeys)
{
- struct sshkey *key;
+ struct sshkey *key = NULL;
RSA *rsa;
+#ifdef ENABLE_PKCS11_ECDSA
+ EC_KEY *ecdsa;
+#else
+ void *ecdsa;
+#endif /* ENABLE_PKCS11_ECDSA */
X509 *x509;
EVP_PKEY *evp = NULL;
int i;
@@ -678,6 +917,9 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
* or ID, label, subject and value for certificates.
*/
rsa = NULL;
+#ifdef ENABLE_PKCS11_ECDSA
+ ecdsa = NULL;
+#endif /* ENABLE_PKCS11_ECDSA */
if ((rv = f->C_GetAttributeValue(session, obj, attribs, nattribs))
!= CKR_OK) {
error("C_GetAttributeValue failed: %lu", rv);
@@ -700,6 +942,45 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
BN_free(rsa_n);
BN_free(rsa_e);
}
+#ifdef ENABLE_PKCS11_ECDSA
+ } else if (attribs[2].type == CKA_EC_PARAMS ) {
+ if ((ecdsa = EC_KEY_new()) == NULL) {
+ error("EC_KEY_new failed");
+ } else {
+ const unsigned char *ptr1 = attribs[2].pValue;
+ const unsigned char *ptr2 = attribs[3].pValue;
+ CK_ULONG len1 = attribs[2].ulValueLen;
+ CK_ULONG len2 = attribs[3].ulValueLen;
+ ASN1_OCTET_STRING *point = NULL;
+
+ /*
+ * CKA_EC_PARAMS contains the curve parameters of the key
+ * either referenced as an OID or directly with all values.
+ * CKA_EC_POINT contains the point (public key) on the curve.
+ * The point is should be returned inside a DER-encoded
+ * ASN.1 OCTET STRING value (but some implementation).
+ */
+ if ((point = d2i_ASN1_OCTET_STRING(NULL, &ptr2, len2))) {
+ /* Pointing to OCTET STRING content */
+ ptr2 = point->data;
+ len2 = point->length;
+ } else {
+ /* No OCTET STRING */
+ ptr2 = attribs[3].pValue;
+ }
+
+ if((d2i_ECParameters(&ecdsa, &ptr1, len1) == NULL) ||
+ (o2i_ECPublicKey(&ecdsa, &ptr2, len2) == NULL)) {
+ EC_KEY_free(ecdsa);
+ ecdsa = NULL;
+ error("EC public key parsing failed");
+ }
+
+ if(point) {
+ ASN1_OCTET_STRING_free(point);
+ }
+ }
+#endif /* ENABLE_PKCS11_ECDSA */
} else {
cp = attribs[3].pValue;
if ((x509 = X509_new()) == NULL) {
@@ -707,13 +988,28 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
} else if (d2i_X509(&x509, &cp, attribs[3].ulValueLen)
== NULL) {
error("d2i_X509 failed");
- } else if ((evp = X509_get_pubkey(x509)) == NULL ||
- EVP_PKEY_base_id(evp) != EVP_PKEY_RSA ||
- EVP_PKEY_get0_RSA(evp) == NULL) {
- debug("X509_get_pubkey failed or no rsa");
- } else if ((rsa = RSAPublicKey_dup(
- EVP_PKEY_get0_RSA(evp))) == NULL) {
- error("RSAPublicKey_dup");
+ } else if ((evp = X509_get_pubkey(x509)) == NULL) {
+ debug("X509_get_pubkey failed");
+ } else {
+ switch (EVP_PKEY_base_id(evp)) {
+ case EVP_PKEY_RSA:
+ if (EVP_PKEY_get0_RSA(evp) == NULL)
+ debug("Missing RSA key");
+ else if ((rsa = RSAPublicKey_dup(
+ EVP_PKEY_get0_RSA(evp))) == NULL)
+ error("RSAPublicKey_dup failed");
+ break;
+ case EVP_PKEY_EC:
+ if (EVP_PKEY_get0_EC_KEY(evp) == NULL)
+ debug("Missing ECDSA key");
+ else if ((ecdsa = EC_KEY_dup(
+ EVP_PKEY_get0_EC_KEY(evp))) == NULL)
+ error("EC_KEY_dup failed");
+ break;
+ default:
+ debug("not a RSA or ECDSA key");
+ break;
+ }
}
X509_free(x509);
EVP_PKEY_free(evp);
@@ -725,6 +1021,18 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
key->rsa = rsa;
key->type = KEY_RSA;
key->flags |= SSHKEY_FLAG_EXT;
+#ifdef ENABLE_PKCS11_ECDSA
+ } else if (ecdsa &&
+ pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], &attribs[1], ecdsa) == 0) {
+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
+ fatal("sshkey_new failed");
+ key->ecdsa = ecdsa;
+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(key->ecdsa);
+ key->type = KEY_ECDSA;
+ key->flags |= SSHKEY_FLAG_EXT;
+#endif /* ENABLE_PKCS11_ECDSA */
+ }
+ if (key) {
if (pkcs11_key_included(keysp, nkeys, key)) {
sshkey_free(key);
} else {
@@ -737,6 +1044,10 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
}
} else if (rsa) {
RSA_free(rsa);
+#ifdef ENABLE_PKCS11_ECDSA
+ } else if (ecdsa) {
+ EC_KEY_free(ecdsa);
+#endif /* ENABLE_PKCS11_ECDSA */
}
for (i = 0; i < nattribs; i++)
free(attribs[i].pValue);
diff -up openssh/ssh-pkcs11-helper.c.pkcs11-ecdsa openssh/ssh-pkcs11-helper.c
--- openssh/ssh-pkcs11-helper.c.pkcs11-ecdsa 2018-10-11 02:56:36.000000000 +0200
+++ openssh/ssh-pkcs11-helper.c 2018-10-12 14:05:55.023656999 +0200
@@ -24,6 +24,17 @@
#include "openbsd-compat/sys-queue.h"
+#include <openssl/rsa.h>
+#ifdef OPENSSL_HAS_ECC
+#include <openssl/ecdsa.h>
+#if ((defined(LIBRESSL_VERSION_NUMBER) && \
+ (LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
+ (defined(ECDSA_F_ECDSA_METHOD_NEW)) || \
+ (OPENSSL_VERSION_NUMBER >= 0x00010100L)
+#define ENABLE_PKCS11_ECDSA 1
+#endif
+#endif
+
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
@@ -77,7 +88,7 @@ del_keys_by_name(char *name)
if (!strcmp(ki->providername, name)) {
TAILQ_REMOVE(&pkcs11_keylist, ki, next);
free(ki->providername);
- sshkey_free(ki->key);
+ pkcs11_del_key(ki->key);
free(ki);
}
}
@@ -172,6 +183,20 @@ process_del(void)
sshbuf_free(msg);
}
+#ifdef ENABLE_PKCS11_ECDSA
+static u_int EC_KEY_order_size(EC_KEY *key)
+{
+ const EC_GROUP *group = EC_KEY_get0_group(key);
+ BIGNUM *order = BN_new();
+ u_int nbytes = 0;
+ if ((group != NULL) && (order != NULL) && EC_GROUP_get_order(group, order, NULL)) {
+ nbytes = BN_num_bytes(order);
+ }
+ BN_clear_free(order);
+ return nbytes;
+}
+#endif /* ENABLE_PKCS11_ECDSA */
+
static void
process_sign(void)
{
@@ -192,14 +217,38 @@ process_sign(void)
else {
if ((found = lookup_key(key)) != NULL) {
#ifdef WITH_OPENSSL
- int ret;
-
- slen = RSA_size(key->rsa);
- signature = xmalloc(slen);
- if ((ret = RSA_private_encrypt(dlen, data, signature,
- found->rsa, RSA_PKCS1_PADDING)) != -1) {
- slen = ret;
- ok = 0;
+ if(found->type == KEY_RSA) {
+ int ret;
+ slen = RSA_size(key->rsa);
+ signature = xmalloc(slen);
+ if ((ret = RSA_private_encrypt(dlen, data, signature,
+ found->rsa, RSA_PKCS1_PADDING)) != -1) {
+ slen = ret;
+ ok = 0;
+ }
+#ifdef ENABLE_PKCS11_ECDSA
+ } else if(found->type == KEY_ECDSA) {
+ ECDSA_SIG *sig;
+ const BIGNUM *r = NULL, *s = NULL;
+ if ((sig = ECDSA_do_sign(data, dlen, found->ecdsa)) != NULL) {
+ /* PKCS11 2.3.1 recommends both r and s to have the order size for
+ backward compatiblity */
+ ECDSA_SIG_get0(sig, &r, &s);
+ u_int o_len = EC_KEY_order_size(found->ecdsa);
+ u_int r_len = BN_num_bytes(r);
+ u_int s_len = BN_num_bytes(s);
+ if (o_len > 0 && r_len <= o_len && s_len <= o_len) {
+ signature = xcalloc(2, o_len);
+ BN_bn2bin(r, signature + o_len - r_len);
+ BN_bn2bin(s, signature + (2 * o_len) - s_len);
+ slen = 2 * o_len;
+ ok = 0;
+ }
+ ECDSA_SIG_free(sig);
+ }
+#endif /* ENABLE_PKCS11_ECDSA */
+ } else {
+ /* Unsupported type */
}
#endif /* WITH_OPENSSL */
}
diff -up openssh/ssh-pkcs11.h.pkcs11-ecdsa openssh/ssh-pkcs11.h
--- openssh/ssh-pkcs11.h.pkcs11-ecdsa 2018-10-12 14:05:55.021656982 +0200
+++ openssh/ssh-pkcs11.h 2018-10-12 14:05:55.023656999 +0200
@@ -20,6 +20,7 @@
int pkcs11_init(int);
void pkcs11_terminate(void);
int pkcs11_add_provider(char *, char *, struct sshkey ***);
+int pkcs11_del_key(struct sshkey *);
int pkcs11_add_provider_by_uri(struct pkcs11_uri *, char *, struct sshkey ***);
int pkcs11_del_provider(char *);
int pkcs11_uri_write(const struct sshkey *, FILE *);

File diff suppressed because it is too large Load Diff

View File

@ -154,20 +154,12 @@ diff -up openssh-7.9p1/dh.h.fips openssh-7.9p1/dh.h
u_int dh_estimate(int);
@@ -51,6 +52,7 @@ u_int dh_estimate(int);
* Miniumum increased in light of DH precomputation attacks.
*/
#define DH_GRP_MIN 2048
+#define DH_GRP_MIN_FIPS 2048
#define DH_GRP_MAX 8192
/*
diff -up openssh-7.9p1/entropy.c.fips openssh-7.9p1/entropy.c
--- openssh-7.9p1/entropy.c.fips 2018-10-17 02:01:20.000000000 +0200
+++ openssh-7.9p1/entropy.c 2019-03-11 17:06:37.621878041 +0100
@@ -223,6 +223,11 @@ seed_rng(void)
fatal("OpenSSL version mismatch. Built against %lx, you "
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
"have %lx", (u_long)OPENSSL_VERSION_NUMBER,
OpenSSL_version_num());
+ /* clean the PRNG status when exiting the program */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
@ -175,13 +167,13 @@ diff -up openssh-7.9p1/entropy.c.fips openssh-7.9p1/entropy.c
+#endif
+
#ifndef OPENSSL_PRNG_ONLY
if (RAND_status() == 1) {
if (RAND_status() == 1)
debug3("RNG is ready, skipping seeding");
diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c
--- openssh-7.9p1/kex.c.fips 2019-03-11 17:06:37.614877975 +0100
+++ openssh-7.9p1/kex.c 2019-03-11 17:06:37.621878041 +0100
@@ -122,6 +123,26 @@ static const struct kexalg kexalgs[] = {
{ NULL, -1, -1, -1},
{ NULL, -1, -1, -1 },
};
+static const struct kexalg kexalgs_fips[] = {
@ -201,22 +193,22 @@ diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c
+ SSH_DIGEST_SHA512 },
+# endif
+#endif
+ { NULL, -1, -1, -1},
+ { NULL, -1, -1, -1 },
+};
+
static char *
kex_alg_list_internal(char sep, const struct kexalg *algs)
{
@@ -129,7 +150,7 @@ kex_alg_list(char sep)
char *
kex_alg_list(char sep)
{
@@ -129,7 +150,7 @@ kex_alg_list(char sep)
size_t nlen, rlen = 0;
const struct kexalg *k;
- return kex_alg_list_internal(sep, kexalgs);
+ return kex_alg_list_internal(sep, (FIPS_mode() ? kexalgs_fips : kexalgs));
}
- for (k = kexalgs; k->name != NULL; k++) {
+ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) {
if (ret != NULL)
ret[rlen++] = sep;
nlen = strlen(k->name);
@@ -149,7 +170,7 @@ kex_alg_by_name(const char *name)
char *
@@ -149,11 +170,11 @@ kex_alg_by_name(const char *name)
{
const struct kexalg *k;
@ -224,7 +216,13 @@ diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c
+ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) {
if (strcmp(k->name, name) == 0)
return k;
#ifdef GSSAPI
}
- for (k = gss_kexalgs; k->name != NULL; k++) {
+ for (k = (FIPS_mode() ? NULL : gss_kexalgs); k->name != NULL; k++) {
if (strncmp(k->name, name, strlen(k->name)) == 0)
return k;
}
return NULL;
@@ -175,7 +196,10 @@ kex_names_valid(const char *names)
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
@ -248,15 +246,6 @@ diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c
#include <sys/types.h>
#include <openssl/dh.h>
@@ -65,7 +66,7 @@ kexgex_client(struct ssh *ssh)
nbits = dh_estimate(kex->dh_need * 8);
- kex->min = DH_GRP_MIN;
+ kex->min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN;
kex->max = DH_GRP_MAX;
kex->nbits = nbits;
if (datafellows & SSH_BUG_DHGEX_LARGE)
@@ -118,6 +119,10 @@ input_kex_dh_gex_group(int type, u_int32
r = SSH_ERR_ALLOC_FAIL;
goto out;
@ -268,21 +257,6 @@ diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c
p = g = NULL; /* belong to kex->dh now */
/* generate and send 'e', client DH public key */
diff -up openssh-7.9p1/kexgexs.c.fips openssh-7.9p1/kexgexs.c
--- openssh-7.9p1/kexgexs.c.fips 2018-10-17 02:01:20.000000000 +0200
+++ openssh-7.9p1/kexgexs.c 2019-03-11 17:06:37.621878041 +0100
@@ -85,9 +85,9 @@ input_kex_dh_gex_request(int type, u_int
kex->nbits = nbits;
kex->min = min;
kex->max = max;
- min = MAXIMUM(DH_GRP_MIN, min);
+ min = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min);
max = MINIMUM(DH_GRP_MAX, max);
- nbits = MAXIMUM(DH_GRP_MIN, nbits);
+ nbits = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits);
nbits = MINIMUM(DH_GRP_MAX, nbits);
if (kex->max < kex->min || kex->nbits < kex->min ||
diff -up openssh-7.9p1/mac.c.fips openssh-7.9p1/mac.c
--- openssh-7.9p1/mac.c.fips 2019-03-11 17:06:37.614877975 +0100
+++ openssh-7.9p1/mac.c 2019-03-11 17:06:37.621878041 +0100
@ -294,7 +268,7 @@ diff -up openssh-7.9p1/mac.c.fips openssh-7.9p1/mac.c
+
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -54,7 +56,7 @@ struct macalg {
int etm; /* Encrypt-then-MAC */
};
@ -376,7 +350,7 @@ diff -up openssh-7.9p1/Makefile.in.fips openssh-7.9p1/Makefile.in
- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o compat.o
- $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
@ -464,15 +438,15 @@ diff -up openssh-7.9p1/readconf.c.fips openssh-7.9p1/readconf.c
+ all)) != 0) \
fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
} while (0)
- ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
- ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
- ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
- ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, all_cipher);
- ASSEMBLE(macs, KEX_CLIENT_MAC, all_mac);
- ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, all_kex);
- ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
- ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
- ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
+ ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
+ ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac);
+ ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
+ ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
+ ASSEMBLE(macs, KEX_CLIENT_MAC, KEX_FIPS_MAC, all_mac);
+ ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
+ ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
+ ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
+ ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig);
@ -553,14 +527,6 @@ diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c
#ifndef HAVE_SETPROCTITLE
/* Prepare for later setproctitle emulation */
@@ -1047,7 +1059,6 @@ main(int ac, char **av)
host_arg = xstrdup(host);
#ifdef WITH_OPENSSL
- OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
#endif
@@ -1283,6 +1294,10 @@ main(int ac, char **av)
seed_rng();
@ -569,9 +535,9 @@ diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c
+ logit("FIPS mode initialized");
+ }
+
if (options.user == NULL)
options.user = xstrdup(pw->pw_name);
/*
* Discard other fds that are hanging around. These can cause problem
* with backgrounded ssh processes started by ControlPersist.
diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c
--- openssh-7.9p1/sshconnect2.c.fips 2019-03-11 17:06:37.580877655 +0100
+++ openssh-7.9p1/sshconnect2.c 2019-03-11 17:06:37.623878060 +0100
@ -584,7 +550,7 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
@@ -235,7 +237,8 @@ order_hostkeyalgs(char *host, struct soc
@@ -117,7 +117,8 @@ order_hostkeyalgs(char *host, struct soc
for (i = 0; i < options.num_system_hostfiles; i++)
load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
@ -594,53 +560,7 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c
maxlen = strlen(avail) + 1;
first = xmalloc(maxlen);
last = xmalloc(maxlen);
@@ -290,23 +293,28 @@ ssh_kex2(char *host, struct sockaddr *ho
#ifdef GSSAPI
if (options.gss_keyex) {
- /* Add the GSSAPI mechanisms currently supported on this
- * client to the key exchange algorithm proposal */
- orig = options.kex_algorithms;
-
- if (options.gss_server_identity)
- gss_host = options.gss_server_identity;
- else if (options.gss_trust_dns)
- gss_host = (char *)get_canonical_hostname(active_state, 1);
- else
- gss_host = host;
-
- gss = ssh_gssapi_client_mechanisms(gss_host,
- options.gss_client_identity, options.gss_kex_algorithms);
- if (gss) {
- debug("Offering GSSAPI proposal: %s", gss);
- xasprintf(&options.kex_algorithms,
- "%s,%s", gss, 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 = options.kex_algorithms;
+
+ if (options.gss_server_identity)
+ gss_host = options.gss_server_identity;
+ else if (options.gss_trust_dns)
+ gss_host = (char *)get_canonical_hostname(active_state, 1);
+ else
+ gss_host = host;
+
+ gss = ssh_gssapi_client_mechanisms(gss_host,
+ options.gss_client_identity, options.gss_kex_algorithms);
+ if (gss) {
+ debug("Offering GSSAPI proposal: %s", gss);
+ xasprintf(&options.kex_algorithms,
+ "%s,%s", gss, orig);
+ }
}
}
#endif
@@ -326,14 +334,16 @@ ssh_kex2(char *host, struct sockaddr *ho
@@ -185,14 +185,16 @@ ssh_kex2(char *host, struct sockaddr *ho
if (options.hostkeyalgorithms != NULL) {
all_key = sshkey_alg_list(0, 0, 1, ',');
if (kex_assemble_names(&options.hostkeyalgorithms,
@ -659,6 +579,64 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c
/* Prefer algorithms that we already have keys for */
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
compat_pkalg_proposal(
@@ -201,29 +201,34 @@ ssh_kex2(char *host, struct sockaddr *ho
#if defined(GSSAPI) && defined(WITH_OPENSSL)
if (options.gss_keyex) {
- /* 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) {
- debug("Offering GSSAPI proposal: %s", gss);
- xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
- "%s,%s", gss, orig);
-
- /* If we've got GSSAPI algorithms, then we also support the
- * 'null' hostkey, as a last resort */
- orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
- xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
- "%s,null", orig);
+ if (FIPS_mode()) {
+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
+ options.gss_keyex = 0;
+ } 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) {
+ debug("Offering GSSAPI proposal: %s", gss);
+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
+ "%s,%s", gss, orig);
+
+ /* If we've got GSSAPI algorithms, then we also support the
+ * 'null' hostkey, as a last resort */
+ orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
+ xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
+ "%s,null", orig);
+ }
}
}
#endif
diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c
--- openssh-7.9p1/sshd.c.fips 2019-03-11 17:06:37.617878003 +0100
+++ openssh-7.9p1/sshd.c 2019-03-11 17:06:37.624878069 +0100
@ -698,15 +676,6 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
saved_argc = ac;
rexec_argc = ac;
@@ -1722,7 +1737,7 @@ main(int ac, char **av)
else
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
-#ifdef WITH_OPENSSL
+#if 0 /* FIPS */
OpenSSL_add_all_algorithms();
#endif
@@ -2036,6 +2051,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);

View File

@ -411,7 +411,7 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c
}
krb5_free_principal(krb_context, princ);
@@ -331,29 +332,19 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
client->creds, ccache))) {
logit("gss_krb5_copy_ccache() failed");
krb5_cc_destroy(krb_context, ccache);
@ -425,6 +425,7 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c
- client->store.envvar = "KRB5CCNAME";
-#ifdef USE_CCAPI
- xasprintf(&client->store.envval, "API:%s", new_ccname);
- client->store.filename = NULL;
-#else
- if (new_ccname[0] == ':')
- new_ccname++;
@ -438,6 +439,8 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c
+ if (set_env) {
+ client->store.envvar = "KRB5CCNAME";
}
if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0))
client->store.filename = xstrdup(new_ccname);
-#endif
#ifdef USE_PAM
@ -477,15 +480,16 @@ index 6cae720e..16e55cbc 100644
}
/* This allows GSSAPI methods to do things to the childs environment based
@@ -496,8 +498,7 @@ ssh_gssapi_rekey_creds() {
@@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() {
char *envstr;
#endif
- if (gssapi_client.store.envval == NULL &&
- 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
@ -590,14 +594,6 @@ diff --git a/ssh-gss.h b/ssh-gss.h
index 6593e422..245178af 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -62,7 +62,6 @@
#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-"
typedef struct {
- char *filename;
char *envvar;
char *envval;
struct passwd *owner;
@@ -83,7 +82,7 @@ typedef struct ssh_gssapi_mech_struct {
int (*dochild) (ssh_gssapi_client *);
int (*userok) (ssh_gssapi_client *, char *);

View File

@ -9,9 +9,9 @@ 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.");
+
seed_rng();
/* 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

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +0,0 @@
diff -up openssh/misc.c.config openssh/misc.c
--- openssh/misc.c.config 2018-08-22 13:58:54.922807799 +0200
+++ openssh/misc.c 2018-08-22 13:58:55.000808428 +0200
@@ -485,7 +485,7 @@ put_host_port(const char *host, u_short
* The delimiter char, if present, is stored in delim.
* If this is the last field, *cp is set to NULL.
*/
-static char *
+char *
hpdelim2(char **cp, char *delim)
{
char *s, *old;
diff -up openssh/misc.h.config openssh/misc.h
--- openssh/misc.h.config 2018-08-20 07:57:29.000000000 +0200
+++ openssh/misc.h 2018-08-22 13:58:55.001808436 +0200
@@ -54,6 +54,7 @@ int set_rdomain(int, const char *);
int a2port(const char *);
int a2tun(const char *, int *);
char *put_host_port(const char *, u_short);
+char *hpdelim2(char **, char *);
char *hpdelim(char **);
char *cleanhostname(char *);
char *colon(char *);
diff -up openssh/servconf.c.config openssh/servconf.c
--- openssh/servconf.c.config 2018-08-22 13:58:54.989808340 +0200
+++ openssh/servconf.c 2018-08-22 14:18:49.235443937 +0200
@@ -886,7 +886,7 @@ process_permitopen_list(struct ssh *ssh,
{
u_int i;
int port;
- char *host, *arg, *oarg;
+ char *host, *arg, *oarg, ch;
int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
const char *what = lookup_opcode_name(opcode);
@@ -904,8 +904,8 @@ process_permitopen_list(struct ssh *ssh,
/* Otherwise treat it as a list of permitted host:port */
for (i = 0; i < num_opens; i++) {
oarg = arg = xstrdup(opens[i]);
- host = hpdelim(&arg);
- if (host == NULL)
+ host = hpdelim2(&arg, &ch);
+ if (host == NULL || ch == '/')
fatal("%s: missing host in %s", __func__, what);
host = cleanhostname(host);
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
@@ -1323,8 +1323,10 @@ process_server_config_line(ServerOptions
port = 0;
p = arg;
} else {
- p = hpdelim(&arg);
- if (p == NULL)
+ char ch;
+ arg2 = NULL;
+ p = hpdelim2(&arg, &ch);
+ if (p == NULL || ch == '/')
fatal("%s line %d: bad address:port usage",
filename, linenum);
p = cleanhostname(p);
@@ -1965,9 +1967,10 @@ process_server_config_line(ServerOptions
*/
xasprintf(&arg2, "*:%s", arg);
} else {
+ char ch;
arg2 = xstrdup(arg);
- p = hpdelim(&arg);
- if (p == NULL) {
+ p = hpdelim2(&arg, &ch);
+ if (p == NULL || ch == '/') {
fatal("%s line %d: missing host in %s",
filename, linenum,
lookup_opcode_name(opcode));

View File

@ -4,11 +4,11 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c
@@ -256,6 +256,9 @@ input_userauth_request(int type, u_int32
Authctxt *authctxt = ssh->authctxt;
Authmethod *m = NULL;
char *user, *service, *method, *style = NULL;
char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
+#ifdef WITH_SELINUX
+ char *role = NULL;
+#endif
int authenticated = 0;
int r, authenticated = 0;
double tstart = monotime_double();
@@ -268,6 +271,11 @@ input_userauth_request(int type, u_int32
@ -37,9 +37,9 @@ diff -up openssh/auth2.c.role-mls openssh/auth2.c
+ mm_inform_authrole(role);
+#endif
+ }
userauth_banner();
userauth_banner(ssh);
if (auth2_setup_methods_lists(authctxt) != 0)
packet_disconnect("no authentication methods enabled");
ssh_packet_disconnect(ssh,
diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
--- openssh/auth2-gss.c.role-mls 2018-08-20 07:57:29.000000000 +0200
+++ openssh/auth2-gss.c 2018-08-22 11:15:42.459799171 +0200
@ -57,7 +57,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
mic.length = len;
- ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
+#ifdef WITH_SELINUX
+ if (authctxt->role && (strlen(authctxt->role) > 0))
+ if (authctxt->role && authctxt->role[0] != 0)
+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role);
+ else
+#endif
@ -197,15 +197,15 @@ 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 *)
int mm_answer_pwnamallow(int, struct sshbuf *);
int mm_answer_auth2_read_banner(int, struct sshbuf *);
int mm_answer_authserv(int, struct sshbuf *);
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 *);
+#ifdef WITH_SELINUX
+int mm_answer_authrole(int, struct sshbuf *);
+int mm_answer_authrole(struct ssh *, int, struct sshbuf *);
+#endif
int mm_answer_authpassword(int, struct sshbuf *);
int mm_answer_bsdauthquery(int, struct sshbuf *);
int mm_answer_bsdauthrespond(int, struct sshbuf *);
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[]
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
@ -227,12 +227,12 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
#ifdef USE_PAM
@@ -842,6 +851,26 @@ mm_answer_authserv(int sock, struct sshb
return (0);
return found;
}
+#ifdef WITH_SELINUX
+int
+mm_answer_authrole(int sock, struct sshbuf *m)
+mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m)
+{
+ int r;
+ monitor_permit_authentications(1);
@ -251,7 +251,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
+#endif
+
int
mm_answer_authpassword(int sock, struct sshbuf *m)
mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
{
@@ -1218,7 +1247,7 @@ monitor_valid_userblob(u_char *data, u_i
{
@ -338,13 +338,13 @@ 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 sshkey *, u_char **, size_t *, const u_char *, size_t,
const char *, u_int compat);
int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *,
const u_char *, size_t, const char *, u_int compat);
void mm_inform_authserv(char *, char *);
+#ifdef WITH_SELINUX
+void mm_inform_authrole(char *);
+#endif
struct passwd *mm_getpwnamallow(const char *);
struct passwd *mm_getpwnamallow(struct ssh *, const char *);
char *mm_auth2_read_banner(void);
int mm_auth_password(struct ssh *, char *);
diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in

View File

@ -1,28 +0,0 @@
From 6010c0303a422a9c5fa8860c061bf7105eb7f8b2 Mon Sep 17 00:00:00 2001
From: "djm@openbsd.org" <djm@openbsd.org>
Date: Fri, 16 Nov 2018 03:03:10 +0000
Subject: [PATCH] upstream: disallow empty incoming filename or ones that refer
to the
current directory; based on report/patch from Harry Sintonen
OpenBSD-Commit-ID: f27651b30eaee2df49540ab68d030865c04f6de9
---
scp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/scp.c b/scp.c
index 60682c687..4f3fdcd3d 100644
--- a/scp.c
+++ b/scp.c
@@ -1106,7 +1106,8 @@ sink(int argc, char **argv)
SCREWUP("size out of range");
size = (off_t)ull;
- if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) {
+ if (*cp == '\0' || strchr(cp, '/') != NULL ||
+ strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) {
run_err("error: unexpected filename: %s", cp);
exit(1);
}

View File

@ -1,186 +0,0 @@
From 631165f6c43d230df9174423aeb19fcf09a67ef4 Mon Sep 17 00:00:00 2001
From: Damien Miller <djm@mindrot.org>
Date: Mon, 22 Oct 2018 11:22:50 +1100
Subject: [PATCH 1/7] fix compile for openssl 1.0.x w/ --with-ssl-engine
bz#2921, patch from cotequeiroz
---
openbsd-compat/openssl-compat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c
index 8b4a3627..590b66d1 100644
--- a/openbsd-compat/openssl-compat.c
+++ b/openbsd-compat/openssl-compat.c
@@ -76,7 +76,7 @@ ssh_OpenSSL_add_all_algorithms(void)
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
-#if OPENSSL_VERSION_NUMBER < 0x10001000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
OPENSSL_config(NULL);
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS |
--
2.20.1
From 55d7cdda4dc4e8284ccd276f73440be400250a1e Mon Sep 17 00:00:00 2001
From: Darren Tucker <dtucker@dtucker.net>
Date: Mon, 22 Oct 2018 20:05:18 +1100
Subject: [PATCH 2/7] Include openssl compatibility.
Patch from rosenp at gmail.com via openssh-unix-dev.
---
ssh-keysign.c | 1 +
ssh_api.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/ssh-keysign.c b/ssh-keysign.c
index 744ecb4f..bcd1508c 100644
--- a/ssh-keysign.c
+++ b/ssh-keysign.c
@@ -40,6 +40,7 @@
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
+#include "openbsd-compat/openssl-compat.h"
#endif
#include "xmalloc.h"
diff --git a/ssh_api.c b/ssh_api.c
index c84b4e71..e727c0d6 100644
--- a/ssh_api.c
+++ b/ssh_api.c
@@ -29,6 +29,8 @@
#include "ssherr.h"
#include "sshbuf.h"
+#include "openbsd-compat/openssl-compat.h"
+
#include <string.h>
int _ssh_exchange_banner(struct ssh *);
--
2.20.1
From 22092e375125dc602227afb8b2d3b285203e77c1 Mon Sep 17 00:00:00 2001
From: Darren Tucker <dtucker@dtucker.net>
Date: Mon, 5 Nov 2018 17:31:24 +1100
Subject: [PATCH 3/7] Fix pasto for HAVE_EVP_CIPHER_CTX_SET_IV.
Prevents unnecessary redefinition. Patch from mforney at mforney.org.
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 7379ab35..1041bf25 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2850,7 +2850,7 @@ if test "x$openssl" = "xyes" ; then
[AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1],
[Define if libcrypto has EVP_CIPHER_CTX_get_iv])])
AC_SEARCH_LIBS([EVP_CIPHER_CTX_set_iv], [crypto],
- [AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1],
+ [AC_DEFINE([HAVE_EVP_CIPHER_CTX_SET_IV], [1],
[Define if libcrypto has EVP_CIPHER_CTX_set_iv])])
AC_SEARCH_LIBS([RSA_get0_crt_params], [crypto],
--
2.20.1
From 904d478f07deabb401f741f88c67ab2e07f742bd Mon Sep 17 00:00:00 2001
From: Darren Tucker <dtucker@dtucker.net>
Date: Sun, 11 Nov 2018 15:54:54 +1100
Subject: [PATCH 4/7] Remove hardcoded service name in cygwin setup.
bz#2922, patch from Christian.Lupien at USherbrooke.ca, sanity check
by vinschen at redhat.com.
---
contrib/cygwin/ssh-host-config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/cygwin/ssh-host-config b/contrib/cygwin/ssh-host-config
index 261020af..e9f038db 100644
--- a/contrib/cygwin/ssh-host-config
+++ b/contrib/cygwin/ssh-host-config
@@ -307,7 +307,7 @@ check_service_files_ownership() {
if [ -z "${run_service_as}" ]
then
- accnt_name=$(/usr/bin/cygrunsrv -VQ sshd |
+ accnt_name=$(/usr/bin/cygrunsrv -VQ "${service_name}" |
/usr/bin/sed -ne 's/^Account *: *//gp')
if [ "${accnt_name}" = "LocalSystem" ]
then
--
2.20.1
From 4608a60cb4893a25490fd88ffdaaae6256381ae3 Mon Sep 17 00:00:00 2001
From: Damien Miller <djm@mindrot.org>
Date: Fri, 23 Nov 2018 10:45:20 +1100
Subject: [PATCH 6/7] fix configure test for OpenSSL version
square brackets in case statements may be eaten by autoconf.
Report and fix from Filipp Gunbin; tweaked by naddy@
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 1041bf25..9920ede5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2616,7 +2616,7 @@ if test "x$openssl" = "xyes" ; then
AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
;;
100*) ;; # 1.0.x
- 101000[0123456]*)
+ 101000[[0123456]]*)
# https://github.com/openssl/openssl/pull/4613
AC_MSG_ERROR([OpenSSL 1.1.x versions prior to 1.1.0g have a bug that breaks their use with OpenSSH (have "$ssl_library_ver")])
;;
--
2.20.1
From f429c1b2ef631f2855e51a790cf71761d752bbca Mon Sep 17 00:00:00 2001
From: "djm@openbsd.org" <djm@openbsd.org>
Date: Thu, 27 Dec 2018 23:02:11 +0000
Subject: [PATCH 7/7] upstream: Request RSA-SHA2 signatures for
rsa-sha2-{256|512}-cert-v01@openssh.com cert algorithms; ok markus@
OpenBSD-Commit-ID: afc6f7ca216ccd821656d1c911d2a3deed685033
---
authfd.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/authfd.c b/authfd.c
index ecdd869a..62cbf8c1 100644
--- a/authfd.c
+++ b/authfd.c
@@ -327,10 +327,12 @@ ssh_free_identitylist(struct ssh_identitylist *idl)
static u_int
agent_encode_alg(const struct sshkey *key, const char *alg)
{
- if (alg != NULL && key->type == KEY_RSA) {
- if (strcmp(alg, "rsa-sha2-256") == 0)
+ if (alg != NULL && sshkey_type_plain(key->type) == KEY_RSA) {
+ if (strcmp(alg, "rsa-sha2-256") == 0 ||
+ strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0)
return SSH_AGENT_RSA_SHA2_256;
- else if (strcmp(alg, "rsa-sha2-512") == 0)
+ if (strcmp(alg, "rsa-sha2-512") == 0 ||
+ strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0)
return SSH_AGENT_RSA_SHA2_512;
}
return 0;
--
2.20.1

View File

@ -1,62 +0,0 @@
diff --git a/monitor.c b/monitor.c
index 12b33e7..a1c3c97 100644
--- a/monitor.c
+++ b/monitor.c
@@ -875,6 +875,34 @@ mm_answer_bsdauthrespond(int sock, struct sshbuf *m)
}
#endif
+/*
+ * Check that the key type appears in the supplied pattern list, ignoring
+ * mismastches in the signature algorithm. (Signature algorithm checks are
+ * performed in the unprivileged authentication code).
+ * Returns 1 on success, 0 otherwise.
+ */
+static int
+key_base_type_match(const struct sshkey *key, const char *list)
+{
+ char *s, *l, *ol = xstrdup(list);
+ int found = 0;
+
+ l = ol;
+ for ((s = strsep(&l, ",")); s && *s != '\0'; (s = strsep(&l, ","))) {
+ if (sshkey_type_from_name(s) == key->type) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ debug("key type %s does not appear in list %s",
+ sshkey_ssh_name(key), list);
+ }
+
+ free(ol);
+ return found;
+}
+
int
mm_answer_keyallowed(int sock, struct sshbuf *m)
{
@@ -909,8 +937,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m)
break;
if (auth2_key_already_used(authctxt, key))
break;
- if (match_pattern_list(sshkey_ssh_name(key),
- options.pubkey_key_types, 0) != 1)
+ if (!key_base_type_match(key,
+ options.pubkey_key_types))
break;
allowed = user_key_allowed(ssh, authctxt->pw, key,
pubkey_auth_attempt, &opts);
@@ -921,8 +949,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m)
break;
if (auth2_key_already_used(authctxt, key))
break;
- if (match_pattern_list(sshkey_ssh_name(key),
- options.hostbased_key_types, 0) != 1)
+ if (!key_base_type_match(key,
+ options.hostbased_key_types))
break;
allowed = hostbased_key_allowed(authctxt->pw,
cuser, chost, key);

View File

@ -1,150 +0,0 @@
From bc74944ce7a2eabd228d47051f277ce108914c96 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 16 Oct 2018 16:44:40 +0200
Subject: [PATCH] Unbreak authentication using gssapi-keyex (#1625366)
---
auth2-gss.c | 6 +++---
gss-serv.c | 4 +++-
monitor.c | 13 ++++++++++---
monitor_wrap.c | 4 +++-
monitor_wrap.h | 2 +-
ssh-gss.h | 2 +-
6 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/auth2-gss.c b/auth2-gss.c
index 3f2ad21d..a61ac089 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -84,7 +84,7 @@ userauth_gsskeyex(Authctxt *authctxt)
if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context,
&gssbuf, &mic))))
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
- authctxt->pw));
+ authctxt->pw, 1));
sshbuf_free(b);
free(mic.value);
@@ -299,7 +299,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
fatal("%s: %s", __func__, ssh_err(r));
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
- authctxt->pw));
+ authctxt->pw, 1));
if ((!use_privsep || mm_is_monitor()) &&
(displayname = ssh_gssapi_displayname()) != NULL)
@@ -347,7 +347,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
authenticated =
- PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw));
+ PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw, 0));
else
logit("GSSAPI MIC check failed");
diff --git a/gss-serv.c b/gss-serv.c
index 786ac95c..87de2baa 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -493,10 +493,12 @@ verify_authentication_indicators(Gssctxt *gssctxt)
/* Privileged */
int
-ssh_gssapi_userok(char *user, struct passwd *pw)
+ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
{
OM_uint32 lmin;
+ (void) kex; /* used in privilege separation */
+
if (gssapi_client.exportedname.length == 0 ||
gssapi_client.exportedname.value == NULL) {
debug("No suitable client data");
diff --git a/monitor.c b/monitor.c
index 9bbe8cc4..7b1903af 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1877,14 +1877,17 @@ mm_answer_gss_checkmic(int sock, struct sshbuf *m)
int
mm_answer_gss_userok(int sock, struct sshbuf *m)
{
- int r, authenticated;
+ int r, authenticated, kex;
const char *displayname;
if (!options.gss_authentication && !options.gss_keyex)
fatal("%s: GSSAPI authentication not enabled", __func__);
+ if ((r = sshbuf_get_u32(m, &kex)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
+
authenticated = authctxt->valid &&
- ssh_gssapi_userok(authctxt->user, authctxt->pw);
+ ssh_gssapi_userok(authctxt->user, authctxt->pw, kex);
sshbuf_reset(m);
if ((r = sshbuf_put_u32(m, authenticated)) != 0)
@@ -1893,7 +1896,11 @@ mm_answer_gss_userok(int sock, struct sshbuf *m)
debug3("%s: sending result %d", __func__, authenticated);
mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);
- auth_method = "gssapi-with-mic";
+ if (kex) {
+ auth_method = "gssapi-keyex";
+ } else {
+ auth_method = "gssapi-with-mic";
+ }
if ((displayname = ssh_gssapi_displayname()) != NULL)
auth2_record_info(authctxt, "%s", displayname);
diff --git a/monitor_wrap.c b/monitor_wrap.c
index fb52a530..508d926d 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -984,13 +984,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
}
int
-mm_ssh_gssapi_userok(char *user, struct passwd *pw)
+mm_ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
{
struct sshbuf *m;
int r, authenticated = 0;
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
+ if ((r = sshbuf_put_u32(m, kex)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m);
mm_request_receive_expect(pmonitor->m_recvfd,
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 494760dd..5eba5ecc 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -60,7 +60,7 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
-int mm_ssh_gssapi_userok(char *user, struct passwd *);
+int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex);
OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *);
diff --git a/ssh-gss.h b/ssh-gss.h
index 39b6ce69..98262837 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -162,7 +162,7 @@ gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *,
const char *);
OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
-int ssh_gssapi_userok(char *name, struct passwd *);
+int ssh_gssapi_userok(char *name, struct passwd *, int kex);
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);
--
2.17.2

View File

@ -1,11 +0,0 @@
diff --git a/session.c b/session.c
--- a/session.c
+++ b/session.c
@@ -1859,6 +1859,7 @@ do_child(Session *s, const char *command)
if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) {
printf("This service allows sftp connections only.\n");
+ logit("The session allows sftp connections only");
fflush(NULL);
exit(1);
} else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {

View File

@ -1,306 +0,0 @@
commit 9e34e0c59ab04514f9de9934a772283f7f372afe
Author: djm@openbsd.org <djm@openbsd.org>
Date: Fri Nov 23 05:08:07 2018 +0000
upstream: add a ssh_config "Match final" predicate
Matches in same pass as "Match canonical" but doesn't require
hostname canonicalisation be enabled. bz#2906 ok markus
OpenBSD-Commit-ID: fba1dfe9f6e0cabcd0e2b3be13f7a434199beffa
diff --git a/readconf.c b/readconf.c
index 7850f2f5..7331ef5a 100644
--- a/readconf.c
+++ b/readconf.c
@@ -133,10 +133,11 @@
static int read_config_file_depth(const char *filename, struct passwd *pw,
const char *host, const char *original_host, Options *options,
- int flags, int *activep, int depth);
+ int flags, int *activep, int *want_final_pass, int depth);
static int process_config_line_depth(Options *options, struct passwd *pw,
const char *host, const char *original_host, char *line,
- const char *filename, int linenum, int *activep, int flags, int depth);
+ const char *filename, int linenum, int *activep, int flags,
+ int *want_final_pass, int depth);
/* Keyword tokens. */
@@ -539,8 +540,8 @@ execute_in_shell(const char *cmd)
*/
static int
match_cfg_line(Options *options, char **condition, struct passwd *pw,
- const char *host_arg, const char *original_host, int post_canon,
- const char *filename, int linenum)
+ const char *host_arg, const char *original_host, int final_pass,
+ int *want_final_pass, const char *filename, int linenum)
{
char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
const char *ruser;
@@ -554,7 +555,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
*/
port = options->port <= 0 ? default_ssh_port() : options->port;
ruser = options->user == NULL ? pw->pw_name : options->user;
- if (post_canon) {
+ if (final_pass) {
host = xstrdup(options->hostname);
} else if (options->hostname != NULL) {
/* NB. Please keep in sync with ssh.c:main() */
@@ -586,8 +587,16 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
goto out;
}
attributes++;
- if (strcasecmp(attrib, "canonical") == 0) {
- r = !!post_canon; /* force bitmask member to boolean */
+ if (strcasecmp(attrib, "canonical") == 0 ||
+ strcasecmp(attrib, "final") == 0) {
+ /*
+ * If the config requests "Match final" then remember
+ * this so we can perform a second pass later.
+ */
+ if (strcasecmp(attrib, "final") == 0 &&
+ want_final_pass != NULL)
+ *want_final_pass = 1;
+ r = !!final_pass; /* force bitmask member to boolean */
if (r == (negate ? 1 : 0))
this_result = result = 0;
debug3("%.200s line %d: %smatched '%s'",
@@ -824,14 +833,14 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
int linenum, int *activep, int flags)
{
return process_config_line_depth(options, pw, host, original_host,
- line, filename, linenum, activep, flags, 0);
+ line, filename, linenum, activep, flags, NULL, 0);
}
#define WHITESPACE " \t\r\n"
static int
process_config_line_depth(Options *options, struct passwd *pw, const char *host,
const char *original_host, char *line, const char *filename,
- int linenum, int *activep, int flags, int depth)
+ int linenum, int *activep, int flags, int *want_final_pass, int depth)
{
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
char **cpptr, fwdarg[256];
@@ -1339,7 +1348,8 @@ parse_keytypes:
fatal("Host directive not supported as a command-line "
"option");
value = match_cfg_line(options, &s, pw, host, original_host,
- flags & SSHCONF_POSTCANON, filename, linenum);
+ flags & SSHCONF_FINAL, want_final_pass,
+ filename, linenum);
if (value < 0)
fatal("%.200s line %d: Bad Match condition", filename,
linenum);
@@ -1548,7 +1558,7 @@ parse_keytypes:
pw, host, original_host, options,
flags | SSHCONF_CHECKPERM |
(oactive ? 0 : SSHCONF_NEVERMATCH),
- activep, depth + 1);
+ activep, want_final_pass, depth + 1);
if (r != 1 && errno != ENOENT) {
fatal("Can't open user config file "
"%.100s: %.100s", gl.gl_pathv[i],
@@ -1751,19 +1761,20 @@ parse_keytypes:
*/
int
read_config_file(const char *filename, struct passwd *pw, const char *host,
- const char *original_host, Options *options, int flags)
+ const char *original_host, Options *options, int flags,
+ int *want_final_pass)
{
int active = 1;
return read_config_file_depth(filename, pw, host, original_host,
- options, flags, &active, 0);
+ options, flags, &active, want_final_pass, 0);
}
#define READCONF_MAX_DEPTH 16
static int
read_config_file_depth(const char *filename, struct passwd *pw,
const char *host, const char *original_host, Options *options,
- int flags, int *activep, int depth)
+ int flags, int *activep, int *want_final_pass, int depth)
{
FILE *f;
char *line = NULL;
@@ -1798,7 +1809,8 @@ read_config_file_depth(const char *filename, struct passwd *pw,
/* Update line number counter. */
linenum++;
if (process_config_line_depth(options, pw, host, original_host,
- line, filename, linenum, activep, flags, depth) != 0)
+ line, filename, linenum, activep, flags, want_final_pass,
+ depth) != 0)
bad_options++;
}
free(line);
diff --git a/readconf.h b/readconf.h
index fc7e3825..8e36bf32 100644
--- a/readconf.h
+++ b/readconf.h
@@ -185,7 +185,7 @@ typedef struct {
#define SSHCONF_CHECKPERM 1 /* check permissions on config file */
#define SSHCONF_USERCONF 2 /* user provided config file not system */
-#define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */
+#define SSHCONF_FINAL 4 /* Final pass over config, after canon. */
#define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */
#define SSH_UPDATE_HOSTKEYS_NO 0
@@ -203,7 +203,7 @@ void fill_default_options_for_canonicalization(Options *);
int process_config_line(Options *, struct passwd *, const char *,
const char *, char *, const char *, int, int *, int);
int read_config_file(const char *, struct passwd *, const char *,
- const char *, Options *, int);
+ const char *, Options *, int, int *);
int parse_forward(struct Forward *, const char *, int, int);
int parse_jump(const char *, Options *, int);
int parse_ssh_uri(const char *, char **, char **, int *);
diff --git a/ssh-keysign.c b/ssh-keysign.c
index 8f487b8c..7ea5ad0e 100644
--- a/ssh-keysign.c
+++ b/ssh-keysign.c
@@ -208,7 +208,8 @@ main(int argc, char **argv)
/* verify that ssh-keysign is enabled by the admin */
initialize_options(&options);
- (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", &options, 0);
+ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "",
+ &options, 0, NULL);
fill_default_options(&options);
if (options.enable_ssh_keysign != 1)
fatal("ssh-keysign not enabled in %s",
diff --git a/ssh.c b/ssh.c
index 1ac903d1..c6cb7847 100644
--- a/ssh.c
+++ b/ssh.c
@@ -527,7 +527,8 @@ check_load(int r, const char *path, const char *message)
* file if the user specifies a config file on the command line.
*/
static void
-process_config_files(const char *host_name, struct passwd *pw, int post_canon)
+process_config_files(const char *host_name, struct passwd *pw, int final_pass,
+ int *want_final_pass)
{
char buf[PATH_MAX];
int r;
@@ -535,7 +536,8 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon)
if (config != NULL) {
if (strcasecmp(config, "none") != 0 &&
!read_config_file(config, pw, host, host_name, &options,
- SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)))
+ SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0),
+ want_final_pass))
fatal("Can't open user config file %.100s: "
"%.100s", config, strerror(errno));
} else {
@@ -544,12 +546,12 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon)
if (r > 0 && (size_t)r < sizeof(buf))
(void)read_config_file(buf, pw, host, host_name,
&options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |
- (post_canon ? SSHCONF_POSTCANON : 0));
+ (final_pass ? SSHCONF_FINAL : 0), want_final_pass);
/* Read systemwide configuration file after user config. */
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
host, host_name, &options,
- post_canon ? SSHCONF_POSTCANON : 0);
+ final_pass ? SSHCONF_FINAL : 0, want_final_pass);
}
}
@@ -581,7 +583,7 @@ main(int ac, char **av)
{
struct ssh *ssh = NULL;
int i, r, opt, exit_status, use_syslog, direct, timeout_ms;
- int was_addr, config_test = 0, opt_terminated = 0;
+ int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0;
char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile;
char cname[NI_MAXHOST];
struct stat st;
@@ -1089,7 +1091,9 @@ main(int ac, char **av)
);
/* Parse the configuration files */
- process_config_files(host_arg, pw, 0);
+ process_config_files(host_arg, pw, 0, &want_final_pass);
+ if (want_final_pass)
+ debug("configuration requests final Match pass");
/* Hostname canonicalisation needs a few options filled. */
fill_default_options_for_canonicalization(&options);
@@ -1146,12 +1150,17 @@ main(int ac, char **av)
* If canonicalisation is enabled then re-parse the configuration
* files as new stanzas may match.
*/
- if (options.canonicalize_hostname != 0) {
- debug("Re-reading configuration after hostname "
- "canonicalisation");
+ if (options.canonicalize_hostname != 0 && !want_final_pass) {
+ debug("hostname canonicalisation enabled, "
+ "will re-parse configuration");
+ want_final_pass = 1;
+ }
+
+ if (want_final_pass) {
+ debug("re-parsing configuration");
free(options.hostname);
options.hostname = xstrdup(host);
- process_config_files(host_arg, pw, 1);
+ process_config_files(host_arg, pw, 1, NULL);
/*
* Address resolution happens early with canonicalisation
* enabled and the port number may have changed since, so
diff --git a/ssh_config.5 b/ssh_config.5
index 4d5b01d3..58a5fa1c 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -139,6 +139,7 @@ or the single token
which always matches.
The available criteria keywords are:
.Cm canonical ,
+.Cm final ,
.Cm exec ,
.Cm host ,
.Cm originalhost ,
@@ -148,12 +149,15 @@ and
The
.Cm all
criteria must appear alone or immediately after
-.Cm canonical .
+.Cm canonical
+or
+.Cm final .
Other criteria may be combined arbitrarily.
All criteria but
.Cm all
-and
.Cm canonical
+and
+.Cm final
require an argument.
Criteria may be negated by prepending an exclamation mark
.Pq Sq !\& .
@@ -166,6 +170,20 @@ after hostname canonicalization (see the
option.)
This may be useful to specify conditions that work with canonical host
names only.
+.Pp
+The
+.Cm final
+keyword requests that the configuration be re-parsed (regardless of whether
+.Cm CanonicalizeHostname
+is enabled), and matches only during this final pass.
+If
+.Cm CanonicalizeHostname
+is enabled, then
+.Cm canonical
+and
+.Cm final
+match during the same pass.
+.Pp
The
.Cm exec
keyword executes the specified command under the user's shell.

View File

@ -2,8 +2,8 @@ diff -up openssh-7.4p1/session.c.update-pw openssh-7.4p1/session.c
--- openssh-7.4p1/session.c.update-pw 2019-03-04 14:10:57.287054645 +0100
+++ openssh-7.4p1/session.c 2019-03-04 14:12:39.259997218 +0100
@@ -1522,9 +1522,18 @@ do_child(Session *s, const char *command
char **env;
char *argv[ARGV_MAX];
extern char **environ;
char **env, *argv[ARGV_MAX], remote_id[512];
const char *shell, *shell0;
- struct passwd *pw = s->pw;
+ struct passwd *pw = NULL;
@ -18,6 +18,6 @@ diff -up openssh-7.4p1/session.c.update-pw openssh-7.4p1/session.c
+ pw = s->pw;
+ }
+
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
/* remove hostkey from the child's memory */
destroy_sensitive_data();
packet_clear_keys();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -65,10 +65,10 @@
%endif
# Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1
%global openssh_ver 7.9p1
%global openssh_rel 5
%global openssh_ver 8.0p1
%global openssh_rel 1
%global pam_ssh_agent_ver 0.10.3
%global pam_ssh_agent_rel 6
%global pam_ssh_agent_rel 7
Summary: An open source implementation of SSH protocol version 2
Name: openssh
@ -150,8 +150,6 @@ Patch702: openssh-5.1p1-askpass-progress.patch
Patch703: openssh-4.3p2-askpass-grab-info.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX)
Patch707: openssh-7.7p1-redhat.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX)
Patch709: openssh-6.2p1-vendor.patch
# warn users for unsupported UsePAM=no (#757545)
Patch711: openssh-7.8p1-UsePAM-warning.patch
# make aes-ctr ciphers use EVP engines such as AES-NI from OpenSSL
@ -161,29 +159,21 @@ Patch713: openssh-6.6p1-ctr-cavstest.patch
# add SSH KDF CAVS test driver
Patch714: openssh-6.7p1-kdf-cavs.patch
#http://www.sxw.org.uk/computing/patches/openssh.html
#changed cache storage type - #848228
Patch800: openssh-7.8p1-gsskex.patch
# GSSAPI Key Exchange (RFC 4462 + draft-ietf-curdle-gss-keyex-sha2-08)
# from https://github.com/openssh-gsskex/openssh-gsskex/tree/fedora/master
Patch800: openssh-8.0p1-gssapi-keyex.patch
#http://www.mail-archive.com/kerberos@mit.edu/msg17591.html
Patch801: openssh-6.6p1-force_krb.patch
# add new option GSSAPIEnablek5users and disable using ~/.k5users by default (#1169843)
# CVE-2014-9278
Patch802: openssh-6.6p1-GSSAPIEnablek5users.patch
# Documentation about GSSAPI
# from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765655
Patch803: openssh-7.1p1-gssapi-documentation.patch
# Improve ccache handling in openssh (#991186, #1199363, #1566494)
# https://bugzilla.mindrot.org/show_bug.cgi?id=2775
Patch804: openssh-7.7p1-gssapi-new-unique.patch
# Respect k5login_directory option in krk5.conf (#1328243)
Patch805: openssh-7.2p2-k5login_directory.patch
# Support SHA2 in GSS key exchanges from draft-ssorce-gss-keyex-sha2-02
Patch807: openssh-7.5p1-gssapi-kex-with-ec.patch
# Do not break when using AuthenticationMethods with gssapi-keyex auth method (#1625366)
Patch808: openssh-7.9p1-gsskex-method.patch
Patch900: openssh-6.1p1-gssapi-canohost.patch
#https://bugzilla.mindrot.org/show_bug.cgi?id=1780
Patch901: openssh-6.6p1-kuserok.patch
# Use tty allocation for a remote scp (#985650)
@ -194,16 +184,12 @@ Patch916: openssh-6.6.1p1-selinux-contexts.patch
Patch918: openssh-6.6.1p1-log-in-chroot.patch
# scp file into non-existing directory (#1142223)
Patch919: openssh-6.6.1p1-scp-non-existing-directory.patch
# Config parser shouldn't accept ip/port syntax (#1130733)
Patch920: openssh-7.8p1-ip-port-config-parser.patch
# apply upstream patch and make sshd -T more consistent (#1187521)
Patch922: openssh-6.8p1-sshdT-output.patch
# Add sftp option to force mode of created files (#1191055)
Patch926: openssh-6.7p1-sftp-force-permission.patch
# Restore compatible default (#89216)
Patch929: openssh-6.9p1-permit-root-login.patch
# Add GSSAPIKexAlgorithms option for server and client application
Patch932: openssh-7.0p1-gssKexAlgorithms.patch
# make s390 use /dev/ crypto devices -- ignore closefrom
Patch939: openssh-7.2p2-s390-closefrom.patch
# Move MAX_DISPLAYS to a configuration option (#1341302)
@ -215,28 +201,13 @@ Patch949: openssh-7.6p1-cleanup-selinux.patch
# Sandbox adjustments for s390 and audit
Patch950: openssh-7.5p1-sandbox.patch
# PKCS#11 URIs (upstream #2817, 2nd iteration)
Patch951: openssh-7.6p1-pkcs11-uri.patch
# PKCS#11 ECDSA keys (upstream #2474, 8th iteration)
Patch952: openssh-7.6p1-pkcs11-ecdsa.patch
Patch951: openssh-8.0p1-pkcs11-uri.patch
# Unbreak scp between two IPv6 hosts (#1620333)
Patch953: openssh-7.8p1-scp-ipv6.patch
# Allow to disable RSA signatures with SHA-1 in server
# https://bugzilla.mindrot.org/show_bug.cgi?id=2746
Patch954: openssh-7.9p1-disable-sha1.patch
# Backport Match final so the crypto-policies do not break canonicalization (#1630166)
# https://bugzilla.mindrot.org/show_bug.cgi?id=2906
Patch955: openssh-7.9p1-match-final.patch
# Backport more after-release fixes (#1665611)
Patch956: openssh-7.9p1-backports.patch
# Backport patch for CVE-2018-20685 (#1665786)
Patch957: openssh-7.9p1-CVE-2018-20685.patch
# ssh-copy-id is unmaintained: Aggreagete patches
# - do not return 0 if the write fails (full disk)
# - shellcheck reports (upstream #2902)
Patch958: openssh-7.9p1-ssh-copy-id.patch
# log when a client requests an interactive session and only sftp is allowed
# https://bugzilla.mindrot.org/show_bug.cgi?id=2960
Patch959: openssh-7.9p1-log-sftp-only-connections.patch
# Update cached passwd structure after PAM authentication (#1674541)
Patch960: openssh-7.9p1-updated-cached-pw.patch
@ -416,7 +387,6 @@ popd
%patch702 -p1 -b .progress
%patch703 -p1 -b .grab-info
%patch707 -p1 -b .redhat
%patch709 -p1 -b .vendor
%patch711 -p1 -b .log-usepam-no
%patch712 -p1 -b .evp-ctr
%patch713 -p1 -b .ctr-cavs
@ -424,38 +394,26 @@ popd
#
%patch800 -p1 -b .gsskex
%patch801 -p1 -b .force_krb
%patch803 -p1 -b .gss-docs
%patch804 -p1 -b .ccache_name
%patch805 -p1 -b .k5login
#
%patch900 -p1 -b .canohost
%patch901 -p1 -b .kuserok
%patch906 -p1 -b .fromto-remote
%patch916 -p1 -b .contexts
%patch918 -p1 -b .log-in-chroot
%patch919 -p1 -b .scp
%patch920 -p1 -b .config
%patch802 -p1 -b .GSSAPIEnablek5users
%patch922 -p1 -b .sshdt
%patch926 -p1 -b .sftp-force-mode
%patch929 -p1 -b .root-login
%patch932 -p1 -b .gsskexalg
%patch939 -p1 -b .s390-dev
%patch944 -p1 -b .x11max
%patch948 -p1 -b .systemd
%patch807 -p1 -b .gsskex-ec
%patch949 -p1 -b .refactor
%patch950 -p1 -b .sandbox
%patch951 -p1 -b .pkcs11-uri
%patch952 -p1 -b .pkcs11-ecdsa
%patch953 -p1 -b .scp-ipv6
%patch808 -p1 -b .gsskex-method
%patch954 -p1 -b .disable-sha1
%patch955 -p1 -b .match-final
%patch956 -p1 -b .backports
%patch957 -p1 -b .CVE-2018-20685
%patch958 -p1 -b .ssh-copy-id
%patch959 -p1 -b .log-sftp-only
%patch960 -p1 -b .update-pw
%patch200 -p1 -b .audit
@ -512,7 +470,6 @@ fi
--with-default-path=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin \
--with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \
--with-privsep-path=%{_var}/empty/sshd \
--enable-vendor-patchlevel="FC-%{openssh_ver}-%{openssh_rel}" \
--disable-strip \
--without-zlib-version-check \
--with-ssl-engine \
@ -760,6 +717,12 @@ getent passwd sshd >/dev/null || \
%endif
%changelog
* Fri Apr 26 2019 Jakub Jelen <jjelen@redhat.com> - 8.0p1-1 + 0.10.3-7
- New upstream release (#1701072)
- Removed support for VendroPatchLevel configuration option
- Significant rework of GSSAPI Key Exchange
- Significant rework of PKCS#11 URI support
* Mon Mar 11 2019 Jakub Jelen <jjelen@redhat.com> - 7.9p1-5 + 0.10.3.6
- Fix kerberos cleanup procedures with GSSAPI
- Update cached passwd structure after PAM authentication

View File

@ -1,4 +1,4 @@
SHA512 (openssh-7.9p1.tar.gz) = 0412c9c429c9287f0794023951469c8e6ec833cdb55821bfa0300dd90d0879ff60484f620cffd93372641ab69bf0b032c2d700ccc680950892725fb631b7708e
SHA512 (openssh-7.9p1.tar.gz.asc) = 881db1b541813136fabd9adb9f5430c4f0fae372c06c99cb049feb8526a573275fe80c129c89511dd4e65f73f41e29364fefaaf8b7c78835224691c488d5da32
SHA512 (openssh-8.0p1.tar.gz) = e280fa2d56f550efd37c5d2477670326261aa8b94d991f9eb17aad90e0c6c9c939efa90fe87d33260d0f709485cb05c379f0fd1bd44fc0d5190298b6398c9982
SHA512 (openssh-8.0p1.tar.gz.asc) = fe9e7383d9467e869762864f2b719165d9a3f2c5316c07067df1d45fc7819bd2cb8ef758454865595688804a4c160dd3d3aaee4c5f887859555d2c7bb8c4592b
SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d
SHA512 (pam_ssh_agent_auth-0.10.3.tar.bz2) = d75062c4e46b0b011f46aed9704a99049995fea8b5115ff7ee26dad7e93cbcf54a8af7efc6b521109d77dc03c6f5284574d2e1b84c6829cec25610f24fb4bd66