Skip to content

Commit

Permalink
upstream: add a "no-touch-required" option for authorized_keys and
Browse files Browse the repository at this point in the history
a similar extension for certificates. This option disables the default
requirement that security key signatures attest that the user touched their
key to authorize them.

feedback deraadt, ok markus

OpenBSD-Commit-ID: f1fb56151ba68d55d554d0f6d3d4dba0cf1a452e
  • Loading branch information
djmdjm committed Nov 25, 2019
1 parent 0fddf29 commit 2e71263
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 32 deletions.
38 changes: 26 additions & 12 deletions auth-options.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth-options.c,v 1.89 2019/09/13 04:36:43 dtucker Exp $ */
/* $OpenBSD: auth-options.c,v 1.90 2019/11/25 00:54:23 djm Exp $ */
/*
* Copyright (c) 2018 Damien Miller <[email protected]>
*
Expand Down Expand Up @@ -96,7 +96,10 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
name, sshbuf_len(data));
found = 0;
if ((which & OPTIONS_EXTENSIONS) != 0) {
if (strcmp(name, "permit-X11-forwarding") == 0) {
if (strcmp(name, "no-touch-required") == 0) {
opts->no_require_user_presence = 1;
found = 1;
} else if (strcmp(name, "permit-X11-forwarding") == 0) {
opts->permit_x11_forwarding_flag = 1;
found = 1;
} else if (strcmp(name,
Expand Down Expand Up @@ -347,6 +350,8 @@ sshauthopt_parse(const char *opts, const char **errstrp)
ret->permit_agent_forwarding_flag = r == 1;
} else if ((r = opt_flag("x11-forwarding", 1, &opts)) != -1) {
ret->permit_x11_forwarding_flag = r == 1;
} else if ((r = opt_flag("touch-required", 1, &opts)) != -1) {
ret->no_require_user_presence = r != 1; /* NB. flip */
} else if ((r = opt_flag("pty", 1, &opts)) != -1) {
ret->permit_pty_flag = r == 1;
} else if ((r = opt_flag("user-rc", 1, &opts)) != -1) {
Expand Down Expand Up @@ -567,14 +572,15 @@ sshauthopt_merge(const struct sshauthopt *primary,
goto alloc_fail;
}

/* Flags are logical-AND (i.e. must be set in both for permission) */
#define OPTFLAG(x) ret->x = (primary->x == 1) && (additional->x == 1)
OPTFLAG(permit_port_forwarding_flag);
OPTFLAG(permit_agent_forwarding_flag);
OPTFLAG(permit_x11_forwarding_flag);
OPTFLAG(permit_pty_flag);
OPTFLAG(permit_user_rc);
#undef OPTFLAG
#define OPTFLAG_AND(x) ret->x = (primary->x == 1) && (additional->x == 1)
/* Permissive flags are logical-AND (i.e. must be set in both) */
OPTFLAG_AND(permit_port_forwarding_flag);
OPTFLAG_AND(permit_agent_forwarding_flag);
OPTFLAG_AND(permit_x11_forwarding_flag);
OPTFLAG_AND(permit_pty_flag);
OPTFLAG_AND(permit_user_rc);
OPTFLAG_AND(no_require_user_presence);
#undef OPTFLAG_AND

/* Earliest expiry time should win */
if (primary->valid_before != 0)
Expand Down Expand Up @@ -643,6 +649,7 @@ sshauthopt_copy(const struct sshauthopt *orig)
OPTSCALAR(cert_authority);
OPTSCALAR(force_tun_device);
OPTSCALAR(valid_before);
OPTSCALAR(no_require_user_presence);
#undef OPTSCALAR
#define OPTSTRING(x) \
do { \
Expand Down Expand Up @@ -765,15 +772,19 @@ sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m,
{
int r = SSH_ERR_INTERNAL_ERROR;

/* Flag and simple integer options */
/* Flag options */
if ((r = sshbuf_put_u8(m, opts->permit_port_forwarding_flag)) != 0 ||
(r = sshbuf_put_u8(m, opts->permit_agent_forwarding_flag)) != 0 ||
(r = sshbuf_put_u8(m, opts->permit_x11_forwarding_flag)) != 0 ||
(r = sshbuf_put_u8(m, opts->permit_pty_flag)) != 0 ||
(r = sshbuf_put_u8(m, opts->permit_user_rc)) != 0 ||
(r = sshbuf_put_u8(m, opts->restricted)) != 0 ||
(r = sshbuf_put_u8(m, opts->cert_authority)) != 0 ||
(r = sshbuf_put_u64(m, opts->valid_before)) != 0)
(r = sshbuf_put_u8(m, opts->no_require_user_presence)) != 0)
return r;

/* Simple integer options */
if ((r = sshbuf_put_u64(m, opts->valid_before)) != 0)
return r;

/* tunnel number can be negative to indicate "unset" */
Expand Down Expand Up @@ -817,6 +828,7 @@ sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp)
if ((opts = calloc(1, sizeof(*opts))) == NULL)
return SSH_ERR_ALLOC_FAIL;

/* Flag options */
#define OPT_FLAG(x) \
do { \
if ((r = sshbuf_get_u8(m, &f)) != 0) \
Expand All @@ -830,8 +842,10 @@ sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp)
OPT_FLAG(permit_user_rc);
OPT_FLAG(restricted);
OPT_FLAG(cert_authority);
OPT_FLAG(no_require_user_presence);
#undef OPT_FLAG

/* Simple integer options */
if ((r = sshbuf_get_u64(m, &opts->valid_before)) != 0)
goto out;

Expand Down
5 changes: 4 additions & 1 deletion auth-options.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth-options.h,v 1.28 2019/07/09 04:15:00 djm Exp $ */
/* $OpenBSD: auth-options.h,v 1.29 2019/11/25 00:54:23 djm Exp $ */

/*
* Copyright (c) 2018 Damien Miller <[email protected]>
Expand Down Expand Up @@ -68,6 +68,9 @@ struct sshauthopt {
*/
char *required_from_host_cert;
char *required_from_host_keys;

/* Key requires user presence asserted */
int no_require_user_presence;
};

struct sshauthopt *sshauthopt_new(void);
Expand Down
7 changes: 4 additions & 3 deletions auth.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.142 2019/10/16 06:05:39 djm Exp $ */
/* $OpenBSD: auth.c,v 1.143 2019/11/25 00:54:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
Expand Down Expand Up @@ -1005,7 +1005,7 @@ auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote)

snprintf(buf, sizeof(buf), "%d", opts->force_tun_device);
/* Try to keep this alphabetically sorted */
snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s",
snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
opts->permit_agent_forwarding_flag ? " agent-forwarding" : "",
opts->force_command == NULL ? "" : " command",
do_env ? " environment" : "",
Expand All @@ -1018,7 +1018,8 @@ auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote)
opts->force_tun_device == -1 ? "" : " tun=",
opts->force_tun_device == -1 ? "" : buf,
opts->permit_user_rc ? " user-rc" : "",
opts->permit_x11_forwarding_flag ? " x11-forwarding" : "");
opts->permit_x11_forwarding_flag ? " x11-forwarding" : "",
opts->no_require_user_presence ? " no-touch-required" : "");

debug("%s: %s", loc, msg);
if (do_remote)
Expand Down
5 changes: 3 additions & 2 deletions auth2-pubkey.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.96 2019/11/25 00:52:46 djm Exp $ */
/* $OpenBSD: auth2-pubkey.c,v 1.97 2019/11/25 00:54:23 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
Expand Down Expand Up @@ -225,7 +225,8 @@ userauth_pubkey(struct ssh *ssh)
__func__, sig_details->sk_counter,
sig_details->sk_flags);
req_presence = (options.pubkey_auth_options &
PUBKEYAUTH_TOUCH_REQUIRED);
PUBKEYAUTH_TOUCH_REQUIRED) ||
!authopts->no_require_user_presence;
if (req_presence && (sig_details->sk_flags &
SSH_SK_USER_PRESENCE_REQD) == 0) {
error("public key %s signature for %s%s from "
Expand Down
5 changes: 3 additions & 2 deletions monitor.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.203 2019/11/25 00:52:46 djm Exp $ */
/* $OpenBSD: monitor.c,v 1.204 2019/11/25 00:54:23 djm Exp $ */
/*
* Copyright 2002 Niels Provos <[email protected]>
* Copyright 2002 Markus Friedl <[email protected]>
Expand Down Expand Up @@ -1440,7 +1440,8 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)

if (ret == 0 && key_blobtype == MM_USERKEY && sig_details != NULL) {
req_presence = (options.pubkey_auth_options &
PUBKEYAUTH_TOUCH_REQUIRED);
PUBKEYAUTH_TOUCH_REQUIRED) ||
!key_opts->no_require_user_presence;
if (req_presence &&
(sig_details->sk_flags & SSH_SK_USER_PRESENCE_REQD) == 0) {
error("public key %s %s signature for %s%s from %.128s "
Expand Down
12 changes: 10 additions & 2 deletions ssh-keygen.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-keygen.1,v 1.176 2019/11/18 23:16:49 naddy Exp $
.\" $OpenBSD: ssh-keygen.1,v 1.177 2019/11/25 00:54:23 djm Exp $
.\"
.\" Author: Tatu Ylonen <[email protected]>
.\" Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: November 18 2019 $
.Dd $Mdocdate: November 25 2019 $
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
Expand Down Expand Up @@ -534,6 +534,14 @@ by
.It Ic permit-X11-forwarding
Allows X11 forwarding.
.Pp
.It Ic no-touch-required
Do not require signatures made using this key require demonstration
of user presence (e.g. by having the user touch the key).
This option only makes sense for the Security Key algorithms
.Cm ecdsa-sk
and
.Cm ed25519-sk .
.Pp
.It Ic source-address Ns = Ns Ar address_list
Restrict the source addresses from which the certificate is considered valid.
The
Expand Down
25 changes: 17 additions & 8 deletions ssh-keygen.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.370 2019/11/25 00:51:37 djm Exp $ */
/* $OpenBSD: ssh-keygen.c,v 1.371 2019/11/25 00:54:23 djm Exp $ */
/*
* Author: Tatu Ylonen <[email protected]>
* Copyright (c) 1994 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -120,11 +120,12 @@ static u_int64_t cert_valid_from = 0;
static u_int64_t cert_valid_to = ~0ULL;

/* Certificate options */
#define CERTOPT_X_FWD (1)
#define CERTOPT_AGENT_FWD (1<<1)
#define CERTOPT_PORT_FWD (1<<2)
#define CERTOPT_PTY (1<<3)
#define CERTOPT_USER_RC (1<<4)
#define CERTOPT_X_FWD (1)
#define CERTOPT_AGENT_FWD (1<<1)
#define CERTOPT_PORT_FWD (1<<2)
#define CERTOPT_PTY (1<<3)
#define CERTOPT_USER_RC (1<<4)
#define CERTOPT_NO_REQUIRE_USER_PRESENCE (1<<5)
#define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
static u_int32_t certflags_flags = CERTOPT_DEFAULT;
Expand Down Expand Up @@ -1665,6 +1666,9 @@ prepare_options_buf(struct sshbuf *c, int which)
if ((which & OPTIONS_EXTENSIONS) != 0 &&
(certflags_flags & CERTOPT_USER_RC) != 0)
add_flag_option(c, "permit-user-rc");
if ((which & OPTIONS_CRITICAL) != 0 &&
(certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0)
add_flag_option(c, "no-touch-required");
if ((which & OPTIONS_CRITICAL) != 0 &&
certflags_src_addr != NULL)
add_string_option(c, "source-address", certflags_src_addr);
Expand Down Expand Up @@ -1967,6 +1971,10 @@ add_cert_option(char *opt)
certflags_flags &= ~CERTOPT_USER_RC;
else if (strcasecmp(opt, "permit-user-rc") == 0)
certflags_flags |= CERTOPT_USER_RC;
else if (strcasecmp(opt, "touch-required") == 0)
certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE;
else if (strcasecmp(opt, "no-touch-required") == 0)
certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE;
else if (strncasecmp(opt, "force-command=", 14) == 0) {
val = opt + 14;
if (*val == '\0')
Expand Down Expand Up @@ -2020,9 +2028,10 @@ show_options(struct sshbuf *optbuf, int in_critical)
strcmp(name, "permit-agent-forwarding") == 0 ||
strcmp(name, "permit-port-forwarding") == 0 ||
strcmp(name, "permit-pty") == 0 ||
strcmp(name, "permit-user-rc") == 0))
strcmp(name, "permit-user-rc") == 0 ||
strcmp(name, "no-touch-required") == 0)) {
printf("\n");
else if (in_critical &&
} else if (in_critical &&
(strcmp(name, "force-command") == 0 ||
strcmp(name, "source-address") == 0)) {
if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0)
Expand Down
13 changes: 11 additions & 2 deletions sshd.8
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd.8,v 1.306 2019/11/18 04:55:02 djm Exp $
.Dd $Mdocdate: November 18 2019 $
.\" $OpenBSD: sshd.8,v 1.307 2019/11/25 00:54:23 djm Exp $
.Dd $Mdocdate: November 25 2019 $
.Dt SSHD 8
.Os
.Sh NAME
Expand Down Expand Up @@ -627,6 +627,13 @@ option.
Permits tty allocation previously disabled by the
.Cm restrict
option.
.It Cm no-touch-required
Do not require demonstration of user presence
for signatures made using this key.
This option only makes sense for the Security Key algorithms
.Cm ecdsa-sk
and
.Cm ed25519-sk .
.It Cm restrict
Enable all restrictions, i.e. disable port, agent and X11 forwarding,
as well as disabling PTY allocation
Expand Down Expand Up @@ -670,6 +677,8 @@ restrict,command="uptime" ssh-rsa AAAA1C8...32Tv==
[email protected]
restrict,pty,command="nethack" ssh-rsa AAAA1f8...IrrC5==
[email protected]
no-touch-required [email protected] AAAAInN...Ko==
[email protected]
.Ed
.Sh SSH_KNOWN_HOSTS FILE FORMAT
The
Expand Down

0 comments on commit 2e71263

Please sign in to comment.