From: djm Date: Sun, 19 Dec 2021 22:14:47 +0000 (+0000) Subject: PubkeyAuthentication=yes|no|unbound|host-bound X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=6d12622932a5f47eb782737a758f045b2a3b101b;p=openbsd PubkeyAuthentication=yes|no|unbound|host-bound Allow control over which pubkey methods are used. Added out of concern that some hardware devices may have difficulty signing the longer pubkey authentication challenges. This provides a way for them to disable the extension. It's also handy for testing. feedback / ok markus@ --- diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index 5324d4fc87a..0365dc67070 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.363 2021/09/16 05:36:03 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.364 2021/12/19 22:14:47 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -876,6 +876,15 @@ static const struct multistate multistate_canonicalizehostname[] = { { "always", SSH_CANONICALISE_ALWAYS }, { NULL, -1 } }; +static const struct multistate multistate_pubkey_auth[] = { + { "true", SSH_PUBKEY_AUTH_ALL }, + { "false", SSH_PUBKEY_AUTH_NO }, + { "yes", SSH_PUBKEY_AUTH_ALL }, + { "no", SSH_PUBKEY_AUTH_NO }, + { "unbound", SSH_PUBKEY_AUTH_UNBOUND }, + { "host-bound", SSH_PUBKEY_AUTH_HBOUND }, + { NULL, -1 } +}; static const struct multistate multistate_compression[] = { #ifdef WITH_ZLIB { "yes", COMP_ZLIB }, @@ -1088,8 +1097,9 @@ parse_time: goto parse_string; case oPubkeyAuthentication: + multistate_ptr = multistate_pubkey_auth; intptr = &options->pubkey_authentication; - goto parse_flag; + goto parse_multistate; case oHostbasedAuthentication: intptr = &options->hostbased_authentication; @@ -2473,7 +2483,7 @@ fill_default_options(Options * options) if (options->fwd_opts.streamlocal_bind_unlink == -1) options->fwd_opts.streamlocal_bind_unlink = 0; if (options->pubkey_authentication == -1) - options->pubkey_authentication = 1; + options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; if (options->gss_deleg_creds == -1) @@ -3116,6 +3126,8 @@ fmt_intarg(OpCodes code, int val) return fmt_multistate_int(val, multistate_canonicalizehostname); case oAddKeysToAgent: return fmt_multistate_int(val, multistate_yesnoaskconfirm); + case oPubkeyAuthentication: + return fmt_multistate_int(val, multistate_pubkey_auth); case oFingerprintHash: return ssh_digest_alg_name(val); default: diff --git a/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h index f24719f982d..ded13c943d3 100644 --- a/usr.bin/ssh/readconf.h +++ b/usr.bin/ssh/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.145 2021/09/15 06:56:01 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.146 2021/12/19 22:14:47 djm Exp $ */ /* * Author: Tatu Ylonen @@ -179,6 +179,11 @@ typedef struct { char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; +#define SSH_PUBKEY_AUTH_NO 0x00 +#define SSH_PUBKEY_AUTH_UNBOUND 0x01 +#define SSH_PUBKEY_AUTH_HBOUND 0x02 +#define SSH_PUBKEY_AUTH_ALL 0x03 + #define SSH_CANONICALISE_NO 0 #define SSH_CANONICALISE_YES 1 #define SSH_CANONICALISE_ALWAYS 2 diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c index 02383a415e9..6a6373fcd16 100644 --- a/usr.bin/ssh/sshconnect2.c +++ b/usr.bin/ssh/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.353 2021/12/19 22:12:54 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.354 2021/12/19 22:14:47 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -1338,16 +1338,20 @@ sign_and_send_pubkey(struct ssh *ssh, Identity *id) int r, fallback_sigtype, sent = 0; char *alg = NULL, *fp = NULL; const char *loc = "", *method = "publickey"; + int hostbound = 0; /* prefer host-bound pubkey signatures if supported by server */ - if ((ssh->kex->flags & KEX_HAS_PUBKEY_HOSTBOUND) != 0) + if ((ssh->kex->flags & KEX_HAS_PUBKEY_HOSTBOUND) != 0 && + (options.pubkey_authentication & SSH_PUBKEY_AUTH_HBOUND) != 0) { + hostbound = 1; method = "publickey-hostbound-v00@openssh.com"; + } if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) return 0; - debug3_f("%s %s", sshkey_type(id->key), fp); + debug3_f("using %s with %s %s", method, sshkey_type(id->key), fp); /* * If the key is an certificate, try to find a matching private key @@ -1433,7 +1437,7 @@ sign_and_send_pubkey(struct ssh *ssh, Identity *id) (r = sshkey_puts(id->key, b)) != 0) { fatal_fr(r, "assemble signed data"); } - if ((ssh->kex->flags & KEX_HAS_PUBKEY_HOSTBOUND) != 0) { + if (hostbound) { if (ssh->kex->initial_hostkey == NULL) { fatal_f("internal error: initial hostkey " "not recorded");