[BACK]Return to readconf.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/readconf.c between version 1.355 and 1.356

version 1.355, 2021/06/08 07:02:46 version 1.356, 2021/06/08 07:07:15
Line 589 
Line 589 
         debug2("checking match for '%s' host %s originally %s",          debug2("checking match for '%s' host %s originally %s",
             cp, host, original_host);              cp, host, original_host);
         while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {          while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
                 criteria = NULL;                  /* Terminate on comment */
                   if (*attrib == '#') {
                           cp = NULL; /* mark all arguments consumed */
                           break;
                   }
                   arg = criteria = NULL;
                 this_result = 1;                  this_result = 1;
                 if ((negate = attrib[0] == '!'))                  if ((negate = attrib[0] == '!'))
                         attrib++;                          attrib++;
                 /* criteria "all" and "canonical" have no argument */                  /* Criterion "all" has no argument and must appear alone */
                 if (strcasecmp(attrib, "all") == 0) {                  if (strcasecmp(attrib, "all") == 0) {
                         if (attributes > 1 ||                          if (attributes > 1 || ((arg = strdelim(&cp)) != NULL &&
                             ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {                              *arg != '\0' && *arg != '#')) {
                                 error("%.200s line %d: '%s' cannot be combined "                                  error("%.200s line %d: '%s' cannot be combined "
                                     "with other Match attributes",                                      "with other Match attributes",
                                     filename, linenum, oattrib);                                      filename, linenum, oattrib);
                                 result = -1;                                  result = -1;
                                 goto out;                                  goto out;
                         }                          }
                           if (arg != NULL && *arg == '#')
                                   cp = NULL; /* mark all arguments consumed */
                         if (result)                          if (result)
                                 result = negate ? 0 : 1;                                  result = negate ? 0 : 1;
                         goto out;                          goto out;
                 }                  }
                 attributes++;                  attributes++;
                   /* criteria "final" and "canonical" have no argument */
                 if (strcasecmp(attrib, "canonical") == 0 ||                  if (strcasecmp(attrib, "canonical") == 0 ||
                     strcasecmp(attrib, "final") == 0) {                      strcasecmp(attrib, "final") == 0) {
                         /*                          /*
Line 626 
Line 634 
                         continue;                          continue;
                 }                  }
                 /* All other criteria require an argument */                  /* All other criteria require an argument */
                 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {                  if ((arg = strdelim(&cp)) == NULL ||
                       *arg == '\0' || *arg == '#') {
                         error("Missing Match criteria for %s", attrib);                          error("Missing Match criteria for %s", attrib);
                         result = -1;                          result = -1;
                         goto out;                          goto out;
Line 901 
Line 910 
     const char *original_host, char *line, const char *filename,      const char *original_host, char *line, const char *filename,
     int linenum, int *activep, int flags, int *want_final_pass, int depth)      int linenum, int *activep, int flags, int *want_final_pass, int depth)
 {  {
         char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch;          char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch;
         char **cpptr, ***cppptr, fwdarg[256];          char **cpptr, ***cppptr, fwdarg[256];
         u_int i, *uintptr, uvalue, max_entries = 0;          u_int i, *uintptr, uvalue, max_entries = 0;
         int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;          int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
Line 915 
Line 924 
         struct allowed_cname *cname;          struct allowed_cname *cname;
         glob_t gl;          glob_t gl;
         const char *errstr;          const char *errstr;
           char **oav = NULL, **av;
           int oac = 0, ac;
           int ret = -1;
   
         if (activep == NULL) { /* We are processing a command line directive */          if (activep == NULL) { /* We are processing a command line directive */
                 cmdline = 1;                  cmdline = 1;
Line 930 
Line 942 
                 line[len] = '\0';                  line[len] = '\0';
         }          }
   
         s = line;          str = line;
         /* Get the keyword. (Each line is supposed to begin with a keyword). */          /* Get the keyword. (Each line is supposed to begin with a keyword). */
         if ((keyword = strdelim(&s)) == NULL)          if ((keyword = strdelim(&str)) == NULL)
                 return 0;                  return 0;
         /* Ignore leading whitespace. */          /* Ignore leading whitespace. */
         if (*keyword == '\0')          if (*keyword == '\0')
                 keyword = strdelim(&s);                  keyword = strdelim(&str);
         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')          if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
                 return 0;                  return 0;
         /* Match lowercase keyword */          /* Match lowercase keyword */
         lowercase(keyword);          lowercase(keyword);
   
           /* Prepare to parse remainder of line */
           if (str != NULL)
                   str += strspn(str, WHITESPACE);
           if (str == NULL || *str == '\0') {
                   error("%s line %d: no argument after keyword \"%s\"",
                       filename, linenum, keyword);
                   return -1;
           }
         opcode = parse_token(keyword, filename, linenum,          opcode = parse_token(keyword, filename, linenum,
             options->ignored_unknown);              options->ignored_unknown);
           if (argv_split(str, &oac, &oav, 1) != 0) {
                   error("%s line %d: invalid quotes", filename, linenum);
                   return -1;
           }
           ac = oac;
           av = oav;
   
         switch (opcode) {          switch (opcode) {
         case oBadOption:          case oBadOption:
                 /* don't panic, but count bad options */                  /* don't panic, but count bad options */
                 return -1;                  goto out;
         case oIgnore:          case oIgnore:
                 return 0;                  argv_consume(&ac);
                   break;
         case oIgnoredUnknownOption:          case oIgnoredUnknownOption:
                 debug("%s line %d: Ignored unknown option \"%s\"",                  debug("%s line %d: Ignored unknown option \"%s\"",
                     filename, linenum, keyword);                      filename, linenum, keyword);
                 return 0;                  argv_consume(&ac);
                   break;
         case oConnectTimeout:          case oConnectTimeout:
                 intptr = &options->connection_timeout;                  intptr = &options->connection_timeout;
 parse_time:  parse_time:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%s line %d: missing time value.",                          error("%s line %d: missing time value.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (strcmp(arg, "none") == 0)                  if (strcmp(arg, "none") == 0)
                         value = -1;                          value = -1;
                 else if ((value = convtime(arg)) == -1) {                  else if ((value = convtime(arg)) == -1) {
                         error("%s line %d: invalid time value.",                          error("%s line %d: invalid time value.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *intptr == -1)                  if (*activep && *intptr == -1)
                         *intptr = value;                          *intptr = value;
Line 978 
Line 1006 
         case oForwardAgent:          case oForwardAgent:
                 intptr = &options->forward_agent;                  intptr = &options->forward_agent;
   
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%s line %d: missing argument.",                          error("%s line %d: missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
   
                 value = -1;                  value = -1;
Line 1010 
Line 1038 
  parse_flag:   parse_flag:
                 multistate_ptr = multistate_flag;                  multistate_ptr = multistate_flag;
  parse_multistate:   parse_multistate:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if ((value = parse_multistate_value(arg, filename, linenum,                  if ((value = parse_multistate_value(arg, filename, linenum,
                     multistate_ptr)) == -1) {                      multistate_ptr)) == -1) {
                         error("%s line %d: unsupported option \"%s\".",                          error("%s line %d: unsupported option \"%s\".",
                             filename, linenum, arg);                              filename, linenum, arg);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *intptr == -1)                  if (*activep && *intptr == -1)
                         *intptr = value;                          *intptr = value;
Line 1105 
Line 1133 
                 goto parse_int;                  goto parse_int;
   
         case oRekeyLimit:          case oRekeyLimit:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.", filename,                          error("%.200s line %d: Missing argument.", filename,
                             linenum);                              linenum);
                         return -1;                          goto out;
                 }                  }
                 if (strcmp(arg, "default") == 0) {                  if (strcmp(arg, "default") == 0) {
                         val64 = 0;                          val64 = 0;
Line 1117 
Line 1145 
                         if (scan_scaled(arg, &val64) == -1) {                          if (scan_scaled(arg, &val64) == -1) {
                                 error("%.200s line %d: Bad number '%s': %s",                                  error("%.200s line %d: Bad number '%s': %s",
                                     filename, linenum, arg, strerror(errno));                                      filename, linenum, arg, strerror(errno));
                                 return -1;                                  goto out;
                         }                          }
                         if (val64 != 0 && val64 < 16) {                          if (val64 != 0 && val64 < 16) {
                                 error("%.200s line %d: RekeyLimit too small",                                  error("%.200s line %d: RekeyLimit too small",
                                     filename, linenum);                                      filename, linenum);
                                 return -1;                                  goto out;
                         }                          }
                 }                  }
                 if (*activep && options->rekey_limit == -1)                  if (*activep && options->rekey_limit == -1)
                         options->rekey_limit = val64;                          options->rekey_limit = val64;
                 if (s != NULL) { /* optional rekey interval present */                  if (ac != 0) { /* optional rekey interval present */
                         if (strcmp(s, "none") == 0) {                          if (strcmp(av[0], "none") == 0) {
                                 (void)strdelim(&s);     /* discard */                                  (void)argv_next(&ac, &av);      /* discard */
                                 break;                                  break;
                         }                          }
                         intptr = &options->rekey_interval;                          intptr = &options->rekey_interval;
Line 1138 
Line 1166 
                 break;                  break;
   
         case oIdentityFile:          case oIdentityFile:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*activep) {                  if (*activep) {
                         intptr = &options->num_identity_files;                          intptr = &options->num_identity_files;
Line 1150 
Line 1178 
                                 error("%.200s line %d: Too many identity files "                                  error("%.200s line %d: Too many identity files "
                                     "specified (max %d).", filename, linenum,                                      "specified (max %d).", filename, linenum,
                                     SSH_MAX_IDENTITY_FILES);                                      SSH_MAX_IDENTITY_FILES);
                                 return -1;                                  goto out;
                         }                          }
                         add_identity_file(options, NULL,                          add_identity_file(options, NULL,
                             arg, flags & SSHCONF_USERCONF);                              arg, flags & SSHCONF_USERCONF);
Line 1158 
Line 1186 
                 break;                  break;
   
         case oCertificateFile:          case oCertificateFile:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*activep) {                  if (*activep) {
                         intptr = &options->num_certificate_files;                          intptr = &options->num_certificate_files;
Line 1171 
Line 1199 
                                     "files specified (max %d).",                                      "files specified (max %d).",
                                     filename, linenum,                                      filename, linenum,
                                     SSH_MAX_CERTIFICATE_FILES);                                      SSH_MAX_CERTIFICATE_FILES);
                                 return -1;                                  goto out;
                         }                          }
                         add_certificate_file(options, arg,                          add_certificate_file(options, arg,
                             flags & SSHCONF_USERCONF);                              flags & SSHCONF_USERCONF);
Line 1185 
Line 1213 
         case oUser:          case oUser:
                 charptr = &options->user;                  charptr = &options->user;
 parse_string:  parse_string:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *charptr == NULL)                  if (*activep && *charptr == NULL)
                         *charptr = xstrdup(arg);                          *charptr = xstrdup(arg);
Line 1200 
Line 1228 
                 uintptr = &options->num_system_hostfiles;                  uintptr = &options->num_system_hostfiles;
                 max_entries = SSH_MAX_HOSTS_FILES;                  max_entries = SSH_MAX_HOSTS_FILES;
 parse_char_array:  parse_char_array:
                 if (*activep && *uintptr == 0) {                  i = 0;
                         while ((arg = strdelim(&s)) != NULL && *arg != '\0') {                  while ((arg = argv_next(&ac, &av)) != NULL) {
                           if (*arg == '\0') {
                                   error("%s line %d: keyword %s empty argument",
                                       filename, linenum, keyword);
                                   goto out;
                           }
                           /* Allow "none" only in first position */
                           if (strcasecmp(arg, "none") == 0) {
                                   if (i > 0 || ac > 0) {
                                           error("%s line %d: keyword %s \"none\" "
                                               "argument must appear alone.",
                                               filename, linenum, keyword);
                                           goto out;
                                   }
                           }
                           i++;
                           if (*activep && *uintptr == 0) {
                                 if ((*uintptr) >= max_entries) {                                  if ((*uintptr) >= max_entries) {
                                         error("%s line %d: too many known "                                          error("%s line %d: too many %s "
                                             "hosts files.", filename, linenum);                                              "entries.", filename, linenum,
                                         return -1;                                              keyword);
                                           goto out;
                                 }                                  }
                                 cpptr[(*uintptr)++] = xstrdup(arg);                                  cpptr[(*uintptr)++] = xstrdup(arg);
                         }                          }
                 }                  }
                 return 0;                  break;
   
         case oUserKnownHostsFile:          case oUserKnownHostsFile:
                 cpptr = (char **)&options->user_hostfiles;                  cpptr = (char **)&options->user_hostfiles;
Line 1256 
Line 1301 
                 if (options->jump_host != NULL)                  if (options->jump_host != NULL)
                         charptr = &options->jump_host; /* Skip below */                          charptr = &options->jump_host; /* Skip below */
 parse_command:  parse_command:
                 if (s == NULL) {                  if (str == NULL) {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 len = strspn(s, WHITESPACE "=");                  len = strspn(str, WHITESPACE "=");
                 if (*activep && *charptr == NULL)                  if (*activep && *charptr == NULL)
                         *charptr = xstrdup(s + len);                          *charptr = xstrdup(str + len);
                 return 0;                  argv_consume(&ac);
                   break;
   
         case oProxyJump:          case oProxyJump:
                 if (s == NULL) {                  if (str == NULL) {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 len = strspn(s, WHITESPACE "=");                  len = strspn(str, WHITESPACE "=");
                 if (parse_jump(s + len, options, *activep) == -1) {                  /* XXX use argv? */
                   if (parse_jump(str + len, options, *activep) == -1) {
                         error("%.200s line %d: Invalid ProxyJump \"%s\"",                          error("%.200s line %d: Invalid ProxyJump \"%s\"",
                             filename, linenum, s + len);                              filename, linenum, str + len);
                         return -1;                          goto out;
                 }                  }
                 return 0;                  argv_consume(&ac);
                   break;
   
         case oPort:          case oPort:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 value = a2port(arg);                  value = a2port(arg);
                 if (value <= 0) {                  if (value <= 0) {
                         error("%.200s line %d: Bad port '%s'.",                          error("%.200s line %d: Bad port '%s'.",
                             filename, linenum, arg);                              filename, linenum, arg);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && options->port == -1)                  if (*activep && options->port == -1)
                         options->port = value;                          options->port = value;
Line 1300 
Line 1348 
         case oConnectionAttempts:          case oConnectionAttempts:
                 intptr = &options->connection_attempts;                  intptr = &options->connection_attempts;
 parse_int:  parse_int:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if ((errstr = atoi_err(arg, &value)) != NULL) {                  if ((errstr = atoi_err(arg, &value)) != NULL) {
                         error("%s line %d: integer value %s.",                          error("%s line %d: integer value %s.",
                             filename, linenum, errstr);                              filename, linenum, errstr);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *intptr == -1)                  if (*activep && *intptr == -1)
                         *intptr = value;                          *intptr = value;
                 break;                  break;
   
         case oCiphers:          case oCiphers:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*arg != '-' &&                  if (*arg != '-' &&
                     !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)){                      !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)){
                         error("%.200s line %d: Bad SSH2 cipher spec '%s'.",                          error("%.200s line %d: Bad SSH2 cipher spec '%s'.",
                             filename, linenum, arg ? arg : "<NONE>");                              filename, linenum, arg ? arg : "<NONE>");
                         return -1;                          goto out;
                 }                  }
                 if (*activep && options->ciphers == NULL)                  if (*activep && options->ciphers == NULL)
                         options->ciphers = xstrdup(arg);                          options->ciphers = xstrdup(arg);
                 break;                  break;
   
         case oMacs:          case oMacs:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*arg != '-' &&                  if (*arg != '-' &&
                     !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) {                      !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) {
                         error("%.200s line %d: Bad SSH2 MAC spec '%s'.",                          error("%.200s line %d: Bad SSH2 MAC spec '%s'.",
                             filename, linenum, arg ? arg : "<NONE>");                              filename, linenum, arg ? arg : "<NONE>");
                         return -1;                          goto out;
                 }                  }
                 if (*activep && options->macs == NULL)                  if (*activep && options->macs == NULL)
                         options->macs = xstrdup(arg);                          options->macs = xstrdup(arg);
                 break;                  break;
   
         case oKexAlgorithms:          case oKexAlgorithms:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*arg != '-' &&                  if (*arg != '-' &&
                     !kex_names_valid(*arg == '+' || *arg == '^' ?                      !kex_names_valid(*arg == '+' || *arg == '^' ?
                     arg + 1 : arg)) {                      arg + 1 : arg)) {
                         error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",                          error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
                             filename, linenum, arg ? arg : "<NONE>");                              filename, linenum, arg ? arg : "<NONE>");
                         return -1;                          goto out;
                 }                  }
                 if (*activep && options->kex_algorithms == NULL)                  if (*activep && options->kex_algorithms == NULL)
                         options->kex_algorithms = xstrdup(arg);                          options->kex_algorithms = xstrdup(arg);
Line 1365 
Line 1413 
         case oHostKeyAlgorithms:          case oHostKeyAlgorithms:
                 charptr = &options->hostkeyalgorithms;                  charptr = &options->hostkeyalgorithms;
 parse_pubkey_algos:  parse_pubkey_algos:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*arg != '-' &&                  if (*arg != '-' &&
                     !sshkey_names_valid2(*arg == '+' || *arg == '^' ?                      !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
                     arg + 1 : arg, 1)) {                      arg + 1 : arg, 1)) {
                         error("%s line %d: Bad key types '%s'.",                          error("%s line %d: Bad key types '%s'.",
                             filename, linenum, arg ? arg : "<NONE>");                              filename, linenum, arg ? arg : "<NONE>");
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *charptr == NULL)                  if (*activep && *charptr == NULL)
                         *charptr = xstrdup(arg);                          *charptr = xstrdup(arg);
Line 1388 
Line 1436 
   
         case oLogLevel:          case oLogLevel:
                 log_level_ptr = &options->log_level;                  log_level_ptr = &options->log_level;
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 value = log_level_number(arg);                  value = log_level_number(arg);
                 if (value == SYSLOG_LEVEL_NOT_SET) {                  if (value == SYSLOG_LEVEL_NOT_SET) {
                         error("%.200s line %d: unsupported log level '%s'",                          error("%.200s line %d: unsupported log level '%s'",
                             filename, linenum, arg ? arg : "<NONE>");                              filename, linenum, arg ? arg : "<NONE>");
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)                  if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
                         *log_level_ptr = (LogLevel) value;                          *log_level_ptr = (LogLevel) value;
Line 1401 
Line 1449 
   
         case oLogFacility:          case oLogFacility:
                 log_facility_ptr = &options->log_facility;                  log_facility_ptr = &options->log_facility;
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 value = log_facility_number(arg);                  value = log_facility_number(arg);
                 if (value == SYSLOG_FACILITY_NOT_SET) {                  if (value == SYSLOG_FACILITY_NOT_SET) {
                         error("%.200s line %d: unsupported log facility '%s'",                          error("%.200s line %d: unsupported log facility '%s'",
                             filename, linenum, arg ? arg : "<NONE>");                              filename, linenum, arg ? arg : "<NONE>");
                         return -1;                          goto out;
                 }                  }
                 if (*log_facility_ptr == -1)                  if (*log_facility_ptr == -1)
                         *log_facility_ptr = (SyslogFacility) value;                          *log_facility_ptr = (SyslogFacility) value;
Line 1415 
Line 1463 
         case oLogVerbose:          case oLogVerbose:
                 cppptr = &options->log_verbose;                  cppptr = &options->log_verbose;
                 uintptr = &options->num_log_verbose;                  uintptr = &options->num_log_verbose;
                 if (*activep && *uintptr == 0) {                  i = 0;
                         while ((arg = strdelim(&s)) != NULL && *arg != '\0') {                  while ((arg = argv_next(&ac, &av)) != NULL) {
                           if (*arg == '\0') {
                                   error("%s line %d: keyword %s empty argument",
                                       filename, linenum, keyword);
                                   goto out;
                           }
                           /* Allow "none" only in first position */
                           if (strcasecmp(arg, "none") == 0) {
                                   if (i > 0 || ac > 0) {
                                           error("%s line %d: keyword %s \"none\" "
                                               "argument must appear alone.",
                                               filename, linenum, keyword);
                                           goto out;
                                   }
                           }
                           i++;
                           if (*activep && *uintptr == 0) {
                                 *cppptr = xrecallocarray(*cppptr, *uintptr,                                  *cppptr = xrecallocarray(*cppptr, *uintptr,
                                     *uintptr + 1, sizeof(**cppptr));                                      *uintptr + 1, sizeof(**cppptr));
                                 (*cppptr)[(*uintptr)++] = xstrdup(arg);                                  (*cppptr)[(*uintptr)++] = xstrdup(arg);
                         }                          }
                 }                  }
                 return 0;                  break;
   
         case oLocalForward:          case oLocalForward:
         case oRemoteForward:          case oRemoteForward:
         case oDynamicForward:          case oDynamicForward:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
   
                 remotefwd = (opcode == oRemoteForward);                  remotefwd = (opcode == oRemoteForward);
                 dynamicfwd = (opcode == oDynamicForward);                  dynamicfwd = (opcode == oDynamicForward);
   
                 if (!dynamicfwd) {                  if (!dynamicfwd) {
                         arg2 = strdelim(&s);                          arg2 = argv_next(&ac, &av);
                         if (arg2 == NULL || *arg2 == '\0') {                          if (arg2 == NULL || *arg2 == '\0') {
                                 if (remotefwd)                                  if (remotefwd)
                                         dynamicfwd = 1;                                          dynamicfwd = 1;
                                 else {                                  else {
                                         error("%.200s line %d: Missing target "                                          error("%.200s line %d: Missing target "
                                             "argument.", filename, linenum);                                              "argument.", filename, linenum);
                                         return -1;                                          goto out;
                                 }                                  }
                         } else {                          } else {
                                 /* construct a string for parse_forward */                                  /* construct a string for parse_forward */
Line 1459 
Line 1523 
                 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) {                  if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) {
                         error("%.200s line %d: Bad forwarding specification.",                          error("%.200s line %d: Bad forwarding specification.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
   
                 if (*activep) {                  if (*activep) {
Line 1474 
Line 1538 
         case oPermitRemoteOpen:          case oPermitRemoteOpen:
                 uintptr = &options->num_permitted_remote_opens;                  uintptr = &options->num_permitted_remote_opens;
                 cppptr = &options->permitted_remote_opens;                  cppptr = &options->permitted_remote_opens;
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0')                  if (!arg || *arg == '\0')
                         fatal("%s line %d: missing %s specification",                          fatal("%s line %d: missing %s specification",
                             filename, linenum, lookup_opcode_name(opcode));                              filename, linenum, lookup_opcode_name(opcode));
Line 1487 
Line 1551 
                         }                          }
                         break;                          break;
                 }                  }
                 for (; arg != NULL && *arg != '\0'; arg = strdelim(&s)) {                  while ((arg = argv_next(&ac, &av)) != NULL) {
                         arg2 = xstrdup(arg);                          arg2 = xstrdup(arg);
                         ch = '\0';                          ch = '\0';
                         p = hpdelim2(&arg, &ch);                          p = hpdelim2(&arg, &ch);
Line 1524 
Line 1588 
                 if (cmdline) {                  if (cmdline) {
                         error("Host directive not supported as a command-line "                          error("Host directive not supported as a command-line "
                             "option");                              "option");
                         return -1;                          goto out;
                 }                  }
                 *activep = 0;                  *activep = 0;
                 arg2 = NULL;                  arg2 = NULL;
                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {                  while ((arg = argv_next(&ac, &av)) != NULL) {
                         if ((flags & SSHCONF_NEVERMATCH) != 0)                          if (*arg == '\0') {
                                   error("%s line %d: keyword %s empty argument",
                                       filename, linenum, keyword);
                                   goto out;
                           }
                           if ((flags & SSHCONF_NEVERMATCH) != 0) {
                                   argv_consume(&ac);
                                 break;                                  break;
                           }
                         negated = *arg == '!';                          negated = *arg == '!';
                         if (negated)                          if (negated)
                                 arg++;                                  arg++;
Line 1541 
Line 1612 
                                             "for %.100s", filename, linenum,                                              "for %.100s", filename, linenum,
                                             arg);                                              arg);
                                         *activep = 0;                                          *activep = 0;
                                           argv_consume(&ac);
                                         break;                                          break;
                                 }                                  }
                                 if (!*activep)                                  if (!*activep)
Line 1551 
Line 1623 
                 if (*activep)                  if (*activep)
                         debug("%.200s line %d: Applying options for %.100s",                          debug("%.200s line %d: Applying options for %.100s",
                             filename, linenum, arg2);                              filename, linenum, arg2);
                 /* Avoid garbage check below, as strdelim is done. */                  break;
                 return 0;  
   
         case oMatch:          case oMatch:
                 if (cmdline) {                  if (cmdline) {
                         error("Host directive not supported as a command-line "                          error("Host directive not supported as a command-line "
                             "option");                              "option");
                         return -1;                          goto out;
                 }                  }
                 value = match_cfg_line(options, &s, pw, host, original_host,                  value = match_cfg_line(options, &str, pw, host, original_host,
                     flags & SSHCONF_FINAL, want_final_pass,                      flags & SSHCONF_FINAL, want_final_pass,
                     filename, linenum);                      filename, linenum);
                 if (value < 0) {                  if (value < 0) {
                         error("%.200s line %d: Bad Match condition", filename,                          error("%.200s line %d: Bad Match condition", filename,
                             linenum);                              linenum);
                         return -1;                          goto out;
                 }                  }
                 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;                  *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
                   /*
                    * If match_cfg_line() didn't consume all its arguments then
                    * arrange for the extra arguments check below to fail.
                    */
   
                   if (str == NULL || *str == '\0')
                           argv_consume(&ac);
                 break;                  break;
   
         case oEscapeChar:          case oEscapeChar:
                 intptr = &options->escape_char;                  intptr = &options->escape_char;
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (strcmp(arg, "none") == 0)                  if (strcmp(arg, "none") == 0)
                         value = SSH_ESCAPECHAR_NONE;                          value = SSH_ESCAPECHAR_NONE;
Line 1589 
Line 1667 
                 else {                  else {
                         error("%.200s line %d: Bad escape character.",                          error("%.200s line %d: Bad escape character.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *intptr == -1)                  if (*activep && *intptr == -1)
                         *intptr = value;                          *intptr = value;
Line 1617 
Line 1695 
                 goto parse_int;                  goto parse_int;
   
         case oSendEnv:          case oSendEnv:
                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {                  while ((arg = argv_next(&ac, &av)) != NULL) {
                         if (strchr(arg, '=') != NULL) {                          if (*arg == '\0' || strchr(arg, '=') != NULL) {
                                 error("%s line %d: Invalid environment name.",                                  error("%s line %d: Invalid environment name.",
                                     filename, linenum);                                      filename, linenum);
                                 return -1;                                  goto out;
                         }                          }
                         if (!*activep)                          if (!*activep)
                                 continue;                                  continue;
Line 1634 
Line 1712 
                                 if (options->num_send_env >= INT_MAX) {                                  if (options->num_send_env >= INT_MAX) {
                                         error("%s line %d: too many send env.",                                          error("%s line %d: too many send env.",
                                             filename, linenum);                                              filename, linenum);
                                         return -1;                                          goto out;
                                 }                                  }
                                 options->send_env = xrecallocarray(                                  options->send_env = xrecallocarray(
                                     options->send_env, options->num_send_env,                                      options->send_env, options->num_send_env,
Line 1648 
Line 1726 
   
         case oSetEnv:          case oSetEnv:
                 value = options->num_setenv;                  value = options->num_setenv;
                 while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {                  while ((arg = argv_next(&ac, &av)) != NULL) {
                         if (strchr(arg, '=') == NULL) {                          if (strchr(arg, '=') == NULL) {
                                 error("%s line %d: Invalid SetEnv.",                                  error("%s line %d: Invalid SetEnv.",
                                     filename, linenum);                                      filename, linenum);
                                 return -1;                                  goto out;
                         }                          }
                         if (!*activep || value != 0)                          if (!*activep || value != 0)
                                 continue;                                  continue;
Line 1660 
Line 1738 
                         if (options->num_setenv >= INT_MAX) {                          if (options->num_setenv >= INT_MAX) {
                                 error("%s line %d: too many SetEnv.",                                  error("%s line %d: too many SetEnv.",
                                     filename, linenum);                                      filename, linenum);
                                 return -1;                                  goto out;
                         }                          }
                         options->setenv = xrecallocarray(                          options->setenv = xrecallocarray(
                             options->setenv, options->num_setenv,                              options->setenv, options->num_setenv,
Line 1681 
Line 1759 
         case oControlPersist:          case oControlPersist:
                 /* no/false/yes/true, or a time spec */                  /* no/false/yes/true, or a time spec */
                 intptr = &options->control_persist;                  intptr = &options->control_persist;
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing ControlPersist"                          error("%.200s line %d: Missing ControlPersist"
                             " argument.", filename, linenum);                              " argument.", filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 value = 0;                  value = 0;
                 value2 = 0;     /* timeout */                  value2 = 0;     /* timeout */
Line 1698 
Line 1776 
                 else {                  else {
                         error("%.200s line %d: Bad ControlPersist argument.",                          error("%.200s line %d: Bad ControlPersist argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *intptr == -1) {                  if (*activep && *intptr == -1) {
                         *intptr = value;                          *intptr = value;
Line 1716 
Line 1794 
                 goto parse_multistate;                  goto parse_multistate;
   
         case oTunnelDevice:          case oTunnelDevice:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 value = a2tun(arg, &value2);                  value = a2tun(arg, &value2);
                 if (value == SSH_TUNID_ERR) {                  if (value == SSH_TUNID_ERR) {
                         error("%.200s line %d: Bad tun device.",                          error("%.200s line %d: Bad tun device.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && options->tun_local == -1) {                  if (*activep && options->tun_local == -1) {
                         options->tun_local = value;                          options->tun_local = value;
Line 1754 
Line 1832 
                 if (cmdline) {                  if (cmdline) {
                         error("Include directive not supported as a "                          error("Include directive not supported as a "
                             "command-line option");                              "command-line option");
                         return -1;                          goto out;
                 }                  }
                 value = 0;                  value = 0;
                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {                  while ((arg = argv_next(&ac, &av)) != NULL) {
                           if (*arg == '\0') {
                                   error("%s line %d: keyword %s empty argument",
                                       filename, linenum, keyword);
                                   goto out;
                           }
                         /*                          /*
                          * Ensure all paths are anchored. User configuration                           * Ensure all paths are anchored. User configuration
                          * files may begin with '~/' but system configurations                           * files may begin with '~/' but system configurations
Line 1768 
Line 1851 
                         if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) {                          if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) {
                                 error("%.200s line %d: bad include path %s.",                                  error("%.200s line %d: bad include path %s.",
                                     filename, linenum, arg);                                      filename, linenum, arg);
                                 return -1;                                  goto out;
                         }                          }
                         if (!path_absolute(arg) && *arg != '~') {                          if (!path_absolute(arg) && *arg != '~') {
                                 xasprintf(&arg2, "%s/%s",                                  xasprintf(&arg2, "%s/%s",
Line 1786 
Line 1869 
                         } else if (r != 0) {                          } else if (r != 0) {
                                 error("%.200s line %d: glob failed for %s.",                                  error("%.200s line %d: glob failed for %s.",
                                     filename, linenum, arg2);                                      filename, linenum, arg2);
                                 return -1;                                  goto out;
                         }                          }
                         free(arg2);                          free(arg2);
                         oactive = *activep;                          oactive = *activep;
Line 1805 
Line 1888 
                                             "%.100s: %.100s", gl.gl_pathv[i],                                              "%.100s: %.100s", gl.gl_pathv[i],
                                             strerror(errno));                                              strerror(errno));
                                         globfree(&gl);                                          globfree(&gl);
                                         return -1;                                          goto out;
                                 }                                  }
                                 /*                                  /*
                                  * don't let Match in includes clobber the                                   * don't let Match in includes clobber the
Line 1818 
Line 1901 
                         globfree(&gl);                          globfree(&gl);
                 }                  }
                 if (value != 0)                  if (value != 0)
                         return value;                          ret = value;
                 break;                  break;
   
         case oIPQoS:          case oIPQoS:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if ((value = parse_ipqos(arg)) == -1) {                  if ((value = parse_ipqos(arg)) == -1) {
                         error("%s line %d: Bad IPQoS value: %s",                          error("%s line %d: Bad IPQoS value: %s",
                             filename, linenum, arg);                              filename, linenum, arg);
                         return -1;                          goto out;
                 }                  }
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (arg == NULL)                  if (arg == NULL)
                         value2 = value;                          value2 = value;
                 else if ((value2 = parse_ipqos(arg)) == -1) {                  else if ((value2 = parse_ipqos(arg)) == -1) {
                         error("%s line %d: Bad IPQoS value: %s",                          error("%s line %d: Bad IPQoS value: %s",
                             filename, linenum, arg);                              filename, linenum, arg);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && options->ip_qos_interactive == -1) {                  if (*activep && options->ip_qos_interactive == -1) {
                         options->ip_qos_interactive = value;                          options->ip_qos_interactive = value;
Line 1857 
Line 1940 
   
         case oCanonicalDomains:          case oCanonicalDomains:
                 value = options->num_canonical_domains != 0;                  value = options->num_canonical_domains != 0;
                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {                  i = 0;
                   while ((arg = argv_next(&ac, &av)) != NULL) {
                           if (*arg == '\0') {
                                   error("%s line %d: keyword %s empty argument",
                                       filename, linenum, keyword);
                                   goto out;
                           }
                           /* Allow "none" only in first position */
                           if (strcasecmp(arg, "none") == 0) {
                                   if (i > 0 || ac > 0) {
                                           error("%s line %d: keyword %s \"none\" "
                                               "argument must appear alone.",
                                               filename, linenum, keyword);
                                           goto out;
                                   }
                           }
                           i++;
                         if (!valid_domain(arg, 1, &errstr)) {                          if (!valid_domain(arg, 1, &errstr)) {
                                 error("%s line %d: %s", filename, linenum,                                  error("%s line %d: %s", filename, linenum,
                                     errstr);                                      errstr);
                                 return -1;                                  goto out;
                         }                          }
                         if (!*activep || value)                          if (!*activep || value)
                                 continue;                                  continue;
Line 1869 
Line 1968 
                             MAX_CANON_DOMAINS) {                              MAX_CANON_DOMAINS) {
                                 error("%s line %d: too many hostname suffixes.",                                  error("%s line %d: too many hostname suffixes.",
                                     filename, linenum);                                      filename, linenum);
                                 return -1;                                  goto out;
                         }                          }
                         options->canonical_domains[                          options->canonical_domains[
                             options->num_canonical_domains++] = xstrdup(arg);                              options->num_canonical_domains++] = xstrdup(arg);
Line 1878 
Line 1977 
   
         case oCanonicalizePermittedCNAMEs:          case oCanonicalizePermittedCNAMEs:
                 value = options->num_permitted_cnames != 0;                  value = options->num_permitted_cnames != 0;
                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {                  while ((arg = argv_next(&ac, &av)) != NULL) {
                         /* Either '*' for everything or 'list:list' */                          /* Either '*' for everything or 'list:list' */
                         if (strcmp(arg, "*") == 0)                          if (strcmp(arg, "*") == 0)
                                 arg2 = arg;                                  arg2 = arg;
Line 1889 
Line 1988 
                                         error("%s line %d: "                                          error("%s line %d: "
                                             "Invalid permitted CNAME \"%s\"",                                              "Invalid permitted CNAME \"%s\"",
                                             filename, linenum, arg);                                              filename, linenum, arg);
                                         return -1;                                          goto out;
                                 }                                  }
                                 *arg2 = '\0';                                  *arg2 = '\0';
                                 arg2++;                                  arg2++;
Line 1900 
Line 1999 
                             MAX_CANON_DOMAINS) {                              MAX_CANON_DOMAINS) {
                                 error("%s line %d: too many permitted CNAMEs.",                                  error("%s line %d: too many permitted CNAMEs.",
                                     filename, linenum);                                      filename, linenum);
                                 return -1;                                  goto out;
                         }                          }
                         cname = options->permitted_cnames +                          cname = options->permitted_cnames +
                             options->num_permitted_cnames++;                              options->num_permitted_cnames++;
Line 1923 
Line 2022 
                 goto parse_flag;                  goto parse_flag;
   
         case oStreamLocalBindMask:          case oStreamLocalBindMask:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing StreamLocalBindMask "                          error("%.200s line %d: Missing StreamLocalBindMask "
                             "argument.", filename, linenum);                              "argument.", filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 /* Parse mode in octal format */                  /* Parse mode in octal format */
                 value = strtol(arg, &endofnumber, 8);                  value = strtol(arg, &endofnumber, 8);
                 if (arg == endofnumber || value < 0 || value > 0777) {                  if (arg == endofnumber || value < 0 || value > 0777) {
                         error("%.200s line %d: Bad mask.", filename, linenum);                          error("%.200s line %d: Bad mask.", filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;                  options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
                 break;                  break;
Line 1948 
Line 2047 
   
         case oFingerprintHash:          case oFingerprintHash:
                 intptr = &options->fingerprint_hash;                  intptr = &options->fingerprint_hash;
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if ((value = ssh_digest_alg_by_name(arg)) == -1) {                  if ((value = ssh_digest_alg_by_name(arg)) == -1) {
                         error("%.200s line %d: Invalid hash algorithm \"%s\".",                          error("%.200s line %d: Invalid hash algorithm \"%s\".",
                             filename, linenum, arg);                              filename, linenum, arg);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *intptr == -1)                  if (*activep && *intptr == -1)
                         *intptr = value;                          *intptr = value;
Line 1977 
Line 2076 
                 goto parse_pubkey_algos;                  goto parse_pubkey_algos;
   
         case oAddKeysToAgent:          case oAddKeysToAgent:
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 arg2 = strdelim(&s);                  arg2 = argv_next(&ac, &av);
                 value = parse_multistate_value(arg, filename, linenum,                  value = parse_multistate_value(arg, filename, linenum,
                     multistate_yesnoaskconfirm);                      multistate_yesnoaskconfirm);
                 value2 = 0; /* unlimited lifespan by default */                  value2 = 0; /* unlimited lifespan by default */
Line 1988 
Line 2087 
                             value2 > INT_MAX) {                              value2 > INT_MAX) {
                                 error("%s line %d: invalid time value.",                                  error("%s line %d: invalid time value.",
                                     filename, linenum);                                      filename, linenum);
                                 return -1;                                  goto out;
                         }                          }
                 } else if (value == -1 && arg2 == NULL) {                  } else if (value == -1 && arg2 == NULL) {
                         if ((value2 = convtime(arg)) == -1 ||                          if ((value2 = convtime(arg)) == -1 ||
                             value2 > INT_MAX) {                              value2 > INT_MAX) {
                                 error("%s line %d: unsupported option",                                  error("%s line %d: unsupported option",
                                     filename, linenum);                                      filename, linenum);
                                 return -1;                                  goto out;
                         }                          }
                         value = 1; /* yes */                          value = 1; /* yes */
                 } else if (value == -1 || arg2 != NULL) {                  } else if (value == -1 || arg2 != NULL) {
                         error("%s line %d: unsupported option",                          error("%s line %d: unsupported option",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && options->add_keys_to_agent == -1) {                  if (*activep && options->add_keys_to_agent == -1) {
                         options->add_keys_to_agent = value;                          options->add_keys_to_agent = value;
Line 2011 
Line 2110 
   
         case oIdentityAgent:          case oIdentityAgent:
                 charptr = &options->identity_agent;                  charptr = &options->identity_agent;
                 arg = strdelim(&s);                  arg = argv_next(&ac, &av);
                 if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0') {
                         error("%.200s line %d: Missing argument.",                          error("%.200s line %d: Missing argument.",
                             filename, linenum);                              filename, linenum);
                         return -1;                          goto out;
                 }                  }
   parse_agent_path:    parse_agent_path:
                 /* Extra validation if the string represents an env var. */                  /* Extra validation if the string represents an env var. */
                 if ((arg2 = dollar_expand(&r, arg)) == NULL || r) {                  if ((arg2 = dollar_expand(&r, arg)) == NULL || r) {
                         error("%.200s line %d: Invalid environment expansion "                          error("%.200s line %d: Invalid environment expansion "
                             "%s.", filename, linenum, arg);                              "%s.", filename, linenum, arg);
                         return -1;                          goto out;
                 }                  }
                 free(arg2);                  free(arg2);
                 /* check for legacy environment format */                  /* check for legacy environment format */
Line 2030 
Line 2129 
                     !valid_env_name(arg + 1)) {                      !valid_env_name(arg + 1)) {
                         error("%.200s line %d: Invalid environment name %s.",                          error("%.200s line %d: Invalid environment name %s.",
                             filename, linenum, arg);                              filename, linenum, arg);
                         return -1;                          goto out;
                 }                  }
                 if (*activep && *charptr == NULL)                  if (*activep && *charptr == NULL)
                         *charptr = xstrdup(arg);                          *charptr = xstrdup(arg);
Line 2039 
Line 2138 
         case oDeprecated:          case oDeprecated:
                 debug("%s line %d: Deprecated option \"%s\"",                  debug("%s line %d: Deprecated option \"%s\"",
                     filename, linenum, keyword);                      filename, linenum, keyword);
                 return 0;                  argv_consume(&ac);
                   break;
   
         case oUnsupported:          case oUnsupported:
                 error("%s line %d: Unsupported option \"%s\"",                  error("%s line %d: Unsupported option \"%s\"",
                     filename, linenum, keyword);                      filename, linenum, keyword);
                 return 0;                  argv_consume(&ac);
                   break;
   
         default:          default:
                 error("%s line %d: Unimplemented opcode %d",                  error("%s line %d: Unimplemented opcode %d",
                     filename, linenum, opcode);                      filename, linenum, opcode);
                   goto out;
         }          }
   
         /* Check that there is no garbage at end of line. */          /* Check that there is no garbage at end of line. */
         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {          if (ac > 0) {
                 error("%.200s line %d: garbage at end of line; \"%.200s\".",                  error("%.200s line %d: keyword %s extra arguments "
                     filename, linenum, arg);                      "at end of line", filename, linenum, keyword);
                 return -1;                  goto out;
         }          }
         return 0;  
           /* success */
           ret = 0;
    out:
           argv_free(oav, oac);
           return ret;
 }  }
   
 /*  /*
Line 2083 
Line 2190 
     int flags, int *activep, int *want_final_pass, int depth)      int flags, int *activep, int *want_final_pass, int depth)
 {  {
         FILE *f;          FILE *f;
         char *cp, *line = NULL;          char *line = NULL;
         size_t linesize = 0;          size_t linesize = 0;
         int linenum;          int linenum;
         int bad_options = 0;          int bad_options = 0;
Line 2119 
Line 2226 
                  * NB - preserve newlines, they are needed to reproduce                   * NB - preserve newlines, they are needed to reproduce
                  * line numbers later for error messages.                   * line numbers later for error messages.
                  */                   */
                 if ((cp = strchr(line, '#')) != NULL)  
                         *cp = '\0';  
                 if (process_config_line_depth(options, pw, host, original_host,                  if (process_config_line_depth(options, pw, host, original_host,
                     line, filename, linenum, activep, flags, want_final_pass,                      line, filename, linenum, activep, flags, want_final_pass,
                     depth) != 0)                      depth) != 0)
Line 2791 
Line 2896 
         if (fwd->connect_host != NULL &&          if (fwd->connect_host != NULL &&
             strlen(fwd->connect_host) >= NI_MAXHOST)              strlen(fwd->connect_host) >= NI_MAXHOST)
                 goto fail_free;                  goto fail_free;
         /* XXX - if connecting to a remote socket, max sun len may not match this host */          /*
            * XXX - if connecting to a remote socket, max sun len may not
            * match this host
            */
         if (fwd->connect_path != NULL &&          if (fwd->connect_path != NULL &&
             strlen(fwd->connect_path) >= PATH_MAX_SUN)              strlen(fwd->connect_path) >= PATH_MAX_SUN)
                 goto fail_free;                  goto fail_free;
Line 2826 
Line 2934 
         active &= o->proxy_command == NULL && o->jump_host == NULL;          active &= o->proxy_command == NULL && o->jump_host == NULL;
   
         orig = sdup = xstrdup(s);          orig = sdup = xstrdup(s);
   
           /* Remove comment and trailing whitespace */
           if ((cp = strchr(orig, '#')) != NULL)
                   *cp = '\0';
           rtrim(orig);
   
         first = active;          first = active;
         do {          do {
                 if (strcasecmp(s, "none") == 0)                  if (strcasecmp(s, "none") == 0)
Line 2998 
Line 3112 
         u_int i;          u_int i;
   
         printf("%s", lookup_opcode_name(code));          printf("%s", lookup_opcode_name(code));
           if (count == 0)
                   printf(" none");
         for (i = 0; i < count; i++)          for (i = 0; i < count; i++)
                 printf(" %s",  vals[i]);                  printf(" %s",  vals[i]);
         printf("\n");          printf("\n");

Legend:
Removed from v.1.355  
changed lines
  Added in v.1.356