[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.16 and 1.17

version 1.16, 1999/11/22 21:52:41 version 1.17, 1999/11/23 22:25:54
Line 86 
Line 86 
   
 /* Keyword tokens. */  /* Keyword tokens. */
   
 typedef enum  typedef enum {
 {          oBadOption,
   oBadOption,          oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
   oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,          oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
   oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,          oSkeyAuthentication,
   oSkeyAuthentication,  
 #ifdef KRB4  #ifdef KRB4
   oKerberosAuthentication,          oKerberosAuthentication,
 #endif /* KRB4 */  #endif /* KRB4 */
 #ifdef AFS  #ifdef AFS
   oKerberosTgtPassing, oAFSTokenPassing,          oKerberosTgtPassing, oAFSTokenPassing,
 #endif  #endif
   oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,          oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
   oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,          oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
   oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,          oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
   oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,          oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
   oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,          oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
   oUsePrivilegedPort, oLogLevel          oUsePrivilegedPort, oLogLevel
 } OpCodes;  } OpCodes;
   
 /* Textual representations of the tokens. */  /* Textual representations of the tokens. */
   
 static struct  static struct {
 {          const char *name;
   const char *name;          OpCodes opcode;
   OpCodes opcode;  } keywords[] = {
 } keywords[] =          { "forwardagent", oForwardAgent },
 {          { "forwardx11", oForwardX11 },
   { "forwardagent", oForwardAgent },          { "gatewayports", oGatewayPorts },
   { "forwardx11", oForwardX11 },          { "useprivilegedport", oUsePrivilegedPort },
   { "gatewayports", oGatewayPorts },          { "rhostsauthentication", oRhostsAuthentication },
   { "useprivilegedport", oUsePrivilegedPort },          { "passwordauthentication", oPasswordAuthentication },
   { "rhostsauthentication", oRhostsAuthentication },          { "rsaauthentication", oRSAAuthentication },
   { "passwordauthentication", oPasswordAuthentication },          { "skeyauthentication", oSkeyAuthentication },
   { "rsaauthentication", oRSAAuthentication },  
   { "skeyauthentication", oSkeyAuthentication },  
 #ifdef KRB4  #ifdef KRB4
   { "kerberosauthentication", oKerberosAuthentication },          { "kerberosauthentication", oKerberosAuthentication },
 #endif /* KRB4 */  #endif /* KRB4 */
 #ifdef AFS  #ifdef AFS
   { "kerberostgtpassing", oKerberosTgtPassing },          { "kerberostgtpassing", oKerberosTgtPassing },
   { "afstokenpassing", oAFSTokenPassing },          { "afstokenpassing", oAFSTokenPassing },
 #endif  #endif
   { "fallbacktorsh", oFallBackToRsh },          { "fallbacktorsh", oFallBackToRsh },
   { "usersh", oUseRsh },          { "usersh", oUseRsh },
   { "identityfile", oIdentityFile },          { "identityfile", oIdentityFile },
   { "hostname", oHostName },          { "hostname", oHostName },
   { "proxycommand", oProxyCommand },          { "proxycommand", oProxyCommand },
   { "port", oPort },          { "port", oPort },
   { "cipher", oCipher },          { "cipher", oCipher },
   { "remoteforward", oRemoteForward },          { "remoteforward", oRemoteForward },
   { "localforward", oLocalForward },          { "localforward", oLocalForward },
   { "user", oUser },          { "user", oUser },
   { "host", oHost },          { "host", oHost },
   { "escapechar", oEscapeChar },          { "escapechar", oEscapeChar },
   { "rhostsrsaauthentication", oRhostsRSAAuthentication },          { "rhostsrsaauthentication", oRhostsRSAAuthentication },
   { "globalknownhostsfile", oGlobalKnownHostsFile },          { "globalknownhostsfile", oGlobalKnownHostsFile },
   { "userknownhostsfile", oUserKnownHostsFile },          { "userknownhostsfile", oUserKnownHostsFile },
   { "connectionattempts", oConnectionAttempts },          { "connectionattempts", oConnectionAttempts },
   { "batchmode", oBatchMode },          { "batchmode", oBatchMode },
   { "checkhostip", oCheckHostIP },          { "checkhostip", oCheckHostIP },
   { "stricthostkeychecking", oStrictHostKeyChecking },          { "stricthostkeychecking", oStrictHostKeyChecking },
   { "compression", oCompression },          { "compression", oCompression },
   { "compressionlevel", oCompressionLevel },          { "compressionlevel", oCompressionLevel },
   { "keepalive", oKeepAlives },          { "keepalive", oKeepAlives },
   { "numberofpasswordprompts", oNumberOfPasswordPrompts },          { "numberofpasswordprompts", oNumberOfPasswordPrompts },
   { "tisauthentication", oTISAuthentication },          { "tisauthentication", oTISAuthentication },
   { "loglevel", oLogLevel },          { "loglevel", oLogLevel },
   { NULL, 0 }          { NULL, 0 }
 };  };
   
 /* Characters considered whitespace in strtok calls. */  /* Characters considered whitespace in strtok calls. */
Line 164 
Line 161 
 /* Adds a local TCP/IP port forward to options.  Never returns if there  /* Adds a local TCP/IP port forward to options.  Never returns if there
    is an error. */     is an error. */
   
 void add_local_forward(Options *options, int port, const char *host,  void
                        int host_port)  add_local_forward(Options *options, int port, const char *host,
                     int host_port)
 {  {
   Forward *fwd;          Forward *fwd;
   extern uid_t original_real_uid;          extern uid_t original_real_uid;
   if ((port & 0xffff) != port)          if ((port & 0xffff) != port)
     fatal("Requested forwarding of nonexistent port %d.", port);                  fatal("Requested forwarding of nonexistent port %d.", port);
   if (port < IPPORT_RESERVED && original_real_uid != 0)          if (port < IPPORT_RESERVED && original_real_uid != 0)
     fatal("Privileged ports can only be forwarded by root.\n");                  fatal("Privileged ports can only be forwarded by root.\n");
   if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)          if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
     fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);                  fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
   fwd = &options->local_forwards[options->num_local_forwards++];          fwd = &options->local_forwards[options->num_local_forwards++];
   fwd->port = port;          fwd->port = port;
   fwd->host = xstrdup(host);          fwd->host = xstrdup(host);
   fwd->host_port = host_port;          fwd->host_port = host_port;
 }  }
   
 /* Adds a remote TCP/IP port forward to options.  Never returns if there  /* Adds a remote TCP/IP port forward to options.  Never returns if there
    is an error. */     is an error. */
   
 void add_remote_forward(Options *options, int port, const char *host,  void
                        int host_port)  add_remote_forward(Options *options, int port, const char *host,
                      int host_port)
 {  {
   Forward *fwd;          Forward *fwd;
   if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)          if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
     fatal("Too many remote forwards (max %d).",                  fatal("Too many remote forwards (max %d).",
           SSH_MAX_FORWARDS_PER_DIRECTION);                        SSH_MAX_FORWARDS_PER_DIRECTION);
   fwd = &options->remote_forwards[options->num_remote_forwards++];          fwd = &options->remote_forwards[options->num_remote_forwards++];
   fwd->port = port;          fwd->port = port;
   fwd->host = xstrdup(host);          fwd->host = xstrdup(host);
   fwd->host_port = host_port;          fwd->host_port = host_port;
 }  }
   
 /* Returns the number of the token pointed to by cp of length len.  /* Returns the number of the token pointed to by cp of length len.
    Never returns if the token is not known. */     Never returns if the token is not known. */
   
 static OpCodes parse_token(const char *cp, const char *filename, int linenum)  static OpCodes
   parse_token(const char *cp, const char *filename, int linenum)
 {  {
   unsigned int i;          unsigned int i;
   
   for (i = 0; keywords[i].name; i++)          for (i = 0; keywords[i].name; i++)
     if (strcmp(cp, keywords[i].name) == 0)                  if (strcmp(cp, keywords[i].name) == 0)
       return keywords[i].opcode;                          return keywords[i].opcode;
   
   fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",          fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
           filename, linenum, cp);                  filename, linenum, cp);
   return oBadOption;          return oBadOption;
 }  }
   
 /* Processes a single option line as used in the configuration files.  /* Processes a single option line as used in the configuration files.
Line 218 
Line 218 
   
 int  int
 process_config_line(Options *options, const char *host,  process_config_line(Options *options, const char *host,
                          char *line, const char *filename, int linenum,                      char *line, const char *filename, int linenum,
                          int *activep)                      int *activep)
 {  {
   char buf[256], *cp, *string, **charptr;          char buf[256], *cp, *string, **charptr;
   int opcode, *intptr, value, fwd_port, fwd_host_port;          int opcode, *intptr, value, fwd_port, fwd_host_port;
   
   /* Skip leading whitespace. */          /* Skip leading whitespace. */
   cp = line + strspn(line, WHITESPACE);          cp = line + strspn(line, WHITESPACE);
   if (!*cp || *cp == '\n' || *cp == '#')          if (!*cp || *cp == '\n' || *cp == '#')
     return 0;                  return 0;
   
   /* Get the keyword. (Each line is supposed to begin with a keyword). */          /* Get the keyword. (Each line is supposed to begin with a
   cp = strtok(cp, WHITESPACE);             keyword). */
   {          cp = strtok(cp, WHITESPACE);
     char *t = cp;          {
     for (; *t != 0; t++)                  char *t = cp;
       if ('A' <= *t && *t <= 'Z')                  for (; *t != 0; t++)
         *t = *t - 'A' + 'a';    /* tolower */                          if ('A' <= *t && *t <= 'Z')
                                   *t = *t - 'A' + 'a';    /* tolower */
   }  
   opcode = parse_token(cp, filename, linenum);  
   
   switch (opcode)          }
     {          opcode = parse_token(cp, filename, linenum);
     case oBadOption:  
       return -1;                /* don't panic, but count bad options */  
       /*NOTREACHED*/  
     case oForwardAgent:  
       intptr = &options->forward_agent;  
     parse_flag:  
       cp = strtok(NULL, WHITESPACE);  
       if (!cp)  
         fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);  
       value = 0; /* To avoid compiler warning... */  
       if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)  
         value = 1;  
       else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)  
         value = 0;  
       else  
         fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);  
       if (*activep && *intptr == -1)  
         *intptr = value;  
       break;  
   
     case oForwardX11:  
       intptr = &options->forward_x11;  
       goto parse_flag;  
   
     case oGatewayPorts:          switch (opcode) {
       intptr = &options->gateway_ports;          case oBadOption:
       goto parse_flag;                  return -1;      /* don't panic, but count bad options */
                   /* NOTREACHED */
     case oUsePrivilegedPort:          case oForwardAgent:
       intptr = &options->use_privileged_port;                  intptr = &options->forward_agent;
       goto parse_flag;  parse_flag:
                   cp = strtok(NULL, WHITESPACE);
     case oRhostsAuthentication:                  if (!cp)
       intptr = &options->rhosts_authentication;                          fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
       goto parse_flag;                  value = 0;      /* To avoid compiler warning... */
                   if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
     case oPasswordAuthentication:                          value = 1;
       intptr = &options->password_authentication;                  else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
       goto parse_flag;                          value = 0;
                   else
     case oRSAAuthentication:                          fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
       intptr = &options->rsa_authentication;                  if (*activep && *intptr == -1)
       goto parse_flag;                          *intptr = value;
                   break;
     case oRhostsRSAAuthentication:  
       intptr = &options->rhosts_rsa_authentication;  
       goto parse_flag;  
   
     case oTISAuthentication:          case oForwardX11:
       /* fallthrough, there is no difference on the client side */                  intptr = &options->forward_x11;
     case oSkeyAuthentication:                  goto parse_flag;
       intptr = &options->skey_authentication;  
       goto parse_flag;  
   
           case oGatewayPorts:
                   intptr = &options->gateway_ports;
                   goto parse_flag;
   
           case oUsePrivilegedPort:
                   intptr = &options->use_privileged_port;
                   goto parse_flag;
   
           case oRhostsAuthentication:
                   intptr = &options->rhosts_authentication;
                   goto parse_flag;
   
           case oPasswordAuthentication:
                   intptr = &options->password_authentication;
                   goto parse_flag;
   
           case oRSAAuthentication:
                   intptr = &options->rsa_authentication;
                   goto parse_flag;
   
           case oRhostsRSAAuthentication:
                   intptr = &options->rhosts_rsa_authentication;
                   goto parse_flag;
   
           case oTISAuthentication:
                   /* fallthrough, there is no difference on the client side */
           case oSkeyAuthentication:
                   intptr = &options->skey_authentication;
                   goto parse_flag;
   
 #ifdef KRB4  #ifdef KRB4
     case oKerberosAuthentication:          case oKerberosAuthentication:
       intptr = &options->kerberos_authentication;                  intptr = &options->kerberos_authentication;
       goto parse_flag;                  goto parse_flag;
 #endif /* KRB4 */  #endif /* KRB4 */
   
 #ifdef AFS  #ifdef AFS
     case oKerberosTgtPassing:          case oKerberosTgtPassing:
       intptr = &options->kerberos_tgt_passing;                  intptr = &options->kerberos_tgt_passing;
       goto parse_flag;                  goto parse_flag;
   
     case oAFSTokenPassing:          case oAFSTokenPassing:
       intptr = &options->afs_token_passing;                  intptr = &options->afs_token_passing;
       goto parse_flag;                  goto parse_flag;
 #endif  #endif
   
     case oFallBackToRsh:  
       intptr = &options->fallback_to_rsh;  
       goto parse_flag;  
   
     case oUseRsh:  
       intptr = &options->use_rsh;  
       goto parse_flag;  
   
     case oBatchMode:          case oFallBackToRsh:
       intptr = &options->batch_mode;                  intptr = &options->fallback_to_rsh;
       goto parse_flag;                  goto parse_flag;
   
     case oCheckHostIP:          case oUseRsh:
       intptr = &options->check_host_ip;                  intptr = &options->use_rsh;
       goto parse_flag;                  goto parse_flag;
   
     case oStrictHostKeyChecking:          case oBatchMode:
       intptr = &options->strict_host_key_checking;                  intptr = &options->batch_mode;
       cp = strtok(NULL, WHITESPACE);                  goto parse_flag;
       if (!cp)  
         fatal("%.200s line %d: Missing yes/no argument.",  
               filename, linenum);  
       value = 0; /* To avoid compiler warning... */  
       if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)  
         value = 1;  
       else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)  
         value = 0;  
       else if (strcmp(cp, "ask") == 0)  
         value = 2;  
       else  
         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);  
       if (*activep && *intptr == -1)  
         *intptr = value;  
       break;  
   
     case oCompression:  
       intptr = &options->compression;  
       goto parse_flag;  
   
     case oKeepAlives:          case oCheckHostIP:
       intptr = &options->keepalives;                  intptr = &options->check_host_ip;
       goto parse_flag;                  goto parse_flag;
   
     case oNumberOfPasswordPrompts:          case oStrictHostKeyChecking:
       intptr = &options->number_of_password_prompts;                  intptr = &options->strict_host_key_checking;
       goto parse_int;                  cp = strtok(NULL, WHITESPACE);
                   if (!cp)
                           fatal("%.200s line %d: Missing yes/no argument.",
                                 filename, linenum);
                   value = 0;      /* To avoid compiler warning... */
                   if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
                           value = 1;
                   else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
                           value = 0;
                   else if (strcmp(cp, "ask") == 0)
                           value = 2;
                   else
                           fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
                   if (*activep && *intptr == -1)
                           *intptr = value;
                   break;
   
     case oCompressionLevel:          case oCompression:
       intptr = &options->compression_level;                  intptr = &options->compression;
       goto parse_int;                  goto parse_flag;
   
     case oIdentityFile:          case oKeepAlives:
       cp = strtok(NULL, WHITESPACE);                  intptr = &options->keepalives;
       if (!cp)                  goto parse_flag;
         fatal("%.200s line %d: Missing argument.", filename, linenum);  
       if (*activep)  
         {  
           if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)  
             fatal("%.200s line %d: Too many identity files specified (max %d).",  
                   filename, linenum, SSH_MAX_IDENTITY_FILES);  
           options->identity_files[options->num_identity_files++] = xstrdup(cp);  
         }  
       break;  
   
     case oUser:  
       charptr = &options->user;  
     parse_string:  
       cp = strtok(NULL, WHITESPACE);  
       if (!cp)  
         fatal("%.200s line %d: Missing argument.", filename, linenum);  
       if (*activep && *charptr == NULL)  
         *charptr = xstrdup(cp);  
       break;  
   
     case oGlobalKnownHostsFile:  
       charptr = &options->system_hostfile;  
       goto parse_string;  
   
     case oUserKnownHostsFile:  
       charptr = &options->user_hostfile;  
       goto parse_string;  
   
     case oHostName:          case oNumberOfPasswordPrompts:
       charptr = &options->hostname;                  intptr = &options->number_of_password_prompts;
       goto parse_string;                  goto parse_int;
   
     case oProxyCommand:  
       charptr = &options->proxy_command;  
       string = xstrdup("");  
       while ((cp = strtok(NULL, WHITESPACE)) != NULL)  
         {  
           string = xrealloc(string, strlen(string) + strlen(cp) + 2);  
           strcat(string, " ");  
           strcat(string, cp);  
         }  
       if (*activep && *charptr == NULL)  
         *charptr = string;  
       else  
         xfree(string);  
       return 0;  
   
     case oPort:          case oCompressionLevel:
       intptr = &options->port;                  intptr = &options->compression_level;
     parse_int:                  goto parse_int;
       cp = strtok(NULL, WHITESPACE);  
       if (!cp)          case oIdentityFile:
         fatal("%.200s line %d: Missing argument.", filename, linenum);                  cp = strtok(NULL, WHITESPACE);
       if (cp[0] < '0' || cp[0] > '9')                  if (!cp)
         fatal("%.200s line %d: Bad number.", filename, linenum);                          fatal("%.200s line %d: Missing argument.", filename, linenum);
                   if (*activep) {
                           if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
                                   fatal("%.200s line %d: Too many identity files specified (max %d).",
                                         filename, linenum, SSH_MAX_IDENTITY_FILES);
                           options->identity_files[options->num_identity_files++] = xstrdup(cp);
                   }
                   break;
   
           case oUser:
                   charptr = &options->user;
   parse_string:
                   cp = strtok(NULL, WHITESPACE);
                   if (!cp)
                           fatal("%.200s line %d: Missing argument.", filename, linenum);
                   if (*activep && *charptr == NULL)
                           *charptr = xstrdup(cp);
                   break;
   
           case oGlobalKnownHostsFile:
                   charptr = &options->system_hostfile;
                   goto parse_string;
   
           case oUserKnownHostsFile:
                   charptr = &options->user_hostfile;
                   goto parse_string;
   
           case oHostName:
                   charptr = &options->hostname;
                   goto parse_string;
   
           case oProxyCommand:
                   charptr = &options->proxy_command;
                   string = xstrdup("");
                   while ((cp = strtok(NULL, WHITESPACE)) != NULL) {
                           string = xrealloc(string, strlen(string) + strlen(cp) + 2);
                           strcat(string, " ");
                           strcat(string, cp);
                   }
                   if (*activep && *charptr == NULL)
                           *charptr = string;
                   else
                           xfree(string);
                   return 0;
   
           case oPort:
                   intptr = &options->port;
   parse_int:
                   cp = strtok(NULL, WHITESPACE);
                   if (!cp)
                           fatal("%.200s line %d: Missing argument.", filename, linenum);
                   if (cp[0] < '0' || cp[0] > '9')
                           fatal("%.200s line %d: Bad number.", filename, linenum);
 #if 0  #if 0
       value = atoi(cp);                  value = atoi(cp);
 #else  #else
       {                  {
         char *ptr;                          char *ptr;
         value = strtol(cp, &ptr, 0); /* Octal, decimal, or hex format? */                          value = strtol(cp, &ptr, 0);    /* Octal, decimal, or
         if (cp == ptr)                                                             hex format? */
           fatal("%.200s line %d: Bad number.", filename, linenum);                          if (cp == ptr)
       }                                  fatal("%.200s line %d: Bad number.", filename, linenum);
                   }
 #endif  #endif
       if (*activep && *intptr == -1)                  if (*activep && *intptr == -1)
         *intptr = value;                          *intptr = value;
       break;                  break;
   
     case oConnectionAttempts:  
       intptr = &options->connection_attempts;  
       goto parse_int;  
   
     case oCipher:          case oConnectionAttempts:
       intptr = &options->cipher;                  intptr = &options->connection_attempts;
       cp = strtok(NULL, WHITESPACE);                  goto parse_int;
       value = cipher_number(cp);  
       if (value == -1)  
         fatal("%.200s line %d: Bad cipher '%s'.",  
               filename, linenum, cp ? cp : "<NONE>");  
       if (*activep && *intptr == -1)  
         *intptr = value;  
       break;  
   
     case oLogLevel:          case oCipher:
       intptr = (int *)&options->log_level;                  intptr = &options->cipher;
       cp = strtok(NULL, WHITESPACE);                  cp = strtok(NULL, WHITESPACE);
       value = log_level_number(cp);                  value = cipher_number(cp);
       if (value == (LogLevel)-1)                  if (value == -1)
         fatal("%.200s line %d: unsupported log level '%s'\n",                          fatal("%.200s line %d: Bad cipher '%s'.",
               filename, linenum, cp ? cp : "<NONE>");                                filename, linenum, cp ? cp : "<NONE>");
       if (*activep && (LogLevel)*intptr == -1)                  if (*activep && *intptr == -1)
         *intptr = (LogLevel)value;                          *intptr = value;
       break;                  break;
   
     case oRemoteForward:  
       cp = strtok(NULL, WHITESPACE);  
       if (!cp)  
         fatal("%.200s line %d: Missing argument.", filename, linenum);  
       if (cp[0] < '0' || cp[0] > '9')  
         fatal("%.200s line %d: Badly formatted port number.",  
               filename, linenum);  
       fwd_port = atoi(cp);  
       cp = strtok(NULL, WHITESPACE);  
       if (!cp)  
         fatal("%.200s line %d: Missing second argument.",  
               filename, linenum);  
       if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2)  
         fatal("%.200s line %d: Badly formatted host:port.",  
               filename, linenum);  
       if (*activep)  
         add_remote_forward(options, fwd_port, buf, fwd_host_port);  
       break;  
   
     case oLocalForward:  
       cp = strtok(NULL, WHITESPACE);  
       if (!cp)  
         fatal("%.200s line %d: Missing argument.", filename, linenum);  
       if (cp[0] < '0' || cp[0] > '9')  
         fatal("%.200s line %d: Badly formatted port number.",  
               filename, linenum);  
       fwd_port = atoi(cp);  
       cp = strtok(NULL, WHITESPACE);  
       if (!cp)  
         fatal("%.200s line %d: Missing second argument.",  
               filename, linenum);  
       if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2)  
         fatal("%.200s line %d: Badly formatted host:port.",  
               filename, linenum);  
       if (*activep)  
         add_local_forward(options, fwd_port, buf, fwd_host_port);  
       break;  
   
     case oHost:  
       *activep = 0;  
       while ((cp = strtok(NULL, WHITESPACE)) != NULL)  
         if (match_pattern(host, cp))  
           {  
             debug("Applying options for %.100s", cp);  
             *activep = 1;  
             break;  
           }  
       /* Avoid garbage check below, as strtok already returned NULL. */  
       return 0;  
   
     case oEscapeChar:          case oLogLevel:
       intptr = &options->escape_char;                  intptr = (int *) &options->log_level;
       cp = strtok(NULL, WHITESPACE);                  cp = strtok(NULL, WHITESPACE);
       if (!cp)                  value = log_level_number(cp);
         fatal("%.200s line %d: Missing argument.", filename, linenum);                  if (value == (LogLevel) - 1)
       if (cp[0] == '^' && cp[2] == 0 &&                          fatal("%.200s line %d: unsupported log level '%s'\n",
           (unsigned char)cp[1] >= 64 && (unsigned char)cp[1] < 128)                                filename, linenum, cp ? cp : "<NONE>");
         value = (unsigned char)cp[1] & 31;                  if (*activep && (LogLevel) * intptr == -1)
       else                          *intptr = (LogLevel) value;
         if (strlen(cp) == 1)                  break;
           value = (unsigned char)cp[0];  
         else          case oRemoteForward:
           if (strcmp(cp, "none") == 0)                  cp = strtok(NULL, WHITESPACE);
             value = -2;                  if (!cp)
           else                          fatal("%.200s line %d: Missing argument.", filename, linenum);
             {                  if (cp[0] < '0' || cp[0] > '9')
               fatal("%.200s line %d: Bad escape character.",                          fatal("%.200s line %d: Badly formatted port number.",
                     filename, linenum);                                filename, linenum);
               /*NOTREACHED*/                  fwd_port = atoi(cp);
               value = 0; /* Avoid compiler warning. */                  cp = strtok(NULL, WHITESPACE);
             }                  if (!cp)
       if (*activep && *intptr == -1)                          fatal("%.200s line %d: Missing second argument.",
         *intptr = value;                                filename, linenum);
       break;                  if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2)
                           fatal("%.200s line %d: Badly formatted host:port.",
     default:                                filename, linenum);
       fatal("process_config_line: Unimplemented opcode %d", opcode);                  if (*activep)
     }                          add_remote_forward(options, fwd_port, buf, fwd_host_port);
                   break;
   /* Check that there is no garbage at end of line. */  
   if (strtok(NULL, WHITESPACE) != NULL)          case oLocalForward:
     fatal("%.200s line %d: garbage at end of line.",                  cp = strtok(NULL, WHITESPACE);
           filename, linenum);                  if (!cp)
   return 0;                          fatal("%.200s line %d: Missing argument.", filename, linenum);
                   if (cp[0] < '0' || cp[0] > '9')
                           fatal("%.200s line %d: Badly formatted port number.",
                                 filename, linenum);
                   fwd_port = atoi(cp);
                   cp = strtok(NULL, WHITESPACE);
                   if (!cp)
                           fatal("%.200s line %d: Missing second argument.",
                                 filename, linenum);
                   if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2)
                           fatal("%.200s line %d: Badly formatted host:port.",
                                 filename, linenum);
                   if (*activep)
                           add_local_forward(options, fwd_port, buf, fwd_host_port);
                   break;
   
           case oHost:
                   *activep = 0;
                   while ((cp = strtok(NULL, WHITESPACE)) != NULL)
                           if (match_pattern(host, cp)) {
                                   debug("Applying options for %.100s", cp);
                                   *activep = 1;
                                   break;
                           }
                   /* Avoid garbage check below, as strtok already returned
                      NULL. */
                   return 0;
   
           case oEscapeChar:
                   intptr = &options->escape_char;
                   cp = strtok(NULL, WHITESPACE);
                   if (!cp)
                           fatal("%.200s line %d: Missing argument.", filename, linenum);
                   if (cp[0] == '^' && cp[2] == 0 &&
                       (unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128)
                           value = (unsigned char) cp[1] & 31;
                   else if (strlen(cp) == 1)
                           value = (unsigned char) cp[0];
                   else if (strcmp(cp, "none") == 0)
                           value = -2;
                   else {
                           fatal("%.200s line %d: Bad escape character.",
                                 filename, linenum);
                           /* NOTREACHED */
                           value = 0;      /* Avoid compiler warning. */
                   }
                   if (*activep && *intptr == -1)
                           *intptr = value;
                   break;
   
           default:
                   fatal("process_config_line: Unimplemented opcode %d", opcode);
           }
   
           /* Check that there is no garbage at end of line. */
           if (strtok(NULL, WHITESPACE) != NULL)
                   fatal("%.200s line %d: garbage at end of line.",
                         filename, linenum);
           return 0;
 }  }
   
   
Line 552 
Line 548 
    already be initialized before this call.  This never returns if there     already be initialized before this call.  This never returns if there
    is an error.  If the file does not exist, this returns immediately. */     is an error.  If the file does not exist, this returns immediately. */
   
 void read_config_file(const char *filename, const char *host, Options *options)  void
   read_config_file(const char *filename, const char *host, Options *options)
 {  {
   FILE *f;          FILE *f;
   char line[1024];          char line[1024];
   int active, linenum;          int active, linenum;
   int bad_options = 0;          int bad_options = 0;
   
   /* Open the file. */          /* Open the file. */
   f = fopen(filename, "r");          f = fopen(filename, "r");
   if (!f)          if (!f)
     return;                  return;
   
   debug("Reading configuration data %.200s", filename);          debug("Reading configuration data %.200s", filename);
   
   /* Mark that we are now processing the options.  This flag is turned on/off          /* Mark that we are now processing the options.  This flag is
      by Host specifications. */             turned on/off by Host specifications. */
   active = 1;          active = 1;
   linenum = 0;          linenum = 0;
   while (fgets(line, sizeof(line), f))          while (fgets(line, sizeof(line), f)) {
     {                  /* Update line number counter. */
       /* Update line number counter. */                  linenum++;
       linenum++;                  if (process_config_line(options, host, line, filename, linenum, &active) != 0)
       if (process_config_line(options, host, line, filename, linenum, &active) != 0)                          bad_options++;
         bad_options++;          }
     }          fclose(f);
   fclose(f);          if (bad_options > 0)
   if (bad_options > 0)                  fatal("%s: terminating, %d bad configuration options\n",
     fatal("%s: terminating, %d bad configuration options\n",                        filename, bad_options);
           filename, bad_options);  
 }  }
   
 /* Initializes options to special values that indicate that they have not  /* Initializes options to special values that indicate that they have not
Line 588 
Line 584 
    Options are processed in the following order: command line, user config     Options are processed in the following order: command line, user config
    file, system config file.  Last, fill_default_options is called. */     file, system config file.  Last, fill_default_options is called. */
   
 void initialize_options(Options *options)  void
   initialize_options(Options * options)
 {  {
   memset(options, 'X', sizeof(*options));          memset(options, 'X', sizeof(*options));
   options->forward_agent = -1;          options->forward_agent = -1;
   options->forward_x11 = -1;          options->forward_x11 = -1;
   options->gateway_ports = -1;          options->gateway_ports = -1;
   options->use_privileged_port = -1;          options->use_privileged_port = -1;
   options->rhosts_authentication = -1;          options->rhosts_authentication = -1;
   options->rsa_authentication = -1;          options->rsa_authentication = -1;
   options->skey_authentication = -1;          options->skey_authentication = -1;
 #ifdef KRB4  #ifdef KRB4
   options->kerberos_authentication = -1;          options->kerberos_authentication = -1;
 #endif  #endif
 #ifdef AFS  #ifdef AFS
   options->kerberos_tgt_passing = -1;          options->kerberos_tgt_passing = -1;
   options->afs_token_passing = -1;          options->afs_token_passing = -1;
 #endif  #endif
   options->password_authentication = -1;          options->password_authentication = -1;
   options->rhosts_rsa_authentication = -1;          options->rhosts_rsa_authentication = -1;
   options->fallback_to_rsh = -1;          options->fallback_to_rsh = -1;
   options->use_rsh = -1;          options->use_rsh = -1;
   options->batch_mode = -1;          options->batch_mode = -1;
   options->check_host_ip = -1;          options->check_host_ip = -1;
   options->strict_host_key_checking = -1;          options->strict_host_key_checking = -1;
   options->compression = -1;          options->compression = -1;
   options->keepalives = -1;          options->keepalives = -1;
   options->compression_level = -1;          options->compression_level = -1;
   options->port = -1;          options->port = -1;
   options->connection_attempts = -1;          options->connection_attempts = -1;
   options->number_of_password_prompts = -1;          options->number_of_password_prompts = -1;
   options->cipher = -1;          options->cipher = -1;
   options->num_identity_files = 0;          options->num_identity_files = 0;
   options->hostname = NULL;          options->hostname = NULL;
   options->proxy_command = NULL;          options->proxy_command = NULL;
   options->user = NULL;          options->user = NULL;
   options->escape_char = -1;          options->escape_char = -1;
   options->system_hostfile = NULL;          options->system_hostfile = NULL;
   options->user_hostfile = NULL;          options->user_hostfile = NULL;
   options->num_local_forwards = 0;          options->num_local_forwards = 0;
   options->num_remote_forwards = 0;          options->num_remote_forwards = 0;
   options->log_level = (LogLevel)-1;          options->log_level = (LogLevel) - 1;
 }  }
   
 /* Called after processing other sources of option data, this fills those  /* Called after processing other sources of option data, this fills those
    options for which no value has been specified with their default values. */     options for which no value has been specified with their default values. */
   
 void fill_default_options(Options *options)  void
   fill_default_options(Options * options)
 {  {
   if (options->forward_agent == -1)          if (options->forward_agent == -1)
     options->forward_agent = 1;                  options->forward_agent = 1;
   if (options->forward_x11 == -1)          if (options->forward_x11 == -1)
     options->forward_x11 = 1;                  options->forward_x11 = 1;
   if (options->gateway_ports == -1)          if (options->gateway_ports == -1)
     options->gateway_ports = 0;                  options->gateway_ports = 0;
   if (options->use_privileged_port == -1)          if (options->use_privileged_port == -1)
     options->use_privileged_port = 1;                  options->use_privileged_port = 1;
   if (options->rhosts_authentication == -1)          if (options->rhosts_authentication == -1)
     options->rhosts_authentication = 1;                  options->rhosts_authentication = 1;
   if (options->rsa_authentication == -1)          if (options->rsa_authentication == -1)
     options->rsa_authentication = 1;                  options->rsa_authentication = 1;
   if (options->skey_authentication == -1)          if (options->skey_authentication == -1)
     options->skey_authentication = 0;                  options->skey_authentication = 0;
 #ifdef KRB4  #ifdef KRB4
   if (options->kerberos_authentication == -1)          if (options->kerberos_authentication == -1)
     options->kerberos_authentication = 1;                  options->kerberos_authentication = 1;
 #endif /* KRB4 */  #endif /* KRB4 */
 #ifdef AFS  #ifdef AFS
   if (options->kerberos_tgt_passing == -1)          if (options->kerberos_tgt_passing == -1)
     options->kerberos_tgt_passing = 1;                  options->kerberos_tgt_passing = 1;
   if (options->afs_token_passing == -1)          if (options->afs_token_passing == -1)
     options->afs_token_passing = 1;                  options->afs_token_passing = 1;
 #endif /* AFS */  #endif /* AFS */
   if (options->password_authentication == -1)          if (options->password_authentication == -1)
     options->password_authentication = 1;                  options->password_authentication = 1;
   if (options->rhosts_rsa_authentication == -1)          if (options->rhosts_rsa_authentication == -1)
     options->rhosts_rsa_authentication = 1;                  options->rhosts_rsa_authentication = 1;
   if (options->fallback_to_rsh == -1)          if (options->fallback_to_rsh == -1)
     options->fallback_to_rsh = 1;                  options->fallback_to_rsh = 1;
   if (options->use_rsh == -1)          if (options->use_rsh == -1)
     options->use_rsh = 0;                  options->use_rsh = 0;
   if (options->batch_mode == -1)          if (options->batch_mode == -1)
     options->batch_mode = 0;                  options->batch_mode = 0;
   if (options->check_host_ip == -1)          if (options->check_host_ip == -1)
     options->check_host_ip = 1;                  options->check_host_ip = 1;
   if (options->strict_host_key_checking == -1)          if (options->strict_host_key_checking == -1)
     options->strict_host_key_checking = 2; /* 2 is default */                  options->strict_host_key_checking = 2;  /* 2 is default */
   if (options->compression == -1)          if (options->compression == -1)
     options->compression = 0;                  options->compression = 0;
   if (options->keepalives == -1)          if (options->keepalives == -1)
     options->keepalives = 1;                  options->keepalives = 1;
   if (options->compression_level == -1)          if (options->compression_level == -1)
     options->compression_level = 6;                  options->compression_level = 6;
   if (options->port == -1)          if (options->port == -1)
     options->port = 0; /* Filled in ssh_connect. */                  options->port = 0;      /* Filled in ssh_connect. */
   if (options->connection_attempts == -1)          if (options->connection_attempts == -1)
     options->connection_attempts = 4;                  options->connection_attempts = 4;
   if (options->number_of_password_prompts == -1)          if (options->number_of_password_prompts == -1)
     options->number_of_password_prompts = 3;                  options->number_of_password_prompts = 3;
   if (options->cipher == -1)          /* Selected in ssh_login(). */
     options->cipher = SSH_CIPHER_NOT_SET; /* Selected in ssh_login(). */          if (options->cipher == -1)
   if (options->num_identity_files == 0)                  options->cipher = SSH_CIPHER_NOT_SET;
     {          if (options->num_identity_files == 0) {
       options->identity_files[0] =                  options->identity_files[0] =
         xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);                          xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
       sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);                  sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
       options->num_identity_files = 1;                  options->num_identity_files = 1;
     }          }
   if (options->escape_char == -1)          if (options->escape_char == -1)
     options->escape_char = '~';                  options->escape_char = '~';
   if (options->system_hostfile == NULL)          if (options->system_hostfile == NULL)
     options->system_hostfile = SSH_SYSTEM_HOSTFILE;                  options->system_hostfile = SSH_SYSTEM_HOSTFILE;
   if (options->user_hostfile == NULL)          if (options->user_hostfile == NULL)
     options->user_hostfile = SSH_USER_HOSTFILE;                  options->user_hostfile = SSH_USER_HOSTFILE;
   if (options->log_level == (LogLevel)-1)          if (options->log_level == (LogLevel) - 1)
     options->log_level = SYSLOG_LEVEL_INFO;                  options->log_level = SYSLOG_LEVEL_INFO;
   /* options->proxy_command should not be set by default */          /* options->proxy_command should not be set by default */
   /* options->user will be set in the main program if appropriate */          /* options->user will be set in the main program if appropriate */
   /* options->hostname will be set in the main program if appropriate */          /* options->hostname will be set in the main program if appropriate */
 }  }
   

Legend:
Removed from v.1.16  
changed lines
  Added in v.1.17