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

Diff for /src/usr.bin/ssh/servconf.c between version 1.78 and 1.78.2.4

version 1.78, 2001/04/15 21:28:35 version 1.78.2.4, 2002/06/02 22:56:10
Line 12 
Line 12 
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #ifdef KRB4  #if defined(KRB4) || defined(KRB5)
 #include <krb.h>  #include <krb.h>
 #endif  #endif
 #ifdef AFS  #ifdef AFS
Line 31 
Line 31 
 #include "kex.h"  #include "kex.h"
 #include "mac.h"  #include "mac.h"
   
 void add_listen_addr(ServerOptions *options, char *addr, u_short port);  static void add_listen_addr(ServerOptions *, char *, u_short);
 void add_one_listen_addr(ServerOptions *options, char *addr, u_short port);  static void add_one_listen_addr(ServerOptions *, char *, u_short);
   
 /* AF_UNSPEC or AF_INET or AF_INET6 */  /* AF_UNSPEC or AF_INET or AF_INET6 */
 extern int IPv4or6;  extern int IPv4or6;
   /* Use of privilege separation or not */
   extern int use_privsep;
   
 /* Initializes the server options to their default values. */  /* Initializes the server options to their default values. */
   
Line 56 
Line 58 
         options->ignore_user_known_hosts = -1;          options->ignore_user_known_hosts = -1;
         options->print_motd = -1;          options->print_motd = -1;
         options->print_lastlog = -1;          options->print_lastlog = -1;
         options->check_mail = -1;  
         options->x11_forwarding = -1;          options->x11_forwarding = -1;
         options->x11_display_offset = -1;          options->x11_display_offset = -1;
           options->x11_use_localhost = -1;
         options->xauth_location = NULL;          options->xauth_location = NULL;
         options->strict_modes = -1;          options->strict_modes = -1;
         options->keepalives = -1;          options->keepalives = -1;
         options->log_facility = (SyslogFacility) - 1;          options->log_facility = SYSLOG_FACILITY_NOT_SET;
         options->log_level = (LogLevel) - 1;          options->log_level = SYSLOG_LEVEL_NOT_SET;
         options->rhosts_authentication = -1;          options->rhosts_authentication = -1;
         options->rhosts_rsa_authentication = -1;          options->rhosts_rsa_authentication = -1;
         options->hostbased_authentication = -1;          options->hostbased_authentication = -1;
         options->hostbased_uses_name_from_packet_only = -1;          options->hostbased_uses_name_from_packet_only = -1;
         options->rsa_authentication = -1;          options->rsa_authentication = -1;
         options->pubkey_authentication = -1;          options->pubkey_authentication = -1;
 #ifdef KRB4  #if defined(KRB4) || defined(KRB5)
         options->kerberos_authentication = -1;          options->kerberos_authentication = -1;
         options->kerberos_or_local_passwd = -1;          options->kerberos_or_local_passwd = -1;
         options->kerberos_ticket_cleanup = -1;          options->kerberos_ticket_cleanup = -1;
 #endif  #endif
 #ifdef AFS  #if defined(AFS) || defined(KRB5)
         options->kerberos_tgt_passing = -1;          options->kerberos_tgt_passing = -1;
   #endif
   #ifdef AFS
         options->afs_token_passing = -1;          options->afs_token_passing = -1;
 #endif  #endif
         options->password_authentication = -1;          options->password_authentication = -1;
         options->kbd_interactive_authentication = -1;          options->kbd_interactive_authentication = -1;
         options->challenge_reponse_authentication = -1;          options->challenge_response_authentication = -1;
         options->permit_empty_passwd = -1;          options->permit_empty_passwd = -1;
         options->use_login = -1;          options->use_login = -1;
         options->allow_tcp_forwarding = -1;          options->allow_tcp_forwarding = -1;
Line 98 
Line 102 
         options->max_startups_rate = -1;          options->max_startups_rate = -1;
         options->max_startups = -1;          options->max_startups = -1;
         options->banner = NULL;          options->banner = NULL;
         options->reverse_mapping_check = -1;          options->verify_reverse_mapping = -1;
         options->client_alive_interval = -1;          options->client_alive_interval = -1;
         options->client_alive_count_max = -1;          options->client_alive_count_max = -1;
           options->authorized_keys_file = NULL;
           options->authorized_keys_file2 = NULL;
   
           /* Needs to be accessable in many places */
           use_privsep = -1;
 }  }
   
 void  void
Line 111 
Line 120 
         if (options->num_host_key_files == 0) {          if (options->num_host_key_files == 0) {
                 /* fill default hostkeys for protocols */                  /* fill default hostkeys for protocols */
                 if (options->protocol & SSH_PROTO_1)                  if (options->protocol & SSH_PROTO_1)
                         options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE;                          options->host_key_files[options->num_host_key_files++] =
                 if (options->protocol & SSH_PROTO_2)                              _PATH_HOST_KEY_FILE;
                         options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE;                  if (options->protocol & SSH_PROTO_2) {
                           options->host_key_files[options->num_host_key_files++] =
                               _PATH_HOST_RSA_KEY_FILE;
                           options->host_key_files[options->num_host_key_files++] =
                               _PATH_HOST_DSA_KEY_FILE;
                   }
         }          }
         if (options->num_ports == 0)          if (options->num_ports == 0)
                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;                  options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
Line 133 
Line 147 
                 options->ignore_rhosts = 1;                  options->ignore_rhosts = 1;
         if (options->ignore_user_known_hosts == -1)          if (options->ignore_user_known_hosts == -1)
                 options->ignore_user_known_hosts = 0;                  options->ignore_user_known_hosts = 0;
         if (options->check_mail == -1)  
                 options->check_mail = 0;  
         if (options->print_motd == -1)          if (options->print_motd == -1)
                 options->print_motd = 1;                  options->print_motd = 1;
         if (options->print_lastlog == -1)          if (options->print_lastlog == -1)
Line 143 
Line 155 
                 options->x11_forwarding = 0;                  options->x11_forwarding = 0;
         if (options->x11_display_offset == -1)          if (options->x11_display_offset == -1)
                 options->x11_display_offset = 10;                  options->x11_display_offset = 10;
 #ifdef XAUTH_PATH          if (options->x11_use_localhost == -1)
                   options->x11_use_localhost = 1;
         if (options->xauth_location == NULL)          if (options->xauth_location == NULL)
                 options->xauth_location = XAUTH_PATH;                  options->xauth_location = _PATH_XAUTH;
 #endif /* XAUTH_PATH */  
         if (options->strict_modes == -1)          if (options->strict_modes == -1)
                 options->strict_modes = 1;                  options->strict_modes = 1;
         if (options->keepalives == -1)          if (options->keepalives == -1)
                 options->keepalives = 1;                  options->keepalives = 1;
         if (options->log_facility == (SyslogFacility) (-1))          if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
                 options->log_facility = SYSLOG_FACILITY_AUTH;                  options->log_facility = SYSLOG_FACILITY_AUTH;
         if (options->log_level == (LogLevel) (-1))          if (options->log_level == SYSLOG_LEVEL_NOT_SET)
                 options->log_level = SYSLOG_LEVEL_INFO;                  options->log_level = SYSLOG_LEVEL_INFO;
         if (options->rhosts_authentication == -1)          if (options->rhosts_authentication == -1)
                 options->rhosts_authentication = 0;                  options->rhosts_authentication = 0;
Line 167 
Line 179 
                 options->rsa_authentication = 1;                  options->rsa_authentication = 1;
         if (options->pubkey_authentication == -1)          if (options->pubkey_authentication == -1)
                 options->pubkey_authentication = 1;                  options->pubkey_authentication = 1;
 #ifdef KRB4  #if defined(KRB4) || defined(KRB5)
         if (options->kerberos_authentication == -1)          if (options->kerberos_authentication == -1)
                 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);                  options->kerberos_authentication = 0;
         if (options->kerberos_or_local_passwd == -1)          if (options->kerberos_or_local_passwd == -1)
                 options->kerberos_or_local_passwd = 1;                  options->kerberos_or_local_passwd = 1;
         if (options->kerberos_ticket_cleanup == -1)          if (options->kerberos_ticket_cleanup == -1)
                 options->kerberos_ticket_cleanup = 1;                  options->kerberos_ticket_cleanup = 1;
 #endif /* KRB4 */  #endif
 #ifdef AFS  #if defined(AFS) || defined(KRB5)
         if (options->kerberos_tgt_passing == -1)          if (options->kerberos_tgt_passing == -1)
                 options->kerberos_tgt_passing = 0;                  options->kerberos_tgt_passing = 0;
   #endif
   #ifdef AFS
         if (options->afs_token_passing == -1)          if (options->afs_token_passing == -1)
                 options->afs_token_passing = k_hasafs();                  options->afs_token_passing = 0;
 #endif /* AFS */  #endif
         if (options->password_authentication == -1)          if (options->password_authentication == -1)
                 options->password_authentication = 1;                  options->password_authentication = 1;
         if (options->kbd_interactive_authentication == -1)          if (options->kbd_interactive_authentication == -1)
                 options->kbd_interactive_authentication = 0;                  options->kbd_interactive_authentication = 0;
         if (options->challenge_reponse_authentication == -1)          if (options->challenge_response_authentication == -1)
                 options->challenge_reponse_authentication = 1;                  options->challenge_response_authentication = 1;
         if (options->permit_empty_passwd == -1)          if (options->permit_empty_passwd == -1)
                 options->permit_empty_passwd = 0;                  options->permit_empty_passwd = 0;
         if (options->use_login == -1)          if (options->use_login == -1)
Line 201 
Line 215 
                 options->max_startups_rate = 100;               /* 100% */                  options->max_startups_rate = 100;               /* 100% */
         if (options->max_startups_begin == -1)          if (options->max_startups_begin == -1)
                 options->max_startups_begin = options->max_startups;                  options->max_startups_begin = options->max_startups;
         if (options->reverse_mapping_check == -1)          if (options->verify_reverse_mapping == -1)
                 options->reverse_mapping_check = 0;                  options->verify_reverse_mapping = 0;
         if (options->client_alive_interval == -1)          if (options->client_alive_interval == -1)
                 options->client_alive_interval = 0;                  options->client_alive_interval = 0;
         if (options->client_alive_count_max == -1)          if (options->client_alive_count_max == -1)
                 options->client_alive_count_max = 3;                  options->client_alive_count_max = 3;
           if (options->authorized_keys_file2 == NULL) {
                   /* authorized_keys_file2 falls back to authorized_keys_file */
                   if (options->authorized_keys_file != NULL)
                           options->authorized_keys_file2 = options->authorized_keys_file;
                   else
                           options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
           }
           if (options->authorized_keys_file == NULL)
                   options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
   
           /* Turn privilege separation _off_ by default */
           if (use_privsep == -1)
                   use_privsep = 0;
 }  }
   
 /* Keyword tokens. */  /* Keyword tokens. */
Line 215 
Line 242 
         sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,          sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
         sPermitRootLogin, sLogFacility, sLogLevel,          sPermitRootLogin, sLogFacility, sLogLevel,
         sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,          sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
 #ifdef KRB4  #if defined(KRB4) || defined(KRB5)
         sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,          sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
 #endif  #endif
   #if defined(AFS) || defined(KRB5)
           sKerberosTgtPassing,
   #endif
 #ifdef AFS  #ifdef AFS
         sKerberosTgtPassing, sAFSTokenPassing,          sAFSTokenPassing,
 #endif  #endif
         sChallengeResponseAuthentication,          sChallengeResponseAuthentication,
         sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,          sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
         sPrintMotd, sPrintLastLog, sIgnoreRhosts,          sPrintMotd, sPrintLastLog, sIgnoreRhosts,
         sX11Forwarding, sX11DisplayOffset,          sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
         sStrictModes, sEmptyPasswd, sKeepAlives, sCheckMail,          sStrictModes, sEmptyPasswd, sKeepAlives,
         sUseLogin, sAllowTcpForwarding,          sUseLogin, sAllowTcpForwarding,
         sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,          sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
         sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,          sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
         sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,          sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
         sBanner, sReverseMappingCheck, sHostbasedAuthentication,          sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
         sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,          sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
         sClientAliveCountMax          sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
           sUsePrivilegeSeparation,
           sDeprecated
 } ServerOpCodes;  } ServerOpCodes;
   
 /* Textual representation of the tokens. */  /* Textual representation of the tokens. */
Line 257 
Line 289 
         { "rsaauthentication", sRSAAuthentication },          { "rsaauthentication", sRSAAuthentication },
         { "pubkeyauthentication", sPubkeyAuthentication },          { "pubkeyauthentication", sPubkeyAuthentication },
         { "dsaauthentication", sPubkeyAuthentication },                 /* alias */          { "dsaauthentication", sPubkeyAuthentication },                 /* alias */
 #ifdef KRB4  #if defined(KRB4) || defined(KRB5)
         { "kerberosauthentication", sKerberosAuthentication },          { "kerberosauthentication", sKerberosAuthentication },
         { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },          { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
         { "kerberosticketcleanup", sKerberosTicketCleanup },          { "kerberosticketcleanup", sKerberosTicketCleanup },
 #endif  #endif
 #ifdef AFS  #if defined(AFS) || defined(KRB5)
         { "kerberostgtpassing", sKerberosTgtPassing },          { "kerberostgtpassing", sKerberosTgtPassing },
   #endif
   #ifdef AFS
         { "afstokenpassing", sAFSTokenPassing },          { "afstokenpassing", sAFSTokenPassing },
 #endif  #endif
         { "passwordauthentication", sPasswordAuthentication },          { "passwordauthentication", sPasswordAuthentication },
         { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },          { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
         { "challengeresponseauthentication", sChallengeResponseAuthentication },          { "challengeresponseauthentication", sChallengeResponseAuthentication },
         { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */          { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
         { "checkmail", sCheckMail },          { "checkmail", sDeprecated },
         { "listenaddress", sListenAddress },          { "listenaddress", sListenAddress },
         { "printmotd", sPrintMotd },          { "printmotd", sPrintMotd },
         { "printlastlog", sPrintLastLog },          { "printlastlog", sPrintLastLog },
Line 278 
Line 312 
         { "ignoreuserknownhosts", sIgnoreUserKnownHosts },          { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
         { "x11forwarding", sX11Forwarding },          { "x11forwarding", sX11Forwarding },
         { "x11displayoffset", sX11DisplayOffset },          { "x11displayoffset", sX11DisplayOffset },
           { "x11uselocalhost", sX11UseLocalhost },
         { "xauthlocation", sXAuthLocation },          { "xauthlocation", sXAuthLocation },
         { "strictmodes", sStrictModes },          { "strictmodes", sStrictModes },
         { "permitemptypasswords", sEmptyPasswd },          { "permitemptypasswords", sEmptyPasswd },
Line 295 
Line 330 
         { "subsystem", sSubsystem },          { "subsystem", sSubsystem },
         { "maxstartups", sMaxStartups },          { "maxstartups", sMaxStartups },
         { "banner", sBanner },          { "banner", sBanner },
         { "reversemappingcheck", sReverseMappingCheck },          { "verifyreversemapping", sVerifyReverseMapping },
           { "reversemappingcheck", sVerifyReverseMapping },
         { "clientaliveinterval", sClientAliveInterval },          { "clientaliveinterval", sClientAliveInterval },
         { "clientalivecountmax", sClientAliveCountMax },          { "clientalivecountmax", sClientAliveCountMax },
         { NULL, 0 }          { "authorizedkeysfile", sAuthorizedKeysFile },
           { "authorizedkeysfile2", sAuthorizedKeysFile2 },
           { "useprivilegeseparation", sUsePrivilegeSeparation},
           { NULL, sBadOption }
 };  };
   
 /*  /*
Line 320 
Line 359 
         return sBadOption;          return sBadOption;
 }  }
   
 void  static void
 add_listen_addr(ServerOptions *options, char *addr, u_short port)  add_listen_addr(ServerOptions *options, char *addr, u_short port)
 {  {
         int i;          int i;
Line 334 
Line 373 
                 add_one_listen_addr(options, addr, port);                  add_one_listen_addr(options, addr, port);
 }  }
   
 void  static void
 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)  add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
 {  {
         struct addrinfo hints, *ai, *aitop;          struct addrinfo hints, *ai, *aitop;
Line 356 
Line 395 
         options->listen_addrs = aitop;          options->listen_addrs = aitop;
 }  }
   
 /* Reads the server configuration file. */  int
   process_server_config_line(ServerOptions *options, char *line,
 void      const char *filename, int linenum)
 read_server_config(ServerOptions *options, const char *filename)  
 {  {
         FILE *f;  
         char line[1024];  
         char *cp, **charptr, *arg, *p;          char *cp, **charptr, *arg, *p;
         int linenum, *intptr, value;          int *intptr, value;
         int bad_options = 0;  
         ServerOpCodes opcode;          ServerOpCodes opcode;
         int i;          int i, n;
   
         f = fopen(filename, "r");          cp = line;
         if (!f) {          arg = strdelim(&cp);
                 perror(filename);          /* Ignore leading whitespace */
                 exit(1);          if (*arg == '\0')
         }  
         linenum = 0;  
         while (fgets(line, sizeof(line), f)) {  
                 linenum++;  
                 cp = line;  
                 arg = strdelim(&cp);                  arg = strdelim(&cp);
                 /* Ignore leading whitespace */          if (!arg || !*arg || *arg == '#')
                 if (*arg == '\0')                  return 0;
                         arg = strdelim(&cp);          intptr = NULL;
                 if (!arg || !*arg || *arg == '#')          charptr = NULL;
                         continue;          opcode = parse_token(arg, filename, linenum);
                 intptr = NULL;          switch (opcode) {
                 charptr = NULL;          case sBadOption:
                 opcode = parse_token(arg, filename, linenum);                  return -1;
                 switch (opcode) {          case sPort:
                 case sBadOption:                  /* ignore ports from configfile if cmdline specifies ports */
                         bad_options++;                  if (options->ports_from_cmdline)
                         continue;                          return 0;
                 case sPort:                  if (options->listen_addrs != NULL)
                         /* ignore ports from configfile if cmdline specifies ports */                          fatal("%s line %d: ports must be specified before "
                         if (options->ports_from_cmdline)                              "ListenAddress.", filename, linenum);
                                 continue;                  if (options->num_ports >= MAX_PORTS)
                         if (options->listen_addrs != NULL)                          fatal("%s line %d: too many ports.",
                                 fatal("%s line %d: ports must be specified before "                              filename, linenum);
                                     "ListenAdress.\n", filename, linenum);                  arg = strdelim(&cp);
                         if (options->num_ports >= MAX_PORTS)                  if (!arg || *arg == '\0')
                                 fatal("%s line %d: too many ports.",                          fatal("%s line %d: missing port number.",
                                     filename, linenum);                              filename, linenum);
                         arg = strdelim(&cp);                  options->ports[options->num_ports++] = a2port(arg);
                         if (!arg || *arg == '\0')                  if (options->ports[options->num_ports-1] == 0)
                                 fatal("%s line %d: missing port number.",                          fatal("%s line %d: Badly formatted port number.",
                                     filename, linenum);                              filename, linenum);
                         options->ports[options->num_ports++] = a2port(arg);                  break;
                         if (options->ports[options->num_ports-1] == 0)  
                                 fatal("%s line %d: Badly formatted port number.",  
                                     filename, linenum);  
                         break;  
   
                 case sServerKeyBits:          case sServerKeyBits:
                         intptr = &options->server_key_bits;                  intptr = &options->server_key_bits;
 parse_int:  parse_int:
                         arg = strdelim(&cp);                  arg = strdelim(&cp);
                         if (!arg || *arg == '\0')                  if (!arg || *arg == '\0')
                                 fatal("%s line %d: missing integer value.",                          fatal("%s line %d: missing integer value.",
                                     filename, linenum);                              filename, linenum);
                         value = atoi(arg);                  value = atoi(arg);
                         if (*intptr == -1)                  if (*intptr == -1)
                                 *intptr = value;                          *intptr = value;
                         break;                  break;
   
                 case sLoginGraceTime:          case sLoginGraceTime:
                         intptr = &options->login_grace_time;                  intptr = &options->login_grace_time;
                         goto parse_int;  parse_time:
                   arg = strdelim(&cp);
                   if (!arg || *arg == '\0')
                           fatal("%s line %d: missing time value.",
                               filename, linenum);
                   if ((value = convtime(arg)) == -1)
                           fatal("%s line %d: invalid time value.",
                               filename, linenum);
                   if (*intptr == -1)
                           *intptr = value;
                   break;
   
                 case sKeyRegenerationTime:          case sKeyRegenerationTime:
                         intptr = &options->key_regeneration_time;                  intptr = &options->key_regeneration_time;
                         goto parse_int;                  goto parse_time;
   
                 case sListenAddress:          case sListenAddress:
                         arg = strdelim(&cp);                  arg = strdelim(&cp);
                         if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)                  if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
                                 fatal("%s line %d: missing inet addr.",                          fatal("%s line %d: missing inet addr.",
                               filename, linenum);
                   if (*arg == '[') {
                           if ((p = strchr(arg, ']')) == NULL)
                                   fatal("%s line %d: bad ipv6 inet addr usage.",
                                     filename, linenum);                                      filename, linenum);
                         if (*arg == '[') {                          arg++;
                                 if ((p = strchr(arg, ']')) == NULL)                          memmove(p, p+1, strlen(p+1)+1);
                                         fatal("%s line %d: bad ipv6 inet addr usage.",                  } else if (((p = strchr(arg, ':')) == NULL) ||
                                             filename, linenum);                              (strchr(p+1, ':') != NULL)) {
                                 arg++;                          add_listen_addr(options, arg, 0);
                                 memmove(p, p+1, strlen(p+1)+1);  
                         } else if (((p = strchr(arg, ':')) == NULL) ||  
                                     (strchr(p+1, ':') != NULL)) {  
                                 add_listen_addr(options, arg, 0);  
                                 break;  
                         }  
                         if (*p == ':') {  
                                 u_short port;  
   
                                 p++;  
                                 if (*p == '\0')  
                                         fatal("%s line %d: bad inet addr:port usage.",  
                                             filename, linenum);  
                                 else {  
                                         *(p-1) = '\0';  
                                         if ((port = a2port(p)) == 0)  
                                                 fatal("%s line %d: bad port number.",  
                                                     filename, linenum);  
                                         add_listen_addr(options, arg, port);  
                                 }  
                         } else if (*p == '\0')  
                                 add_listen_addr(options, arg, 0);  
                         else  
                                 fatal("%s line %d: bad inet addr usage.",  
                                     filename, linenum);  
                         break;                          break;
                   }
                   if (*p == ':') {
                           u_short port;
   
                 case sHostKeyFile:                          p++;
                         intptr = &options->num_host_key_files;                          if (*p == '\0')
                         if (*intptr >= MAX_HOSTKEYS)                                  fatal("%s line %d: bad inet addr:port usage.",
                                 fatal("%s line %d: too many host keys specified (max %d).",  
                                     filename, linenum, MAX_HOSTKEYS);  
                         charptr = &options->host_key_files[*intptr];  
 parse_filename:  
                         arg = strdelim(&cp);  
                         if (!arg || *arg == '\0')  
                                 fatal("%s line %d: missing file name.",  
                                     filename, linenum);                                      filename, linenum);
                         if (*charptr == NULL) {                          else {
                                 *charptr = tilde_expand_filename(arg, getuid());                                  *(p-1) = '\0';
                                 /* increase optional counter */                                  if ((port = a2port(p)) == 0)
                                 if (intptr != NULL)                                          fatal("%s line %d: bad port number.",
                                         *intptr = *intptr + 1;                                              filename, linenum);
                                   add_listen_addr(options, arg, port);
                         }                          }
                         break;                  } else if (*p == '\0')
                           add_listen_addr(options, arg, 0);
                   else
                           fatal("%s line %d: bad inet addr usage.",
                               filename, linenum);
                   break;
   
                 case sPidFile:          case sHostKeyFile:
                         charptr = &options->pid_file;                  intptr = &options->num_host_key_files;
                         goto parse_filename;                  if (*intptr >= MAX_HOSTKEYS)
                           fatal("%s line %d: too many host keys specified (max %d).",
                               filename, linenum, MAX_HOSTKEYS);
                   charptr = &options->host_key_files[*intptr];
   parse_filename:
                   arg = strdelim(&cp);
                   if (!arg || *arg == '\0')
                           fatal("%s line %d: missing file name.",
                               filename, linenum);
                   if (*charptr == NULL) {
                           *charptr = tilde_expand_filename(arg, getuid());
                           /* increase optional counter */
                           if (intptr != NULL)
                                   *intptr = *intptr + 1;
                   }
                   break;
   
                 case sPermitRootLogin:          case sPidFile:
                         intptr = &options->permit_root_login;                  charptr = &options->pid_file;
                         arg = strdelim(&cp);                  goto parse_filename;
                         if (!arg || *arg == '\0')  
                                 fatal("%s line %d: missing yes/"  
                                     "without-password/forced-commands-only/no "  
                                     "argument.", filename, linenum);  
                         value = 0;      /* silence compiler */  
                         if (strcmp(arg, "without-password") == 0)  
                                 value = PERMIT_NO_PASSWD;  
                         else if (strcmp(arg, "forced-commands-only") == 0)  
                                 value = PERMIT_FORCED_ONLY;  
                         else if (strcmp(arg, "yes") == 0)  
                                 value = PERMIT_YES;  
                         else if (strcmp(arg, "no") == 0)  
                                 value = PERMIT_NO;  
                         else  
                                 fatal("%s line %d: Bad yes/"  
                                     "without-password/forced-commands-only/no "  
                                     "argument: %s", filename, linenum, arg);  
                         if (*intptr == -1)  
                                 *intptr = value;  
                         break;  
   
                 case sIgnoreRhosts:          case sPermitRootLogin:
                         intptr = &options->ignore_rhosts;                  intptr = &options->permit_root_login;
                   arg = strdelim(&cp);
                   if (!arg || *arg == '\0')
                           fatal("%s line %d: missing yes/"
                               "without-password/forced-commands-only/no "
                               "argument.", filename, linenum);
                   value = 0;      /* silence compiler */
                   if (strcmp(arg, "without-password") == 0)
                           value = PERMIT_NO_PASSWD;
                   else if (strcmp(arg, "forced-commands-only") == 0)
                           value = PERMIT_FORCED_ONLY;
                   else if (strcmp(arg, "yes") == 0)
                           value = PERMIT_YES;
                   else if (strcmp(arg, "no") == 0)
                           value = PERMIT_NO;
                   else
                           fatal("%s line %d: Bad yes/"
                               "without-password/forced-commands-only/no "
                               "argument: %s", filename, linenum, arg);
                   if (*intptr == -1)
                           *intptr = value;
                   break;
   
           case sIgnoreRhosts:
                   intptr = &options->ignore_rhosts;
 parse_flag:  parse_flag:
                         arg = strdelim(&cp);                  arg = strdelim(&cp);
                         if (!arg || *arg == '\0')                  if (!arg || *arg == '\0')
                                 fatal("%s line %d: missing yes/no argument.",                          fatal("%s line %d: missing yes/no argument.",
                                     filename, linenum);                              filename, linenum);
                         value = 0;      /* silence compiler */                  value = 0;      /* silence compiler */
                         if (strcmp(arg, "yes") == 0)                  if (strcmp(arg, "yes") == 0)
                                 value = 1;                          value = 1;
                         else if (strcmp(arg, "no") == 0)                  else if (strcmp(arg, "no") == 0)
                                 value = 0;                          value = 0;
                         else                  else
                                 fatal("%s line %d: Bad yes/no argument: %s",                          fatal("%s line %d: Bad yes/no argument: %s",
                                         filename, linenum, arg);                                  filename, linenum, arg);
                         if (*intptr == -1)                  if (*intptr == -1)
                                 *intptr = value;                          *intptr = value;
                         break;                  break;
   
                 case sIgnoreUserKnownHosts:          case sIgnoreUserKnownHosts:
                         intptr = &options->ignore_user_known_hosts;                  intptr = &options->ignore_user_known_hosts;
                         goto parse_flag;                  goto parse_flag;
   
                 case sRhostsAuthentication:          case sRhostsAuthentication:
                         intptr = &options->rhosts_authentication;                  intptr = &options->rhosts_authentication;
                         goto parse_flag;                  goto parse_flag;
   
                 case sRhostsRSAAuthentication:          case sRhostsRSAAuthentication:
                         intptr = &options->rhosts_rsa_authentication;                  intptr = &options->rhosts_rsa_authentication;
                         goto parse_flag;                  goto parse_flag;
   
                 case sHostbasedAuthentication:          case sHostbasedAuthentication:
                         intptr = &options->hostbased_authentication;                  intptr = &options->hostbased_authentication;
                         goto parse_flag;                  goto parse_flag;
   
                 case sHostbasedUsesNameFromPacketOnly:          case sHostbasedUsesNameFromPacketOnly:
                         intptr = &options->hostbased_uses_name_from_packet_only;                  intptr = &options->hostbased_uses_name_from_packet_only;
                         goto parse_flag;                  goto parse_flag;
   
                 case sRSAAuthentication:          case sRSAAuthentication:
                         intptr = &options->rsa_authentication;                  intptr = &options->rsa_authentication;
                         goto parse_flag;                  goto parse_flag;
   
                 case sPubkeyAuthentication:          case sPubkeyAuthentication:
                         intptr = &options->pubkey_authentication;                  intptr = &options->pubkey_authentication;
                         goto parse_flag;                  goto parse_flag;
   #if defined(KRB4) || defined(KRB5)
           case sKerberosAuthentication:
                   intptr = &options->kerberos_authentication;
                   goto parse_flag;
   
 #ifdef KRB4          case sKerberosOrLocalPasswd:
                 case sKerberosAuthentication:                  intptr = &options->kerberos_or_local_passwd;
                         intptr = &options->kerberos_authentication;                  goto parse_flag;
                         goto parse_flag;  
   
                 case sKerberosOrLocalPasswd:          case sKerberosTicketCleanup:
                         intptr = &options->kerberos_or_local_passwd;                  intptr = &options->kerberos_ticket_cleanup;
                         goto parse_flag;                  goto parse_flag;
   
                 case sKerberosTicketCleanup:  
                         intptr = &options->kerberos_ticket_cleanup;  
                         goto parse_flag;  
 #endif  #endif
   #if defined(AFS) || defined(KRB5)
           case sKerberosTgtPassing:
                   intptr = &options->kerberos_tgt_passing;
                   goto parse_flag;
   #endif
 #ifdef AFS  #ifdef AFS
                 case sKerberosTgtPassing:          case sAFSTokenPassing:
                         intptr = &options->kerberos_tgt_passing;                  intptr = &options->afs_token_passing;
                         goto parse_flag;                  goto parse_flag;
   
                 case sAFSTokenPassing:  
                         intptr = &options->afs_token_passing;  
                         goto parse_flag;  
 #endif  #endif
   
                 case sPasswordAuthentication:          case sPasswordAuthentication:
                         intptr = &options->password_authentication;                  intptr = &options->password_authentication;
                         goto parse_flag;                  goto parse_flag;
   
                 case sKbdInteractiveAuthentication:          case sKbdInteractiveAuthentication:
                         intptr = &options->kbd_interactive_authentication;                  intptr = &options->kbd_interactive_authentication;
                         goto parse_flag;                  goto parse_flag;
   
                 case sCheckMail:          case sChallengeResponseAuthentication:
                         intptr = &options->check_mail;                  intptr = &options->challenge_response_authentication;
                         goto parse_flag;                  goto parse_flag;
   
                 case sChallengeResponseAuthentication:          case sPrintMotd:
                         intptr = &options->challenge_reponse_authentication;                  intptr = &options->print_motd;
                         goto parse_flag;                  goto parse_flag;
   
                 case sPrintMotd:          case sPrintLastLog:
                         intptr = &options->print_motd;                  intptr = &options->print_lastlog;
                         goto parse_flag;                  goto parse_flag;
   
                 case sPrintLastLog:          case sX11Forwarding:
                         intptr = &options->print_lastlog;                  intptr = &options->x11_forwarding;
                         goto parse_flag;                  goto parse_flag;
   
                 case sX11Forwarding:          case sX11DisplayOffset:
                         intptr = &options->x11_forwarding;                  intptr = &options->x11_display_offset;
                         goto parse_flag;                  goto parse_int;
   
                 case sX11DisplayOffset:          case sX11UseLocalhost:
                         intptr = &options->x11_display_offset;                  intptr = &options->x11_use_localhost;
                         goto parse_int;                  goto parse_flag;
   
                 case sXAuthLocation:          case sXAuthLocation:
                         charptr = &options->xauth_location;                  charptr = &options->xauth_location;
                         goto parse_filename;                  goto parse_filename;
   
                 case sStrictModes:          case sStrictModes:
                         intptr = &options->strict_modes;                  intptr = &options->strict_modes;
                         goto parse_flag;                  goto parse_flag;
   
                 case sKeepAlives:          case sKeepAlives:
                         intptr = &options->keepalives;                  intptr = &options->keepalives;
                         goto parse_flag;                  goto parse_flag;
   
                 case sEmptyPasswd:          case sEmptyPasswd:
                         intptr = &options->permit_empty_passwd;                  intptr = &options->permit_empty_passwd;
                         goto parse_flag;                  goto parse_flag;
   
                 case sUseLogin:          case sUseLogin:
                         intptr = &options->use_login;                  intptr = &options->use_login;
                         goto parse_flag;                  goto parse_flag;
   
                 case sGatewayPorts:          case sGatewayPorts:
                         intptr = &options->gateway_ports;                  intptr = &options->gateway_ports;
                         goto parse_flag;                  goto parse_flag;
   
                 case sReverseMappingCheck:          case sVerifyReverseMapping:
                         intptr = &options->reverse_mapping_check;                  intptr = &options->verify_reverse_mapping;
                         goto parse_flag;                  goto parse_flag;
   
                 case sLogFacility:          case sLogFacility:
                         intptr = (int *) &options->log_facility;                  intptr = (int *) &options->log_facility;
                         arg = strdelim(&cp);                  arg = strdelim(&cp);
                         value = log_facility_number(arg);                  value = log_facility_number(arg);
                         if (value == (SyslogFacility) - 1)                  if (value == SYSLOG_FACILITY_NOT_SET)
                                 fatal("%.200s line %d: unsupported log facility '%s'",                          fatal("%.200s line %d: unsupported log facility '%s'",
                                     filename, linenum, arg ? arg : "<NONE>");                              filename, linenum, arg ? arg : "<NONE>");
                         if (*intptr == -1)                  if (*intptr == -1)
                                 *intptr = (SyslogFacility) value;                          *intptr = (SyslogFacility) value;
                         break;                  break;
   
                 case sLogLevel:          case sLogLevel:
                         intptr = (int *) &options->log_level;                  intptr = (int *) &options->log_level;
                         arg = strdelim(&cp);                  arg = strdelim(&cp);
                         value = log_level_number(arg);                  value = log_level_number(arg);
                         if (value == (LogLevel) - 1)                  if (value == SYSLOG_LEVEL_NOT_SET)
                                 fatal("%.200s line %d: unsupported log level '%s'",                          fatal("%.200s line %d: unsupported log level '%s'",
                                     filename, linenum, arg ? arg : "<NONE>");                              filename, linenum, arg ? arg : "<NONE>");
                         if (*intptr == -1)                  if (*intptr == -1)
                                 *intptr = (LogLevel) value;                          *intptr = (LogLevel) value;
                         break;                  break;
   
                 case sAllowTcpForwarding:          case sAllowTcpForwarding:
                         intptr = &options->allow_tcp_forwarding;                  intptr = &options->allow_tcp_forwarding;
                         goto parse_flag;                  goto parse_flag;
   
                 case sAllowUsers:          case sUsePrivilegeSeparation:
                         while ((arg = strdelim(&cp)) && *arg != '\0') {                  intptr = &use_privsep;
                                 if (options->num_allow_users >= MAX_ALLOW_USERS)                  goto parse_flag;
                                         fatal("%s line %d: too many allow users.",  
                                             filename, linenum);  
                                 options->allow_users[options->num_allow_users++] = xstrdup(arg);  
                         }  
                         break;  
   
                 case sDenyUsers:          case sAllowUsers:
                         while ((arg = strdelim(&cp)) && *arg != '\0') {                  while ((arg = strdelim(&cp)) && *arg != '\0') {
                                 if (options->num_deny_users >= MAX_DENY_USERS)                          if (options->num_allow_users >= MAX_ALLOW_USERS)
                                         fatal( "%s line %d: too many deny users.",                                  fatal("%s line %d: too many allow users.",
                                             filename, linenum);                                      filename, linenum);
                                 options->deny_users[options->num_deny_users++] = xstrdup(arg);                          options->allow_users[options->num_allow_users++] = xstrdup(arg);
                         }                  }
                         break;                  break;
   
                 case sAllowGroups:          case sDenyUsers:
                         while ((arg = strdelim(&cp)) && *arg != '\0') {                  while ((arg = strdelim(&cp)) && *arg != '\0') {
                                 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)                          if (options->num_deny_users >= MAX_DENY_USERS)
                                         fatal("%s line %d: too many allow groups.",                                  fatal( "%s line %d: too many deny users.",
                                             filename, linenum);                                      filename, linenum);
                                 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);                          options->deny_users[options->num_deny_users++] = xstrdup(arg);
                         }                  }
                         break;                  break;
   
                 case sDenyGroups:          case sAllowGroups:
                         while ((arg = strdelim(&cp)) && *arg != '\0') {                  while ((arg = strdelim(&cp)) && *arg != '\0') {
                                 if (options->num_deny_groups >= MAX_DENY_GROUPS)                          if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
                                         fatal("%s line %d: too many deny groups.",                                  fatal("%s line %d: too many allow groups.",
                                             filename, linenum);                                      filename, linenum);
                                 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);                          options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
                         }                  }
                         break;                  break;
   
                 case sCiphers:          case sDenyGroups:
                         arg = strdelim(&cp);                  while ((arg = strdelim(&cp)) && *arg != '\0') {
                         if (!arg || *arg == '\0')                          if (options->num_deny_groups >= MAX_DENY_GROUPS)
                                 fatal("%s line %d: Missing argument.", filename, linenum);                                  fatal("%s line %d: too many deny groups.",
                         if (!ciphers_valid(arg))                                      filename, linenum);
                                 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",                          options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
                                     filename, linenum, arg ? arg : "<NONE>");                  }
                         if (options->ciphers == NULL)                  break;
                                 options->ciphers = xstrdup(arg);  
                         break;  
   
                 case sMacs:          case sCiphers:
                         arg = strdelim(&cp);                  arg = strdelim(&cp);
                         if (!arg || *arg == '\0')                  if (!arg || *arg == '\0')
                                 fatal("%s line %d: Missing argument.", filename, linenum);                          fatal("%s line %d: Missing argument.", filename, linenum);
                         if (!mac_valid(arg))                  if (!ciphers_valid(arg))
                                 fatal("%s line %d: Bad SSH2 mac spec '%s'.",                          fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
                                     filename, linenum, arg ? arg : "<NONE>");                              filename, linenum, arg ? arg : "<NONE>");
                         if (options->macs == NULL)                  if (options->ciphers == NULL)
                                 options->macs = xstrdup(arg);                          options->ciphers = xstrdup(arg);
                         break;                  break;
   
                 case sProtocol:          case sMacs:
                         intptr = &options->protocol;                  arg = strdelim(&cp);
                         arg = strdelim(&cp);                  if (!arg || *arg == '\0')
                         if (!arg || *arg == '\0')                          fatal("%s line %d: Missing argument.", filename, linenum);
                                 fatal("%s line %d: Missing argument.", filename, linenum);                  if (!mac_valid(arg))
                         value = proto_spec(arg);                          fatal("%s line %d: Bad SSH2 mac spec '%s'.",
                         if (value == SSH_PROTO_UNKNOWN)                              filename, linenum, arg ? arg : "<NONE>");
                                 fatal("%s line %d: Bad protocol spec '%s'.",                  if (options->macs == NULL)
                                       filename, linenum, arg ? arg : "<NONE>");                          options->macs = xstrdup(arg);
                         if (*intptr == SSH_PROTO_UNKNOWN)                  break;
                                 *intptr = value;  
                         break;  
   
                 case sSubsystem:          case sProtocol:
                         if(options->num_subsystems >= MAX_SUBSYSTEMS) {                  intptr = &options->protocol;
                                 fatal("%s line %d: too many subsystems defined.",                  arg = strdelim(&cp);
                                       filename, linenum);                  if (!arg || *arg == '\0')
                         }                          fatal("%s line %d: Missing argument.", filename, linenum);
                         arg = strdelim(&cp);                  value = proto_spec(arg);
                         if (!arg || *arg == '\0')                  if (value == SSH_PROTO_UNKNOWN)
                                 fatal("%s line %d: Missing subsystem name.",                          fatal("%s line %d: Bad protocol spec '%s'.",
                                       filename, linenum);                              filename, linenum, arg ? arg : "<NONE>");
                         for (i = 0; i < options->num_subsystems; i++)                  if (*intptr == SSH_PROTO_UNKNOWN)
                                 if(strcmp(arg, options->subsystem_name[i]) == 0)                          *intptr = value;
                                         fatal("%s line %d: Subsystem '%s' already defined.",                  break;
                                               filename, linenum, arg);  
                         options->subsystem_name[options->num_subsystems] = xstrdup(arg);  
                         arg = strdelim(&cp);  
                         if (!arg || *arg == '\0')  
                                 fatal("%s line %d: Missing subsystem command.",  
                                       filename, linenum);  
                         options->subsystem_command[options->num_subsystems] = xstrdup(arg);  
                         options->num_subsystems++;  
                         break;  
   
                 case sMaxStartups:          case sSubsystem:
                         arg = strdelim(&cp);                  if (options->num_subsystems >= MAX_SUBSYSTEMS) {
                         if (!arg || *arg == '\0')                          fatal("%s line %d: too many subsystems defined.",
                                 fatal("%s line %d: Missing MaxStartups spec.",                              filename, linenum);
                                       filename, linenum);                  }
                         if (sscanf(arg, "%d:%d:%d",                  arg = strdelim(&cp);
                             &options->max_startups_begin,                  if (!arg || *arg == '\0')
                             &options->max_startups_rate,                          fatal("%s line %d: Missing subsystem name.",
                             &options->max_startups) == 3) {                              filename, linenum);
                                 if (options->max_startups_begin >                  for (i = 0; i < options->num_subsystems; i++)
                                     options->max_startups ||                          if (strcmp(arg, options->subsystem_name[i]) == 0)
                                     options->max_startups_rate > 100 ||                                  fatal("%s line %d: Subsystem '%s' already defined.",
                                     options->max_startups_rate < 1)                                      filename, linenum, arg);
                   options->subsystem_name[options->num_subsystems] = xstrdup(arg);
                   arg = strdelim(&cp);
                   if (!arg || *arg == '\0')
                           fatal("%s line %d: Missing subsystem command.",
                               filename, linenum);
                   options->subsystem_command[options->num_subsystems] = xstrdup(arg);
                   options->num_subsystems++;
                   break;
   
           case sMaxStartups:
                   arg = strdelim(&cp);
                   if (!arg || *arg == '\0')
                           fatal("%s line %d: Missing MaxStartups spec.",
                               filename, linenum);
                   if ((n = sscanf(arg, "%d:%d:%d",
                       &options->max_startups_begin,
                       &options->max_startups_rate,
                       &options->max_startups)) == 3) {
                           if (options->max_startups_begin >
                               options->max_startups ||
                               options->max_startups_rate > 100 ||
                               options->max_startups_rate < 1)
                                 fatal("%s line %d: Illegal MaxStartups spec.",                                  fatal("%s line %d: Illegal MaxStartups spec.",
                                       filename, linenum);                                      filename, linenum);
                                 break;                  } else if (n != 1)
                         }                          fatal("%s line %d: Illegal MaxStartups spec.",
                         intptr = &options->max_startups;                              filename, linenum);
                         goto parse_int;                  else
                           options->max_startups = options->max_startups_begin;
                   break;
   
                 case sBanner:          case sBanner:
                         charptr = &options->banner;                  charptr = &options->banner;
                         goto parse_filename;                  goto parse_filename;
                 case sClientAliveInterval:          /*
                         intptr = &options->client_alive_interval;           * These options can contain %X options expanded at
                         goto parse_int;           * connect time, so that you can specify paths like:
                 case sClientAliveCountMax:           *
                         intptr = &options->client_alive_count_max;           * AuthorizedKeysFile   /etc_keys/%u
                         goto parse_int;           */
                 default:          case sAuthorizedKeysFile:
                         fatal("%s line %d: Missing handler for opcode %s (%d)",          case sAuthorizedKeysFile2:
                             filename, linenum, arg, opcode);                  charptr = (opcode == sAuthorizedKeysFile ) ?
                 }                      &options->authorized_keys_file :
                 if ((arg = strdelim(&cp)) != NULL && *arg != '\0')                      &options->authorized_keys_file2;
                         fatal("%s line %d: garbage at end of line; \"%.200s\".",                  goto parse_filename;
                             filename, linenum, arg);  
           case sClientAliveInterval:
                   intptr = &options->client_alive_interval;
                   goto parse_time;
   
           case sClientAliveCountMax:
                   intptr = &options->client_alive_count_max;
                   goto parse_int;
   
           case sDeprecated:
                   log("%s line %d: Deprecated option %s",
                       filename, linenum, arg);
                   while (arg)
                       arg = strdelim(&cp);
                   break;
   
           default:
                   fatal("%s line %d: Missing handler for opcode %s (%d)",
                       filename, linenum, arg, opcode);
           }
           if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
                   fatal("%s line %d: garbage at end of line; \"%.200s\".",
                       filename, linenum, arg);
           return 0;
   }
   
   /* Reads the server configuration file. */
   
   void
   read_server_config(ServerOptions *options, const char *filename)
   {
           FILE *f;
           char line[1024];
           int linenum;
           int bad_options = 0;
   
           f = fopen(filename, "r");
           if (!f) {
                   perror(filename);
                   exit(1);
           }
           linenum = 0;
           while (fgets(line, sizeof(line), f)) {
                   /* Update line number counter. */
                   linenum++;
                   if (process_server_config_line(options, line, filename, linenum) != 0)
                           bad_options++;
         }          }
         fclose(f);          fclose(f);
         if (bad_options > 0)          if (bad_options > 0)

Legend:
Removed from v.1.78  
changed lines
  Added in v.1.78.2.4