From 383f10fb84a0fee3c01f9d97594f3e22aa3cd5e0 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Mon, 16 Nov 2015 00:30:02 +0000 Subject: [PATCH] upstream commit Add a new authorized_keys option "restrict" that includes all current and future key restrictions (no-*-forwarding, etc). Also add permissive versions of the existing restrictions, e.g. "no-pty" -> "pty". This simplifies the task of setting up restricted keys and ensures they are maximally-restricted, regardless of any permissions we might implement in the future. Example: restrict,pty,command="nethack" ssh-ed25519 AAAAC3NzaC1lZDI1... Idea from Jann Horn; ok markus@ Upstream-ID: 04ceb9d448e46e67e13887a7ae5ea45b4f1719d0 --- auth-options.c | 93 ++++++++++++++++++++++++++++++++------------------ sshd.8 | 36 +++++++++++++++++-- 2 files changed, 94 insertions(+), 35 deletions(-) diff --git a/auth-options.c b/auth-options.c index e387697d3..cb68802de 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.68 2015/07/03 03:43:18 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.69 2015/11/16 00:30:02 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -87,6 +87,36 @@ auth_clear_options(void) channel_clear_permitted_opens(); } +/* + * Match flag 'opt' in *optsp, and if allow_negate is set then also match + * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0 + * if negated option matches. + * If the option or negated option matches, then *optsp is updated to + * point to the first character after the option and, if 'msg' is not NULL + * then a message based on it added via auth_debug_add(). + */ +static int +match_flag(const char *opt, int allow_negate, char **optsp, const char *msg) +{ + size_t opt_len = strlen(opt); + char *opts = *optsp; + int negate = 0; + + if (allow_negate && strncasecmp(opts, "no-", 3) == 0) { + opts += 3; + negate = 1; + } + if (strncasecmp(opts, opt, opt_len) == 0) { + *optsp = opts + opt_len; + if (msg != NULL) { + auth_debug_add("%s %s.", msg, + negate ? "disabled" : "enabled"); + } + return negate ? 0 : 1; + } + return -1; +} + /* * return 1 if access is granted, 0 if not. * side effect: sets key option flags @@ -95,7 +125,7 @@ int auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) { const char *cp; - int i; + int i, r; /* reset options */ auth_clear_options(); @@ -104,45 +134,42 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) return 1; while (*opts && *opts != ' ' && *opts != '\t') { - cp = "cert-authority"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - key_is_cert_authority = 1; - opts += strlen(cp); + if ((r = match_flag("cert-authority", 0, &opts, NULL)) != -1) { + key_is_cert_authority = r; goto next_option; } - cp = "no-port-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Port forwarding disabled."); + if ((r = match_flag("restrict", 0, &opts, NULL)) != -1) { + auth_debug_add("Key is restricted."); no_port_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-agent-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Agent forwarding disabled."); no_agent_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-X11-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("X11 forwarding disabled."); no_x11_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-pty"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Pty allocation disabled."); no_pty_flag = 1; - opts += strlen(cp); + no_user_rc = 1; goto next_option; } - cp = "no-user-rc"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("User rc file execution disabled."); - no_user_rc = 1; - opts += strlen(cp); + if ((r = match_flag("port-forwarding", 1, &opts, + "Port forwarding")) != -1) { + no_port_forwarding_flag = r != 1; + goto next_option; + } + if ((r = match_flag("agent-forwarding", 1, &opts, + "Agent forwarding")) != -1) { + no_agent_forwarding_flag = r != 1; + goto next_option; + } + if ((r = match_flag("x11-forwarding", 1, &opts, + "X11 forwarding")) != -1) { + no_x11_forwarding_flag = r != 1; + goto next_option; + } + if ((r = match_flag("pty", 1, &opts, + "PTY allocation")) != -1) { + no_pty_flag = r != 1; + goto next_option; + } + if ((r = match_flag("user-rc", 1, &opts, + "User rc execution")) != -1) { + no_user_rc = r != 1; goto next_option; } cp = "command=\""; diff --git a/sshd.8 b/sshd.8 index 3b20d9f32..9bf3d5bb2 100644 --- a/sshd.8 +++ b/sshd.8 @@ -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.281 2015/09/11 03:13:36 djm Exp $ -.Dd $Mdocdate: September 11 2015 $ +.\" $OpenBSD: sshd.8,v 1.282 2015/11/16 00:30:02 djm Exp $ +.Dd $Mdocdate: November 16 2015 $ .Dt SSHD 8 .Os .Sh NAME @@ -522,6 +522,10 @@ No spaces are permitted, except within double quotes. The following option specifications are supported (note that option keywords are case-insensitive): .Bl -tag -width Ds +.It Cm agent-forwarding +Enable authentication agent forwarding previously disabled by the +.Cm restrict +option. .It Cm cert-authority Specifies that the listed key is a certification authority (CA) that is trusted to validate signed certificates for user authentication. @@ -616,6 +620,9 @@ they must be literal domains or addresses. A port specification of .Cm * matches any port. +.It Cm port-forwarding +Enable port forwarding previously disabled by the +.Cm restrict .It Cm principals="principals" On a .Cm cert-authority @@ -627,12 +634,33 @@ This option is ignored for keys that are not marked as trusted certificate signers using the .Cm cert-authority option. +.It Cm pty +Permits tty allocation previously disabled by the +.Cm restrict +option. +.It Cm restrict +Enable all restrictions, i.e. disable port, agent and X11 forwarding, +as well as disabling PTY allocation +and execution of +.Pa ~/.ssh/rc . +If any future restriction capabilities are added to authorized_keys files +they will be included in this set. .It Cm tunnel="n" Force a .Xr tun 4 device on the server. Without this option, the next available device will be used if the client requests a tunnel. +.It Cm user-rc +Enables execution of +.Pa ~/.ssh/rc +previously disabled by the +.Cm restrict +option. +.It Cm X11-forwarding +Permits X11 forwarding previously disabled by the +.Cm restrict +option. .El .Pp An example authorized_keys file: @@ -647,6 +675,10 @@ permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss AAAAB5...21S== tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== jane@example.net +restrict,command="uptime" ssh-rsa AAAA1C8...32Tv== +user@example.net +restrict,pty,command="nethack" ssh-rsa AAAA1f8...IrrC5== +user@example.net .Ed .Sh SSH_KNOWN_HOSTS FILE FORMAT The