fix bug in PermitRemoteOpen which caused it to ignore its first
authordjm <djm@openbsd.org>
Mon, 2 Jan 2023 07:03:30 +0000 (07:03 +0000)
committerdjm <djm@openbsd.org>
Mon, 2 Jan 2023 07:03:30 +0000 (07:03 +0000)
argument unless it was one of the special keywords "any" or "none".

Reported by Georges Chaudy in bz3515; ok dtucker@

usr.bin/ssh/readconf.c

index 6e3f697..8bbaabf 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.370 2022/11/28 01:37:36 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.371 2023/01/02 07:03:30 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1554,37 +1554,37 @@ parse_pubkey_algos:
        case oPermitRemoteOpen:
                uintptr = &options->num_permitted_remote_opens;
                cppptr = &options->permitted_remote_opens;
-               arg = argv_next(&ac, &av);
-               if (!arg || *arg == '\0')
-                       fatal("%s line %d: missing %s specification",
-                           filename, linenum, lookup_opcode_name(opcode));
                uvalue = *uintptr;      /* modified later */
-               if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
-                       if (*activep && uvalue == 0) {
-                               *uintptr = 1;
-                               *cppptr = xcalloc(1, sizeof(**cppptr));
-                               (*cppptr)[0] = xstrdup(arg);
-                       }
-                       break;
-               }
+               i = 0;
                while ((arg = argv_next(&ac, &av)) != NULL) {
                        arg2 = xstrdup(arg);
-                       p = hpdelim(&arg);
-                       if (p == NULL) {
-                               fatal("%s line %d: missing host in %s",
-                                   filename, linenum,
-                                   lookup_opcode_name(opcode));
-                       }
-                       p = cleanhostname(p);
-                       /*
-                        * don't want to use permitopen_port to avoid
-                        * dependency on channels.[ch] here.
-                        */
-                       if (arg == NULL ||
-                           (strcmp(arg, "*") != 0 && a2port(arg) <= 0)) {
-                               fatal("%s line %d: bad port number in %s",
-                                   filename, linenum,
-                                   lookup_opcode_name(opcode));
+                       /* Allow any/none only in first position */
+                       if (strcasecmp(arg, "none") == 0 ||
+                           strcasecmp(arg, "any") == 0) {
+                               if (i > 0 || ac > 0) {
+                                       error("%s line %d: keyword %s \"%s\" "
+                                           "argument must appear alone.",
+                                           filename, linenum, keyword, arg);
+                                       goto out;
+                               }
+                       } else {
+                               p = hpdelim(&arg);
+                               if (p == NULL) {
+                                       fatal("%s line %d: missing host in %s",
+                                           filename, linenum,
+                                           lookup_opcode_name(opcode));
+                               }
+                               p = cleanhostname(p);
+                               /*
+                                * don't want to use permitopen_port to avoid
+                                * dependency on channels.[ch] here.
+                                */
+                               if (arg == NULL || (strcmp(arg, "*") != 0 &&
+                                   a2port(arg) <= 0)) {
+                                       fatal("%s line %d: bad port number "
+                                           "in %s", filename, linenum,
+                                           lookup_opcode_name(opcode));
+                               }
                        }
                        if (*activep && uvalue == 0) {
                                opt_array_append(filename, linenum,
@@ -1592,7 +1592,11 @@ parse_pubkey_algos:
                                    cppptr, uintptr, arg2);
                        }
                        free(arg2);
+                       i++;
                }
+               if (i == 0)
+                       fatal("%s line %d: missing %s specification",
+                           filename, linenum, lookup_opcode_name(opcode));
                break;
 
        case oClearAllForwardings: