]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream commit
authordjm@openbsd.org <djm@openbsd.org>
Mon, 16 Nov 2015 00:30:02 +0000 (00:30 +0000)
committerDamien Miller <djm@mindrot.org>
Mon, 16 Nov 2015 00:31:41 +0000 (11:31 +1100)
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
sshd.8

index e387697d36d027939d46812c36b06d940d1b8822..cb68802dee7dccaba818a724b54b071a5fbed767 100644 (file)
@@ -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 <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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);
+                       no_agent_forwarding_flag = 1;
+                       no_x11_forwarding_flag = 1;
+                       no_pty_flag = 1;
+                       no_user_rc = 1;
                        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);
+               if ((r = match_flag("port-forwarding", 1, &opts,
+                   "Port forwarding")) != -1) {
+                       no_port_forwarding_flag = r != 1;
                        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);
+               if ((r = match_flag("agent-forwarding", 1, &opts,
+                   "Agent forwarding")) != -1) {
+                       no_agent_forwarding_flag = r != 1;
                        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);
+               if ((r = match_flag("x11-forwarding", 1, &opts,
+                   "X11 forwarding")) != -1) {
+                       no_x11_forwarding_flag = r != 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("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 3b20d9f32761e291492f22a1c0cefae96813a83b..9bf3d5bb2cc4d480c44caa22386bd9e2f7af54f7 100644 (file)
--- 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