[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.53 and 1.53.2.7

version 1.53, 2000/10/14 12:12:09 version 1.53.2.7, 2002/03/08 17:04:43
Line 12 
Line 12 
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
   #if defined(KRB4) || defined(KRB5)
   #include <krb.h>
   #endif
   #ifdef AFS
   #include <kafs.h>
   #endif
   
 #include "ssh.h"  #include "ssh.h"
   #include "log.h"
 #include "servconf.h"  #include "servconf.h"
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "compat.h"  #include "compat.h"
   #include "pathnames.h"
   #include "tildexpand.h"
   #include "misc.h"
   #include "cipher.h"
   #include "kex.h"
   #include "mac.h"
   
 /* add listen address */  static void add_listen_addr(ServerOptions *, char *, u_short);
 void add_listen_addr(ServerOptions *options, char *addr);  static void add_one_listen_addr(ServerOptions *, char *, u_short);
   
   /* AF_UNSPEC or AF_INET or AF_INET6 */
   extern int IPv4or6;
   
 /* Initializes the server options to their default values. */  /* Initializes the server options to their default values. */
   
 void  void
Line 29 
Line 46 
         options->num_ports = 0;          options->num_ports = 0;
         options->ports_from_cmdline = 0;          options->ports_from_cmdline = 0;
         options->listen_addrs = NULL;          options->listen_addrs = NULL;
         options->host_key_file = NULL;          options->num_host_key_files = 0;
         options->host_dsa_key_file = NULL;  
         options->pid_file = NULL;          options->pid_file = NULL;
         options->server_key_bits = -1;          options->server_key_bits = -1;
         options->login_grace_time = -1;          options->login_grace_time = -1;
         options->key_regeneration_time = -1;          options->key_regeneration_time = -1;
         options->permit_root_login = -1;          options->permit_root_login = PERMIT_NOT_SET;
         options->ignore_rhosts = -1;          options->ignore_rhosts = -1;
         options->ignore_user_known_hosts = -1;          options->ignore_user_known_hosts = -1;
         options->print_motd = -1;          options->print_motd = -1;
         options->check_mail = -1;          options->print_lastlog = -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_uses_name_from_packet_only = -1;
         options->rsa_authentication = -1;          options->rsa_authentication = -1;
         options->dsa_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;
 #ifdef SKEY          options->challenge_response_authentication = -1;
         options->skey_authentication = -1;  
 #endif  
         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 73 
Line 92 
         options->num_allow_groups = 0;          options->num_allow_groups = 0;
         options->num_deny_groups = 0;          options->num_deny_groups = 0;
         options->ciphers = NULL;          options->ciphers = NULL;
           options->macs = NULL;
         options->protocol = SSH_PROTO_UNKNOWN;          options->protocol = SSH_PROTO_UNKNOWN;
         options->gateway_ports = -1;          options->gateway_ports = -1;
         options->num_subsystems = 0;          options->num_subsystems = 0;
         options->max_startups_begin = -1;          options->max_startups_begin = -1;
         options->max_startups_rate = -1;          options->max_startups_rate = -1;
         options->max_startups = -1;          options->max_startups = -1;
           options->banner = NULL;
           options->verify_reverse_mapping = -1;
           options->client_alive_interval = -1;
           options->client_alive_count_max = -1;
           options->authorized_keys_file = NULL;
           options->authorized_keys_file2 = NULL;
 }  }
   
 void  void
 fill_default_server_options(ServerOptions *options)  fill_default_server_options(ServerOptions *options)
 {  {
           if (options->protocol == SSH_PROTO_UNKNOWN)
                   options->protocol = SSH_PROTO_1|SSH_PROTO_2;
           if (options->num_host_key_files == 0) {
                   /* fill default hostkeys for protocols */
                   if (options->protocol & SSH_PROTO_1)
                           options->host_key_files[options->num_host_key_files++] =
                               _PATH_HOST_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;
         if (options->listen_addrs == NULL)          if (options->listen_addrs == NULL)
                 add_listen_addr(options, NULL);                  add_listen_addr(options, NULL, 0);
         if (options->host_key_file == NULL)  
                 options->host_key_file = HOST_KEY_FILE;  
         if (options->host_dsa_key_file == NULL)  
                 options->host_dsa_key_file = HOST_DSA_KEY_FILE;  
         if (options->pid_file == NULL)          if (options->pid_file == NULL)
                 options->pid_file = SSH_DAEMON_PID_FILE;                  options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
         if (options->server_key_bits == -1)          if (options->server_key_bits == -1)
                 options->server_key_bits = 768;                  options->server_key_bits = 768;
         if (options->login_grace_time == -1)          if (options->login_grace_time == -1)
                 options->login_grace_time = 600;                  options->login_grace_time = 600;
         if (options->key_regeneration_time == -1)          if (options->key_regeneration_time == -1)
                 options->key_regeneration_time = 3600;                  options->key_regeneration_time = 3600;
         if (options->permit_root_login == -1)          if (options->permit_root_login == PERMIT_NOT_SET)
                 options->permit_root_login = 1;                 /* yes */                  options->permit_root_login = PERMIT_YES;
         if (options->ignore_rhosts == -1)          if (options->ignore_rhosts == -1)
                 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)
                   options->print_lastlog = 1;
         if (options->x11_forwarding == -1)          if (options->x11_forwarding == -1)
                 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;
         if (options->rhosts_rsa_authentication == -1)          if (options->rhosts_rsa_authentication == -1)
                 options->rhosts_rsa_authentication = 0;                  options->rhosts_rsa_authentication = 0;
           if (options->hostbased_authentication == -1)
                   options->hostbased_authentication = 0;
           if (options->hostbased_uses_name_from_packet_only == -1)
                   options->hostbased_uses_name_from_packet_only = 0;
         if (options->rsa_authentication == -1)          if (options->rsa_authentication == -1)
                 options->rsa_authentication = 1;                  options->rsa_authentication = 1;
         if (options->dsa_authentication == -1)          if (options->pubkey_authentication == -1)
                 options->dsa_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 = (access(KEYFILE, R_OK) == 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 = k_hasafs();
 #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;
 #ifdef SKEY          if (options->challenge_response_authentication == -1)
         if (options->skey_authentication == -1)                  options->challenge_response_authentication = 1;
                 options->skey_authentication = 1;  
 #endif  
         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)
                 options->use_login = 0;                  options->use_login = 0;
         if (options->allow_tcp_forwarding == -1)          if (options->allow_tcp_forwarding == -1)
                 options->allow_tcp_forwarding = 1;                  options->allow_tcp_forwarding = 1;
         if (options->protocol == SSH_PROTO_UNKNOWN)  
                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;  
         if (options->gateway_ports == -1)          if (options->gateway_ports == -1)
                 options->gateway_ports = 0;                  options->gateway_ports = 0;
         if (options->max_startups == -1)          if (options->max_startups == -1)
Line 172 
Line 210 
                 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->verify_reverse_mapping == -1)
                   options->verify_reverse_mapping = 0;
           if (options->client_alive_interval == -1)
                   options->client_alive_interval = 0;
           if (options->client_alive_count_max == -1)
                   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;
 }  }
   
 /* Keyword tokens. */  /* Keyword tokens. */
Line 180 
Line 233 
         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
 #ifdef SKEY          sChallengeResponseAuthentication,
         sSkeyAuthentication,  
 #endif  
         sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,          sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
         sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,          sPrintMotd, sPrintLastLog, sIgnoreRhosts,
         sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,          sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
           sStrictModes, sEmptyPasswd, sKeepAlives,
         sUseLogin, sAllowTcpForwarding,          sUseLogin, sAllowTcpForwarding,
         sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,          sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
         sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,          sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
         sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups          sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
           sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
           sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
           sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
           sDeprecated
 } ServerOpCodes;  } ServerOpCodes;
   
 /* Textual representation of the tokens. */  /* Textual representation of the tokens. */
Line 205 
Line 264 
 } keywords[] = {  } keywords[] = {
         { "port", sPort },          { "port", sPort },
         { "hostkey", sHostKeyFile },          { "hostkey", sHostKeyFile },
         { "hostdsakey", sHostDSAKeyFile },          { "hostdsakey", sHostKeyFile },                                 /* alias */
         { "pidfile", sPidFile },          { "pidfile", sPidFile },
         { "serverkeybits", sServerKeyBits },          { "serverkeybits", sServerKeyBits },
         { "logingracetime", sLoginGraceTime },          { "logingracetime", sLoginGraceTime },
         { "keyregenerationinterval", sKeyRegenerationTime },          { "keyregenerationinterval", sKeyRegenerationTime },
Line 215 
Line 274 
         { "loglevel", sLogLevel },          { "loglevel", sLogLevel },
         { "rhostsauthentication", sRhostsAuthentication },          { "rhostsauthentication", sRhostsAuthentication },
         { "rhostsrsaauthentication", sRhostsRSAAuthentication },          { "rhostsrsaauthentication", sRhostsRSAAuthentication },
           { "hostbasedauthentication", sHostbasedAuthentication },
           { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
         { "rsaauthentication", sRSAAuthentication },          { "rsaauthentication", sRSAAuthentication },
         { "dsaauthentication", sDSAAuthentication },          { "pubkeyauthentication", sPubkeyAuthentication },
 #ifdef KRB4          { "dsaauthentication", sPubkeyAuthentication },                 /* alias */
   #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 },
 #ifdef SKEY          { "challengeresponseauthentication", sChallengeResponseAuthentication },
         { "skeyauthentication", sSkeyAuthentication },          { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
 #endif          { "checkmail", sDeprecated },
         { "checkmail", sCheckMail },  
         { "listenaddress", sListenAddress },          { "listenaddress", sListenAddress },
         { "printmotd", sPrintMotd },          { "printmotd", sPrintMotd },
           { "printlastlog", sPrintLastLog },
         { "ignorerhosts", sIgnoreRhosts },          { "ignorerhosts", sIgnoreRhosts },
         { "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 },
         { "uselogin", sUseLogin },          { "uselogin", sUseLogin },
         { "randomseed", sRandomSeedFile },  
         { "keepalive", sKeepAlives },          { "keepalive", sKeepAlives },
         { "allowtcpforwarding", sAllowTcpForwarding },          { "allowtcpforwarding", sAllowTcpForwarding },
         { "allowusers", sAllowUsers },          { "allowusers", sAllowUsers },
Line 250 
Line 314 
         { "allowgroups", sAllowGroups },          { "allowgroups", sAllowGroups },
         { "denygroups", sDenyGroups },          { "denygroups", sDenyGroups },
         { "ciphers", sCiphers },          { "ciphers", sCiphers },
           { "macs", sMacs },
         { "protocol", sProtocol },          { "protocol", sProtocol },
         { "gatewayports", sGatewayPorts },          { "gatewayports", sGatewayPorts },
         { "subsystem", sSubsystem },          { "subsystem", sSubsystem },
         { "maxstartups", sMaxStartups },          { "maxstartups", sMaxStartups },
         { NULL, 0 }          { "banner", sBanner },
           { "verifyreversemapping", sVerifyReverseMapping },
           { "reversemappingcheck", sVerifyReverseMapping },
           { "clientaliveinterval", sClientAliveInterval },
           { "clientalivecountmax", sClientAliveCountMax },
           { "authorizedkeysfile", sAuthorizedKeysFile },
           { "authorizedkeysfile2", sAuthorizedKeysFile2 },
           { NULL, sBadOption }
 };  };
   
 /*  /*
  * Returns the number of the token pointed to by cp of length len. Never   * Returns the number of the token pointed to by cp or sBadOption.
  * returns if the token is not known.  
  */   */
   
 static ServerOpCodes  static ServerOpCodes
 parse_token(const char *cp, const char *filename,  parse_token(const char *cp, const char *filename,
             int linenum)              int linenum)
 {  {
         unsigned int i;          u_int i;
   
         for (i = 0; keywords[i].name; i++)          for (i = 0; keywords[i].name; i++)
                 if (strcasecmp(cp, keywords[i].name) == 0)                  if (strcasecmp(cp, keywords[i].name) == 0)
                         return keywords[i].opcode;                          return keywords[i].opcode;
   
         fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",          error("%s: line %d: Bad configuration option: %s",
                 filename, linenum, cp);              filename, linenum, cp);
         return sBadOption;          return sBadOption;
 }  }
   
 /*  static void
  * add listen address  add_listen_addr(ServerOptions *options, char *addr, u_short port)
  */  
 void  
 add_listen_addr(ServerOptions *options, char *addr)  
 {  {
         extern int IPv4or6;  
         struct addrinfo hints, *ai, *aitop;  
         char strport[NI_MAXSERV];  
         int gaierr;  
         int i;          int i;
   
         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;
         for (i = 0; i < options->num_ports; i++) {          if (port == 0)
                 memset(&hints, 0, sizeof(hints));                  for (i = 0; i < options->num_ports; i++)
                 hints.ai_family = IPv4or6;                          add_one_listen_addr(options, addr, options->ports[i]);
                 hints.ai_socktype = SOCK_STREAM;          else
                 hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;                  add_one_listen_addr(options, addr, port);
                 snprintf(strport, sizeof strport, "%d", options->ports[i]);  
                 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)  
                         fatal("bad addr or host: %s (%s)\n",  
                             addr ? addr : "<NULL>",  
                             gai_strerror(gaierr));  
                 for (ai = aitop; ai->ai_next; ai = ai->ai_next)  
                         ;  
                 ai->ai_next = options->listen_addrs;  
                 options->listen_addrs = aitop;  
         }  
 }  }
   
 /* Reads the server configuration file. */  static void
   add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
   {
           struct addrinfo hints, *ai, *aitop;
           char strport[NI_MAXSERV];
           int gaierr;
   
 void          memset(&hints, 0, sizeof(hints));
 read_server_config(ServerOptions *options, const char *filename)          hints.ai_family = IPv4or6;
           hints.ai_socktype = SOCK_STREAM;
           hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
           snprintf(strport, sizeof strport, "%d", port);
           if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
                   fatal("bad addr or host: %s (%s)",
                       addr ? addr : "<NULL>",
                       gai_strerror(gaierr));
           for (ai = aitop; ai->ai_next; ai = ai->ai_next)
                   ;
           ai->ai_next = options->listen_addrs;
           options->listen_addrs = aitop;
   }
   
   int
   process_server_config_line(ServerOptions *options, char *line,
       const char *filename, int linenum)
 {  {
         FILE *f;          char *cp, **charptr, *arg, *p;
         char line[1024];          int *intptr, value;
         char *cp, **charptr, *arg;  
         int linenum, *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 == '#')          charptr = NULL;
                         continue;          opcode = parse_token(arg, filename, linenum);
                 opcode = parse_token(arg, filename, linenum);          switch (opcode) {
                 switch (opcode) {          case sBadOption:
                 case sBadOption:                  return -1;
                         bad_options++;          case sPort:
                         continue;                  /* ignore ports from configfile if cmdline specifies ports */
                 case sPort:                  if (options->ports_from_cmdline)
                         /* ignore ports from configfile if cmdline specifies ports */                          return 0;
                         if (options->ports_from_cmdline)                  if (options->listen_addrs != NULL)
                                 continue;                          fatal("%s line %d: ports must be specified before "
                         if (options->listen_addrs != NULL)                              "ListenAddress.", filename, linenum);
                                 fatal("%s line %d: ports must be specified before "                  if (options->num_ports >= MAX_PORTS)
                                     "ListenAdress.\n", filename, linenum);                          fatal("%s line %d: too many ports.",
                         if (options->num_ports >= MAX_PORTS)                              filename, linenum);
                                 fatal("%s line %d: too many ports.\n",                  arg = strdelim(&cp);
                                     filename, linenum);                  if (!arg || *arg == '\0')
                         arg = strdelim(&cp);                          fatal("%s line %d: missing port number.",
                         if (!arg || *arg == '\0')                              filename, linenum);
                                 fatal("%s line %d: missing port number.\n",                  options->ports[options->num_ports++] = a2port(arg);
                                     filename, linenum);                  if (options->ports[options->num_ports-1] == 0)
                         options->ports[options->num_ports++] = atoi(arg);                          fatal("%s line %d: Badly formatted port number.",
                         break;                              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')
                                 fprintf(stderr, "%s line %d: missing integer value.\n",                          fatal("%s line %d: missing integer value.",
                                         filename, linenum);                              filename, linenum);
                                 exit(1);                  value = atoi(arg);
                         }                  if (*intptr == -1)
                         value = atoi(arg);                          *intptr = value;
                         if (*intptr == -1)                  break;
                                 *intptr = value;  
                         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')                  if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
                                 fatal("%s line %d: missing inet addr.\n",                          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);
                         add_listen_addr(options, arg);                          arg++;
                           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;                          break;
                   }
                   if (*p == ':') {
                           u_short port;
   
                 case sHostKeyFile:                          p++;
                 case sHostDSAKeyFile:                          if (*p == '\0')
                         charptr = (opcode == sHostKeyFile ) ?                                  fatal("%s line %d: bad inet addr:port usage.",
                             &options->host_key_file : &options->host_dsa_key_file;  
 parse_filename:  
                         arg = strdelim(&cp);  
                         if (!arg || *arg == '\0') {  
                                 fprintf(stderr, "%s line %d: missing file name.\n",  
                                     filename, linenum);                                      filename, linenum);
                                 exit(1);                          else {
                                   *(p-1) = '\0';
                                   if ((port = a2port(p)) == 0)
                                           fatal("%s line %d: bad port number.",
                                               filename, linenum);
                                   add_listen_addr(options, arg, port);
                         }                          }
                         if (*charptr == NULL)                  } else if (*p == '\0')
                                 *charptr = tilde_expand_filename(arg, getuid());                          add_listen_addr(options, arg, 0);
                         break;                  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 sRandomSeedFile:          case sPidFile:
                         fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",                  charptr = &options->pid_file;
                                 filename, linenum);                  goto parse_filename;
                         arg = strdelim(&cp);  
                         break;  
   
                 case sPermitRootLogin:          case sPermitRootLogin:
                         intptr = &options->permit_root_login;                  intptr = &options->permit_root_login;
                         arg = strdelim(&cp);                  arg = strdelim(&cp);
                         if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0')
                                 fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",                          fatal("%s line %d: missing yes/"
                                         filename, linenum);                              "without-password/forced-commands-only/no "
                                 exit(1);                              "argument.", filename, linenum);
                         }                  value = 0;      /* silence compiler */
                         if (strcmp(arg, "without-password") == 0)                  if (strcmp(arg, "without-password") == 0)
                                 value = 2;                          value = PERMIT_NO_PASSWD;
                         else if (strcmp(arg, "yes") == 0)                  else if (strcmp(arg, "forced-commands-only") == 0)
                                 value = 1;                          value = PERMIT_FORCED_ONLY;
                         else if (strcmp(arg, "no") == 0)                  else if (strcmp(arg, "yes") == 0)
                                 value = 0;                          value = PERMIT_YES;
                         else {                  else if (strcmp(arg, "no") == 0)
                                 fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",                          value = PERMIT_NO;
                                         filename, linenum, arg);                  else
                                 exit(1);                          fatal("%s line %d: Bad yes/"
                         }                              "without-password/forced-commands-only/no "
                         if (*intptr == -1)                              "argument: %s", filename, linenum, arg);
                                 *intptr = value;                  if (*intptr == -1)
                         break;                          *intptr = value;
                   break;
   
                 case sIgnoreRhosts:          case sIgnoreRhosts:
                         intptr = &options->ignore_rhosts;                  intptr = &options->ignore_rhosts;
 parse_flag:  parse_flag:
                         arg = strdelim(&cp);                  arg = strdelim(&cp);
                         if (!arg || *arg == '\0') {                  if (!arg || *arg == '\0')
                                 fprintf(stderr, "%s line %d: missing yes/no argument.\n",                          fatal("%s line %d: missing yes/no argument.",
                                         filename, linenum);                              filename, linenum);
                                 exit(1);                  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",
                                 fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",                                  filename, linenum, arg);
                                         filename, linenum, arg);                  if (*intptr == -1)
                                 exit(1);                          *intptr = value;
                         }                  break;
                         if (*intptr == -1)  
                                 *intptr = value;  
                         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 sRSAAuthentication:          case sHostbasedAuthentication:
                         intptr = &options->rsa_authentication;                  intptr = &options->hostbased_authentication;
                         goto parse_flag;                  goto parse_flag;
   
                 case sDSAAuthentication:          case sHostbasedUsesNameFromPacketOnly:
                         intptr = &options->dsa_authentication;                  intptr = &options->hostbased_uses_name_from_packet_only;
                         goto parse_flag;                  goto parse_flag;
   
 #ifdef KRB4          case sRSAAuthentication:
                 case sKerberosAuthentication:                  intptr = &options->rsa_authentication;
                         intptr = &options->kerberos_authentication;                  goto parse_flag;
                         goto parse_flag;  
   
                 case sKerberosOrLocalPasswd:          case sPubkeyAuthentication:
                         intptr = &options->kerberos_or_local_passwd;                  intptr = &options->pubkey_authentication;
                         goto parse_flag;                  goto parse_flag;
   #if defined(KRB4) || defined(KRB5)
           case sKerberosAuthentication:
                   intptr = &options->kerberos_authentication;
                   goto parse_flag;
   
                 case sKerberosTicketCleanup:          case sKerberosOrLocalPasswd:
                         intptr = &options->kerberos_ticket_cleanup;                  intptr = &options->kerberos_or_local_passwd;
                         goto parse_flag;                  goto parse_flag;
 #endif  
   
           case sKerberosTicketCleanup:
                   intptr = &options->kerberos_ticket_cleanup;
                   goto parse_flag;
   #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;
   
 #ifdef SKEY          case sPrintMotd:
                 case sSkeyAuthentication:                  intptr = &options->print_motd;
                         intptr = &options->skey_authentication;                  goto parse_flag;
                         goto parse_flag;  
 #endif  
   
                 case sPrintMotd:          case sPrintLastLog:
                         intptr = &options->print_motd;                  intptr = &options->print_lastlog;
                         goto parse_flag;                  goto parse_flag;
   
                 case sX11Forwarding:          case sX11Forwarding:
                         intptr = &options->x11_forwarding;                  intptr = &options->x11_forwarding;
                         goto parse_flag;                  goto parse_flag;
   
                 case sX11DisplayOffset:          case sX11DisplayOffset:
                         intptr = &options->x11_display_offset;                  intptr = &options->x11_display_offset;
                         goto parse_int;                  goto parse_int;
   
                 case sXAuthLocation:          case sX11UseLocalhost:
                         charptr = &options->xauth_location;                  intptr = &options->x11_use_localhost;
                         goto parse_filename;                  goto parse_flag;
   
                 case sStrictModes:  
                         intptr = &options->strict_modes;  
                         goto parse_flag;  
   
                 case sKeepAlives:          case sXAuthLocation:
                         intptr = &options->keepalives;                  charptr = &options->xauth_location;
                         goto parse_flag;                  goto parse_filename;
   
                 case sEmptyPasswd:          case sStrictModes:
                         intptr = &options->permit_empty_passwd;                  intptr = &options->strict_modes;
                         goto parse_flag;                  goto parse_flag;
   
                 case sUseLogin:          case sKeepAlives:
                         intptr = &options->use_login;                  intptr = &options->keepalives;
                         goto parse_flag;                  goto parse_flag;
   
                 case sGatewayPorts:          case sEmptyPasswd:
                         intptr = &options->gateway_ports;                  intptr = &options->permit_empty_passwd;
                         goto parse_flag;                  goto parse_flag;
   
                 case sLogFacility:          case sUseLogin:
                         intptr = (int *) &options->log_facility;                  intptr = &options->use_login;
                         arg = strdelim(&cp);                  goto parse_flag;
                         value = log_facility_number(arg);  
                         if (value == (SyslogFacility) - 1)  
                                 fatal("%.200s line %d: unsupported log facility '%s'\n",  
                                     filename, linenum, arg ? arg : "<NONE>");  
                         if (*intptr == -1)  
                                 *intptr = (SyslogFacility) value;  
                         break;  
   
                 case sLogLevel:          case sGatewayPorts:
                         intptr = (int *) &options->log_level;                  intptr = &options->gateway_ports;
                         arg = strdelim(&cp);                  goto parse_flag;
                         value = log_level_number(arg);  
                         if (value == (LogLevel) - 1)  
                                 fatal("%.200s line %d: unsupported log level '%s'\n",  
                                     filename, linenum, arg ? arg : "<NONE>");  
                         if (*intptr == -1)  
                                 *intptr = (LogLevel) value;  
                         break;  
   
                 case sAllowTcpForwarding:          case sVerifyReverseMapping:
                         intptr = &options->allow_tcp_forwarding;                  intptr = &options->verify_reverse_mapping;
                         goto parse_flag;                  goto parse_flag;
   
                 case sAllowUsers:          case sLogFacility:
                         while ((arg = strdelim(&cp)) && *arg != '\0') {                  intptr = (int *) &options->log_facility;
                                 if (options->num_allow_users >= MAX_ALLOW_USERS)                  arg = strdelim(&cp);
                                         fatal("%s line %d: too many allow users.\n",                  value = log_facility_number(arg);
                                             filename, linenum);                  if (value == SYSLOG_FACILITY_NOT_SET)
                                 options->allow_users[options->num_allow_users++] = xstrdup(arg);                          fatal("%.200s line %d: unsupported log facility '%s'",
                         }                              filename, linenum, arg ? arg : "<NONE>");
                         break;                  if (*intptr == -1)
                           *intptr = (SyslogFacility) value;
                   break;
   
                 case sDenyUsers:          case sLogLevel:
                         while ((arg = strdelim(&cp)) && *arg != '\0') {                  intptr = (int *) &options->log_level;
                                 if (options->num_deny_users >= MAX_DENY_USERS)                  arg = strdelim(&cp);
                                         fatal( "%s line %d: too many deny users.\n",                  value = log_level_number(arg);
                                             filename, linenum);                  if (value == SYSLOG_LEVEL_NOT_SET)
                                 options->deny_users[options->num_deny_users++] = xstrdup(arg);                          fatal("%.200s line %d: unsupported log level '%s'",
                         }                              filename, linenum, arg ? arg : "<NONE>");
                         break;                  if (*intptr == -1)
                           *intptr = (LogLevel) value;
                   break;
   
                 case sAllowGroups:          case sAllowTcpForwarding:
                         while ((arg = strdelim(&cp)) && *arg != '\0') {                  intptr = &options->allow_tcp_forwarding;
                                 if (options->num_allow_groups >= MAX_ALLOW_GROUPS)                  goto parse_flag;
                                         fatal("%s line %d: too many allow groups.\n",  
                                             filename, linenum);  
                                 options->allow_groups[options->num_allow_groups++] = xstrdup(arg);  
                         }  
                         break;  
   
                 case sDenyGroups:          case sAllowUsers:
                         while ((arg = strdelim(&cp)) && *arg != '\0') {                  while ((arg = strdelim(&cp)) && *arg != '\0') {
                                 if (options->num_deny_groups >= MAX_DENY_GROUPS)                          if (options->num_allow_users >= MAX_ALLOW_USERS)
                                         fatal("%s line %d: too many deny groups.\n",                                  fatal("%s line %d: too many allow users.",
                                             filename, linenum);                                      filename, linenum);
                                 options->deny_groups[options->num_deny_groups++] = xstrdup(arg);                          options->allow_users[options->num_allow_users++] = xstrdup(arg);
                         }                  }
                         break;                  break;
   
                 case sCiphers:          case sDenyUsers:
                         arg = strdelim(&cp);                  while ((arg = strdelim(&cp)) && *arg != '\0') {
                         if (!arg || *arg == '\0')                          if (options->num_deny_users >= MAX_DENY_USERS)
                                 fatal("%s line %d: Missing argument.", filename, linenum);                                  fatal( "%s line %d: too many deny users.",
                         if (!ciphers_valid(arg))                                      filename, linenum);
                                 fatal("%s line %d: Bad SSH2 cipher spec '%s'.",                          options->deny_users[options->num_deny_users++] = xstrdup(arg);
                                     filename, linenum, arg ? arg : "<NONE>");                  }
                         if (options->ciphers == NULL)                  break;
                                 options->ciphers = xstrdup(arg);  
                         break;  
   
                 case sProtocol:          case sAllowGroups:
                         intptr = &options->protocol;                  while ((arg = strdelim(&cp)) && *arg != '\0') {
                         arg = strdelim(&cp);                          if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
                         if (!arg || *arg == '\0')                                  fatal("%s line %d: too many allow groups.",
                                 fatal("%s line %d: Missing argument.", filename, linenum);                                      filename, linenum);
                         value = proto_spec(arg);                          options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
                         if (value == SSH_PROTO_UNKNOWN)                  }
                                 fatal("%s line %d: Bad protocol spec '%s'.",                  break;
                                       filename, linenum, arg ? arg : "<NONE>");  
                         if (*intptr == SSH_PROTO_UNKNOWN)  
                                 *intptr = value;  
                         break;  
   
                 case sSubsystem:          case sDenyGroups:
                         if(options->num_subsystems >= MAX_SUBSYSTEMS) {                  while ((arg = strdelim(&cp)) && *arg != '\0') {
                                 fatal("%s line %d: too many subsystems defined.",                          if (options->num_deny_groups >= MAX_DENY_GROUPS)
                                       filename, linenum);                                  fatal("%s line %d: too many deny groups.",
                         }                                      filename, linenum);
                         arg = strdelim(&cp);                          options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
                         if (!arg || *arg == '\0')                  }
                                 fatal("%s line %d: Missing subsystem name.",                  break;
                                       filename, linenum);  
                         for (i = 0; i < options->num_subsystems; i++)  
                                 if(strcmp(arg, options->subsystem_name[i]) == 0)  
                                         fatal("%s line %d: Subsystem '%s' already defined.",  
                                               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 sCiphers:
                         arg = strdelim(&cp);                  arg = strdelim(&cp);
                         if (!arg || *arg == '\0')                  if (!arg || *arg == '\0')
                                 fatal("%s line %d: Missing MaxStartups spec.",                          fatal("%s line %d: Missing argument.", filename, linenum);
                                       filename, linenum);                  if (!ciphers_valid(arg))
                         if (sscanf(arg, "%d:%d:%d",                          fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
                             &options->max_startups_begin,                              filename, linenum, arg ? arg : "<NONE>");
                             &options->max_startups_rate,                  if (options->ciphers == NULL)
                             &options->max_startups) == 3) {                          options->ciphers = xstrdup(arg);
                                 if (options->max_startups_begin >                  break;
                                     options->max_startups ||  
                                     options->max_startups_rate > 100 ||  
                                     options->max_startups_rate < 1)  
                                 fatal("%s line %d: Illegal MaxStartups spec.",  
                                       filename, linenum);  
                                 break;  
                         }  
                         intptr = &options->max_startups;  
                         goto parse_int;  
   
                 default:          case sMacs:
                         fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",                  arg = strdelim(&cp);
                                 filename, linenum, arg, opcode);                  if (!arg || *arg == '\0')
                         exit(1);                          fatal("%s line %d: Missing argument.", filename, linenum);
                   if (!mac_valid(arg))
                           fatal("%s line %d: Bad SSH2 mac spec '%s'.",
                               filename, linenum, arg ? arg : "<NONE>");
                   if (options->macs == NULL)
                           options->macs = xstrdup(arg);
                   break;
   
           case sProtocol:
                   intptr = &options->protocol;
                   arg = strdelim(&cp);
                   if (!arg || *arg == '\0')
                           fatal("%s line %d: Missing argument.", filename, linenum);
                   value = proto_spec(arg);
                   if (value == SSH_PROTO_UNKNOWN)
                           fatal("%s line %d: Bad protocol spec '%s'.",
                               filename, linenum, arg ? arg : "<NONE>");
                   if (*intptr == SSH_PROTO_UNKNOWN)
                           *intptr = value;
                   break;
   
           case sSubsystem:
                   if (options->num_subsystems >= MAX_SUBSYSTEMS) {
                           fatal("%s line %d: too many subsystems defined.",
                               filename, linenum);
                 }                  }
                 if ((arg = strdelim(&cp)) != NULL && *arg != '\0') {                  arg = strdelim(&cp);
                         fprintf(stderr,                  if (!arg || *arg == '\0')
                                 "%s line %d: garbage at end of line; \"%.200s\".\n",                          fatal("%s line %d: Missing subsystem name.",
                                 filename, linenum, arg);                              filename, linenum);
                         exit(1);                  for (i = 0; i < options->num_subsystems; i++)
                 }                          if (strcmp(arg, options->subsystem_name[i]) == 0)
                                   fatal("%s line %d: Subsystem '%s' already defined.",
                                       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.",
                                       filename, linenum);
                   } else if (n != 1)
                           fatal("%s line %d: Illegal MaxStartups spec.",
                               filename, linenum);
                   else
                           options->max_startups = options->max_startups_begin;
                   break;
   
           case sBanner:
                   charptr = &options->banner;
                   goto parse_filename;
           /*
            * These options can contain %X options expanded at
            * connect time, so that you can specify paths like:
            *
            * AuthorizedKeysFile   /etc_keys/%u
            */
           case sAuthorizedKeysFile:
           case sAuthorizedKeysFile2:
                   charptr = (opcode == sAuthorizedKeysFile ) ?
                       &options->authorized_keys_file :
                       &options->authorized_keys_file2;
                   goto parse_filename;
   
           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);
         }          }
         fclose(f);          if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
         if (bad_options > 0) {                  fatal("%s line %d: garbage at end of line; \"%.200s\".",
                 fprintf(stderr, "%s: terminating, %d bad configuration options\n",                      filename, linenum, arg);
                         filename, bad_options);          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);                  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);
           if (bad_options > 0)
                   fatal("%s: terminating, %d bad configuration options",
                       filename, bad_options);
 }  }

Legend:
Removed from v.1.53  
changed lines
  Added in v.1.53.2.7